fixed uniform resampling of edge mesh

This commit is contained in:
Luigi Malomo 2015-11-05 23:35:44 +00:00
parent 0f05ee423d
commit 62b7955f22
1 changed files with 76 additions and 55 deletions

View File

@ -643,67 +643,88 @@ static void VertexUniform(MeshType & m, VertexSampler &ps, int sampleNum)
/// ///
static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius) static void EdgeMeshUniform(MeshType &m, VertexSampler &ps, float radius)
{ {
tri::RequireEEAdjacency(m); tri::RequireEEAdjacency(m);
tri::RequireCompactness(m); tri::RequireCompactness(m);
tri::UpdateTopology<MeshType>::EdgeEdge(m); tri::RequirePerEdgeFlags(m);
tri::UpdateFlags<MeshType>::EdgeClearV(m); tri::RequirePerVertexFlags(m);
tri::UpdateTopology<MeshType>::EdgeEdge(m);
tri::UpdateFlags<MeshType>::EdgeClearV(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; VertexPointer startVertex = 0;
do // first loop to search a boundary component. do // first loop to search a boundary component.
{ {
ep.NextE(); ep.NextE();
if(ep.IsBorder()) break; if (ep.IsBorder())
} while(startep!=ep); break;
if(!ep.IsBorder()) } while (startep != ep);
startVertex=ep.V(); if (!ep.IsBorder())
{
// it's a loop
startVertex = ep.V();
}
else
{
// to keep the uniform resampling order-independent
// start from the border with 'lowest' point
edge::Pos<EdgeType> altEp = ep;
do {
altEp.NextE();
} while (!altEp.IsBorder());
ScalarType totalLen=0; if (altEp.V()->cP() < ep.V()->cP())
ep.FlipV(); {
do // second loop to compute len of the chain. ep = altEp;
{ }
ep.E()->SetV(); }
totalLen+=Distance(ep.V()->P(),ep.VFlip()->P());
ep.NextE();
} while(!ep.IsBorder() && ep.V()!=startVertex);
ep.E()->SetV();
totalLen+=Distance(ep.V()->P(),ep.VFlip()->P());
// Third loop actually perform the sampling. ScalarType totalLen = 0;
int sampleNum = floor(totalLen / radius); ep.FlipV();
ScalarType sampleDist = totalLen/sampleNum; // second loop to compute length of the chain.
// printf("Found a chain of %f with %i samples every %f (%f)\n",totalLen,sampleNum,sampleDist,radius); do
{
ep.E()->SetV();
totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP());
ep.NextE();
} while (!ep.IsBorder() && ep.V() != startVertex);
ep.E()->SetV();
totalLen += Distance(ep.V()->cP(), ep.VFlip()->cP());
ScalarType curLen=0; // Third loop actually perform the sampling.
int sampleCnt=1; int sampleNum = floor(totalLen / radius);
ps.AddEdge(*(ep.E()),ep.VInd()==0?0.0:1.0); ScalarType sampleDist = totalLen / sampleNum;
ep.FlipV(); // printf("Found a chain of %f with %i samples every %f (%f)\n", totalLen, sampleNum, sampleDist, radius);
do
{
ScalarType edgeLen = Distance(ep.V()->P(),ep.VFlip()->P());
ScalarType d0 = curLen;
ScalarType d1 = d0+edgeLen;
while(d1>sampleCnt*sampleDist) ScalarType curLen = 0;
{ int sampleCnt = 1;
ScalarType off = (sampleCnt*sampleDist-d0) /edgeLen; ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0);
// printf("edgeLen %f off %f samplecnt %i\n",edgeLen,off,sampleCnt); do
ps.AddEdge(*(ep.E()),ep.VInd()==0?1.0-off:off); {
sampleCnt++; ep.NextE();
} assert(ep.E()->IsV());
curLen+=edgeLen; ScalarType edgeLen = Distance(ep.V()->cP(), ep.VFlip()->cP());
ep.NextE(); ScalarType d0 = curLen;
} while(!ep.IsBorder() && ep.V()!=startVertex); ScalarType d1 = d0 + edgeLen;
if(ep.V()!=startVertex) while (d1 > sampleCnt * sampleDist && sampleCnt < sampleNum)
ps.AddEdge(*(ep.E()),ep.VInd()==0?0.0:1.0); {
} ScalarType off = (sampleCnt * sampleDist - d0) / edgeLen;
} // printf("edgeLen %f off %f samplecnt %i\n", edgeLen, off, sampleCnt);
ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 1.0 - off : off);
sampleCnt++;
}
curLen += edgeLen;
} while(!ep.IsBorder() && ep.V() != startVertex);
if(ep.V() != startVertex)
ps.AddEdge(*(ep.E()), ep.VInd() == 0 ? 0.0 : 1.0);
}
}
} }