def updateCurve(self): if self.controlPointsMarkupNode and self.curveModelNode: self.curvePoints.Reset() # clear without deallocating memory lines = vtk.vtkCellArray() self.curvePoly.SetLines(lines) if self.controlPointsMarkupNode.GetNumberOfFiducials() >= 2: self.pointInterpolationFunction(self.controlPointsMarkupNode, self.curvePoints) nInterpolatedPoints = self.curvePoints.GetNumberOfPoints() lines.InsertNextCell(nInterpolatedPoints) for i in range(nInterpolatedPoints): lines.InsertCellPoint(i) tubeFilter = vtk.vtkTubeFilter() tubeFilter.SetInputData(self.curvePoly) tubeFilter.SetRadius(self.tubeRadius) tubeFilter.SetNumberOfSides(self.tubeResolution) tubeFilter.SetCapping(not self.closed) # Triangulation is necessary to avoid discontinuous lines # in model/slice intersection display triangles = vtk.vtkTriangleFilter() triangles.SetInputConnection(tubeFilter.GetOutputPort()) triangles.Update() self.curveModelNode.SetAndObservePolyData(triangles.GetOutput()) self.curveModelNode.Modified()
def updateCurve(self): if self.SourceNode and self.DestinationNode: if self.SourceNode.GetNumberOfFiducials() < 2: if self.CurvePoly != None: self.CurvePoly.Initialize() else: if self.CurvePoly == None: self.CurvePoly = vtk.vtkPolyData() if self.DestinationNode.GetDisplayNodeID() == None: modelDisplayNode = slicer.vtkMRMLModelDisplayNode() modelDisplayNode.SetColor(self.CurveColour) slicer.mrmlScene.AddNode(modelDisplayNode) self.DestinationNode.SetAndObserveDisplayNodeID( modelDisplayNode.GetID()) if self.InterpolationMethod == 0: self.nodesToLinear(self.SourceNode, self.CurvePoly) elif self.InterpolationMethod == 1: self.nodesToSpline(self.SourceNode, self.CurvePoly) tubeFilter = vtk.vtkTubeFilter() tubeFilter.SetInputData(self.CurvePoly) tubeFilter.SetRadius(self.CurveThickness) tubeFilter.SetNumberOfSides(self.CurveFaces) tubeFilter.CappingOn() tubeFilter.Update() self.DestinationNode.SetAndObservePolyData(tubeFilter.GetOutput()) self.DestinationNode.Modified() if self.DestinationNode.GetScene() == None: slicer.mrmlScene.AddNode(self.DestinationNode) displayNode = self.DestinationNode.GetDisplayNode() if displayNode: displayNode.SetActiveScalarName('')
def updateTipModelNode(self, tipModelNode, poly, p0, pe, radius, color, opacity): points = vtk.vtkPoints() cellArray = vtk.vtkCellArray() points.SetNumberOfPoints(2) cellArray.InsertNextCell(2) points.SetPoint(0, p0) cellArray.InsertCellPoint(0) points.SetPoint(1, pe) cellArray.InsertCellPoint(1) poly.Initialize() poly.SetPoints(points) poly.SetLines(cellArray) tubeFilter = vtk.vtkTubeFilter() tubeFilter.SetInputData(poly) tubeFilter.SetRadius(radius) tubeFilter.SetNumberOfSides(20) tubeFilter.CappingOn() tubeFilter.Update() # Sphere represents the locator tip sphere = vtk.vtkSphereSource() sphere.SetRadius(radius * 2.0) sphere.SetCenter(pe) sphere.Update() apd = vtk.vtkAppendPolyData() if vtk.VTK_MAJOR_VERSION <= 5: apd.AddInput(sphere.GetOutput()) apd.AddInput(tubeFilter.GetOutput()) else: apd.AddInputConnection(sphere.GetOutputPort()) apd.AddInputConnection(tubeFilter.GetOutputPort()) apd.Update() tipModelNode.SetAndObservePolyData(apd.GetOutput()) tipModelNode.Modified() tipDispID = tipModelNode.GetDisplayNodeID() if tipDispID == None: tipDispNode = self.scene.AddNewNodeByClass( 'vtkMRMLModelDisplayNode') tipDispNode.SetScene(self.scene) tipModelNode.SetAndObserveDisplayNodeID(tipDispNode.GetID()) tipDispID = tipModelNode.GetDisplayNodeID() tipDispNode = self.scene.GetNodeByID(tipDispID) prevState = tipDispNode.StartModify() tipDispNode.SetColor(color) tipDispNode.SetOpacity(opacity) tipDispNode.SliceIntersectionVisibilityOn() tipDispNode.SetSliceDisplayModeToIntersection() tipDispNode.EndModify(prevState)
def createOptionalPathModel(self, pos, holeInfoList, intNumOfOptionalPath): if intNumOfOptionalPath == 1: self.setOptionalPathVisibility(1) pathListRAS = [] for i in range(len(holeInfoList)): pathListRAS.append(self.templateRAS[holeInfoList[i][3]]) print "pathListRAS: ", pathListRAS #(not generate path -> pass, otherwise go on) self.optModelNode = slicer.mrmlScene.GetNodeByID(self.optionalPathModelNodeID) if self.optModelNode == None: self.optModelNode = slicer.vtkMRMLModelNode() self.optModelNode.SetName('AllOptionalPaths') slicer.mrmlScene.AddNode(self.optModelNode) self.optionalPathModelNodeID = self.optModelNode.GetID() self.dnodeOpt = slicer.vtkMRMLModelDisplayNode() self.dnodeOpt.SetColor(0.96,0.92,0.56) slicer.mrmlScene.AddNode(self.dnodeOpt) self.optModelNode.SetAndObserveDisplayNodeID(self.dnodeOpt.GetID()) optModelAppend = vtk.vtkAppendPolyData() #for path in pathListRAS: for index in range(len(pathListRAS)): optLineSource = vtk.vtkLineSource() optLineSource.SetPoint1(pos) optLineSource.SetPoint2(pathListRAS[index]) optTubeFilter = vtk.vtkTubeFilter() optTubeFilter.SetInputConnection(optLineSource.GetOutputPort()) optTubeFilter.SetRadius(1.0) optTubeFilter.SetNumberOfSides(10) optTubeFilter.CappingOn() optTubeFilter.Update() if vtk.VTK_MAJOR_VERSION <= 5: optModelAppend.AddInput(optTubeFilter.GetOutput()) else: optModelAppend.AddInputData(optTubeFilter.GetOutput()) optModelAppend.Update() self.optModelNode.SetAndObservePolyData(optModelAppend.GetOutput())
def createCylinder(name, R, H=50): cylinder = slicer.mrmlScene.CreateNodeByClass('vtkMRMLModelNode') cylinder.SetName(slicer.mrmlScene.GetUniqueNameByString(name)) slicer.mrmlScene.AddNode(cylinder) cylinder.CreateDefaultDisplayNodes() lineSource = vtk.vtkLineSource() lineSource.SetPoint1(0, 0, H / 2) lineSource.SetPoint2(0, 0, -H / 2) tubeFilter = vtk.vtkTubeFilter() tubeFilter.SetInputConnection(lineSource.GetOutputPort()) tubeFilter.SetRadius(R) tubeFilter.SetNumberOfSides(50) tubeFilter.CappingOn() #tubeFilter.Update() cylinder.SetPolyDataConnection(tubeFilter.GetOutputPort()) cylinder.SetAttribute('radius', str(R)) cylinder.SetAttribute('height', str(H)) return cylinder
def updateCurve(self): if self.AutomaticUpdate == False: return if self.SourceNode and self.DestinationNode: if self.SourceNode.GetNumberOfFiducials() < 2: if self.CurvePoly != None: self.CurvePoly.Initialize() self.CurveLength = 0.0 else: if self.CurvePoly == None: self.CurvePoly = vtk.vtkPolyData() if self.DestinationNode.GetDisplayNodeID() == None: modelDisplayNode = slicer.vtkMRMLModelDisplayNode() modelDisplayNode.SetColor(self.ModelColor) slicer.mrmlScene.AddNode(modelDisplayNode) self.DestinationNode.SetAndObserveDisplayNodeID(modelDisplayNode.GetID()) if self.InterpolationMethod == 0: if self.RingMode > 0: self.nodeToPoly(self.SourceNode, self.CurvePoly, True) else: self.nodeToPoly(self.SourceNode, self.CurvePoly, False) elif self.InterpolationMethod == 1: # Cardinal Spline if self.RingMode > 0: self.nodeToPolyCardinalSpline(self.SourceNode, self.CurvePoly, True) else: self.nodeToPolyCardinalSpline(self.SourceNode, self.CurvePoly, False) elif self.InterpolationMethod == 2: # Hermite Spline if self.RingMode > 0: self.nodeToPolyHermiteSpline(self.SourceNode, self.CurvePoly, True) else: self.nodeToPolyHermiteSpline(self.SourceNode, self.CurvePoly, False) self.CurveLength = self.calculateLineLength(self.CurvePoly) tubeFilter = vtk.vtkTubeFilter() curvatureValues = vtk.vtkDoubleArray() if self.Curvature: ## If the curvature option is ON, calculate the curvature along the curve. (meanKappa, minKappa, maxKappa) = self.computeCurvatures(self.CurvePoly, curvatureValues) self.CurvePoly.GetPointData().AddArray(curvatureValues) self.curvatureMeanKappa = meanKappa self.curvatureMinKappa = minKappa self.curvatureMaxKappa = maxKappa else: self.curvatureMeanKappa = None self.curvatureMinKappa = None self.curvatureMaxKappa = None tubeFilter.SetInputData(self.CurvePoly) tubeFilter.SetRadius(self.TubeRadius) tubeFilter.SetNumberOfSides(20) tubeFilter.CappingOn() tubeFilter.Update() self.DestinationNode.SetAndObservePolyData(tubeFilter.GetOutput()) self.DestinationNode.Modified() if self.DestinationNode.GetScene() == None: slicer.mrmlScene.AddNode(self.DestinationNode) displayNode = self.DestinationNode.GetDisplayNode() if displayNode: if self.Curvature: displayNode.SetActiveScalarName('Curvature') else: displayNode.SetActiveScalarName('')
def createTemplateModel(self): self.templatePathVectors = [] self.templatePathOrigins = [] tempModelNode = slicer.mrmlScene.GetNodeByID(self.templateModelNodeID) if tempModelNode == None: tempModelNode = slicer.vtkMRMLModelNode() tempModelNode.SetName('NeedleGuideTemplate') slicer.mrmlScene.AddNode(tempModelNode) self.templateModelNodeID = tempModelNode.GetID() dnode = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(dnode) tempModelNode.SetAndObserveDisplayNodeID(dnode.GetID()) self.modelNodetag = tempModelNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent, self.onTemplateTransformUpdated) tempModelAppend = vtk.vtkAppendPolyData() for row in self.templateConfig: p1 = numpy.array(row[0:3]) p2 = numpy.array(row[3:6]) tempLineSource = vtk.vtkLineSource() tempLineSource.SetPoint1(p1) tempLineSource.SetPoint2(p2) tempTubeFilter = vtk.vtkTubeFilter() tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort()) tempTubeFilter.SetRadius(1.0) tempTubeFilter.SetNumberOfSides(18) tempTubeFilter.CappingOn() tempTubeFilter.Update() pathLineSource = vtk.vtkLineSource() v = p2-p1 nl = numpy.linalg.norm(v) n = v/nl # normal vector l = row[6] p3 = p1 + l * n pathLineSource.SetPoint1(p1) pathLineSource.SetPoint2(p3) self.templatePathOrigins.append([row[0], row[1], row[2], 1.0]) self.templatePathVectors.append([n[0], n[1], n[2], 1.0]) self.templateMaxDepth.append(row[6]) pathTubeFilter = vtk.vtkTubeFilter() pathTubeFilter.SetInputConnection(pathLineSource.GetOutputPort()) pathTubeFilter.SetRadius(0.8) pathTubeFilter.SetNumberOfSides(18) pathTubeFilter.CappingOn() pathTubeFilter.Update() if vtk.VTK_MAJOR_VERSION <= 5: tempModelAppend.AddInput(tempTubeFilter.GetOutput()) # pathModelAppend.AddInput(pathTubeFilter.GetOutput()) else: tempModelAppend.AddInputData(tempTubeFilter.GetOutput()) # pathModelAppend.AddInputData(pathTubeFilter.GetOutput()) tempModelAppend.Update() tempModelNode.SetAndObservePolyData(tempModelAppend.GetOutput())
def visualNeedlePath(self, pos, pointOnTemplateRAS): if type(pointOnTemplateRAS) == list: pass elif type(pointOnTemplateRAS) == int: pointOnTemplateRAS = self.templateRAS[pointOnTemplateRAS] self.pathModelNode = slicer.mrmlScene.GetNodeByID(self.needlePathModelNodeID) if self.pathModelNode == None: self.pathModelNode = slicer.vtkMRMLModelNode() self.pathModelNode.SetName('AngulatedNeedlePath') slicer.mrmlScene.AddNode(self.pathModelNode) self.needlePathModelNodeID = self.pathModelNode.GetID() self.dnodeSelectedPath = slicer.vtkMRMLModelDisplayNode() self.dnodeSelectedPath.SetColor(0, 1, 1) slicer.mrmlScene.AddNode(self.dnodeSelectedPath) self.pathModelNode.SetAndObserveDisplayNodeID(self.dnodeSelectedPath.GetID()) pathModelAppend = vtk.vtkAppendPolyData() tempLineSource = vtk.vtkLineSource() tempLineSource.SetPoint1(pos) # target in RAS tempLineSource.SetPoint2(pointOnTemplateRAS) # point on template in RAS tempTubeFilter = vtk.vtkTubeFilter() tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort()) tempTubeFilter.SetRadius(1.0) tempTubeFilter.SetNumberOfSides(18) tempTubeFilter.CappingOn() tempTubeFilter.Update() self.setModelSliceIntersectionVisibilityByID(self.needlePathModelNodeID, 1) if vtk.VTK_MAJOR_VERSION <= 5: pathModelAppend.AddInput(tempTubeFilter.GetOutput()) else: pathModelAppend.AddInputData(tempTubeFilter.GetOutput()) pathModelAppend.Update() self.pathModelNode.SetAndObservePolyData(pathModelAppend.GetOutput()) # # Reslice along with the selected needle # print "(target) pos: ", pos print "pointOnTemplateRAS: ", pointOnTemplateRAS R = pointOnTemplateRAS[0] A = pointOnTemplateRAS[1] S = pointOnTemplateRAS[2] deltaR = pos[0] - R deltaA = pos[1] - A deltaS = pos[2] - S pathVector = numpy.array([deltaR, deltaA, deltaS]) tR = numpy.array([1.0, 0, 0]) vectorA = numpy.cross(pathVector, tR) vectorS = numpy.cross(pathVector, vectorA) pathVectorNorm = numpy.linalg.norm(pathVector) vectorANorm = numpy.linalg.norm(vectorA) vectorSNorm = numpy.linalg.norm(vectorS) matrix = vtk.vtkMatrix4x4() matrix.Identity() ## TODO: if pathVector is parallel to R matrix.SetElement(0, 0, pathVector[0]/pathVectorNorm) matrix.SetElement(1, 0, pathVector[1]/pathVectorNorm) matrix.SetElement(2, 0, pathVector[2]/pathVectorNorm) matrix.SetElement(0, 1, vectorA[0]/vectorANorm) matrix.SetElement(1, 1, vectorA[1]/vectorANorm) matrix.SetElement(2, 1, vectorA[2]/vectorANorm) matrix.SetElement(0, 2, vectorS[0]/vectorSNorm) matrix.SetElement(1, 2, vectorS[1]/vectorSNorm) matrix.SetElement(2, 2, vectorS[2]/vectorSNorm) matrix.SetElement(0, 3, R) matrix.SetElement(1, 3, A) matrix.SetElement(2, 3, S) selectNeedleNode = slicer.mrmlScene.GetNodeByID(self.selectNeedleNodeID) if selectNeedleNode == None: selectNeedleNode = slicer.vtkMRMLLinearTransformNode() selectNeedleNode.SetName('SelectedNeedle') slicer.mrmlScene.AddNode(selectNeedleNode) self.selectNeedleNodeID = selectNeedleNode.GetID() selectNeedleNode.SetAndObserveMatrixTransformToParent(matrix) modelNodes = slicer.mrmlScene.GetNodesByClass("vtkMRMLModelNode") for index in range(modelNodes.GetNumberOfItems()): indexNode = modelNodes.GetItemAsObject(index) if indexNode.GetTransformNodeID() == selectNeedleNode.GetID(): indexNode.SetDisplayVisibility(1) self.selectNeedleModelNode = indexNode print indexNode.GetID() red = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeRed") yellow = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeYellow") green = slicer.mrmlScene.GetNodeByID("vtkMRMLSliceNodeGreen") ## Changed by yz, Sep/25 ## If 3D Slicer includes the extension "SlicerIGT", uncomment the below code # vrdLogic = slicer.modules.volumereslicedriver.logic() # redDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), red) # redMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_INPLANE, red) # yellowDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), yellow) # yellowMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_INPLANE90, yellow) # greenDriver = vrdLogic.SetDriverForSlice(selectNeedleNode.GetID(), green) # greenMode = vrdLogic.SetModeForSlice(vrdLogic.MODE_TRANSVERSE, green) # vrdLogic.Modified() return pointOnTemplateRAS
def createTemplateModel(self): self.templatePathVectors = [] self.templatePathOrigins = [] self.tempModelNode = slicer.mrmlScene.GetNodeByID(self.templateModelNodeID) if self.tempModelNode is None: self.tempModelNode = slicer.vtkMRMLModelNode() self.tempModelNode.SetName('NeedleGuideTemplate') slicer.mrmlScene.AddNode(self.tempModelNode) self.templateModelNodeID = self.tempModelNode.GetID() dnode = slicer.vtkMRMLModelDisplayNode() #dnode.SetColor(self.ModelColor) slicer.mrmlScene.AddNode(dnode) self.tempModelNode.SetAndObserveDisplayNodeID(dnode.GetID()) self.modelNodetag = self.tempModelNode.AddObserver(slicer.vtkMRMLTransformableNode.TransformModifiedEvent, self.onTemplateTransformUpdated) self.pathModelNode = slicer.mrmlScene.GetNodeByID(self.needlePathModelNodeID) if self.pathModelNode is None: self.pathModelNode = slicer.vtkMRMLModelNode() self.pathModelNode.SetName('NeedleGuideNeedlePath') slicer.mrmlScene.AddNode(self.pathModelNode) self.needlePathModelNodeID = self.pathModelNode.GetID() dnode = slicer.vtkMRMLModelDisplayNode() slicer.mrmlScene.AddNode(dnode) self.pathModelNode.SetAndObserveDisplayNodeID(dnode.GetID()) pathModelAppend = vtk.vtkAppendPolyData() tempModelAppend = vtk.vtkAppendPolyData() for row in self.templateConfig: p1 = numpy.array(row[0:3]) p2 = numpy.array(row[3:6]) tempLineSource = vtk.vtkLineSource() tempLineSource.SetPoint1(p1) tempLineSource.SetPoint2(p2) tempTubeFilter = vtk.vtkTubeFilter() tempTubeFilter.SetInputConnection(tempLineSource.GetOutputPort()) tempTubeFilter.SetRadius(1.0) tempTubeFilter.SetNumberOfSides(18) tempTubeFilter.CappingOn() tempTubeFilter.Update() pathLineSource = vtk.vtkLineSource() v = p2-p1 nl = numpy.linalg.norm(v) n = v/nl # normal vector l = row[6] p3 = p1 + l * n pathLineSource.SetPoint1(p1) pathLineSource.SetPoint2(p3) self.templatePathOrigins.append([row[0], row[1], row[2], 1.0]) self.templatePathVectors.append([n[0], n[1], n[2], 1.0]) self.templateMaxDepth.append(row[6]) pathTubeFilter = vtk.vtkTubeFilter() pathTubeFilter.SetInputConnection(pathLineSource.GetOutputPort()) pathTubeFilter.SetRadius(0.8) pathTubeFilter.SetNumberOfSides(18) pathTubeFilter.CappingOn() pathTubeFilter.Update() if vtk.VTK_MAJOR_VERSION <= 5: tempModelAppend.AddInput(tempTubeFilter.GetOutput()) pathModelAppend.AddInput(pathTubeFilter.GetOutput()) else: tempModelAppend.AddInputData(tempTubeFilter.GetOutput()) pathModelAppend.AddInputData(pathTubeFilter.GetOutput()) tempModelAppend.Update() self.tempModelNode.SetAndObservePolyData(tempModelAppend.GetOutput()) pathModelAppend.Update() self.pathModelNode.SetAndObservePolyData(pathModelAppend.GetOutput())
def updateCurve(self): if self.AutomaticUpdate == False: return if self.SourceNode and self.DestinationNode: if self.SourceNode.GetNumberOfFiducials() < 2: if self.CurvePoly != None: self.CurvePoly.Initialize() self.CurveLength = 0.0 else: if self.CurvePoly == None: self.CurvePoly = vtk.vtkPolyData() if self.DestinationNode.GetDisplayNodeID() == None: modelDisplayNode = slicer.vtkMRMLModelDisplayNode() modelDisplayNode.SetColor(self.ModelColor) slicer.mrmlScene.AddNode(modelDisplayNode) self.DestinationNode.SetAndObserveDisplayNodeID( modelDisplayNode.GetID()) if self.InterpolationMethod == 0: if self.RingMode > 0: self.nodeToPoly(self.SourceNode, self.CurvePoly, True) else: self.nodeToPoly(self.SourceNode, self.CurvePoly, False) elif self.InterpolationMethod == 1: # Cardinal Spline if self.RingMode > 0: self.nodeToPolyCardinalSpline(self.SourceNode, self.CurvePoly, True) else: self.nodeToPolyCardinalSpline(self.SourceNode, self.CurvePoly, False) elif self.InterpolationMethod == 2: # Hermite Spline if self.RingMode > 0: self.nodeToPolyHermiteSpline(self.SourceNode, self.CurvePoly, True) else: self.nodeToPolyHermiteSpline(self.SourceNode, self.CurvePoly, False) self.CurveLength = self.calculateLineLength(self.CurvePoly) tubeFilter = vtk.vtkTubeFilter() curvatureValues = vtk.vtkDoubleArray() if self.Curvature: ## If the curvature option is ON, calculate the curvature along the curve. (meanKappa, minKappa, maxKappa) = self.computeCurvatures(self.CurvePoly, curvatureValues) self.CurvePoly.GetPointData().AddArray(curvatureValues) self.curvatureMeanKappa = meanKappa self.curvatureMinKappa = minKappa self.curvatureMaxKappa = maxKappa else: self.curvatureMeanKappa = None self.curvatureMinKappa = None self.curvatureMaxKappa = None tubeFilter.SetInputData(self.CurvePoly) tubeFilter.SetRadius(self.TubeRadius) tubeFilter.SetNumberOfSides(20) tubeFilter.CappingOn() tubeFilter.Update() # self.DestinationNode.SetAndObservePolyData(tubeFilter.GetOutput()) self.DestinationNode.SetAndObservePolyData(self.CurvePoly) self.DestinationNode.Modified() if self.DestinationNode.GetScene() == None: slicer.mrmlScene.AddNode(self.DestinationNode) displayNode = self.DestinationNode.GetDisplayNode() if displayNode: if self.Curvature: displayNode.SetActiveScalarName('Curvature') else: displayNode.SetActiveScalarName('')
def vtk_to_obj_converter(self, node, radius=0.1, number_of_sides=3): qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) polydata = node.GetPolyData() tuber = vtk.vtkTubeFilter() tuber.SetNumberOfSides(int(number_of_sides)) tuber.SetRadius(radius) tuber.SetInputData(polydata) tuber.Update() tubes = tuber.GetOutputDataObject(0) # scalars = tubes.GetPointData().GetArray(0) # scalars.SetName("scalars") triangles = vtk.vtkTriangleFilter() triangles.SetInputData(tubes) triangles.Update() tripolydata = vtk.vtkPolyData() tripolydata.ShallowCopy(triangles.GetOutput()) # Decrease the number of triangle of 30% to reduce Blender loading costs decimate = vtk.vtkDecimatePro() decimate.SetInputData(tripolydata) decimate.SetTargetReduction(.30) decimate.Update() mapper = vtk.vtkPolyDataMapper() mapper.SetInputConnection(decimate.GetOutputPort()) r = random.randrange(0, 256, 1) g = random.randrange(0, 256, 1) b = random.randrange(0, 256, 1) actor = vtk.vtkActor() actor.SetMapper(mapper) # actor.GetProperty().SetColor(0, 0, 0) # Ka: ambient color of the material (r, g, b) actor.GetProperty().SetDiffuseColor( r, g, b) # Kd: diffuse color of the material (r, g, b) # actor.GetProperty().SetSpecularColor(0, 0, 0) # Ks: specular color of the material (r, g, b) renderer = vtk.vtkRenderer() renderer.AddActor(actor) window = vtk.vtkRenderWindow() window.AddRenderer(renderer) # Get output path storageNode = node.GetStorageNode() filepath = storageNode.GetFullNameFromFileName() filename = filepath.rsplit('.', 1) writer = vtk.vtkOBJExporter() writer.SetFilePrefix(filename[0]) writer.SetInput(window) writer.Write() qt.QApplication.restoreOverrideCursor() if writer.Write() == 0: qt.QMessageBox.critical(None, "Conversion", "Conversion failed") else: qt.QMessageBox.information(None, "Conversion", "Conversion done")