VTK - Boolean布尔操作

简介:本博文记录vtk关于布尔操作的应用,以及其中的坑,供小伙伴参考。

VTK中包含可以执行布尔操作的接口有vtkImplicitBoolean,vtkBooleanOperationPolyDataFilter,vtkLoopBooleanPolyDataFilter。

布尔操作包括:布尔加,布尔减和布尔交。

1.vtkImplictiBoolean

位置:Filters\DataModel

用途:隐函数,用于布尔运算

用法:

    // create a sphere
    auto sphere =
        vtkSmartPointer::New();
    sphere->SetCenter(1.0, 0.0, 0.0);
    sphere->SetRadius(1);

    //create a box
    auto box =
        vtkSmartPointer::New();
    box->SetBounds(-1, 1, -1, 1, -1, 1);

    // combine the two implicit functions
    auto boolean =
        vtkSmartPointer::New();
    boolean->SetOperationTypeToDifference();
    // boolean->SetOperationTypeToUnion()
    // boolean->SetOperationTypeToIntersection()
    boolean->AddFunction(box);
    boolean->AddFunction(sphere);
    //The sample function generates a distance function from the implicit
    //function.This is then contoured to get a polygonal surface.
    auto sample =
        vtkSmartPointer::New();
    sample->SetImplicitFunction(boolean);
    sample->SetModelBounds(-1, 2, -1, 1, -1, 1);
    sample->SetSampleDimensions(40, 40, 40);
    sample->ComputeNormalsOff();

    // contour
    auto surface =
        vtkSmartPointer::New();
    surface->SetInputConnection(sample->GetOutputPort());
    surface->SetValue(0, 0.0);
    
    //surface->vtkPolyDataMapper->vtkActor

2.vtkBooleanOperationPolyDataFilter

位置:Filters\General

用途:该接口用于计算边界的Union,intersection,difference。

限制:输入的数据可接受non-manifold,但生成的结果可能不是我们想要的。

vtkPolyData的边界包括:
1)边界(boundary),只被一个多边形使用的边,或者直线单元;
2)非流形(non-manifold),被三个以上的多边形共用的边;
3)特征边(feature edges),被两个三角形使用且二面角大于特征角的边;
4)流形边(manifold edges),只被两个多边形使用的边。

检测是不是manifold,可通过vtkFeatureEdges接口进行检测

    //	检测模型是否为Closed
    vtkSmartPointer closedSurface =
		vtkSmartPointer::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;
	}

用法:

vtkBooleanOperationPolyDataFilter* operation = vtkBooleanOperationPolyDataFilter::New();
operation->SetOperationToUnion();

vtkPolyData* polyData1 = ...;

 vtkPolyData* polyData2 = ...;

operation->SetInputData(0, polyData1);
operation->SetInputData(1, polyData2);
operation->Update();

3. vtk中布尔减存在的问题

下图左侧为VTK生成的结果(vtkBooleanOperationPolyDataFilter和vtkLoopBooleanPolyDataFilter均会产生此种情况),右侧为3-matic生成的结果。vtk生成的结果存在BadEdges及BadContour。

VTK - Boolean布尔操作_第1张图片VTK - Boolean布尔操作_第2张图片

究其原因为vtkIntersectionPolyDataFilter的结果有误,如下图所示。

VTK - Boolean布尔操作_第3张图片

更多细节请查看:https://blog.csdn.net/qq_40041064/article/details/129793184

你可能感兴趣的:(VTK,VTK)