前言:本博文主要记录vtk中用于计算体积和表面积的接口vtkMassProperties,分享该接口使用时的注意事项,使用方法以及算法实现原理,希望能给各位小伙伴带来一点帮助!
目录
vtkMassProperties
描述:
估算三角形网格的体积、面积和形状索引。算法基于离散形式的散度定理实现,一般假设输入的模型为闭合曲面。
*形状索引,还不太理解。
注意事项
1. 输入数据为闭合曲面,若为非闭合,体积计算出错。
2. 输入数据为三角面片,即数据不能存在Strips和Polys的形式。建议采用vtkTriangleFilter对数据进行三角划分。
3. 若输入数据定义了多个封闭对象,请考虑使用vtkMultiObjectMassProperties接口进行计算;也可以考虑采用vtkPolyDataConnectivityFilter提取连接区域后,采用vtkMassProperties对每个连接区域进行计算。
使用方法
vtkMassProperties* massProperties = vtkMassProperties::New();
if (pd->GetNumberOfPolys() > 0 || pd->GetNumberOfStrips() > 0)
{
vtkTriangleFilter* triFilter = vtkTriangleFilter::New();
triFilter->SetInputData(pd);
triFilter->Update();
massProperties->SetInputData(triFilter->GetOutput());
massProperties->Update();
triFilter->Delete();
triFilter = nullptr;
}
else
{
massProperties->SetInputData(pd);
massProperties->Update();
}
实现原理
待添加。
VTK参考样例
#include <vtkSmartPointer.h>
#include <vtkMassProperties.h>
#include <vtkTriangleFilter.h>
#include <vtkFillHolesFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkBYUReader.h>
#include <vtkOBJReader.h>
#include <vtkPLYReader.h>
#include <vtkPolyDataReader.h>
#include <vtkSTLReader.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkSphereSource.h>
#include <vtksys/SystemTools.hxx>
namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName);
}
int main (int argc, char *argv[])
{
vtkSmartPointer<vtkPolyData> polyData = ReadPolyData(argc > 1 ? argv[1] : "");;
vtkSmartPointer<vtkFillHolesFilter> fillHolesFilter =
vtkSmartPointer<vtkFillHolesFilter>::New();
fillHolesFilter->SetInputData(polyData);
fillHolesFilter->SetHoleSize(1000.0);
vtkSmartPointer<vtkTriangleFilter> triangleFilter =
vtkSmartPointer<vtkTriangleFilter>::New();
triangleFilter->SetInputConnection(fillHolesFilter->GetOutputPort());
// Make the triangle windong order consistent
vtkSmartPointer<vtkPolyDataNormals> normals =
vtkSmartPointer<vtkPolyDataNormals>::New();
normals->SetInputConnection(triangleFilter->GetOutputPort());
normals->ConsistencyOn();
normals->SplittingOff();
vtkSmartPointer<vtkMassProperties> massProperties =
vtkSmartPointer<vtkMassProperties>::New();
massProperties->SetInputConnection(normals->GetOutputPort());
massProperties->Update();
std::cout << "Volume: " << massProperties->GetVolume() << std::endl
<< " VolumeX: " << massProperties->GetVolumeX() << std::endl
<< " VolumeY: " << massProperties->GetVolumeY() << std::endl
<< " VolumeZ: " << massProperties->GetVolumeZ() << std::endl
<< "Area: " << massProperties->GetSurfaceArea() << std::endl
<< " MinCellArea: " << massProperties->GetMinCellArea() << std::endl
<< " MinCellArea: " << massProperties->GetMaxCellArea() << std::endl
<< "NormalizedShapeIndex: " << massProperties->GetNormalizedShapeIndex() << std::endl;
return EXIT_SUCCESS;
}
namespace
{
vtkSmartPointer<vtkPolyData> ReadPolyData(const char *fileName)
{
vtkSmartPointer<vtkPolyData> polyData;
std::string extension = vtksys::SystemTools::GetFilenameExtension(std::string(fileName));
if (extension == ".ply")
{
vtkSmartPointer<vtkPLYReader> reader =
vtkSmartPointer<vtkPLYReader>::New();
reader->SetFileName (fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".vtp")
{
vtkSmartPointer<vtkXMLPolyDataReader> reader =
vtkSmartPointer<vtkXMLPolyDataReader>::New();
reader->SetFileName (fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".obj")
{
vtkSmartPointer<vtkOBJReader> reader =
vtkSmartPointer<vtkOBJReader>::New();
reader->SetFileName (fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".stl")
{
vtkSmartPointer<vtkSTLReader> reader =
vtkSmartPointer<vtkSTLReader>::New();
reader->SetFileName (fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".vtk")
{
vtkSmartPointer<vtkPolyDataReader> reader =
vtkSmartPointer<vtkPolyDataReader>::New();
reader->SetFileName (fileName);
reader->Update();
polyData = reader->GetOutput();
}
else if (extension == ".g")
{
vtkSmartPointer<vtkBYUReader> reader =
vtkSmartPointer<vtkBYUReader>::New();
reader->SetGeometryFileName (fileName);
reader->Update();
polyData = reader->GetOutput();
}
else
{
vtkSmartPointer<vtkSphereSource> source =
vtkSmartPointer<vtkSphereSource>::New();
source->SetPhiResolution(51);
source->SetThetaResolution(51);
source->Update();
polyData = source->GetOutput();
}
return polyData;
}
}