def save_stl(array, spacing, origin, name): # array to vtkImageData flatten_array = array.ravel() shape = np.array(array.shape) vtk_data_array = numpy_to_vtk( num_array= flatten_array, # ndarray contains the fitting result from the points. It is a 3D array deep=True, array_type=vtk.VTK_FLOAT) # convert vessel array to poly and save as STL img_vtk = vtk.vtkImageData() img_vtk.SetDimensions(shape[::-1]) img_vtk.SetSpacing(spacing) img_vtk.SetOrigin(origin) img_vtk.SetDirectionMatrix(-1, 0, 0, 0, -1, 0, 0, 0, 1) img_vtk.GetPointData().SetScalars(vtk_data_array) surf = vtk.vtkDiscreteMarchingCubes() surf.SetInputData(img_vtk) surf.SetValue(0, array.max()) # smoothing the mesh smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(surf.GetOutputPort()) smoother.SetNumberOfIterations(50) smoother.SetRelaxationFactor(0.1) smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOn() smoother.Update() stl_writer = vtk.vtkSTLWriter() stl_writer.SetFileName(name) stl_writer.SetInputData(smoother.GetOutput()) stl_writer.Write()
def smooth(vtkPoly, iterations=100, relaxation=0.1, edgesmoothing=True): # Smooth mesh with Laplacian Smoothing smooth = vtkSmoothPolyDataFilter() smooth.SetInputData(vtkPoly) smooth.SetRelaxationFactor(relaxation) smooth.SetNumberOfIterations(iterations) if edgesmoothing: smooth.FeatureEdgeSmoothingOn() else: smooth.FeatureEdgeSmoothingOff() smooth.BoundarySmoothingOn() smooth.Update() smoothPoly = vtkPolyData() smoothPoly.ShallowCopy(smooth.GetOutput()) # Find mesh normals (Not sure why) normal = vtkPolyDataNormals() normal.SetInputData(smoothPoly) normal.ComputePointNormalsOn() normal.ComputeCellNormalsOn() normal.Update() normalPoly = vtkPolyData() normalPoly.ShallowCopy(normal.GetOutput()) return normalPoly
def Convert(image: Image_Data, threshold1, threshold2, smooth_iterations=0): ''' Input: 需转换的图像,两个阈值,平滑迭代次数 Output: 转换得到的曲面数据 Description: 使用Marching cube方法将标签图转换为曲面,并平滑。两个阈值间的灰度范围为前景,其余部分为背景 ''' label = Threshold_Seg.Threshold(image, threshold1, threshold2) Extractor = vtk.vtkMarchingCubes() Extractor.SetInputData(label.Get_vtkImageData()) Extractor.SetValue(0, 1) Smoother = vtk.vtkSmoothPolyDataFilter() Smoother.SetInputConnection(Extractor.GetOutputPort()) Smoother.SetNumberOfIterations(smooth_iterations) Smoother.SetRelaxationFactor(0.1) Smoother.FeatureEdgeSmoothingOff() Smoother.BoundarySmoothingOn() Smoother.Update() Normals = vtk.vtkPolyDataNormals() Normals.SetInputConnection(Smoother.GetOutputPort()) Normals.SetFeatureAngle(60.0) Stripper = vtk.vtkStripper() Stripper.SetInputConnection(Normals.GetOutputPort()) Stripper.Update() polydata = Poly_Data() polydata.Init_From_Vtk(Stripper.GetOutput()) return polydata
def extract(color, isovalue): skinExtractor = vtk.vtkDiscreteMarchingCubes() skinExtractor.SetInputConnection(dataImporter.GetOutputPort()) skinExtractor.SetValue(0, isovalue) smooth = vtk.vtkSmoothPolyDataFilter() smooth.SetInputConnection(skinExtractor.GetOutputPort()) smooth.SetNumberOfIterations(15) smooth.SetRelaxationFactor(0.2) smooth.FeatureEdgeSmoothingOff() smooth.BoundarySmoothingOn() smooth.Update() skinStripper = vtk.vtkStripper() skinStripper.SetInputConnection(smooth.GetOutputPort()) skinMapper = vtk.vtkOpenGLPolyDataMapper() skinMapper.SetInputConnection(skinStripper.GetOutputPort()) skinMapper.ScalarVisibilityOff() skin = vtk.vtkOpenGLActor() skin.SetMapper(skinMapper) skin.GetProperty().SetDiffuseColor(colors.GetColor3d(color)) skin.GetProperty().SetSpecular(.3) skin.GetProperty().SetSpecularPower(20) return skin
def process_data(input_file, color): reader = vtk.vtkNIFTIImageReader() reader.SetFileName(input_file) extractor = vtk.vtkMarchingCubes() extractor.SetInputConnection(reader.GetOutputPort()) extractor.SetValue(0, 1) smooth_filter = vtk.vtkSmoothPolyDataFilter() smooth_filter.SetInputConnection(extractor.GetOutputPort()) smooth_filter.SetNumberOfIterations(5) smooth_filter.SetRelaxationFactor(0.5) smooth_filter.FeatureEdgeSmoothingOff() smooth_filter.BoundarySmoothingOn() smooth_filter.Update() cleaned = vtk.vtkCleanPolyData() cleaned.SetInputData(smooth_filter.GetOutput()) normal_generator = vtk.vtkPolyDataNormals() normal_generator.ComputePointNormalsOn() normal_generator.ComputeCellNormalsOn() normal_generator.SetInputConnection(cleaned.GetOutputPort()) normal_generator.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(normal_generator.GetOutputPort()) mapper.ScalarVisibilityOff() actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetDiffuseColor(color) return normal_generator, actor
def smoothPolyData(poly, relax=0.1): # mergeDuplicateNodes may be needed before applying this filter smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(poly) smoother.SetRelaxationFactor(relax) smoother.Update() return smoother.GetOutput()
def __init__(self, grid, vtkish_polydata=None, angle=15): vtkPolyDataPipeline.__init__(self, vtkish_polydata) # Make sure grid argument is correct type assert isinstance(grid, vtkVolumeGrid) self.grid = grid # Split polys with intersection angles greater than angle vtk_dnorm = vtkPolyDataNormals() vtk_dnorm.SetFeatureAngle(angle) vtk_dnorm.SplittingOn() vtk_dnorm.ComputeCellNormalsOff() vtk_dnorm.ComputePointNormalsOff() self.append(vtk_dnorm) relax = self.grid.get_relaxation_factor() if relax is not None: print 'relax=',relax #vtk_subdiv = vtkButterflySubdivisionFilter() vtk_subdiv = vtkLinearSubdivisionFilter() self.append(vtk_subdiv) # Smooth out some of the sharp points. vtk_smooth = vtkSmoothPolyDataFilter() vtk_smooth.SetRelaxationFactor(relax) self.append(vtk_smooth)
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') smoothingFilter = None if self.Method is 'taubin': smoothingFilter = vtk.vtkWindowedSincPolyDataFilter() smoothingFilter.SetInputData(self.Surface) smoothingFilter.SetNumberOfIterations(self.NumberOfIterations) smoothingFilter.SetPassBand(self.PassBand) smoothingFilter.SetBoundarySmoothing(self.BoundarySmoothing) smoothingFilter.SetNormalizeCoordinates(self.NormalizeCoordinates) smoothingFilter.Update() elif self.Method is 'laplace': smoothingFilter = vtk.vtkSmoothPolyDataFilter() smoothingFilter.SetInputData(self.Surface) smoothingFilter.SetNumberOfIterations(self.NumberOfIterations) smoothingFilter.SetRelaxationFactor(self.RelaxationFactor) smoothingFilter.Update() else: self.PrintError('Error: smoothing method not supported.') self.Surface = smoothingFilter.GetOutput() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = self.Surface normals.Execute() self.Surface = normals.Surface
def marching_cubes(source): # Render in 3D with marching cubes. marchingCubes = vtk.vtkMarchingCubes() marchingCubes.SetInputData(source) marchingCubes.ComputeNormalsOn() marchingCubes.SetValue(0, 1.0) # Smooth the generated surface. smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputConnection(marchingCubes.GetOutputPort()) smoothFilter.SetNumberOfIterations(14) smoothFilter.SetRelaxationFactor(0.4) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.Update() # Update normals on newly smoothed polyData. normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputConnection(smoothFilter.GetOutputPort()) normalGenerator.ComputePointNormalsOn() normalGenerator.ComputeCellNormalsOn() normalGenerator.Update() return normalGenerator
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__( self, module_manager, vtk.vtkSmoothPolyDataFilter(), 'Processing.', ('vtkPolyData', 'vtkPolyData'), ('vtkPolyData',), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def Execute(self): if self.Surface == None: self.PrintError('Error: No input surface.') smoothingFilter = None if self.Method is 'taubin': smoothingFilter = vtk.vtkWindowedSincPolyDataFilter() smoothingFilter.SetInput(self.Surface) smoothingFilter.SetNumberOfIterations(self.NumberOfIterations) smoothingFilter.SetPassBand(self.PassBand) smoothingFilter.SetBoundarySmoothing(self.BoundarySmoothing) ## smoothingFilter.NormalizeCoordinatesOn() smoothingFilter.Update() elif self.Method is 'laplace': smoothingFilter = vtk.vtkSmoothPolyDataFilter() smoothingFilter.SetInput(self.Surface) smoothingFilter.SetNumberOfIterations(self.NumberOfIterations) smoothingFilter.SetRelaxationFactor(self.RelaxationFactor) smoothingFilter.Update() else: self.PrintError('Error: smoothing method not supported.') self.Surface = smoothingFilter.GetOutput() normals = vmtkscripts.vmtkSurfaceNormals() normals.Surface = self.Surface normals.Execute() self.Surface = normals.Surface if self.Surface.GetSource(): self.Surface.GetSource().UnRegisterAllOutputs()
def smooth_mesh(dmc, iterations=20): inputPoly = vtk.vtkPolyData() inputPoly.ShallowCopy(dmc.GetOutput()) cleanPolyData = vtk.vtkCleanPolyData() cleanPolyData.SetInputData(inputPoly) cleanPolyData.Update() smooth_butterfly = vtk.vtkButterflySubdivisionFilter() smooth_butterfly.SetNumberOfSubdivisions(0) smooth_butterfly.SetInputConnection(cleanPolyData.GetOutputPort()) smooth_butterfly.Update() upsampledInputPoly = vtk.vtkPolyData() upsampledInputPoly.DeepCopy(smooth_butterfly.GetOutput()) decimate = vtk.vtkDecimatePro() decimate.SetInputData(upsampledInputPoly) decimate.SetTargetReduction(0.0) decimate.PreserveTopologyOn() decimate.Update() smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(decimate.GetOutputPort()) smoother.SetNumberOfIterations(iterations) # smoother.SetRelaxationFactor(0.1) smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOn() smoother.Update() normals = vtk.vtkPolyDataNormals() normals.SetInputConnection(smoother.GetOutputPort()) normals.FlipNormalsOn() return normals
def __init__(self, grid, vtkish_polydata=None, angle=15): vtkPolyDataPipeline.__init__(self, vtkish_polydata) # Make sure grid argument is correct type assert isinstance(grid, vtkVolumeGrid) self.grid = grid # Split polys with intersection angles greater than angle vtk_dnorm = vtkPolyDataNormals() vtk_dnorm.SetFeatureAngle(angle) vtk_dnorm.SplittingOn() vtk_dnorm.ComputeCellNormalsOff() vtk_dnorm.ComputePointNormalsOff() self.append(vtk_dnorm) relax = self.grid.get_relaxation_factor() if relax is not None: print('relax=',relax) #vtk_subdiv = vtkButterflySubdivisionFilter() vtk_subdiv = vtkLinearSubdivisionFilter() self.append(vtk_subdiv) # Smooth out some of the sharp points. vtk_smooth = vtkSmoothPolyDataFilter() vtk_smooth.SetRelaxationFactor(relax) self.append(vtk_smooth)
def updateModelFromFiducial(self, caller=None, event=None): # get fiducial points to vtkPoints and description to vtkDoubleArray samplePoints = vtk.vtkPoints() valuesArray = [] pos = [0.0] * 3 i = 0 while i < self.traceFiducials.GetNumberOfControlPoints(): if self.traceFiducials.GetNthControlPointDescription(i) in [ '', 'nan' ]: if i < self.traceFiducials.GetNumberOfControlPoints() - 3: self.traceFiducials.RemoveNthControlPoint(i) continue else: self.traceFiducials.GetNthFiducialPosition(i, pos) samplePoints.InsertNextPoint(pos) valuesArray.append( float( self.traceFiducials.GetNthControlPointDescription(i))) i += 1 if not valuesArray: return # array to vtk valuesMedian = np.median(valuesArray[:min(len(valuesArray), 5)]) vtkValuesArray = vtk.vtkDoubleArray() vtkValuesArray.SetName('values') for value in valuesArray: vtkValuesArray.InsertNextTuple((max( (value - valuesMedian) / valuesMedian / 2.0, 0.1), )) # line source polyLineSource = vtk.vtkPolyLineSource() polyLineSource.SetPoints(samplePoints) polyLineSource.Update() # poly data polyData = polyLineSource.GetOutput() polyData.GetPointData().AddArray(vtkValuesArray) polyData.GetPointData().SetScalars(vtkValuesArray) # run tube filter tubeFilter = vtk.vtkTubeFilter() tubeFilter.SetInputData(polyData) tubeFilter.SetVaryRadiusToVaryRadiusByAbsoluteScalar() tubeFilter.SetNumberOfSides(16) tubeFilter.CappingOn() tubeFilter.Update() # smooth smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(tubeFilter.GetOutput()) smoothFilter.SetNumberOfIterations(2) smoothFilter.SetRelaxationFactor(0.5) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.Update() # update self.traceModel.SetAndObservePolyData(smoothFilter.GetOutput()) self.traceModel.GetDisplayNode().SetActiveScalarName('values') self.traceModel.GetDisplayNode().SetAutoScalarRange(False) self.traceModel.GetDisplayNode().SetScalarRange(0.0, 1.0) self.traceModel.Modified() return
def Smooth_stl(stl): smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputConnection(stl) smoothFilter.SetNumberOfIterations(15) smoothFilter.SetRelaxationFactor(0.1) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.Update()
def smooth_laplacian(self, number_of_iterations=50): smooth = vtk.vtkSmoothPolyDataFilter() smooth.SetInputConnection(self.mesh.GetOutputPort()) smooth.SetNumberOfIterations(number_of_iterations) smooth.FeatureEdgeSmoothingOff() smooth.BoundarySmoothingOn() smooth.Update() self.mesh = smooth
def smooth(polydata,iterations,factor): smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputData(polydata) smoother.SetNumberOfIterations(iterations) smoother.FeatureEdgeSmoothingOn() smoother.SetRelaxationFactor(factor) smoother.Update() return smoother.GetOutput()
def smooth(path, iterations=100, relaxation=0.1, edgesmoothing=True, savepath=None): """ Edit a mesh file (ply format) applying iterative Laplacian smoothing """ # source https://vtk.org/Wiki/VTK/Examples/Cxx/PolyData/SmoothPolyDataFilter # read Ply file reader = vtkPLYReader() reader.SetFileName(path) reader.Update() # create Poly data inputPoly = vtkPolyData() inputPoly.ShallowCopy(reader.GetOutput()) # Smooth mesh with Laplacian Smoothing smooth = vtkSmoothPolyDataFilter() smooth.SetInputData(inputPoly) smooth.SetRelaxationFactor(relaxation) smooth.SetNumberOfIterations(iterations) if edgesmoothing: smooth.FeatureEdgeSmoothingOn() else: smooth.FeatureEdgeSmoothingOff() smooth.BoundarySmoothingOn() smooth.Update() smoothPoly = vtkPolyData() smoothPoly.ShallowCopy(smooth.GetOutput()) # Find mesh normals (Not sure why) normal = vtkPolyDataNormals() normal.SetInputData(smoothPoly) normal.ComputePointNormalsOn() normal.ComputeCellNormalsOn() normal.Update() normalPoly = vtkPolyData() normalPoly.ShallowCopy(normal.GetOutput()) # write results on output file if savepath is None: outfile_path = os.path.splitext(path)[0] outfile_path = f"{outfile_path}_smooth_{iterations}.ply" else: outfile_path = os.path.splitext(path)[0] outfile_path = f"{os.path.basename(outfile_path)}_smooth_{iterations}.ply" outfile_path = os.path.join(savepath, outfile_path) writer = vtkPLYWriter() writer.SetInputData(normalPoly) writer.SetFileName(outfile_path) writer.Write() print(f" -> Saving file at: {outfile_path}") return outfile_path
def arrayToPoly(array, origin, spacing, direction): # array to vtkImageData flatten_array = array.ravel() vtk_data_array = numpy_to_vtk( num_array= flatten_array, # ndarray contains the fitting result from the points. It is a 3D array deep=True, array_type=vtk.VTK_UNSIGNED_CHAR) # Convert the VTK array to vtkImageData shape = np.array(array.shape[::-1]) origin = np.array(origin) spacing = np.array(spacing) img_vtk = vtk.vtkImageData() img_vtk.SetDimensions(shape) img_vtk.SetSpacing(spacing) img_vtk.SetOrigin(origin) img_vtk.SetDirectionMatrix(*direction) img_vtk.GetPointData().SetScalars(vtk_data_array) surf = vtk.vtkDiscreteMarchingCubes() surf.SetInputData(img_vtk) surf.SetValue( 0, 1 ) # use surf.GenerateValues function if more than one contour is available in the file # surf.GenerateValues(2, 0, 1) # use surf.GenerateValues function if more than one contour is available in the file surf.Update() # smoothing the mesh smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(surf.GetOutputPort()) smoother.SetNumberOfIterations(50) smoother.SetRelaxationFactor(0.1) smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOn() smoother.Update() # Update normals on newly smoothed polydata normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputConnection(smoother.GetOutputPort()) normalGenerator.ComputePointNormalsOn() normalGenerator.ComputeCellNormalsOn() normalGenerator.Update() # transform transform = vtk.vtkTransform() transform.Scale(-1, -1, 1) transform_filter = vtk.vtkTransformFilter() transform_filter.SetTransform(transform) transform_filter.SetInputData(normalGenerator.GetOutput()) transform_filter.TransformAllInputVectorsOn() transform_filter.Update() poly = transform_filter.GetOutput() return poly
def LabelToSurface(label_path, surface_path, lcc=False, smoothIterations=15,relaxationFactor=0.1): tqdm.write("Converting segmentation label to surface file: {}".format(label_path)) # binary path if platform == "linux" or platform == "linux2": bin_path = "/home/jacky/Projects/CFD_intraranial/cxx/label_to_mesh/build_linux/LabelToMesh" elif platform == "darwin": return elif platform == "win32": bin_path = "D:/projects/CFD_intracranial/cxx/label_to_mesh/build/Release/LabelToMesh.exe" # convert to binary file command = bin_path + " " + label_path + " " + surface_path + " 1 1" # print(command) os.system(command) reader = vtk.vtkGenericDataObjectReader() reader.SetFileName(surface_path) reader.Update() surface = reader.GetOutput() transform = vtk.vtkTransform() transform.Scale(-1,-1,1) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputData(surface) transformFilter.SetTransform(transform) transformFilter.Update() surface = transformFilter.GetOutput() smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(surface) smoothFilter.SetNumberOfIterations(smoothIterations); smoothFilter.SetRelaxationFactor(relaxationFactor); smoothFilter.FeatureEdgeSmoothingOff(); smoothFilter.BoundarySmoothingOn(); smoothFilter.Update(); surface = smoothFilter.GetOutput() if lcc: connectedFilter = vtk.vtkConnectivityFilter() connectedFilter.SetInputData(surface) connectedFilter.Update() surface = connectedFilter.GetOutput() if pathlib.Path(surface_path).suffix == ".vtk": writer = vtk.vtkGenericDataObjectWriter() elif pathlib.Path(surface_path).suffix == ".vtp": writer = vtk.vtkXMLPolyDataWriter() elif pathlib.Path(surface_path).suffix == ".stl": writer = vtk.vtkSTLWriter() writer.SetFileName(surface_path) writer.SetInputData(surface) writer.Update() tqdm.write("Convert segmentation label to surface file complete: {}".format(label_path))
def main(args): img_fn_array = [] if args.image: img_obj = {} img_obj["img"] = args.image img_obj["out"] = args.out img_fn_array.append(img_obj) elif args.dir: normpath = os.path.normpath("/".join([args.dir, '**', '*'])) for img_fn in glob.iglob(normpath, recursive=True): if os.path.isfile(img_fn) and True in [ ext in img_fn for ext in [".nrrd"] ]: img_obj = {} img_obj["img"] = img_fn img_obj["out"] = os.path.normpath("/".join([args.out])) img_fn_array.append(img_obj) for img_obj in img_fn_array: image = img_obj["img"] out = img_obj["out"] print("Reading:", image) surf = vtk.vtkNrrdReader() surf.SetFileName(image) surf.Update() dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(surf.GetOutputPort()) dmc.GenerateValues(100, 1, 100) # LAPLACIAN smooth SmoothPolyDataFilter = vtk.vtkSmoothPolyDataFilter() SmoothPolyDataFilter.SetInputConnection(dmc.GetOutputPort()) SmoothPolyDataFilter.SetNumberOfIterations(10) SmoothPolyDataFilter.SetFeatureAngle(120.0) SmoothPolyDataFilter.SetRelaxationFactor(0.6) SmoothPolyDataFilter.Update() # SINC smooth # smoother = vtk.vtkWindowedSincPolyDataFilter() # smoother.SetInputConnection(dmc.GetOutputPort()) # smoother.SetNumberOfIterations(30) # smoother.BoundarySmoothingOff() # smoother.FeatureEdgeSmoothingOff() # smoother.SetFeatureAngle(120.0) # smoother.SetPassBand(0.001) # smoother.NonManifoldSmoothingOn() # smoother.NormalizeCoordinatesOn() # smoother.Update() outputFilename = out + "/" + os.path.splitext( os.path.basename(image))[0] + ".vtk" Write(SmoothPolyDataFilter.GetOutput(), outputFilename)
def __init__(self, module_manager): SimpleVTKClassModuleBase.__init__(self, module_manager, vtk.vtkSmoothPolyDataFilter(), 'Processing.', ('vtkPolyData', 'vtkPolyData'), ('vtkPolyData', ), replaceDoc=True, inputFunctions=None, outputFunctions=None)
def smoothPolyData(polyObject): smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputData(polyObject) smoother.SetFeatureAngle(60.0) smoother.SetEdgeAngle(60.0) smoother.SetBoundarySmoothing(1) smoother.SetFeatureEdgeSmoothing(1) smoother.SetNumberOfIterations(50) smoother.Update() return smoother.GetOutput()
def applyFilters(self, state): surface = None surface = state.inputModelNode.GetPolyDataConnection() if state.decimation: triangle = vtk.vtkTriangleFilter() triangle.SetInputConnection(surface) decimation = vtk.vtkDecimatePro() decimation.SetTargetReduction(state.reduction) decimation.SetBoundaryVertexDeletion(state.boundaryDeletion) decimation.PreserveTopologyOn() decimation.SetInputConnection(triangle.GetOutputPort()) surface = decimation.GetOutputPort() if state.smoothing: if state.smoothingMethod == "Laplace": smoothing = vtk.vtkSmoothPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.laplaceIterations) smoothing.SetRelaxationFactor(state.laplaceRelaxation) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() elif state.smoothingMethod == "Taubin": smoothing = vtk.vtkWindowedSincPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.taubinIterations) smoothing.SetPassBand(state.taubinPassBand) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() if state.normals: normals = vtk.vtkPolyDataNormals() normals.AutoOrientNormalsOn() normals.SetFlipNormals(state.flipNormals) normals.SetSplitting(state.splitting) normals.SetFeatureAngle(state.featureAngle) normals.ConsistencyOn() normals.SetInputConnection(surface) surface = normals.GetOutputPort() if state.cleaner: cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(surface) surface = cleaner.GetOutputPort() if state.connectivity: connectivity = vtk.vtkPolyDataConnectivityFilter() connectivity.SetExtractionModeToLargestRegion() connectivity.SetInputConnection(surface) surface = connectivity.GetOutputPort() state.outputModelNode.SetPolyDataConnection(surface) return True
def applySmoothPolyFilter(self, imgData, iternum, relax): smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(imgData.GetOutput()) smoothFilter.SetNumberOfIterations(iternum) smoothFilter.SetRelaxationFactor(relax) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.Update return smoothFilter
def test_pipeline(): # check defaults s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f) assert isinstance(out, BSPolyData) assert out.n_points > 0 # check update filter s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, as_data=False) assert isinstance(out, BSAlgorithm) assert out.GetOutput().GetNumberOfPoints() > 0 # check filter no update s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, as_data=False, update=False) assert isinstance(out, BSAlgorithm) assert out.GetOutput().GetNumberOfPoints() == 0 # check non-existing port s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, port=1) assert out is None # check get all possible ports s = vtk.vtkSphereSource() f = vtk.vtkSmoothPolyDataFilter() out = serial_connect(s, f, port=-1) assert isinstance(out, list) assert len(out) == f.GetNumberOfOutputPorts() assert isinstance(out[0], BSPolyData) assert out[0].n_points > 0 # check accept wrappers s = wrap_vtk(vtk.vtkSphereSource) f = wrap_vtk(vtk.vtkSmoothPolyDataFilter) assert isinstance(serial_connect(s, f), BSPolyData)
def create_smoother(reducer, smoothness): """ Reorients some points in the volume to smooth the render edges. (https://www.vtk.org/doc/nightly/html/classvtkSmoothPolyDataFilter.html) :param reducer: :param smoothness: :return: """ smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(reducer.GetOutputPort()) smoother.SetNumberOfIterations(smoothness) return smoother
def MarchingCubes(image,threshold): # marching cubes mc = vtk.vtkMarchingCubes() mc.SetInputData(image) mc.ComputeNormalsOn() mc.ComputeGradientsOn() mc.SetValue(0, threshold) mc.Update() # To remain largest region #confilter = vtk.vtkPolyDataConnectivityFilter() #confilter.SetInputData(mc.GetOutput()) #confilter.SetExtractionModeToLargestRegion() #confilter.Update() # reduce poly data inputPoly = vtk.vtkPolyData() inputPoly.ShallowCopy(mc.GetOutput()) print("Before decimation\n" "-----------------\n" "There are " + str(inputPoly.GetNumberOfPoints()) + "points.\n" "There are " + str(inputPoly.GetNumberOfPolys()) + "polygons.\n") #decimate = vtk.vtkDecimatePro() decimate = vtk.vtkQuadricDecimation() decimate.SetInputData(inputPoly) decimate.SetTargetReduction(.90) decimate.Update() decimatedPoly = vtk.vtkPolyData() decimatedPoly.ShallowCopy(decimate.GetOutput()) print("After decimation \n" "-----------------\n" "There are " + str(decimatedPoly.GetNumberOfPoints()) + "points.\n" "There are " + str(decimatedPoly.GetNumberOfPolys()) + "polygons.\n") # smooth surface smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(decimatedPoly) smoothFilter.SetNumberOfIterations(15) smoothFilter.SetRelaxationFactor(0.1) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.Update() decimatedPoly = vtk.vtkPolyData() decimatedPoly.ShallowCopy(smoothFilter.GetOutput()) return decimatedPoly#confilter.GetOutput()
def SmoothPolyData(self, PolyData, ConvergenceThresh, NumIterations): # Instantiate vtk polydata smoother vtkSmoother = vtk.vtkSmoothPolyDataFilter() vtkSmoother.SetFeatureEdgeSmoothing(True) vtkSmoother.SetConvergence(ConvergenceThresh) vtkSmoother.SetNumberOfIterations(int(NumIterations)) vtkSmoother.SetInputData(PolyData) vtkSmoother.Update() SmoothedPolyData = vtkSmoother.GetOutput() return SmoothedPolyData
def SmoothMesh(self, nbIter, RelaxFactor): print("Smoother") smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(self.dmc.GetOutputPort()) smoother.SetNumberOfIterations(nbIter) smoother.SetRelaxationFactor( RelaxFactor) #this has little effect on the error! smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOn() self.dmc = vtk.vtkPolyDataNormals() self.dmc.SetInputConnection(smoother.GetOutputPort()) self.dmc.Update()
def smoothPoly(poly, num_iter=15, rlx_factor=0.1): ''' http://www.vtk.org/doc/nightly/html/classvtkSmoothPolyDataFilter.html ''' smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(poly) smoothFilter.SetNumberOfIterations(num_iter) smoothFilter.SetRelaxationFactor(rlx_factor) smoothFilter.FeatureEdgeSmoothingOff() #smoothFilter.FeatureEdgeSmoothingOn() smoothFilter.BoundarySmoothingOff() #smoothFilter.BoundarySmoothingOff() smoothFilter.Update() return smoothFilter.GetOutput()
def getSmoothNormals(self, surfaceNode,iterations): smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(surfaceNode.GetPolyData()) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.SetNumberOfIterations(iterations) smoothFilter.SetRelaxationFactor(1) smoothFilter.Update() normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.ComputePointNormalsOn() normalGenerator.SetInputData(smoothFilter.GetOutput()) normalGenerator.Update() normalArray = normalGenerator.GetOutput().GetPointData().GetArray("Normals") return normalArray
def stl_writer(filename, stack, spacing, dcm_folder): ###### filename: the file name of the output ".stl" ####### ###### stack: the volume of 3D ndarray #################### ###### spacing: resolution of raw data #################### DEBUG = False RElAXATIONFACTOR = 0.03 ITERATIONS = 100 stack = stack.transpose(0, 1, 2) stack[stack >= 0.5] = 1.0 stack[stack <= 0.5] = 0.0 stack = stack * 255 stack = np.require(stack, dtype=np.uint8) data_string = stack.tostring() #### 转换成vtk-image的形式,调用vtkImageImport类 ############ dataImporter = vtk.vtkImageImport() dataImporter.CopyImportVoidPointer(data_string, len(data_string)) dataImporter.SetDataScalarTypeToUnsignedChar() dataImporter.SetNumberOfScalarComponents(1) #### importer数据只有灰度信息,不是rgb之类的 #### vtk uses an array in the order : height, depth, width which is different of numpy (w,h,d) w, d, h = stack.shape dataImporter.SetWholeExtent(0, h - 1, 0, d - 1, 0, w - 1) dataImporter.SetDataExtent(0, h - 1, 0, d - 1, 0, w - 1) dataImporter.SetDataSpacing(spacing[2], spacing[1], spacing[0]) # dataImporter.SetWholeExtent(0, h-1, 0, d-1, 0, w-1) reader = vtk.vtkDICOMImageReader() reader.SetDirectoryName(dcm_folder) reader.Update() dcmImagePosition = reader.GetImagePositionPatient() dataImporter.SetDataOrigin(dcmImagePosition) threshold = vtk.vtkImageThreshold() threshold.SetInputConnection(dataImporter.GetOutputPort()) threshold.ThresholdByLower(128) threshold.ReplaceInOn() threshold.SetInValue(0) threshold.ReplaceOutOn() threshold.SetOutValue(1) threshold.Update() dmc = vtk.vtkDiscreteMarchingCubes() dmc.SetInputConnection(threshold.GetOutputPort()) dmc.GenerateValues(1, 1, 1) dmc.Update() smooth = vtk.vtkSmoothPolyDataFilter() smooth.SetInputConnection(dmc.GetOutputPort()) smooth.SetRelaxationFactor(RElAXATIONFACTOR) smooth.SetNumberOfIterations(ITERATIONS) writer = vtk.vtkSTLWriter() writer.SetInputConnection(smooth.GetOutputPort()) writer.SetFileTypeToBinary() writer.SetFileName(filename) writer.Write()
def SmoothMesh(self,nbIter,RelaxFactor): smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(self.dmc.GetOutputPort()) smoother.SetNumberOfIterations(nbIter) smoother.SetRelaxationFactor(RelaxFactor)#this has little effect on the error! self.dmc = vtk.vtkPolyDataNormals() self.dmc.SetInputConnection(smoother.GetOutputPort()) stlWriter = vtk.vtkSTLWriter() stlWriter.SetFileName('./Data/' + strftime("%Y-%m-%d %H:%M:%S", gmtime())+'.stl') stlWriter.SetFileTypeToBinary() stlWriter.SetInputConnection(self.dmc.GetOutputPort()) stlWriter.Write()
def ApplySmoothFilter(polydata, iterations, relaxation_factor): """ Smooth given vtkPolyData surface, based on iteration and relaxation_factor. """ smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputData(polydata) smoother.SetNumberOfIterations(iterations) smoother.SetFeatureAngle(80) smoother.SetRelaxationFactor(relaxation_factor) smoother.FeatureEdgeSmoothingOn() smoother.BoundarySmoothingOn() smoother.GetOutput().ReleaseDataFlagOn() smoother.AddObserver("ProgressEvent", lambda obj, evt: UpdateProgress(smoother, "Smoothing surface...")) return smoother.GetOutput()
def Smooth(self): self.smooth = vtk.vtkSmoothPolyDataFilter() self.smooth.SetInputData(self.inputPolyData) self.smooth.SetNumberOfIterations(self.iter) self.smooth.SetRelaxationFactor(self.rela) self.smooth.SetConvergence(0.0) #self.smooth.FeatureEdgeSmoothingOff() #self.smooth.BoundarySmoothingOff() self.smooth.Update() ######################### self.normalGenerator = vtk.vtkPolyDataNormals() self.normalGenerator.SetInputConnection(self.smooth.GetOutputPort()) self.normalGenerator.ComputePointNormalsOff() self.normalGenerator.ComputeCellNormalsOff() self.normalGenerator.Update() self.outputPolyData = self.normalGenerator.GetOutput()
def vtk_smooth(iso, iter=20, relax=0.5, decimate=0.0): isoSmooth = vtk.vtkSmoothPolyDataFilter() if decimate>0: deci = vtk.vtkDecimatePro() deci.SetInput(iso.GetOutput()) deci.SetTargetReduction(decimate) deci.PreserveTopologyOn() isoSmooth.SetInputConnection(deci.GetOutputPort()) else: isoSmooth.SetInputConnection(iso.GetOutputPort()) isoSmooth.SetNumberOfIterations(100) isoSmooth.BoundarySmoothingOn() isoSmooth.FeatureEdgeSmoothingOff() isoSmooth.SetFeatureAngle(45) isoSmooth.SetEdgeAngle(15) isoSmooth.SetRelaxationFactor(relax) return isoSmooth
def vtkSmoothPD(pd,iters=15,relax=0.1): smoothFilter = vtk.vtkSmoothPolyDataFilter() smoothFilter.SetInputData(pd) smoothFilter.SetNumberOfIterations(iters) smoothFilter.SetRelaxationFactor(relax) smoothFilter.FeatureEdgeSmoothingOff() smoothFilter.BoundarySmoothingOn() smoothFilter.Update() #Update normals on newly smoothed polydata normalGenerator = vtk.vtkPolyDataNormals() normalGenerator.SetInputConnection(smoothFilter.GetOutputPort()) normalGenerator.ComputePointNormalsOn() normalGenerator.ComputeCellNormalsOn() normalGenerator.Update() return normalGenerator.GetOutput()
def __init__(self, filename, renderer): self.renderer = renderer reader = vtk.vtkStructuredPointsReader() #reader.SetFileName('/home/mcc/src/devel/extract_mri_slices/braintest2.vtk') reader.SetFileName(filename) # we want to move this from its (.87 .92 .43) esque position to something more like 'the center' # how to do this?!? # ALTERNATIVELY: we want to use vtkInteractorStyleTrackballActor # somewhere instead of the interactor controlling the main window and 3 planes imagedata = reader.GetOutput() #reader.SetFileName(filename) cf = vtk.vtkContourFilter() cf.SetInput(imagedata) # ??? cf.SetValue(0, 1) deci = vtk.vtkDecimatePro() deci.SetInput(cf.GetOutput()) deci.SetTargetReduction(.1) deci.PreserveTopologyOn() smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(deci.GetOutput()) smoother.SetNumberOfIterations(100) # XXX try to call SetScale directly on actor.. #self.scaleTransform = vtk.vtkTransform() #self.scaleTransform.Identity() #self.scaleTransform.Scale(.1, .1, .1) #transformFilter = vtk.vtkTransformPolyDataFilter() #transformFilter.SetTransform(self.scaleTransform) #transformFilter.SetInput(smoother.GetOutput()) #cf.SetValue(1, 2) #cf.SetValue(2, 3) #cf.GenerateValues(0, -1.0, 1.0) #deci = vtk.vtkDecimatePro() #deci.SetInput(cf.GetOutput()) #deci.SetTargetReduction(0.8) # decimate_value normals = vtk.vtkPolyDataNormals() #normals.SetInput(transformFilter.GetOutput()) normals.SetInput(smoother.GetOutput()) normals.FlipNormalsOn() """ tags = vtk.vtkFloatArray() tags.InsertNextValue(1.0) tags.InsertNextValue(0.5) tags.InsertNextValue(0.7) tags.SetName("tag") """ lut = vtk.vtkLookupTable() lut.SetHueRange(0, 0) lut.SetSaturationRange(0, 0) lut.SetValueRange(0.2, 0.55) contourMapper = vtk.vtkPolyDataMapper() contourMapper.SetInput(normals.GetOutput()) contourMapper.SetLookupTable(lut) ###contourMapper.SetColorModeToMapScalars() ###contourMapper.SelectColorArray("tag") self.contours = vtk.vtkActor() self.contours.SetMapper(contourMapper) #if (do_wireframe): #self.contours.GetProperty().SetRepresentationToWireframe() #elif (do_surface): self.contours.GetProperty().SetRepresentationToSurface() self.contours.GetProperty().SetInterpolationToGouraud() self.contours.GetProperty().SetOpacity(1.0) self.contours.GetProperty().SetAmbient(0.1) self.contours.GetProperty().SetDiffuse(0.1) self.contours.GetProperty().SetSpecular(0.1) self.contours.GetProperty().SetSpecularPower(0.1) # XXX arbitrarily setting scale to this #self.contours.SetScale(.1, .1,.1) renderer.AddActor(self.contours) # XXX: mcc will this work?!? print "PlaneWidgetsXYZ.set_image_data: setting EventHandler.set_vtkactor(self.contours)!" EventHandler().set_vtkactor(self.contours)
def AddNewActor(self, pubsub_evt): """ Create surface actor, save into project and send it to viewer. """ slice_, mask, surface_parameters = pubsub_evt.data matrix = slice_.matrix filename_img = slice_.matrix_filename spacing = slice_.spacing algorithm = surface_parameters['method']['algorithm'] options = surface_parameters['method']['options'] surface_name = surface_parameters['options']['name'] quality = surface_parameters['options']['quality'] fill_holes = surface_parameters['options']['fill'] keep_largest = surface_parameters['options']['keep_largest'] mode = 'CONTOUR' # 'GRAYSCALE' min_value, max_value = mask.threshold_range colour = mask.colour try: overwrite = surface_parameters['options']['overwrite'] except KeyError: overwrite = False mask.matrix.flush() if quality in const.SURFACE_QUALITY.keys(): imagedata_resolution = const.SURFACE_QUALITY[quality][0] smooth_iterations = const.SURFACE_QUALITY[quality][1] smooth_relaxation_factor = const.SURFACE_QUALITY[quality][2] decimate_reduction = const.SURFACE_QUALITY[quality][3] #if imagedata_resolution: #imagedata = iu.ResampleImage3D(imagedata, imagedata_resolution) pipeline_size = 4 if decimate_reduction: pipeline_size += 1 if (smooth_iterations and smooth_relaxation_factor): pipeline_size += 1 if fill_holes: pipeline_size += 1 if keep_largest: pipeline_size += 1 ## Update progress value in GUI UpdateProgress = vu.ShowProgress(pipeline_size) UpdateProgress(0, _("Creating 3D surface...")) language = ses.Session().language if (prj.Project().original_orientation == const.CORONAL): flip_image = False else: flip_image = True n_processors = multiprocessing.cpu_count() pipe_in, pipe_out = multiprocessing.Pipe() o_piece = 1 piece_size = 2000 n_pieces = int(round(matrix.shape[0] / piece_size + 0.5, 0)) q_in = multiprocessing.Queue() q_out = multiprocessing.Queue() p = [] for i in xrange(n_processors): sp = surface_process.SurfaceProcess(pipe_in, filename_img, matrix.shape, matrix.dtype, mask.temp_file, mask.matrix.shape, mask.matrix.dtype, spacing, mode, min_value, max_value, decimate_reduction, smooth_relaxation_factor, smooth_iterations, language, flip_image, q_in, q_out, algorithm != 'Default', algorithm, imagedata_resolution) p.append(sp) sp.start() for i in xrange(n_pieces): init = i * piece_size end = init + piece_size + o_piece roi = slice(init, end) q_in.put(roi) print "new_piece", roi for i in p: q_in.put(None) none_count = 1 while 1: msg = pipe_out.recv() if(msg is None): none_count += 1 else: UpdateProgress(msg[0]/(n_pieces * pipeline_size), msg[1]) if none_count > n_pieces: break polydata_append = vtk.vtkAppendPolyData() polydata_append.ReleaseDataFlagOn() t = n_pieces while t: filename_polydata = q_out.get() reader = vtk.vtkXMLPolyDataReader() reader.SetFileName(filename_polydata) reader.ReleaseDataFlagOn() reader.Update() reader.GetOutput().ReleaseDataFlagOn() polydata = reader.GetOutput() polydata.SetSource(None) polydata_append.AddInput(polydata) del reader del polydata t -= 1 polydata_append.Update() polydata_append.GetOutput().ReleaseDataFlagOn() polydata = polydata_append.GetOutput() #polydata.Register(None) polydata.SetSource(None) del polydata_append if algorithm == 'ca_smoothing': normals = vtk.vtkPolyDataNormals() normals_ref = weakref.ref(normals) normals_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(normals_ref(), _("Creating 3D surface..."))) normals.SetInput(polydata) normals.ReleaseDataFlagOn() #normals.SetFeatureAngle(80) #normals.AutoOrientNormalsOn() normals.ComputeCellNormalsOn() normals.GetOutput().ReleaseDataFlagOn() normals.Update() del polydata polydata = normals.GetOutput() polydata.SetSource(None) del normals clean = vtk.vtkCleanPolyData() clean.ReleaseDataFlagOn() clean.GetOutput().ReleaseDataFlagOn() clean_ref = weakref.ref(clean) clean_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(clean_ref(), _("Creating 3D surface..."))) clean.SetInput(polydata) clean.PointMergingOn() clean.Update() del polydata polydata = clean.GetOutput() polydata.SetSource(None) del clean try: polydata.BuildLinks() except TypeError: polydata.BuildLinks(0) polydata = ca_smoothing.ca_smoothing(polydata, options['angle'], options['max distance'], options['min weight'], options['steps']) polydata.SetSource(None) polydata.DebugOn() else: #smoother = vtk.vtkWindowedSincPolyDataFilter() smoother = vtk.vtkSmoothPolyDataFilter() smoother_ref = weakref.ref(smoother) smoother_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(smoother_ref(), _("Creating 3D surface..."))) smoother.SetInput(polydata) smoother.SetNumberOfIterations(smooth_iterations) smoother.SetRelaxationFactor(smooth_relaxation_factor) smoother.SetFeatureAngle(80) #smoother.SetEdgeAngle(90.0) #smoother.SetPassBand(0.1) smoother.BoundarySmoothingOn() smoother.FeatureEdgeSmoothingOn() #smoother.NormalizeCoordinatesOn() #smoother.NonManifoldSmoothingOn() smoother.ReleaseDataFlagOn() smoother.GetOutput().ReleaseDataFlagOn() smoother.Update() del polydata polydata = smoother.GetOutput() #polydata.Register(None) polydata.SetSource(None) del smoother if decimate_reduction: print "Decimating", decimate_reduction decimation = vtk.vtkQuadricDecimation() decimation.ReleaseDataFlagOn() decimation.SetInput(polydata) decimation.SetTargetReduction(decimate_reduction) decimation_ref = weakref.ref(decimation) decimation_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(decimation_ref(), _("Creating 3D surface..."))) #decimation.PreserveTopologyOn() #decimation.SplittingOff() #decimation.BoundaryVertexDeletionOff() decimation.GetOutput().ReleaseDataFlagOn() decimation.Update() del polydata polydata = decimation.GetOutput() #polydata.Register(None) polydata.SetSource(None) del decimation to_measure = polydata #to_measure.Register(None) to_measure.SetSource(None) if keep_largest: conn = vtk.vtkPolyDataConnectivityFilter() conn.SetInput(polydata) conn.SetExtractionModeToLargestRegion() conn_ref = weakref.ref(conn) conn_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(conn_ref(), _("Creating 3D surface..."))) conn.Update() conn.GetOutput().ReleaseDataFlagOn() del polydata polydata = conn.GetOutput() #polydata.Register(None) polydata.SetSource(None) del conn #Filter used to detect and fill holes. Only fill boundary edges holes. #TODO: Hey! This piece of code is the same from #polydata_utils.FillSurfaceHole, we need to review this. if fill_holes: filled_polydata = vtk.vtkFillHolesFilter() filled_polydata.ReleaseDataFlagOn() filled_polydata.SetInput(polydata) filled_polydata.SetHoleSize(300) filled_polydata_ref = weakref.ref(filled_polydata) filled_polydata_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(filled_polydata_ref(), _("Creating 3D surface..."))) filled_polydata.Update() filled_polydata.GetOutput().ReleaseDataFlagOn() del polydata polydata = filled_polydata.GetOutput() #polydata.Register(None) polydata.SetSource(None) polydata.DebugOn() del filled_polydata normals = vtk.vtkPolyDataNormals() normals.ReleaseDataFlagOn() normals_ref = weakref.ref(normals) normals_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(normals_ref(), _("Creating 3D surface..."))) normals.SetInput(polydata) normals.SetFeatureAngle(80) normals.AutoOrientNormalsOn() normals.GetOutput().ReleaseDataFlagOn() normals.Update() del polydata polydata = normals.GetOutput() #polydata.Register(None) polydata.SetSource(None) del normals # Improve performance stripper = vtk.vtkStripper() stripper.ReleaseDataFlagOn() stripper_ref = weakref.ref(stripper) stripper_ref().AddObserver("ProgressEvent", lambda obj,evt: UpdateProgress(stripper_ref(), _("Creating 3D surface..."))) stripper.SetInput(polydata) stripper.PassThroughCellIdsOn() stripper.PassThroughPointIdsOn() stripper.GetOutput().ReleaseDataFlagOn() stripper.Update() del polydata polydata = stripper.GetOutput() #polydata.Register(None) polydata.SetSource(None) del stripper # Map polygonal data (vtkPolyData) to graphics primitives. mapper = vtk.vtkPolyDataMapper() mapper.SetInput(polydata) mapper.ScalarVisibilityOff() mapper.ReleaseDataFlagOn() mapper.ImmediateModeRenderingOn() # improve performance # Represent an object (geometry & properties) in the rendered scene actor = vtk.vtkActor() actor.SetMapper(mapper) del mapper #Create Surface instance if overwrite: surface = Surface(index = self.last_surface_index) else: surface = Surface(name=surface_name) surface.colour = colour surface.polydata = polydata del polydata # Set actor colour and transparency actor.GetProperty().SetColor(colour) actor.GetProperty().SetOpacity(1-surface.transparency) prop = actor.GetProperty() interpolation = int(ses.Session().surface_interpolation) prop.SetInterpolation(interpolation) proj = prj.Project() if overwrite: proj.ChangeSurface(surface) else: index = proj.AddSurface(surface) surface.index = index self.last_surface_index = index session = ses.Session() session.ChangeProject() # The following lines have to be here, otherwise all volumes disappear measured_polydata = vtk.vtkMassProperties() measured_polydata.ReleaseDataFlagOn() measured_polydata.SetInput(to_measure) volume = float(measured_polydata.GetVolume()) surface.volume = volume self.last_surface_index = surface.index del measured_polydata del to_measure Publisher.sendMessage('Load surface actor into viewer', actor) # Send actor by pubsub to viewer's render if overwrite and self.actors_dict.keys(): old_actor = self.actors_dict[self.last_surface_index] Publisher.sendMessage('Remove surface actor from viewer', old_actor) # Save actor for future management tasks self.actors_dict[surface.index] = actor Publisher.sendMessage('Update surface info in GUI', (surface.index, surface.name, surface.colour, surface.volume, surface.transparency)) #When you finalize the progress. The bar is cleaned. UpdateProgress = vu.ShowProgress(1) UpdateProgress(0, _("Ready")) Publisher.sendMessage('Update status text in GUI', _("Ready")) Publisher.sendMessage('End busy cursor') del actor
def decimate(points, faces, reduction=0.5, smooth_steps=100, output_vtk=''): """ Decimate vtk triangular mesh with vtk.vtkDecimatePro. Parameters ---------- points : list of lists of floats each element is a list of 3-D coordinates of a vertex on a surface mesh faces : list of lists of integers each element is list of 3 indices of vertices that form a face on a surface mesh reduction : float fraction of mesh faces to remove smooth_steps : integer number of smoothing steps output_vtk : string output decimated vtk file Returns ------- points : list of lists of floats decimated points faces : list of lists of integers decimated faces output_vtk : string output decimated vtk file Examples -------- >>> import os >>> from mindboggle.utils.io_vtk import read_vtk, write_vtk >>> from mindboggle.utils.mesh import decimate >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'labels', 'label22.vtk') >>> reduction = 0.5 >>> smooth_steps = 100 >>> output_vtk = '' >>> faces, lines, indices, points, npoints, scalars, scalar_names, ... o2 = read_vtk(input_vtk) >>> points, faces, output_vtk = decimate(points, faces, reduction, >>> smooth_steps, output_vtk) >>> len(points) == 4567 True >>> len(points) 4567 >>> # View: >>> write_vtk('decimated.vtk', points, indices, lines, faces, scalars, >>> scalar_names) # doctest: +SKIP >>> os.system('mayavi2 -d decimated.vtk -m Surface &') # doctest: +SKIP """ import os import vtk from mindboggle.utils.io_vtk import read_vtk # vtk points: vtk_points = vtk.vtkPoints() [vtk_points.InsertPoint(i, x[0], x[1], x[2]) for i,x in enumerate(points)] # vtk faces: vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) # vtkPolyData: polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() # Export output: if not output_vtk: output_vtk = os.path.join(os.getcwd(), 'decimated_file.vtk') #exporter = vtk.vtkPolyDataWriter() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(decimate.GetOutput()) smoother.SetNumberOfIterations(smooth_steps) smoother.Update() out = smoother.GetOutput() #exporter.SetInput(smoother.GetOutput()) else: decimate.Update() out = decimate.GetOutput() #exporter.SetInput(decimate.GetOutput()) #exporter.SetFileName(output_vtk) #exporter.Write() ## Extract points and faces: #faces, u1, u2, points, u4, u5, u6, u7 = read_vtk(output_vtk) points = [list(out.GetPoint(point_id)) for point_id in range(out.GetNumberOfPoints())] if out.GetNumberOfPolys() > 0: polys = out.GetPolys() faces = [[int(polys.GetData().GetValue(j)) for j in range(i*4 + 1, i*4 + 4)] for i in range(polys.GetNumberOfCells())] else: faces = [] return points, faces, output_vtk
def decimate_file(input_vtk, reduction=0.5, smooth_steps=100, output_vtk=''): """ Decimate vtk triangular mesh file with vtk.vtkDecimatePro. Parameters ---------- input_vtk : string input vtk file with triangular surface mesh reduction : float fraction of mesh faces to remove do_smooth : Boolean smooth after decimation? output_vtk : string output decimated vtk file Returns ------- output_vtk : string output decimated vtk file Examples -------- >>> import os >>> from mindboggle.utils.mesh import decimate_file >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'labels', 'label22.vtk') >>> output_vtk = 'decimated_file.vtk' >>> reduction = 0.9 >>> smooth_steps = 0 >>> decimate_file(input_vtk, reduction=reduction, >>> smooth_steps=smooth_steps, output_vtk=output_vtk) >>> # View: >>> os.system('mayavi2 -d ' + output_vtk + ' -m Surface &') """ import os import vtk from mindboggle.utils.io_vtk import read_vtk # Read VTK surface mesh file: faces, u1, u2, points, u4, labels, u5, u6 = read_vtk(input_vtk) # vtk points: vtk_points = vtk.vtkPoints() [vtk_points.InsertPoint(i, x[0], x[1], x[2]) for i,x in enumerate(points)] # vtk faces: vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) # vtkPolyData: polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() # Export output: if not output_vtk: output_vtk = os.path.join(os.getcwd(), 'decimated_file.vtk') exporter = vtk.vtkPolyDataWriter() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(decimate.GetOutputPort()) smoother.SetNumberOfIterations(smooth_steps) exporter.SetInput(smoother.GetOutput()) else: exporter.SetInput(decimate.GetOutput()) exporter.SetFileName(output_vtk) exporter.Write() return output_vtk
transform.RotateWXYZ(180, 1, 0, 0) move = [0, 0, 0] transform.Translate(move) #transformFilter = vtk.vtkTransformPolyDataFilter() #transformFilter.SetTransform(transform) transforms = [] transforms_filter = [] ############################################################################### # read obj file # obj_filename = '/mnt/data1/StandardBrain/SB/SB256.obj' object = vtk.vtkOBJReader() object.SetFileName(obj_filename) objectSmoother = vtk.vtkSmoothPolyDataFilter() objectSmoother.SetInputConnection(object.GetOutputPort()) objectSmoother.SetNumberOfIterations(100) transforms_filter.append(vtk.vtkTransformPolyDataFilter()) transforms_filter[-1].SetTransform(transform) transforms_filter[-1].SetInputConnection(objectSmoother.GetOutputPort()) transforms_filter[-1].Update() objectMapper = vtk.vtkPolyDataMapper() objectMapper.SetInputConnection(transforms_filter[-1].GetOutputPort()) objectActor = vtk.vtkActor() objectActor.SetMapper(objectMapper) #objectActor.GetProperty().SetRepresentationToWireframe(); objectActor.GetProperty().SetColor(0.5, 0.5, 0.5)
# vtk faces: vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) # vtkPolyData: polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInputConnection(decimate.GetOutputPort()) smoother.SetNumberOfIterations(smooth_steps) output = smoother.GetOutput() else: output = decimate.GetOutput()
def _makeSTL(self): local_dir = self._gray_dir surface_dir = self._vol_dir+'_surfaces'+self._path_dlm try: os.mkdir(surface_dir) except: pass files = fnmatch.filter(sorted(os.listdir(local_dir)),'*.tif') counter = re.search("[0-9]*\.tif", files[0]).group() prefix = self._path_dlm+string.replace(files[0],counter,'') counter = str(len(counter)-4) prefixImageName = local_dir + prefix ### Create the renderer, the render window, and the interactor. The renderer # The following reader is used to read a series of 2D slices (images) # that compose the volume. The slice dimensions are set, and the # pixel spacing. The data Endianness must also be specified. The reader v16=vtk.vtkTIFFReader() v16.SetFilePrefix(prefixImageName) v16.SetDataExtent(0,100,0,100,1,len(files)) v16.SetFilePattern("%s%0"+counter+"d.tif") v16.Update() im = v16.GetOutput() im.SetSpacing(self._pixel_dim[0],self._pixel_dim[1],self._pixel_dim[2]) v = vte.vtkImageExportToArray() v.SetInputData(im) n = np.float32(v.GetArray()) idx = np.argwhere(n) (ystart,xstart,zstart), (ystop,xstop,zstop) = idx.min(0),idx.max(0)+1 I,J,K = n.shape if ystart > 5: ystart -= 5 else: ystart = 0 if ystop < I-5: ystop += 5 else: ystop = I if xstart > 5: xstart -= 5 else: xstart = 0 if xstop < J-5: xstop += 5 else: xstop = J if zstart > 5: zstart -= 5 else: zstart = 0 if zstop < K-5: zstop += 5 else: zstop = K a = n[ystart:ystop,xstart:xstop,zstart:zstop] itk_img = sitk.GetImageFromArray(a) itk_img.SetSpacing([self._pixel_dim[0],self._pixel_dim[1],self._pixel_dim[2]]) print "\n" print "-------------------------------------------------------" print "-- Applying Patch Based Denoising - this can be slow --" print "-------------------------------------------------------" print "\n" pb = sitk.PatchBasedDenoisingImageFilter() pb.KernelBandwidthEstimationOn() pb.SetNoiseModel(3) #use a Poisson noise model since this is confocal pb.SetNoiseModelFidelityWeight(1) pb.SetNumberOfSamplePatches(20) pb.SetPatchRadius(4) pb.SetNumberOfIterations(10) fimg = pb.Execute(itk_img) b = sitk.GetArrayFromImage(fimg) intensity = b.max() #grad = sitk.GradientMagnitudeRecursiveGaussianImageFilter() #grad.SetSigma(0.05) gf = sitk.GradientMagnitudeImageFilter() gf.UseImageSpacingOn() grad = gf.Execute(fimg) edge = sitk.Cast(sitk.BoundedReciprocal( grad ),sitk.sitkFloat32) print "\n" print "-------------------------------------------------------" print "---- Thresholding to deterimine initial level sets ----" print "-------------------------------------------------------" print "\n" t = 0.5 seed = sitk.BinaryThreshold(fimg,t*intensity) #Opening (Erosion/Dilation) step to remove islands smaller than 2 voxels in radius) seed = sitk.BinaryMorphologicalOpening(seed,2) seed = sitk.BinaryFillhole(seed!=0) #Get connected regions r = sitk.ConnectedComponent(seed) labels = sitk.GetArrayFromImage(r) ids = sorted(np.unique(labels)) N = len(ids) if N > 2: i = np.copy(N) while i == N and (t-self._tratio)>-1e-7: t -= 0.01 seed = sitk.BinaryThreshold(fimg,t*intensity) #Opening (Erosion/Dilation) step to remove islands smaller than 2 voxels in radius) seed = sitk.BinaryMorphologicalOpening(seed,2) seed = sitk.BinaryFillhole(seed!=0) #Get connected regions r = sitk.ConnectedComponent(seed) labels = sitk.GetArrayFromImage(r) i = len(np.unique(labels)) if i > N: N = np.copy(i) t+=0.01 else: t = np.copy(self._tratio) seed = sitk.BinaryThreshold(fimg,t*intensity) #Opening (Erosion/Dilation) step to remove islands smaller than 2 voxels in radius) seed = sitk.BinaryMorphologicalOpening(seed,2) seed = sitk.BinaryFillhole(seed!=0) #Get connected regions r = sitk.ConnectedComponent(seed) labels = sitk.GetArrayFromImage(r) labels = np.unique(labels)[1:] ''' labels[labels==0] = -1 labels = sitk.GetImageFromArray(labels) labels.SetSpacing([self._pixel_dim[0],self._pixel_dim[1],self._pixel_dim[2]]) #myshow3d(labels,zslices=range(20)) #plt.show() ls = sitk.ScalarChanAndVeseDenseLevelSetImageFilter() ls.UseImageSpacingOn() ls.SetLambda2(1.5) #ls.SetCurvatureWeight(1.0) ls.SetAreaWeight(1.0) #ls.SetReinitializationSmoothingWeight(1.0) ls.SetNumberOfIterations(100) seg = ls.Execute(sitk.Cast(labels,sitk.sitkFloat32),sitk.Cast(fimg,sitk.sitkFloat32)) seg = sitk.Cast(seg,sitk.sitkUInt8) seg = sitk.BinaryMorphologicalOpening(seg,1) seg = sitk.BinaryFillhole(seg!=0) #Get connected regions #r = sitk.ConnectedComponent(seg) contours = sitk.BinaryContour(seg) myshow3d(sitk.LabelOverlay(sitk.Cast(fimg,sitk.sitkUInt8),contours),zslices=range(fimg.GetSize()[2])) plt.show() ''' segmentation = sitk.Image(r.GetSize(),sitk.sitkUInt8) segmentation.SetSpacing([self._pixel_dim[0],self._pixel_dim[1],self._pixel_dim[2]]) for l in labels: d = sitk.SignedMaurerDistanceMap(r==l,insideIsPositive=False,squaredDistance=True,useImageSpacing=True) #d = sitk.BinaryThreshold(d,-1000,0) #d = sitk.Cast(d,edge.GetPixelIDValue() )*-1+0.5 #d = sitk.Cast(d,edge.GetPixelIDValue() ) seg = sitk.GeodesicActiveContourLevelSetImageFilter() seg.SetPropagationScaling(1.0) seg.SetAdvectionScaling(1.0) seg.SetCurvatureScaling(0.5) seg.SetMaximumRMSError(0.01) levelset = seg.Execute(d,edge) levelset = sitk.BinaryThreshold(levelset,-1000,0) segmentation = sitk.Add(segmentation,levelset) print ("RMS Change for Cell %d: "% l,seg.GetRMSChange()) print ("Elapsed Iterations for Cell %d: "% l, seg.GetElapsedIterations()) ''' contours = sitk.BinaryContour(segmentation) myshow3d(sitk.LabelOverlay(sitk.Cast(fimg,sitk.sitkUInt8),contours),zslices=range(fimg.GetSize()[2])) plt.show() ''' n[ystart:ystop,xstart:xstop,zstart:zstop] = sitk.GetArrayFromImage(segmentation)*100 i = vti.vtkImageImportFromArray() i.SetDataSpacing([self._pixel_dim[0],self._pixel_dim[1],self._pixel_dim[2]]) i.SetDataExtent([0,100,0,100,1,len(files)]) i.SetArray(n) i.Update() thres=vtk.vtkImageThreshold() thres.SetInputData(i.GetOutput()) thres.ThresholdByLower(0) thres.ThresholdByUpper(101) iso=vtk.vtkImageMarchingCubes() iso.SetInputConnection(thres.GetOutputPort()) iso.SetValue(0,1) regions = vtk.vtkConnectivityFilter() regions.SetInputConnection(iso.GetOutputPort()) regions.SetExtractionModeToAllRegions() regions.ColorRegionsOn() regions.Update() N = regions.GetNumberOfExtractedRegions() for i in xrange(N): r = vtk.vtkConnectivityFilter() r.SetInputConnection(iso.GetOutputPort()) r.SetExtractionModeToSpecifiedRegions() r.AddSpecifiedRegion(i) g = vtk.vtkExtractUnstructuredGrid() g.SetInputConnection(r.GetOutputPort()) geo = vtk.vtkGeometryFilter() geo.SetInputConnection(g.GetOutputPort()) geo.Update() t = vtk.vtkTriangleFilter() t.SetInputConnection(geo.GetOutputPort()) t.Update() cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(t.GetOutputPort()) s = vtk.vtkSmoothPolyDataFilter() s.SetInputConnection(cleaner.GetOutputPort()) s.SetNumberOfIterations(50) dl = vtk.vtkDelaunay3D() dl.SetInputConnection(s.GetOutputPort()) dl.Update() self.cells.append(dl) for i in xrange(N): g = vtk.vtkGeometryFilter() g.SetInputConnection(self.cells[i].GetOutputPort()) t = vtk.vtkTriangleFilter() t.SetInputConnection(g.GetOutputPort()) #get the surface points of the cells and save to points attribute v = t.GetOutput() points = [] for j in xrange(v.GetNumberOfPoints()): p = [0,0,0] v.GetPoint(j,p) points.append(p) self.points.append(points) #get the volume of the cell vo = vtk.vtkMassProperties() vo.SetInputConnection(t.GetOutputPort()) self.volumes.append(vo.GetVolume()) stl = vtk.vtkSTLWriter() stl.SetInputConnection(t.GetOutputPort()) stl.SetFileName(surface_dir+'cell%02d.stl' % (i+self._counter)) stl.Write() if self._display: skinMapper = vtk.vtkDataSetMapper() skinMapper.SetInputConnection(regions.GetOutputPort()) skinMapper.SetScalarRange(regions.GetOutput().GetPointData().GetArray("RegionId").GetRange()) skinMapper.SetColorModeToMapScalars() #skinMapper.ScalarVisibilityOff() skinMapper.Update() skin = vtk.vtkActor() skin.SetMapper(skinMapper) #skin.GetProperty().SetColor(0,0,255) # An outline provides context around the data. # outlineData = vtk.vtkOutlineFilter() outlineData.SetInputConnection(v16.GetOutputPort()) mapOutline = vtk.vtkPolyDataMapper() mapOutline.SetInputConnection(outlineData.GetOutputPort()) outline = vtk.vtkActor() #outline.SetMapper(mapOutline) #outline.GetProperty().SetColor(0,0,0) colorbar = vtk.vtkScalarBarActor() colorbar.SetLookupTable(skinMapper.GetLookupTable()) colorbar.SetTitle("Cells") colorbar.SetNumberOfLabels(N) # Create the renderer, the render window, and the interactor. The renderer # draws into the render window, the interactor enables mouse- and # keyboard-based interaction with the data within the render window. # aRenderer = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(aRenderer) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) # It is convenient to create an initial view of the data. The FocalPoint # and Position form a vector direction. Later on (ResetCamera() method) # this vector is used to position the camera to look at the data in # this direction. aCamera = vtk.vtkCamera() aCamera.SetViewUp (0, 0, -1) aCamera.SetPosition (0, 1, 0) aCamera.SetFocalPoint (0, 0, 0) aCamera.ComputeViewPlaneNormal() # Actors are added to the renderer. An initial camera view is created. # The Dolly() method moves the camera towards the FocalPoint, # thereby enlarging the image. aRenderer.AddActor(outline) aRenderer.AddActor(skin) aRenderer.AddActor(colorbar) aRenderer.SetActiveCamera(aCamera) aRenderer.ResetCamera () aCamera.Dolly(1.5) # Set a background color for the renderer and set the size of the # render window (expressed in pixels). aRenderer.SetBackground(0.0,0.0,0.0) renWin.SetSize(800, 600) # Note that when camera movement occurs (as it does in the Dolly() # method), the clipping planes often need adjusting. Clipping planes # consist of two planes: near and far along the view direction. The # near plane clips out objects in front of the plane the far plane # clips out objects behind the plane. This way only what is drawn # between the planes is actually rendered. aRenderer.ResetCameraClippingRange() im=vtk.vtkWindowToImageFilter() im.SetInput(renWin) iren.Initialize(); iren.Start(); #remove gray directory shutil.rmtree(local_dir)
def get_actor(vtk_source, color=color_diffuse, opacity=1.0, has_scalar_visibility=False): """ Set `scalar_visibility` be `True` makes `color` unavailable. :return: a vtkActor """ # Reduce the number of triangles decimator = vtk.vtkDecimatePro() decimator.SetInputConnection(vtk_source.GetOutputPort()) # decimator.SetInputData(vtk_source) decimator.SetFeatureAngle(60) decimator.MaximumIterations = 1 decimator.PreserveTopologyOn() decimator.SetMaximumError(0.0002) decimator.SetTargetReduction(0.3) decimator.SetErrorIsAbsolute(1) decimator.SetAbsoluteError(0.0002) decimator.ReleaseDataFlagOn() # Smooth the triangle vertices smoother = vtk.vtkSmoothPolyDataFilter() # smoother.SetInputConnection(decimator.GetOutputPort()) smoother.SetInputConnection(vtk_source.GetOutputPort()) smoother.SetNumberOfIterations(smooth_iteration) smoother.SetRelaxationFactor(smooth_factor) smoother.SetFeatureAngle(smooth_angle) smoother.FeatureEdgeSmoothingOff() smoother.BoundarySmoothingOff() smoother.SetConvergence(0) smoother.ReleaseDataFlagOn() # Generate Normals normals = vtk.vtkPolyDataNormals() # normals.SetInputConnection(vtk_source.GetOutputPort()) normals.SetInputConnection(smoother.GetOutputPort()) normals.SetFeatureAngle(60.0) normals.ReleaseDataFlagOn() stripper = vtk.vtkStripper() stripper.SetInputConnection(normals.GetOutputPort()) stripper.ReleaseDataFlagOn() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(vtk_source.GetOutputPort()) # mapper.SetInputConnection(stripper.GetOutputPort()) mapper.SetScalarVisibility(has_scalar_visibility) actor = vtk.vtkActor() actor.SetMapper(mapper) actor.GetProperty().SetDiffuseColor(color) actor.GetProperty().SetSpecular(0.3) actor.GetProperty().SetSpecularPower(20) # actor.GetProperty().SetOpacity(opacity) if opacity < 1.0: if is_depth_peeling_supported(render_window, renderer, True): setup_evn_for_depth_peeling(render_window, renderer, max_peels, occlusion) actor.GetProperty().SetOpacity(opacity) else: print "Depth Peeling is not supported." return actor
def init_cell_field_borders_actors(self, actor_specs, drawing_params=None): """ initializes cell field actors where each cell is rendered individually as a separate spatial domain :param actor_specs: {ActorSpecs} :param drawing_params: {DrawingParameters} :return: None """ field_dim = self.currentDrawingParameters.bsd.fieldDim hex_flag = False lattice_type_str = self.get_lattice_type_str() # if lattice_type_str.lower() == 'hexagonal': # hex_flag = True hex_flag = self.is_lattice_hex(drawing_params=drawing_params) cell_type_image_data = vtk.vtkImageData() # adding 1 pixel border around the lattice to make rendering smooth at lattice borders cell_type_image_data.SetDimensions(field_dim.x + 2, field_dim.y + 2, field_dim.z + 2) cell_type_image_data.GetPointData().SetScalars(self.cell_id_array) # create a different actor for each cell type number_of_actors = len(self.used_cell_types_list) # creating and initializing filters, smoothers and mappers - one for each cell type filter_list = [vtk.vtkDiscreteMarchingCubes() for i in xrange(number_of_actors)] smoother_list = [vtk.vtkSmoothPolyDataFilter() for i in xrange(number_of_actors)] normals_list = [vtk.vtkPolyDataNormals() for i in xrange(number_of_actors)] mapper_list = [vtk.vtkPolyDataMapper() for i in xrange(number_of_actors)] for actor_counter, actor_number in enumerate(self.used_cell_types_list): if VTK_MAJOR_VERSION >= 6: filter_list[actor_counter].SetInputData(cell_type_image_data) else: filter_list[actor_counter].SetInput(cell_type_image_data) if self.used_cell_types_list[actor_counter] >= 1: ct_all = vtk_to_numpy(self.cell_type_array) cid_all = vtk_to_numpy(self.cell_id_array) cid_unique = [] for idx in range(len(ct_all)): if ct_all[idx] == self.used_cell_types_list[actor_counter]: cid = cid_all[idx] if cid not in cid_unique: cid_unique.append(cid_all[idx]) for idx in range(len(cid_unique)): filter_list[actor_counter].SetValue(idx, cid_unique[idx]) else: filter_list[actor_counter].SetValue(0, 13) # rwh: what the?? smoother_list[actor_counter].SetInputConnection(filter_list[actor_counter].GetOutputPort()) normals_list[actor_counter].SetInputConnection(smoother_list[actor_counter].GetOutputPort()) normals_list[actor_counter].SetFeatureAngle(45.0) mapper_list[actor_counter].SetInputConnection(normals_list[actor_counter].GetOutputPort()) mapper_list[actor_counter].ScalarVisibilityOff() actors_dict = actor_specs.actors_dict if actor_number in actors_dict.keys(): actor = actors_dict[actor_number] actor.SetMapper(mapper_list[actor_counter]) cell_type_lut = self.get_type_lookup_table() actor.GetProperty().SetDiffuseColor( cell_type_lut.GetTableValue(actor_number)[0:3]) if hex_flag: actor.SetScale(self.xScaleHex, self.yScaleHex, self.zScaleHex)
cropOutlineSource.GenerateScalarsOn() cropOutlineSource.SetActivePlaneId(0) cropOutlineMapper = vtk.vtkPolyDataMapper() cropOutlineMapper.SetInputConnection(cropOutlineSource.GetOutputPort()) cropOutline = vtk.vtkActor() cropOutline.SetMapper(cropOutlineMapper) #--------------------------------------------------------- # Do the surface rendering skinExtractor = vtk.vtkMarchingCubes() skinExtractor.SetInputConnection(readers[img2].GetOutputPort()) skinExtractor.SetValue(0,1) # 500) skinSmooth = vtk.vtkSmoothPolyDataFilter() skinSmooth.SetInputConnection(skinExtractor.GetOutputPort()) skinDecimate = vtk.vtkDecimatePro() skinDecimate.SetInputConnection(skinSmooth.GetOutputPort()) skinDecimate.SetFeatureAngle(180) skinDecimate.PreserveTopologyOn() skinDecimate.SetTargetReduction(0.2) skinNormals = vtk.vtkPolyDataNormals() skinNormals.SetInputConnection(skinDecimate.GetOutputPort()) skinNormals.SetFeatureAngle(60.0) skinStripper = vtk.vtkStripper() skinStripper.SetMaximumLength(10) skinStripper.SetInputConnection(skinNormals.GetOutputPort())
def applyFilters(self, state): surface = None surface = state.inputModelNode.GetPolyDataConnection() if state.decimation: triangle = vtk.vtkTriangleFilter() triangle.SetInputConnection(surface) decimation = vtk.vtkDecimatePro() decimation.SetTargetReduction(state.reduction) decimation.SetBoundaryVertexDeletion(state.boundaryDeletion) decimation.PreserveTopologyOn() decimation.SetInputConnection(triangle.GetOutputPort()) surface = decimation.GetOutputPort() if state.smoothing: if state.smoothingMethod == "Laplace": smoothing = vtk.vtkSmoothPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.laplaceIterations) smoothing.SetRelaxationFactor(state.laplaceRelaxation) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() elif state.smoothingMethod == "Taubin": smoothing = vtk.vtkWindowedSincPolyDataFilter() smoothing.SetBoundarySmoothing(state.boundarySmoothing) smoothing.SetNumberOfIterations(state.taubinIterations) smoothing.SetPassBand(state.taubinPassBand) smoothing.SetInputConnection(surface) surface = smoothing.GetOutputPort() if state.normals: normals = vtk.vtkPolyDataNormals() normals.SetAutoOrientNormals(state.autoOrientNormals) normals.SetFlipNormals(state.flipNormals) normals.SetSplitting(state.splitting) normals.SetFeatureAngle(state.featureAngle) normals.ConsistencyOn() normals.SetInputConnection(surface) surface = normals.GetOutputPort() if state.mirror: mirrorTransformMatrix = vtk.vtkMatrix4x4() mirrorTransformMatrix.SetElement(0, 0, -1 if state.mirrorX else 1) mirrorTransformMatrix.SetElement(1, 1, -1 if state.mirrorY else 1) mirrorTransformMatrix.SetElement(2, 2, -1 if state.mirrorZ else 1) mirrorTransform = vtk.vtkTransform() mirrorTransform.SetMatrix(mirrorTransformMatrix) transformFilter = vtk.vtkTransformPolyDataFilter() transformFilter.SetInputConnection(surface) transformFilter.SetTransform(mirrorTransform) surface = transformFilter.GetOutputPort() if mirrorTransformMatrix.Determinant()<0: reverse = vtk.vtkReverseSense() reverse.SetInputConnection(surface) surface = reverse.GetOutputPort() if state.cleaner: cleaner = vtk.vtkCleanPolyData() cleaner.SetInputConnection(surface) surface = cleaner.GetOutputPort() if state.fillHoles: fillHoles = vtk.vtkFillHolesFilter() fillHoles.SetHoleSize(state.fillHolesSize) fillHoles.SetInputConnection(surface) # Need to auto-orient normals, otherwise holes # could appear to be unfilled when only front-facing elements # are chosen to be visible. normals = vtk.vtkPolyDataNormals() normals.AutoOrientNormalsOn() normals.ConsistencyOn() normals.SetInputConnection(fillHoles.GetOutputPort()) surface = normals.GetOutputPort() if state.connectivity: connectivity = vtk.vtkPolyDataConnectivityFilter() connectivity.SetExtractionModeToLargestRegion() connectivity.SetInputConnection(surface) surface = connectivity.GetOutputPort() state.outputModelNode.SetPolyDataConnection(surface) return True
def Render(self, volumeReader): """ This method attempts to tesselate the image data. :@type volumeReader: data.imageIO.base.VolumeImageReader :@param volumeReader: This object handles opening image data and passing it to the appropriate VTK image container :@rtype: 2-tuple :@return: The vtkActor created from tesselated image data and a vtkLocator for improving picking operations. """ if self.imageSetID is None: return self.volumeReader = volumeReader self.vtkReader = volumeReader.LoadVTKReader(self.dataSpacing) # Gaussian Smoothing self.gaussFilter = vtk.vtkImageGaussianSmooth() self.gaussFilter.SetDimensionality(3) self.gaussFilter.SetStandardDeviation(1) self.gaussFilter.SetRadiusFactors(1, 1, 1) self.gaussFilter.SetInput(self.vtkReader.GetOutput()) # VOI Extractor self.voi = vtk.vtkExtractVOI() self.voi.SetInputConnection(self.gaussFilter.GetOutputPort()) # self.voi.SetInputConnection(self.vtkReader.GetOutputPort()) self.voi.SetVOI(self.volumeReader.VolumeExtents) # Surface rendering self.bactExtractor = vtk.vtkMarchingCubes() self.bactExtractor.GenerateValues(1, self.isocontourLevel) self.bactExtractor.ComputeNormalsOff() self.bactExtractor.SetInputConnection(self.voi.GetOutputPort()) # surface rendering with dividing cubes # self.bactExtractor = vtk.vtkRecursiveDividingCubes() # self.bactExtractor.SetInputConnection(self.voi.GetOutputPort()) # self.bactExtractor.SetValue(self.isocontourLevel[0]) # self.bactExtractor.SetDistance(0.5) # self.bactExtractor.SetIncrement(2) # Smooth the mesh relaxedMesh = vtk.vtkSmoothPolyDataFilter() relaxedMesh.SetNumberOfIterations(50) relaxedMesh.SetInput(self.bactExtractor.GetOutput()) # Calculate normals meshNormals = vtk.vtkPolyDataNormals() meshNormals.SetFeatureAngle(60.0) meshNormals.SetInput(relaxedMesh.GetOutput()) # Restrip mesh after normal computation restrippedMesh = vtk.vtkStripper() restrippedMesh.SetInput(meshNormals.GetOutput()) # Convert mesh to graphics primitives self.meshMapper = vtk.vtkPolyDataMapper() self.meshMapper.ScalarVisibilityOff() self.meshMapper.SetInput(restrippedMesh.GetOutput()) # Finally create a renderable object "Actor" # that can be passed to the render window self.ibcActor = vtk.vtkActor() self.ibcActor.SetMapper(self.meshMapper) ibcColor = DataStore.GetImageSet(self.imageSetID).color self.ibcActor.GetProperty().SetDiffuseColor(ibcColor.r, ibcColor.g, ibcColor.b) self.ibcActor.GetProperty().SetSpecular(.1) self.ibcActor.GetProperty().SetSpecularPower(5) self.ibcActor.GetProperty().SetOpacity(1) self.ibcActor.SetVisibility(boolInt(self.visible)) self.renderer.AddActor(self.ibcActor) # Optional Locator to help the ray traced picker self.bactLocator = vtk.vtkCellLocator() self.bactLocator.SetDataSet(restrippedMesh.GetOutput()) self.bactLocator.LazyEvaluationOn() return self.bactLocator
def __init__ (self, interactor, renderer, mesh_filename, reg_filename): self.interactor = interactor self.renderer = renderer reader = vtk.vtkStructuredPointsReader() reader.SetFileName(mesh_filename) cf = vtk.vtkContourFilter() cf.SetInput(reader.GetOutput()) cf.SetValue(0, 1) deci = vtk.vtkDecimatePro() deci.SetInput(cf.GetOutput()) deci.SetTargetReduction(.1) deci.PreserveTopologyOn() smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(deci.GetOutput()) smoother.SetNumberOfIterations(100) normals = vtk.vtkPolyDataNormals() normals.SetInput(smoother.GetOutput()) normals.FlipNormalsOn() normals.SetFeatureAngle(60.0) stripper = vtk.vtkStripper() stripper.SetInputConnection(normals.GetOutputPort()) lut = vtk.vtkLookupTable() lut.SetHueRange(0, 0) lut.SetSaturationRange(0, 0) lut.SetValueRange(0.2, 0.55) contourMapper = vtk.vtkPolyDataMapper() #contourMapper.SetInput(normals.GetOutput()) contourMapper.SetInput(stripper.GetOutput()) contourMapper.SetLookupTable(lut) self.contours = vtk.vtkActor() self.contours.SetMapper(contourMapper) #self.contours.GetProperty().SetRepresentationToWireframe() self.contours.GetProperty().SetRepresentationToSurface() #self.contours.GetProperty().SetInterpolationToGouraud() #self.contours.GetProperty().SetOpacity(1.0) #self.contours.GetProperty().SetAmbient(0.1) self.contours.GetProperty().SetDiffuse(0.1) #self.contours.GetProperty().SetSpecular(0.1) #self.contours.GetProperty().SetSpecularPower(0.1) # now setmatrix() on the actor from the reg file ! def array_to_vtkmatrix4x4(scipy_array): vtkmat = vtk.vtkMatrix4x4() for i in range(0,4): for j in range(0,4): vtkmat.SetElement(i,j, scipy_array[i,j]) return vtkmat mat = pickle.load(file(reg_filename, 'r')) vtkmat = array_to_vtkmatrix4x4(mat) self.contours.SetUserMatrix(vtkmat) #self.contours.GetProperty().SetOpacity(.38) #adjustable in the grid manager now # XXX YAH somehow get a callback when actor is moved... self.renderer.AddActor(self.contours)
def init_cell_field_actors_borderless(self, actor_specs, drawing_params=None): hex_flag = False lattice_type_str = self.get_lattice_type_str() if lattice_type_str.lower() == 'hexagonal': hex_flag = True # todo 5 - check if this should be called earlier # self.extractCellFieldData() # initializes self.usedCellTypesList field_dim = self.currentDrawingParameters.bsd.fieldDim cell_type_image_data = vtk.vtkImageData() cell_type_image_data.SetDimensions(field_dim.x + 2, field_dim.y + 2, field_dim.z + 2) # adding 1 pixel border around the lattice to make rendering smooth at lattice borders cell_type_image_data.GetPointData().SetScalars(self.cell_type_array) voi = vtk.vtkExtractVOI() if VTK_MAJOR_VERSION >= 6: voi.SetInputData(cell_type_image_data) else: voi.SetInput(cell_type_image_data) # voi.SetVOI(1,self.dim[0]-1, 1,self.dim[1]-1, 1,self.dim[2]-1 ) # crop out the artificial boundary layer that we created voi.SetVOI(0, 249, 0, 189, 0, 170) # # todo 5- check if it is possible to call it once # self.usedCellTypesList = self.extractCellFieldData() number_of_actors = len(self.used_cell_types_list) # creating and initializing filters, smoothers and mappers - one for each cell type filterList = [vtk.vtkDiscreteMarchingCubes() for i in xrange(number_of_actors)] smootherList = [vtk.vtkSmoothPolyDataFilter() for i in xrange(number_of_actors)] normalsList = [vtk.vtkPolyDataNormals() for i in xrange(number_of_actors)] mapperList = [vtk.vtkPolyDataMapper() for i in xrange(number_of_actors)] # actorCounter=0 # for i in usedCellTypesList: for actorCounter, actor_number in enumerate(self.used_cell_types_list): # for actorCounter in xrange(len(self.usedCellTypesList)): if VTK_MAJOR_VERSION >= 6: filterList[actorCounter].SetInputData(cell_type_image_data) else: filterList[actorCounter].SetInput(cell_type_image_data) # filterList[actorCounter].SetInputConnection(voi.GetOutputPort()) # filterList[actorCounter].SetValue(0, usedCellTypesList[actorCounter]) filterList[actorCounter].SetValue(0, self.used_cell_types_list[actorCounter]) smootherList[actorCounter].SetInputConnection(filterList[actorCounter].GetOutputPort()) # smootherList[actorCounter].SetNumberOfIterations(200) normalsList[actorCounter].SetInputConnection(smootherList[actorCounter].GetOutputPort()) normalsList[actorCounter].SetFeatureAngle(45.0) mapperList[actorCounter].SetInputConnection(normalsList[actorCounter].GetOutputPort()) mapperList[actorCounter].ScalarVisibilityOff() actors_dict = actor_specs.actors_dict cell_type_lut = self.get_type_lookup_table() cell_type_lut_max = cell_type_lut.GetNumberOfTableValues() - 1 if actor_number in actors_dict.keys(): actor = actors_dict[actor_number] actor.SetMapper(mapperList[actorCounter]) actor.GetProperty().SetDiffuseColor( cell_type_lut.GetTableValue(self.used_cell_types_list[actorCounter])[0:3]) # actor.GetProperty().SetDiffuseColor( # # self.celltypeLUT.GetTableValue(self.usedCellTypesList[actorCounter])[0:3]) # self.celltypeLUT.GetTableValue(actor_number)[0:3]) if hex_flag: actor.SetScale(self.xScaleHex, self.yScaleHex, self.zScaleHex)
def renderIBC(filePrefix, imgLow, imgHigh): global picker, redCone, greenCone # # This example reads a volume dataset, extracts an isosurface that # represents the skin and displays it. # # The following reader is used to read a series of 2D slices (images) # that compose the volume. The slice dimensions are set, and the # pixel spacing. The data Endianness must also be specified. The reader # usese the FilePrefix in combination with the slice number to construct # filenames using the format FilePrefix.%d. (In this case the FilePrefix # is the root name of the file: quarter.) #vtkVolume16Reader v13R # v13R SetDataDimensions 1388 1040 # v13R SetDataByteOrderToBigEndian # v13R SetFilePrefix "IBC146h.R_s" # v13R SetImageRange 0 44 # v13R SetDataSpacing 1 1 2 # Image reader v13G = vtk.vtkTIFFReader() v13G.SetDataExtent(1, 1380, 1, 1030, imgLow, imgHigh) v13G.SetDataByteOrderToLittleEndian() v13G.SetFilePrefix(filePrefix) v13G.SetDataSpacing(0.1, 0.1, 0.6) # Gaussian Smoothing gaus_v13G = vtk.vtkImageGaussianSmooth() gaus_v13G.SetDimensionality(3) gaus_v13G.SetStandardDeviation(1) gaus_v13G.SetRadiusFactors(1, 1, 1) gaus_v13G.SetInput(v13G.GetOutput()) # Set up the volume rendering volumeMapper = vtk.vtkVolumeTextureMapper3D() volumeMapper.SetInput(v13G.GetOutput()) volume = vtk.vtkVolume() volume.SetMapper(volumeMapper) # Surface rendering bactExtractor = vtk.vtkMarchingCubes() bactExtractor.SetInputConnection(gaus_v13G.GetOutputPort()) bactExtractor.SetValue(0,20000) # bactNormals = vtk.vtkPolyDataNormals() # bactNormals.SetInputConnection(bactExtractor.GetOutputPort()) # bactNormals.SetFeatureAngle(90.0) # # bactStripper = vtk.vtkStripper() # bactStripper.SetInputConnection(bactNormals.GetOutputPort()) # bactLocator = vtk.vtkCellLocator() bactLocator.SetDataSet(bactExtractor.GetOutput()) bactLocator.LazyEvaluationOn() # # bactMapper = vtk.vtkPolyDataMapper() # bactMapper.SetInputConnection(bactStripper.GetOutputPort()) # bactMapper.ScalarVisibilityOff() # skinE_v13G = vtk.vtkContourFilter() ## skinE_v13G = vtk.vtkMarchingCubes() # skinE_v13G.UseScalarTreeOn() # skinE_v13G.SetInput(gaus_v13G.GetOutput()) # skinE_v13G.SetValue(0, 10000) # smooth_v13G = vtk.vtkSmoothPolyDataFilter() smooth_v13G.SetInput(bactExtractor.GetOutput()) smooth_v13G.SetNumberOfIterations(50) deci_v13G = vtk.vtkDecimatePro() deci_v13G.SetInput(smooth_v13G.GetOutput()) deci_v13G.SetTargetReduction(0.5) deci_v13G.PreserveTopologyOn() smoother_v13G = vtk.vtkSmoothPolyDataFilter() smoother_v13G.SetInput(deci_v13G.GetOutput()) smoother_v13G.SetNumberOfIterations(50) skinNormals_v13G = vtk.vtkPolyDataNormals() skinNormals_v13G.SetInput(deci_v13G.GetOutput()) skinNormals_v13G.SetFeatureAngle(60.0) skinStripper_v13G = vtk.vtkStripper() skinStripper_v13G.SetInput(skinNormals_v13G.GetOutput()) skinMapper_v13G = vtk.vtkPolyDataMapper() skinMapper_v13G.SetInput(skinStripper_v13G.GetOutput()) skinMapper_v13G.ScalarVisibilityOff() skin_v13G = vtk.vtkActor() skin_v13G.SetMapper(skinMapper_v13G) skin_v13G.GetProperty().SetDiffuseColor(0.2, 1, 0.2) skin_v13G.GetProperty().SetSpecular(.1) skin_v13G.GetProperty().SetSpecularPower(5) skin_v13G.GetProperty().SetOpacity(0.9) # It is convenient to create an initial view of the data. The FocalPoint # and Position form a vector direction. Later on (ResetCamera() method) # this vector is used to position the camera to look at the data in # this direction. aCamera = vtk.vtkCamera() aCamera.SetViewUp(0, 0, -1) aCamera.SetPosition(0, 1.1, 2) aCamera.SetFocalPoint(0, -0.25, 0) aCamera.ComputeViewPlaneNormal() # Actors are added to the renderer. An initial camera view is created. # The Dolly() method moves the camera towards the FocalPoint, # thereby enlarging the image. #aRenderer AddActor skin_v13R ren.AddActor(skin_v13G) ren.SetActiveCamera(aCamera) ren.ResetCamera() aCamera.Dolly(1.0) # Note that when camera movement occurs (as it does in the Dolly() # method), the clipping planes often need adjusting. Clipping planes # consist of two planes: near and far along the view direction. The # near plane clips out objects in front of the plane the far plane # clips out objects behind the plane. This way only what is drawn # between the planes is actually rendered. ren.ResetCameraClippingRange() # render renWin.Render() # CONE PICKER RENDER #--------------------------------------------------------- # the cone points along the -x axis coneSource = vtk.vtkConeSource() coneSource.CappingOn() coneSource.SetHeight(2) coneSource.SetRadius(1) coneSource.SetResolution(11) coneSource.SetCenter(1,0,0) coneSource.SetDirection(-1,0,0) coneMapper = vtk.vtkDataSetMapper() coneMapper.SetInputConnection(coneSource.GetOutputPort()) redCone = vtk.vtkActor() redCone.PickableOff() redCone.SetMapper(coneMapper) redCone.GetProperty().SetColor(1,0,0) greenCone = vtk.vtkActor() greenCone.PickableOff() greenCone.SetMapper(coneMapper) greenCone.GetProperty().SetColor(0,1,0) # Add the two cones (or just one, if you want) ren.AddViewProp(redCone) ren.AddViewProp(greenCone) #--------------------------------------------------------- # the picker picker = vtk.vtkVolumePicker() picker.SetTolerance(1e-6) picker.SetVolumeOpacityIsovalue(0.1) # locator is optional, but improves performance for large polydata picker.AddLocator(bactLocator) #--------------------------------------------------------- # custom interaction iren.AddObserver("MouseMoveEvent", MoveCursor) # END CONE PICKER RENDER # initialize and start the interactor iren.Initialize() iren.Start()
def decimate(points, faces, reduction=0.5, smooth_steps=100, scalars=[], save_vtk=False, output_vtk=''): """ Decimate vtk triangular mesh with vtk.vtkDecimatePro. Parameters ---------- points : list of lists of floats each element is a list of 3-D coordinates of a vertex on a surface mesh faces : list of lists of integers each element is list of 3 indices of vertices that form a face on a surface mesh reduction : float fraction of mesh faces to remove smooth_steps : integer number of smoothing steps scalars : list of integers or floats optional scalars for output VTK file save_vtk : Boolean output decimated vtk file? output_vtk : string output decimated vtk file name Returns ------- points : list of lists of floats decimated points faces : list of lists of integers decimated faces scalars : list of integers or floats scalars for output VTK file output_vtk : string output decimated vtk file Examples -------- >>> import os >>> from mindboggle.utils.io_vtk import read_vtk, write_vtk >>> from mindboggle.utils.mesh import decimate >>> from mindboggle.utils.plots import plot_vtk >>> path = os.environ['MINDBOGGLE_DATA'] >>> input_vtk = os.path.join(path, 'arno', 'labels', 'label22.vtk') >>> reduction = 0.5 >>> smooth_steps = 100 >>> save_vtk = False >>> output_vtk = '' >>> faces, lines, indices, points, npoints, scalars, scalar_names, ... o2 = read_vtk(input_vtk) >>> points, faces, scalars, output_vtk = decimate(points, faces, reduction, >>> smooth_steps, scalars, >>> save_vtk, output_vtk) >>> len(points) == 2679 True >>> len(points) 2679 >>> # View: >>> output_vtk = 'decimated.vtk' >>> write_vtk(output_vtk, points, indices, lines, faces, scalars, >>> scalar_names) # doctest: +SKIP >>> plot_vtk(output_vtk) # doctest: +SKIP """ import os import vtk #------------------------------------------------------------------------- # vtk points: #------------------------------------------------------------------------- vtk_points = vtk.vtkPoints() [vtk_points.InsertPoint(i, x[0], x[1], x[2]) for i,x in enumerate(points)] #------------------------------------------------------------------------- # vtk faces: #------------------------------------------------------------------------- vtk_faces = vtk.vtkCellArray() for face in faces: vtk_face = vtk.vtkPolygon() vtk_face.GetPointIds().SetNumberOfIds(3) vtk_face.GetPointIds().SetId(0, face[0]) vtk_face.GetPointIds().SetId(1, face[1]) vtk_face.GetPointIds().SetId(2, face[2]) vtk_faces.InsertNextCell(vtk_face) #------------------------------------------------------------------------- # vtk scalars: #------------------------------------------------------------------------- if scalars: vtk_scalars = vtk.vtkFloatArray() vtk_scalars.SetName("scalars") for scalar in scalars: vtk_scalars.InsertNextValue(scalar) #------------------------------------------------------------------------- # vtkPolyData: #------------------------------------------------------------------------- polydata = vtk.vtkPolyData() polydata.SetPoints(vtk_points) polydata.SetPolys(vtk_faces) if scalars: polydata.GetPointData().SetScalars(vtk_scalars) #------------------------------------------------------------------------- # Decimate: #------------------------------------------------------------------------- # We want to preserve topology (not let any cracks form). # This may limit the total reduction possible. decimate = vtk.vtkDecimatePro() decimate.SetInput(polydata) decimate.SetTargetReduction(reduction) decimate.PreserveTopologyOn() #------------------------------------------------------------------------- # Smooth: #------------------------------------------------------------------------- if save_vtk: if not output_vtk: output_vtk = os.path.join(os.getcwd(), 'decimated.vtk') exporter = vtk.vtkPolyDataWriter() if smooth_steps > 0: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(decimate.GetOutput()) smoother.SetNumberOfIterations(smooth_steps) smoother.Update() out = smoother.GetOutput() if save_vtk: exporter.SetInput(smoother.GetOutput()) else: decimate.Update() out = decimate.GetOutput() if save_vtk: exporter.SetInput(decimate.GetOutput()) #------------------------------------------------------------------------- # Export output: #------------------------------------------------------------------------- if save_vtk: exporter.SetFileName(output_vtk) exporter.Write() if not os.path.exists(output_vtk): raise(IOError(output_vtk + " not found")) #------------------------------------------------------------------------- # Extract decimated points, faces, and scalars: #------------------------------------------------------------------------- points = [list(out.GetPoint(point_id)) for point_id in range(out.GetNumberOfPoints())] if out.GetNumberOfPolys() > 0: polys = out.GetPolys() pt_data = out.GetPointData() faces = [[int(polys.GetData().GetValue(j)) for j in range(i*4 + 1, i*4 + 4)] for i in range(polys.GetNumberOfCells())] if scalars: scalars = [pt_data.GetScalars().GetValue(i) for i in range(len(points))] else: faces = [] scalars = [] return points, faces, scalars, output_vtk
def CreateSurface(self): _ = i18n.InstallLanguage(self.language) reader = vtk.vtkXMLImageDataReader() reader.SetFileName(self.filename) reader.Update() image = reader.GetOutput() if (self.flip_image): # Flip original vtkImageData flip = vtk.vtkImageFlip() flip.SetInput(reader.GetOutput()) flip.SetFilteredAxis(1) flip.FlipAboutOriginOn() image = flip.GetOutput() # Create vtkPolyData from vtkImageData if self.mode == "CONTOUR": contour = vtk.vtkContourFilter() contour.SetInput(image) contour.SetValue(0, self.min_value) # initial threshold contour.SetValue(1, self.max_value) # final threshold contour.GetOutput().ReleaseDataFlagOn() contour.AddObserver("ProgressEvent", lambda obj,evt: self.SendProgress(obj, _("Generating 3D surface..."))) polydata = contour.GetOutput() else: #mode == "GRAYSCALE": mcubes = vtk.vtkMarchingCubes() mcubes.SetInput(image) mcubes.SetValue(0, 255) mcubes.ComputeScalarsOn() mcubes.ComputeGradientsOn() mcubes.ComputeNormalsOn() mcubes.ThresholdBetween(self.min_value, self.max_value) mcubes.GetOutput().ReleaseDataFlagOn() mcubes.AddObserver("ProgressEvent", lambda obj,evt: self.SendProgress(obj, _("Generating 3D surface..."))) polydata = mcubes.GetOutput() if self.decimate_reduction: decimation = vtk.vtkQuadricDecimation() decimation.SetInput(polydata) decimation.SetTargetReduction(self.decimate_reduction) decimation.GetOutput().ReleaseDataFlagOn() decimation.AddObserver("ProgressEvent", lambda obj,evt: self.SendProgress(obj, _("Generating 3D surface..."))) polydata = decimation.GetOutput() if self.smooth_iterations and self.smooth_relaxation_factor: smoother = vtk.vtkSmoothPolyDataFilter() smoother.SetInput(polydata) smoother.SetNumberOfIterations(self.smooth_iterations) smoother.SetFeatureAngle(80) smoother.SetRelaxationFactor(self.smooth_relaxation_factor) smoother.FeatureEdgeSmoothingOn() smoother.BoundarySmoothingOn() smoother.GetOutput().ReleaseDataFlagOn() smoother.AddObserver("ProgressEvent", lambda obj,evt: self.SendProgress(obj, _("Generating 3D surface..."))) polydata = smoother.GetOutput() if self.keep_largest: conn = vtk.vtkPolyDataConnectivityFilter() conn.SetInput(polydata) conn.SetExtractionModeToLargestRegion() conn.AddObserver("ProgressEvent", lambda obj,evt: self.SendProgress(obj, _("Generating 3D surface..."))) polydata = conn.GetOutput() # Filter used to detect and fill holes. Only fill boundary edges holes. #TODO: Hey! This piece of code is the same from # polydata_utils.FillSurfaceHole, we need to review this. if self.fill_holes: filled_polydata = vtk.vtkFillHolesFilter() filled_polydata.SetInput(polydata) filled_polydata.SetHoleSize(300) filled_polydata.AddObserver("ProgressEvent", lambda obj,evt: self.SendProgress(obj, _("Generating 3D surface..."))) polydata = filled_polydata.GetOutput() filename = tempfile.mktemp() writer = vtk.vtkXMLPolyDataWriter() writer.SetInput(polydata) writer.SetFileName(filename) writer.Write() self.pipe.send(None) self.pipe.send(filename)