前言
此文旨在记录本人在做VTK相关项目开发过程中遇到的问题及摸索出来的解决方案。欢迎大家指正讨论。
在实际生活中,由于我们往往只能获得待建模物体的表面数据而无法获得其内部数据,这就导致我们在建模过程中由于缺少内部数据,建立的模型都是一个徒有外壳的空腔,而并非实体模型。此文章就是为了解决这个问题。目标是通过地表的高程点构建一个实体的可切割的三维地质模型。
一、读取三维高程点建面
这一块很多博客都有介绍,再次不多做介绍,直接贴代码上图。
代码如下:
while (std::getline(filestream, line))
{
double x, y, z;
std::stringstream linestream;
linestream << line;
linestream >> x >> y >> z;
points->InsertNextPoint(x, y, z);
}
filestream.close();
vtkSmartPointer<vtkPolyData> polyData =
vtkSmartPointer<vtkPolyData>::New();
polyData->SetPoints(points);
/*
vtkSmartPointer<vtkTriangleFilter> triangle1 =
vtkSmartPointer<vtkTriangleFilter>::New();
triangle1->SetInputData(polyData);
triangle1->Update();
*/
vtkSmartPointer<vtkDelaunay2D> delaunay =
vtkSmartPointer<vtkDelaunay2D>::New();
delaunay->SetInputData(polyData);
delaunay->Update();
结果如下图所示
二、构建侧面
1.获取边界点集
通过VTK提供的vtkFeatureEdges类获取刚刚构建模型的边界,我们通过cleanpolydata的输出可以获得边界点集逆时针排序的输出序列。代码如下:
vtkSmartPointer<vtkFeatureEdges> featureEdges =
vtkSmartPointer<vtkFeatureEdges>::New();
featureEdges->SetInputConnection(delaunay->GetOutputPort());
featureEdges->BoundaryEdgesOn();
featureEdges->FeatureEdgesOff();
featureEdges->ManifoldEdgesOff();
featureEdges->NonManifoldEdgesOff();
featureEdges->Update();
结果如下图所示(此时点都是单独存在)
2.处理边界点集
有了边界点集的顺序输出,我们接下来就是希望能通过这些点依次连接,构造出几个能和地表模型完全重合的侧面。经查,vtk中可以通过polygon类依次连接点,还可通过cell类将封闭曲线建立成面。例如,我们将上述所获点通过polygon依次连接获得图形如下图所示:
代码如下
vtkSmartPointer<vtkPolyData> addDEMItem(vtkPoints *points)
{
vtkSmartPointer<vtkPolygon> polygon =
vtkSmartPointer < vtkPolygon > ::New();
polygon->GetPointIds()->SetNumberOfIds(points->GetNumberOfPoints());
for (int i = 0; i < points->GetNumberOfPoints(); i++)
{
polygon->GetPointIds()->SetId(i, i);
}
vtkSmartPointer<vtkCellArray> polygons =
vtkSmartPointer<vtkCellArray>::New();
polygons->InsertNextCell(polygon);
vtkSmartPointer<vtkPolyData> polygonPolyData =
vtkSmartPointer<vtkPolyData>::New();
polygonPolyData->SetPoints(points);
polygonPolyData->SetPolys(polygons);
return polygonPolyData;
}
3.构建面
建立面的操作在此节中比较简单,因为需要构建的立体模型的底面是由4个点确定的,我们只需根据这四个点的位置将之前获得的边界点分为4份,每份边界点和底部的两个点逆时针依次连接就可以获得侧面。最后通过appendPolydata将六个面拼起来便获得我们的最终模型。如下图所示:
平面切割后可以看到该模型为实体模型。