wolfhece 2.0.55__py3-none-any.whl → 2.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
wolfhece/PyDraw.py CHANGED
@@ -12,6 +12,7 @@ from PIL.PngImagePlugin import PngInfo
12
12
  import io
13
13
  import json
14
14
  import glob
15
+ import traceback
15
16
  try:
16
17
  from osgeo import gdal
17
18
  except ModuleNotFoundError:
@@ -50,7 +51,7 @@ from .wolfresults_2D import Wolfresults_2D, views_2D
50
51
  from .PyTranslate import _
51
52
  from .PyVertex import cloud_vertices, getIfromRGB
52
53
  from .RatingCurve import SPWMIGaugingStations, SPWDCENNGaugingStations
53
- from .wolf_array import WOLF_ARRAY_MB, SelectionData, WolfArray, WolfArray_Sim2D, WolfArrayMB, CropDialog, header_wolf, WolfArrayMNAP, WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_INTEGER
54
+ from .wolf_array import WOLF_ARRAY_MB, SelectionData, WolfArray, WolfArrayMB, CropDialog, header_wolf, WolfArrayMNAP, WOLF_ARRAY_FULL_SINGLE, WOLF_ARRAY_FULL_INTEGER8, WOLF_ARRAY_FULL_INTEGER16, WOLF_ARRAY_FULL_DOUBLE, WOLF_ARRAY_FULL_INTEGER
54
55
  from .PyParams import Wolf_Param, key_Param, Type_Param
55
56
  from .mesh2d.bc_manager import BcManager
56
57
  from .PyVertexvectors import *
@@ -107,6 +108,108 @@ class draw_type(Enum):
107
108
  WMSFORE = 'wms-foreground'
108
109
  TILES = 'tiles'
109
110
 
111
+
112
+ class DragdropFileTarget(wx.FileDropTarget):
113
+ def __init__(self, window:"WolfMapViewer"):
114
+ wx.FileDropTarget.__init__(self)
115
+ self.window = window
116
+
117
+ def OnDropFiles(self, x, y, filenames):
118
+
119
+ def test_if_array(filename):
120
+
121
+ ext = Path(filename).suffix
122
+
123
+ if ext.lower() in ['.bin', '.npy', '.hbin', '.qxin','.qybin', '.top',
124
+ '.kbin', '.epsbin', '.tif', '.frot', '.topini_fine']:
125
+ return True
126
+ else:
127
+ return False
128
+
129
+ def test_if_arrayMB(filename):
130
+
131
+ ext = Path(filename).suffix
132
+
133
+ if ext.lower() in ['.hbinb', '.qxbinb','.qybinb', '.kbinb',
134
+ '.epsbinb', '.topini', '.frotini']:
135
+ return True
136
+ else:
137
+ return False
138
+
139
+ def test_if_vector(filename):
140
+ ext = Path(filename).suffix
141
+
142
+ if ext.lower() in ['.vec', '.vecz', '.shp', '.dxf']:
143
+ return True
144
+ else:
145
+ return False
146
+
147
+ def test_if_cloud(filename):
148
+ ext = Path(filename).suffix
149
+
150
+ if ext.lower() in ['.xyz']:
151
+ return True
152
+ else:
153
+ return False
154
+
155
+ for name in filenames:
156
+
157
+ if Path(name).is_dir():
158
+ for file in scandir(name):
159
+ if file.is_file():
160
+ self.OnDropFiles(x, y, [file.path])
161
+ continue
162
+
163
+ if test_if_array(name):
164
+ ids = self.window.get_list_keys(draw_type.ARRAYS)
165
+ id = Path(name).stem
166
+ while id in ids:
167
+ id = id + '_1'
168
+
169
+ try:
170
+ newobj = WolfArray(fname=name)
171
+ self.window.add_object('array', newobj = newobj, id = id)
172
+ except:
173
+ logging.error(_('Error while loading array : ') + name)
174
+
175
+ elif test_if_arrayMB(name):
176
+ ids = self.window.get_list_keys(draw_type.ARRAYS)
177
+ id = Path(name).stem
178
+ while id in ids:
179
+ id = id + '_1'
180
+
181
+ try:
182
+ newobj = WolfArrayMB(fname=name)
183
+ self.window.add_object('array', newobj = newobj, id = id)
184
+ except:
185
+ logging.error(_('Error while loading array : ') + name)
186
+
187
+ elif test_if_vector(name):
188
+ ids = self.window.get_list_keys(draw_type.VECTORS)
189
+ id = Path(name).stem
190
+ while id in ids:
191
+ id = id + '_1'
192
+
193
+ try:
194
+ newobj = Zones(filename=name)
195
+ self.window.add_object('vector', newobj = newobj, id = id)
196
+ except:
197
+ logging.error(_('Error while loading vector : ') + name)
198
+
199
+ elif test_if_cloud(name):
200
+ ids = self.window.get_list_keys(draw_type.CLOUD)
201
+ id = Path(name).stem
202
+ while id in ids:
203
+ id = id + '_1'
204
+
205
+ try:
206
+ newobj = cloud_vertices(fname=name)
207
+ self.window.add_object('cloud', newobj = newobj, id = id)
208
+ except:
209
+ logging.error(_('Error while loading cloud : ') + name)
210
+
211
+ return True
212
+
110
213
  class WolfMapViewer(wx.Frame):
111
214
  """
112
215
  Fenêtre de visualisation de données WOLF grâce aux WxWidgets
@@ -151,7 +254,27 @@ class WolfMapViewer(wx.Frame):
151
254
  active_particle_system: Particle_system
152
255
  active_viewer3d: Wolf_Viewer3D
153
256
 
154
- def __init__(self, wxparent, title, w=500, h=500, treewidth=200, wolfparent=None, wxlogging=None):
257
+ def __init__(self,
258
+ wxparent = None,
259
+ title:str = _('Default Wolf Map Viewer'),
260
+ w:int=500,
261
+ h:int=500,
262
+ treewidth:int=200,
263
+ wolfparent=None,
264
+ wxlogging=None):
265
+
266
+ """
267
+ Create a Viewer for WOLF data/simulation
268
+
269
+ :params wxparent: wx parent - set to None if main window
270
+ :params title: title of the window
271
+ :params w: width of the window in pixels
272
+ :params h: height of the window in pixels
273
+ :params treewidth: width of the tree list in pixels
274
+ :params wolfparent: WOLF object parent -- see PyGui.py
275
+ :params wxlogging: wx logging object
276
+
277
+ """
155
278
 
156
279
  self._wxlogging = wxlogging
157
280
  self.action = None # Action à entreprendre
@@ -207,6 +330,9 @@ class WolfMapViewer(wx.Frame):
207
330
  self.treewidth = treewidth
208
331
  super(WolfMapViewer, self).__init__(wxparent, title=title, size=(w + self.treewidth, h))
209
332
 
333
+ self._dragdrop = DragdropFileTarget(self)
334
+ self.SetDropTarget(self._dragdrop)
335
+
210
336
  # Gestion des menus
211
337
  self.popupmenu = wx.Menu()
212
338
  self.popupmenu.Bind(wx.EVT_MENU, self.OnPopupItemSelected)
@@ -220,6 +346,7 @@ class WolfMapViewer(wx.Frame):
220
346
  self.menu2d_cache_setup = None
221
347
  self.menuparticlesystem = None
222
348
  self.menu2dGPU = None
349
+ self.menuwalous = None
223
350
  self.timer_ps = None
224
351
  self.menusim2D = None
225
352
  self.menulaz = None
@@ -245,9 +372,16 @@ class WolfMapViewer(wx.Frame):
245
372
  updategltf = self.menugltf.Append(wx.ID_ANY, _('Update...'), _('Update data from gltf files'))
246
373
 
247
374
  self.filemenu.AppendSeparator()
248
- check2D = self.filemenu.Append(wx.ID_ANY, _('Check 2D simulation headers'), _('Check 2D sim'))
375
+
376
+ # SIMULATION 2D
377
+
378
+ sim2d = self.filemenu.Append(wx.ID_ANY, _('Create/Open multiblock model'), _('Create or open a multiblock model in a new viewer'))
379
+ check2D = self.filemenu.Append(wx.ID_ANY, _('Check headers'), _('Check the header .txt files from an existing 2D simulation'))
249
380
 
250
381
  self.filemenu.AppendSeparator()
382
+
383
+ # MULTIVIEWER
384
+
251
385
  compareitem = self.filemenu.Append(wx.ID_ANY, _('Set comparison'), _('Set comparison'))
252
386
  multiview = self.filemenu.Append(wx.ID_ANY, _('Multiviewer'), _('Multiviewer'))
253
387
  viewer3d = self.filemenu.Append(wx.ID_ANY, _('3D viewer'), _('3D viewer'))
@@ -299,30 +433,40 @@ class WolfMapViewer(wx.Frame):
299
433
  self.filemenu.AppendSeparator()
300
434
  addscan = self.filemenu.Append(wx.ID_FILE5, _('Recursive scan...'), _('Add recursively'))
301
435
 
302
- self.toolsmenu = wx.Menu()
303
- self.link_cs_zones = self.toolsmenu.Append(wx.ID_ANY, _("Link cross sections to active zones"),
436
+ # Tools
437
+ # ----------------
438
+
439
+ self.tools_menu = wx.Menu()
440
+
441
+ self.menu_contour_from_arrays = self.tools_menu.Append(wx.ID_ANY, _("Create contour from checked arrays..."), _("Create contour"))
442
+
443
+ # Cross sections
444
+ # ----------------
445
+
446
+ self.cs_menu = wx.Menu()
447
+ self.link_cs_zones = self.cs_menu.Append(wx.ID_ANY, _("Link cross sections to active zones"),
304
448
  _("Link cross section"))
305
- self.sortalong = self.toolsmenu.Append(ID_SORTALONG, _("Sort along..."),
449
+ self.sortalong = self.cs_menu.Append(ID_SORTALONG, _("Sort along..."),
306
450
  _("Sort cross sections along support vector"))
307
- self.select_cs = self.toolsmenu.Append(ID_SELECTCS, _("Pick one cross section"), _("Select cross section"),
451
+ self.select_cs = self.cs_menu.Append(ID_SELECTCS, _("Pick one cross section"), _("Select cross section"),
308
452
  kind=wx.ITEM_CHECK)
309
- self.menumanagebanks = self.toolsmenu.Append(wx.ID_ANY, _("Manage banks..."), _("Manage banks"))
310
- self.menucreatenewbanks = self.toolsmenu.Append(wx.ID_ANY, _("Create banks from vertices..."),
453
+ self.menumanagebanks = self.cs_menu.Append(wx.ID_ANY, _("Manage banks..."), _("Manage banks"))
454
+ self.menucreatenewbanks = self.cs_menu.Append(wx.ID_ANY, _("Create banks from vertices..."),
311
455
  _("Manage banks"))
312
- self.renamecs = self.toolsmenu.Append(wx.ID_ANY, _("Rename cross sections..."), _("Rename"))
313
- self.menutrianglecs = self.toolsmenu.Append(wx.ID_ANY, _("Triangulate cross sections..."), _("Triangulate"))
314
- self.menuexportgltfonebyone = self.toolsmenu.Append(wx.ID_ANY, _("Export cross sections to gltf..."),
456
+ self.renamecs = self.cs_menu.Append(wx.ID_ANY, _("Rename cross sections..."), _("Rename"))
457
+ self.menutrianglecs = self.cs_menu.Append(wx.ID_ANY, _("Triangulate cross sections..."), _("Triangulate"))
458
+ self.menuexportgltfonebyone = self.cs_menu.Append(wx.ID_ANY, _("Export cross sections to gltf..."),
315
459
  _("Export gltf"))
316
- self.menupontgltfonebyone = self.toolsmenu.Append(wx.ID_ANY, _("Create bridge and export gltf..."),
460
+ self.menupontgltfonebyone = self.cs_menu.Append(wx.ID_ANY, _("Create bridge and export gltf..."),
317
461
  _("Bridge gltf"))
318
462
  # self.menuimport3dfaces_from_DXF = self.toolsmenu.Append(wx.ID_ANY, _("Import triangulation..."), _("DXF"))
319
- self.menuinteractptri = self.toolsmenu.Append(wx.ID_ANY, _("Interpolate on active triangulation..."), _("InterpolateTri"))
320
- self.menucomparecloud = self.toolsmenu.Append(wx.ID_ANY, _("Compare cloud to array..."), _("Comparison"))
321
- self.menucomparetri = self.toolsmenu.Append(wx.ID_ANY, _("Compare triangles to array..."), _("Comparison"))
463
+ self.menuinteractptri = self.cs_menu.Append(wx.ID_ANY, _("Interpolate on active triangulation..."), _("InterpolateTri"))
464
+ self.menucomparecloud = self.cs_menu.Append(wx.ID_ANY, _("Compare cloud to array..."), _("Comparison"))
465
+ self.menucomparetri = self.cs_menu.Append(wx.ID_ANY, _("Compare triangles to array..."), _("Comparison"))
322
466
 
323
467
  #Profile plots
324
468
  #The action for plotting cross section's profile is initialised.
325
- self.plot_cs = self.toolsmenu.Append(ID_PLOTCS, _("Plot cross section"),_("Plot cross section"),kind=wx.ITEM_CHECK)
469
+ self.plot_cs = self.cs_menu.Append(ID_PLOTCS, _("Plot cross section"),_("Plot cross section"),kind=wx.ITEM_CHECK)
326
470
 
327
471
  self.menuviewerinterpcs = None
328
472
  self.menuinterpcs = None
@@ -387,6 +531,8 @@ class WolfMapViewer(wx.Frame):
387
531
  curtool['menu'] = self.plot_cs
388
532
  curtool['name'] = 'Plot cross section'
389
533
 
534
+ self.mybc = []
535
+
390
536
  self.active_vector = None
391
537
  self.active_zone = None
392
538
  self.active_zones = None
@@ -424,7 +570,8 @@ class WolfMapViewer(wx.Frame):
424
570
  # ajout du menu pour les données LAZ
425
571
  self.menu_laz()
426
572
 
427
- self.menubar.Append(self.toolsmenu, _('&Cross sections'))
573
+ self.menubar.Append(self.tools_menu, _('&Tools'))
574
+ self.menubar.Append(self.cs_menu, _('&Cross sections'))
428
575
 
429
576
  self.menubar.Append(self.minmaxmenu, _('&Colormap'))
430
577
  self.menubar.Append(self.analyzemenu, _('&Analyze'))
@@ -434,6 +581,8 @@ class WolfMapViewer(wx.Frame):
434
581
 
435
582
  # Ajout du conteneur OpenGL
436
583
  self.canvas = GLCanvas(self)
584
+ self.canvas.SetDropTarget(self._dragdrop)
585
+
437
586
  self.context = GLContext(self.canvas)
438
587
  self.mybackisloaded = False
439
588
  self.myfrontisloaded = False
@@ -515,6 +664,32 @@ class WolfMapViewer(wx.Frame):
515
664
  def wxlogging(self, value):
516
665
  self._wxlogging = value
517
666
 
667
+
668
+ def create_2D_MB_model(self):
669
+ """ Create a 2D model """
670
+
671
+ from .PyGui import Wolf2DModel
672
+
673
+ newview = Wolf2DModel(splash = False)
674
+
675
+ def check_2D_MB_headers(self):
676
+ """ Check headers of a 2D simulation without opening viewer"""
677
+
678
+ # Check 2D simulation
679
+ dlg = wx.FileDialog(self, _("Choose 2D simulation file"), wildcard="all (*.*)|*.*", style=wx.FD_OPEN)
680
+ if dlg.ShowModal() == wx.ID_CANCEL:
681
+ dlg.Destroy()
682
+ return
683
+
684
+ filename = dlg.GetPath()
685
+ dlg.Destroy()
686
+
687
+ from .mesh2d.wolf2dprev import prev_sim2D
688
+
689
+ sim = prev_sim2D(filename)
690
+ sim.verify_files()
691
+
692
+
518
693
  def get_mapviewer(self):
519
694
  """ Retourne une instance WolfMapViewer """
520
695
  return self
@@ -644,26 +819,355 @@ class WolfMapViewer(wx.Frame):
644
819
  bridgelaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from bridges'), _('LAZ Bridge'))
645
820
  buildinglaz = self.menulazdata.Append(wx.ID_ANY, _('Create cloud points from buildings'), _('LAZ Buildings'))
646
821
 
647
- croplaz = self.menulaz.Append(wx.ID_ANY, _('Clip LAZ grid on current zoom'), _('Select LAZ data based on the visible screen extent'),)
648
- viewlaz = self.menulaz.Append(wx.ID_ANY, _('Create LAZ viewer'), _('Create a LAZ Viewer based on loaded data'))
649
- aroundlaz = self.menulaz.Append(wx.ID_ANY, _('Plot LAZ around active vector'), _('Display a Matplotlib plot with the LAZ values around the active vector/polyline'),)
650
- pick_aroundlaz = self.menulaz.Append(wx.ID_ANY, _('Plot LAZ around temporary vector'), _('Display a Matplotlib plot with the LAZ values around a temporary vector/polyline -- Right clicks to add points + Enter'),)
651
- updatecolors_laz = self.menulaz.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
822
+ croplaz = self.menulaz.Append(wx.ID_ANY, _('Clip LAZ grid on current zoom'), _('Select LAZ data based on the visible screen extent'),)
823
+ viewlaz = self.menulaz.Append(wx.ID_ANY, _('Create LAZ viewer'), _('Create a LAZ Viewer based on loaded data'))
824
+ aroundlaz = self.menulaz.Append(wx.ID_ANY, _('Plot LAZ around active vector'), _('Display a Matplotlib plot with the LAZ values around the active vector/polyline'),)
825
+ pick_aroundlaz = self.menulaz.Append(wx.ID_ANY, _('Plot LAZ around temporary vector'), _('Display a Matplotlib plot with the LAZ values around a temporary vector/polyline -- Right clicks to add points + Enter'),)
826
+ updatecolors_laz = self.menulaz.Append(wx.ID_ANY, _('Change colors - Classification'), _('Change color map associated to the current classification'),)
827
+
828
+ def menu_wolf2d(self):
829
+
830
+ if self.menuwolf2d is None:
831
+ self.menuwolf2d = wx.Menu()
832
+
833
+ self.menu2d_curentview = self.menuwolf2d.Append(wx.ID_ANY, _("Change current view"), _("Current view"))
834
+ self.menu2d_lastres = self.menuwolf2d.Append(wx.ID_ANY, _("Read last result"), _("Current view"))
835
+ self.menu2d_epsilon = self.menuwolf2d.Append(wx.ID_ANY, _("Set epsilon water depth"), _("Set the epsilon used in the mask"))
836
+
837
+ self.menu_filter_independent = self.menuwolf2d.Append(wx.ID_ANY, _("Filter independent"), _("Filter independent"), kind=wx.ITEM_CHECK)
838
+
839
+ # self.menu2d_bc = self.menuwolf2d.Append(wx.ID_ANY, _("Manage boundary conditions..."), _("BC manager"))
840
+ self.menu2d_video = self.menuwolf2d.Append(wx.ID_ANY, _("Create video..."), _("Video/Movie"))
841
+
842
+ self.menubar.Append(self.menuwolf2d, _('Results 2D'))
843
+
844
+ self.menuwolf2d.Bind(wx.EVT_MENU, self.Onmenuwolf2d)
845
+
846
+ def menu_walous(self):
847
+
848
+ if self.menuwalous is None:
849
+ self.menuwalous = wx.Menu()
850
+
851
+ self.menuwalous_crop = self.menuwalous.Append(wx.ID_ANY, _("Crop on active array"), _("Crop active array"))
852
+ self.menuwalous_cropscreen = self.menuwalous.Append(wx.ID_ANY, _("Crop on screen"), _("Crop screen"))
853
+ self.menuwalous_map = self.menuwalous.Append(wx.ID_ANY, _("Map active array"), _("Map active array"))
854
+ self.menuwalous_legend = self.menuwalous.Append(wx.ID_ANY, _("Legend"), _("Legend"))
855
+ self._walous_filepath = None
856
+ self._walous_layer = None
857
+ self._walous_map = None
858
+
859
+ self.menubar.Append(self.menuwalous, _('Walous'))
860
+
861
+ self.menuwalous.Bind(wx.EVT_MENU, self.Onmenuwalous)
862
+
863
+
864
+ def get_canvas_bounds(self, gridsize:float = None):
865
+ """ Retourne les limites de la zone d'affichage """
866
+
867
+ if gridsize is None:
868
+
869
+ return [self.xmin, self.ymin, self.xmax, self.ymax]
870
+
871
+ else:
872
+
873
+ xmin = float(np.rint(self.xmin / gridsize) * gridsize)
874
+ ymin = float(np.rint(self.ymin / gridsize) * gridsize)
875
+ xmax = float(np.rint(self.xmax / gridsize) * gridsize)
876
+ ymax = float(np.rint(self.ymax / gridsize) * gridsize)
877
+
878
+ return [xmin, ymin, xmax, ymax]
879
+
880
+ def Onmenuwalous(self, event: wx.MenuEvent):
881
+
882
+ id = event.GetId()
883
+ item = self.menubar.FindItemById(event.GetId())
884
+
885
+ if item is None:
886
+ return
887
+
888
+ itemlabel = item.ItemLabel
889
+
890
+ if itemlabel in [_("Crop on active array"), _("Crop on screen")]:
891
+
892
+
893
+ if itemlabel == _("Crop on screen"):
894
+
895
+ bounds = self.get_canvas_bounds(gridsize=1.)
896
+
897
+ def_outdrir = ''
898
+ spatial_res = 1.
899
+
900
+ if self.active_array is not None:
901
+ spatial_res = self.active_array.dx
902
+
903
+ dlg = wx.TextEntryDialog(None,_("Spatial resolution [m] ?"), value = str(spatial_res))
904
+
905
+ dlg.ShowModal()
906
+ try:
907
+ spatial_res = float(dlg.GetValue())
908
+ dlg.Destroy()
909
+ except:
910
+ dlg.Destroy()
911
+ logging.warning(_("Bad value -- Rety"))
912
+ return
913
+
914
+ else:
915
+
916
+ if self.active_array is None:
917
+ logging.warning(_('No active array -- Please activate data first'))
918
+ return
919
+
920
+ bounds = self.active_array.get_bounds()
921
+ def_outdrir = Path(self.active_array.filename).parent
922
+ spatial_res = self.active_array.dx
923
+
924
+ from .pywalous import Walous_data, WALOUS2MANNING_MAJ_NIV1, WALOUS2MANNING_MAJ_NIV2, update_palette_walous
925
+
926
+ if self._walous_filepath is None:
927
+ dlg = wx.FileDialog(self, _("Choose the Walous shape file"), wildcard="Shapefile (*.shp)|*.shp|all (*.*)|*.*", style=wx.FD_OPEN)
928
+ if dlg.ShowModal() == wx.ID_CANCEL:
929
+ dlg.Destroy()
930
+ return
931
+
932
+ self._walous_filepath = Path(dlg.GetPath())
933
+ dlg.Destroy()
934
+
935
+
936
+ dlg = wx.FileDialog(self, _("Choose the output file"), wildcard="Geotif (*.tif)|*.tif|all (*.*)|*.*", style=wx.FD_SAVE, defaultDir=def_outdrir)
937
+ if dlg.ShowModal() == wx.ID_CANCEL:
938
+ dlg.Destroy()
939
+ return
940
+
941
+ output = Path(dlg.GetPath())
942
+ dlg.Destroy()
943
+
944
+ # choix de la couche entre MAJ_NIV1 et MAJ_NIV2
945
+ dlg = wx.SingleChoiceDialog(None, _("Choose a layer"), "Choices", ['MAJ_NIV1', 'MAJ_NIV2'])
946
+ ret = dlg.ShowModal()
947
+ if ret == wx.ID_CANCEL:
948
+ dlg.Destroy()
949
+ return
950
+
951
+ self._walous_layer = dlg.GetStringSelection()
952
+
953
+ locwalous = Walous_data(self._walous_filepath.parent, self._walous_filepath.name)
954
+ ret = locwalous.rasterize(bounds=bounds,
955
+ layer=self._walous_layer,
956
+ fn_out=output,
957
+ pixel_size=spatial_res)
958
+
959
+ if isinstance(ret, int):
960
+ logging.error(_('Error {}').format(ret))
961
+ return
962
+
963
+ if Path(output).exists():
964
+ logging.info(_('File {} created').format(output))
965
+ else:
966
+ logging.error(_('File {} not created').format(output))
967
+ return
968
+
969
+ dlg = wx.MessageDialog(self, _('Do you want to load the created file ?'), _('Load file'), wx.YES_NO | wx.ICON_QUESTION)
970
+ ret = dlg.ShowModal()
971
+
972
+ if ret == wx.ID_CANCEL:
973
+ dlg.Destroy()
974
+ return
975
+
976
+ elif ret == wx.ID_YES:
977
+ walousarray = WolfArray(fname=output)
978
+ update_palette_walous(self._walous_layer, walousarray.mypal)
979
+ self.add_object('array', newobj=walousarray, id = 'walous_crop')
980
+ dlg.Destroy()
981
+
982
+ elif itemlabel == _("Legend"):
983
+
984
+ from .pywalous import WalousLegend
985
+
986
+ newlegend = WalousLegend(self)
987
+ newlegend.Show()
988
+
989
+ elif itemlabel == _("Map active array"):
990
+
991
+ from .pywalous import DlgMapWalous, WALOUS2MANNING_MAJ_NIV1, WALOUS2MANNING_MAJ_NIV2
992
+
993
+ if self.active_array is None:
994
+ logging.warning(_('No active array -- Please activate data first'))
995
+ return
996
+
997
+ vals = self.active_array.get_unique_values()
998
+
999
+ if self._walous_layer is None:
1000
+
1001
+ if vals[0] > 10:
1002
+ self._walous_layer = 'MAJ_NIV2'
1003
+ else:
1004
+ self._walous_layer = 'MAJ_NIV1'
1005
+
1006
+ dlg = DlgMapWalous(self, which=self._walous_layer)
1007
+
1008
+ ret = dlg.ShowModal()
1009
+
1010
+ if ret == wx.ID_CANCEL:
1011
+ dlg.Destroy()
1012
+ return
1013
+
1014
+ mapvals = dlg.get_mapping()
1015
+ dlg.Destroy()
1016
+
1017
+ if mapvals == -1:
1018
+ logging.error(_('Bad values -- retry'))
1019
+ return
1020
+
1021
+ self.active_array.map_values(mapvals)
1022
+
1023
+ self.active_array.reset_plot()
1024
+
1025
+ def Onmenuwolf2d(self, event: wx.MenuEvent):
1026
+
1027
+ id = event.GetId()
1028
+ item = self.menubar.FindItemById(event.GetId())
1029
+
1030
+ if item is None:
1031
+ return
1032
+
1033
+ itemlabel = item.ItemLabel
1034
+
1035
+
1036
+ if itemlabel == _("Read last result"):
1037
+
1038
+ self.read_last_result()
1039
+
1040
+ elif itemlabel == _("Change current view"):
1041
+
1042
+ # Change view for results
1043
+
1044
+ autoscale = False
1045
+ choices = [cur.value for cur in views_2D]
1046
+ dlg = wx.SingleChoiceDialog(None, _("Pick a view"), "Choices", choices)
1047
+ ret = dlg.ShowModal()
1048
+ if ret == wx.ID_CANCEL:
1049
+ dlg.Destroy()
1050
+ return
1051
+
1052
+ method = dlg.GetStringSelection()
1053
+
1054
+ method = list(views_2D)[choices.index(method)]
1055
+
1056
+ dlg.Destroy()
1057
+
1058
+ diamsize = None
1059
+ if method == views_2D.SHIELDS_NUMBER :
1060
+
1061
+ if self.active_res2d is not None:
1062
+ sediment_diam = self.active_res2d.sediment_diameter
1063
+ sediment_density = self.active_res2d.sediment_density
1064
+ elif self.compare_results is not None:
1065
+ sediment_diam = 0.001
1066
+ sediment_density = 2.650
1067
+ else:
1068
+ logging.warning(_('No active 2D result or comparison !'))
1069
+ return
1070
+
1071
+ dlg = wx.TextEntryDialog(None,_("Diameter grain size [m] ?"), value = str(sediment_diam))
1072
+ ret = dlg.ShowModal()
1073
+ if ret == wx.ID_CANCEL:
1074
+ dlg.Destroy()
1075
+ return
1076
+ try:
1077
+ diamsize = float(dlg.GetValue())
1078
+ except:
1079
+ dlg.Destroy()
1080
+ logging.warning(_("Bad value -- Rety"))
1081
+ return
1082
+
1083
+ dlg = wx.TextEntryDialog(None,_("Density grain [-] ?"), value = str(sediment_density))
1084
+ ret = dlg.ShowModal()
1085
+ if ret == wx.ID_CANCEL:
1086
+ dlg.Destroy()
1087
+ return
1088
+ try:
1089
+ density = float(dlg.GetValue())
1090
+ except:
1091
+ dlg.Destroy()
1092
+ logging.warning(_("Bad value -- Rety"))
1093
+ return
1094
+
1095
+ if len(self.myres2D)>1:
1096
+
1097
+ dlg = wx.MessageDialog(None, _('Apply to all results?'), style=wx.YES_NO)
1098
+ ret = dlg.ShowModal()
1099
+ if ret == wx.ID_NO:
1100
+ if diamsize is not None:
1101
+ self.active_res2d.sediment_diameter = diamsize
1102
+ self.active_res2d.sediment_density = density
1103
+ self.active_res2d.load_default_colormap('shields_cst')
1104
+
1105
+ self.active_res2d.set_currentview(method, force_wx = True, force_updatepal = True)
1106
+ else:
1107
+ for curarray in self.iterator_over_objects(draw_type.RES2D):
1108
+ curarray:Wolfresults_2D
1109
+ if diamsize is not None:
1110
+ curarray.sediment_diameter = diamsize
1111
+ curarray.sediment_density = density
1112
+ curarray.load_default_colormap('shields_cst')
1113
+
1114
+ curarray.set_currentview(method, force_wx = True, force_updatepal = True)
1115
+
1116
+ else:
1117
+ if self.active_res2d is not None:
1118
+ if diamsize is not None:
1119
+ self.active_res2d.sediment_diameter = diamsize
1120
+ self.active_res2d.sediment_density = density
1121
+ self.active_res2d.load_default_colormap('shields_cst')
1122
+ self.active_res2d.set_currentview(method, force_wx = True, force_updatepal = True)
1123
+
1124
+ if self.compare_results is not None:
1125
+ # update compare results
1126
+ if diamsize is not None:
1127
+ self.compare_results.set_shields_param(diamsize, density)
1128
+ self.compare_results.update_type_result(method)
1129
+
1130
+ elif itemlabel == _("Set epsilon water depth"):
1131
+
1132
+ dlg = wx.TextEntryDialog(self, _('Enter an epsilon [m]'),value='0.0')
1133
+
1134
+ ret = dlg.ShowModal()
1135
+
1136
+ if ret == wx.ID_CANCEL:
1137
+ dlg.Destroy()
1138
+ return
1139
+
1140
+ try:
1141
+ neweps = float(dlg.GetValue())
1142
+ dlg.Destroy()
1143
+ except:
1144
+ logging.error(_('Bad value -- retry !'))
1145
+ dlg.Destroy()
1146
+ return
1147
+
1148
+ for curmodel in self.iterator_over_objects(draw_type.RES2D):
1149
+ curmodel: Wolfresults_2D
1150
+ curmodel.epsilon = neweps
1151
+ curmodel._epsilon_default = neweps
1152
+ curmodel.read_oneresult(curmodel.current_result)
1153
+ curmodel.set_currentview()
1154
+
1155
+ elif itemlabel == _("Filter independent"):
652
1156
 
653
- def menu_wolf2d(self):
1157
+ self.menu_filter_independent.IsChecked = not self.menu_filter_independent.IsChecked
654
1158
 
655
- if self.menuwolf2d is None:
656
- self.menuwolf2d = wx.Menu()
657
- self.menu2d_curentview = self.menuwolf2d.Append(wx.ID_ANY, _("Change current view"), _("Current view"))
658
- self.menu2d_lastres = self.menuwolf2d.Append(wx.ID_ANY, _("Read last result"), _("Current view"))
659
- self.menu2d_epsilon = self.menuwolf2d.Append(wx.ID_ANY, _("Set epsilon water depth"), _("Set the epsilon used in the mask"))
1159
+ for curmodel in self.iterator_over_objects(draw_type.RES2D):
1160
+ curmodel: Wolfresults_2D
1161
+ curmodel.to_filter_independent = not self.menu_filter_independent.IsChecked
660
1162
 
661
- self.menu_filter_independent = self.menuwolf2d.Append(wx.ID_ANY, _("Filter independent"), _("Filter independent"), kind=wx.ITEM_CHECK)
1163
+ # elif itemlabel == _("Manage boundary conditions..."):
662
1164
 
663
- self.menu2d_bc = self.menuwolf2d.Append(wx.ID_ANY, _("Manage boundary conditions..."), _("BC manager"))
664
- self.menu2d_video = self.menuwolf2d.Append(wx.ID_ANY, _("Create video..."), _("Video/Movie"))
1165
+ # if self.active_res2d is not None:
1166
+ # self.active_res2d.myparams.editing_bc(self.myres2D)
665
1167
 
666
- self.menubar.Append(self.menuwolf2d, _('Options 2D'))
1168
+ elif itemlabel ==_("Create video..."):
1169
+ if self.active_res2d is not None:
1170
+ self.create_video()
667
1171
 
668
1172
  def menu_2dgpu(self):
669
1173
 
@@ -903,21 +1407,21 @@ class WolfMapViewer(wx.Frame):
903
1407
  if self.active_array is None:
904
1408
  logging.warning(_('No active array -- Please activate an array first'))
905
1409
  return
906
- if len(self.active_array.mngselection.myselection) == 0 and len(self.active_array.mngselection.selections) ==0:
1410
+ if len(self.active_array.SelectionData.myselection) == 0 and len(self.active_array.SelectionData.selections) ==0:
907
1411
  logging.warning(_('No selection -- Please select some nodes first'))
908
1412
  return
909
1413
 
910
1414
  from .lagrangian.emitter import Emitter
911
1415
 
912
1416
  newemitters=[]
913
- if len(self.active_array.mngselection.myselection) > 0:
914
- indices = [self.active_array.get_ij_from_xy(cur[0], cur[1]) for cur in self.active_array.mngselection.myselection]
1417
+ if len(self.active_array.SelectionData.myselection) > 0:
1418
+ indices = [self.active_array.get_ij_from_xy(cur[0], cur[1]) for cur in self.active_array.SelectionData.myselection]
915
1419
  newemitters = [Emitter(indices,
916
1420
  header = (self.active_array.origx, self.active_array.origy, self.active_array.dx, self.active_array.dy))]
917
1421
 
918
- if len(self.active_array.mngselection.selections) > 0:
1422
+ if len(self.active_array.SelectionData.selections) > 0:
919
1423
 
920
- for cursel in self.active_array.mngselection.selections.values():
1424
+ for cursel in self.active_array.SelectionData.selections.values():
921
1425
  indices = [self.active_array.get_ij_from_xy(cur[0], cur[1]) for cur in cursel['select']]
922
1426
  newemitters += [Emitter(indices, header = (self.active_array.origx, self.active_array.origy, self.active_array.dx, self.active_array.dy))]
923
1427
 
@@ -980,18 +1484,162 @@ class WolfMapViewer(wx.Frame):
980
1484
  self.timer_ps.Stop()
981
1485
 
982
1486
  def menu_sim2D(self):
1487
+ """ Menu for 2D simulations """
1488
+
983
1489
  if self.menusim2D is None:
984
1490
  self.menusim2D = wx.Menu()
985
1491
  self.menubar.Append(self.menusim2D, _('Tools 2D'))
986
1492
 
987
- update = self.menusim2D.Append(wx.ID_ANY, _('Update model from current mask'), _('Update model'))
988
- updateblocfile = self.menusim2D.Append(wx.ID_ANY, _('Update .bloc file'), _('Update bloc'))
989
- updatefreesurface = self.menusim2D.Append(wx.ID_ANY, _('Update free surface elevation - IC'), _('Update free surface elevation'))
990
- updaterough = self.menusim2D.Append(wx.ID_ANY, _('Update roughness coeff'), _('Update roughness coefficient'))
991
- updateic = self.menusim2D.Append(wx.ID_ANY, _('Update IC reading mode'), _('Update IC'))
992
- menu2d_tft_ic = self.menusim2D.Append(wx.ID_ANY,_("Transfer initial conditions..."),_("Transfer IC"))
1493
+ menu2d_options = self.menusim2D.Append(wx.ID_ANY, _("Parameters..."), _("Parameters"))
1494
+ menu2d_zbin2hbin = self.menusim2D.Append(wx.ID_ANY, _("Convert zbin to hbin"), _("Convert zbin to hbin"))
1495
+ menu2d_hbin2zbin = self.menusim2D.Append(wx.ID_ANY, _("Convert hbin to zbin"), _("Convert hbin to zbin"))
1496
+ menu2D_zbinb2hbinb = self.menusim2D.Append(wx.ID_ANY, _("Convert zbinb to hbinb"), _("Convert zbinb to hbinb"))
1497
+ menu2d_hbinb2zbinb = self.menusim2D.Append(wx.ID_ANY, _("Convert hbinb to zbinb"), _("Convert hbinb to zbinb"))
1498
+ menu2d_forcemask = self.menusim2D.Append(wx.ID_ANY, _("Reset mask of all arrays"), _("Reset mask"))
1499
+
1500
+ # update = self.menusim2D.Append(wx.ID_ANY, _('Update model from current mask'), _('Update model'))
1501
+ # updateblocfile = self.menusim2D.Append(wx.ID_ANY, _('Update .bloc file'), _('Update bloc'))
1502
+ # updatefreesurface = self.menusim2D.Append(wx.ID_ANY, _('Update free surface elevation - IC'), _('Update free surface elevation'))
1503
+ # updaterough = self.menusim2D.Append(wx.ID_ANY, _('Update roughness coeff'), _('Update roughness coefficient'))
1504
+ # updateic = self.menusim2D.Append(wx.ID_ANY, _('Update IC reading mode'), _('Update IC'))
1505
+ # menu2d_tft_ic = self.menusim2D.Append(wx.ID_ANY,_("Transfer initial conditions..."),_("Transfer IC"))
1506
+
1507
+ self.menusim2D.Bind(wx.EVT_MENU, self.Onmenusim2D)
1508
+
1509
+ def Onmenusim2D(self, event: wx.MenuEvent):
1510
+ """ Action to perform whern menu 2D entry is selected """
1511
+
1512
+ id = event.GetId()
1513
+ item = self.menubar.FindItemById(event.GetId())
1514
+
1515
+ if item is None:
1516
+ return
1517
+
1518
+ itemlabel = item.ItemLabel
1519
+
1520
+ from .PyGui import Wolf2DModel
1521
+
1522
+ if not isinstance(self.wolfparent, Wolf2DModel):
1523
+ logging.error(_('This is not a 2D model'))
1524
+ return
1525
+
1526
+ self.wolfparent:Wolf2DModel
1527
+
1528
+ if itemlabel == _('Update .bloc file'):
1529
+
1530
+ msg = _('If you continue the .bloc file will be relpaced !')+'\n'
1531
+ msg += '\n'
1532
+ msg += _('Continue ?')+'\n'
1533
+
1534
+ dlg = wx.MessageDialog(self,msg,caption = _('Attention'), style = wx.YES_NO)
1535
+ ret = dlg.ShowModal()
1536
+ dlg.Destroy()
1537
+ if ret == wx.ID_NO:
1538
+ return
1539
+
1540
+ self.wolfparent.write_bloc_file()
1541
+
1542
+ elif itemlabel == _('Reset mask of all arrays'):
1543
+
1544
+ self.wolfparent.sim.force_mask()
1545
+
1546
+ elif itemlabel == _('Convert zbin to hbin'):
1547
+
1548
+ if self.wolfparent.sim._zbin is not None:
1549
+ self.wolfparent.sim.zbin2hbin()
1550
+ self.wolfparent.sim.hbin.reset_plot()
1551
+
1552
+ elif itemlabel == _('Convert hbin to zbin'):
1553
+
1554
+ if self.wolfparent.sim._hbin is not None:
1555
+ self.wolfparent.sim.hbin2zbin()
1556
+ self.wolfparent.sim.zbin.reset_plot()
1557
+
1558
+ elif itemlabel == _('Convert zbinb to hbinb'):
1559
+
1560
+ if self.wolfparent.sim._zbinb is not None:
1561
+ self.wolfparent.sim.zbinb2hbinb()
1562
+ self.wolfparent.sim.hbinb.reset_plot()
1563
+
1564
+ elif itemlabel == _('Convert hbinb to zbinb'):
1565
+
1566
+ if self.wolfparent.sim._hbinb is not None:
1567
+ self.wolfparent.sim.hbinb2zbinb()
1568
+ self.wolfparent.sim.zbinb.reset_plot()
1569
+
1570
+ elif itemlabel == _("Transfer initial conditions..."):
1571
+
1572
+ if self.active_array is not None:
1573
+ from .PyGui import Wolf2DModel
1574
+ if isinstance(self.wolfparent,Wolf2DModel):
1575
+ self.wolfparent.transfer_ic(self.active_vector)
1576
+
1577
+ elif itemlabel == _("Parameters..."):
1578
+ self.wolfparent.show_properties()
1579
+
1580
+ elif itemlabel == _('Update free surface elevation - IC'):
1581
+
1582
+ if len(self.active_array.SelectionData.myselection)==0:
1583
+
1584
+ msg = _('There is none selected nodes in the active array !')+'\n'
1585
+ msg += '\n'
1586
+ msg += _('Please select the desired zone and retry !')+'\n'
1587
+
1588
+ logging.warning(msg)
1589
+ return
1590
+
1591
+ self.wolfparent.extend_freesurface_elevation(self.active_array.SelectionData.myselection)
1592
+
1593
+ elif itemlabel== _('Update roughness coeff'):
1594
+
1595
+ if len(self.active_array.SelectionData.myselection)==0:
1596
+
1597
+ msg = _('There is none selected nodes in the active array !')+'\n'
1598
+ msg += '\n'
1599
+ msg += _('Please select the desired zone and retry !')+'\n'
1600
+
1601
+ logging.warning(msg)
1602
+ return
1603
+
1604
+ self.wolfparent.extend_roughness(self.active_array.SelectionData.myselection)
1605
+
1606
+ # elif itemlabel == _('Update IC reading mode'):
1607
+
1608
+ # self.wolfparent.set_type_ic()
1609
+
1610
+ elif itemlabel == _('Update model from current mask'):
1611
+
1612
+ if type(self.active_array) not in [WolfArray]:
1613
+ msg = _('Please select a mono-block array !')+'\n'
1614
+ dlg=wx.MessageBox(msg,style=wx.OK)
1615
+ return
1616
+
1617
+ msg = _('If you continue, the mask of all arrays will be replaced by the current mask !')+'\n'
1618
+ msg += _('The external contour in the .bloc file will also be relpaced.')+'\n'
1619
+ msg += '\n'
1620
+ msg += _('Continue ?')+'\n'
1621
+
1622
+ dlg = wx.MessageDialog(self,msg,caption = _('Attention'), style = wx.YES_NO)
1623
+ ret = dlg.ShowModal()
1624
+ dlg.Destroy()
1625
+ if ret == wx.ID_NO:
1626
+ return
1627
+
1628
+ with wx.lib.busy.BusyInfo(_('Updating 2D model')):
1629
+ wait = wx.BusyCursor()
1630
+
1631
+ sux,suy,cont,interior = self.active_array.suxsuy_contour(self.wolfparent.filenamegen,True)
1632
+
1633
+ self.wolfparent.mimic_mask(self.active_array)
1634
+ self.wolfparent.replace_external_contour(cont,interior)
1635
+
1636
+ del wait
1637
+
1638
+ self.wolfparent.extend_bed_elevation()
993
1639
 
994
1640
  def get_configuration(self) -> Union[WolfConfiguration, None]:
1641
+ """ Get global configuration parameters """
1642
+
995
1643
  # At this point, I'm not too sure about
996
1644
  # which window/frame does what. So to be on
997
1645
  # the safe side, I make sure that the configuration
@@ -1085,10 +1733,10 @@ class WolfMapViewer(wx.Frame):
1085
1733
  self.add_object('vector', newobj=self.myinterp.myzones, ToCheck=False, id='Interp_mesh')
1086
1734
 
1087
1735
  if self.menuviewerinterpcs is None:
1088
- self.menuviewerinterpcs = self.toolsmenu.Append(wx.ID_ANY, _("New cloud Viewer..."),
1736
+ self.menuviewerinterpcs = self.cs_menu.Append(wx.ID_ANY, _("New cloud Viewer..."),
1089
1737
  _("Cloud viewer Interpolate"))
1090
1738
  if self.menuinterpcs is None:
1091
- self.menuinterpcs = self.toolsmenu.Append(wx.ID_ANY, _("Interpolate on active array..."), _("Interpolate"))
1739
+ self.menuinterpcs = self.cs_menu.Append(wx.ID_ANY, _("Interpolate on active array..."), _("Interpolate"))
1092
1740
 
1093
1741
  def interpolate_cloud(self):
1094
1742
  """
@@ -1748,6 +2396,8 @@ class WolfMapViewer(wx.Frame):
1748
2396
  self.all_lists = [self.myarrays, self.myvectors, self.myclouds, self.mytri, self.myothers, self.myviews, self.myres2D, self.mytiles, self.mypartsystems, self.myviewers3d]
1749
2397
 
1750
2398
  if self.get_configuration() is not None:
2399
+ # see PyGui.py if necessary
2400
+
1751
2401
  self.menu_options = wx.Menu()
1752
2402
  self.menubar.Append(self.menu_options, _('Options'))
1753
2403
  self.option_global = self.menu_options.Append(wx.ID_ANY,_("Global"),_("Modify global options"))
@@ -1809,9 +2459,30 @@ class WolfMapViewer(wx.Frame):
1809
2459
  mydiag = wx.MessageDialog(self, msg, _('Sort along'))
1810
2460
  mydiag.ShowModal()
1811
2461
 
2462
+ def center_view_on(self, cx, cy):
2463
+ """
2464
+ Center the view on the point of (map) coordinates (x,y)
2465
+ """
2466
+
2467
+ self.mousex, self.mousey = cx, cy
2468
+
2469
+ # retrouve la taille de la fenêtre OpenGL
2470
+ width, height = self.canvas.GetSize()
2471
+
2472
+ # calcule la taille selon X et Y en coordonnées réelles
2473
+ width = width / self.sx
2474
+ height = height / self.sy
2475
+
2476
+ # retrouve les bornes min et max sur base de la valeur centrale qui est censée ne pas bouger
2477
+ self.xmin = self.mousex - width / 2.
2478
+ self.xmax = self.xmin + width
2479
+ self.ymin = self.mousey - height / 2.
2480
+ self.ymax = self.ymin + height
2481
+
1812
2482
  def setbounds(self,updatescale=True):
1813
2483
  """
1814
- Calcule les limites visibles de la fenêtrte graphique sur base des facteurs d'échelle courants
2484
+ Calcule les limites visibles de la fenêtrte graphique sur base des
2485
+ facteurs d'échelle courants
1815
2486
  """
1816
2487
 
1817
2488
  if updatescale:
@@ -1858,7 +2529,11 @@ class WolfMapViewer(wx.Frame):
1858
2529
  self.canvas.SetClientSize(width, height)
1859
2530
 
1860
2531
  def updatescalefactors(self):
1861
- """ Mise à jour des facteurs d'échelle """
2532
+ """ Mise à jour des facteurs d'échelle
2533
+ This one updates the scale factors based on the relative sizes
2534
+ of the GLCanvas and the footprint that should fit in it.
2535
+ """
2536
+
1862
2537
  width, height = self.canvas.GetSize()
1863
2538
 
1864
2539
  self.sx = 1
@@ -1873,6 +2548,7 @@ class WolfMapViewer(wx.Frame):
1873
2548
 
1874
2549
  def add_viewer_and_link(self):
1875
2550
  """ Ajout d'une nouvelle fenêtre de visualisation et liaison avec la fenêtre courante """
2551
+
1876
2552
  dlg = wx.TextEntryDialog(self, _('Enter a caption for the new window'))
1877
2553
 
1878
2554
  ret = dlg.ShowModal()
@@ -1901,6 +2577,7 @@ class WolfMapViewer(wx.Frame):
1901
2577
 
1902
2578
  def add_grid(self):
1903
2579
  """ Ajout d'une grille """
2580
+
1904
2581
  mygrid = Grid(1000.)
1905
2582
  self.add_object('vector', newobj=mygrid, ToCheck=False, id='Grid')
1906
2583
 
@@ -2464,6 +3141,91 @@ class WolfMapViewer(wx.Frame):
2464
3141
  if cur is not self:
2465
3142
  cur.update()
2466
3143
 
3144
+ def zoom_on_id(self, id:str, draw_type:draw_type = draw_type.ARRAYS, forceupdate=True, canvas_height=1024):
3145
+ """
3146
+ Zoom on id
3147
+
3148
+ :param id: id of the object to zoom on
3149
+ :param drawtype: type of object to zoom on - Different types elements can have the same id
3150
+
3151
+ """
3152
+
3153
+ if draw_type not in [draw_type.ARRAYS, draw_type.VECTORS]:
3154
+ logging.warning(_('Draw type must be either ARRAYS or VECTORS'))
3155
+ return
3156
+
3157
+ obj = self.get_obj_from_id(id, draw_type)
3158
+
3159
+ if obj is None:
3160
+ logging.warning(_('No object found with id {} and drawtype {}'.format(id, draw_type)))
3161
+ return
3162
+
3163
+ if draw_type == draw_type.ARRAYS:
3164
+ self.zoom_on_array(obj, forceupdate=forceupdate, canvas_height=canvas_height)
3165
+ elif draw_type == draw_type.VECTORS:
3166
+ self.zoom_on_vector(obj, forceupdate=forceupdate, canvas_height=canvas_height)
3167
+
3168
+ def zoom_on_array(self, array:WolfArray, forceupdate=True, canvas_height=1024):
3169
+ """ Zoom on array """
3170
+
3171
+ if array.xmin == -99999:
3172
+ array.find_minmax()
3173
+
3174
+ bounds = array.get_bounds()
3175
+
3176
+ center = [(bounds[0][1] + bounds[0][0]) / 2., (bounds[1][1] + bounds[1][0]) / 2.]
3177
+ width = bounds[0][1] - bounds[0][0]
3178
+ height = bounds[1][1] - bounds[1][0]
3179
+
3180
+ self.zoom_on({'center':center, 'width':width, 'height':height}, forceupdate=forceupdate, canvas_height=canvas_height)
3181
+
3182
+ def zoom_on_vector(self, vector:vector, forceupdate=True, canvas_height=1024):
3183
+ """ Zoom on vector """
3184
+
3185
+ if vector.xmin == -99999:
3186
+ vector.find_minmax()
3187
+
3188
+ bounds = vector.get_bounds_xx_yy()
3189
+
3190
+ center = [(bounds[0][1] + bounds[0][0]) / 2., (bounds[1][1] + bounds[1][0]) / 2.]
3191
+ width = bounds[0][1] - bounds[0][0]
3192
+ height = bounds[1][1] - bounds[1][0]
3193
+
3194
+ self.zoom_on({'center':center, 'width':width, 'height':height}, forceupdate=forceupdate, canvas_height=canvas_height)
3195
+
3196
+ def create_Zones_from_arrays(self, arrays:list[WolfArray], id:str = None, add_legend:bool=True) -> Zones:
3197
+ """
3198
+ Create a Zones instance from list of WolfArrays
3199
+
3200
+ One zone per array.
3201
+
3202
+ One vector per zone with the masked contour.
3203
+
3204
+ :param arrays: list of WolfArrays
3205
+ :param id: id of the Zones instance
3206
+ :param add_legend: add legend to the vector -- centroid of the contour
3207
+
3208
+ """
3209
+
3210
+ # création de l'instance de Zones
3211
+ new_zones = Zones(idx = 'contour' if id is None else id.lower(), mapviewer=self)
3212
+
3213
+ for curarray in arrays:
3214
+
3215
+ if isinstance(curarray, WolfArray):
3216
+ new_zone = zone(name = curarray.idx)
3217
+ new_zones.add_zone(new_zone, forceparent=True)
3218
+
3219
+ sux, sux, curvect, interior = curarray.suxsuy_contour()
3220
+ new_zone.add_vector(curvect, forceparent=True)
3221
+ curvect.set_legend_to_centroid(curarray.idx)
3222
+ logging.info(_('{} treated'.format(curarray.idx)))
3223
+ else:
3224
+ logging.warning(_('All elements in the list must be of type WolfArray'))
3225
+
3226
+ return new_zones
3227
+
3228
+
2467
3229
  def zoom_on(self, zoom_dict = None, width = 500, height = 500, center = None, xll = None, yll = None, forceupdate=True, canvas_height=1024):
2468
3230
  """
2469
3231
  Zoom on a specific area
@@ -2543,7 +3305,7 @@ class WolfMapViewer(wx.Frame):
2543
3305
  if cur is not self:
2544
3306
  cur.update()
2545
3307
 
2546
- def zoomon_active_profile(self, size:float=500., forceupdate:bool=True):
3308
+ def zoom_on_active_profile(self, size:float=500., forceupdate:bool=True):
2547
3309
  """ Zoom on active profile """
2548
3310
 
2549
3311
  curvec = self.active_profile
@@ -3122,123 +3884,49 @@ class WolfMapViewer(wx.Frame):
3122
3884
  dlg.Destroy()
3123
3885
 
3124
3886
  if idx == 0:
3125
- laz_source = self.mylazdata
3126
- else:
3127
- laz_source = self.mylazgrid
3128
-
3129
- return laz_source
3130
-
3131
- def OnMenubar(self, event: wx.MenuEvent):
3132
- """
3133
- Gestion des clicks sur le menu quel que soit le niveau
3134
-
3135
- Idée générale :
3136
- - récupérer le label du menu sur base de l'id de l'event WX passé en argument --> itemlabel
3137
- - tester le label du menu sur base de la chaîne traduite
3138
- - a priori appeler une autre routine spécifique au traitement choisi
3139
- - éviter autant que possible de coder des fonctions directement dans cette routine ce qui la rendrait complexe à lire
3140
-
3141
- AUTRE POSSIBILITE:
3142
- - mettre en place un dictionnaire avec key==label, value==action qui se contenterait de tester la présence du label dans les clés et d'appeler l'action
3143
- - dans ce dernier cas, il faudrait que les routines possèdent idéalement une interface unique
3144
- """
3145
- id = event.GetId()
3146
- item = self.menubar.FindItemById(event.GetId())
3147
-
3148
- if item is None:
3149
- return
3150
-
3151
- itemlabel = item.ItemLabel
3152
-
3153
- autoscale = True
3154
-
3155
- if id == wx.ID_OPEN:
3156
- filterProject = "proj (*.proj)|*.proj|param (*.param)|*.param|all (*.*)|*.*"
3157
- file = wx.FileDialog(self, "Choose file", wildcard=filterProject)
3158
- if file.ShowModal() == wx.ID_CANCEL:
3159
- file.Destroy()
3160
- return
3161
- else:
3162
- # récuparétaion du nom de fichier avec chemin d'accès
3163
- filename = file.GetPath()
3164
- file.Destroy()
3165
-
3166
- os.chdir(os.path.dirname(filename))
3167
- self.read_project(filename)
3168
-
3169
- elif itemlabel == _('Update .bloc file'):
3170
-
3171
- msg = _('If you continue the .bloc file will be relpaced !')+'\n'
3172
- msg += '\n'
3173
- msg += _('Continue ?')+'\n'
3174
-
3175
- dlg = wx.MessageDialog(self,msg,caption = _('Attention'), style = wx.YES_NO)
3176
- ret = dlg.ShowModal()
3177
- dlg.Destroy()
3178
- if ret == wx.ID_NO:
3179
- return
3180
-
3181
- self.wolfparent.write_bloc_file()
3182
-
3183
- elif itemlabel == _('Update free surface elevation - IC'):
3184
-
3185
- if len(self.active_array.mngselection.myselection)==0:
3186
-
3187
- msg = _('There is none selected nodes in the active array !')+'\n'
3188
- msg += '\n'
3189
- msg += _('Please select the desired zone and retry !')+'\n'
3190
-
3191
- logging.warning(msg)
3192
- return
3193
-
3194
- self.wolfparent.extend_freesurface_elevation(self.active_array.mngselection.myselection)
3195
-
3196
- elif itemlabel== _('Update roughness coeff'):
3197
-
3198
- if len(self.active_array.mngselection.myselection)==0:
3199
-
3200
- msg = _('There is none selected nodes in the active array !')+'\n'
3201
- msg += '\n'
3202
- msg += _('Please select the desired zone and retry !')+'\n'
3203
-
3204
- logging.warning(msg)
3205
- return
3206
-
3207
- self.wolfparent.extend_roughness(self.active_array.mngselection.myselection)
3208
-
3209
- elif itemlabel == _('Update IC reading mode'):
3210
-
3211
- self.wolfparent.set_type_ic()
3887
+ laz_source = self.mylazdata
3888
+ else:
3889
+ laz_source = self.mylazgrid
3212
3890
 
3213
- elif itemlabel == _('Update model from current mask'):
3891
+ return laz_source
3214
3892
 
3215
- if type(self.active_array) != WolfArray_Sim2D:
3216
- msg = _('Please select a mono-block array !')+'\n'
3217
- dlg=wx.MessageBox(msg,style=wx.OK)
3218
- return
3893
+ def OnMenubar(self, event: wx.MenuEvent):
3894
+ """
3895
+ Gestion des clicks sur le menu quel que soit le niveau
3219
3896
 
3220
- msg = _('If you continue, the mask of all arrays will be replaced by the current mask !')+'\n'
3221
- msg += _('The external contour in the .bloc file will also be relpaced.')+'\n'
3222
- msg += '\n'
3223
- msg += _('Continue ?')+'\n'
3897
+ Idée générale :
3898
+ - récupérer le label du menu sur base de l'id de l'event WX passé en argument --> itemlabel
3899
+ - tester le label du menu sur base de la chaîne traduite
3900
+ - a priori appeler une autre routine spécifique au traitement choisi
3901
+ - éviter autant que possible de coder des fonctions directement dans cette routine ce qui la rendrait complexe à lire
3224
3902
 
3225
- dlg = wx.MessageDialog(self,msg,caption = _('Attention'), style = wx.YES_NO)
3226
- ret = dlg.ShowModal()
3227
- dlg.Destroy()
3228
- if ret == wx.ID_NO:
3229
- return
3903
+ AUTRE POSSIBILITE:
3904
+ - mettre en place un dictionnaire avec key==label, value==action qui se contenterait de tester la présence du label dans les clés et d'appeler l'action
3905
+ - dans ce dernier cas, il faudrait que les routines possèdent idéalement une interface unique
3906
+ """
3907
+ id = event.GetId()
3908
+ item = self.menubar.FindItemById(event.GetId())
3230
3909
 
3231
- with wx.lib.busy.BusyInfo(_('Updating 2D model')):
3232
- wait = wx.BusyCursor()
3910
+ if item is None:
3911
+ return
3233
3912
 
3234
- sux,suy,cont,interior = self.active_array.suxsuy_contour(self.wolfparent.filenamegen,True)
3913
+ itemlabel = item.ItemLabel
3235
3914
 
3236
- self.wolfparent.mimic_mask(self.active_array)
3237
- self.wolfparent.replace_external_contour(cont,interior)
3915
+ autoscale = True
3238
3916
 
3239
- del wait
3917
+ if id == wx.ID_OPEN:
3918
+ filterProject = "proj (*.proj)|*.proj|param (*.param)|*.param|all (*.*)|*.*"
3919
+ file = wx.FileDialog(self, "Choose file", wildcard=filterProject)
3920
+ if file.ShowModal() == wx.ID_CANCEL:
3921
+ file.Destroy()
3922
+ return
3923
+ else:
3924
+ # récuparétaion du nom de fichier avec chemin d'accès
3925
+ filename = file.GetPath()
3926
+ file.Destroy()
3240
3927
 
3241
- self.wolfparent.extend_bed_elevation()
3928
+ os.chdir(os.path.dirname(filename))
3929
+ self.read_project(filename)
3242
3930
 
3243
3931
  elif itemlabel == _('Shortcuts'):
3244
3932
  # show shortcuts in log
@@ -3297,7 +3985,7 @@ class WolfMapViewer(wx.Frame):
3297
3985
  elif unknown == _('Head'):
3298
3986
  unknown = 'head'
3299
3987
 
3300
- fig, ax = self.active_res2d.plot_h(self.active_res2d.mngselection.myselection,
3988
+ fig, ax = self.active_res2d.plot_h(self.active_res2d.SelectionData.myselection,
3301
3989
  unknown, toshow=True)
3302
3990
 
3303
3991
  elif itemlabel == _("Plot stats unknown (inside active vector)..."):
@@ -3532,141 +4220,141 @@ class WolfMapViewer(wx.Frame):
3532
4220
  ax.legend()
3533
4221
  fig.show()
3534
4222
 
3535
- elif itemlabel == _("Change current view"):
3536
-
3537
- # Change view for results
3538
-
3539
- autoscale = False
3540
- choices = [cur.value for cur in views_2D]
3541
- dlg = wx.SingleChoiceDialog(None, _("Pick a view"), "Choices", choices)
3542
- ret = dlg.ShowModal()
3543
- if ret == wx.ID_CANCEL:
3544
- dlg.Destroy()
3545
- return
3546
-
3547
- method = dlg.GetStringSelection()
3548
-
3549
- method = list(views_2D)[choices.index(method)]
3550
-
3551
- dlg.Destroy()
3552
-
3553
- diamsize = None
3554
- if method == views_2D.SHIELDS_NUMBER :
3555
-
3556
- if self.active_res2d is not None:
3557
- sediment_diam = self.active_res2d.sediment_diameter
3558
- sediment_density = self.active_res2d.sediment_density
3559
- elif self.compare_results is not None:
3560
- sediment_diam = 0.001
3561
- sediment_density = 2.650
3562
- else:
3563
- logging.warning(_('No active 2D result or comparison !'))
3564
- return
3565
-
3566
- dlg = wx.TextEntryDialog(None,_("Diameter grain size [m] ?"), value = str(sediment_diam))
3567
- ret = dlg.ShowModal()
3568
- if ret == wx.ID_CANCEL:
3569
- dlg.Destroy()
3570
- return
3571
- try:
3572
- diamsize = float(dlg.GetValue())
3573
- except:
3574
- dlg.Destroy()
3575
- logging.warning(_("Bad value -- Rety"))
3576
- return
3577
-
3578
- dlg = wx.TextEntryDialog(None,_("Density grain [-] ?"), value = str(sediment_density))
3579
- ret = dlg.ShowModal()
3580
- if ret == wx.ID_CANCEL:
3581
- dlg.Destroy()
3582
- return
3583
- try:
3584
- density = float(dlg.GetValue())
3585
- except:
3586
- dlg.Destroy()
3587
- logging.warning(_("Bad value -- Rety"))
3588
- return
3589
-
3590
- if len(self.myres2D)>1:
3591
-
3592
- dlg = wx.MessageDialog(None, _('Apply to all results?'), style=wx.YES_NO)
3593
- ret = dlg.ShowModal()
3594
- if ret == wx.ID_NO:
3595
- if diamsize is not None:
3596
- self.active_res2d.sediment_diameter = diamsize
3597
- self.active_res2d.sediment_density = density
3598
- self.active_res2d.load_default_colormap('shields_cst')
3599
-
3600
- self.active_res2d.set_currentview(method, force_wx = True, force_updatepal = True)
3601
- else:
3602
- for curarray in self.iterator_over_objects(draw_type.RES2D):
3603
- curarray:Wolfresults_2D
3604
- if diamsize is not None:
3605
- curarray.sediment_diameter = diamsize
3606
- curarray.sediment_density = density
3607
- curarray.load_default_colormap('shields_cst')
3608
-
3609
- curarray.set_currentview(method, force_wx = True, force_updatepal = True)
3610
-
3611
- else:
3612
- if self.active_res2d is not None:
3613
- if diamsize is not None:
3614
- self.active_res2d.sediment_diameter = diamsize
3615
- self.active_res2d.sediment_density = density
3616
- self.active_res2d.load_default_colormap('shields_cst')
3617
- self.active_res2d.set_currentview(method, force_wx = True, force_updatepal = True)
3618
-
3619
- if self.compare_results is not None:
3620
- # update compare results
3621
- if diamsize is not None:
3622
- self.compare_results.set_shields_param(diamsize, density)
3623
- self.compare_results.update_type_result(method)
3624
-
3625
- elif itemlabel == _("Read last result"):
3626
-
3627
- self.read_last_result()
3628
-
3629
- elif itemlabel == _("Filter independent"):
3630
-
3631
- self.menu_filter_independent.IsChecked = not self.menu_filter_independent.IsChecked
3632
-
3633
- for curmodel in self.iterator_over_objects(draw_type.RES2D):
3634
- curmodel: Wolfresults_2D
3635
- curmodel.to_filter_independent = not self.menu_filter_independent.IsChecked
3636
-
3637
- elif itemlabel == _("Set epsilon water depth"):
3638
-
3639
- dlg = wx.TextEntryDialog(self, _('Enter an epsilon [m]'),value='0.0')
3640
-
3641
- ret = dlg.ShowModal()
3642
-
3643
- if ret == wx.ID_CANCEL:
3644
- dlg.Destroy()
3645
- return
3646
-
3647
- try:
3648
- neweps = float(dlg.GetValue())
3649
- dlg.Destroy()
3650
- except:
3651
- logging.error(_('Bad value -- retry !'))
3652
- dlg.Destroy()
3653
- return
3654
-
3655
- for curmodel in self.iterator_over_objects(draw_type.RES2D):
3656
- curmodel: Wolfresults_2D
3657
- curmodel.epsilon = neweps
3658
- curmodel._epsilon_default = neweps
3659
- curmodel.read_oneresult(curmodel.current_result)
3660
- curmodel.set_currentview()
3661
-
3662
- elif itemlabel == _("Manage boundary conditions..."):
3663
-
3664
- if self.active_res2d is not None:
3665
- self.active_res2d.myparams.editing_bc(self.myres2D)
3666
-
3667
- elif itemlabel ==_("Create video..."):
3668
- if self.active_res2d is not None:
3669
- self.create_video()
4223
+ # elif itemlabel == _("Change current view"):
4224
+
4225
+ # # Change view for results
4226
+
4227
+ # autoscale = False
4228
+ # choices = [cur.value for cur in views_2D]
4229
+ # dlg = wx.SingleChoiceDialog(None, _("Pick a view"), "Choices", choices)
4230
+ # ret = dlg.ShowModal()
4231
+ # if ret == wx.ID_CANCEL:
4232
+ # dlg.Destroy()
4233
+ # return
4234
+
4235
+ # method = dlg.GetStringSelection()
4236
+
4237
+ # method = list(views_2D)[choices.index(method)]
4238
+
4239
+ # dlg.Destroy()
4240
+
4241
+ # diamsize = None
4242
+ # if method == views_2D.SHIELDS_NUMBER :
4243
+
4244
+ # if self.active_res2d is not None:
4245
+ # sediment_diam = self.active_res2d.sediment_diameter
4246
+ # sediment_density = self.active_res2d.sediment_density
4247
+ # elif self.compare_results is not None:
4248
+ # sediment_diam = 0.001
4249
+ # sediment_density = 2.650
4250
+ # else:
4251
+ # logging.warning(_('No active 2D result or comparison !'))
4252
+ # return
4253
+
4254
+ # dlg = wx.TextEntryDialog(None,_("Diameter grain size [m] ?"), value = str(sediment_diam))
4255
+ # ret = dlg.ShowModal()
4256
+ # if ret == wx.ID_CANCEL:
4257
+ # dlg.Destroy()
4258
+ # return
4259
+ # try:
4260
+ # diamsize = float(dlg.GetValue())
4261
+ # except:
4262
+ # dlg.Destroy()
4263
+ # logging.warning(_("Bad value -- Rety"))
4264
+ # return
4265
+
4266
+ # dlg = wx.TextEntryDialog(None,_("Density grain [-] ?"), value = str(sediment_density))
4267
+ # ret = dlg.ShowModal()
4268
+ # if ret == wx.ID_CANCEL:
4269
+ # dlg.Destroy()
4270
+ # return
4271
+ # try:
4272
+ # density = float(dlg.GetValue())
4273
+ # except:
4274
+ # dlg.Destroy()
4275
+ # logging.warning(_("Bad value -- Rety"))
4276
+ # return
4277
+
4278
+ # if len(self.myres2D)>1:
4279
+
4280
+ # dlg = wx.MessageDialog(None, _('Apply to all results?'), style=wx.YES_NO)
4281
+ # ret = dlg.ShowModal()
4282
+ # if ret == wx.ID_NO:
4283
+ # if diamsize is not None:
4284
+ # self.active_res2d.sediment_diameter = diamsize
4285
+ # self.active_res2d.sediment_density = density
4286
+ # self.active_res2d.load_default_colormap('shields_cst')
4287
+
4288
+ # self.active_res2d.set_currentview(method, force_wx = True, force_updatepal = True)
4289
+ # else:
4290
+ # for curarray in self.iterator_over_objects(draw_type.RES2D):
4291
+ # curarray:Wolfresults_2D
4292
+ # if diamsize is not None:
4293
+ # curarray.sediment_diameter = diamsize
4294
+ # curarray.sediment_density = density
4295
+ # curarray.load_default_colormap('shields_cst')
4296
+
4297
+ # curarray.set_currentview(method, force_wx = True, force_updatepal = True)
4298
+
4299
+ # else:
4300
+ # if self.active_res2d is not None:
4301
+ # if diamsize is not None:
4302
+ # self.active_res2d.sediment_diameter = diamsize
4303
+ # self.active_res2d.sediment_density = density
4304
+ # self.active_res2d.load_default_colormap('shields_cst')
4305
+ # self.active_res2d.set_currentview(method, force_wx = True, force_updatepal = True)
4306
+
4307
+ # if self.compare_results is not None:
4308
+ # # update compare results
4309
+ # if diamsize is not None:
4310
+ # self.compare_results.set_shields_param(diamsize, density)
4311
+ # self.compare_results.update_type_result(method)
4312
+
4313
+ # elif itemlabel == _("Read last result"):
4314
+
4315
+ # self.read_last_result()
4316
+
4317
+ # elif itemlabel == _("Filter independent"):
4318
+
4319
+ # self.menu_filter_independent.IsChecked = not self.menu_filter_independent.IsChecked
4320
+
4321
+ # for curmodel in self.iterator_over_objects(draw_type.RES2D):
4322
+ # curmodel: Wolfresults_2D
4323
+ # curmodel.to_filter_independent = not self.menu_filter_independent.IsChecked
4324
+
4325
+ # elif itemlabel == _("Set epsilon water depth"):
4326
+
4327
+ # dlg = wx.TextEntryDialog(self, _('Enter an epsilon [m]'),value='0.0')
4328
+
4329
+ # ret = dlg.ShowModal()
4330
+
4331
+ # if ret == wx.ID_CANCEL:
4332
+ # dlg.Destroy()
4333
+ # return
4334
+
4335
+ # try:
4336
+ # neweps = float(dlg.GetValue())
4337
+ # dlg.Destroy()
4338
+ # except:
4339
+ # logging.error(_('Bad value -- retry !'))
4340
+ # dlg.Destroy()
4341
+ # return
4342
+
4343
+ # for curmodel in self.iterator_over_objects(draw_type.RES2D):
4344
+ # curmodel: Wolfresults_2D
4345
+ # curmodel.epsilon = neweps
4346
+ # curmodel._epsilon_default = neweps
4347
+ # curmodel.read_oneresult(curmodel.current_result)
4348
+ # curmodel.set_currentview()
4349
+
4350
+ # elif itemlabel == _("Manage boundary conditions..."):
4351
+
4352
+ # if self.active_res2d is not None:
4353
+ # self.active_res2d.myparams.editing_bc(self.myres2D)
4354
+
4355
+ # elif itemlabel ==_("Create video..."):
4356
+ # if self.active_res2d is not None:
4357
+ # self.create_video()
3670
4358
 
3671
4359
  elif itemlabel == _("Setup cache..."):
3672
4360
 
@@ -3737,13 +4425,6 @@ class WolfMapViewer(wx.Frame):
3737
4425
 
3738
4426
  self.active_res2d.show_tiles()
3739
4427
 
3740
- elif itemlabel == _("Transfer initial conditions..."):
3741
-
3742
- if self.active_array is not None:
3743
- from .PyGui import Wolf2DModel
3744
- if isinstance(self.wolfparent,Wolf2DModel):
3745
- self.wolfparent.transfer_ic(self.active_vector)
3746
-
3747
4428
  elif itemlabel == _("Manage banks..."):
3748
4429
  if self.active_vector is None:
3749
4430
  msg = _('Active vector is None\nPlease activate the one desired')
@@ -3802,6 +4483,12 @@ class WolfMapViewer(wx.Frame):
3802
4483
  elif itemlabel==_("Compare triangles to array..."):
3803
4484
  self.compare_tri2array()
3804
4485
 
4486
+ elif itemlabel == _("Create contour from checked arrays..."):
4487
+
4488
+ # Create contour from checked arrays and add it to the list of objects
4489
+ newzones = self.create_Zones_from_arrays(self.get_list_objects(draw_type.ARRAYS, checked_state=True))
4490
+ self.add_object('vector', newobj=newzones, ToCheck=True, id='Contours from arrays')
4491
+
3805
4492
  elif itemlabel == _("Create bridge and export gltf..."):
3806
4493
 
3807
4494
  if self.active_cs is None:
@@ -3998,22 +4685,13 @@ class WolfMapViewer(wx.Frame):
3998
4685
 
3999
4686
  pass
4000
4687
 
4001
- elif itemlabel == _('Check 2D simulation headers'):
4002
-
4003
- # Check 2D simulation
4004
- dlg = wx.FileDialog(self, _("Choose 2D simulation file"), wildcard="all (*.*)|*.*", style=wx.FD_OPEN)
4005
- if dlg.ShowModal() == wx.ID_CANCEL:
4006
- dlg.Destroy()
4007
- return
4008
-
4009
- filename = dlg.GetPath()
4010
- dlg.Destroy()
4688
+ elif itemlabel == _('Create/Open multiblock model'):
4011
4689
 
4012
- from .mesh2d.wolf2dprev import prev_sim2D
4690
+ self.create_2D_MB_model()
4013
4691
 
4014
- sim = prev_sim2D(filename)
4015
- sim.verify_files()
4692
+ elif itemlabel == _('Check headers'):
4016
4693
 
4694
+ self.check_2D_MB_headers()
4017
4695
 
4018
4696
  elif itemlabel == _('Set comparison'):
4019
4697
 
@@ -4417,14 +5095,19 @@ class WolfMapViewer(wx.Frame):
4417
5095
  self.Autoscale()
4418
5096
 
4419
5097
  def pop_boundary_manager(self, which:BcManager):
4420
- """ pop a boundary manager after Destroying """
5098
+ """ Pop a boundary condition manager after Destroying """
5099
+
4421
5100
  idx = self.mybc.index(which)
4422
5101
  if self.active_bc is which:
4423
5102
  self.active_bc = None
4424
5103
  self.mybc.pop(idx)
4425
5104
 
5105
+ self.Refresh()
5106
+
5107
+
4426
5108
  def get_boundary_manager(self, which:WolfArray):
4427
- """ get a boundary manager """
5109
+ """ Get a boundary manager """
5110
+
4428
5111
  for curbc in self.mybc:
4429
5112
  if curbc.linked_array is which:
4430
5113
  return curbc
@@ -4835,6 +5518,7 @@ class WolfMapViewer(wx.Frame):
4835
5518
  logging.warning("Warning : the following file is not present here : " + filename)
4836
5519
  return -1
4837
5520
 
5521
+ curtree = None
4838
5522
  if which.lower() == 'array' or which.lower() == 'array_crop':
4839
5523
  curdict = self.myarrays
4840
5524
  curtree = self.myitemsarray
@@ -4941,9 +5625,9 @@ class WolfMapViewer(wx.Frame):
4941
5625
  newobj.dx = tmpdx
4942
5626
  newobj.dy = tmpdy
4943
5627
 
4944
- if newobj.mngselection is not None:
4945
- newobj.mngselection.dx = tmpdx
4946
- newobj.mngselection.dy = tmpdy
5628
+ if newobj.SelectionData is not None:
5629
+ newobj.SelectionData.dx = tmpdx
5630
+ newobj.SelectionData.dy = tmpdy
4947
5631
 
4948
5632
  if cropini[0][0] != 99999. and cropini[1][0]!=99999.:
4949
5633
  newobj.origx = cropini[0][0]
@@ -5370,13 +6054,16 @@ class WolfMapViewer(wx.Frame):
5370
6054
 
5371
6055
  newobj.idx = id.lower()
5372
6056
 
5373
- myitem = self.treelist.AppendItem(curtree, id, data=newobj)
6057
+ if curtree is not None:
6058
+ myitem = self.treelist.AppendItem(curtree, id, data=newobj)
5374
6059
 
5375
- if ToCheck:
5376
- self.treelist.CheckItem(myitem)
5377
- self.treelist.CheckItem(self.treelist.GetItemParent(myitem))
6060
+ if ToCheck:
6061
+ self.treelist.CheckItem(myitem)
6062
+ self.treelist.CheckItem(self.treelist.GetItemParent(myitem))
5378
6063
 
5379
- newobj.check_plot()
6064
+ newobj.check_plot()
6065
+ else:
6066
+ logging.info(f'No tree item for this object {newobj.idx}')
5380
6067
 
5381
6068
  # curdict[id.lower()] = newobj
5382
6069
  if filename != '':
@@ -5395,6 +6082,7 @@ class WolfMapViewer(wx.Frame):
5395
6082
 
5396
6083
  def get_obj_from_treeitem(self, treeitem):
5397
6084
  """ Find the object associated with treeitem """
6085
+
5398
6086
  return self.treelist.GetItemData(treeitem)
5399
6087
 
5400
6088
  def getobj_from_id(self, id: str):
@@ -5409,6 +6097,24 @@ class WolfMapViewer(wx.Frame):
5409
6097
  except:
5410
6098
  return None
5411
6099
 
6100
+ def get_obj_from_id(self, id: str, drawtype: draw_type):
6101
+ """ Find the object associated with id in a specifid drawtype
6102
+
6103
+ If you want to search in all drawtypes, use getobj_from_id instead.
6104
+
6105
+ :param id: str : id of the object
6106
+ :param drawtype: draw_type : type of object to search
6107
+
6108
+ """
6109
+
6110
+ keys = self.get_list_keys(draw_type, checked_state=None)
6111
+ if id.lower() in keys:
6112
+ try:
6113
+ idx = keys.index(id.lower())
6114
+ return self.get_list_objects(draw_type, checked_state=None)[idx]
6115
+ except:
6116
+ return None
6117
+
5412
6118
  def _get_list(self, drawing_type:draw_type):
5413
6119
  """ return the list of objects of type drawing_type """
5414
6120
 
@@ -5455,6 +6161,7 @@ class WolfMapViewer(wx.Frame):
5455
6161
 
5456
6162
  def get_list_keys(self, drawing_type:draw_type, checked_state:bool=True):
5457
6163
  """ Create a list of keys of type draw_type """
6164
+
5458
6165
  if checked_state is None:
5459
6166
  return [curobj.idx for curobj in self._get_list(drawing_type)]
5460
6167
  else:
@@ -5462,6 +6169,7 @@ class WolfMapViewer(wx.Frame):
5462
6169
 
5463
6170
  def get_list_objects(self, drawing_type:draw_type, checked_state:bool=True):
5464
6171
  """ Create a list of objects of type draw_type """
6172
+
5465
6173
  if checked_state is None:
5466
6174
  return [curobj for curobj in self._get_list(drawing_type)]
5467
6175
  else:
@@ -5683,7 +6391,7 @@ class WolfMapViewer(wx.Frame):
5683
6391
 
5684
6392
  if text == _('Save'):
5685
6393
  if self.selected_object is not None:
5686
- if type(self.selected_object) is WolfArray or type(self.selected_object) is WolfArray_Sim2D:
6394
+ if issubclass(type(self.selected_object), WolfArray):
5687
6395
  self.selected_object.write_all()
5688
6396
  elif type(self.selected_object) is Zones:
5689
6397
  self.selected_object.saveas()
@@ -5721,7 +6429,7 @@ class WolfMapViewer(wx.Frame):
5721
6429
  newlab = dlg.GetValue()
5722
6430
  dlg.Destroy()
5723
6431
 
5724
- if isinstance(self.selected_object, WolfArray) and (not type(self.selected_object) in [WolfArrayMB, WolfArrayMNAP, WolfArray_Sim2D]):
6432
+ if isinstance(self.selected_object, WolfArray) and (not type(self.selected_object) in [WolfArrayMB, WolfArrayMNAP]):
5725
6433
 
5726
6434
  curtype = self.selected_object.dtype
5727
6435
 
@@ -5778,7 +6486,7 @@ class WolfMapViewer(wx.Frame):
5778
6486
  # save objet to file, choosing the file name
5779
6487
 
5780
6488
  if self.selected_object is not None:
5781
- if type(self.selected_object) is WolfArray or type(self.selected_object) is WolfArray_Sim2D:
6489
+ if issubclass(type(self.selected_object), WolfArray):
5782
6490
  filterArray = "bin (*.bin)|*.bin|Geotif (*.tif)|*.tif|Numpy (*.npy)|*.npy|all (*.*)|*.*"
5783
6491
  fdlg = wx.FileDialog(self, "Choose file name for Array : " + self.selected_object.idx, wildcard=filterArray,
5784
6492
  style=wx.FD_SAVE)
@@ -5820,7 +6528,7 @@ class WolfMapViewer(wx.Frame):
5820
6528
  elif text == _('Properties'):
5821
6529
 
5822
6530
  myobj = self.selected_object
5823
- if type(myobj) in [WolfArray, WolfArray_Sim2D, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui]:
6531
+ if type(myobj) in [WolfArray, WolfArrayMB, WolfArrayMNAP, Zones, Wolfresults_2D, wolfres2DGPU, Particle_system, Picc_data, Cadaster_data, hydrometry_wolfgui]:
5824
6532
  myobj.show_properties()
5825
6533
 
5826
6534
  elif text == _('Boundary conditions'):
@@ -5828,6 +6536,41 @@ class WolfMapViewer(wx.Frame):
5828
6536
  if bc is not None:
5829
6537
  bc.Show()
5830
6538
 
6539
+ elif _('Convert to mono-block') in text:
6540
+
6541
+ if isinstance(self.selected_object, WolfArrayMB):
6542
+ mono = self.selected_object.as_WolfArray()
6543
+ self.add_object('array', newobj=mono, id=self.selected_object.idx + '_mono')
6544
+ logging.info(_('Mono-block created and added to the viewer'))
6545
+
6546
+ elif isinstance(self.selected_object, Wolfresults_2D):
6547
+ mono = self.selected_object.as_WolfArray()
6548
+
6549
+ if isinstance(mono, WolfArrayMB):
6550
+ mono = mono.as_WolfArray()
6551
+
6552
+ self.add_object('array', newobj=mono, id=self.selected_object.idx + '_mono')
6553
+ logging.info(_('Mono-block created and added to the viewer'))
6554
+
6555
+ else:
6556
+ logging.warning(_('Convert to mono-blocks not yet implemented for this type of object'))
6557
+
6558
+ elif _('Convert to multi-blocks') in text:
6559
+
6560
+ if isinstance(self.selected_object, Wolfresults_2D):
6561
+ mb = self.selected_object.as_WolfArray(force_mb=True)
6562
+
6563
+ if isinstance(mb, WolfArrayMB):
6564
+ logging.info(_('Multi-blocks created and added to the viewer'))
6565
+
6566
+ elif isinstance(mb, WolfArray):
6567
+ logging.warning(_('Mono-blocks created and added to the viewer -- Instead of multi-blocks as only one block was found'))
6568
+
6569
+ self.add_object('array', newobj=mb, id=self.selected_object.idx + '_mb')
6570
+ else:
6571
+ logging.warning(_('Convert to multi-blocks not yet implemented for this type of object'))
6572
+
6573
+
5831
6574
  def OnClose(self, event):
5832
6575
  nb = 0
5833
6576
  if self.linked:
@@ -5900,7 +6643,7 @@ class WolfMapViewer(wx.Frame):
5900
6643
  wx.LogMessage(str(ex))
5901
6644
  wx.MessageBox(str(ex), _("Error"), wx.ICON_ERROR)
5902
6645
  else:
5903
- if type(curobj) in [WolfArray, WolfArrayMB]:
6646
+ if issubclass(type(curobj), WolfArray):
5904
6647
  curobj.uncheck_plot(not ctrl,ctrl)
5905
6648
  else:
5906
6649
  curobj.uncheck_plot()
@@ -6095,7 +6838,7 @@ class WolfMapViewer(wx.Frame):
6095
6838
 
6096
6839
  #on met le profil en rouge et plus épais
6097
6840
  self.active_profile.color_active_profile()
6098
- self.zoomon_active_profile()
6841
+ self.zoom_on_active_profile()
6099
6842
 
6100
6843
  self.Paint()
6101
6844
 
@@ -6176,13 +6919,13 @@ class WolfMapViewer(wx.Frame):
6176
6919
 
6177
6920
  if 'results' in self.action:
6178
6921
  curobj:Wolfresults_2D
6179
- curobj = self.active_res2d.mngselection
6922
+ curobj = self.active_res2d.SelectionData
6180
6923
  else:
6181
6924
  curobj: WolfArray
6182
- curobj = self.active_array.mngselection
6925
+ curobj = self.active_array.SelectionData
6183
6926
 
6184
6927
  curobj.add_node_to_selection(x, y)
6185
- curobj.update_nb_nodes_sections()
6928
+ curobj.update_nb_nodes_selection()
6186
6929
  self.Paint()
6187
6930
 
6188
6931
  elif 'select by tmp vector' in self.action or 'select by vector' in self.action:
@@ -6295,6 +7038,7 @@ class WolfMapViewer(wx.Frame):
6295
7038
  altdown = e.AltDown()
6296
7039
  ctrldown = e.ControlDown()
6297
7040
  shiftdown = e.ShiftDown()
7041
+ spacedown = wx.GetKeyState(wx.WXK_SPACE)
6298
7042
 
6299
7043
  if self.action == 'dynamic parallel' and shiftdown and not ctrldown:
6300
7044
  self.dynapar_dist *= (1 - .1 * (r / max(d, 1)))
@@ -6324,9 +7068,34 @@ class WolfMapViewer(wx.Frame):
6324
7068
  self.Refresh()
6325
7069
  return
6326
7070
 
7071
+ # Allow the user to zoom onto the pixel where the
7072
+ # mouse cursor is
7073
+
7074
+ # Step1: move the map so that the pixem under the mouse cursor
7075
+ # ends up right in the middle of the screen (this move is
7076
+ # not visible from the end user point of view, it's just
7077
+ # here to make computation seasier)
7078
+ if spacedown:
7079
+ self.center_view_on( *self.getXY( e.GetPosition()))
7080
+
7081
+ # Zoom/dezoom, center pf the tranfromation is the center of the screen
6327
7082
  self.width = self.width * (1 - .1 * (r / max(d, 1)))
6328
7083
  self.height = self.height * (1 - .1 * (r / max(d, 1)))
6329
7084
 
7085
+ if spacedown:
7086
+ self.updatescalefactors() # not base on mousex
7087
+
7088
+ # Translate back the pixel at the center of the screen to where the
7089
+ # mouse cursor is. For that we measure the delta in screen coordinates
7090
+ # and transform it to map space coordinates.
7091
+ x_mid, y_mid = self.canvas.GetSize()
7092
+ x_mid, y_mid = self.getXY((0.5*x_mid, y_mid*0.5))
7093
+ x, y = self.getXY( e.GetPosition())
7094
+ dx, dy = x_mid - x, y_mid - y
7095
+ self.mousex += dx
7096
+ self.mousey += dy
7097
+
7098
+ # will translate and rescale the map view so that it fits the window.
6330
7099
  self.setbounds()
6331
7100
 
6332
7101
  def OnRDClick(self, e):
@@ -6414,7 +7183,7 @@ class WolfMapViewer(wx.Frame):
6414
7183
  elif type(myobj) == Tiles:
6415
7184
  self.active_tile= myobj
6416
7185
 
6417
- elif type(myobj) in [WolfArray, WolfArray_Sim2D, WolfArrayMB, WolfArrayMNAP]:
7186
+ elif issubclass(type(myobj), WolfArray):
6418
7187
  if ctrl:
6419
7188
  myobj.show_properties()
6420
7189
  # myobj.myops.SetTitle(_('Operations on array: ')+myobj.idx)
@@ -6422,8 +7191,22 @@ class WolfMapViewer(wx.Frame):
6422
7191
 
6423
7192
  logging.info(_('Activating array : ' + nameitem))
6424
7193
  self.active_array = myobj
7194
+
7195
+ # If BC maneger is attached to the array, we activate it
6425
7196
  self._set_active_bc()
6426
7197
 
7198
+ #Print info in the status bar
7199
+ txt = 'Dx : {:4f} ; Dy : {:4f}'.format(self.active_array.dx, self.active_array.dy)
7200
+ txt += ' ; Xmin : {:4f} ; Ymin : {:4f}'.format(self.active_array.xmin, self.active_array.ymin)
7201
+ txt += ' ; Xmax : {:4f} ; Ymax : {:4f}'.format(self.active_array.xmax, self.active_array.ymax)
7202
+ txt += ' ; Nx : {:d} ; Ny : {:d}'.format(self.active_array.nbx, self.active_array.nby)
7203
+
7204
+ if self.active_array.nb_blocks > 0:
7205
+ txt += ' ; Nb blocks : {:d}'.format(self.active_array.nb_blocks)
7206
+
7207
+ self.StatusBar.SetStatusText(txt)
7208
+
7209
+
6427
7210
  elif type(myobj) in [WolfViews]:
6428
7211
  logging.info(_('Activating view : ' + nameitem))
6429
7212
  self.active_view = myobj
@@ -6874,9 +7657,9 @@ class WolfMapViewer(wx.Frame):
6874
7657
 
6875
7658
  if inside_under:
6876
7659
  self.active_vector.close_force()
6877
- self.active_array.mngselection.select_insidepoly(self.active_vector)
7660
+ self.active_array.SelectionData.select_insidepoly(self.active_vector)
6878
7661
  else:
6879
- self.active_array.mngselection.select_underpoly(self.active_vector)
7662
+ self.active_array.SelectionData.select_underpoly(self.active_vector)
6880
7663
 
6881
7664
  if 'tmp' in locaction:
6882
7665
  # we must reset the temporary vector
@@ -6947,7 +7730,7 @@ class WolfMapViewer(wx.Frame):
6947
7730
  # Le test not(self in self.linkedList) permet de ne pas créer le liste OpenGL en cas de multi-viewers
6948
7731
  # car une liste OpenGL ne sera pas tracée sur les autres fenêtres
6949
7732
  # C'est donc plus lent mais plus sûr pour que l'affichage dynamique soit correct
6950
- self.active_vector.parentzone.plot(prep = not(self in self.linkedList))
7733
+ self.active_vector.parentzone.plot(prep = self.linkedList is None or not(self in self.linkedList))
6951
7734
 
6952
7735
  elif self.action == 'modify vertices':
6953
7736
 
@@ -6958,7 +7741,7 @@ class WolfMapViewer(wx.Frame):
6958
7741
  # Le test not(self in self.linkedList) permet de ne pas créer le liste OpenGL en cas de multi-viewers
6959
7742
  # car une liste OpenGL ne sera pas tracée sur les autres fenêtres
6960
7743
  # C'est donc plus lent mais plus sûr pour que l'affichage dynamique soit correct
6961
- self.active_vector.parentzone.plot(prep = not(self in self.linkedList))
7744
+ self.active_vector.parentzone.plot(prep = self.linkedList is None or not(self in self.linkedList))
6962
7745
  self.active_zones.find_minmax(True)
6963
7746
 
6964
7747
  self.active_vertex = None
@@ -6970,7 +7753,7 @@ class WolfMapViewer(wx.Frame):
6970
7753
  # Le test not(self in self.linkedList) permet de ne pas créer le liste OpenGL en cas de multi-viewers
6971
7754
  # car une liste OpenGL ne sera pas tracée sur les autres fenêtres
6972
7755
  # C'est donc plus lent mais plus sûr pour que l'affichage dynamique soit correct
6973
- self.active_vector.parentzone.plot(prep = not(self in self.linkedList))
7756
+ self.active_vector.parentzone.plot(prep = self.linkedList is None or not(self in self.linkedList))
6974
7757
  self.active_zones.find_minmax(True)
6975
7758
 
6976
7759
  self.active_vertex = None
@@ -6986,7 +7769,7 @@ class WolfMapViewer(wx.Frame):
6986
7769
  # Le test not(self in self.linkedList) permet de ne pas créer le liste OpenGL en cas de multi-viewers
6987
7770
  # car une liste OpenGL ne sera pas tracée sur les autres fenêtres
6988
7771
  # C'est donc plus lent mais plus sûr pour que l'affichage dynamique soit correct
6989
- self.active_vector.parentzone.plot(prep = not(self in self.linkedList))
7772
+ self.active_vector.parentzone.plot(prep = self.linkedList is None or not(self in self.linkedList))
6990
7773
 
6991
7774
  self.active_vertex = None
6992
7775
 
@@ -7363,7 +8146,7 @@ class WolfMapViewer(wx.Frame):
7363
8146
  self.copyfrom = self.active_array
7364
8147
  self.mimicme_copyfrom() # force le recopiage de copyfrom dans les autres matrices liées
7365
8148
 
7366
- self.active_array.mngselection.copy_to_clipboard()
8149
+ self.active_array.SelectionData.copy_to_clipboard()
7367
8150
 
7368
8151
  elif key == ord('C') and ctrldown and altdown:
7369
8152
  if self.active_array is None:
@@ -7378,7 +8161,7 @@ class WolfMapViewer(wx.Frame):
7378
8161
  self.copyfrom = self.active_array
7379
8162
  self.mimicme_copyfrom() # force le recopiage de copyfrom dans les autres matrices liées
7380
8163
 
7381
- self.active_array.mngselection.copy_to_clipboard(typestr='script')
8164
+ self.active_array.SelectionData.copy_to_clipboard(typestr='script')
7382
8165
 
7383
8166
  elif key == ord('V') and ctrldown:
7384
8167
  # CTRL+V
@@ -7406,16 +8189,16 @@ class WolfMapViewer(wx.Frame):
7406
8189
  logging.warning(_('No selection to be pasted !'))
7407
8190
  return
7408
8191
 
7409
- cursel = fromarray.mngselection.myselection
8192
+ cursel = fromarray.SelectionData.myselection
7410
8193
 
7411
8194
  if e.AltDown():
7412
8195
  logging.info(_('Paste selection position'))
7413
8196
 
7414
8197
  if cursel == 'all':
7415
- self.active_array.mngselection.OnAllSelect(0)
8198
+ self.active_array.SelectionData.OnAllSelect(0)
7416
8199
  elif len(cursel) > 0:
7417
- self.active_array.mngselection.myselection = cursel.copy()
7418
- self.active_array.mngselection.update_nb_nodes_sections()
8200
+ self.active_array.SelectionData.myselection = cursel.copy()
8201
+ self.active_array.SelectionData.update_nb_nodes_selection()
7419
8202
 
7420
8203
  else:
7421
8204
  logging.info(_('Copy selection values'))
@@ -7423,7 +8206,7 @@ class WolfMapViewer(wx.Frame):
7423
8206
  self.active_array.paste_all(fromarray)
7424
8207
 
7425
8208
  elif len(cursel) > 0:
7426
- z = fromarray.mngselection.get_values_sel()
8209
+ z = fromarray.SelectionData.get_values_sel()
7427
8210
  self.active_array.set_values_sel(cursel, z)
7428
8211
 
7429
8212
  self.Refresh()
@@ -7447,6 +8230,8 @@ class WolfMapViewer(wx.Frame):
7447
8230
  self.active_vertex = None
7448
8231
  self.active_cloud = None
7449
8232
 
8233
+ self.StatusBar.SetStatusText(_('Esc pressed - No more action in progress'))
8234
+
7450
8235
  elif key == ord('C'):
7451
8236
 
7452
8237
  self.copy_canvasogl(mpl = False)
@@ -7492,7 +8277,7 @@ class WolfMapViewer(wx.Frame):
7492
8277
  if idx > 8:
7493
8278
  idx -= 9
7494
8279
 
7495
- self.active_array.mngselection.move_selectionto(str(idx+1), colors[idx])
8280
+ self.active_array.SelectionData.move_selectionto(str(idx+1), colors[idx])
7496
8281
 
7497
8282
  elif key == wx.WXK_F1:
7498
8283
  self.read_last_result()
@@ -7526,8 +8311,8 @@ class WolfMapViewer(wx.Frame):
7526
8311
  elif key == wx.WXK_F9:
7527
8312
 
7528
8313
  if self.active_array is not None:
7529
- if self.active_array.mngselection is not None:
7530
- self.active_array.mngselection.myselection = 'all'
8314
+ if self.active_array.SelectionData is not None:
8315
+ self.active_array.SelectionData.myselection = 'all'
7531
8316
  logging.info(_('Selecting all nodes in the active array !'))
7532
8317
  else:
7533
8318
  logging.warning(_('No selection manager for this array !'))
@@ -7593,34 +8378,69 @@ class WolfMapViewer(wx.Frame):
7593
8378
 
7594
8379
  def paste_values(self,fromarray:WolfArray):
7595
8380
  logging.info(_('Copy selection values'))
7596
- cursel = fromarray.mngselection.myselection
8381
+ cursel = fromarray.SelectionData.myselection
7597
8382
  if cursel == 'all':
7598
8383
  self.active_array.paste_all(fromarray)
7599
8384
  elif len(cursel) > 0:
7600
- z = fromarray.mngselection.get_values_sel()
8385
+ z = fromarray.SelectionData.get_values_sel()
7601
8386
  self.active_array.set_values_sel(cursel, z)
7602
8387
 
7603
8388
  def paste_selxy(self,fromarray:WolfArray):
7604
8389
  logging.info(_('Paste selection position'))
7605
- cursel = fromarray.mngselection.myselection
8390
+ cursel = fromarray.SelectionData.myselection
7606
8391
  if cursel == 'all':
7607
- self.active_array.mngselection.OnAllSelect(0)
8392
+ self.active_array.SelectionData.OnAllSelect(0)
7608
8393
  elif len(cursel) > 0:
7609
- self.active_array.mngselection.myselection = cursel.copy()
7610
- self.active_array.mngselection.update_nb_nodes_sections()
8394
+ self.active_array.SelectionData.myselection = cursel.copy()
8395
+ self.active_array.SelectionData.update_nb_nodes_selection()
7611
8396
 
7612
8397
  def OntreeRight(self, e: wx.MouseEvent):
7613
8398
  """ Gestion du menu contextuel sur l'arbre des objets """
7614
8399
 
7615
8400
  if self.selected_object is not None:
8401
+
8402
+ # On va nettoyer le menu contextuel car certaines entrées ne sont
8403
+ # pas nécessairement pertinentes
8404
+
8405
+ # Chaînes à supprimer
8406
+ tracks=[]
8407
+ tracks.append(_('Boundary conditions'))
8408
+ tracks.append(_('Convert to mono-block'))
8409
+ tracks.append(_('Convert to mono-block (result)'))
8410
+ tracks.append(_('Convert to multi-blocks (result)'))
8411
+
8412
+ # Récupération des items du menu contextuel
8413
+ menuitems = self.popupmenu.GetMenuItems()
8414
+ text = [cur.GetItemLabelText() for cur in menuitems]
8415
+
8416
+ # Liste des indices à supprimer
8417
+ # Pas possible de supprimer à la volée car cela modifie la liste
8418
+ to_delete = []
8419
+ for track in tracks:
8420
+ if track in text:
8421
+ to_delete.append(text.index(track))
8422
+
8423
+ # Suppression des items
8424
+ if len(to_delete) > 0:
8425
+ # Suppression en ordre décroissant pour ne pas décaler les indices
8426
+ to_delete.sort(reverse=True)
8427
+ for idx in to_delete:
8428
+ self.popupmenu.Remove(menuitems[idx])
8429
+
8430
+ # Add specific menu items for WolfArray
7616
8431
  if isinstance(self.selected_object, WolfArray):
7617
8432
  bc = self.get_boundary_manager(self.selected_object)
7618
8433
  if bc is not None:
7619
8434
  self.popupmenu.Append(wx.ID_ANY, _('Boundary conditions'), _('Boundary conditions'))
7620
- else:
7621
- text = [cur.GetItemLabelText() for cur in self.popupmenu.GetMenuItems()]
7622
- if _('Boundary conditions') in text:
7623
- self.popupmenu.RemoveItem(text.index(_('Boundary conditions')))
8435
+
8436
+ # Add specific menu items for WolfArrayMB
8437
+ if isinstance(self.selected_object, WolfArrayMB):
8438
+ self.popupmenu.Append(wx.ID_ANY, _('Convert to mono-block'), _('Convert to mono-block'))
8439
+
8440
+ # Add specific menu items for Wolfresults_2D
8441
+ if isinstance(self.selected_object, Wolfresults_2D):
8442
+ self.popupmenu.Append(wx.ID_ANY, _('Convert to mono-block (result)'), _('Convert to mono-block'))
8443
+ self.popupmenu.Append(wx.ID_ANY, _('Convert to multi-blocks (result)'), _('Convert to multi-blocks'))
7624
8444
 
7625
8445
  self.treelist.PopupMenu(self.popupmenu)
7626
8446
 
@@ -7654,10 +8474,13 @@ class WolfMapViewer(wx.Frame):
7654
8474
  curobj.plotting = True
7655
8475
  curobj.plot(sx = self.sx, sy=self.sy, xmin=self.xmin, ymin=self.ymin, xmax=self.xmax, ymax=self.ymax, size = (self.xmax - self.xmin) / 100.)
7656
8476
  curobj.plotting = False
7657
- except:
8477
+ except Exception as ex:
7658
8478
  curobj.plotting = False
7659
8479
  logging.error(_('Error while plotting objects of type {}').format(drawing_type.name))
7660
8480
 
8481
+ traceback.print_exc()
8482
+ logging.error(ex)
8483
+
7661
8484
  def get_MVP_Viewport_matrix(self):
7662
8485
  """ Get the modelview projection matrix """
7663
8486
 
@@ -7969,6 +8792,8 @@ class WolfMapViewer(wx.Frame):
7969
8792
  return [cur.idx for cur in self.mywmsfore]
7970
8793
 
7971
8794
  def check_id(self, id=str, gridsize = 100.):
8795
+ """ Check an element from its id """
8796
+
7972
8797
  curobj = self.getobj_from_id(id)
7973
8798
 
7974
8799
  if curobj is None:
@@ -7984,13 +8809,15 @@ class WolfMapViewer(wx.Frame):
7984
8809
  curobj.creategrid(gridsize, self.xmin, self.ymin, self.xmax, self.ymax)
7985
8810
 
7986
8811
  def uncheck_id(self, id=str, unload=True, forceresetOGL=True, askquestion=False):
8812
+ """ Uncheck an element from its id """
8813
+
7987
8814
  curobj = self.getobj_from_id(id)
7988
8815
 
7989
8816
  if curobj is None:
7990
8817
  logging.warning('Bad id')
7991
8818
  return
7992
8819
 
7993
- if type(curobj) in [WolfArray, WolfArrayMB]:
8820
+ if issubclass(type(curobj), WolfArray):
7994
8821
  curobj.uncheck_plot(unload, forceresetOGL, askquestion)
7995
8822
  else:
7996
8823
  curobj.uncheck_plot()
@@ -7999,6 +8826,12 @@ class WolfMapViewer(wx.Frame):
7999
8826
  self.treelist.CheckItem(curitem, False)
8000
8827
 
8001
8828
  def get_current_zoom(self):
8829
+ """
8830
+ Get the current zoom
8831
+
8832
+ :return: dict with keys 'center', 'xmin', 'xmax', 'ymin', 'ymax', 'width', 'height'
8833
+
8834
+ """
8002
8835
 
8003
8836
  return {'center': (self.mousex, self.mousey),
8004
8837
  'xmin' : self.xmin,
@@ -8009,12 +8842,15 @@ class WolfMapViewer(wx.Frame):
8009
8842
  'height' : self.ymax-self.ymin}
8010
8843
 
8011
8844
  def save_current_zoom(self, filepath):
8845
+ """ Save the current zoom in a json file """
8012
8846
 
8013
8847
  zoom = self.get_current_zoom()
8014
8848
  with open(filepath, 'w') as fp:
8015
8849
  json.dump(zoom, fp)
8016
8850
 
8017
8851
  def read_current_zoom(self, filepath):
8852
+ """ Read the current zoom from a json file """
8853
+
8018
8854
  if exists(filepath):
8019
8855
  with open(filepath, 'r') as fp:
8020
8856
  zoom = json.load(fp)