def test_get_bounds(): size = (15, 15) test_bounds = [0.0, 15, 0.0, 15, 0.0, 0.0] points = Points() points.InsertNextPoint(0, 0, 0) points.InsertNextPoint(size[0], 0, 0) points.InsertNextPoint(size[0], size[1], 0) points.InsertNextPoint(0, size[1], 0) # Create the polygon polygon = Polygon() polygon.GetPointIds().SetNumberOfIds(4) # make a quad polygon.GetPointIds().SetId(0, 0) polygon.GetPointIds().SetId(1, 1) polygon.GetPointIds().SetId(2, 2) polygon.GetPointIds().SetId(3, 3) # Add the polygon to a list of polygons polygons = CellArray() polygons.InsertNextCell(polygon) # Create a PolyData polygonPolyData = PolyData() polygonPolyData.SetPoints(points) polygonPolyData.SetPolys(polygons) # Create a mapper and actor mapper = PolyDataMapper2D() mapper = set_input(mapper, polygonPolyData) actor = Actor2D() actor.SetMapper(mapper) compute_bounds(actor) npt.assert_equal(get_bounds(actor), test_bounds)
def test_save_and_load_polydata(): l_ext = ["vtk", "fib", "ply", "xml"] fname = "temp-io" for ext in l_ext: with InTemporaryDirectory() as odir: data = np.random.randint(0, 255, size=(50, 3)) pd = PolyData() pd.SetPoints(numpy_to_vtk_points(data)) fname_path = pjoin(odir, "{0}.{1}".format(fname, ext)) save_polydata(pd, fname_path) npt.assert_equal(os.path.isfile(fname_path), True) assert_greater(os.stat(fname_path).st_size, 0) out_pd = load_polydata(fname_path) out_data = numpy_support.vtk_to_numpy(out_pd.GetPoints().GetData()) npt.assert_array_equal(data, out_data) npt.assert_raises(IOError, save_polydata, PolyData(), "test.vti") npt.assert_raises(IOError, save_polydata, PolyData(), "test.obj") npt.assert_raises(IOError, load_polydata, "test.vti")
def generate_points(): centers = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) colors = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]) * 255 vtk_vertices = Points() # Create the topology of the point (a vertex) vtk_faces = CellArray() # Add points for i in range(len(centers)): p = centers[i] id = vtk_vertices.InsertNextPoint(p) vtk_faces.InsertNextCell(1) vtk_faces.InsertCellPoint(id) # Create a polydata object polydata = PolyData() # Set the vertices and faces we created as the geometry and topology of the # polydata polydata.SetPoints(vtk_vertices) polydata.SetVerts(vtk_faces) set_polydata_colors(polydata, colors) mapper = PolyDataMapper() mapper.SetInputData(polydata) mapper.SetVBOShiftScaleMethod(False) point_actor = Actor() point_actor.SetMapper(mapper) return point_actor
def test_set_polydata_tangents(): my_polydata = PolyData() poly_point_data = my_polydata.GetPointData() npt.assert_equal(poly_point_data.GetNumberOfArrays(), 0) array = np.array([[0, 0, 0], [1, 1, 1]]) set_polydata_tangents(my_polydata, array) npt.assert_equal(poly_point_data.GetNumberOfArrays(), 1) npt.assert_equal(poly_point_data.HasArray('Tangents'), True)
def test_get_polydata_tangents(): my_polydata = PolyData() tangents = get_polydata_tangents(my_polydata) npt.assert_equal(tangents, None) array = np.array([[0, 0, 0], [1, 1, 1]]) my_polydata.GetPointData().SetTangents( numpy_support.numpy_to_vtk(array, deep=True, array_type=VTK_FLOAT)) tangents = get_polydata_tangents(my_polydata) npt.assert_array_equal(tangents, array)
def test_add_polydata_numeric_field(): my_polydata = PolyData() poly_field_data = my_polydata.GetFieldData() npt.assert_equal(poly_field_data.GetNumberOfArrays(), 0) bool_data = True add_polydata_numeric_field(my_polydata, 'Test Bool', bool_data) npt.assert_equal(poly_field_data.GetNumberOfArrays(), 1) npt.assert_equal( poly_field_data.GetArray('Test Bool').GetValue(0), bool_data) poly_field_data.RemoveArray('Test Bool') npt.assert_equal(poly_field_data.GetNumberOfArrays(), 0) int_data = 1 add_polydata_numeric_field(my_polydata, 'Test Int', int_data) npt.assert_equal(poly_field_data.GetNumberOfArrays(), 1) npt.assert_equal( poly_field_data.GetArray('Test Int').GetValue(0), int_data) poly_field_data.RemoveArray('Test Int') npt.assert_equal(poly_field_data.GetNumberOfArrays(), 0) float_data = .1 add_polydata_numeric_field(my_polydata, 'Test Float', float_data, array_type=VTK_FLOAT) npt.assert_equal(poly_field_data.GetNumberOfArrays(), 1) npt.assert_almost_equal( poly_field_data.GetArray('Test Float').GetValue(0), float_data) poly_field_data.RemoveArray('Test Float') npt.assert_equal(poly_field_data.GetNumberOfArrays(), 0) double_data = .1 add_polydata_numeric_field(my_polydata, 'Test Double', double_data, array_type=VTK_DOUBLE) npt.assert_equal(poly_field_data.GetNumberOfArrays(), 1) npt.assert_equal( poly_field_data.GetArray('Test Double').GetValue(0), double_data) poly_field_data.RemoveArray('Test Double') npt.assert_equal(poly_field_data.GetNumberOfArrays(), 0) array_data = [-1, 0, 1] add_polydata_numeric_field(my_polydata, 'Test Array', array_data) npt.assert_equal(poly_field_data.GetNumberOfArrays(), 1) npt.assert_equal( numpy_support.vtk_to_numpy(poly_field_data.GetArray('Test Array')), array_data) poly_field_data.RemoveArray('Test Array') npt.assert_equal(poly_field_data.GetNumberOfArrays(), 0) ndarray_data = np.array([[-.1, -.1], [0, 0], [.1, .1]]) add_polydata_numeric_field(my_polydata, 'Test NDArray', ndarray_data, array_type=VTK_FLOAT) npt.assert_equal(poly_field_data.GetNumberOfArrays(), 1) npt.assert_almost_equal( numpy_support.vtk_to_numpy(poly_field_data.GetArray('Test NDArray')), ndarray_data)
def test_get_polydata_field(): my_polydata = PolyData() field_data = get_polydata_field(my_polydata, 'Test') npt.assert_equal(field_data, None) data = 1 field_name = 'Test' vtk_data = numpy_support.numpy_to_vtk(data) vtk_data.SetName(field_name) my_polydata.GetFieldData().AddArray(vtk_data) field_data = get_polydata_field(my_polydata, field_name) npt.assert_equal(field_data, data)
def _setup(self): """Set up this UI component. Creating the button actor used internally. """ # This is highly inspired by # https://github.com/Kitware/VTK/blob/c3ec2495b183e3327820e927af7f8f90d34c3474/Interaction/Widgets/vtkBalloonRepresentation.cxx#L47 self.texture_polydata = PolyData() self.texture_points = Points() self.texture_points.SetNumberOfPoints(4) polys = CellArray() polys.InsertNextCell(4) polys.InsertCellPoint(0) polys.InsertCellPoint(1) polys.InsertCellPoint(2) polys.InsertCellPoint(3) self.texture_polydata.SetPolys(polys) tc = FloatArray() tc.SetNumberOfComponents(2) tc.SetNumberOfTuples(4) tc.InsertComponent(0, 0, 0.0) tc.InsertComponent(0, 1, 0.0) tc.InsertComponent(1, 0, 1.0) tc.InsertComponent(1, 1, 0.0) tc.InsertComponent(2, 0, 1.0) tc.InsertComponent(2, 1, 1.0) tc.InsertComponent(3, 0, 0.0) tc.InsertComponent(3, 1, 1.0) self.texture_polydata.GetPointData().SetTCoords(tc) texture_mapper = PolyDataMapper2D() texture_mapper = set_input(texture_mapper, self.texture_polydata) button = TexturedActor2D() button.SetMapper(texture_mapper) self.texture = Texture() button.SetTexture(self.texture) button_property = Property2D() button_property.SetOpacity(1.0) button.SetProperty(button_property) self.actor = button # Add default events listener to the VTK actor. self.handle_events(self.actor)
def _setup(self): """Setup this UI Component. Return an image as a 2D actor with a specific position. Returns ------- :class:`vtkTexturedActor2D` """ self.texture_polydata = PolyData() self.texture_points = Points() self.texture_points.SetNumberOfPoints(4) polys = CellArray() polys.InsertNextCell(4) polys.InsertCellPoint(0) polys.InsertCellPoint(1) polys.InsertCellPoint(2) polys.InsertCellPoint(3) self.texture_polydata.SetPolys(polys) tc = FloatArray() tc.SetNumberOfComponents(2) tc.SetNumberOfTuples(4) tc.InsertComponent(0, 0, 0.0) tc.InsertComponent(0, 1, 0.0) tc.InsertComponent(1, 0, 1.0) tc.InsertComponent(1, 1, 0.0) tc.InsertComponent(2, 0, 1.0) tc.InsertComponent(2, 1, 1.0) tc.InsertComponent(3, 0, 0.0) tc.InsertComponent(3, 1, 1.0) self.texture_polydata.GetPointData().SetTCoords(tc) texture_mapper = PolyDataMapper2D() texture_mapper = set_input(texture_mapper, self.texture_polydata) image = TexturedActor2D() image.SetMapper(texture_mapper) self.texture = Texture() image.SetTexture(self.texture) image_property = Property2D() image_property.SetOpacity(1.0) image.SetProperty(image_property) self.actor = image # Add default events listener to the VTK actor. self.handle_events(self.actor)
def _update_mapper(self): """ Map vtkPolyData to the actor. """ polydata = PolyData() offsets = self._get_odf_offsets(self.mask) if len(offsets) == 0: self.mapper.SetInputData(polydata) return None sph_dirs = self._get_sphere_directions() sf = self._get_sf(self.mask) all_vertices = self._get_all_vertices(offsets, sph_dirs, sf) all_faces = self._get_all_faces(len(offsets), len(sph_dirs)) all_colors = self._generate_color_for_vertices(sf) # TODO: There is a lot of deep copy here. # Optimize (see viz_network.py example). set_polydata_triangles(polydata, all_faces) set_polydata_vertices(polydata, all_vertices) set_polydata_colors(polydata, all_colors) self.mapper.SetInputData(polydata)
def test_polydata_polygon(interactive=False): # Create a cube my_triangles = np.array( [[0, 6, 4], [0, 2, 6], [0, 3, 2], [0, 1, 3], [2, 7, 6], [2, 3, 7], [4, 6, 7], [4, 7, 5], [0, 4, 5], [0, 5, 1], [1, 5, 7], [1, 7, 3]], dtype='i8') my_vertices = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 0.0], [1.0, 0.0, 1.0], [1.0, 1.0, 0.0], [1.0, 1.0, 1.0]]) colors = my_vertices * 255 my_polydata = PolyData() utils.set_polydata_vertices(my_polydata, my_vertices) utils.set_polydata_triangles(my_polydata, my_triangles) npt.assert_equal(len(my_vertices), my_polydata.GetNumberOfPoints()) npt.assert_equal(len(my_triangles), my_polydata.GetNumberOfCells()) npt.assert_equal(utils.get_polydata_normals(my_polydata), None) res_triangles = utils.get_polydata_triangles(my_polydata) res_vertices = utils.get_polydata_vertices(my_polydata) npt.assert_array_equal(my_vertices, res_vertices) npt.assert_array_equal(my_triangles, res_triangles) utils.set_polydata_colors(my_polydata, colors) npt.assert_equal(utils.get_polydata_colors(my_polydata), colors) utils.update_polydata_normals(my_polydata) normals = utils.get_polydata_normals(my_polydata) npt.assert_equal(len(normals), len(my_vertices)) mapper = utils.get_polymapper_from_polydata(my_polydata) actor1 = utils.get_actor_from_polymapper(mapper) actor2 = utils.get_actor_from_polydata(my_polydata) scene = window.Scene() for act in [actor1, actor2]: scene.add(act) if interactive: window.show(scene) arr = window.snapshot(scene) report = window.analyze_snapshot(arr) npt.assert_equal(report.objects, 1)
def _setup(self): """Set up this UI component. Creating the polygon actor used internally. """ # Setup four points size = (1, 1) self._points = Points() self._points.InsertNextPoint(0, 0, 0) self._points.InsertNextPoint(size[0], 0, 0) self._points.InsertNextPoint(size[0], size[1], 0) self._points.InsertNextPoint(0, size[1], 0) # Create the polygon polygon = Polygon() polygon.GetPointIds().SetNumberOfIds(4) # make a quad polygon.GetPointIds().SetId(0, 0) polygon.GetPointIds().SetId(1, 1) polygon.GetPointIds().SetId(2, 2) polygon.GetPointIds().SetId(3, 3) # Add the polygon to a list of polygons polygons = CellArray() polygons.InsertNextCell(polygon) # Create a PolyData self._polygonPolyData = PolyData() self._polygonPolyData.SetPoints(self._points) self._polygonPolyData.SetPolys(polygons) # Create a mapper and actor mapper = PolyDataMapper2D() mapper = set_input(mapper, self._polygonPolyData) self.actor = Actor2D() self.actor.SetMapper(mapper) # Add default events listener to the VTK actor. self.handle_events(self.actor)
def get_actor_from_primitive(vertices, triangles, colors=None, normals=None, backface_culling=True): """Get actor from a vtkPolyData. Parameters ---------- vertices : (Mx3) ndarray XYZ coordinates of the object triangles: (Nx3) ndarray Indices into vertices; forms triangular faces. colors: (Nx3) or (Nx4) ndarray RGB or RGBA (for opacity) R, G, B and A should be at the range [0, 1] N is equal to the number of vertices. normals: (Nx3) ndarray normals, represented as 2D ndarrays (Nx3) (one per vertex) backface_culling: bool culling of polygons based on orientation of normal with respect to camera. If backface culling is True, polygons facing away from camera are not drawn. Default: True Returns ------- actor : actor """ # Create a Polydata pd = PolyData() set_polydata_vertices(pd, vertices) set_polydata_triangles(pd, triangles) if isinstance(colors, np.ndarray): if len(colors) != len(vertices): msg = "Vertices and Colors should have the same size." msg += " Please, update your color array or use the function " msg += "``fury.primitive.repeat_primitives`` to normalize your " msg += "color array before calling this function. e.g." raise ValueError(msg) set_polydata_colors(pd, colors, array_name="colors") if isinstance(normals, np.ndarray): set_polydata_normals(pd, normals) current_actor = get_actor_from_polydata(pd) current_actor.GetProperty().SetBackfaceCulling(backface_culling) return current_actor
def test_polydata_lines(): colors = np.array([[1, 0, 0], [0, 0, 1.]]) line_1 = np.array([[0, 0, 0], [2, 2, 2], [3, 3, 3.]]) line_2 = line_1 + np.array([0.5, 0., 0.]) lines = [line_1, line_2] pd_lines, is_cmap = utils.lines_to_vtk_polydata(lines, colors) res_lines = utils.get_polydata_lines(pd_lines) npt.assert_array_equal(lines, res_lines) npt.assert_equal(is_cmap, False) res_colors = utils.get_polydata_colors(pd_lines) res_colors = np.unique(res_colors, axis=0) / 255 npt.assert_array_equal(colors, np.flipud(res_colors)) npt.assert_equal(utils.get_polydata_colors(PolyData()), None)
def test_save_and_load_options(): l_ext = ["ply", "vtk"] l_options = [{ 'color_array_name': 'horizon', }, { 'binary': True, }] fname = "temp-io" for ext, option in zip(l_ext, l_options): with InTemporaryDirectory() as odir: data = np.random.randint(0, 255, size=(50, 3)) pd = PolyData() pd.SetPoints(numpy_to_vtk_points(data)) fname_path = pjoin(odir, "{0}.{1}".format(fname, ext)) save_polydata(pd, fname_path, **option) npt.assert_equal(os.path.isfile(fname_path), True) assert_greater(os.stat(fname_path).st_size, 0) out_pd = load_polydata(fname_path) out_data = numpy_support.vtk_to_numpy(out_pd.GetPoints().GetData()) npt.assert_array_equal(data, out_data) l_ext = ["vtk", "vtp", "ply", "stl", "mni.obj"] l_options = [{}, { 'binary': False, }] for ext, option in zip(l_ext, l_options): with InTemporaryDirectory() as odir: data = np.random.randint(0, 255, size=(50, 3)) pd = PolyData() pd.SetPoints(numpy_to_vtk_points(data)) fname_path = pjoin(odir, "{0}.{1}".format(fname, ext)) save_polydata(pd, fname_path, **option) npt.assert_equal(os.path.isfile(fname_path), True) assert_greater(os.stat(fname_path).st_size, 0)
def repeat_sources(centers, colors, active_scalars=1., directions=None, source=None, vertices=None, faces=None, orientation=None): """Transform a vtksource to glyph.""" if source is None and faces is None: raise IOError("A source or faces should be defined") if np.array(colors).ndim == 1: colors = np.tile(colors, (len(centers), 1)) pts = numpy_to_vtk_points(np.ascontiguousarray(centers)) cols = numpy_to_vtk_colors(255 * np.ascontiguousarray(colors)) cols.SetName('colors') if isinstance(active_scalars, (float, int)): active_scalars = np.tile(active_scalars, (len(centers), 1)) if isinstance(active_scalars, np.ndarray): ascalars = numpy_support.numpy_to_vtk(np.asarray(active_scalars), deep=True, array_type=VTK_DOUBLE) ascalars.SetName('active_scalars') if directions is not None: directions_fa = numpy_support.numpy_to_vtk(np.asarray(directions), deep=True, array_type=VTK_DOUBLE) directions_fa.SetName('directions') polydata_centers = PolyData() polydata_geom = PolyData() if faces is not None: set_polydata_vertices(polydata_geom, vertices) set_polydata_triangles(polydata_geom, faces) polydata_centers.SetPoints(pts) polydata_centers.GetPointData().AddArray(cols) if directions is not None: polydata_centers.GetPointData().AddArray(directions_fa) polydata_centers.GetPointData().SetActiveVectors('directions') if isinstance(active_scalars, np.ndarray): polydata_centers.GetPointData().AddArray(ascalars) polydata_centers.GetPointData().SetActiveScalars('active_scalars') glyph = Glyph3D() if faces is None: if orientation is not None: transform = Transform() transform.SetMatrix(numpy_to_vtk_matrix(orientation)) rtrans = TransformPolyDataFilter() rtrans.SetInputConnection(source.GetOutputPort()) rtrans.SetTransform(transform) source = rtrans glyph.SetSourceConnection(source.GetOutputPort()) else: glyph.SetSourceData(polydata_geom) glyph.SetInputData(polydata_centers) glyph.SetOrient(True) glyph.SetScaleModeToScaleByScalar() glyph.SetVectorModeToUseVector() glyph.Update() mapper = PolyDataMapper() mapper.SetInputData(glyph.GetOutput()) mapper.SetScalarModeToUsePointFieldData() mapper.SelectColorArray('colors') actor = Actor() actor.SetMapper(mapper) return actor
def lines_to_vtk_polydata(lines, colors=None): """Create a vtkPolyData with lines and colors. Parameters ---------- lines : list list of N curves represented as 2D ndarrays colors : array (N, 3), list of arrays, tuple (3,), array (K,) If None or False, a standard orientation colormap is used for every line. If one tuple of color is used. Then all streamlines will have the same colour. If an array (N, 3) is given, where N is equal to the number of lines. Then every line is coloured with a different RGB color. If a list of RGB arrays is given then every point of every line takes a different color. If an array (K, 3) is given, where K is the number of points of all lines then every point is colored with a different RGB color. If an array (K,) is given, where K is the number of points of all lines then these are considered as the values to be used by the colormap. If an array (L,) is given, where L is the number of streamlines then these are considered as the values to be used by the colormap per streamline. If an array (X, Y, Z) or (X, Y, Z, 3) is given then the values for the colormap are interpolated automatically using trilinear interpolation. Returns ------- poly_data : vtkPolyData color_is_scalar : bool, true if the color array is a single scalar Scalar array could be used with a colormap lut None if no color was used """ # Get the 3d points_array points_array = np.vstack(lines) # Set Points to vtk array format vtk_points = numpy_to_vtk_points(points_array) # Set Lines to vtk array format vtk_cell_array = numpy_to_vtk_cells(lines) # Create the poly_data poly_data = PolyData() poly_data.SetPoints(vtk_points) poly_data.SetLines(vtk_cell_array) # Get colors_array (reformat to have colors for each points) # - if/else tested and work in normal simple case nb_points = len(points_array) nb_lines = len(lines) lines_range = range(nb_lines) points_per_line = [len(lines[i]) for i in lines_range] points_per_line = np.array(points_per_line, np.intp) color_is_scalar = False if colors is None or colors is False: # set automatic rgb colors cols_arr = line_colors(lines) colors_mapper = np.repeat(lines_range, points_per_line, axis=0) vtk_colors = numpy_to_vtk_colors(255 * cols_arr[colors_mapper]) else: cols_arr = np.asarray(colors) if cols_arr.dtype == object: # colors is a list of colors vtk_colors = numpy_to_vtk_colors(255 * np.vstack(colors)) else: if len(cols_arr) == nb_points: if cols_arr.ndim == 1: # values for every point vtk_colors = numpy_support.numpy_to_vtk(cols_arr, deep=True) color_is_scalar = True elif cols_arr.ndim == 2: # map color to each point vtk_colors = numpy_to_vtk_colors(255 * cols_arr) elif cols_arr.ndim == 1: if len(cols_arr) == nb_lines: # values for every streamline cols_arrx = [] for (i, value) in enumerate(colors): cols_arrx += lines[i].shape[0] * [value] cols_arrx = np.array(cols_arrx) vtk_colors = numpy_support.numpy_to_vtk(cols_arrx, deep=True) color_is_scalar = True else: # the same colors for all points vtk_colors = numpy_to_vtk_colors( np.tile(255 * cols_arr, (nb_points, 1))) elif cols_arr.ndim == 2: # map color to each line colors_mapper = np.repeat(lines_range, points_per_line, axis=0) vtk_colors = numpy_to_vtk_colors(255 * cols_arr[colors_mapper]) else: # colormap # get colors for each vertex cols_arr = map_coordinates_3d_4d(cols_arr, points_array) vtk_colors = numpy_support.numpy_to_vtk(cols_arr, deep=True) color_is_scalar = True vtk_colors.SetName("colors") poly_data.GetPointData().SetScalars(vtk_colors) return poly_data, color_is_scalar
class ImageContainer2D(UI): """A 2D container to hold an image. Currently Supports: - png and jpg/jpeg images Attributes ---------- size: (float, float) Image size (width, height) in pixels. img : ImageData The image loaded from the specified path. """ def __init__(self, img_path, position=(0, 0), size=(100, 100)): """Init class instance. Parameters ---------- img_path : string URL or local path of the image position : (float, float), optional Absolute coordinates (x, y) of the lower-left corner of the image. size : (int, int), optional Width and height in pixels of the image. """ super(ImageContainer2D, self).__init__(position) self.img = load_image(img_path, as_vtktype=True) self.set_img(self.img) self.resize(size) def _get_size(self): lower_left_corner = self.texture_points.GetPoint(0) upper_right_corner = self.texture_points.GetPoint(2) size = np.array(upper_right_corner) - np.array(lower_left_corner) return abs(size[:2]) def _setup(self): """Setup this UI Component. Return an image as a 2D actor with a specific position. Returns ------- :class:`vtkTexturedActor2D` """ self.texture_polydata = PolyData() self.texture_points = Points() self.texture_points.SetNumberOfPoints(4) polys = CellArray() polys.InsertNextCell(4) polys.InsertCellPoint(0) polys.InsertCellPoint(1) polys.InsertCellPoint(2) polys.InsertCellPoint(3) self.texture_polydata.SetPolys(polys) tc = FloatArray() tc.SetNumberOfComponents(2) tc.SetNumberOfTuples(4) tc.InsertComponent(0, 0, 0.0) tc.InsertComponent(0, 1, 0.0) tc.InsertComponent(1, 0, 1.0) tc.InsertComponent(1, 1, 0.0) tc.InsertComponent(2, 0, 1.0) tc.InsertComponent(2, 1, 1.0) tc.InsertComponent(3, 0, 0.0) tc.InsertComponent(3, 1, 1.0) self.texture_polydata.GetPointData().SetTCoords(tc) texture_mapper = PolyDataMapper2D() texture_mapper = set_input(texture_mapper, self.texture_polydata) image = TexturedActor2D() image.SetMapper(texture_mapper) self.texture = Texture() image.SetTexture(self.texture) image_property = Property2D() image_property.SetOpacity(1.0) image.SetProperty(image_property) self.actor = image # Add default events listener to the VTK actor. self.handle_events(self.actor) def _get_actors(self): """Return the actors that compose this UI component.""" return [self.actor] def _add_to_scene(self, scene): """Add all subcomponents or VTK props that compose this UI component. Parameters ---------- scene : scene """ scene.add(self.actor) def resize(self, size): """Resize the image. Parameters ---------- size : (float, float) image size (width, height) in pixels. """ # Update actor. self.texture_points.SetPoint(0, 0, 0, 0.0) self.texture_points.SetPoint(1, size[0], 0, 0.0) self.texture_points.SetPoint(2, size[0], size[1], 0.0) self.texture_points.SetPoint(3, 0, size[1], 0.0) self.texture_polydata.SetPoints(self.texture_points) def _set_position(self, coords): """Set the lower-left corner position of this UI component. Parameters ---------- coords: (float, float) Absolute pixel coordinates (x, y). """ self.actor.SetPosition(*coords) def scale(self, factor): """Scale the image. Parameters ---------- factor : (float, float) Scaling factor (width, height) in pixels. """ self.resize(self.size * factor) def set_img(self, img): """Modify the image used by the vtkTexturedActor2D. Parameters ---------- img : imageData """ self.texture = set_input(self.texture, img)
def __init__(self, directions, indices, values=None, affine=None, colors=None, lookup_colormap=None, linewidth=1, symmetric=True): if affine is not None: w_pos = apply_affine(affine, np.asarray(indices).T) valid_dirs = directions[indices] num_dirs = len(np.nonzero(np.abs(valid_dirs).max(axis=-1) > 0)[0]) pnts_per_line = 2 points_array = np.empty((num_dirs * pnts_per_line, 3)) centers_array = np.empty_like(points_array, dtype=int) diffs_array = np.empty_like(points_array) line_count = 0 for idx, center in enumerate(zip(indices[0], indices[1], indices[2])): if affine is None: xyz = np.asarray(center) else: xyz = w_pos[idx, :] valid_peaks = np.nonzero( np.abs(valid_dirs[idx, :, :]).max(axis=-1) > 0.)[0] for direction in valid_peaks: if values is not None: pv = values[center][direction] else: pv = 1. if symmetric: point_i = directions[center][direction] * pv + xyz point_e = -directions[center][direction] * pv + xyz else: point_i = directions[center][direction] * pv + xyz point_e = xyz diff = point_e - point_i points_array[line_count * pnts_per_line, :] = point_e points_array[line_count * pnts_per_line + 1, :] = point_i centers_array[line_count * pnts_per_line, :] = center centers_array[line_count * pnts_per_line + 1, :] = center diffs_array[line_count * pnts_per_line, :] = diff diffs_array[line_count * pnts_per_line + 1, :] = diff line_count += 1 vtk_points = numpy_to_vtk_points(points_array) vtk_cells = _points_to_vtk_cells(points_array) colors_tuple = _peaks_colors_from_points(points_array, colors=colors) vtk_colors, colors_are_scalars, self.__global_opacity = colors_tuple poly_data = PolyData() poly_data.SetPoints(vtk_points) poly_data.SetLines(vtk_cells) poly_data.GetPointData().SetScalars(vtk_colors) self.__mapper = PolyDataMapper() self.__mapper.SetInputData(poly_data) self.__mapper.ScalarVisibilityOn() self.__mapper.SetScalarModeToUsePointFieldData() self.__mapper.SelectColorArray('colors') self.__mapper.Update() self.SetMapper(self.__mapper) attribute_to_actor(self, centers_array, 'center') attribute_to_actor(self, diffs_array, 'diff') vs_dec_code = import_fury_shader('peak_dec.vert') vs_impl_code = import_fury_shader('peak_impl.vert') fs_dec_code = import_fury_shader('peak_dec.frag') fs_impl_code = import_fury_shader('peak_impl.frag') shader_to_actor(self, 'vertex', decl_code=vs_dec_code, impl_code=vs_impl_code) shader_to_actor(self, 'fragment', decl_code=fs_dec_code) shader_to_actor(self, 'fragment', impl_code=fs_impl_code, block='light') # Color scale with a lookup table if colors_are_scalars: if lookup_colormap is None: lookup_colormap = colormap_lookup_table() self.__mapper.SetLookupTable(lookup_colormap) self.__mapper.UseLookupTableScalarRangeOn() self.__mapper.Update() self.__lw = linewidth self.GetProperty().SetLineWidth(self.__lw) if self.__global_opacity >= 0: self.GetProperty().SetOpacity(self.__global_opacity) self.__min_centers = np.min(indices, axis=1) self.__max_centers = np.max(indices, axis=1) self.__is_range = True self.__low_ranges = self.__min_centers self.__high_ranges = self.__max_centers self.__cross_section = self.__high_ranges // 2 self.__mapper.AddObserver(Command.UpdateShaderEvent, self.__display_peaks_vtk_callback)
should apply for any surface. """ import numpy as np ############################################################################### # Import useful functions from fury import window, utils from fury.io import save_polydata, load_polydata from fury.lib import PolyData ############################################################################### # Create an empty ``PolyData`` my_polydata = PolyData() ############################################################################### # Create a cube with vertices and triangles as numpy arrays my_vertices = np.array([[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [0.0, 1.0, 1.0], [1.0, 0.0, 0.0], [1.0, 0.0, 1.0], [1.0, 1.0, 0.0], [1.0, 1.0, 1.0]]) # the data type is needed to mention here, numpy.int64 my_triangles = np.array( [[0, 6, 4], [0, 2, 6], [0, 3, 2], [0, 1, 3], [2, 7, 6], [2, 3, 7], [4, 6, 7], [4, 7, 5], [0, 4, 5], [0, 5, 1], [1, 5, 7], [1, 7, 3]], dtype='i8') ############################################################################### # Set vertices and triangles in the ``PolyData``
class Button2D(UI): """A 2D overlay button and is of type vtkTexturedActor2D. Currently supports:: - Multiple icons. - Switching between icons. """ def __init__(self, icon_fnames, position=(0, 0), size=(30, 30)): """Init class instance. Parameters ---------- icon_fnames : List(string, string) ((iconname, filename), (iconname, filename), ....) position : (float, float), optional Absolute coordinates (x, y) of the lower-left corner of the button. size : (int, int), optional Width and height in pixels of the button. """ super(Button2D, self).__init__(position) self.icon_extents = dict() self.icons = self._build_icons(icon_fnames) self.icon_names = [icon[0] for icon in self.icons] self.current_icon_id = 0 self.current_icon_name = self.icon_names[self.current_icon_id] self.set_icon(self.icons[self.current_icon_id][1]) self.resize(size) def _get_size(self): lower_left_corner = self.texture_points.GetPoint(0) upper_right_corner = self.texture_points.GetPoint(2) size = np.array(upper_right_corner) - np.array(lower_left_corner) return abs(size[:2]) def _build_icons(self, icon_fnames): """Convert file names to ImageData. A pre-processing step to prevent re-read of file names during every state change. Parameters ---------- icon_fnames : List(string, string) ((iconname, filename), (iconname, filename), ....) Returns ------- icons : List A list of corresponding ImageData. """ icons = [] for icon_name, icon_fname in icon_fnames: icons.append((icon_name, load_image(icon_fname, as_vtktype=True))) return icons def _setup(self): """Set up this UI component. Creating the button actor used internally. """ # This is highly inspired by # https://github.com/Kitware/VTK/blob/c3ec2495b183e3327820e927af7f8f90d34c3474/Interaction/Widgets/vtkBalloonRepresentation.cxx#L47 self.texture_polydata = PolyData() self.texture_points = Points() self.texture_points.SetNumberOfPoints(4) polys = CellArray() polys.InsertNextCell(4) polys.InsertCellPoint(0) polys.InsertCellPoint(1) polys.InsertCellPoint(2) polys.InsertCellPoint(3) self.texture_polydata.SetPolys(polys) tc = FloatArray() tc.SetNumberOfComponents(2) tc.SetNumberOfTuples(4) tc.InsertComponent(0, 0, 0.0) tc.InsertComponent(0, 1, 0.0) tc.InsertComponent(1, 0, 1.0) tc.InsertComponent(1, 1, 0.0) tc.InsertComponent(2, 0, 1.0) tc.InsertComponent(2, 1, 1.0) tc.InsertComponent(3, 0, 0.0) tc.InsertComponent(3, 1, 1.0) self.texture_polydata.GetPointData().SetTCoords(tc) texture_mapper = PolyDataMapper2D() texture_mapper = set_input(texture_mapper, self.texture_polydata) button = TexturedActor2D() button.SetMapper(texture_mapper) self.texture = Texture() button.SetTexture(self.texture) button_property = Property2D() button_property.SetOpacity(1.0) button.SetProperty(button_property) self.actor = button # Add default events listener to the VTK actor. self.handle_events(self.actor) def _get_actors(self): """Get the actors composing this UI component.""" return [self.actor] def _add_to_scene(self, scene): """Add all subcomponents or VTK props that compose this UI component. Parameters ---------- scene : scene """ scene.add(self.actor) def resize(self, size): """Resize the button. Parameters ---------- size : (float, float) Button size (width, height) in pixels. """ # Update actor. self.texture_points.SetPoint(0, 0, 0, 0.0) self.texture_points.SetPoint(1, size[0], 0, 0.0) self.texture_points.SetPoint(2, size[0], size[1], 0.0) self.texture_points.SetPoint(3, 0, size[1], 0.0) self.texture_polydata.SetPoints(self.texture_points) def _set_position(self, coords): """Set the lower-left corner position of this UI component. Parameters ---------- coords: (float, float) Absolute pixel coordinates (x, y). """ self.actor.SetPosition(*coords) @property def color(self): """Get the button's color.""" color = self.actor.GetProperty().GetColor() return np.asarray(color) @color.setter def color(self, color): """Set the button's color. Parameters ---------- color : (float, float, float) RGB. Must take values in [0, 1]. """ self.actor.GetProperty().SetColor(*color) def scale(self, factor): """Scale the button. Parameters ---------- factor : (float, float) Scaling factor (width, height) in pixels. """ self.resize(self.size * factor) def set_icon_by_name(self, icon_name): """Set the button icon using its name. Parameters ---------- icon_name : str """ icon_id = self.icon_names.index(icon_name) self.set_icon(self.icons[icon_id][1]) def set_icon(self, icon): """Modify the icon used by the vtkTexturedActor2D. Parameters ---------- icon : imageData """ self.texture = set_input(self.texture, icon) def next_icon_id(self): """Set the next icon ID while cycling through icons.""" self.current_icon_id += 1 if self.current_icon_id == len(self.icons): self.current_icon_id = 0 self.current_icon_name = self.icon_names[self.current_icon_id] def next_icon(self): """Increment the state of the Button. Also changes the icon. """ self.next_icon_id() self.set_icon(self.icons[self.current_icon_id][1])
class Rectangle2D(UI): """A 2D rectangle sub-classed from UI.""" def __init__(self, size=(0, 0), position=(0, 0), color=(1, 1, 1), opacity=1.0): """Initialize a rectangle. Parameters ---------- size : (int, int) The size of the rectangle (width, height) in pixels. position : (float, float) Coordinates (x, y) of the lower-left corner of the rectangle. color : (float, float, float) Must take values in [0, 1]. opacity : float Must take values in [0, 1]. """ super(Rectangle2D, self).__init__(position) self.color = color self.opacity = opacity self.resize(size) def _setup(self): """Set up this UI component. Creating the polygon actor used internally. """ # Setup four points size = (1, 1) self._points = Points() self._points.InsertNextPoint(0, 0, 0) self._points.InsertNextPoint(size[0], 0, 0) self._points.InsertNextPoint(size[0], size[1], 0) self._points.InsertNextPoint(0, size[1], 0) # Create the polygon polygon = Polygon() polygon.GetPointIds().SetNumberOfIds(4) # make a quad polygon.GetPointIds().SetId(0, 0) polygon.GetPointIds().SetId(1, 1) polygon.GetPointIds().SetId(2, 2) polygon.GetPointIds().SetId(3, 3) # Add the polygon to a list of polygons polygons = CellArray() polygons.InsertNextCell(polygon) # Create a PolyData self._polygonPolyData = PolyData() self._polygonPolyData.SetPoints(self._points) self._polygonPolyData.SetPolys(polygons) # Create a mapper and actor mapper = PolyDataMapper2D() mapper = set_input(mapper, self._polygonPolyData) self.actor = Actor2D() self.actor.SetMapper(mapper) # Add default events listener to the VTK actor. self.handle_events(self.actor) def _get_actors(self): """Get the actors composing this UI component.""" return [self.actor] def _add_to_scene(self, scene): """Add all subcomponents or VTK props that compose this UI component. Parameters ---------- scene : scene """ scene.add(self.actor) def _get_size(self): # Get 2D coordinates of two opposed corners of the rectangle. lower_left_corner = np.array(self._points.GetPoint(0)[:2]) upper_right_corner = np.array(self._points.GetPoint(2)[:2]) size = abs(upper_right_corner - lower_left_corner) return size @property def width(self): return self._points.GetPoint(2)[0] @width.setter def width(self, width): self.resize((width, self.height)) @property def height(self): return self._points.GetPoint(2)[1] @height.setter def height(self, height): self.resize((self.width, height)) def resize(self, size): """Set the button size. Parameters ---------- size : (float, float) Button size (width, height) in pixels. """ self._points.SetPoint(0, 0, 0, 0.0) self._points.SetPoint(1, size[0], 0, 0.0) self._points.SetPoint(2, size[0], size[1], 0.0) self._points.SetPoint(3, 0, size[1], 0.0) self._polygonPolyData.SetPoints(self._points) mapper = PolyDataMapper2D() mapper = set_input(mapper, self._polygonPolyData) self.actor.SetMapper(mapper) def _set_position(self, coords): """Set the lower-left corner position of this UI component. Parameters ---------- coords: (float, float) Absolute pixel coordinates (x, y). """ self.actor.SetPosition(*coords) @property def color(self): """Get the rectangle's color.""" color = self.actor.GetProperty().GetColor() return np.asarray(color) @color.setter def color(self, color): """Set the rectangle's color. Parameters ---------- color : (float, float, float) RGB. Must take values in [0, 1]. """ self.actor.GetProperty().SetColor(*color) @property def opacity(self): """Get the rectangle's opacity.""" return self.actor.GetProperty().GetOpacity() @opacity.setter def opacity(self, opacity): """Set the rectangle's opacity. Parameters ---------- opacity : float Degree of transparency. Must be between [0, 1]. """ self.actor.GetProperty().SetOpacity(opacity)
def ribbon(molecule): """Create an actor for ribbon molecular representation. Parameters ---------- molecule : Molecule The molecule to be rendered. Returns ------- molecule_actor : vtkActor Actor created to render the rubbon representation of the molecule to be visualized. References ---------- Richardson, J.S. The anatomy and taxonomy of protein structure `Advances in Protein Chemistry, 1981, 34, 167-339. <https://doi.org/10.1016/S0065-3233(08)60520-3>`_ """ coords = get_all_atomic_positions(molecule) all_atomic_numbers = get_all_atomic_numbers(molecule) num_total_atoms = molecule.total_num_atoms secondary_structures = np.ones(num_total_atoms) for i in range(num_total_atoms): secondary_structures[i] = ord('c') resi = molecule.residue_seq[i] for j, _ in enumerate(molecule.sheet): sheet = molecule.sheet[j] if molecule.chain[i] != sheet[0] or resi < sheet[1] or \ resi > sheet[3]: continue secondary_structures[i] = ord('s') for j, _ in enumerate(molecule.helix): helix = molecule.helix[j] if molecule.chain[i] != helix[0] or resi < helix[1] or \ resi > helix[3]: continue secondary_structures[i] = ord('h') output = PolyData() # for atomic numbers atomic_num_arr = nps.numpy_to_vtk(num_array=all_atomic_numbers, deep=True, array_type=VTK_ID_TYPE) # setting the array name to atom_type as vtkProteinRibbonFilter requires # the array to be named atom_type atomic_num_arr.SetName("atom_type") output.GetPointData().AddArray(atomic_num_arr) # for atom names atom_names = StringArray() # setting the array name to atom_types as vtkProteinRibbonFilter requires # the array to be named atom_types atom_names.SetName("atom_types") atom_names.SetNumberOfTuples(num_total_atoms) for i in range(num_total_atoms): atom_names.SetValue(i, molecule.atom_names[i]) output.GetPointData().AddArray(atom_names) # for residue sequences residue_seq = nps.numpy_to_vtk(num_array=molecule.residue_seq, deep=True, array_type=VTK_ID_TYPE) residue_seq.SetName("residue") output.GetPointData().AddArray(residue_seq) # for chain chain = nps.numpy_to_vtk(num_array=molecule.chain, deep=True, array_type=VTK_UNSIGNED_CHAR) chain.SetName("chain") output.GetPointData().AddArray(chain) # for secondary structures s_s = nps.numpy_to_vtk(num_array=secondary_structures, deep=True, array_type=VTK_UNSIGNED_CHAR) s_s.SetName("secondary_structures") output.GetPointData().AddArray(s_s) # for secondary structures begin newarr = np.ones(num_total_atoms) s_sb = nps.numpy_to_vtk(num_array=newarr, deep=True, array_type=VTK_UNSIGNED_CHAR) s_sb.SetName("secondary_structures_begin") output.GetPointData().AddArray(s_sb) # for secondary structures end newarr = np.ones(num_total_atoms) s_se = nps.numpy_to_vtk(num_array=newarr, deep=True, array_type=VTK_UNSIGNED_CHAR) s_se.SetName("secondary_structures_end") output.GetPointData().AddArray(s_se) # for is_hetatm is_hetatm = nps.numpy_to_vtk(num_array=molecule.is_hetatm, deep=True, array_type=VTK_UNSIGNED_CHAR) is_hetatm.SetName("ishetatm") output.GetPointData().AddArray(is_hetatm) # for model model = nps.numpy_to_vtk(num_array=molecule.model, deep=True, array_type=VTK_UNSIGNED_INT) model.SetName("model") output.GetPointData().AddArray(model) table = PTable() # for colors and radii of hetero-atoms radii = np.ones((num_total_atoms, 3)) rgb = np.ones((num_total_atoms, 3)) for i in range(num_total_atoms): radii[i] = np.repeat(table.atomic_radius(all_atomic_numbers[i], 'VDW'), 3) rgb[i] = table.atom_color(all_atomic_numbers[i]) Rgb = nps.numpy_to_vtk(num_array=rgb, deep=True, array_type=VTK_UNSIGNED_CHAR) Rgb.SetName("rgb_colors") output.GetPointData().SetScalars(Rgb) Radii = nps.numpy_to_vtk(num_array=radii, deep=True, array_type=VTK_FLOAT) Radii.SetName("radius") output.GetPointData().SetVectors(Radii) # setting the coordinates points = numpy_to_vtk_points(coords) output.SetPoints(points) ribbonFilter = ProteinRibbonFilter() ribbonFilter.SetInputData(output) ribbonFilter.SetCoilWidth(0.2) ribbonFilter.SetDrawSmallMoleculesAsSpheres(0) mapper = PolyDataMapper() mapper.SetInputConnection(ribbonFilter.GetOutputPort()) molecule_actor = Actor() molecule_actor.SetMapper(mapper) return molecule_actor