remove memset from meshtree.h

This commit is contained in:
alemuntoni 2021-10-19 12:14:31 +02:00
parent 70ac3d8248
commit 5e17997b37
1 changed files with 190 additions and 148 deletions

View File

@ -125,21 +125,28 @@ namespace vcg {
return count; return count;
} }
void Process(vcg::AlignPair::Param &ap, MeshTree::Param &mtp) { void Process(vcg::AlignPair::Param& ap, MeshTree::Param& mtp)
{
char buf[1024]; std::array<char, 1024> buf;
std::sprintf(buf, "Starting Processing of %i glued meshes out of %zu meshes\n", gluedNum(), nodeMap.size()); std::sprintf(
cb(0, buf); buf.data(),
"Starting Processing of %i glued meshes out of %zu meshes\n",
gluedNum(),
nodeMap.size());
cb(0, buf.data());
/******* Occupancy Grid Computation *************/ /******* Occupancy Grid Computation *************/
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "Computing Overlaps %i glued meshes...\n", gluedNum()); std::sprintf(buf.data(), "Computing Overlaps %i glued meshes...\n", gluedNum());
cb(0, buf); cb(0, buf.data());
OG.Init(static_cast<int>(nodeMap.size()), vcg::Box3<ScalarType>::Construct(gluedBBox()), mtp.OGSize); OG.Init(
static_cast<int>(nodeMap.size()),
vcg::Box3<ScalarType>::Construct(gluedBBox()),
mtp.OGSize);
for (auto& ni : nodeMap) { for (auto& ni : nodeMap) {
MeshTree::MeshNode *mn = ni.second; MeshTree::MeshNode* mn = ni.second;
if (mn->glued) { if (mn->glued) {
OG.AddMesh(mn->m->cm, vcg::Matrix44<ScalarType>::Construct(mn->tr()), mn->Id()); OG.AddMesh(mn->m->cm, vcg::Matrix44<ScalarType>::Construct(mn->tr()), mn->Id());
} }
@ -154,7 +161,6 @@ namespace vcg {
// count existing arcs within current error threshold // count existing arcs within current error threshold
float percentileThr = 0; float percentileThr = 0;
if (!resultList.empty()) { if (!resultList.empty()) {
vcg::Distribution<float> H; vcg::Distribution<float> H;
for (auto& li : resultList) { for (auto& li : resultList) {
H.Add(li.err); H.Add(li.err);
@ -166,9 +172,10 @@ namespace vcg {
std::size_t totalArcNum = 0; std::size_t totalArcNum = 0;
int preservedArcNum = 0, recalcArcNum = 0; int preservedArcNum = 0, recalcArcNum = 0;
while(totalArcNum < OG.SVA.size() && OG.SVA[totalArcNum].norm_area > mtp.arcThreshold) while (totalArcNum < OG.SVA.size() &&
{ OG.SVA[totalArcNum].norm_area > mtp.arcThreshold) {
AlignPair::Result *curResult = findResult(OG.SVA[totalArcNum].s, OG.SVA[totalArcNum].t); AlignPair::Result* curResult =
findResult(OG.SVA[totalArcNum].s, OG.SVA[totalArcNum].t);
if (curResult) { if (curResult) {
if (curResult->err < percentileThr) { if (curResult->err < percentileThr) {
++preservedArcNum; ++preservedArcNum;
@ -186,39 +193,48 @@ namespace vcg {
++totalArcNum; ++totalArcNum;
} }
//if there are no arcs at all complain and return // if there are no arcs at all complain and return
if (totalArcNum == 0) { if (totalArcNum == 0) {
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. Nothing Done.\n"); std::sprintf(
cb(0, buf); buf.data(),
"\n Failure. There are no overlapping meshes?\n No candidate alignment arcs. "
"Nothing Done.\n");
cb(0, buf.data());
return; return;
} }
int num_max_thread = 1; int num_max_thread = 1;
#ifdef _OPENMP #ifdef _OPENMP
if (totalArcNum > 32) num_max_thread = omp_get_max_threads(); if (totalArcNum > 32)
num_max_thread = omp_get_max_threads();
#endif #endif
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size()); std::sprintf(
cb(0, buf); buf.data(), "Arc with good overlap %6zu (on %6zu)\n", totalArcNum, OG.SVA.size());
cb(0, buf.data());
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, " %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum); std::sprintf(buf.data(), " %6i preserved %i Recalc \n", preservedArcNum, recalcArcNum);
cb(0, buf); cb(0, buf.data());
bool hasValidAlign = false; bool hasValidAlign = false;
#pragma omp parallel for schedule(dynamic, 1) num_threads(num_max_thread) #pragma omp parallel for schedule(dynamic, 1) num_threads(num_max_thread)
// on windows, omp does not support unsigned types for indices on cycles // on windows, omp does not support unsigned types for indices on cycles
for (int i = 0 ;i < static_cast<int>(totalArcNum); ++i) { for (int i = 0; i < static_cast<int>(totalArcNum); ++i) {
std::fprintf(
std::fprintf(stdout,"%4i -> %4i Area:%5i NormArea:%5.3f\n",OG.SVA[i].s,OG.SVA[i].t,OG.SVA[i].area,OG.SVA[i].norm_area); stdout,
AlignPair::Result *curResult = findResult(OG.SVA[i].s,OG.SVA[i].t); "%4i -> %4i Area:%5i NormArea:%5.3f\n",
OG.SVA[i].s,
OG.SVA[i].t,
OG.SVA[i].area,
OG.SVA[i].norm_area);
AlignPair::Result* curResult = findResult(OG.SVA[i].s, OG.SVA[i].t);
// // missing arc and arc with great error must be recomputed. // // missing arc and arc with great error must be recomputed.
if (curResult->err >= percentileThr) { if (curResult->err >= percentileThr) {
ProcessArc(OG.SVA[i].s, OG.SVA[i].t, *curResult, ap); ProcessArc(OG.SVA[i].s, OG.SVA[i].t, *curResult, ap);
curResult->area = OG.SVA[i].norm_area; curResult->area = OG.SVA[i].norm_area;
@ -227,44 +243,65 @@ namespace vcg {
std::pair<double, double> dd = curResult->computeAvgErr(); std::pair<double, double> dd = curResult->computeAvgErr();
#pragma omp critical #pragma omp critical
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n", i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,dd.first,dd.second); std::sprintf(
cb(0, buf); buf.data(),
"(%3i/%3zu) %2i -> %2i Aligned AvgErr dd=%f -> dd=%f \n",
i + 1,
totalArcNum,
OG.SVA[i].s,
OG.SVA[i].t,
dd.first,
dd.second);
cb(0, buf.data());
} }
else { else {
#pragma omp critical #pragma omp critical
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n",i+1,totalArcNum,OG.SVA[i].s,OG.SVA[i].t,vcg::AlignPair::errorMsg(curResult->status)); std::sprintf(
cb(0, buf); buf.data(),
"(%3i/%3zu) %2i -> %2i Failed Alignment of one arc %s\n",
i + 1,
totalArcNum,
OG.SVA[i].s,
OG.SVA[i].t,
vcg::AlignPair::errorMsg(curResult->status));
cb(0, buf.data());
} }
} }
} }
//if there are no valid arcs complain and return // if there are no valid arcs complain and return
if (!hasValidAlign) { if (!hasValidAlign) {
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "\n Failure. No successful arc among candidate Alignment arcs. Nothing Done.\n"); std::sprintf(
cb(0, buf); buf.data(),
"\n Failure. No successful arc among candidate Alignment arcs. Nothing "
"Done.\n");
cb(0, buf.data());
return; return;
} }
vcg::Distribution<float> H; // stat for printing vcg::Distribution<float> H; // stat for printing
for (auto& li : resultList) { for (auto& li : resultList) {
if (li.isValid()) H.Add(li.err); if (li.isValid())
H.Add(li.err);
} }
std::memset(buf, '\0', 1024); buf.fill('\0');
std::sprintf(buf, "Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n", H.Avg(), H.Percentile(0.5f), H.Percentile(0.9f)); std::sprintf(
cb(0, buf); buf.data(),
"Completed Mesh-Mesh Alignment: Avg Err %5.3f; Median %5.3f; 90%% %5.3f\n",
H.Avg(),
H.Percentile(0.5f),
H.Percentile(0.9f));
cb(0, buf.data());
ProcessGlobal(ap); ProcessGlobal(ap);
} }
void ProcessGlobal(vcg::AlignPair::Param &ap) { void ProcessGlobal(vcg::AlignPair::Param& ap)
{
char buff[1024];
std::memset(buff, '\0', 1024);
/************** Preparing Matrices for global alignment *************/ /************** Preparing Matrices for global alignment *************/
std::vector<int> GluedIdVec; std::vector<int> GluedIdVec;
std::vector<vcg::Matrix44d> GluedTrVec; std::vector<vcg::Matrix44d> GluedTrVec;
@ -272,8 +309,7 @@ namespace vcg {
std::map<int, std::string> names; std::map<int, std::string> names;
for (auto& ni : nodeMap) { for (auto& ni : nodeMap) {
MeshTree::MeshNode* mn = ni.second;
MeshTree::MeshNode *mn = ni.second;
if (mn->glued) { if (mn->glued) {
GluedIdVec.push_back(mn->Id()); GluedIdVec.push_back(mn->Id());
GluedTrVec.push_back(vcg::Matrix44d::Construct(mn->tr())); GluedTrVec.push_back(vcg::Matrix44d::Construct(mn->tr()));
@ -282,7 +318,7 @@ namespace vcg {
} }
vcg::AlignGlobal AG; vcg::AlignGlobal AG;
std::vector<vcg::AlignPair::Result *> ResVecPtr; std::vector<vcg::AlignPair::Result*> ResVecPtr;
for (auto& li : resultList) { for (auto& li : resultList) {
if (li.isValid()) { if (li.isValid()) {
ResVecPtr.push_back(&li); ResVecPtr.push_back(&li);
@ -292,21 +328,27 @@ namespace vcg {
AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec); AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec);
float StartGlobErr = 0.001f; float StartGlobErr = 0.001f;
while (!AG.GlobalAlign(names, StartGlobErr, 100, ap.MatchMode == vcg::AlignPair::Param::MMRigid, stdout, cb)) { while (!AG.GlobalAlign(
names,
StartGlobErr,
100,
ap.MatchMode == vcg::AlignPair::Param::MMRigid,
stdout,
cb)) {
StartGlobErr *= 2; StartGlobErr *= 2;
AG.BuildGraph(ResVecPtr,GluedTrVec, GluedIdVec); AG.BuildGraph(ResVecPtr, GluedTrVec, GluedIdVec);
} }
std::vector<vcg::Matrix44d> GluedTrVecOut(GluedTrVec.size()); std::vector<vcg::Matrix44d> GluedTrVecOut(GluedTrVec.size());
AG.GetMatrixVector(GluedTrVecOut,GluedIdVec); AG.GetMatrixVector(GluedTrVecOut, GluedIdVec);
// Now get back the results! // Now get back the results!
for (std::size_t ii = 0; ii < GluedTrVecOut.size(); ++ii) { for (std::size_t ii = 0; ii < GluedTrVecOut.size(); ++ii) {
MM(GluedIdVec[ii])->cm.Tr.Import(GluedTrVecOut[ii]); MM(GluedIdVec[ii])->cm.Tr.Import(GluedTrVecOut[ii]);
} }
std::string str =
std::sprintf(buff, "Completed Global Alignment (error bound %6.4f)\n", StartGlobErr); "Completed Global Alignment (error bound " + std::to_string(StartGlobErr) + ")\n";
cb(0, buff); cb(0, str.c_str());
} }
void ProcessArc(int fixId, int movId, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) { void ProcessArc(int fixId, int movId, vcg::AlignPair::Result &result, vcg::AlignPair::Param ap) {