minor changes in isotropic remesher

This commit is contained in:
korialis 2020-11-12 16:38:56 +01:00
parent 0488a0242a
commit 8409535255
1 changed files with 1272 additions and 1250 deletions

View File

@ -185,7 +185,30 @@ private:
vcg::Triangle3<ScalarType> t1(f.P(longestIdx), f.P1(longestIdx), f.P2(longestIdx)), t2(g->P(k), g->P1(k), g->P2(k)), vcg::Triangle3<ScalarType> t1(f.P(longestIdx), f.P1(longestIdx), f.P2(longestIdx)), t2(g->P(k), g->P1(k), g->P2(k)),
t3(f.P(longestIdx), g->P2(k), f.P2(longestIdx)), t4(g->P(k), f.P2(longestIdx), g->P2(k)); t3(f.P(longestIdx), g->P2(k), f.P2(longestIdx)), t4(g->P(k), f.P2(longestIdx), g->P2(k));
if ( std::min( QualityFace(t1), QualityFace(t2) ) <= std::min( QualityFace(t3), QualityFace(t4) )) auto n1 = vcg::TriangleNormal(t1);
auto n2 = vcg::TriangleNormal(t2);
auto n3 = vcg::TriangleNormal(t3);
auto n4 = vcg::TriangleNormal(t4);
auto biggestSmallest = vcg::DoubleArea(t1) > vcg::DoubleArea(t2) ? std::make_pair(t1, t2) : std::make_pair(t2, t1);
auto areaRatio = vcg::DoubleArea(biggestSmallest.first) / vcg::DoubleArea(biggestSmallest.second);
bool normalCheck = true;
// if (n1.Norm() > 0.001 && n2.Norm() > 0.001)
{
auto referenceNormal = vcg::NormalizedTriangleNormal(biggestSmallest.first);
normalCheck &= vcg::NormalizedTriangleNormal(t3) * referenceNormal >= 0.95;
normalCheck &= vcg::NormalizedTriangleNormal(t4) * referenceNormal >= 0.95;
}
bool areaCheck = false;
if (areaRatio > 1000)
{
areaCheck |= vcg::DoubleArea(t3) / vcg::DoubleArea(biggestSmallest.second) > 1000 && vcg::DoubleArea(t4) / vcg::DoubleArea(biggestSmallest.second) > 1000;
}
if ((normalCheck) && (areaCheck || std::min( QualityFace(t1), QualityFace(t2) ) <= std::min( QualityFace(t3), QualityFace(t4))))
{ {
ScalarType dist; ScalarType dist;
CoordType closest; CoordType closest;
@ -203,7 +226,8 @@ private:
} }
} }
} }
} while (count && ++iter < 50); } while (count && ++iter < 75);
} }
static void cleanMesh(MeshType & m, Params & params) static void cleanMesh(MeshType & m, Params & params)
@ -374,15 +398,16 @@ private:
return (int)(std::ceil(angleSumRad / (M_PI/3.0f))); return (int)(std::ceil(angleSumRad / (M_PI/3.0f)));
} }
static bool testHausdorff (MeshType & m, StaticGrid & grid, const std::vector<CoordType> & verts, const ScalarType maxD) static bool testHausdorff (MeshType & m, StaticGrid & grid, const std::vector<CoordType> & verts, const ScalarType maxD, const CoordType checkOrientation = CoordType(0,0,0))
{ {
for (CoordType v : verts) for (CoordType v : verts)
{ {
CoordType closest; CoordType closest, normal, ip;
ScalarType dist = 0; ScalarType dist = 0;
FaceType* fp = GetClosestFaceBase(m, grid, v, maxD, dist, closest); FaceType* fp = GetClosestFaceBase(m, grid, v, maxD, dist, closest);
if (fp == NULL) //you can't use this kind of orientation check, since when you stand on edges it fails
if (fp == NULL /*|| (checkOrientation != CoordType(0,0,0) && checkOrientation * fp->N() < 0.5)*/)
{ {
return false; return false;
} }
@ -794,8 +819,10 @@ private:
Point3<ScalarType> oldN = NormalizedTriangleNormal(*(pi.F())); Point3<ScalarType> oldN = NormalizedTriangleNormal(*(pi.F()));
Point3<ScalarType> newN = Normal(mp, v1->P(), v2->P()).Normalize(); Point3<ScalarType> newN = Normal(mp, v1->P(), v2->P()).Normalize();
float div = fastAngle(oldN, newN); // float div = fastAngle(oldN, newN);
if(div < .0f ) return false; // if(div < .9f ) return false;
if (oldN * newN < 0.8f)
return false;
// // check on new face distance from original mesh // // check on new face distance from original mesh
if (params.surfDistCheck) if (params.surfDistCheck)
@ -805,7 +832,7 @@ private:
points[1] = (v1->cP() + mp) / 2.; points[1] = (v1->cP() + mp) / 2.;
points[2] = (v2->cP() + mp) / 2.; points[2] = (v2->cP() + mp) / 2.;
points[3] = mp; points[3] = mp;
if (!testHausdorff(*(params.mProject), params.grid, points, params.maxSurfDist)) if (!testHausdorff(*(params.mProject), params.grid, points, params.maxSurfDist, newN))
return false; return false;
} }
} }
@ -841,11 +868,6 @@ private:
assert(int(false) == 0); assert(int(false) == 0);
mp = (p0.V()->cP() * int(moveable1) + p1.V()->cP() * int(moveable0)) / (int(moveable0) + int(moveable1)); mp = (p0.V()->cP() * int(moveable1) + p1.V()->cP() * int(moveable0)) / (int(moveable0) + int(moveable1));
if (!moveable0)
p = p0;
else
p = p1;
if (checkFacesAfterCollapse(ff0, p0, mp, params, relaxed)) if (checkFacesAfterCollapse(ff0, p0, mp, params, relaxed))
return checkFacesAfterCollapse(ff1, p1, mp, params, relaxed); return checkFacesAfterCollapse(ff1, p1, mp, params, relaxed);
@ -1155,17 +1177,17 @@ private:
//this aspect ratio check doesn't work on cadish meshes (long thin triangles spanning whole mesh) //this aspect ratio check doesn't work on cadish meshes (long thin triangles spanning whole mesh)
ForEachFace(m, [&] (FaceType & f) { // ForEachFace(m, [&] (FaceType & f) {
if (vcg::Quality(f.cP(0), f.cP(1), f.cP(2)) < params.aspectRatioThr || vcg::DoubleArea(f) < 0.00001) // if (vcg::Quality(f.cP(0), f.cP(1), f.cP(2)) < params.aspectRatioThr || vcg::DoubleArea(f) < 0.00001)
{ // {
if (creaseVerts[vcg::tri::Index(m, f.V(0))] == 0) // if (creaseVerts[vcg::tri::Index(m, f.V(0))] == 0)
f.V(0)->SetS(); // f.V(0)->SetS();
if (creaseVerts[vcg::tri::Index(m, f.V(1))] == 0) // if (creaseVerts[vcg::tri::Index(m, f.V(1))] == 0)
f.V(1)->SetS(); // f.V(1)->SetS();
if (creaseVerts[vcg::tri::Index(m, f.V(2))] == 0) // if (creaseVerts[vcg::tri::Index(m, f.V(2))] == 0)
f.V(2)->SetS(); // f.V(2)->SetS();
} // }
}); // });
ForEachFace(m, [&] (FaceType & f) { ForEachFace(m, [&] (FaceType & f) {
@ -1344,8 +1366,8 @@ private:
if(!(*vi).IsD()) if(!(*vi).IsD())
{ {
Point3<ScalarType> newP, normP, barP; Point3<ScalarType> newP, normP, barP;
ScalarType maxDist = params.maxSurfDist * 1.5f, minDist = 0.f; ScalarType maxDist = params.maxSurfDist * 2.5f, minDist = 0.f;
FaceType* fp = GetClosestFaceBase(*params.mProject, params.grid, vi->cP(), maxDist, minDist, newP, normP, barP); FaceType* fp = GetClosestFaceBase(*params.mProject, params.grid, vi->cP(), maxDist, minDist, newP/*, normP, barP*/);
if (fp != NULL) if (fp != NULL)
{ {