1# https://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6from pyrocko.plot import automap 

7from pyrocko.dataset.topo import tile 

8from pyrocko.guts import String 

9from pyrocko.dataset import topo 

10from pyrocko.gui.qt_compat import qw, qc 

11 

12from pyrocko.gui.vtk_util import cpt_to_vtk_lookuptable 

13 

14from .base import Element 

15from .topo import TopoMeshPipe, TopoCPTChoice, TopoState 

16 

17from .. import common 

18 

19guts_prefix = 'sparrow' 

20 

21 

22class CustomTopoState(TopoState): 

23 path = String.T(optional=True) 

24 

25 def create(self): 

26 element = CustomTopoElement() 

27 return element 

28 

29 

30class CustomTopoElement(Element): 

31 

32 def __init__(self): 

33 Element.__init__(self) 

34 self._parent = None 

35 self._controls = None 

36 self._visible = False 

37 self._mesh = None 

38 self._lookuptables = {} 

39 self._path_loaded = None 

40 

41 def get_name(self): 

42 return 'Custom Topography' 

43 

44 def bind_state(self, state): 

45 Element.bind_state(self, state) 

46 self.register_state_listener3(self.update, state, 'visible') 

47 self.register_state_listener3(self.update, state, 'exaggeration') 

48 self.register_state_listener3(self.update, state, 'opacity') 

49 self.register_state_listener3(self.update, state, 'smooth') 

50 self.register_state_listener3(self.update, state, 'cpt') 

51 self.register_state_listener3(self.update, state, 'path') 

52 

53 def set_parent(self, parent): 

54 self._parent = parent 

55 

56 self._parent.add_panel( 

57 self.get_name(), 

58 self._get_controls(), 

59 visible=True, 

60 title_controls=[ 

61 self.get_title_control_remove(), 

62 self.get_title_control_visible()]) 

63 

64 self.update() 

65 

66 def unset_parent(self): 

67 self.unbind_state() 

68 if self._parent: 

69 if self._mesh is not None: 

70 self._parent.remove_actor(self._mesh.actor) 

71 

72 self._mesh = None 

73 

74 if self._controls: 

75 self._parent.remove_panel(self._controls) 

76 self._controls = None 

77 

78 self._parent.update_view() 

79 self._parent = None 

80 

81 def update_cpt(self, cpt_name): 

82 if cpt_name not in self._lookuptables: 

83 if cpt_name == 'light': 

84 topo_cpt_wet = 'light_sea' 

85 topo_cpt_dry = 'light_land' 

86 

87 elif cpt_name == 'uniform': 

88 topo_cpt_wet = 'light_sea_uniform' 

89 topo_cpt_dry = 'light_land_uniform' 

90 

91 cpt_wet = automap.read_cpt(topo.cpt(topo_cpt_wet)) 

92 cpt_dry = automap.read_cpt(topo.cpt(topo_cpt_dry)) 

93 cpt_combi = automap.cpt_merge_wet_dry(cpt_wet, cpt_dry) 

94 

95 lut_combi = cpt_to_vtk_lookuptable(cpt_combi) 

96 lut_combi.SetNanColor(0.0, 0.0, 0.0, 0.0) 

97 

98 self._lookuptables[cpt_name] = lut_combi 

99 

100 def update(self, *args): 

101 visible = self._state.visible 

102 

103 self.update_cpt(self._state.cpt) 

104 

105 if visible: 

106 if self._path_loaded is None and self._state.path is not None or \ 

107 self._state.path != self._path_loaded: 

108 

109 if self._mesh: 

110 self._parent.remove_actor(self._mesh.actor) 

111 self._mesh = None 

112 

113 t = tile.Tile.from_grd(self._state.path) 

114 self._path_loaded = self._state.path 

115 self._mesh = TopoMeshPipe( 

116 t, 

117 mask_ocean=False, 

118 smooth=self._state.smooth, 

119 lut=self._lookuptables[self._state.cpt]) 

120 

121 self._parent.add_actor(self._mesh.actor) 

122 

123 if not visible and self._mesh: 

124 self._parent.remove_actor(self._mesh.actor) 

125 

126 if self._mesh: 

127 if visible: 

128 self._parent.add_actor(self._mesh.actor) 

129 

130 self._mesh.set_exaggeration(self._state.exaggeration) 

131 self._mesh.set_opacity(self._state.opacity) 

132 self._mesh.set_smooth(self._state.smooth) 

133 self._mesh.set_lookuptable( 

134 self._lookuptables[self._state.cpt]) 

135 

136 self._parent.update_view() 

137 

138 def open_file_dialog(self): 

139 caption = 'Select a file to open' 

140 

141 fn, _ = qw.QFileDialog.getOpenFileName( 

142 self._parent, caption, options=common.qfiledialog_options) 

143 

144 if fn: 

145 self._state.path = str(fn) 

146 

147 def _get_controls(self): 

148 state = self._state 

149 if not self._controls: 

150 from ..state import state_bind_slider, state_bind_checkbox, \ 

151 state_bind_combobox 

152 

153 frame = qw.QFrame() 

154 layout = qw.QGridLayout() 

155 frame.setLayout(layout) 

156 

157 lab = qw.QLabel('Load from:') 

158 pb_file = qw.QPushButton('File') 

159 

160 layout.addWidget(lab, 0, 0) 

161 layout.addWidget(pb_file, 0, 1) 

162 

163 pb_file.clicked.connect(self.open_file_dialog) 

164 

165 # exaggeration 

166 

167 layout.addWidget(qw.QLabel('Exaggeration'), 1, 0) 

168 

169 slider = qw.QSlider(qc.Qt.Horizontal) 

170 slider.setSizePolicy( 

171 qw.QSizePolicy( 

172 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) 

173 slider.setMinimum(0) 

174 slider.setMaximum(2000) 

175 layout.addWidget(slider, 1, 1) 

176 

177 state_bind_slider(self, state, 'exaggeration', slider, factor=0.01) 

178 

179 # opacity 

180 

181 layout.addWidget(qw.QLabel('Opacity'), 2, 0) 

182 

183 slider = qw.QSlider(qc.Qt.Horizontal) 

184 slider.setSizePolicy( 

185 qw.QSizePolicy( 

186 qw.QSizePolicy.Expanding, qw.QSizePolicy.Fixed)) 

187 slider.setMinimum(0) 

188 slider.setMaximum(1000) 

189 layout.addWidget(slider, 2, 1) 

190 

191 state_bind_slider(self, state, 'opacity', slider, factor=0.001) 

192 

193 cb = qw.QCheckBox('Smooth') 

194 layout.addWidget(cb, 3, 1) 

195 state_bind_checkbox(self, state, 'smooth', cb) 

196 

197 cb = common.string_choices_to_combobox(TopoCPTChoice) 

198 layout.addWidget(qw.QLabel('CPT'), 4, 0) 

199 layout.addWidget(cb, 4, 1) 

200 state_bind_combobox(self, state, 'cpt', cb) 

201 

202 layout.addWidget(qw.QFrame(), 6, 0, 1, 2) 

203 

204 self._controls = frame 

205 

206 return self._controls 

207 

208 

209__all__ = [ 

210 'CustomTopoElement', 

211 'CustomTopoState', 

212]