edgemesh uniform sampler fixed + voronoi remesher improved

This commit is contained in:
Luigi Malomo 2017-09-11 14:47:32 +02:00
parent 7f38262616
commit 992ab0ca2e
3 changed files with 60 additions and 21 deletions

View File

@ -78,7 +78,7 @@ int main( int argc, char **argv )
} catch (exception &) {} } catch (exception &) {}
} }
std::cout << "Remeshing using sampling radius: " << samplingRadius << std::endl; std::cout << "Remeshing using sampling radius: " << samplingRadius << std::endl;
auto remeshed = Remesher<MyMesh>::Remesh(startMesh, samplingRadius, 50.0, 0.0); auto remeshed = Remesher<MyMesh>::Remesh(startMesh, samplingRadius, 70.0);
tri::io::ExporterPLY<MyMesh>::Save(*remeshed,"Full.ply",tri::io::Mask::IOM_VERTCOLOR|tri::io::Mask::IOM_WEDGTEXCOORD ); tri::io::ExporterPLY<MyMesh>::Save(*remeshed,"Full.ply",tri::io::Mask::IOM_VERTCOLOR|tri::io::Mask::IOM_WEDGTEXCOORD );

View File

@ -46,6 +46,7 @@ sampling strategies (montecarlo, stratified etc).
#include <vcg/complex/algorithms/update/bounding.h> #include <vcg/complex/algorithms/update/bounding.h>
#include <vcg/space/segment2.h> #include <vcg/space/segment2.h>
#include <vcg/space/index/grid_static_ptr.h> #include <vcg/space/index/grid_static_ptr.h>
namespace vcg namespace vcg
{ {
namespace tri namespace tri
@ -770,13 +771,13 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c
tri::UpdateTopology<MeshType>::EdgeEdge(m); tri::UpdateTopology<MeshType>::EdgeEdge(m);
tri::UpdateFlags<MeshType>::EdgeClearV(m); tri::UpdateFlags<MeshType>::EdgeClearV(m);
tri::MeshAssert<MeshType>::EEOneManifold(m); tri::MeshAssert<MeshType>::EEOneManifold(m);
for (EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei) for (EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
{ {
if (!ei->IsV()) if (!ei->IsV())
{ {
edge::Pos<EdgeType> ep(&*ei,0); edge::Pos<EdgeType> ep(&*ei,0);
edge::Pos<EdgeType> startep = ep; edge::Pos<EdgeType> startep = ep;
VertexPointer startVertex = 0;
do // first loop to search a boundary component. do // first loop to search a boundary component.
{ {
ep.NextE(); ep.NextE();
@ -786,10 +787,33 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c
if (!ep.IsBorder()) if (!ep.IsBorder())
{ {
// it's a loop // it's a loop
startVertex = ep.V(); assert(ep == startep);
// to keep the uniform resampling order-independent:
// 1) start from the 'lowest' point...
edge::Pos<EdgeType> altEp = ep;
altEp.NextE();
while (altEp != startep) {
if (altEp.V()->cP() < ep.V()->cP())
{
ep = altEp;
}
altEp.NextE();
}
// 2) ... with consistent direction
const auto dir0 = ep.VFlip()->cP() - ep.V()->cP();
ep.FlipE();
const auto dir1 = ep.VFlip()->cP() - ep.V()->cP();
if (dir0 < dir1)
{
ep.FlipE();
}
} }
else else
{ {
// not a loop
// to keep the uniform resampling order-independent // to keep the uniform resampling order-independent
// start from the border with 'lowest' point // start from the border with 'lowest' point
edge::Pos<EdgeType> altEp = ep; edge::Pos<EdgeType> altEp = ep;
@ -805,17 +829,22 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c
ScalarType totalLen = 0; ScalarType totalLen = 0;
ep.FlipV(); ep.FlipV();
// second loop to compute length of the chain. // second loop to compute the length of the chain.
do do
{ {
ep.E()->SetV(); ep.E()->SetV();
totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP()); totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP());
ep.NextE(); ep.NextE();
} while (!ep.IsBorder() && ep.V() != startVertex); } while (!ep.E()->IsV() && !ep.IsBorder());
if (ep.IsBorder())
{
ep.E()->SetV(); ep.E()->SetV();
totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP()); totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP());
}
// Third loop actually perform the sampling. VertexPointer startVertex = ep.V();
// Third loop actually performs the sampling.
int sampleNum = conservative ? floor(totalLen / radius) : ceil(totalLen / radius); int sampleNum = conservative ? floor(totalLen / radius) : ceil(totalLen / radius);
ScalarType sampleDist = totalLen / sampleNum; ScalarType sampleDist = totalLen / sampleNum;
@ -824,11 +853,11 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c
ScalarType curLen = 0; ScalarType curLen = 0;
int sampleCnt = 1; int sampleCnt = 1;
ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0); ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0);
do
{ do {
ep.NextE(); ep.NextE();
assert(ep.E()->IsV()); assert(ep.E()->IsV());
ScalarType edgeLen = Distance(ep.V()->cP(), ep.VFlip()->cP()); ScalarType edgeLen = Distance(ep.VFlip()->cP(), ep.V()->cP());
ScalarType d0 = curLen; ScalarType d0 = curLen;
ScalarType d1 = d0 + edgeLen; ScalarType d1 = d0 + edgeLen;
@ -843,10 +872,12 @@ static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius, bool c
} while(!ep.IsBorder() && ep.V() != startVertex); } while(!ep.IsBorder() && ep.V() != startVertex);
if(ep.V() != startVertex) if(ep.V() != startVertex)
{
ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0); ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0);
} }
} }
} }
}
/// \brief Sample all the border corner vertices /// \brief Sample all the border corner vertices

View File

@ -265,6 +265,8 @@ protected:
// QElapsedTimer timer; // QElapsedTimer timer;
// timer.start(); // timer.start();
(void)idx;
RequireCompactness(original); RequireCompactness(original);
RequirePerFaceFlags(original); RequirePerFaceFlags(original);
@ -295,9 +297,10 @@ protected:
} }
} }
const int manifoldSplits = vcg::tri::Clean<EdgeMeshType>::SplitSelectedVertexOnEdgeMesh(em); const int manifoldSplits = vcg::tri::Clean<EdgeMeshType>::SplitSelectedVertexOnEdgeMesh(em);
// std::cout << manifoldSplits << " non-manifold splits" << std::endl; (void)manifoldSplits;
#ifdef DEBUG_VORO #ifdef DEBUG_VORO
std::cout << manifoldSplits << " non-manifold splits" << std::endl;
io::ExporterOBJ<EdgeMeshType>::Save(em, QString("edgeMesh_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX); io::ExporterOBJ<EdgeMeshType>::Save(em, QString("edgeMesh_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX);
#endif #endif
@ -309,11 +312,13 @@ protected:
UpdateFlags<EdgeMeshType>::VertexClearV(em); UpdateFlags<EdgeMeshType>::VertexClearV(em);
Clean<EdgeMeshType>::SelectCreaseVertexOnEdgeMesh(em, vcg::math::ToRad(borderCreaseAngleDeg)); Clean<EdgeMeshType>::SelectCreaseVertexOnEdgeMesh(em, vcg::math::ToRad(borderCreaseAngleDeg));
const int splits = Clean<EdgeMeshType>::SplitSelectedVertexOnEdgeMesh(em); const int splits = Clean<EdgeMeshType>::SplitSelectedVertexOnEdgeMesh(em);
// std::cout << splits << " splits" << std::endl; (void)splits;
}
#ifdef DEBUG_VORO #ifdef DEBUG_VORO
std::cout << splits << " splits" << std::endl;
io::ExporterOBJ<EdgeMeshType>::Save(em, QString("edgeMesh_split_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX); io::ExporterOBJ<EdgeMeshType>::Save(em, QString("edgeMesh_split_%1.obj").arg(idx).toStdString().c_str(), io::Mask::IOM_EDGEINDEX);
#endif #endif
}
// Samples vector // Samples vector
std::vector<Coord> borderSamples; std::vector<Coord> borderSamples;
@ -321,7 +326,7 @@ protected:
// uniform edge sampling // uniform edge sampling
UpdateTopology<EdgeMeshType>::EdgeEdge(em); UpdateTopology<EdgeMeshType>::EdgeEdge(em);
SurfaceSampling<EdgeMeshType>::EdgeMeshUniform(em, ps, samplingRadius, true); SurfaceSampling<EdgeMeshType>::EdgeMeshUniform(em, ps, samplingRadius, false);
BuildMeshFromCoordVector(poissonEdgeMesh, borderSamples); BuildMeshFromCoordVector(poissonEdgeMesh, borderSamples);
UpdateBounding<Mesh>::Box(poissonEdgeMesh); UpdateBounding<Mesh>::Box(poissonEdgeMesh);
@ -538,10 +543,13 @@ protected:
if (!vit->IsD() && vit->IsB()) if (!vit->IsD() && vit->IsB())
borderPts.push_back(vit->cP()); borderPts.push_back(vit->cP());
} }
if (!borderPts.empty())
{
BuildMeshFromCoordVector(borderMesh,borderPts); BuildMeshFromCoordVector(borderMesh,borderPts);
borderMesh.bbox = m.bbox; borderMesh.bbox = m.bbox;
borderHG.Set(borderMesh.vert.begin(), borderMesh.vert.end(), bbox); borderHG.Set(borderMesh.vert.begin(), borderMesh.vert.end(), bbox);
} }
}
const ScalarType dist_upper_bound=samplingRadius*4; const ScalarType dist_upper_bound=samplingRadius*4;
VertexType * vp = NULL; VertexType * vp = NULL;