取决于VTK(python)中的法线方向着色面

时间:2018-03-14 07:28:53

标签: python stl vtk

我想在STLVTK文件中显示一个对象,这不是问题。

然而,我还要突出显示某些面部并使它们与主要对象的颜色不同,具体取决于它们的法线和任意选择的方向之间的阈值角度值,比如z = (0.0, 0.0, 1.0)。比如说,与45 degrees形成小于z-direction角度的所有面都应该用红色着色。

我设法使用trimesh模块执行此操作,但绘制对象需要太多时间。 有没有一种优雅的方法来使用VTK模块执行此操作?

到目前为止,这是我的代码:

import vtk
import numpy as np
from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk

filename = "out.stl"
reader = vtk.vtkSTLReader()
reader.SetFileName(filename)

normals = vtk.vtkPPolyDataNormals()
normals.SetInputConnection(reader.GetOutputPort())
normals.ComputeCellNormalsOn()
normals.ComputePointNormalsOff()
normals.ConsistencyOn()
normals.AutoOrientNormalsOn()
normals.Update()

cellNormals = vtk_to_numpy(normals.GetOutput().GetCellData().GetNormals())

angle = numpy_to_vtk(np.arccos(np.dot(cellNormals, (0.0,0.0,1.0))))
normals.GetOutput().GetCellData().SetScalars(angle)

mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(reader.GetOutputPort())

actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor.GetProperty().SetColor(0, 0, 1)

# Create a rendering window and renderer
renderer = vtk.vtkRenderer()
renderingwindow = vtk.vtkRenderWindow()
renderingwindow.AddRenderer(renderer)

# Create a renderwindowinteractor
renderwindowinteractor = vtk.vtkRenderWindowInteractor()
renderwindowinteractor.SetRenderWindow(renderingwindow)

# Assign actor to the renderer
renderer.AddActor(actor)

# Enable user interface interactor
renderwindowinteractor.Initialize()
renderingwindow.Render()
renderwindowinteractor.Start()

1 个答案:

答案 0 :(得分:0)

我假设您正在使用vtkPolyDataNormals来计算法线 - 请确保您拥有ComputeCellNormalsOn。

接下来,您需要循环法线并根据测试方向计算点积。既然你是Python,我建议在normals数组上使用vtk_to_numpy,并在numpy中进行。

from vtk.util.numpy_support import vtk_to_numpy, numpy_to_vtk
pd = polyDataNormals.GetOutput()
cellNormals = vtk_to_numpy(pd.GetCellData().GetNormals())
angle = numpy_to_vtk(np.arccos(np.dot(cellNormals, testNormal)))
pd.GetCellData().SetScalars(angle)

现在,您可以使用vtkPolyDataMapper的颜色映射功能来完成您的需要。