补洞
在VTK中,利用vtkFillHolesFilter进行补洞。其内部执行过程是首先检测出网格中的所有边界边,然后找出这些边界边中的每个孔洞,最后利用vtkPolygon::NonDegenerateTriangulate将每个孔洞进行三角化(即生成三角网格)。需要注意的是,有些边界的孔洞是不需要三角化的,例如一个平面网格,若填补其四周的边界变,则会与原网格产生覆盖。vtkFillHolesFilter的SetHoleSize函数用来控制需要修补洞的最大面积,大于该值则不需要修补该洞。
示例演示
我们利用vtkFillHolesFilter对bunny进行补洞,看看效果。
/**********************************************************************
Copyright (c) Mr.Bin. All rights reserved.
For more information visit: http://blog.csdn.net/webzhuce
**********************************************************************/
#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkFeatureEdges.h>
#include <vtkFillHolesFilter.h>
#include <vtkPLYReader.h>
int main(int argc, char *argv[])
{
vtkNew<vtkPLYReader> reader;
reader->SetFileName("E:/github/Study-VTK/data/bunny.ply");
reader->Update();
vtkNew<vtkFeatureEdges> featureedges;
featureedges->SetInputData(reader->GetOutput());
featureedges->BoundaryEdgesOn();
featureedges->FeatureEdgesOff();
featureedges->ManifoldEdgesOff();
featureedges->NonManifoldEdgesOff();
featureedges->Update();
int numberofopenedges = featureedges->GetOutput()->GetNumberOfCells();
if(numberofopenedges)
std::cout<<"该网格模型不是封闭的..."<<std::endl;
else {
std::cout<<"该网格模型是封闭的..."<<std::endl;
return EXIT_SUCCESS;
}
vtkNew<vtkFillHolesFilter> fillholesfilter;
fillholesfilter->SetInputData(reader->GetOutput());
fillholesfilter->Update();
//
double leftviewport[4] = {0.0, 0.0, 0.5, 1.0};
double rightviewport[4] = {0.5, 0.0, 1.0, 1.0};
vtkNew<vtkPolyDataMapper> originalmapper;
originalmapper->SetInputData(reader->GetOutput());
vtkNew<vtkActor> originalactor;
originalactor->SetMapper(originalmapper);
vtkNew<vtkPolyDataMapper> filledmapper;
filledmapper->SetInputData(fillholesfilter->GetOutput());
vtkNew<vtkActor> filledactor;
filledactor->SetMapper(filledmapper);
filledactor->GetProperty()->SetRepresentationToWireframe();
filledactor->GetProperty()->SetColor(1.0, 0.0, 0.0);
vtkNew<vtkRenderer> leftrenderer;
leftrenderer->SetViewport(leftviewport);
leftrenderer->AddActor(originalactor);
leftrenderer->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderer> rightrenderer;
rightrenderer->SetViewport(rightviewport);
rightrenderer->AddActor(filledactor);
rightrenderer->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderWindow> renderwindow;
renderwindow->AddRenderer(leftrenderer);
renderwindow->AddRenderer(rightrenderer);
renderwindow->SetSize(640, 320);
renderwindow->Render();
renderwindow->SetWindowName("FillHoles");
vtkNew<vtkRenderWindowInteractor> renderwindowinteractor;
renderwindowinteractor->SetRenderWindow(renderwindow);
renderwindow->Render();
renderwindowinteractor->Start();
return EXIT_SUCCESS;
}
运行结果
从结果来看,修补的区域三角形单元明显比原始网格数据的大,同时也不光滑。所以真实应用,该类作用不大。
参考资料
- VTK图形图像开发进阶[M]