# https://pyrocko.org - GPLv3 # # The Pyrocko Developers, 21st Century # ---|P------/S----------~Lg----------
from __future__ import absolute_import, print_function, division
import numpy as num
from pyrocko.guts import Int, Float, Bool from pyrocko.gui.qt_compat import qw, qc
from pyrocko.gui.vtk_util import TrimeshPipe from .base import Element, ElementState from pyrocko import icosphere, moment_tensor as pmt, orthodrome as od, cake from pyrocko.geometry import d2r
guts_prefix = 'sparrow'
class SpheroidState(ElementState): level = Int.T(default=4) visible = Bool.T(default=True) opacity = Float.T(default=1.0) lat = Float.T(default=0.0) lon = Float.T(default=0.0) depth = Float.T(default=0.0) a = Float.T(default=10000.) b = Float.T(default=10000.) c = Float.T(default=10000.) azimuth = Float.T(default=0.0) dip = Float.T(default=0.0)
def create(self): element = SpheroidElement() element.bind_state(self) return element
class SpheroidElement(Element):
def __init__(self): Element.__init__(self) self._mesh = None self._controls = None self._params = None self._opacity = None
def get_name(self): return 'Spheroid'
def bind_state(self, state): Element.bind_state(self, state)
upd = self.update self._listeners.append(upd) for k in [ 'visible', 'level', 'opacity', 'lat', 'lon', 'depth', 'a', 'b', 'c', 'azimuth', 'dip']:
state.add_listener(upd, k)
def unbind_state(self): self._listeners = []
def set_parent(self, parent): Element.set_parent(self, parent)
self._parent.add_panel( self.get_name(), self._get_controls(), visible=True)
self.update()
def unset_parent(self): self.unbind_state() if self._parent: if self._mesh: self._parent.remove_actor(self._mesh.actor) self._mesh = None
if self._controls: self._parent.remove_panel(self._controls) self._controls = None
self._parent.update_view() self._parent = None self._opacity = None self._params = None
def update(self, *args): state = self._state
params = (state.level,)
if self._mesh and (params != self._params or not state.visible): self._parent.remove_actor(self._mesh.actor) self._mesh = None
if state.visible and not self._mesh: vertices, faces = icosphere.sphere( state.level, 'icosahedron', 'kind1', radius=1.0, triangulate=False)
self._vertices0 = vertices self._mesh = TrimeshPipe(vertices, faces, smooth=True) self._params = params
self._parent.add_actor(self._mesh.actor)
s = num.array( [state.c, state.b, state.a]) / cake.earthradius
if self._mesh: vertices = self._vertices0 * s[num.newaxis, :] bc = num.matrix([[1, 0, 0], [0, 0, 1], [0, 1, 0]], dtype=num.float) rot = num.dot( bc, num.dot( pmt.euler_to_matrix(-d2r*state.azimuth, -d2r*state.dip, 0), bc.T)) vertices = num.dot(rot, vertices.T).T vertices[:, 0] += 1.0 - state.depth / cake.earthradius rot = od.rot_to_00(state.lat, state.lon).T vertices = num.dot(rot, vertices.T).T
self._mesh.set_vertices(vertices) self._mesh.prop.SetColor(0.8, 0.2, 0.1)
if self._mesh and self._opacity != state.opacity: self._mesh.set_opacity(state.opacity) self._opacity = state.opacity else: self._opacity = None
self._parent.update_view()
def move_here(self): pstate = self._parent.state state = self._state state.lat = pstate.lat state.lon = pstate.lon
def _get_controls(self): state = self._state if not self._controls: from ..state import state_bind_slider, state_bind_checkbox
frame = qw.QFrame() layout = qw.QGridLayout() frame.setLayout(layout)
iy = 0 for (param, vmin, vmax) in [ ('lat', -90., 90.), ('lon', -180., 180.), ('depth', -10000., 100000.), ('a', 100., 100000.), ('b', 100., 100000.), ('c', 100., 100000.), ('azimuth', -180., 180.), ('dip', -90., 90.), ('opacity', 0., 1.)]:
layout.addWidget(qw.QLabel(param.capitalize()), iy, 0)
slider = qw.QSlider(qc.Qt.Horizontal) slider.setSizePolicy(qw.QSizePolicy( qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
slider.setMinimum(vmin * 100.) slider.setMaximum(vmax * 100.) layout.addWidget(slider, iy, 1)
state_bind_slider(self, state, param, slider, factor=0.01) iy += 1
pb = qw.QPushButton('Move Here') layout.addWidget(pb, iy, 0) pb.clicked.connect(self.move_here)
iy += 1
cb = qw.QCheckBox('Show') layout.addWidget(cb, iy, 0) state_bind_checkbox(self, state, 'visible', cb)
pb = qw.QPushButton('Remove') layout.addWidget(pb, iy, 1) pb.clicked.connect(self.remove)
iy += 1
layout.addWidget(qw.QFrame(), iy, 0, 1, 2)
self._controls = frame
return self._controls
__all__ = [ 'SpheroidElement', 'SpheroidState'] |