VTK笔记-图形相关-布尔运算-vtkBooleanOperationPolyDataFilter类
问题
群里有人问:我从左边的模型经过vtkClipPolyData的裁剪得到右边的模型。但裁剪完之后,里面是空心的,想问要如何操作才能把裁剪路径面给补上。

我理解的是,他想做将裁剪后的空腔与原来的vtkPolyData相连;类似下图,具体看VTK笔记-裁剪分割-几何裁剪-vtkClipPolyData

一开始我想着是不是同刚才那个笔记,获取到在多边形上闭合曲线点,然后在获取多面与当前点的线的交点,形成一个三角带与之前的vtkPolyData就形成了一个闭合的多边形数据vtkPolyData;
从VTK图像处理交流群里,林木甜认为就是两个vtkPolyData之间的布尔操作,使用vtkBooleanOperationPolyDataFilter类就可以完成该功能,自己写个例子试验一下;
vtkBooleanOperationPolyDataFilter类
计算由两个输入曲面定义的体积计算的并集、交点或差分体积的边界。
这两个曲面不需要是流形(manifold),但如果不是流形,则可能会得到意外的结果。生成的曲面在过滤器的第一个输出中可用。第二个输出包含一组多段线,表示两个输入曲面之间的交点。
注意:此过滤器不是为执行二维布尔运算而设计的,实际上依赖于没有共面重叠单元的输入。

接口
vtkBooleanOperationPolyDataFilter类支持三种bool操作,分别是合集(union)、交集(intersection)以及差异(difference);
void SetOperationToUnion() { this->SetOperation(VTK_UNION); }
void SetOperationToIntersection() { this->SetOperation(VTK_INTERSECTION); }
void SetOperationToDifference() { this->SetOperation(VTK_DIFFERENCE); } vtkSetMacro(ReorientDifferenceCells, vtkTypeBool);
vtkGetMacro(ReorientDifferenceCells, vtkTypeBool);
vtkBooleanMacro(ReorientDifferenceCells, vtkTypeBool);
试验
1.创建圆球和圆柱
创建两个多边形,分别是圆球和圆柱,两者相交;
vtkSphereSource* sphere = vtkSphereSource::New();
sphere->SetCenter(0, 0, 0);
sphere->SetRadius(10);
sphere->SetThetaResolution(40);
sphere->SetPhiResolution(40);
sphere->Update();
vtkCylinderSource* cylinder = vtkCylinderSource::New();//圆柱
cylinder->SetCenter(0, 0, 0);
cylinder->SetRadius(3);
cylinder->SetHeight(40);
cylinder->SetResolution(10);
cylinder->Update();
vtkPolyDataMapper* map = vtkPolyDataMapper::New();
map->SetInputConnection(sphere->GetOutputPort());
map->ScalarVisibilityOff();
vtkActor* actor = vtkActor::New();
actor->SetMapper(map);
vtkPolyDataMapper* map2 = vtkPolyDataMapper::New();
map2->SetInputConnection(cylinder->GetOutputPort());
map2->ScalarVisibilityOff();
vtkActor* actor2 = vtkActor::New();
actor2->SetMapper(map2);
vtkRenderer* ren = vtkRenderer::New();
vtkRenderWindow* renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);ren->AddActor(actor);
ren->AddActor(actor2);
ren->SetBackground(0.3, 0.4, 0.5);
renWin->SetSize(450, 450);vtkInteractorStyleTrackballCamera* style = vtkInteractorStyleTrackballCamera::New();
iren->SetInteractorStyle(style);iren->Initialize();
renWin->Render();
iren->Start();

1.圆球和圆柱的布尔运算
vtkSphereSource* sphere = vtkSphereSource::New();
sphere->SetCenter(0, 0, 0);
sphere->SetRadius(10);
sphere->SetThetaResolution(40);
sphere->SetPhiResolution(40);
sphere->Update();
vtkCylinderSource* cylinder = vtkCylinderSource::New();//圆柱
cylinder->SetCenter(0, 0, 0);
cylinder->SetRadius(3);
cylinder->SetHeight(40);
cylinder->SetResolution(10);
cylinder->Update();
vtkNew<vtkTriangleFilter> filter1;
filter1->SetInputData(sphere->GetOutput());
filter1->Update();
vtkNew<vtkTriangleFilter> filter2;
filter2->SetInputData(cylinder->GetOutput());
filter2->Update();
vtkNew<vtkBooleanOperationPolyDataFilter> filter_merge;
filter_merge->SetInputData(0, filter1->GetOutput());
filter_merge->SetInputData(1, filter2->GetOutput());
filter_merge->SetOperationToDifference();
filter_merge->Update();vtkPolyDataMapper* map = vtkPolyDataMapper::New();
map->SetInputConnection(filter_merge->GetOutputPort());
map->ScalarVisibilityOff();
vtkActor* actor = vtkActor::New();
actor->SetMapper(map);vtkRenderer* ren = vtkRenderer::New();
vtkRenderWindow* renWin = vtkRenderWindow::New();
renWin->AddRenderer(ren);
vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);ren->AddActor(actor);
ren->SetBackground(0.3, 0.4, 0.5);
renWin->SetSize(450, 450);vtkInteractorStyleTrackballCamera* style = vtkInteractorStyleTrackballCamera::New();
iren->SetInteractorStyle(style);iren->Initialize();
renWin->Render();
iren->Start();
以圆球为主体,圆球设置输入为0的效果图
Union
filter_merge->SetOperationToUnion();


Intersection
filter_merge->SetOperationToIntersection();

Difference
filter_merge->SetOperationToDifference();


以圆柱为主体,圆球设置输入为0的效果图
Union

Intersection


Difference


代码实现中遇到的问题
直接在vtkBooleanOperationPolyDataFilter类设置圆柱和圆球,出现错误:

后从网上查的资料:“VTK的boolean operationa中,仅仅能够处理两个三角面片交点为2或者更小的情况。对于两个三角面片共面的情况,交点情况将会变得更加复杂。”然后,想着把几何多边形三角化,果然可以解决该问题;
参考资料
1.VTK boolean operation 使用方法
2.vtkBooleanOperationPolyDataFilter类说明
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
