一:主要的知识点
1、说明
本文只是教程内容的一小段,因博客字数限制,故进行拆分。主教程链接:vtk教程——逐行解析官网所有Python示例-CSDN博客
2、知识点纪要
本段代码主要涉及的有①模型裁剪模型的相关注意事项与运用
二:代码及注释
import numpy as np import vtkmodules.vtkInteractionStyle import vtkmodules.vtkRenderingOpenGL2 from vtkmodules.vtkFiltersSources import vtkConeSource from vtkmodules.vtkRenderingCore import vtkActor, vtkPolyDataMapper, vtkDataSetMapper, vtkRenderWindow, vtkRenderer, \ vtkRenderWindowInteractor from vtkmodules.vtkCommonColor import vtkNamedColors from vtkmodules.vtkFiltersCore import vtkImplicitPolyDataDistance from vtkmodules.vtkCommonCore import vtkFloatArray from vtkmodules.vtkCommonDataModel import vtkRectilinearGrid from vtkmodules.vtkFiltersGeneral import vtkClipDataSet from vtkmodules.vtkFiltersGeometry import vtkRectilinearGridGeometryFilter def main(): colors = vtkNamedColors() cone = vtkConeSource() cone.SetResolution(50) # 设置圆锥体侧面沿周长方向的细分数 cone.SetDirection(0, 0, -1) # 设置圆锥体的轴线方向,默认情况下,圆锥的尖端在原点 cone.SetHeight(3.0) # 设置 圆锥体沿其轴线的长度 cone.CappingOn() # 开启圆锥底面的**封闭(Capping)**功能 cone.Update() """ 用于裁剪的模型必须得是封闭的,待裁剪的模型似乎没有这个要求 """ implicitPolyDataDistance = vtkImplicitPolyDataDistance() implicitPolyDataDistance.SetInput(cone.GetOutput()) dimension = 51 xCoords = vtkFloatArray() for x, i in enumerate(np.linspace(-1, 1, dimension)): xCoords.InsertNextValue(i) yCoords = vtkFloatArray() for y, i in enumerate(np.linspace(-1.0, 1.0, dimension)): yCoords.InsertNextValue(i) zCoords = vtkFloatArray() for z, i in enumerate(np.linspace(-1.0, 1.0, dimension)): zCoords.InsertNextValue(i) """ vtkRectilinearGrid 用于表示一种特定类型的**结构化数据集(Structured Data Set)**的类 特点是: 结构化(Structured): 拓扑是规则的。网格中的每个单元(Cell,即 3D 中的体素)都可以通过其在三个方向上的整数索引 (i,j,k) 唯一确定 轴向非均匀(Rectilinear / Axis-Aligned Non-Uniform): 虽然网格是沿着 X,Y,Z 轴对齐的,但沿每个轴的**间距(Spacing)**可以是非均匀的 """ rgrid = vtkRectilinearGrid() rgrid.SetDimensions(xCoords.GetNumberOfTuples(), yCoords.GetNumberOfTuples(), zCoords.GetNumberOfTuples()) rgrid.SetXCoordinates(xCoords) rgrid.SetYCoordinates(yCoords) rgrid.SetZCoordinates(zCoords) signedDistances = vtkFloatArray() signedDistances.SetNumberOfComponents(1) signedDistances.SetName('SignedDistances') for pointId in range(0, rgrid.GetNumberOfPoints()): p = rgrid.GetPoint(pointId) signedDistance = implicitPolyDataDistance.EvaluateFunction(p) signedDistances.InsertNextValue(signedDistance) rgrid.GetPointData().SetScalars(signedDistances) """ vtkClipDataSet 裁剪 与vtkClipPolyData的不同在于vtkClipPolyData用于切割表面几何体 vtkClipDataSet用于切割体积数据 """ clipper = vtkClipDataSet() clipper.SetInputData(rgrid) """ InsideOutOn 开启内外反转模式,默认情况下,clipper保留函数值f(x)>value的区域 开启 InsideOutOn() 后,它将保留函数值 f(x)<Value 的区域 """ clipper.InsideOutOn() # 这里保留的就是内部 """ 开启此选项后,clipper 不仅会通过其主输出端口 (GetOutput()) 输出被保留的部分,还会通过第二个输出端口 (GetOutputPort(1)) 输出被**移除(即被裁剪)**的那部分网格 """ clipper.GenerateClippedOutputOn() clipper.Update() # print("num: ",clipper.GetNumberOfOutputPorts()) coneMapper = vtkPolyDataMapper() coneMapper.SetInputConnection(cone.GetOutputPort()) coneActor = vtkActor() coneActor.SetMapper(coneMapper) """ vtkRectilinearGridGeometryFilter 将vtkRectilinearGrid这种体积数据集转换为polyData的过滤器 """ geometryFilter = vtkRectilinearGridGeometryFilter() geometryFilter.SetInputData(rgrid) """ SetExtent 使用3D索引范围来定义要提取的几何体 """ geometryFilter.SetExtent(0, dimension, 0, dimension, int(dimension / 2), int(dimension / 2)) geometryFilter.Update() rgridMapper = vtkPolyDataMapper() rgridMapper.SetInputConnection(geometryFilter.GetOutputPort()) rgridMapper.SetScalarRange( rgrid.GetPointData().GetArray('SignedDistances').GetRange()) wireActor = vtkActor() wireActor.SetMapper(rgridMapper) wireActor.GetProperty().SetRepresentationToWireframe() clipperMapper = vtkDataSetMapper() clipperMapper.SetInputConnection(clipper.GetOutputPort()) clipperMapper.ScalarVisibilityOff() """ 示例代码clipper.GetOutputPort(1)个不起作用,加一个clip clipperOutsideMapper = vtkDataSetMapper() clipperOutsideMapper.SetInputConnection(clipper.GetOutputPort(1)) clipperOutsideMapper.ScalarVisibilityOff() """ clipper1 = vtkClipDataSet() clipper1.SetInputData(rgrid) clipper1.InsideOutOff() # Retain f(x) > Value, which is outside the cone clipper1.SetValue(0.0) clipper1.GenerateClippedOutputOff() clipper1.Update() clipperOutsideMapper = vtkDataSetMapper() clipperOutsideMapper.SetInputConnection(clipper1.GetOutputPort()) clipperOutsideMapper.ScalarVisibilityOff() clipperActor = vtkActor() clipperActor.SetMapper(clipperMapper) clipperActor.GetProperty().SetColor(colors.GetColor3d('Banana')) clipperOutsideActor = vtkActor() clipperOutsideActor.SetMapper(clipperOutsideMapper) clipperOutsideActor.GetProperty().SetColor( colors.GetColor3d('Banana')) leftViewport = [0.0, 0.0, 0.5, 1.0] leftRenderer = vtkRenderer() leftRenderer.SetViewport(leftViewport) leftRenderer.SetBackground(colors.GetColor3d('SteelBlue')) rightViewport = [0.5, 0.0, 1.0, 1.0] rightRenderer = vtkRenderer() rightRenderer.SetViewport(rightViewport) rightRenderer.SetBackground(colors.GetColor3d('CadetBlue')) # add the actors leftRenderer.AddActor(wireActor) leftRenderer.AddActor(clipperActor) rightRenderer.AddActor(clipperOutsideActor) renwin = vtkRenderWindow() renwin.SetSize(640, 480) renwin.AddRenderer(leftRenderer) renwin.AddRenderer(rightRenderer) renwin.SetWindowName('ClipDataSetWithPolyData') # An interactor interactor = vtkRenderWindowInteractor() interactor.SetRenderWindow(renwin) # Share the camera 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.SetActiveCamera(leftRenderer.GetActiveCamera()) renwin.Render() interactor.Start() if __name__ == '__main__': main()