@@ -117,8 +117,7 @@ def __init__(
117117 self .state .read_in_status = self .state .all_read_in_statuses [
118118 "vtu_conversion_error"
119119 ]
120-
121- self .update_pyvista_render_objects (init_rendering = True )
120+ self .init_pyvista_render_objects ()
122121
123122 # create ui
124123 create_gui (self .server , self ._server_vars ["render_window" ])
@@ -140,7 +139,7 @@ def init_state_and_server_vars(self):
140139 """Initialize state variables (reactive shared state) and server-side
141140 only variables, particularly the ones related to the fourc yaml
142141 content."""
143-
142+ self . _actors = {}
144143 ### --- self.state VARIABLES FOR INPUT FILE CONTENT --- ###
145144 # name of the 4C yaml file
146145 self .state .fourc_yaml_name = self ._server_vars ["fourc_yaml_name" ]
@@ -228,61 +227,149 @@ def sync_server_vars_from_state(self):
228227 self .sync_result_description_section_from_state ()
229228 self .sync_funct_section_from_state ()
230229
231- def update_pyvista_render_objects (self , init_rendering = False ):
232- """Update/ initialize pyvista view objects (reader, thresholds, global
233- COS, ...) for the rendered window. The saved vtu file path is hereby
234- utilized.
230+ def init_pyvista_render_objects (self ):
231+ """Initialize pyvista view objects (reader, thresholds, global COS,
232+ ...) for the rendered window.
235233
236- Args:
237- init_rendering (bool): perform initialization tasks? (True:
238- yes | False: no -> only updating)
234+ The saved vtu file path is hereby utilized.
239235 """
240-
241- # initialization tasks
242- if init_rendering :
243- # initialization: declare render window as a pyvista plotter
236+ if "render_window" not in self ._actors :
244237 self ._server_vars ["render_window" ] = pv .Plotter ()
245238
239+ self ._server_vars ["render_window" ].clear_actors ()
240+
241+ problem_mesh = pv .read (self .state .vtu_path )
246242 # get problem mesh
247- self ._server_vars ["pv_mesh" ] = pv .read (self .state .vtu_path )
243+ self ._actors ["problem_mesh" ] = self ._server_vars ["render_window" ].add_mesh (
244+ problem_mesh , color = "bisque" , opacity = 0.2 , render = False
245+ )
248246
249247 # get mesh of the selected material
250- master_mat_ind = self .determine_master_mat_ind_for_current_selection ()
251- self ._server_vars ["pv_selected_material_mesh" ] = self ._server_vars [
252- "pv_mesh"
253- ].threshold (
254- value = (master_mat_ind - 0.05 , master_mat_ind + 0.05 ),
255- scalars = "element-material" ,
256- )
248+ self ._actors ["material_meshes" ] = {}
249+ for material in self .state .materials_section .keys ():
250+ # get meshes of materials
251+ master_mat_ind = self .determine_master_mat_ind_for_material (material )
252+ self ._actors ["material_meshes" ][material ] = self ._server_vars [
253+ "render_window"
254+ ].add_mesh (
255+ problem_mesh .threshold (
256+ value = (master_mat_ind - 0.05 , master_mat_ind + 0.05 ),
257+ scalars = "element-material" ,
258+ ),
259+ color = "darkorange" ,
260+ opacity = 0.7 ,
261+ render = False ,
262+ )
257263
258- # get nodes of the selected condition geometry + entity
259- self ._server_vars ["pv_selected_dc_geometry_entity" ] = pv .PointSet (
260- self ._server_vars ["pv_mesh" ]
261- ).threshold (
262- value = 1.0 ,
263- scalars = f"d{ self .state .selected_dc_geometry_type .lower ()} { self .state .selected_dc_entity .replace ('E' , '' )} " ,
264- preference = "point" ,
265- )
264+ all_dc_entities = [
265+ {"entity" : k , "geometry_type" : sec_name }
266+ for sec_name , sec in self .state .dc_sections .items ()
267+ for k in sec # == sec.keys()
268+ ]
269+ self ._actors ["dc_geometry_entities" ] = {}
270+ # get nodes of the selected condition geometries + entities
271+ for dc_entity in all_dc_entities :
272+ points = problem_mesh .threshold (
273+ value = 1.0 ,
274+ scalars = f"d{ dc_entity ['geometry_type' ].lower ()} { dc_entity ['entity' ].replace ('E' , '' )} " ,
275+ preference = "point" ,
276+ ).points
277+
278+ if points .size :
279+ pts = pv .PolyData (points )
280+ r = (
281+ pv_render .get_problem_length_scale (self ._actors ["problem_mesh" ])
282+ * pv_render .PV_SPHERE_FRAC_SCALE
283+ )
284+
285+ # niedrige Auflösung = viel schneller
286+ sphere = pv .Sphere (radius = r , theta_resolution = 5 , phi_resolution = 5 )
287+
288+ glyphs = pts .glyph (
289+ geom = sphere , scale = False , orient = False
290+ ) # in PolyData
291+ self ._actors ["dc_geometry_entities" ][
292+ (dc_entity ["entity" ], dc_entity ["geometry_type" ])
293+ ] = self ._server_vars ["render_window" ].add_mesh (
294+ glyphs ,
295+ color = "navy" ,
296+ opacity = 1.0 ,
297+ render = False ,
298+ )
266299
267- # get coords of node with prescribed result description
268- self ._server_vars ["pv_selected_result_description_node_coords" ] = (
269- self ._server_vars ["pv_mesh" ].points [
270- self .state .result_description_section [
271- self .state .selected_result_description_id
272- ]["PARAMETERS" ]["NODE" ]
273- - 1 ,
300+ self ._actors ["result_description_nodes" ] = {}
301+ all_result_descriptions = self .state .result_description_section .keys ()
302+
303+ for dc in all_result_descriptions :
304+ node_coords = problem_mesh .points [
305+ self .state .result_description_section [dc ]["PARAMETERS" ]["NODE" ] - 1 ,
274306 :,
275307 ]
276- )
308+ self ._actors ["result_description_nodes" ][dc ] = self ._server_vars [
309+ "render_window"
310+ ].add_mesh (
311+ pv .Sphere (
312+ center = node_coords ,
313+ radius = pv_render .get_problem_length_scale (problem_mesh )
314+ * pv_render .PV_SPHERE_FRAC_SCALE ,
315+ ),
316+ color = "deepskyblue" ,
317+ render = False ,
318+ )
319+ self .update_pyvista_render_objects ()
277320
278- # update plotter / rendering
279- pv_render .update_pv_plotter (
280- self ._server_vars ["render_window" ],
281- self ._server_vars ["pv_mesh" ],
282- self ._server_vars ["pv_selected_material_mesh" ],
283- self ._server_vars ["pv_selected_dc_geometry_entity" ],
284- self ._server_vars ["pv_selected_result_description_node_coords" ],
285- )
321+ def update_pyvista_render_objects (self ):
322+ """Update/ initialize pyvista view objects (reader, thresholds, global
323+ COS, ...) for the rendered window. The saved vtu file path is hereby
324+ utilized.
325+
326+ Args:
327+ init_rendering (bool): perform initialization tasks? (True:
328+ yes(also when loading a new file) | False: no -> only updating)
329+ """
330+ # 70ms for tutorial_solid.4C.yaml DESIGN CONDITIONS/SURF/E2 on LasseLaptop
331+ # 0ms for tutorial_solid.4C.yaml PROBLEM TYPE on LasseLaptop
332+ legend_items = []
333+
334+ for dc in self ._actors ["result_description_nodes" ].values ():
335+ dc .SetVisibility (False )
336+ if (
337+ self .state .selected_result_description_id
338+ in self ._actors ["result_description_nodes" ].keys ()
339+ and self .state .selected_result_description_id
340+ and self .state .selected_main_section_name == "RESULT DESCRIPTION"
341+ ):
342+ self ._actors ["result_description_nodes" ][
343+ self .state .selected_result_description_id
344+ ].SetVisibility (True )
345+ legend_items .append (("Selected result description" , "deepskyblue" ))
346+
347+ for rd in self ._actors ["dc_geometry_entities" ].values ():
348+ rd .SetVisibility (False )
349+ if (
350+ self .state .selected_dc_entity
351+ and self .state .selected_dc_geometry_type
352+ and self .state .selected_main_section_name == "DESIGN CONDITIONS"
353+ ):
354+ self ._actors ["dc_geometry_entities" ][
355+ (self .state .selected_dc_entity , self .state .selected_dc_geometry_type )
356+ ].SetVisibility (True )
357+ legend_items .append (("Selected design condition" , "navy" ))
358+
359+ for mat in self ._actors ["material_meshes" ].values ():
360+ mat .SetVisibility (False )
361+ if (
362+ self .state .selected_material
363+ and self .state .selected_main_section_name == "MATERIALS"
364+ ):
365+ self ._actors ["material_meshes" ][self .state .selected_material ].SetVisibility (
366+ True
367+ )
368+ legend_items .append (("Selected material" , "orange" ))
369+
370+ self ._server_vars ["render_window" ].remove_legend ()
371+ if legend_items :
372+ self ._server_vars ["render_window" ].add_legend (labels = legend_items )
286373
287374 def init_general_sections_state_and_server_vars (self ):
288375 """Get the general sections and cluster them into subsections. For
@@ -951,6 +1038,9 @@ def change_selected_main_section_name(self, selected_main_section_name, **kwargs
9511038 selected_main_section_name
9521039 ]["subsections" ][0 ]
9531040
1041+ # update plotter / render objects
1042+ self .update_pyvista_render_objects ()
1043+
9541044 @change ("selected_material" )
9551045 def change_selected_material (self , selected_material , ** kwargs ):
9561046 """Reaction to change of state.selected_material."""
@@ -1148,7 +1238,7 @@ def click_convert_button(self, **kwargs):
11481238 ]
11491239 else :
11501240 # reset view
1151- self .update_pyvista_render_objects ()
1241+ self .init_pyvista_render_objects ()
11521242 self ._server_vars ["render_window" ].reset_camera ()
11531243 self .ctrl .view_reset_camera ()
11541244 self .ctrl .view_update ()
@@ -1189,21 +1279,20 @@ def convert_string2num_all_sections(self):
11891279 self .state .result_description_section
11901280 )
11911281
1192- def determine_master_mat_ind_for_current_selection (self ):
1193- """Determines the real master/source material of the currently selected
1194- material. Accounts for CLONING MATERIAL MAP by going one step further
1195- and checking for the real source material recursively (important in
1196- multi-field problem settings, e.g., in SSTI, the procedure finds the
1197- structural material).
1282+ def determine_master_mat_ind_for_material (self , material ):
1283+ """Determines the real master/source material of a material. Accounts
1284+ for CLONING MATERIAL MAP by going one step further and checking for the
1285+ real source material recursively (important in multi-field problem
1286+ settings, e.g., in SSTI, the procedure finds the structural material).
11981287
11991288 Returns:
12001289 int: id of the real master material of the currently
12011290 selected material.
12021291 """
12031292 # get id of the master material
1204- master_mat_id = self .state .materials_section [self . state . selected_material ][
1205- "RELATIONSHIPS "
1206- ][ "MASTER MATERIAL" ]
1293+ master_mat_id = self .state .materials_section [material ][ "RELATIONSHIPS" ][
1294+ "MASTER MATERIAL "
1295+ ]
12071296
12081297 # it could now be that the master material is a TARGET material
12091298 # during cloning material map (and its master might be also a
0 commit comments