5.vtk学习——点云显示进阶
三角化模型显示实现
承接上文,这里介绍如何实现点云三角化后的显示效果。

如果理解了前文内容,这里的思路就非常自然:三角化会把点相连形成三角面,这些三角面正是我们需要显示的拓扑结构。
我们只需从 Halcon 获取三角化后的三角形数据,并添加到 VTK 中作为拓扑结构,即可显示模型。
实现过程
1. 点云预处理与三角化
首先,读取点云数据,生成 3D 模型,然后进行滤波、采样和三角化。
// 读取点云坐标
HOperatorSet.ReadTuple(@"C:\Users\Yty\Desktop\xpoints.dat", out var X);
HOperatorSet.ReadTuple(@"C:\Users\Yty\Desktop\ypoints.dat", out var Y);
HOperatorSet.ReadTuple(@"C:\Users\Yty\Desktop\zpoints.dat", out var Z);
// 生成3D对象
HOperatorSet.GenObjectModel3dFromPoints(X, Y, Z, out var WareModel3D);
// 采样
double SamplingFactor = 0.01;
HOperatorSet.GetObjectModel3dParams(WareModel3D, "diameter_axis_aligned_bounding_box", out var Diameter);
HOperatorSet.SampleObjectModel3d(WareModel3D, "fast", SamplingFactor * Diameter, new HTuple(), new HTuple(), out var SampledWareModel3D);
// 计算法向量
HOperatorSet.SurfaceNormalsObjectModel3d(SampledWareModel3D, "mls", new HTuple(), new HTuple(), out SampledWareModel3D);
// 三角化
HOperatorSet.TriangulateObjectModel3d(SampledWareModel3D, "greedy", new HTuple(), new HTuple(), out var TriangulatedObjectModel3D, out var Information);
// 获取三角形和点坐标
HOperatorSet.GetObjectModel3dParams(TriangulatedObjectModel3D, "triangles", out var tris);
HOperatorSet.GetObjectModel3dParams(TriangulatedObjectModel3D, "point_coord_x", out var hv_x);
HOperatorSet.GetObjectModel3dParams(TriangulatedObjectModel3D, "point_coord_y", out var hv_y);
HOperatorSet.GetObjectModel3dParams(TriangulatedObjectModel3D, "point_coord_z", out var hv_z);
HOperatorSet.GetObjectModel3dParams(TriangulatedObjectModel3D, "num_points", out var hv_num);
HOperatorSet.GetObjectModel3dParams(TriangulatedObjectModel3D, "num_triangles", out var numTris);
说明:每 3 个
tris元素表示一个三角形的三个顶点索引,例如[0,10,11]表示三角形由索引 0、10、11 的点组成。
2. 添加拓扑结构到 VTK
根据 Halcon 的三角化数据,创建 vtkTriangle 并插入 vtkCellArray,然后构建 vtkPolyData。
vtkCellArray vtkCell = new vtkCellArray();
for (int i = 0; i < numTris; i++)
{
vtkTriangle tri = new vtkTriangle();
tri.GetPointIds().SetNumberOfIds(3);
tri.GetPointIds().SetId(0, tris[i * 3]);
tri.GetPointIds().SetId(1, tris[i * 3 + 1]);
tri.GetPointIds().SetId(2, tris[i * 3 + 2]);
vtkCell.InsertNextCell(tri);
}
// 构建 PolyData
vtkPolyData Model3D = new vtkPolyData();
vtkPolyData PointData = new vtkPolyData();
Model3D.SetPoints(Points);
Model3D.GetPointData().SetScalars(colors_rgb);
Model3D.SetPolys(vtkCell);
PointData.SetPoints(Points);
3. 可视化显示
使用 vtkPolyDataMapper 和 vtkActor 显示三角化模型和点云。
vtkPolyDataMapper Model3DMapper = vtkPolyDataMapper.New();
vtkPolyDataMapper PointsMapper = vtkPolyDataMapper.New();
vtkVertexGlyphFilter glyphFilter = vtkVertexGlyphFilter.New();
glyphFilter.SetInput(PointData); // 使用 SetInput
Model3DMapper.SetInput(Model3D);
PointsMapper.SetInput(glyphFilter.GetOutput());
vtkActor ModelActor = vtkActor.New();
vtkActor PointActor = vtkActor.New();
ModelActor.SetMapper(Model3DMapper);
PointActor.SetMapper(PointsMapper);
// 设置透明度
ModelActor.GetProperty().SetOpacity(0.5);
vtkRenderer renderer = vtkRenderer.New();
renderer.AddActor(PointActor);
renderer.AddActor(ModelActor);
// 背景设置
renderer.SetBackground(0, 0, 0);
renderer.GradientBackgroundOn();
renderer.SetBackground2(0.8, 0.8, 0.8);
// 深度剥离设置,保证半透明正确显示
renderer.SetUseDepthPeeling(1);
renderer.SetMaximumNumberOfPeels(300);
renderer.SetOcclusionRatio(0.1);
ResetCamera(Model3D);
// 渲染窗口
renderWindow.AddRenderer(renderer);
renderWindow.SetAlphaBitPlanes(1);
renderWindow.Render();
VtkPanel.Invalidate();
Application.DoEvents();
// 强制刷新三部曲
renderWindow.Render();
VtkPanel.Invalidate(true);
Application.DoEvents();
4. 透明显示效果说明
- 直接设置
ModelActor.GetProperty().SetOpacity(0.5)可以实现透明显示,但可能出现透视错乱。 - 原因:VTK 默认使用画家算法渲染半透明面,当多个半透明面重叠时顺序判断不准确。
- 解决方法:开启 深度剥离 (Depth Peeling) 渲染模式。
深度剥离设置
renderer.SetUseDepthPeeling(1); // 开启深度剥离
renderer.SetMaximumNumberOfPeels(300); // 最大剥离层数
renderer.SetOcclusionRatio(0.1); // 每层遮挡比例
renderWindow.SetAlphaBitPlanes(1); // 支持 Alpha 通道
渲染流程:
- 渲染场景的第一层透明面(最前面)。
- “剥掉”该层深度信息。
- 渲染下一层透明面,重复上述步骤。
- 将所有层按深度从前到后混合,获得正确的透明显示效果。

浙公网安备 33010602011771号