I want to implement a function to voxelize the triangular mesh model. Since I need to traverse each triangle, I want to use Openmp for parallelization acceleration. When the number of triangles is large, using Openmp is effective, but when the number of triangles is small, the cost of enabling Openmp is too high. Therefore, I want to dynamically choose whether to use Openmp based on the number of triangles, how to implement it in the code, and whether it can be achieved without a simple if else, because the two parts of the code are almost identical, Openmp only has two additional instructions, so I avoid duplicate code.
std::shared_ptr<hive3DModel::CSparseVoxelGrid> voxelizeInSurface(const hive3DModel::CTriangleMesh& vTriangleMesh, double vVoxelSize)
{
_ASSERTE(vVoxelSize > 0);
Eigen::AlignedBox3d BoundBox;
for (auto it = vTriangleMesh.vertexBegin(); it != vTriangleMesh.vertexEnd(); it++)
{
BoundBox.extend(it->getPosition());
}
Eigen::Vector3d MinBound = BoundBox.min().array() - vVoxelSize / 2;
auto pVoxelGrid = std::make_shared<hive3DModel::CSparseVoxelGrid>(vVoxelSize, MinBound);
const Eigen::Vector3d HalfVoxel(vVoxelSize / 2, vVoxelSize / 2, vVoxelSize / 2);
int NumTriangles = vTriangleMesh.getNumTriangles();
double InverseVoxelSize = 1 / vVoxelSize;
#pragma omp parallel for num_threads(8)
for (int i = 0; i < NumTriangles; i++)
{
const Eigen::Vector3i& Indexs = vTriangleMesh.getTriangle(i);
const Eigen::Vector3d& A = vTriangleMesh.getVertex(Indexs[0]).getPosition(),
B = vTriangleMesh.getVertex(Indexs[1]).getPosition(),
C = vTriangleMesh.getVertex(Indexs[2]).getPosition();
Eigen::Vector3d TriangleMinBound, TriangleMaxBound;
TriangleMinBound = A.cwiseMin(B).cwiseMin(C);
TriangleMaxBound = A.cwiseMax(B).cwiseMax(C);
Eigen::Vector3i MinIndex, MaxIndex;
MinIndex = Eigen::floor(((TriangleMinBound - MinBound) * InverseVoxelSize).array()).cast<int>();
MaxIndex = Eigen::ceil(((TriangleMaxBound - MinBound) * InverseVoxelSize).array()).cast<int>();
for (int x = MinIndex[0]; x <= MaxIndex[0]; x++)
{
for (int y = MinIndex[1]; y <= MaxIndex[1]; y++)
{
for (int z = MinIndex[2]; z <= MaxIndex[2]; z++)
{
Eigen::Vector3i Index(x, y, z);
Eigen::Vector3d Center = (Index.cast<double>() * vVoxelSize + MinBound) + HalfVoxel;
if (hiveUtils::checkTriangleIntersectAABB(A, B, C, Center, HalfVoxel[0]))
{
#pragma omp critical
{
pVoxelGrid->addVoxels(hive3DModel::CVoxel(), Index);
}
}
}
}
}
}
return pVoxelGrid;
}
I want to write the code for judging a triangle as an anonymous function, and then pass in the index of the triangle as a parameter. However, the # pragma omp critical instruction cannot handle it, as it will slow down the speed of not using openmp
if (TriangleNums > 10000)
{
#pragma omp parallel for num_threads(8)
for (int i = 0; i < NumTriangles; i++)
{
dealTriangle(i);
}
}
else
{
for (int i = 0; i < NumTriangles; i++)
{
dealTriangle(i);
}
}