网格封闭性检测 见:
vtk Edges 特征边 提取 网格封闭性检测_vtkfeatureedges-CSDN博客
由于以前做过3D打印模型,要求模型必须是封闭的,原来对模型封闭有研究过,不过没有记录;现在又遇到,整理一下;
1.vtkStripper ,vtkFillHolesFilter
closeSurface 大家首先想到的是 vtkFillHolesFilter
但不一定,由时一个模型是有多个模型组合的,没有连接性,所以首先可以使用:
vtkStripper
见:vtkStripper vtkTriangleFilter-CSDN博客
将多个模型变成一个;
然后使用 vtkFillHolesFilter
vtkNew<vtkFillHolesFilter> fillHolesFilter;
fillHolesFilter->SetInputData(polydata);
fillHolesFilter->SetHoleSize(10.0);
fillHolesFilter->Update();
2.使用 vtkFillHolesFilter 后,仍然不是闭合
2.1孔洞阈值过小vtkFillHolesFilter
有一个属性叫做 HoleSize
,表示可以填充的最大孔洞的大小(基于孔洞的边界周长)。
- 解决方法:尝试增大
HoleSize
,以确保较大的孔洞也能被填充
vtkNew<vtkFillHolesFilter> fillHolesFilter;
fillHolesFilter->SetInputData(polydata);
fillHolesFilter->SetHoleSize(10.0);
fillHolesFilter->Update();
2.2 几何结构缺陷
原始的 vtkPolyData
可能存在几何缺陷,比如:
- 非流形边 (Non-manifold edges)
- 重叠点 (Duplicate points)
- 法线方向不一致
这些问题可能会导致孔洞无法被正确识别和填充。
- 解决方法:
- 使用
vtkCleanPolyData
清理数据,合并重复点并修复拓扑结构。 - 使用
vtkPolyDataNormals
确保法线方向一致。
- 使用
# 清理PolyData
cleanFilter = vtk.vtkCleanPolyData()
cleanFilter.SetInputData(polydata)
cleanFilter.Update()
# 重新计算法线
normals = vtk.vtkPolyDataNormals()
normals.SetInputData(cleanFilter.GetOutput())
normals.ConsistencyOn() # 确保法线方向一致
normals.AutoOrientNormalsOn()
normals.Update()
# 填充孔洞
fillHolesFilter = vtk.vtkFillHolesFilter()
fillHolesFilter.SetInputData(normals.GetOutput())
fillHolesFilter.SetHoleSize(1000.0) # 根据情况调整阈值
fillHolesFilter.Update()
2.2 数据孔洞不是封闭边界
如果数据存在不完整的边界或破洞,vtkFillHolesFilter
无法正确填充,因为它只能识别封闭环状的孔洞。
- 解决方法:
- 使用
vtkDelaunay3D
生成一个闭合的网格。
- 使用
delaunay = vtk.vtkDelaunay3D()
delaunay.SetInputData(polydata)
delaunay.Update()
surfaceFilter = vtk.vtkDataSetSurfaceFilter()
surfaceFilter.SetInputConnection(delaunay.GetOutputPort())
surfaceFilter.Update()
closedPolyData = surfaceFilter.GetOutput()
使用前,有边界;
使用后,无边界:
不过这个真不是用眼睛能看出来的;需要用算法检测;使用;