在python中使用VTK查找具有负平均曲率的.stl文件的单元格
我有一个在python中使用VTK查找具有负平均曲率的.stl文件的单元格,python,opengl,mesh,vtk,Python,Opengl,Mesh,Vtk,我有一个.stl文件,我正在尝试使用VTK和python查找具有负平均曲率的单元的坐标。我已经编写了这些代码,这些代码可以根据平均曲率更改单元格的颜色,但我愿意实现的是具有特定平均曲率的精确单元格和三角形的坐标,例如,具有最负平均曲率的单元格的三维坐标。 代码如下: import vtk def gaussian_curve(fileNameSTL): colors = vtk.vtkNamedColors() reader = vtk.vtkSTLReader()
.stl
文件,我正在尝试使用VTK和python查找具有负平均曲率的单元的坐标。我已经编写了这些代码,这些代码可以根据平均曲率更改单元格的颜色,但我愿意实现的是具有特定平均曲率的精确单元格和三角形的坐标,例如,具有最负平均曲率的单元格的三维坐标。
代码如下:
import vtk
def gaussian_curve(fileNameSTL):
colors = vtk.vtkNamedColors()
reader = vtk.vtkSTLReader()
reader.SetFileName(fileNameSTL)
reader.Update()
curveGauss = vtk.vtkCurvatures()
curveGauss.SetInputConnection(reader.GetOutputPort())
curveGauss.SetCurvatureTypeToGaussian() # SetCurvatureTypeToMean() works better in the case of kidney.
ctf = vtk.vtkColorTransferFunction()
ctf.SetColorSpaceToDiverging()
p1 = [0.0] + list(colors.GetColor3d("MidnightBlue"))
p2 = [1.0] + list(colors.GetColor3d("DarkRed"))
ctf.AddRGBPoint(*p1)
ctf.AddRGBPoint(*p2)
cc = list()
for i in range(256):
cc.append(ctf.GetColor(float(i) / 255.0))
lut = vtk.vtkLookupTable()
lut.SetNumberOfColors(256)
for i, item in enumerate(cc):
lut.SetTableValue(i, item[0], item[1], item[2], 1.0)
lut.SetRange(0, 0) # In the case of kidney, the (0, 0) worked better.
lut.Build()
cmapper = vtk.vtkPolyDataMapper()
cmapper.SetInputConnection(curveGauss.GetOutputPort())
cmapper.SetLookupTable(lut)
cmapper.SetUseLookupTableScalarRange(1)
cActor = vtk.vtkActor()
cActor.SetMapper(cmapper)
return cActor
def render_scene(my_actor_list):
renderer = vtk.vtkRenderer()
for arg in my_actor_list:
renderer.AddActor(arg)
namedColors = vtk.vtkNamedColors()
renderer.SetBackground(namedColors.GetColor3d("SlateGray"))
window = vtk.vtkRenderWindow()
window.SetWindowName("Render Window")
window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)
# Visualize
window.Render()
interactor.Start()
if __name__ == '__main__':
fileName = "400_tri.stl"
my_list = list()
my_list.append(gaussian_curve(fileName))
render_scene(my_list)
此代码生成红细胞表示正平均曲率,蓝色表示负平均曲率
我需要数组或类似的形式的结果(单元格坐标)。
如果您能就此问题提供任何建议和帮助,我将不胜感激。可能的解决方案包括:
从vtkplotter导入*
圆环1=圆环().addCurvatureScalars().addScalarBar()
打印(“标量列表:”,torus1.scalars())
torus2=torus1.clone().addScalarBar()
圆环2.阈值(“高斯曲率”,vmin=-15,vmax=0)
显示(圆环1,圆环2,N=2)#在两个单独的渲染器上打印
打印(“顶点坐标:”,len(torus2.coordinates())
打印(“单元格中心:”,len(torus2.cellCenters())
附加示例
希望这能有所帮助。因此我从中找到了答案,下面是使用
vtk.numpy\u接口
和vtk.util.numpy\u支持
可以正常工作的代码,但它仍然不能生成normals\u数组
,我不知道为什么
import vtk
from vtk.numpy_interface import dataset_adapter as dsa
from vtk.util.numpy_support import vtk_to_numpy
def curvature_to_numpy(fileNameSTL, curve_type='Mean'):
colors = vtk.vtkNamedColors()
reader = vtk.vtkSTLReader()
reader.SetFileName(fileNameSTL)
reader.Update()
# Defining the curvature type.
curve = vtk.vtkCurvatures()
curve.SetInputConnection(reader.GetOutputPort())
if curve_type == "Mean":
curve.SetCurvatureTypeToMean()
else:
curve.SetCurvatureTypeToGaussian()
curve.Update()
# Applying color lookup table.
ctf = vtk.vtkColorTransferFunction()
ctf.SetColorSpaceToDiverging()
p1 = [0.0] + list(colors.GetColor3d("MidnightBlue"))
p2 = [1.0] + list(colors.GetColor3d("DarkOrange"))
ctf.AddRGBPoint(*p1)
ctf.AddRGBPoint(*p2)
cc = list()
for i in range(256):
cc.append(ctf.GetColor(float(i) / 255.0))
lut = vtk.vtkLookupTable()
lut.SetNumberOfColors(256)
for i, item in enumerate(cc):
lut.SetTableValue(i, item[0], item[1], item[2], 1.0)
lut.SetRange(0, 0) # In the case of kidney, the (0, 0) worked better.
lut.Build()
# Creating Mappers and Actors.
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(curve.GetOutputPort())
mapper.SetLookupTable(lut)
mapper.SetUseLookupTableScalarRange(1)
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# Scalar values to numpy array. (Curvature).
dataObject = dsa.WrapDataObject(curve.GetOutput())
normals_array = dataObject.PointData['Normals'] # Output array.
curvature_array = dataObject.PointData['Mean_Curvature'] # output array.
# Node values to numpy array.
nodes = curve.GetOutput().GetPoints().GetData()
nodes_array = vtk_to_numpy(nodes)
# Creating a report file (.vtk file).
writer = vtk.vtkPolyDataWriter()
writer.SetFileName('vtk_file_generic.vtk')
writer.SetInputConnection(curve.GetOutputPort())
writer.Write()
# EDIT:
# Creating the point normal array using vtkPolyDataNormals().
normals = vtk.vtkPolyDataNormals()
normals.SetInputConnection(reader.GetOutputPort()) # Here "curve" could be replaced by "reader".
normals.ComputePointNormalsOn()
normals.SplittingOff()
normals.Update()
dataNormals = dsa.WrapDataObject(normals.GetOutput())
normals_array = dataNormals.PointData["Normals"]
return actor, normals_array, curvature_array, nodes_array
def render_scene(my_actor_list):
renderer = vtk.vtkRenderer()
for arg in my_actor_list:
renderer.AddActor(arg)
namedColors = vtk.vtkNamedColors()
renderer.SetBackground(namedColors.GetColor3d("SlateGray"))
window = vtk.vtkRenderWindow()
window.SetWindowName("Render Window")
window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)
# Visualize
window.Render()
interactor.Start()
if __name__ == '__main__':
filename = "400_tri.stl"
my_list = list()
my_actor, my_normals, my_curve, my_nodes = curvature_to_numpy(filename, curve_type="Mean")
my_list.append(my_actor)
render_scene(my_list) # Visualization.
print(my_nodes) # Data points.
print(my_normals) # Normal vectors.
print(my_curve) # Mean curvatures.
谢谢你的建议,但我只想坚持vtk图书馆。另外,我将添加一个答案。你是WOLWGO,认为VTKPLTTER不是一个新的/独立的软件,但它是VTK的辅助模块。例如,上例中的
torus2
是一个vtkActor
对象(具有扩展功能)。可以检查您是否在polydata中获得一个普通数组。polydata=curves.GetOutput()normals=polydata.GetPointData().GetNormals()打印(法线)我编辑了代码并添加了法线数组的计算。我使用法线。ComputePointNormalsOn()
计算每个顶点的法向量,我不知道它是对还是错?