def __init__(self, poly_src: vtkPolyDataAlgorithm, parent: Optional['QObject'] = None) -> None: super().__init__(parent=parent) self._poly_src = poly_src self.id = QUuid.createUuid().toString() self.actor = vtkActor() mapper = vtkPolyDataMapper() mapper.SetInputConnection(poly_src.GetOutputPort()) self.actor.SetMapper(mapper) user_transform = vtkTransform() user_transform.Identity() user_transform.PostMultiply() self.actor.SetUserTransform(user_transform) self.actor.ComputeMatrix() transform = vtkTransform() transform.SetMatrix(self.actor.GetMatrix()) self._coord_converter = vtkTransformPolyDataFilter() self._coord_converter.SetTransform(transform) self._coord_converter.AddInputData(poly_src.GetOutput()) self._coord_converter.Update() self._voxelizer = VoxelSlicer() self._voxelizer.SetInputConnection( self._coord_converter.GetOutputPort()) self.results = vtkActor() self._init_input_id_key() self._init_output_id_key(self.results)
def _arrow_glyph(grid, factor): glyph = vtkGlyphSource2D() glyph.SetGlyphTypeToArrow() glyph.FilledOff() glyph.Update() # fix position tr = vtkTransform() tr.Translate(0.5, 0., 0.) trp = vtkTransformPolyDataFilter() trp.SetInputConnection(glyph.GetOutputPort()) trp.SetTransform(tr) trp.Update() alg = _glyph( grid, scale_mode='vector', scalars=False, orient='vec', factor=factor, geom=trp.GetOutputPort(), ) mapper = vtkDataSetMapper() mapper.SetInputConnection(alg.GetOutputPort()) return mapper
def TransformPeelPosition(self, p): peel_transform = vtkTransform() if not np.all(np.equal(self.affine, np.eye(4))): affine_vtk = self.CreateTransformedVTKAffine() peel_transform.SetMatrix(affine_vtk) refpeelspace = vtkTransformPolyDataFilter() refpeelspace.SetInputData(self.peel[p]) refpeelspace.SetTransform(peel_transform) refpeelspace.Update() currentPeel = refpeelspace.GetOutput() return currentPeel
def _do_surface_creation(self, mask, mask_sFormMatrix=None): if mask_sFormMatrix is None: mask_sFormMatrix = vtkMatrix4x4() value = np.mean(mask.GetScalarRange()) # Use the mask to create isosurface mc = vtkContourFilter() mc.SetInputData(mask) mc.SetValue(0, value) mc.ComputeNormalsOn() mc.Update() # Mask isosurface refSurface = mc.GetOutput() # Create a uniformly meshed surface tmpPeel = downsample(refSurface) # Standard space coordinates # Apply coordinate transform to the meshed mask mask_ijk2xyz = vtkTransform() mask_ijk2xyz.SetMatrix(mask_sFormMatrix) mask_ijk2xyz_filter = vtkTransformPolyDataFilter() mask_ijk2xyz_filter.SetInputData(tmpPeel) mask_ijk2xyz_filter.SetTransform(mask_ijk2xyz) mask_ijk2xyz_filter.Update() # Smooth the mesh tmpPeel = smooth(mask_ijk2xyz_filter.GetOutput()) # Configure calculation of normals tmpPeel = fixMesh(tmpPeel) # Remove duplicate points etc # tmpPeel = cleanMesh(tmpPeel) # Generate triangles tmpPeel = upsample(tmpPeel) tmpPeel = smooth(tmpPeel) tmpPeel = fixMesh(tmpPeel) tmpPeel = cleanMesh(tmpPeel) refImageSpace2_xyz_transform = vtkTransform() refImageSpace2_xyz_transform.SetMatrix(vtk_utils.numpy_to_vtkMatrix4x4(np.linalg.inv(self.affine))) self.refImageSpace2_xyz = vtkTransformPolyDataFilter() self.refImageSpace2_xyz.SetTransform(refImageSpace2_xyz_transform) xyz2_refImageSpace_transform = vtkTransform() xyz2_refImageSpace_transform.SetMatrix(vtk_utils.numpy_to_vtkMatrix4x4(self.affine)) self.xyz2_refImageSpace = vtkTransformPolyDataFilter() self.xyz2_refImageSpace.SetTransform(xyz2_refImageSpace_transform) currentPeel = tmpPeel self.currentPeelNo = 0 currentPeel= self.MapImageOnCurrentPeel(currentPeel) newPeel = vtkPolyData() newPeel.DeepCopy(currentPeel) newPeel.DeepCopy(currentPeel) self.peel_normals = vtkFloatArray() self.peel_centers = vtkFloatArray() self.peel.append(newPeel) self.currentPeelActor = vtkActor() if not np.all(np.equal(self.affine, np.eye(4))): affine_vtk = self.CreateTransformedVTKAffine() self.currentPeelActor.SetUserMatrix(affine_vtk) self.GetCurrentPeelActor(currentPeel) self.peelActors.append(self.currentPeelActor) # locator will later find the triangle on the peel surface where the coil's normal intersect self.locator = vtkCellLocator() self.PeelDown(currentPeel)
def quiver3d(self, x, y, z, u, v, w, color, scale, mode, resolution=8, glyph_height=None, glyph_center=None, glyph_resolution=None, opacity=1.0, scale_mode='none', scalars=None, colormap=None, backface_culling=False, line_width=2., name=None, glyph_width=None, glyph_depth=None, glyph_radius=0.15, solid_transform=None, *, clim=None): _check_option('mode', mode, ALLOWED_QUIVER_MODES) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=FutureWarning) factor = scale vectors = np.c_[u, v, w] points = np.vstack(np.c_[x, y, z]) n_points = len(points) cell_type = np.full(n_points, VTK_VERTEX) cells = np.c_[np.full(n_points, 1), range(n_points)] args = (cells, cell_type, points) if not VTK9: args = (np.arange(n_points) * 3, ) + args grid = UnstructuredGrid(*args) if scalars is None: scalars = np.ones((n_points, )) _point_data(grid)['scalars'] = np.array(scalars) _point_data(grid)['vec'] = vectors if mode == '2darrow': return _arrow_glyph(grid, factor), grid elif mode == 'arrow': alg = _glyph(grid, orient='vec', scalars='scalars', factor=factor) mesh = pyvista.wrap(alg.GetOutput()) else: tr = None if mode == 'cone': glyph = vtkConeSource() glyph.SetCenter(0.5, 0, 0) if glyph_radius is not None: glyph.SetRadius(glyph_radius) elif mode == 'cylinder': glyph = vtkCylinderSource() if glyph_radius is not None: glyph.SetRadius(glyph_radius) elif mode == 'oct': glyph = vtkPlatonicSolidSource() glyph.SetSolidTypeToOctahedron() else: assert mode == 'sphere', mode # guaranteed above glyph = vtkSphereSource() if mode == 'cylinder': if glyph_height is not None: glyph.SetHeight(glyph_height) if glyph_center is not None: glyph.SetCenter(glyph_center) if glyph_resolution is not None: glyph.SetResolution(glyph_resolution) tr = vtkTransform() tr.RotateWXYZ(90, 0, 0, 1) elif mode == 'oct': if solid_transform is not None: assert solid_transform.shape == (4, 4) tr = vtkTransform() tr.SetMatrix( solid_transform.astype(np.float64).ravel()) if tr is not None: # fix orientation glyph.Update() trp = vtkTransformPolyDataFilter() trp.SetInputData(glyph.GetOutput()) trp.SetTransform(tr) glyph = trp glyph.Update() geom = glyph.GetOutput() mesh = grid.glyph(orient='vec', scale=scale_mode == 'vector', factor=factor, geom=geom) actor = _add_mesh( self.plotter, mesh=mesh, color=color, opacity=opacity, scalars=None, colormap=colormap, show_scalar_bar=False, backface_culling=backface_culling, clim=clim, ) return actor, mesh
def CreateSurfaceFromPolydata(self, polydata, overwrite=False, index=None, name=None, colour=None, transparency=None, volume=None, area=None, scalar=False): if self.convert_to_inv: # convert between invesalius and world space with shift in the Y coordinate matrix_shape = sl.Slice().matrix.shape spacing = sl.Slice().spacing img_shift = spacing[1] * (matrix_shape[1] - 1) affine = sl.Slice().affine.copy() affine[1, -1] -= img_shift affine_vtk = vtk_utils.numpy_to_vtkMatrix4x4(affine) polydata_transform = vtkTransform() polydata_transform.PostMultiply() polydata_transform.Concatenate(affine_vtk) transformFilter = vtkTransformPolyDataFilter() transformFilter.SetTransform(polydata_transform) transformFilter.SetInputData(polydata) transformFilter.Update() polydata = transformFilter.GetOutput() self.convert_to_inv = False normals = vtkPolyDataNormals() normals.SetInputData(polydata) normals.SetFeatureAngle(80) normals.AutoOrientNormalsOn() normals.Update() mapper = vtkPolyDataMapper() mapper.SetInputData(normals.GetOutput()) if scalar: mapper.ScalarVisibilityOn() else: mapper.ScalarVisibilityOff() # mapper.ImmediateModeRenderingOn() # improve performance actor = vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetBackfaceCulling(1) if overwrite: if index is None: index = self.last_surface_index surface = Surface(index=index) else: surface = Surface() if not colour: surface.colour = random.choice(const.SURFACE_COLOUR) else: surface.colour = colour surface.polydata = polydata if transparency: surface.transparency = transparency if name: surface.name = name # Append surface into Project.surface_dict proj = prj.Project() if overwrite: proj.ChangeSurface(surface) else: index = proj.AddSurface(surface) surface.index = index self.last_surface_index = index # Set actor colour and transparency actor.GetProperty().SetColor(surface.colour) actor.GetProperty().SetOpacity(1 - surface.transparency) if overwrite and self.actors_dict.keys(): try: old_actor = self.actors_dict[index] Publisher.sendMessage('Remove surface actor from viewer', actor=old_actor) except KeyError: pass self.actors_dict[surface.index] = actor session = ses.Session() session.ChangeProject() # The following lines have to be here, otherwise all volumes disappear if not volume or not area: triangle_filter = vtkTriangleFilter() triangle_filter.SetInputData(polydata) triangle_filter.Update() measured_polydata = vtkMassProperties() measured_polydata.SetInputConnection( triangle_filter.GetOutputPort()) measured_polydata.Update() volume = measured_polydata.GetVolume() area = measured_polydata.GetSurfaceArea() surface.volume = volume surface.area = area print(">>>>", surface.volume) else: surface.volume = volume surface.area = area self.last_surface_index = surface.index Publisher.sendMessage('Load surface actor into viewer', actor=actor) Publisher.sendMessage('Update surface info in GUI', surface=surface) return surface.index