Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/gui/sparrow/elements/icosphere.py: 100%
138 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 06:59 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-06 06:59 +0000
1# https://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6import math
8from pyrocko.guts import Int, StringChoice, Bool, Float
9from pyrocko.gui.qt_compat import qw, qc
11from .. import common
12from pyrocko.gui.vtk_util import TrimeshPipe
13from .base import Element, ElementState
14from pyrocko import icosphere
15from pyrocko.geometry import r2d
16from pyrocko.color import Color
18km = 1000.
20guts_prefix = 'sparrow'
23class IcosphereBaseChoice(StringChoice):
24 choices = ['icosahedron', 'tetrahedron', 'tcube']
27class IcosphereKindChoice(StringChoice):
28 choices = ['kind1', 'kind2']
31class IcosphereState(ElementState):
32 base = IcosphereBaseChoice.T(default='icosahedron')
33 kind = IcosphereKindChoice.T(default='kind1')
34 level = Int.T(default=0)
35 visible = Bool.T(default=True)
36 smooth = Bool.T(default=False)
37 color = Color.T(default=Color.D('aluminium5'))
39 ambient = Float.T(default=0.0)
40 diffuse = Float.T(default=1.0)
41 specular = Float.T(default=0.0)
43 opacity = Float.T(default=1.0)
44 depth = Float.T(default=30.0*km)
46 def create(self):
47 element = IcosphereElement()
48 return element
51class IcosphereElement(Element):
53 def __init__(self):
54 Element.__init__(self)
55 self._mesh = None
56 self._controls = None
57 self._params = None
59 def get_name(self):
60 return 'Icosphere'
62 def bind_state(self, state):
63 Element.bind_state(self, state)
64 variables = [
65 'visible', 'level', 'base', 'kind', 'smooth', 'color', 'ambient',
66 'diffuse', 'specular', 'depth', 'opacity']
68 self.talkie_connect(state, variables, self.update)
70 def set_parent(self, parent):
71 Element.set_parent(self, parent)
72 self.talkie_connect(self._parent.state, 'dip', self.update)
74 self._parent.add_panel(
75 self.get_title_label(),
76 self._get_controls(),
77 visible=True,
78 title_controls=[
79 self.get_title_control_remove(),
80 self.get_title_control_visible()])
82 self.update()
84 def unset_parent(self):
85 self.unbind_state()
86 if self._parent:
87 if self._mesh:
88 self._parent.remove_actor(self._mesh.actor)
89 self._mesh = None
91 if self._controls:
92 self._parent.remove_panel(self._controls)
93 self._controls = None
95 self._parent.update_view()
96 self._parent = None
98 def update(self, *args):
99 state = self._state
101 params = state.level, state.base, state.kind, state.smooth
103 if self._mesh and (params != self._params or not state.visible):
104 self._parent.remove_actor(self._mesh.actor)
105 self._mesh = None
107 if state.visible and not self._mesh:
108 vertices, faces = icosphere.sphere(
109 state.level, state.base, state.kind, radius=1.0,
110 triangulate=False)
112 self._vertices = vertices
113 self._depth = 0.0
115 self._mesh = TrimeshPipe(vertices, faces, smooth=state.smooth)
116 self._params = params
118 self._parent.add_actor(self._mesh.actor)
120 if self._parent.state.distance < 2.0:
121 angle = 180. - math.acos(self._parent.state.distance / 2.0)*r2d
123 opacity = min(
124 1.0,
125 max(0., (angle+5. - self._parent.state.dip) / 10.))
126 else:
127 opacity = 1.0
129 opacity *= state.opacity
131 if self._mesh:
132 if self._depth != state.depth:
133 radius = (self._parent.planet_radius - state.depth) \
134 / self._parent.planet_radius
136 self._mesh.set_vertices(self._vertices * radius)
137 self._depth = state.depth
139 self._mesh.set_opacity(opacity)
140 self._mesh.set_color(state.color)
141 self._mesh.set_ambient(state.ambient)
142 self._mesh.set_diffuse(state.diffuse)
143 self._mesh.set_specular(state.specular)
145 self._parent.update_view()
147 def _get_controls(self):
148 state = self._state
149 if not self._controls:
150 from ..state import state_bind_slider, \
151 state_bind_combobox, state_bind_checkbox, \
152 state_bind_combobox_color, state_bind_lineedit
154 frame = qw.QFrame()
155 layout = qw.QGridLayout()
156 frame.setLayout(layout)
158 slider = qw.QSlider(qc.Qt.Horizontal)
159 slider.setSizePolicy(
160 qw.QSizePolicy(
161 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
162 slider.setMinimum(0)
163 slider.setMaximum(5)
164 slider.setSingleStep(1)
165 slider.setPageStep(1)
167 layout.addWidget(qw.QLabel('Level'), 0, 0)
168 layout.addWidget(slider, 0, 1)
170 state_bind_slider(self, state, 'level', slider, dtype=int)
172 cb = common.string_choices_to_combobox(IcosphereBaseChoice)
173 layout.addWidget(qw.QLabel('Base'), 1, 0)
174 layout.addWidget(cb, 1, 1)
175 state_bind_combobox(self, state, 'base', cb)
177 cb = common.string_choices_to_combobox(IcosphereKindChoice)
178 layout.addWidget(qw.QLabel('Kind'), 2, 0)
179 layout.addWidget(cb, 2, 1)
180 state_bind_combobox(self, state, 'kind', cb)
182 layout.addWidget(qw.QLabel('Color'), 3, 0)
184 cb = common.strings_to_combobox(
185 ['black', 'aluminium6', 'aluminium5', 'aluminium4',
186 'aluminium3', 'aluminium2', 'aluminium1', 'white',
187 'scarletred2', 'orange2', 'skyblue2', 'plum2'])
189 layout.addWidget(cb, 3, 1)
190 state_bind_combobox_color(
191 self, self._state, 'color', cb)
193 def add_slider(title, param, irow):
194 layout.addWidget(qw.QLabel(title), irow, 0)
196 slider = qw.QSlider(qc.Qt.Horizontal)
197 slider.setSizePolicy(
198 qw.QSizePolicy(
199 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed))
200 slider.setMinimum(0)
201 slider.setMaximum(1000)
202 layout.addWidget(slider, irow, 1)
204 state_bind_slider(
205 self, state, param, slider, factor=0.001)
207 add_slider('Opacity', 'opacity', 4)
208 add_slider('Ambient', 'ambient', 5)
209 add_slider('Diffuse', 'diffuse', 6)
210 add_slider('Specular', 'specular', 7)
212 cb = qw.QCheckBox('Smooth')
213 layout.addWidget(cb, 8, 1)
214 state_bind_checkbox(self, state, 'smooth', cb)
216 layout.addWidget(qw.QLabel('Depth [km]'), 9, 0)
217 le = qw.QLineEdit()
218 layout.addWidget(le, 9, 1)
219 state_bind_lineedit(
220 self, state, 'depth', le,
221 from_string=lambda s: float(s)*1000.,
222 to_string=lambda v: str(v/1000.))
224 layout.addWidget(qw.QFrame(), 10, 0, 1, 2)
226 self._controls = frame
228 return self._controls
231__all__ = [
232 'IcosphereElement',
233 'IcosphereState',
234 'IcosphereKindChoice',
235 'IcosphereBaseChoice']