1. 程式人生 > >VTK:對輸入的三維模型在某個方向等間距提取模型的切面輪廓線

VTK:對輸入的三維模型在某個方向等間距提取模型的切面輪廓線

測試的三維模型為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檔案包含了每一條輪廓線的點資料