@@ -535,10 +535,8 @@ def setup_time_viewer(self, time_viewer=True, show_traces=True):
535535 self .mpl_canvas = None
536536 self .help_canvas = None
537537 self .rms = None
538- self .picked_patches = {key : list () for key in all_keys }
539- self .picked_points = {key : list () for key in all_keys }
540- self .pick_table = dict ()
541- self ._spheres = list ()
538+ self ._picked_patches = {key : list () for key in all_keys }
539+ self ._picked_points = dict ()
542540 self ._mouse_no_mvt = - 1
543541
544542 # Derived parameters:
@@ -622,6 +620,8 @@ def _clean(self):
622620 self .plotter ._Iren = _FakeIren ()
623621 if getattr (self .plotter , "picker" , None ) is not None :
624622 self .plotter .picker = None
623+ if getattr (self ._renderer , "_picker" , None ) is not None :
624+ self ._renderer ._picker = None
625625 # XXX end PyVista
626626 for key in (
627627 "plotter" ,
@@ -925,7 +925,7 @@ def _set_annot(annot):
925925 def _set_label_mode (mode ):
926926 if self .traces_mode != "label" :
927927 return
928- glyphs = copy .deepcopy (self .picked_patches )
928+ glyphs = copy .deepcopy (self ._picked_patches )
929929 self .label_extract_mode = mode
930930 self .clear_glyphs ()
931931 for hemi in self ._hemis :
@@ -1048,7 +1048,7 @@ def _configure_vertex_time_course(self):
10481048 # simulate a picked renderer
10491049 if self ._hemi in ("both" , "rh" ) or hemi == "vol" :
10501050 idx = 0
1051- self .picked_renderer = self ._renderer ._all_renderers [idx ]
1051+ self ._picked_renderer = self ._renderer ._all_renderers [idx ]
10521052
10531053 # initialize the default point
10541054 if self ._data ["initial_time" ] is not None :
@@ -1201,16 +1201,9 @@ def _on_button_release(self, vtk_picker, event):
12011201 if self ._mouse_no_mvt > 0 :
12021202 x , y = vtk_picker .GetEventPosition ()
12031203 # programmatically detect the picked renderer
1204- try :
1205- # pyvista<0.30.0
1206- self .picked_renderer = self .plotter .iren .FindPokedRenderer (x , y )
1207- except AttributeError :
1208- # pyvista>=0.30.0
1209- self .picked_renderer = self .plotter .iren .interactor .FindPokedRenderer (
1210- x , y
1211- )
1204+ self ._picked_renderer = self .plotter .iren .interactor .FindPokedRenderer (x , y )
12121205 # trigger the pick
1213- self .plotter . picker .Pick (x , y , 0 , self .picked_renderer )
1206+ self ._renderer . _picker .Pick (x , y , 0 , self .picked_renderer )
12141207 self ._mouse_no_mvt = 0
12151208
12161209 def _on_pick (self , vtk_picker , event ):
@@ -1224,28 +1217,17 @@ def _on_pick(self, vtk_picker, event):
12241217 if mesh is None or cell_id == - 1 or not self ._mouse_no_mvt :
12251218 return # don't pick
12261219
1227- # 1) Check to see if there are any spheres along the ray
1228- if len (self ._spheres ):
1220+ # 1) Check to see if there are any spheres along the ray and remove if so
1221+ if len (self ._picked_points ):
12291222 collection = vtk_picker .GetProp3Ds ()
1230- found_sphere = None
12311223 for ii in range (collection .GetNumberOfItems ()):
12321224 actor = collection .GetItemAsObject (ii )
1233- for sphere in self ._spheres :
1234- if any (a is actor for a in sphere ._actors ):
1235- found_sphere = sphere
1236- break
1237- if found_sphere is not None :
1238- break
1239- if found_sphere is not None :
1240- assert found_sphere ._is_glyph
1241- mesh = found_sphere
1242-
1243- # 2) Remove sphere if it's what we have
1244- if hasattr (mesh , "_is_glyph" ):
1245- self ._remove_vertex_glyph (mesh )
1246- return
1225+ for (hemi , vertex_id ), spheres in self ._picked_points .items ():
1226+ if any (sphere ["actor" ] is actor for sphere in spheres ):
1227+ self ._remove_vertex_glyph (hemi = hemi , vertex_id = vertex_id )
1228+ return
12471229
1248- # 3 ) Otherwise, pick the objects in the scene
1230+ # 2 ) Otherwise, pick the objects in the scene
12491231 for hemi , this_mesh in self ._layered_meshes .items ():
12501232 assert hemi in ("lh" , "rh" ), f"Unexpected { hemi = } "
12511233 if this_mesh ._polydata is mesh :
@@ -1359,24 +1341,25 @@ def _add_label_glyph(self, hemi, mesh, vertex_id):
13591341 label = self ._annotation_labels [hemi ][label_id ]
13601342
13611343 # remove the patch if already picked
1362- if label_id in self .picked_patches [hemi ]:
1344+ if label_id in self ._picked_patches [hemi ]:
13631345 self ._remove_label_glyph (hemi , label_id )
13641346 return
13651347
13661348 if hemi == label .hemi :
13671349 self .add_label (label , borders = True )
1368- self .picked_patches [hemi ].append (label_id )
1350+ self ._picked_patches [hemi ].append (label_id )
13691351
13701352 def _remove_label_glyph (self , hemi , label_id ):
13711353 label = self ._annotation_labels [hemi ][label_id ]
13721354 label ._line .remove ()
13731355 self .color_cycle .restore (label ._color )
13741356 self .mpl_canvas .update_plot ()
13751357 self ._layered_meshes [hemi ].remove_overlay (label .name )
1376- self .picked_patches [hemi ].remove (label_id )
1358+ self ._picked_patches [hemi ].remove (label_id )
13771359
13781360 def _add_vertex_glyph (self , hemi , mesh , vertex_id , update = True ):
1379- if vertex_id in self .picked_points [hemi ]:
1361+ _ensure_int (vertex_id )
1362+ if (hemi , vertex_id ) in self ._picked_points :
13801363 return
13811364
13821365 # skip if the wrong hemi is selected
@@ -1400,10 +1383,9 @@ def _add_vertex_glyph(self, hemi, mesh, vertex_id, update=True):
14001383 lst = self ._renderer ._all_renderers ._renderers
14011384 except AttributeError :
14021385 lst = self ._renderer ._all_renderers
1403- rindex = lst .index (self .picked_renderer )
1386+ rindex = lst .index (self ._picked_renderer )
14041387 row , col = self ._renderer ._index_to_loc (rindex )
14051388
1406- actors = list ()
14071389 spheres = list ()
14081390 for _ in self ._iter_views (hemi ):
14091391 # Using _sphere() instead of renderer.sphere() for 2 reasons:
@@ -1412,39 +1394,28 @@ def _add_vertex_glyph(self, hemi, mesh, vertex_id, update=True):
14121394 # mitigated with synchronization/delay?)
14131395 # 2) the glyph filter is used in renderer.sphere() but only one
14141396 # sphere is required in this function.
1415- actor , sphere = self ._renderer ._sphere (
1397+ actor , mesh = self ._renderer ._sphere (
14161398 center = np .array (center ),
14171399 color = color ,
14181400 radius = 4.0 ,
14191401 )
1420- actors .append (actor )
1421- spheres .append (sphere )
1402+ spheres .append (dict (mesh = mesh , actor = actor ))
14221403
14231404 # add metadata for picking
14241405 for sphere in spheres :
1425- sphere ._is_glyph = True
1426- sphere ._hemi = hemi
1427- sphere ._line = line
1428- sphere ._actors = actors
1429- sphere ._color = color
1430- sphere ._vertex_id = vertex_id
1431-
1432- self .picked_points [hemi ].append (vertex_id )
1433- self ._spheres .extend (spheres )
1434- self .pick_table [vertex_id ] = spheres
1435- return sphere
1406+ sphere .update (hemi = hemi , line = line , color = color , vertex_id = vertex_id )
14361407
1437- def _remove_vertex_glyph (self , mesh , render = True ):
1438- vertex_id = mesh ._vertex_id
1439- if vertex_id not in self .pick_table :
1440- return
1408+ _ensure_int (vertex_id )
1409+ self ._picked_points [(hemi , vertex_id )] = spheres
1410+ return sphere
14411411
1442- hemi = mesh ._hemi
1443- color = mesh ._color
1444- spheres = self .pick_table [vertex_id ]
1445- spheres [0 ]._line .remove ()
1412+ def _remove_vertex_glyph (self , * , hemi , vertex_id , render = True ):
1413+ _ensure_int (vertex_id )
1414+ assert isinstance (hemi , str ), f"got { type (hemi )} for { hemi = } "
1415+ spheres = self ._picked_points .pop ((hemi , vertex_id ))
1416+ color , line = spheres [0 ]["color" ], spheres [0 ]["line" ]
1417+ line .remove ()
14461418 self .mpl_canvas .update_plot ()
1447- self .picked_points [hemi ].remove (vertex_id )
14481419
14491420 with warnings .catch_warnings (record = True ):
14501421 # We intentionally ignore these in case we have traversed the
@@ -1453,26 +1424,21 @@ def _remove_vertex_glyph(self, mesh, render=True):
14531424 self .color_cycle .restore (color )
14541425 for sphere in spheres :
14551426 # remove all actors
1456- self .plotter .remove_actor (sphere ._actors , render = False )
1457- sphere ._actors = None
1458- self ._spheres .pop (self ._spheres .index (sphere ))
1427+ self .plotter .remove_actor (sphere .pop ("actor" ), render = False )
14591428 if render :
14601429 self ._renderer ._update ()
1461- self .pick_table .pop (vertex_id )
14621430
14631431 def clear_glyphs (self ):
14641432 """Clear the picking glyphs."""
14651433 if not self .time_viewer :
14661434 return
1467- for sphere in list (self ._spheres ): # will remove itself, so copy
1468- self ._remove_vertex_glyph (sphere , render = False )
1469- assert sum (len (v ) for v in self .picked_points .values ()) == 0
1470- assert len (self .pick_table ) == 0
1471- assert len (self ._spheres ) == 0
1435+ for hemi , vertex_id in list (self ._picked_points ):
1436+ self ._remove_vertex_glyph (hemi = hemi , vertex_id = vertex_id , render = False )
1437+ assert len (self ._picked_points ) == 0
14721438 for hemi in self ._hemis :
1473- for label_id in list (self .picked_patches [hemi ]):
1439+ for label_id in list (self ._picked_patches [hemi ]):
14741440 self ._remove_label_glyph (hemi , label_id )
1475- assert sum (len (v ) for v in self .picked_patches .values ()) == 0
1441+ assert sum (len (v ) for v in self ._picked_patches .values ()) == 0
14761442 if self .rms is not None :
14771443 self .rms .remove ()
14781444 self .rms = None
@@ -4025,11 +3991,14 @@ def get_picked_points(self):
40253991
40263992 Returns
40273993 -------
4028- points : list of int | None
4029- The vertices picked by the time viewer.
3994+ points : dict | None
3995+ The vertices picked by the time viewer, one key per hemisphere with
3996+ a list of vertex indices.
40303997 """
4031- if hasattr (self , "time_viewer" ):
4032- return self .picked_points
3998+ out = dict (lh = [], rh = [], vol = [])
3999+ for hemi , vertex_id in self ._picked_points :
4000+ out [hemi ].append (vertex_id )
4001+ return out
40334002
40344003 def __hash__ (self ):
40354004 """Hash the object."""
0 commit comments