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 CreateSurfaceFromPolydata(self, polydata, overwrite=False, index=None, name=None, colour=None, transparency=None, volume=None, area=None, scalar=False): normals = vtk.vtkPolyDataNormals() normals.SetInputData(polydata) normals.SetFeatureAngle(80) normals.AutoOrientNormalsOn() normals.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(normals.GetOutput()) if scalar: mapper.ScalarVisibilityOn() else: mapper.ScalarVisibilityOff() # mapper.ImmediateModeRenderingOn() # improve performance actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetBackfaceCulling(1) if self.convert2inv: # convert between invesalius and world space with shift in the Y coordinate affine = sl.Slice().affine # TODO: Check that this is needed with the new way of using affine # now the affine should be at least the identity(4) and never None if affine is not None: 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) actor.SetUserMatrix(affine_vtk) 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 = vtk.vtkTriangleFilter() triangle_filter.SetInputData(polydata) triangle_filter.Update() measured_polydata = vtk.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