天天看點

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

問題

  群裡有人問:我從左邊的模型經過vtkClipPolyData的裁剪得到右邊的模型。但裁剪完之後,裡面是空心的,想問要如何操作才能把裁剪路徑面給補上。

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

  我了解的是,他想做将裁剪後的空腔與原來的vtkPolyData相連;類似下圖,具體看VTK筆記-裁剪分割-幾何裁剪-vtkClipPolyData

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

  一開始我想着是不是同剛才那個筆記,擷取到在多邊形上閉合曲線點,然後在擷取多面與目前點的線的交點,形成一個三角帶與之前的vtkPolyData就形成了一個閉合的多邊形資料vtkPolyData;

  從VTK圖像處理交流群裡,林木甜認為就是兩個vtkPolyData之間的布爾操作,使用vtkBooleanOperationPolyDataFilter類就可以完成該功能,自己寫個例子試驗一下;

vtkBooleanOperationPolyDataFilter類

計算由兩個輸入曲面定義的體積計算的并集、交點或差分體積的邊界。

這兩個曲面不需要是流形(manifold),但如果不是流形,則可能會得到意外的結果。生成的曲面在過濾器的第一個輸出中可用。第二個輸出包含一組多段線,表示兩個輸入曲面之間的交點。

注意:此過濾器不是為執行二維布爾運算而設計的,實際上依賴于沒有共面重疊單元的輸入。

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

接口

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();
           
VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

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

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料
VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

Intersection

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

Difference

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料
VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

以圓柱為主體,圓球設定輸入為0的效果圖

Union

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

Intersection

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料
VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

Difference

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料
VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

代碼實作中遇到的問題

直接在vtkBooleanOperationPolyDataFilter類設定圓柱和圓球,出現錯誤:

VTK筆記-多邊形Poly-布爾運算-vtkBooleanOperationPolyDataFilter類問題vtkBooleanOperationPolyDataFilter類試驗參考資料

後從網上查的資料:“VTK的boolean operationa中,僅僅能夠處理兩個三角面片交點為2或者更小的情況。對于兩個三角面片共面的情況,交點情況将會變得更加複雜。”然後,想着把幾何多邊形三角化,果然可以解決該問題;

參考資料

1.VTK boolean operation 使用方法

2.vtkBooleanOperationPolyDataFilter類說明