一、CC中计算体积和表面积 

PCL vtk 计算点云的体积和表面积-LMLPHP

 二、PCL中计算体积和表面积


// 计算点云的体积和表面积
// 输入的不能是点云,只能是三角化之后的点云模型
int  vtkCalc_Area_Volume(pcl::PolygonMesh  &model, float surface_area, float volume)
{
	vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();

	// mesh  ply 格式的模型
	reader->SetFileName("C:\\Users\\Albert\\Desktop\\Halcon2PCL\\bundy.ply");
	reader->Update();

	// 三角化, vtkMassProperties 这个只能计算三角化的模型
	vtkSmartPointer<vtkTriangleFilter> triangle = vtkSmartPointer<vtkTriangleFilter>::New();
	triangle->SetInputData(reader->GetOutput());
	triangle->Update();
	//  vtkMassProperties  来计算体积和表面积
	vtkSmartPointer<vtkMassProperties>  ploy = vtkSmartPointer<vtkMassProperties>::New();
	ploy->SetInputData(triangle->GetOutput());
	ploy->Update();

	  volume = ploy->GetVolume();//  体积

	  // 计算三角形的面积 并求和
	  surface_area = ploy->GetSurfaceArea(); // 表面积

	  cout << "体积: "<< volume << endl;
	  cout << "面积: " << surface_area << endl;
	  double maxArea = ploy->GetMaxCellArea();//最大单元面积
	  double minArea = ploy->GetMinCellArea();//最小单元面积
	  cout << "单元最大面积:   " << maxArea << endl;
	  cout << "单元最小面积:   " << minArea << endl;
	return 0;
}

 PCL vtk 计算点云的体积和表面积-LMLPHP

三、vtk 切片法求体积

// 平面切点云模型并求体积
int vtk_Plane_Cut_Model_Volume(std::string stlfile, double &spacing, double &vol)
{
	vtkSmartPointer<vtkPLYReader> reader = vtkSmartPointer<vtkPLYReader>::New();
	reader->SetFileName(stlfile.c_str());  // 读入模型
	reader->Update();

	vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
	polyData = reader->GetOutput();


	// 设定平面模型
	vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
	//设置切割平面起点
	plane->SetOrigin(polyData->GetCenter());
	cout << "切割平面起点" << plane << endl;
	//设置切割方向为X方向,其实设置Y 方向也可以,只是这里的参数这设置的好的话会减少切的次数
	plane->SetNormal(1, 0, 0);


	// 拿到输入的最小\大坐标
	double min_bound[3], max_bound[3];
	min_bound[0] = polyData->GetBounds()[0];
	min_bound[1] = polyData->GetBounds()[2];
	min_bound[2] = polyData->GetBounds()[4];


	max_bound[0] = polyData->GetBounds()[1];
	max_bound[1] = polyData->GetBounds()[3];
	max_bound[2] = polyData->GetBounds()[5];


	// 拿到点云模型的质心
	double  center[3];
	center[0] = polyData->GetCenter()[0];
	center[1] = polyData->GetCenter()[1];
	center[2] = polyData->GetCenter()[2];
	std::cout << "  中心点:" << center[0] << "," << center[1] << "," << center[2] << endl;
	

	// 计算极值点到中心点的距离
	Eigen::Vector3d  min(min_bound);
	Eigen::Vector3d  max(max_bound);
	Eigen::Vector3d  center_v(center);
	double  dist_min_center  = (min - center_v).norm();
	double  dist_max_center = (max - center_v).norm();
	cout << "距离:      "<< dist_min_center<<"           "<< dist_max_center << endl;

	// 计算切片的次数
	int  number = (int)(dist_min_center + dist_max_center) / spacing;
	vtkSmartPointer<vtkCutter> cutter = vtkSmartPointer<vtkCutter>::New();
	 // 设置切割平面
	cutter->SetCutFunction(plane);
	// 输入切割的模型
	cutter->SetInputData(polyData);
	// 设置切片的范围
	cutter->GenerateValues(number,-dist_min_center, dist_max_center);
	cutter->Update();

	std::cout << "  切片个数:" << number << "     切片间距:     " << (dist_min_center + dist_max_center) / (number - 1) << endl;
	// 
	vtkSmartPointer<vtkStripper> cut_Stripper = vtkSmartPointer<vtkStripper>::New();
	cut_Stripper->SetInputConnection(cutter->GetOutputPort());
	cut_Stripper->Update();



	vtkSmartPointer<vtkPolyData> cutPolyData = vtkSmartPointer<vtkPolyData>::New();
	cutPolyData->SetPoints(cut_Stripper->GetOutput()->GetPoints());
	cutPolyData->SetPolys(cut_Stripper->GetOutput()->GetLines());

	//三角化
	vtkSmartPointer<vtkTriangleFilter> cutTriangles = vtkSmartPointer<vtkTriangleFilter>::New();
	cutTriangles->SetInputData(cutPolyData);
	cutTriangles->Update();


	//  计算体积和面积
	vtkSmartPointer<vtkMassProperties> mass = vtkSmartPointer<vtkMassProperties>::New();
	mass->SetInputData(cutTriangles->GetOutput());

	cout << mass->GetSurfaceArea() << endl;
	 vol = (dist_min_center + dist_max_center) / (number - 1)  * mass->GetSurfaceArea();

	return 0;
}
07-03 20:02