Improved the SplitNonManifoldVertex function. Now it is able to also move the split vertexes apart

This commit is contained in:
Paolo Cignoni 2012-07-27 12:57:34 +00:00
parent 3adc453f53
commit 500a478e14
1 changed files with 23 additions and 10 deletions

View File

@ -469,18 +469,24 @@ private:
/// Removal of faces that were incident on a non manifold edge.
static int SplitNonManifoldVertex(MeshType& m)
{
FaceIterator fi;
typedef std::pair<FacePointer,int> FaceInt;
// Given a mesh with FF adjacency
// it search for non manifold vertices and duplicate them.
// Duplicated vertices are moved apart according to the move threshold param.
// that is a percentage of the average vector from the non manifold vertex to the barycenter of the incident faces.
static int SplitNonManifoldVertex(MeshType& m, float moveThreshold)
{
assert(HasFFAdjacency(m));
typedef std::pair<FacePointer,int> FaceInt; // a face and the index of the vertex that we have to change
//
std::vector<std::pair<VertexPointer, std::vector<FaceInt> > >ToSplitVec;
SelectionStack<MeshType> ss(m);
ss.push();
CountNonManifoldVertexFF(m,true);
UpdateFlags<MeshType>::VertexClearV(m);
for (fi = m.face.begin(); fi != m.face.end(); ++fi) if (!fi->IsD())
for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) if (!fi->IsD())
{
for(int i=0;i<3;i++)
if((*fi).V(i)->IsS() && !(*fi).V(i)->IsV())
@ -513,11 +519,16 @@ private:
VertexPointer np=ToSplitVec[i].first;
pu.Update(np);
firstVp->ImportData(*np);
// loop on the face to be changed, and also compute the movement vector;
Point3f delta(0,0,0);
for(size_t j=0;j<ToSplitVec[i].second.size();++j)
{
FaceInt ff=ToSplitVec[i].second[j];
ff.first->V(ff.second)=&*firstVp;
delta+=Barycenter(*(ff.first))-np->cP();
}
delta /= ToSplitVec[i].second.size();
firstVp->P() = firstVp->P() + delta * moveThreshold;
firstVp++;
}
@ -1512,7 +1523,7 @@ private:
for(fib=inBox.begin();fib!=inBox.end();++fib)
{
if(!(*fib)->IsUserBit(referredBit) && (*fib != &*fi) )
if(TestIntersection(&*fi,*fib)){
if(TestFaceFaceIntersection(&*fi,*fib)){
ret.push_back(*fib);
if(!Intersected) {
ret.push_back(&*fi);
@ -1598,21 +1609,23 @@ private:
/**
This function test if two face intersect.
We assume that the two faces are different.
This function test if two triangular faces of a mesh intersect.
It assumes that the faces (as storage) are different (e.g different address)
If the two faces are different but coincident (same set of vertexes) return true.
if the faces share an edge no test is done.
if the faces share only a vertex, the opposite edge is tested against the face
*/
static bool TestIntersection(FaceType *f0,FaceType *f1)
static bool TestFaceFaceIntersection(FaceType *f0,FaceType *f1)
{
assert(f0!=f1);
int sv = face::CountSharedVertex(f0,f1);
if(sv==3) return true;
if(sv==0) return (vcg::IntersectionTriangleTriangle<FaceType>((*f0),(*f1)));
// if the faces share only a vertex, the opposite edge is tested against the face
if(sv==1)
{
int i0,i1; ScalarType a,b;
face::SharedVertex(f0,f1,i0,i1);
face::FindSharedVertex(f0,f1,i0,i1);
if(vcg::IntersectionSegmentTriangle(Segment3<ScalarType>((*f0).V1(i0)->P(),(*f0).V2(i0)->P()), *f1, a, b) ) return true;
if(vcg::IntersectionSegmentTriangle(Segment3<ScalarType>((*f1).V1(i1)->P(),(*f1).V2(i1)->P()), *f0, a, b) ) return true;
}