import vtk
sphereSource = vtk.vtkSphereSource()
sphereSource.Update()
ids = vtk.vtkIdTypeArray()
ids.SetNumberOfComponents(1)
ids.InsertNextValue(2)
ids.InsertNextValue(10)
selectionNode = vtk.vtkSelectionNode()
selectionNode.SetFieldType(vtk.vtkSelectionNode.CELL)
selectionNode.SetContentType(vtk.vtkSelectionNode.INDICES)
selectionNode.SetSelectionList(ids)
selectionNode.GetProperties().Set(vtk.vtkSelectionNode.INVERSE(), 1)
selection = vtk.vtkSelection()
selection.AddNode(selectionNode)
extractSelection = vtk.vtkExtractSelection()
extractSelection.SetInputData(0, sphereSource.GetOutput())
extractSelection.SetInputData(1, selection)
extractSelection.Update()
surfaceFilter = vtk.vtkDataSetSurfaceFilter()
surfaceFilter.SetInputConnection(extractSelection.GetOutputPort())
surfaceFilter.Update()
input = vtk.vtkPolyData()
input.ShallowCopy(surfaceFilter.GetOutput())
featureEdges = vtk.vtkFeatureEdges()
'''
vtkFeatureEdges能够提取多边形网格模型中四种类型的边
1. 边界边 即只被一个多边形或者一条边包含的边
2. 非流行边 被3个或3个以上的多边形包含的边
3. 特征边 需要设置一个特征角的阈值,当包含同一条边的两个三角形的法向量的夹角大于该阈值时,即为一个特征边
4. 流行边 只被两个多边形包含的边
'''
featureEdges.SetInputData(input)
featureEdges.BoundaryEdgesOn()
featureEdges.FeatureEdgesOff()
featureEdges.ManifoldEdgesOff()
featureEdges.NonManifoldEdgesOff()
featureEdges.Update()
numberOfOpenEdges = featureEdges.GetOutput().GetNumberOfCells()
if numberOfOpenEdges:
print('No close')
else:
print('close')
fillHolesFilter = vtk.vtkFillHolesFilter()
fillHolesFilter.SetInputData(input)
featureEdges.Update()
normals = vtk.vtkPolyDataNormals()
'''
vtkPolyDataNormals主要是用来计算法向量的,而法向量与光照和阴影计算有关。
单元的法向量朝向则与单元的点的顺序相关,只有保持所有单元的点顺序一致才能得到正确的法向量,否则在网格模型显示时会得到意外的结果
由于漏洞填充,模型的所有单元的点顺序不一致,所以使用vtkPolyDataNormals进行调整
'''
normals.SetInputConnection(fillHolesFilter.GetOutputPort())
normals.ConsistencyOn()
normals.SplittingOff()
normals.Update()
leftViewport = [0.0, 0.0, 0.5, 1.0]
rightViewport = [0.5, 0.0, 1.0, 1.0]
originalMapper = vtk.vtkPolyDataMapper()
originalMapper.SetInputData(input)
backfaceProp = vtk.vtkProperty()
backfaceProp.SetDiffuseColor(0.89, 0.81, 0.34)
originalActor = vtk.vtkActor()
originalActor.SetMapper(originalMapper)
originalActor.SetBackfaceProperty(backfaceProp)
originalActor.GetProperty().SetDiffuseColor(1.0, 0.3882, 0.2784)
edgeMapper = vtk.vtkPolyDataMapper()
edgeMapper.SetInputData(featureEdges.GetOutput())
edgeActor = vtk.vtkActor()
edgeActor.SetMapper(edgeMapper)
edgeActor.GetProperty().SetEdgeColor(0.0, 0.0, 1.0)
edgeActor.GetProperty().SetEdgeVisibility(1)
edgeActor.GetProperty().SetLineWidth(5)
filledMapper = vtk.vtkPolyDataMapper()
filledMapper.SetInputData(normals.GetOutput())
filledActor = vtk.vtkActor()
filledActor.SetMapper(filledMapper)
filledActor.GetProperty().SetDiffuseColor(1.0, 0.3882, 0.2784)
leftRenderer = vtk.vtkRenderer()
leftRenderer.SetViewport(leftViewport)
leftRenderer.AddActor(originalActor)
leftRenderer.AddActor(edgeActor)
leftRenderer.GetActiveCamera().SetPosition(0, -1, 0)
leftRenderer.GetActiveCamera().SetFocalPoint(0, 0, 0)
leftRenderer.GetActiveCamera().SetViewUp(0, 0, 1)
leftRenderer.GetActiveCamera().Azimuth(30)
leftRenderer.GetActiveCamera().Elevation(30)
leftRenderer.ResetCamera()
rightRenderer = vtk.vtkRenderer()
rightRenderer.SetViewport(rightViewport)
rightRenderer.AddActor(filledActor)
rightRenderer.SetActiveCamera(leftRenderer.GetActiveCamera())
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(leftRenderer)
renderWindow.AddRenderer(rightRenderer)
renderWindow.SetSize(640, 480)
renderWindow.Render()
renderWindow.SetWindowName("PolyDataClosed")
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.Initialize()
renderWindowInteractor.Start()