minor aestetical changes and added edge size checking to the IsSizeConsistent function

This commit is contained in:
Paolo Cignoni 2014-08-28 01:55:43 +00:00
parent 875a7d1aac
commit fdf0b5b2ec
1 changed files with 1070 additions and 1071 deletions

View File

@ -124,7 +124,6 @@ public:
typedef typename vcg::Box3<ScalarType> Box3Type; typedef typename vcg::Box3<ScalarType> Box3Type;
typedef GridStaticPtr<FaceType, ScalarType > TriMeshGrid; typedef GridStaticPtr<FaceType, ScalarType > TriMeshGrid;
typedef Point3<ScalarType> Point3x;
/* classe di confronto per l'algoritmo di eliminazione vertici duplicati*/ /* classe di confronto per l'algoritmo di eliminazione vertici duplicati*/
class RemoveDuplicateVert_Compare{ class RemoveDuplicateVert_Compare{
@ -137,8 +136,8 @@ public:
/** This function removes all duplicate vertices of the mesh by looking only at their spatial positions. /** This function removes all duplicate vertices of the mesh by looking only at their spatial positions.
Note that it does not update any topology relation that could be affected by this like the VT or TT relation. * Note that it does not update any topology relation that could be affected by this like the VT or TT relation.
the reason this function is usually performed BEFORE building any topology information. * the reason this function is usually performed BEFORE building any topology information.
*/ */
static int RemoveDuplicateVertex( MeshType & m, bool RemoveDegenerateFlag=true) // V1.0 static int RemoveDuplicateVertex( MeshType & m, bool RemoveDegenerateFlag=true) // V1.0
{ {
@ -263,9 +262,8 @@ public:
*/ */
static int RemoveDuplicateFace( MeshType & m) // V1.0 static int RemoveDuplicateFace( MeshType & m) // V1.0
{ {
FaceIterator fi;
std::vector<SortedTriple> fvec; std::vector<SortedTriple> fvec;
for(fi=m.face.begin();fi!=m.face.end();++fi) for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD()) if(!(*fi).IsD())
{ {
fvec.push_back(SortedTriple( tri::Index(m,(*fi).V(0)), fvec.push_back(SortedTriple( tri::Index(m,(*fi).V(0)),
@ -274,7 +272,6 @@ public:
&*fi)); &*fi));
} }
assert (size_t(m.fn) == fvec.size()); assert (size_t(m.fn) == fvec.size());
//for(int i=0;i<fvec.size();++i) qDebug("fvec[%i] = (%i %i %i)(%i)",i,fvec[i].v[0],fvec[i].v[1],fvec[i].v[2],tri::Index(m,fvec[i].fp));
std::sort(fvec.begin(),fvec.end()); std::sort(fvec.begin(),fvec.end());
int total=0; int total=0;
for(int i=0;i<int(fvec.size())-1;++i) for(int i=0;i<int(fvec.size())-1;++i)
@ -283,7 +280,6 @@ public:
{ {
total++; total++;
tri::Allocator<MeshType>::DeleteFace(m, *(fvec[i].fp) ); tri::Allocator<MeshType>::DeleteFace(m, *(fvec[i].fp) );
//qDebug("deleting face %i (pos in fvec %i)",tri::Index(m,fvec[i].fp) ,i);
} }
} }
return total; return total;
@ -296,8 +292,7 @@ public:
*/ */
static int RemoveDuplicateEdge( MeshType & m) // V1.0 static int RemoveDuplicateEdge( MeshType & m) // V1.0
{ {
//assert(m.fn == 0 && m.en >0); // just to be sure we are using an edge mesh... if (m.en==0) return 0;
if (m.en==0)return 0;
std::vector<SortedPair> eVec; std::vector<SortedPair> eVec;
for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
if(!(*ei).IsD()) if(!(*ei).IsD())
@ -319,6 +314,7 @@ public:
} }
return total; return total;
} }
static int CountUnreferencedVertex( MeshType& m) static int CountUnreferencedVertex( MeshType& m)
{ {
return RemoveUnreferencedVertex(m,false); return RemoveUnreferencedVertex(m,false);
@ -440,9 +436,7 @@ public:
static int RemoveNonManifoldVertex(MeshType& m) static int RemoveNonManifoldVertex(MeshType& m)
{ {
/*int count_vd = */
CountNonManifoldVertexFF(m,true); CountNonManifoldVertexFF(m,true);
/*int count_fd = */
tri::UpdateSelection<MeshType>::FaceFromVertexLoose(m); tri::UpdateSelection<MeshType>::FaceFromVertexLoose(m);
int count_removed = 0; int count_removed = 0;
FaceIterator fi; FaceIterator fi;
@ -560,7 +554,7 @@ public:
VertexIterator firstVp = tri::Allocator<MeshType>::AddVertices(m,ToSplitVec.size(),pu); VertexIterator firstVp = tri::Allocator<MeshType>::AddVertices(m,ToSplitVec.size(),pu);
for(size_t i =0;i<ToSplitVec.size();++i) for(size_t i =0;i<ToSplitVec.size();++i)
{ {
// qDebug("Splitting Vertex %i",ToSplitVec[i].first-&*m.vert.begin()); // qDebug("Splitting Vertex %i",ToSplitVec[i].first-&*m.vert.begin());
VertexPointer np=ToSplitVec[i].first; VertexPointer np=ToSplitVec[i].first;
pu.Update(np); pu.Update(np);
firstVp->ImportData(*np); firstVp->ImportData(*np);
@ -1021,7 +1015,7 @@ public:
vcg::face::Pos<FaceType> he; vcg::face::Pos<FaceType> he;
vcg::face::Pos<FaceType> hei; vcg::face::Pos<FaceType> hei;
std::vector< std::vector<Point3x> > holes; //indices of vertices std::vector< std::vector<CoordType> > holes; //indices of vertices
vcg::tri::UpdateFlags<MeshType>::VertexClearS(m); vcg::tri::UpdateFlags<MeshType>::VertexClearS(m);
@ -1036,7 +1030,7 @@ public:
if(face::IsBorder(*fi,j))//found an unvisited border edge if(face::IsBorder(*fi,j))//found an unvisited border edge
{ {
he.Set(&(*fi),j,fi->V(j)); //set the face-face iterator to the current face, edge and vertex he.Set(&(*fi),j,fi->V(j)); //set the face-face iterator to the current face, edge and vertex
std::vector<Point3x> hole; //start of a new hole std::vector<CoordType> hole; //start of a new hole
hole.push_back(fi->P(j)); // including the first vertex hole.push_back(fi->P(j)); // including the first vertex
numholev++; numholev++;
he.v->SetS(); //set the current vertex as selected he.v->SetS(); //set the current vertex as selected
@ -1045,11 +1039,11 @@ public:
while(fi->V(j) != he.v)//will we do not encounter the first boundary edge. while(fi->V(j) != he.v)//will we do not encounter the first boundary edge.
{ {
Point3x newpoint = he.v->P(); //select its vertex. CoordType newpoint = he.v->P(); //select its vertex.
if(he.v->IsS())//check if this vertex was selected already, because then we have an additional hole. if(he.v->IsS())//check if this vertex was selected already, because then we have an additional hole.
{ {
//cut and paste the additional hole. //cut and paste the additional hole.
std::vector<Point3x> hole2; std::vector<CoordType> hole2;
int index = static_cast<int>(find(hole.begin(),hole.end(),newpoint) int index = static_cast<int>(find(hole.begin(),hole.end(),newpoint)
- hole.begin()); - hole.begin());
for(unsigned int i=index; i<hole.size(); i++) for(unsigned int i=index; i<hole.size(); i++)
@ -1334,14 +1328,14 @@ public:
std::vector< VertexPointer > maxVertVec; std::vector< VertexPointer > maxVertVec;
// The set of directions to be choosen // The set of directions to be choosen
std::vector< Point3x > dirVec; std::vector< CoordType > dirVec;
dirVec.push_back(Point3x(1,0,0)); dirVec.push_back(CoordType(1,0,0));
dirVec.push_back(Point3x(0,1,0)); dirVec.push_back(CoordType(0,1,0));
dirVec.push_back(Point3x(0,0,1)); dirVec.push_back(CoordType(0,0,1));
dirVec.push_back(Point3x( 1, 1,1)); dirVec.push_back(CoordType( 1, 1,1));
dirVec.push_back(Point3x(-1, 1,1)); dirVec.push_back(CoordType(-1, 1,1));
dirVec.push_back(Point3x(-1,-1,1)); dirVec.push_back(CoordType(-1,-1,1));
dirVec.push_back(Point3x( 1,-1,1)); dirVec.push_back(CoordType( 1,-1,1));
for(size_t i=0;i<dirVec.size();++i) for(size_t i=0;i<dirVec.size();++i)
{ {
Normalize(dirVec[i]); Normalize(dirVec[i]);
@ -1361,12 +1355,12 @@ public:
ScalarType angleThreshold = cos(math::ToRad(85.0)); ScalarType angleThreshold = cos(math::ToRad(85.0));
for(size_t i=0;i<dirVec.size();++i) for(size_t i=0;i<dirVec.size();++i)
{ {
// qDebug("Min vert along (%f %f %f) is %f %f %f",dirVec[i][0],dirVec[i][1],dirVec[i][2],minVertVec[i]->P()[0],minVertVec[i]->P()[1],minVertVec[i]->P()[2]); // qDebug("Min vert along (%f %f %f) is %f %f %f",dirVec[i][0],dirVec[i][1],dirVec[i][2],minVertVec[i]->P()[0],minVertVec[i]->P()[1],minVertVec[i]->P()[2]);
// qDebug("Max vert along (%f %f %f) is %f %f %f",dirVec[i][0],dirVec[i][1],dirVec[i][2],maxVertVec[i]->P()[0],maxVertVec[i]->P()[1],maxVertVec[i]->P()[2]); // qDebug("Max vert along (%f %f %f) is %f %f %f",dirVec[i][0],dirVec[i][1],dirVec[i][2],maxVertVec[i]->P()[0],maxVertVec[i]->P()[1],maxVertVec[i]->P()[2]);
if(minVertVec[i]->N().dot(dirVec[i]) > angleThreshold ) voteCount++; if(minVertVec[i]->N().dot(dirVec[i]) > angleThreshold ) voteCount++;
if(maxVertVec[i]->N().dot(dirVec[i]) < -angleThreshold ) voteCount++; if(maxVertVec[i]->N().dot(dirVec[i]) < -angleThreshold ) voteCount++;
} }
// qDebug("votecount = %i",voteCount); // qDebug("votecount = %i",voteCount);
if(voteCount < int(dirVec.size())/2) return false; if(voteCount < int(dirVec.size())/2) return false;
FlipMesh(m); FlipMesh(m);
return true; return true;
@ -1558,15 +1552,20 @@ public:
*/ */
static bool IsSizeConsistent(MeshType &m) static bool IsSizeConsistent(MeshType &m)
{ {
int DeletedVertexNum=0; int DeletedVertNum=0;
for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
if((*vi).IsD()) DeletedVertexNum++; if((*vi).IsD()) DeletedVertNum++;
int DeletedEdgeNum=0;
for (EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
if((*ei).IsD()) DeletedEdgeNum++;
int DeletedFaceNum=0; int DeletedFaceNum=0;
for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
if((*fi).IsD()) DeletedFaceNum++; if((*fi).IsD()) DeletedFaceNum++;
if(size_t(m.vn+DeletedVertexNum) != m.vert.size()) return false; if(size_t(m.vn+DeletedVertNum) != m.vert.size()) return false;
if(size_t(m.en+DeletedEdgeNum) != m.edge.size()) return false;
if(size_t(m.fn+DeletedFaceNum) != m.face.size()) return false; if(size_t(m.fn+DeletedFaceNum) != m.face.size()) return false;
return true; return true;
@ -1589,7 +1588,7 @@ public:
return true; return true;
} }
/** /**
This function simply test that a mesh has some reasonable tex coord. This function simply test that a mesh has some reasonable tex coord.
*/ */
static bool HasConsistentPerWedgeTexCoord(MeshType &m) static bool HasConsistentPerWedgeTexCoord(MeshType &m)
@ -1663,7 +1662,7 @@ public:
/** /**
This function merge all the vertices that are closer than the given radius This function merge all the vertices that are closer than the given radius
*/ */
static int MergeCloseVertex(MeshType &m, const ScalarType radius) static int MergeCloseVertex(MeshType &m, const ScalarType radius)
@ -1711,8 +1710,8 @@ public:
} }
static std::pair<int,int> RemoveSmallConnectedComponentsSize(MeshType &m, int maxCCSize) static std::pair<int,int> RemoveSmallConnectedComponentsSize(MeshType &m, int maxCCSize)
{ {
std::vector< std::pair<int, typename MeshType::FacePointer> > CCV; std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
int TotalCC=ConnectedComponents(m, CCV); int TotalCC=ConnectedComponents(m, CCV);
int DeletedCC=0; int DeletedCC=0;
@ -1733,13 +1732,13 @@ static std::pair<int,int> RemoveSmallConnectedComponentsSize(MeshType &m, int m
} }
} }
return std::make_pair(TotalCC,DeletedCC); return std::make_pair(TotalCC,DeletedCC);
} }
/// Remove the connected components smaller than a given diameter /// Remove the connected components smaller than a given diameter
// it returns a pair with the number of connected components and the number of deleted ones. // it returns a pair with the number of connected components and the number of deleted ones.
static std::pair<int,int> RemoveSmallConnectedComponentsDiameter(MeshType &m, ScalarType maxDiameter) static std::pair<int,int> RemoveSmallConnectedComponentsDiameter(MeshType &m, ScalarType maxDiameter)
{ {
std::vector< std::pair<int, typename MeshType::FacePointer> > CCV; std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
int TotalCC=ConnectedComponents(m, CCV); int TotalCC=ConnectedComponents(m, CCV);
int DeletedCC=0; int DeletedCC=0;
@ -1764,12 +1763,12 @@ static std::pair<int,int> RemoveSmallConnectedComponentsDiameter(MeshType &m, Sc
} }
} }
return std::make_pair(TotalCC,DeletedCC); return std::make_pair(TotalCC,DeletedCC);
} }
/// Remove the connected components greater than a given diameter /// Remove the connected components greater than a given diameter
// it returns a pair with the number of connected components and the number of deleted ones. // it returns a pair with the number of connected components and the number of deleted ones.
static std::pair<int,int> RemoveHugeConnectedComponentsDiameter(MeshType &m, ScalarType minDiameter) static std::pair<int,int> RemoveHugeConnectedComponentsDiameter(MeshType &m, ScalarType minDiameter)
{ {
std::vector< std::pair<int, typename MeshType::FacePointer> > CCV; std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
int TotalCC=ConnectedComponents(m, CCV); int TotalCC=ConnectedComponents(m, CCV);
int DeletedCC=0; int DeletedCC=0;
@ -1794,11 +1793,11 @@ static std::pair<int,int> RemoveHugeConnectedComponentsDiameter(MeshType &m, Sca
} }
} }
return std::make_pair(TotalCC,DeletedCC); return std::make_pair(TotalCC,DeletedCC);
} }
}; // end class }; // end class
/*@}*/ /*@}*/
} //End Namespace Tri } //End Namespace Tri
} // End Namespace vcg } // End Namespace vcg
#endif #endif