vtkFeatureEdges,VTK的一个类,用于边界提取。
提取的边界包括:
1)边界(boundary),只被一个多边形使用的边,或者直线单元;
2)非流行(non-manifold),被三个以上的多边形共用的边;
3)特征边(feature edges),被两个三角形使用且二面角大于特征角的边;
4)流行边(manifold edges),只被两个多边形使用的边。
常用于
1)提取模型的边界
vtkSmartPointer<vtkFeatureEdges> boundaryEdges =
vtkSmartPointer<vtkFeatureEdges>::New();
boundaryEdges->SetInputConnection(diskSource->GetOutputPort());
boundaryEdges->BoundaryEdgesOn();
boundaryEdges->FeatureEdgesOff();
boundaryEdges->ManifoldEdgesOff();
boundaryEdges->NonManifoldEdgesOff();
boundaryEdges->Update();
注意:提取出来的边界点是无序的,可以用vtkCleanPolyData使其变得有序:
vtkSmartPointer<vtkStripper> stripper =
vtkSmartPointer<vtkStripper>::New();
stripper->SetInputConnection(featureEdges->GetOutputPort());
stripper->JoinContiguousSegmentsOn();
vtkSmartPointer<vtkCleanPolyData> cleanPolyData =
vtkSmartPointer<vtkCleanPolyData>::New();
cleanPolyData->SetInputConnection(stripper->GetOutputPort());
cleanPolyData->Update();
2)检测模型是否闭合
vtkSmartPointer<vtkFeatureEdges> closedSurface =
vtkSmartPointer<vtkFeatureEdges>::New();
closedSurface->SetInputConnection(diskSource->GetOutputPort());
closedSurface->FeatureEdgesOff();
closedSurface->BoundaryEdgesOn();
closedSurface->NonManifoldEdgesOn();
closedSurface->Update();
int numberOfOpenEdges = closedSurface->GetOutput()->GetNumberOfCells();
if (numberOfOpenEdges > 0)
{
std::cout << "Surface is not closed" << std::endl;
}
else
{
std::cout << "Surface is closed" << std::endl;
}
完整代码
#include <vtkSmartPointer.h>
#include <vtkFeatureEdges.h>
#include <vtkPolyData.h>
#include <vtkDiskSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
int main(int, char *[])
{
vtkSmartPointer<vtkDiskSource> diskSource =
vtkSmartPointer<vtkDiskSource>::New();
diskSource->Update();
vtkSmartPointer<vtkFeatureEdges> boundaryEdges =
vtkSmartPointer<vtkFeatureEdges>::New();
boundaryEdges->SetInputConnection(diskSource->GetOutputPort());
boundaryEdges->BoundaryEdgesOn();
boundaryEdges->FeatureEdgesOff();
boundaryEdges->ManifoldEdgesOff();
boundaryEdges->NonManifoldEdgesOff();
boundaryEdges->Update();
vtkSmartPointer<vtkFeatureEdges> closedSurface =
vtkSmartPointer<vtkFeatureEdges>::New();
closedSurface->SetInputConnection(diskSource->GetOutputPort());
closedSurface->FeatureEdgesOff();
closedSurface->BoundaryEdgesOn();
closedSurface->NonManifoldEdgesOn();
closedSurface->Update();
int numberOfOpenEdges = closedSurface->GetOutput()->GetNumberOfCells();
if (numberOfOpenEdges > 0)
{
std::cout << "Surface is not closed" << std::endl;
}
else
{
std::cout << "Surface is closed" << std::endl;
}
// Visualize
vtkSmartPointer<vtkPolyDataMapper> edgeMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
edgeMapper->SetInputConnection(boundaryEdges->GetOutputPort());
vtkSmartPointer<vtkActor> edgeActor =
vtkSmartPointer<vtkActor>::New();
edgeActor->SetMapper(edgeMapper);
vtkSmartPointer<vtkPolyDataMapper> diskMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
diskMapper->SetInputConnection(diskSource->GetOutputPort());
vtkSmartPointer<vtkActor> diskActor =
vtkSmartPointer<vtkActor>::New();
diskActor->SetMapper(diskMapper);
// Create a renderer, render window, and interactor
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(400, 400);
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(edgeActor);
renderer->AddActor(diskActor);
renderer->SetBackground(.3, .6, .3); // Background color green
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}