欢迎加入我的VTK社区 雪易VTK社区-CSDN社区云
前言:本文主要分三部分,第一部分对3-matic中的Remesh功能进行展示;第二部分对Remesh的概念、方法论,以及CGAL库下的实现方法进行介绍;第三部分对Mesh的质量进行评价。如果我的分享对你有帮助,记得点赞+关注,鼓励我以下吧!
3-matic中的Remesh
Adaptive Remesh允许在保留实体几何形状的同时对其进行Remesh。与Uniform Remesh相比,该工具对生成的网格提供了更精细的控制,甚至可以将网格限制在一个感兴趣的小区域。
Remesh
Remesh即对输入的网格进行一些算法处理后生成另一个网格,进而满足需求。
Remesh一般划分为:
网格的几何信息不变(即输入点集不变),优化拓扑结构。
网格的几何信息和拓扑结构同时改变,但几何信息在原有的基础上进行删减或插入。
网格的几何信息和拓扑结构同时改变,几何信息通过重采样获取。
Remesh实现算法主要分为两种:Delaunay(德劳内)三角化 和 Voronoi(泰森多边形)。
Delaunay(德劳内)三角化
带约束的Delaunay三角化
有时候,点云包含一些线段连接约束,如下左图所示。有些约束边并不满足Denaulay性质,所以,它并不能得到整体的Delaunay三角化结果(如下中图是点云的一个Delaunay三角化结果)。我们可以放开一些Delaunay性质约束,使其尽量的接近Delaunay三角化。下右图是一个带约束的Denaulay三角化的结果。可以比较一下中图和右图的结果差异。
Delaunay网格优化
Delaunay优化,可以优化网格的连接关系,减少狭长三角形,保持网格顶点数目和位置不变。如下图所示,图2和图3是图1点云不同的三角化结果。图2经过一系列拓扑优化,如Delaunay边翻转操作,得到图3的高质量网格。Delaunay优化只改变了网格顶点的连接关系,一般是局部的Delaunay边翻转。由于顶点保持不变,它可以极大可能的保持住原始网格的几何信息。缺点是,在顶点分布很差的情况下,优化的效果有限。
Voronoi三角化-重心Voronoi优化
重心Voronoi优化,可以减少狭长三角形。它和Delaunay优化的区别是,它不仅优化网格顶点的连接关系,还要优化顶点的位置。如下图1所示,虽然这是一个Delaunay三角化,但明显可以看出其网格质量很很差的,经过一系列几何优化(如重心Voronoi优化)后,顶点分布更加均匀,然后再做一个Delaunay三角化就得到了图2的结果。重心Voronoi优化,虽然可以优化顶点分布,但其优化程度有限,在顶点分布极不均匀的情况下,效果还是不理想的。
CGAL下的Remeshing
应用实例:
上述分别为uniform remesh 和 adaptive remesh的结果。
VTK+CGAL实现stl数据的Remeshing,可以私信我哟!
网格质量
网格质量是影响模型好坏的重要因素,vtk中提供了两种质量相关接口vtkCellQuality/vtkMeshQuality。
vtkMeshQuality
描述:
vtkMeshQuality为网格的每个2-D和3-D单元(三角形、四边形、四面体或六面体)计算一个或多个(几何)质量函数。然后在整个网格上平均这些质量函数。每种类型单元格的最小值、平均值、最大值和无偏方差都存储在输出网格的FieldData中。FieldData数组被命名为“网格三角形质量”、“网格四边形质量”、“网格四面体质量”和“网格六面体质量”。每个数组都有一个包含5个组件的元组。前4个组成部分是上面提到的质量统计;最后的值是给定类型的单元格数。最后一个组件使分布式网格数据的统计信息聚合成为可能。
默认情况下,每个单元格的质量被添加到网格的单元格数据中,在一个名为“quality”的数组中。此筛选器不支持的单元格类型的条目为0。使用SaveCellQualityOff()只存储最终的统计数据。
示例
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->Update();
vtkSmartPointer<vtkTriangleFilter> triangleFilter =
vtkSmartPointer<vtkTriangleFilter>::New();
triangleFilter->SetInputConnection(sphereSource->GetOutputPort());
triangleFilter->Update();
vtkPolyData* mesh = triangleFilter->GetOutput();
std::cout << "There are " << mesh->GetNumberOfCells() << " cells." << std::endl;
vtkSmartPointer<vtkMeshQuality> qualityFilter =
vtkSmartPointer<vtkMeshQuality>::New();
qualityFilter->SetInputData(mesh);
qualityFilter->SetTriangleQualityMeasureToArea();
qualityFilter->Update();
vtkSmartPointer<vtkDoubleArray> qualityArray =
dynamic_cast<vtkDoubleArray*>(qualityFilter->GetOutput()->GetCellData()->GetArray("Quality"));
std::cout << "There are " << qualityArray->GetNumberOfTuples() << " values." << std::endl;
for(vtkIdType i = 0; i < qualityArray->GetNumberOfTuples(); i++)
{
double val = qualityArray->GetValue(i);
std::cout << "value " << i << " : " << val << std::endl;
}
vtkSmartPointer<vtkPolyData> polydata =
vtkSmartPointer<vtkPolyData>::New();
polydata->ShallowCopy(qualityFilter->GetOutput());
vtkCellQuality
描述:
vtkCellQuality为网格的每个单元计算一个或多个(几何)质量函数。每个单元格的质量被添加到网格的单元格数据中,在一个名为“CellQuality”的数组中。此过滤器不支持的单元格类型或支持的单元格类型的未定义质量将具有-1的条目。
参考:
如果我的分享对你有帮助,记得点赞+关注,鼓励我以下吧!