VTK:對輸入的三維模型在某個方向等間距提取模型的切面輪廓線
阿新 • • 發佈:2019-02-10
測試的三維模型為bunny,即斯坦福兔子
程式碼示例:
結果示例:#include <vtkOBJReader.h> #include <vtkSmartPointer.h> #include <vtkCutter.h> #include <vtkPolyDataMapper.h> #include <vtkPlane.h> #include <vtkProperty.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkSphereSource.h> #include <vtkPolyDataWriter.h> #include <vtkPolyData.h> #include <vtkStripper.h> #include <vtkContourFilter.h> #include <vtkPoints.h> #include <iostream> using namespace std; double Distance(double *a,double *b) { double o=(a[0]-b[0])*(a[0]-b[0]); double p=(a[1]-b[1])*(a[1]-b[1]); double q=(a[2]-b[2])*(a[2]-b[2]); return o+p+q; } int main() { //讀取obj檔案 vtkSmartPointer<vtkOBJReader> reader =vtkSmartPointer<vtkOBJReader>::New(); reader->SetFileName("C:\\Users\\HuangWang\\Desktop\\bunny-chuli.obj"); reader->Update(); vtkSmartPointer<vtkPolyData> inputPolyData=vtkSmartPointer<vtkPolyData>::New(); inputPolyData = reader->GetOutput(); vtkSmartPointer<vtkPolyDataMapper> inputMapper =vtkSmartPointer<vtkPolyDataMapper>::New(); inputMapper->SetInput(inputPolyData); //建立切割平面 vtkSmartPointer<vtkPlane> plane =vtkSmartPointer<vtkPlane>::New(); plane->SetOrigin(inputPolyData->GetCenter());//設定切割平面起點 plane->SetNormal(1,0,0);//設定切割方向為X方向 //得到輸入的obj模型的最小座標 double minBound[3]; minBound[0] = inputPolyData->GetBounds()[0]; minBound[1] = inputPolyData->GetBounds()[2]; minBound[2] = inputPolyData->GetBounds()[4]; //得到輸入的obj模型的最小大座標 double maxBound[3]; maxBound[0] = inputPolyData->GetBounds()[1]; maxBound[1] = inputPolyData->GetBounds()[3]; maxBound[2] = inputPolyData->GetBounds()[5]; //得到輸入的obj模型的中心座標 double center[3]; center[0] = inputPolyData->GetCenter()[0]; center[1] = inputPolyData->GetCenter()[1]; center[2] = inputPolyData->GetCenter()[2]; double distanceMin=sqrt(Distance(minBound,center)); double distanceMax=sqrt(Distance(maxBound,center)); //建立模型切割器 vtkSmartPointer<vtkCutter> cutter =vtkSmartPointer<vtkCutter>::New(); cutter->SetCutFunction(plane);//設定切割平面 cutter->SetInput(inputPolyData);//設定模型 cutter->GenerateValues(30, -distanceMin, distanceMax);//在模型的最大最小範圍內等間距建立30個切面,得到輪廓線 //將切線結果輸出為vtk檔案格式 vtkSmartPointer<vtkPolyData> ResultPoly=cutter->GetOutput();//輸出為polydata vtkSmartPointer<vtkPolyDataWriter> vtkWriter = vtkSmartPointer<vtkPolyDataWriter>::New(); vtkWriter->SetInput(cutter->GetOutput()); vtkWriter->SetFileName("C:\\Users\\HuangWang\\Desktop\\result.vtk"); vtkWriter->Write(); vtkSmartPointer<vtkPolyDataMapper> cutterMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); cutterMapper->SetInputConnection( cutter->GetOutputPort()); cutterMapper->ScalarVisibilityOff(); vtkSmartPointer<vtkActor> planeActor = vtkSmartPointer<vtkActor>::New(); planeActor->GetProperty()->SetColor(1,0,0); planeActor->GetProperty()->SetLineWidth(5); planeActor->SetMapper(cutterMapper); vtkSmartPointer<vtkActor> inputActor = vtkSmartPointer<vtkActor>::New(); inputActor->GetProperty()->SetColor(0,1,0); inputActor->SetMapper(inputMapper); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(planeActor); renderer->AddActor(inputActor); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetSize(600, 600); vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renderWindow); renderer->SetBackground(0,0,0); renderWindow->Render(); interactor->Start(); return 0; }
最後輸出的結果VTK檔案包含了每一條輪廓線的點資料