Source code for fury.pick

from collections.abc import Sequence

import numpy as np

from fury.lib import (
    CellPicker,
    DataObject,
    HardwareSelector,
    PointPicker,
    PropPicker,
    WorldPointPicker,
    numpy_support,
)


[docs] class PickingManager: """Picking Manager helps with picking 3D objects."""
[docs] def __init__(self, vertices=True, faces=True, actors=True, world_coords=True): """Initialize Picking Manager. Parameters ---------- vertices : bool If True allows to pick vertex indices. faces : bool If True allows to pick face indices. actors : bool If True allows to pick actor indices. world_coords : bool If True allows to pick xyz position in world coordinates. """ self.pickers = {} if vertices: self.pickers["vertices"] = PointPicker() if faces: self.pickers["faces"] = CellPicker() if actors: self.pickers["actors"] = PropPicker() if world_coords: self.pickers["world_coords"] = WorldPointPicker()
[docs] def pick(self, disp_xy, sc): """Pick on display coordinates. Parameters ---------- disp_xy : tuple Display coordinates x, y. sc : Scene """ x, y = disp_xy z = 0 info = {"vertex": None, "face": None, "actor": None, "xyz": None} keys = self.pickers.keys() if "vertices" in keys: self.pickers["vertices"].Pick(x, y, z, sc) info["vertex"] = self.pickers["vertices"].GetPointId() if "faces" in keys: self.pickers["faces"].Pick(x, y, z, sc) info["vertex"] = self.pickers["faces"].GetPointId() info["face"] = self.pickers["faces"].GetCellId() if "actors" in keys: self.pickers["actors"].Pick(x, y, z, sc) info["actor"] = self.pickers["actors"].GetViewProp() if "world_coords" in keys: self.pickers["world_coords"].Pick(x, y, z, sc) info["xyz"] = self.pickers["world_coords"].GetPickPosition() return info
[docs] def event_position(self, iren): """Return event display position from interactor. Parameters ---------- iren : interactor The interactor object can be retrieved for example using providing ShowManager's iren attribute. """ return iren.GetEventPosition()
[docs] def pickable_on(self, actors): """Choose which actors can be picked. Parameters ---------- actors : actor or sequence of actors """ if isinstance(actors, Sequence): for a in actors: a.PickableOn() else: actors.PickableOn()
[docs] def pickable_off(self, actors): """Choose which actors cannot be picked. Parameters ---------- actors : actor or sequence of actors """ if isinstance(actors, Sequence): for a in actors: a.PickableOff() else: actors.PickableOff()
[docs] class SelectionManager: """Selection Manager helps with picking many objects simultaneously."""
[docs] def __init__(self, select="faces"): """Initialize Selection Manager. Parameters ---------- select : 'faces' Options are 'faces', 'vertices' or 'actors'. Default 'faces'. Methods ------- select() pick() """ self.hsel = HardwareSelector() self.update_selection_type(select)
[docs] def update_selection_type(self, select): """Update selection type. Parameters ---------- select : 'faces' Options are 'faces', 'vertices' or 'actors'. Default 'faces'. """ self.selected_type = select.lower() if select == "faces" or select == "edges": self.hsel.SetFieldAssociation(DataObject.FIELD_ASSOCIATION_CELLS) elif select == "points" or select == "vertices": self.hsel.SetFieldAssociation(DataObject.FIELD_ASSOCIATION_POINTS) elif select == "actors": self.hsel.SetActorPassOnly(True) else: raise ValueError("Unknown parameter select")
[docs] def pick(self, disp_xy, sc): """Pick on display coordinates returns a single object. Parameters ---------- disp_xy : tuple Display coordinates x, y. sc : Scene """ return self.select(disp_xy, sc, area=0)[0]
[docs] def select(self, disp_xy, sc, area=0): """Select multiple objects using display coordinates. Parameters ---------- disp_xy : tuple Display coordinates x, y. sc : Scene area : int or 2d tuple of ints Selection area around x, y coords. """ info_plus = {} self.hsel.SetRenderer(sc) if isinstance(area, int): picking_area = area, area else: picking_area = area try: self.hsel.SetArea( disp_xy[0] - picking_area[0], disp_xy[1] - picking_area[1], disp_xy[0] + picking_area[0], disp_xy[1] + picking_area[1], ) res = self.hsel.Select() except OverflowError: return {0: {"node": None, "vertex": None, "face": None, "actor": None}} num_nodes = res.GetNumberOfNodes() if num_nodes < 1: sel_node = None return {0: {"node": None, "vertex": None, "face": None, "actor": None}} else: for i in range(num_nodes): sel_node = res.GetNode(i) info = {"node": None, "vertex": None, "face": None, "actor": None} if sel_node is not None: selected_nodes = set( np.floor( numpy_support.vtk_to_numpy(sel_node.GetSelectionList()) ).astype(int) ) info["node"] = sel_node info["actor"] = sel_node.GetProperties().Get(sel_node.PROP()) if self.selected_type == "faces": info["face"] = list(selected_nodes) if self.selected_type == "vertex": info["vertex"] = list(selected_nodes) info_plus[i] = info return info_plus
[docs] def event_position(self, iren): """Return event display position from interactor. Parameters ---------- iren : interactor The interactor object can be retrieved for example using ShowManager's iren attribute. """ return iren.GetEventPosition()
[docs] def selectable_on(self, actors): """Choose which actors can be selected. Parameters ---------- actors : actor or sequence of actors """ if isinstance(actors, Sequence): for a in actors: a.PickableOn() else: actors.PickableOn()
[docs] def selectable_off(self, actors): """Choose which actors cannot be selected. Parameters ---------- actors : actor or sequence of actors """ if isinstance(actors, Sequence): for a in actors: a.PickableOff() else: actors.PickableOff()