一、CC中计算体积和表面积
二、PCL中计算体积和表面积
vtkMassProperties 来计算体积和表面积,但是必须是三角化的模型,不能是多边形的模型
vtkTriangleFilter如果是其他模型的就转换为三角化的模型
// 计算点云的体积和表面积
// 输入的不能是点云,只能是三角化之后的点云模型
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;
}
三、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;
}