如何在vtk中仅显示纹理表面的三角形边界?

3 投票
1 回答
4042 浏览
提问于 2025-04-17 03:04

我想显示一个有纹理的表面,并且希望三角形的边界能用不同的颜色(比如红色)显示出来。我在vtk的代码示例中找到了以下代码,但它并没有显示三角形的边界,而是填充了整个三角形。

   import vtk

   # create a rendering window and renderer
   ren = vtk.vtkRenderer()
   renWin = vtk.vtkRenderWindow()
   renWin.AddRenderer(ren)

   # create a renderwindowinteractor
   iren = vtk.vtkRenderWindowInteractor()
   iren.SetRenderWindow(renWin)

   # create points
   points = vtk.vtkPoints()
   points.InsertNextPoint(1.0,0.0,0.0)
   points.InsertNextPoint(0.0,0.0,0.0)
   points.InsertNextPoint(0.0,1.0,0.0)

   triangle = vtk.vtkTriangle()
   triangle.GetPointIds().SetId(0,0)
   triangle.GetPointIds().SetId(1,1)
   triangle.GetPointIds().SetId(2,2)

   triangles = vtk.vtkCellArray()
   triangles.InsertNextCell(triangle)

   # polydata object
   trianglePolyData = vtk.vtkPolyData()
   trianglePolyData.SetPoints( points )
   trianglePolyData.SetPolys( triangles )

   # mapper
   mapper = vtk.vtkPolyDataMapper()
   mapper.SetInput(trianglePolyData)

   # actor
   actor = vtk.vtkActor()
   actor.SetMapper(mapper)

   # assign actor to the renderer
   ren.AddActor(actor)

   # enable user interface interactor
   iren.Initialize()
   renWin.Render()
   iren.Start()

有没有人能告诉我怎么只显示三角形的边界,并且用特定的颜色呢?

我其实想在一个有纹理的表面上显示三角形。我的数据是由三角形组成的。也有可能我给vtk的三角形顶点能被显示出来。

我是在用python编程。

非常感谢!

1 个回答

4

你需要从你的 vtkPolyData 对象中提取边缘:

edges = vtk.vtkExtractEdges()
edges.SetInput(trianglePolyData)
edge_mapper = vtk.vtkPolyDataMapper()
edge_mapper.SetInput(edges.GetOutput())

edge_actor = vtk.vtkActor()
edge_actor.SetMapper(edge_mapper)
edge_actor.GetProperty().SetColor(1,0,0)

ren.AddActor(edge_actor)

vtk.vtkPolyDataMapper().SetResolveCoincidentTopologyToPolygonOffset()

首先,你得通过一个叫 vtkExtractEdges 的过滤器来提取边缘。然后把这个过滤器的结果映射到一个 vtkPolyData 对象上,并为这些数据构建一个演员(actor)。接着,我们直接修改这个演员的属性,把网格的颜色设置为红色。

调用 vtk.vtkPolyDataMapper().SetResolveCoincidentTopologyToPolygonOffset() 这个方法,可以防止边缘和表面发生冲突(因为这两个几何对象重叠在一起,可能会因为深度缓冲的精度问题而互相“穿透”)。

为了完整起见,这里是整个代码:

import vtk

# create a rendering window and renderer
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)

# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# create points
points = vtk.vtkPoints()
points.InsertNextPoint(1.0,0.0,0.0)
points.InsertNextPoint(0.0,0.0,0.0)
points.InsertNextPoint(0.0,1.0,0.0)

triangle = vtk.vtkTriangle()
triangle.GetPointIds().SetId(0,0)
triangle.GetPointIds().SetId(1,1)
triangle.GetPointIds().SetId(2,2)

triangles = vtk.vtkCellArray()
triangles.InsertNextCell(triangle)

# polydata object
trianglePolyData = vtk.vtkPolyData()
trianglePolyData.SetPoints( points )
trianglePolyData.SetPolys( triangles )

# mapper
mapper = vtk.vtkPolyDataMapper()
mapper.SetInput(trianglePolyData)

# actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)

# assign actor to the renderer
ren.AddActor(actor)

#++++++++++++++++++++++++++++++++++++++++++++++++
# Get the edges from the mesh
edges = vtk.vtkExtractEdges()
edges.SetInput(trianglePolyData)
edge_mapper = vtk.vtkPolyDataMapper()
edge_mapper.SetInput(edges.GetOutput())

# Make an actor for those edges    
edge_actor = vtk.vtkActor()
edge_actor.SetMapper(edge_mapper)

# Make the actor red (there are other ways of doing this also)
edge_actor.GetProperty().SetColor(1,0,0)

ren.AddActor(edge_actor)

# Avoid z-buffer fighting
vtk.vtkPolyDataMapper().SetResolveCoincidentTopologyToPolygonOffset()
#------------------------------------------------

# enable user interface interactor
iren.Initialize()
renWin.Render()
iren.Start()

撰写回答