24 #ifndef __VCGLIB_CLEAN 
   25 #define __VCGLIB_CLEAN 
   27 #include <unordered_set> 
   30 #include <vcg/complex/complex.h> 
   31 #include <vcg/complex/algorithms/closest.h> 
   32 #include <vcg/space/index/grid_static_ptr.h> 
   33 #include <vcg/space/index/spatial_hashing.h> 
   34 #include <vcg/complex/algorithms/update/normal.h> 
   35 #include <vcg/space/triangle3.h> 
   36 #include <vcg/complex/append.h> 
   41 template <
class ConnectedEdgeMeshType>
 
   45     typedef ConnectedEdgeMeshType MeshType;
 
   46     typedef typename MeshType::VertexType     VertexType;
 
   47     typedef typename MeshType::VertexPointer  VertexPointer;
 
   48     typedef typename MeshType::VertexIterator VertexIterator;
 
   49     typedef typename MeshType::ScalarType     ScalarType;
 
   50     typedef typename MeshType::EdgeType       EdgeType;
 
   51     typedef typename MeshType::EdgePointer    EdgePointer;
 
   52     typedef typename MeshType::EdgeIterator   EdgeIterator;
 
   53     typedef typename MeshType::ConstEdgeIterator   ConstEdgeIterator;
 
   54     typedef typename MeshType::EdgeContainer  EdgeContainer;
 
   59         EdgePointer ep = se.top();
 
   61         for(
int i = 0; i < 2; ++i)
 
   63             edge::VEIterator<EdgeType> vei(ep->V(i));
 
   66                 if (!tri::IsMarked(*mp, vei.E()))
 
   68                     tri::Mark(*mp, vei.E());
 
   76     void start(MeshType &m, EdgePointer e)
 
   78         tri::RequirePerEdgeMark(m);
 
   94     EdgePointer operator *()
 
   99     std::stack<EdgePointer> se;
 
  103 template <
class ConnectedMeshType>
 
  107     typedef ConnectedMeshType MeshType;
 
  108     typedef typename MeshType::VertexType     VertexType;
 
  109     typedef typename MeshType::VertexPointer  VertexPointer;
 
  110     typedef typename MeshType::VertexIterator VertexIterator;
 
  111     typedef typename MeshType::ScalarType     ScalarType;
 
  112     typedef typename MeshType::FaceType       FaceType;
 
  113     typedef typename MeshType::FacePointer    FacePointer;
 
  114     typedef typename MeshType::FaceIterator   FaceIterator;
 
  115     typedef typename MeshType::ConstFaceIterator   ConstFaceIterator;
 
  116     typedef typename MeshType::FaceContainer  FaceContainer;
 
  121         FacePointer fpt=sf.top();
 
  123         for(
int j=0; j<fpt->VN(); ++j)
 
  126                 FacePointer l=fpt->FFp(j);
 
  127                 if( !tri::IsMarked(*mp,l) )
 
  135     void start(MeshType &m, FacePointer p)
 
  137         tri::RequirePerFaceMark(m);
 
  139         while(!sf.empty()) sf.pop();
 
  149     FacePointer operator *()
 
  154     std::stack<FacePointer> sf;
 
  163 template <
class CleanMeshType>
 
  168     typedef CleanMeshType MeshType;
 
  169     typedef typename MeshType::VertexType           VertexType;
 
  170     typedef typename MeshType::VertexPointer        VertexPointer;
 
  171     typedef typename MeshType::ConstVertexPointer   ConstVertexPointer;
 
  172     typedef typename MeshType::VertexIterator       VertexIterator;
 
  173     typedef typename MeshType::ConstVertexIterator  ConstVertexIterator;
 
  174     typedef typename MeshType::EdgeIterator         EdgeIterator;
 
  175     typedef typename MeshType::EdgePointer          EdgePointer;
 
  176     typedef typename MeshType::CoordType            CoordType;
 
  177     typedef typename MeshType::ScalarType           ScalarType;
 
  178     typedef typename MeshType::FaceType             FaceType;
 
  179     typedef typename MeshType::FacePointer          FacePointer;
 
  180     typedef typename MeshType::FaceIterator         FaceIterator;
 
  181     typedef typename MeshType::ConstFaceIterator    ConstFaceIterator;
 
  182     typedef typename MeshType::FaceContainer        FaceContainer;
 
  183     typedef typename MeshType::TetraType            TetraType;
 
  184     typedef typename MeshType::TetraPointer         TetraPointer;
 
  185     typedef typename MeshType::TetraIterator        TetraIterator;
 
  186     typedef typename MeshType::ConstTetraIterator   ConstTetraIterator;
 
  190     typedef GridStaticPtr<FaceType, ScalarType > TriMeshGrid;
 
  195         inline bool operator()(VertexPointer 
const &a, VertexPointer 
const &b)
 
  197             return ((*a).cP() == (*b).cP()) ? (a<b): ((*a).cP() < (*b).cP());
 
  208         if(m.vert.size()==0 || m.vn==0) 
return 0;
 
  210         std::map<VertexPointer, VertexPointer> mp;
 
  215         size_t num_vert = m.vert.size();
 
  216         std::vector<VertexPointer> perm(num_vert);
 
  217         for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi, ++k)
 
  222         std::sort(perm.begin(),perm.end(),c_obj);
 
  226         mp[perm[i]] = perm[j];
 
  230             if( (! (*perm[i]).IsD()) &&
 
  231                 (! (*perm[j]).IsD()) &&
 
  232                 (*perm[i]).P() == (*perm[j]).cP() )
 
  234                 VertexPointer t = perm[i];
 
  235                 mp[perm[i]] = perm[j];
 
  247         for(FaceIterator fi = m.face.begin(); fi!=m.face.end(); ++fi)
 
  249                 for(k = 0; k < (*fi).VN(); ++k)
 
  250                     if( mp.find( (
typename MeshType::VertexPointer)(*fi).V(k) ) != mp.end() )
 
  252                         (*fi).V(k) = &*mp[ (*fi).V(k) ];
 
  256         for(EdgeIterator ei = m.edge.begin(); ei!=m.edge.end(); ++ei)
 
  258                 for(k = 0; k < 2; ++k)
 
  259                     if( mp.find( (
typename MeshType::VertexPointer)(*ei).V(k) ) != mp.end() )
 
  261                         (*ei).V(k) = &*mp[ (*ei).V(k) ];
 
  264         for (TetraIterator ti = m.tetra.begin(); ti != m.tetra.end(); ++ti)
 
  266                 for (k = 0; k < 4; ++k)
 
  267                     if (mp.find((
typename MeshType::VertexPointer)(*ti).V(k)) != mp.end())
 
  268                         (*ti).V(k) = &*mp[ (*ti).V(k) ];
 
  271         if(RemoveDegenerateFlag && m.en>0) {
 
  272             RemoveDegenerateEdge(m);
 
  282         SortedPair(
unsigned int v0, 
unsigned int v1, EdgePointer _fp)
 
  286             if(v[0]>v[1]) std::swap(v[0],v[1]);
 
  290             return (v[1]!=p.v[1])?(v[1]<p.v[1]):
 
  295             if( (v[0]==s.v[0]) && (v[1]==s.v[1]) ) 
return true;
 
  306         SortedTriple(
unsigned int v0, 
unsigned int v1, 
unsigned int v2,FacePointer _fp)
 
  308             v[0]=v0;v[1]=v1;v[2]=v2;
 
  314             return (v[2]!=p.v[2])?(v[2]<p.v[2]):
 
  315                 (v[1]!=p.v[1])?(v[1]<p.v[1]):
 
  320             if( (v[0]==s.v[0]) && (v[1]==s.v[1]) && (v[2]==s.v[2]) ) 
return true;
 
  336         std::vector<SortedTriple> fvec;
 
  337         for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
 
  341                                                 tri::Index(m,(*fi).V(1)),
 
  342                                                 tri::Index(m,(*fi).V(2)),
 
  345         std::sort(fvec.begin(),fvec.end());
 
  347         for(
int i=0;i<int(fvec.size())-1;++i)
 
  349             if(fvec[i]==fvec[i+1])
 
  365         if (m.en==0) 
return 0;
 
  366         std::vector<SortedPair> eVec;
 
  367         for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei)
 
  370                 eVec.push_back(
SortedPair(  tri::Index(m,(*ei).V(0)), tri::Index(m,(*ei).V(1)), &*ei));
 
  372         std::sort(eVec.begin(),eVec.end());
 
  374         for(
int i=0;i<int(eVec.size())-1;++i)
 
  376             if(eVec[i]==eVec[i+1])
 
  385     static int CountUnreferencedVertex( MeshType& m)
 
  398         tri::RequirePerVertexFlags(m);
 
  400         std::vector<bool> referredVec(m.vert.size(),
false);
 
  403         for(
auto fi = m.face.begin(); fi != m.face.end(); ++fi)
 
  405                 for(
auto j=0; j < (*fi).VN(); ++j)
 
  406                     referredVec[tri::Index(m, (*fi).V(j))]=
true;
 
  408         for(
auto ei=m.edge.begin();ei!=m.edge.end();++ei)
 
  410                 referredVec[tri::Index(m, (*ei).V(0))]=
true;
 
  411                 referredVec[tri::Index(m, (*ei).V(1))]=
true;
 
  414         for(
auto ti=m.tetra.begin(); ti!=m.tetra.end();++ti)
 
  416                 referredVec[tri::Index(m, (*ti).V(0))]=
true;
 
  417                 referredVec[tri::Index(m, (*ti).V(1))]=
true;
 
  418                 referredVec[tri::Index(m, (*ti).V(2))]=
true;
 
  419                 referredVec[tri::Index(m, (*ti).V(3))]=
true;
 
  423         if(!DeleteVertexFlag)
 
  424             return std::count(referredVec.begin(),referredVec.end(),
false);
 
  426         for(
auto vi=m.vert.begin();vi!=m.vert.end();++vi)
 
  427             if( (!(*vi).IsD()) && (!referredVec[tri::Index(m,*vi)]) )
 
  444         for(vi=m.vert.begin(); vi!=m.vert.end();++vi)
 
  445             if(math::IsNAN( (*vi).P()[0]) ||
 
  446                math::IsNAN( (*vi).P()[1]) ||
 
  447                math::IsNAN( (*vi).P()[2]) )
 
  456         for(fi=m.face.begin(); fi!=m.face.end();++fi)
 
  458                 if( (*fi).V(0)->IsD() ||
 
  481         for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
 
  484                 if((*fi).V(0) == (*fi).V(1) ||
 
  485                    (*fi).V(0) == (*fi).V(2) ||
 
  486                    (*fi).V(1) == (*fi).V(2) )
 
  495     static int RemoveDegenerateEdge(MeshType& m)
 
  499         for(EdgeIterator ei=m.edge.begin(); ei!=m.edge.end();++ei)
 
  502                 if((*ei).V(0) == (*ei).V(1) )
 
  511     static int RemoveNonManifoldVertex(MeshType& m)
 
  515         int count_removed = 0;
 
  516         for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
 
  517             if(!(*fi).IsD() && (*fi).IsS())
 
  519         for(VertexIterator vi=m.vert.begin(); vi!=m.vert.end();++vi)
 
  520             if(!(*vi).IsD() && (*vi).IsS()) {
 
  524         return count_removed;
 
  528     static int SplitSelectedVertexOnEdgeMesh(MeshType& m)
 
  530         tri::RequireCompactness(m);
 
  533         std::unordered_map<size_t,size_t> refCount; 
 
  534         size_t countSplit = 0;
 
  535         for (
size_t i=0; i<m.edge.size(); ++i)
 
  537             for (
int j=0; j<2; ++j)
 
  539                 const VertexPointer vp = m.edge[i].V(j);
 
  542                     const size_t refs = ++refCount[Index(m, m.edge[i].V(j))];
 
  553             for (
size_t i=0; i<m.edge.size(); ++i)
 
  555                 for (
int j=0; j<2; ++j)
 
  557                     const VertexPointer vp = m.edge[i].V(j);
 
  558                     const size_t vIdx = Index(m, vp);
 
  561                         if (--refCount[vIdx] > 0)
 
  563                             newVertIt->ImportData(*vp);
 
  564                             m.edge[i].V(j) = &*(newVertIt++);
 
  570         return int(countSplit);
 
  574     static void SelectNonManifoldVertexOnEdgeMesh(MeshType &m)
 
  576         tri::RequireCompactness(m);
 
  578         std::vector<int> cnt(m.vn,0);
 
  580         for(
size_t i=0;i<m.edge.size();++i)
 
  582             cnt[tri::Index(m,m.edge[i].V(0))]++;
 
  583             cnt[tri::Index(m,m.edge[i].V(1))]++;
 
  585         for(
size_t i=0;i<m.vert.size();++i)
 
  586             if(cnt[i]>2) m.vert[i].SetS();
 
  589     static void SelectCreaseVertexOnEdgeMesh(MeshType &m, ScalarType AngleRadThr)
 
  591         tri::RequireCompactness(m);
 
  592         tri::RequireVEAdjacency(m);
 
  593         tri::UpdateTopology<MeshType>::VertexEdge(m);
 
  595         for(
size_t i=0;i<m.vert.size();++i)
 
  597             std::vector<VertexPointer> VVStarVec;
 
  598             edge::VVStarVE(&(m.vert[i]),VVStarVec);
 
  599             if(VVStarVec.size()==2)
 
  601                 CoordType v0 = m.vert[i].P() - VVStarVec[0]->P();
 
  602                 CoordType v1 = m.vert[i].P() - VVStarVec[1]->P();
 
  603                 float angle = M_PI-vcg::Angle(v0,v1);
 
  604                 if(angle > AngleRadThr) m.vert[i].SetS();
 
  619         RequireFFAdjacency(m);
 
  620         typedef std::pair<FacePointer,int> FaceInt; 
 
  622         std::vector<std::pair<VertexPointer, std::vector<FaceInt> > >ToSplitVec;
 
  628         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD())
 
  630             for (
int i=0; i<fi->VN(); i++)
 
  631                 if ((*fi).V(i)->IsS() && !(*fi).V(i)->IsV())
 
  634                     face::Pos<FaceType> startPos(&*fi,i);
 
  635                     face::Pos<FaceType> curPos = startPos;
 
  636                     std::set<FaceInt> faceSet;
 
  639                         faceSet.insert(std::make_pair(curPos.F(),curPos.VInd()));
 
  642                     } 
while (curPos != startPos);
 
  644                     ToSplitVec.push_back(make_pair((*fi).V(i),std::vector<FaceInt>()));
 
  646                     typename std::set<FaceInt>::const_iterator iii;
 
  648                     for(iii=faceSet.begin();iii!=faceSet.end();++iii)
 
  649                         ToSplitVec.back().second.push_back(*iii);
 
  656         for(
size_t i =0;i<ToSplitVec.size();++i)
 
  659             VertexPointer np=ToSplitVec[i].first;
 
  661             firstVp->ImportData(*np);
 
  663             CoordType delta(0,0,0);
 
  664             for(
size_t j=0;j<ToSplitVec[i].second.size();++j)
 
  666                 FaceInt ff=ToSplitVec[i].second[j];
 
  667                 ff.first->V(ff.second)=&*firstVp;
 
  668                 delta+=Barycenter(*(ff.first))-np->cP();
 
  670             delta /= ToSplitVec[i].second.size();
 
  671             firstVp->P() = firstVp->P() + delta * moveThreshold;
 
  675         return int(ToSplitVec.size());
 
  681         typedef typename MeshType::FacePointer FacePointer;
 
  682         typedef typename MeshType::FaceIterator FaceIterator;
 
  684         RequireFFAdjacency(m);
 
  690         tmpMesh.vert.EnableVFAdjacency();
 
  691         tmpMesh.face.EnableVFAdjacency();
 
  693         if (m.face.IsWedgeTexCoordEnabled())
 
  694             tmpMesh.face.EnableWedgeTexCoord();
 
  698         for(FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
  699             if( !(*fi).IsD() && !(*fi).IsV() && !(*fi).IsS())
 
  703                 std::deque<FacePointer> visitStack;
 
  704                 visitStack.push_back(&*fi);
 
  709                 while(!visitStack.empty())
 
  711                     FacePointer fp = visitStack.front();
 
  712                     visitStack.pop_front();
 
  714                     for(
int i=0;i<fp->VN();++i) {
 
  715                         FacePointer ff = fp->FFp(i);
 
  721                             visitStack.push_back(ff);
 
  732         for (
size_t i = 0; i < size_t(tmpMesh.VN()); ++i)
 
  734             VertexType & v = tmpMesh.vert[i];
 
  738                 std::vector<FacePointer> faceVec;
 
  739                 std::vector<int> idxVec;
 
  743                 CoordType delta(0, 0, 0);
 
  744                 for (
auto fp : faceVec)
 
  746                     delta += vcg::Barycenter(*fp) - v.cP();
 
  748                 delta /= faceVec.size();
 
  750                 v.P() += delta * moveThreshold;
 
  762         bool operator ()(FacePointer 
const& f1, FacePointer 
const& f2)
 const {
 
  763             return DoubleArea(*f1) < DoubleArea(*f2);
 
  772         std::vector<FacePointer> ToDelVec;
 
  774         for(fi=m.face.begin(); fi!=m.face.end();++fi)
 
  777                 if ((!IsManifold(*fi,0))||
 
  778                     (!IsManifold(*fi,1))||
 
  779                     (!IsManifold(*fi,2)))
 
  780                     ToDelVec.push_back(&*fi);
 
  785         for(
size_t i=0;i<ToDelVec.size();++i)
 
  787             if(!ToDelVec[i]->IsD())
 
  789                 FaceType &ff= *ToDelVec[i];
 
  790                 if ((!IsManifold(ff,0))||
 
  791                     (!IsManifold(ff,1))||
 
  795                         if(!face::IsBorder<FaceType>(ff,j))
 
  796                             vcg::face::FFDetach<FaceType>(ff,j);
 
  807     static int RemoveFaceOutOfRangeArea(MeshType& m, ScalarType MinAreaThr=0, ScalarType MaxAreaThr=(std::numeric_limits<ScalarType>::max)(), 
bool OnlyOnSelected=
false)
 
  812         for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi){
 
  814                 if(!OnlyOnSelected || (*fi).IsS())
 
  816                     const ScalarType doubleArea=DoubleArea<FaceType>(*fi);
 
  817                     if((doubleArea<=MinAreaThr) || (doubleArea>=MaxAreaThr) )
 
  827     static int RemoveZeroAreaFace(MeshType& m) { 
return RemoveFaceOutOfRangeArea(m,0);}
 
  836         typedef typename MeshType::FaceType F;
 
  837         tri::RequirePerFaceFlags(m);
 
  838         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD()) {
 
  839             unsigned int tmp = fi->Flags()&(F::FAUX0|F::FAUX1|F::FAUX2);
 
  840             if ( tmp != F::FAUX0 && tmp != F::FAUX1 && tmp != F::FAUX2) 
return false;
 
  846     static bool IsFaceFauxConsistent(MeshType &m)
 
  848         RequirePerFaceFlags(m);
 
  849         RequireFFAdjacency(m);
 
  850         for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) 
if(!(*fi).IsD())
 
  852             for(
int z=0;z<(*fi).VN();++z)
 
  854                 FacePointer fp = fi->FFp(z);
 
  856                 if(fi->IsF(z) != fp->IsF(zp)) 
return false;
 
  867         tri::RequirePerFaceFlags(m);
 
  868         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) {
 
  869             if ( !fi->IsD()  &&  fi->IsAnyF() ) 
return false;
 
  874     static bool IsBitPolygonal(
const MeshType &m){
 
  884         tri::RequirePerFaceFlags(m);
 
  885         typedef typename MeshType::FaceType F;
 
  886         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD()) {
 
  887             unsigned int tmp = fi->cFlags()&(F::FAUX0|F::FAUX1|F::FAUX2);
 
  888             if ( tmp!=F::FAUX0 && tmp!=F::FAUX1 && tmp!=F::FAUX2 && tmp!=0 ) 
return false;
 
  899         tri::RequirePerFaceFlags(m);
 
  900         typedef typename MeshType::FaceType F;
 
  902         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD()) {
 
  903             unsigned int tmp = fi->cFlags()&(F::FAUX0|F::FAUX1|F::FAUX2);
 
  904             if ( tmp==F::FAUX0 || tmp==F::FAUX1 || tmp==F::FAUX2) count++;
 
  914         tri::RequirePerFaceFlags(m);
 
  916         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD()) {
 
  917             if (!(fi->IsAnyF())) count++;
 
  928         tri::RequirePerFaceFlags(m);
 
  930         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD())  {
 
  931             if (fi->IsF(0)) count++;
 
  932             if (fi->IsF(1)) count++;
 
  933             if (fi->IsF(2)) count++;
 
  935         return m.fn - count/2;
 
  955         std::unordered_map<ConstVertexPointer, bool> vertVisited;
 
  956         for (ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
 
  957             if (!vi->IsD()) vertVisited[&(*vi)] = 
true;
 
  960         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
  962                 for(
int i=0;i<3;++i){
 
  963                     vertVisited[fi->V(i)] = 
false;
 
  970         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
  978                         vertVisited[fi->V0(i)] = 
true;
 
  979                         vertVisited[fi->V1(i)] = 
true;
 
  986         for (ConstVertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
 
  987             if (!vi->IsD() && !(vertVisited[&(*vi)])) countV++;
 
  989         return m.fn - countE/2 + countV ;
 
 1002         RequireFFAdjacency(m);
 
 1003         RequirePerFaceFlags(m);
 
 1005         for (ConstFaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1007                 for (
int k=0; k<3; k++)
 
 1008                     if( ( fi->IsF(k) != fi->cFFp(k)->IsF(fi->cFFi(k)) ) ||
 
 1022         MeshAssert<MeshType>::OnlyEdgeMesh(m);
 
 1023         RequireEEAdjacency(m);
 
 1028         int nonManifoldCnt=0;
 
 1029         SimpleTempData<typename MeshType::VertContainer, int > TD(m.vert,0);
 
 1033         for (ei = m.edge.begin(); ei != m.edge.end(); ++ei) 
if (!ei->IsD())
 
 1041         for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)  
if (!vi->IsD())
 
 1045                 if(SelectFlag) (*vi).SetS();
 
 1049         return nonManifoldCnt;
 
 1060         RequireFFAdjacency(m);
 
 1062         nmfBit[0]= FaceType::NewBitFlag();
 
 1063         nmfBit[1]= FaceType::NewBitFlag();
 
 1064         nmfBit[2]= FaceType::NewBitFlag();
 
 1075         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1079                 for(
int i=0;i<3;++i)
 
 1080                     if(!IsManifold(*fi,i))
 
 1082                         if(!(*fi).IsUserBit(nmfBit[i]))
 
 1087                                 (*fi).V0(i)->SetS();
 
 1088                                 (*fi).V1(i)->SetS();
 
 1091                             face::Pos<FaceType> nmf(&*fi,i);
 
 1094                                 if(SelectFlag) nmf.F()->SetS();
 
 1095                                 nmf.F()->SetUserBit(nmfBit[nmf.E()]);
 
 1098                             while(nmf.f != &*fi);
 
 1112         RequireFFAdjacency(m);
 
 1115         int nonManifoldCnt=0;
 
 1116         SimpleTempData<typename MeshType::VertContainer, int > TD(m.vert,0);
 
 1120         for (fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD())
 
 1122             for (
int k=0; k<fi->VN(); k++)
 
 1131         for (fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD())
 
 1133             for(
int i=0; i<fi->VN(); ++i)
 
 1134                 if (!IsManifold(*fi,i))
 
 1136                     (*fi).V0(i)->SetV();
 
 1137                     (*fi).V1(i)->SetV();
 
 1142         for (fi = m.face.begin(); fi != m.face.end(); ++fi) 
if (!fi->IsD())
 
 1144             for(
int i=0; i<fi->VN(); i++) 
if (!(*fi).V(i)->IsV())
 
 1147                 face::Pos<FaceType> pos(&(*fi),i);
 
 1149                 int starSizeFF = pos.NumberOfIncidentFaces();
 
 1151                 if (starSizeFF != TD[(*fi).V(i)])
 
 1159         return nonManifoldCnt;
 
 1170         int edgeNum=0,edgeBorderNum=0,edgeNonManifNum=0;
 
 1171         CountEdgeNum(m, edgeNum, edgeBorderNum,edgeNonManifNum);
 
 1172         return  (edgeBorderNum==0) && (edgeNonManifNum==0);
 
 1175     static void CountEdgeNum( MeshType & m, 
int &total_e, 
int &boundary_e, 
int &non_manif_e )
 
 1177         std::vector< typename tri::UpdateTopology<MeshType>::PEdge > edgeVec;
 
 1179         sort(edgeVec.begin(), edgeVec.end());       
 
 1184         size_t f_on_cur_edge =1;
 
 1185         for(
size_t i=0;i<edgeVec.size();++i)
 
 1187             if(( (i+1) == edgeVec.size()) ||  !(edgeVec[i] == edgeVec[i+1]))
 
 1190                 if(f_on_cur_edge==1)
 
 1205     static int CountHoles( MeshType & m)
 
 1207         UpdateFlags<MeshType>::FaceClearV(m);
 
 1209         for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi) 
if(!fi->IsD())
 
 1211             for(
int j=0;j<3;++j)
 
 1215                     face::Pos<FaceType> startPos(&*fi,j);
 
 1216                     face::Pos<FaceType> curPos=startPos;
 
 1222                     while(curPos!=startPos);
 
 1234     static int CountConnectedComponents(MeshType &m)
 
 1236         std::vector< std::pair<int,FacePointer> > CCV;
 
 1237         return ConnectedComponents(m,CCV);
 
 1240     static int ConnectedComponents(MeshType &m, std::vector< std::pair<int,FacePointer> > &CCV)
 
 1242         tri::RequireFFAdjacency(m);
 
 1244         tri::UpdateFlags<MeshType>::FaceClearV(m);
 
 1245         std::stack<FacePointer> sf;
 
 1246         FacePointer fpt=&*(m.face.begin());
 
 1247         for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
 
 1249             if(!((*fi).IsD()) && !(*fi).IsV())
 
 1252                 CCV.push_back(std::make_pair(0,&*fi));
 
 1259                     for(
int j=0; j<fpt->VN(); ++j)
 
 1263                             FacePointer l = fpt->FFp(j);
 
 1274         return int(CCV.size());
 
 1277     static int edgeMeshConnectedComponents(MeshType & poly,  std::vector<std::pair<int, typename MeshType::EdgePointer> > &eCC)
 
 1279         typedef typename MeshType::EdgePointer EdgePointer;
 
 1280         tri::UpdateTopology<MeshType>::VertexEdge(poly);
 
 1281         tri::UpdateFlags<MeshType>::EdgeClear(poly);
 
 1283         std::stack<EdgePointer> stack;
 
 1285         for (
auto ei = poly.edge.begin(); ei != poly.edge.end(); ++ei)
 
 1286             if (!ei->IsD() && !ei->IsV())
 
 1290                 std::pair<int, EdgePointer> cc(1, &*ei);
 
 1293                 while (!stack.empty())
 
 1295                     EdgePointer ep = stack.top();
 
 1298                     for (
int i = 0; i < 2; ++i)
 
 1300                         edge::VEIterator<typename MeshType::EdgeType> vei(ep->V(i));
 
 1303                             if (!vei.E()->IsV())
 
 1306                                 stack.push(vei.E());
 
 1315         return int(eCC.size());
 
 1318     static void ComputeValence( MeshType &m, 
typename MeshType::PerVertexIntHandle &h)
 
 1320         for(VertexIterator vi=m.vert.begin(); vi!= m.vert.end();++vi)
 
 1323         for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi)
 
 1326                 for(
int j=0;j<fi->VN();j++)
 
 1327                     ++h[tri::Index(m,fi->V(j))];
 
 1366     static int MeshGenus(
int nvert,
int nedges,
int nfaces, 
int numholes, 
int numcomponents)
 
 1368         return -((nvert + nfaces - nedges + numholes - 2 * numcomponents) / 2);
 
 1375         int boundary_e,total_e,nonmanif_e;
 
 1376         CountEdgeNum(m,total_e,boundary_e,nonmanif_e);
 
 1377         int numholes=CountHoles(m);
 
 1378         int numcomponents=CountConnectedComponents(m);
 
 1379         int G=
MeshGenus(nvert,total_e,nfaces,numholes,numcomponents);
 
 1396         RequireVFAdjacency(m);
 
 1402         for (vi = m.vert.begin(); vi != m.vert.end(); ++vi)
 
 1406                 face::Pos<FaceType> he((*vi).VFp(), &*vi);
 
 1407                 face::Pos<FaceType> ht = he;
 
 1423                 if ((n != 6)&&(!border && n != 4))
 
 1432             Semiregular = 
false;
 
 1436             Semiregular = 
false;
 
 1441     static bool IsCoherentlyOrientedMesh(MeshType &m)
 
 1443         RequireFFAdjacency(m);
 
 1444         MeshAssert<MeshType>::FFAdjacencyIsInitialized(m);
 
 1445         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1447                 for(
int i=0;i<3;++i)
 
 1454     static void OrientCoherentlyMesh(MeshType &m, 
bool &_IsOriented, 
bool &_IsOrientable)
 
 1456         RequireFFAdjacency(m);
 
 1457         MeshAssert<MeshType>::FFAdjacencyIsInitialized(m);
 
 1458         bool IsOrientable = 
true;
 
 1459         bool IsOriented = 
true;
 
 1461         UpdateFlags<MeshType>::FaceClearV(m);
 
 1462         std::stack<FacePointer> faces;
 
 1463         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1465             if (!fi->IsD() && !fi->IsV())
 
 1470                 while (!faces.empty())
 
 1472                     FacePointer fp = faces.top();
 
 1476                     for (
int j = 0; j < 3; j++)
 
 1478                         if (!
face::IsBorder(*fp,j) && face::IsManifold<FaceType>(*fp, j))
 
 1480                             FacePointer fpaux = fp->FFp(j);
 
 1481                             int iaux = fp->FFi(j);
 
 1482                             if (!CheckOrientation(*fpaux, iaux))
 
 1487                                     face::SwapEdge<FaceType,true>(*fpaux, iaux);
 
 1490                                     IsOrientable = 
false;
 
 1503             if (!IsOrientable)  
break;
 
 1505         _IsOriented = IsOriented;
 
 1506         _IsOrientable = IsOrientable;
 
 1513         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi) 
if(!(*fi).IsD())
 
 1514             if(!selected || (*fi).IsS())
 
 1516                 face::SwapEdge<FaceType,false>((*fi), 0);
 
 1517                 if (HasPerWedgeTexCoord(m))
 
 1518                     std::swap((*fi).WT(0),(*fi).WT(1));
 
 1528         if(m.vert.empty()) 
return false;
 
 1533         std::vector< VertexPointer > minVertVec;
 
 1534         std::vector< VertexPointer > maxVertVec;
 
 1537         std::vector< CoordType > dirVec;
 
 1538         dirVec.push_back(CoordType(1,0,0));
 
 1539         dirVec.push_back(CoordType(0,1,0));
 
 1540         dirVec.push_back(CoordType(0,0,1));
 
 1541         dirVec.push_back(CoordType( 1, 1,1));
 
 1542         dirVec.push_back(CoordType(-1, 1,1));
 
 1543         dirVec.push_back(CoordType(-1,-1,1));
 
 1544         dirVec.push_back(CoordType( 1,-1,1));
 
 1545         for(
size_t i=0;i<dirVec.size();++i)
 
 1547             Normalize(dirVec[i]);
 
 1548             minVertVec.push_back(&*m.vert.begin());
 
 1549             maxVertVec.push_back(&*m.vert.begin());
 
 1551         for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi) 
if(!(*vi).IsD())
 
 1553             for(
size_t i=0;i<dirVec.size();++i)
 
 1555                 if( (*vi).cP().dot(dirVec[i]) < minVertVec[i]->P().dot(dirVec[i])) minVertVec[i] = &*vi;
 
 1556                 if( (*vi).cP().dot(dirVec[i]) > maxVertVec[i]->P().dot(dirVec[i])) maxVertVec[i] = &*vi;
 
 1561         ScalarType angleThreshold = cos(math::ToRad(85.0));
 
 1562         for(
size_t i=0;i<dirVec.size();++i)
 
 1566             if(minVertVec[i]->N().dot(dirVec[i]) > angleThreshold ) voteCount++;
 
 1567             if(maxVertVec[i]->N().dot(dirVec[i]) < -angleThreshold ) voteCount++;
 
 1570         if(voteCount < 
int(dirVec.size())/2) 
return false;
 
 1578     static int RemoveFaceFoldByFlip(MeshType &m, 
float normalThresholdDeg=175, 
bool repeat=
true)
 
 1580         RequireFFAdjacency(m);
 
 1581         RequirePerVertexMark(m);
 
 1583         int count, total = 0;
 
 1590             ScalarType NormalThrRad = math::ToRad(normalThresholdDeg);
 
 1591             ScalarType eps = ScalarType(0.0001); 
 
 1593             for(FaceIterator fi=m.face.begin();fi!= m.face.end();++fi ) 
if(!(*fi).IsV())
 
 1595                 if( vcg::AngleN(NN,TriangleNormal(*(*fi).FFp(0)).Normalize()) > NormalThrRad &&
 
 1596                     vcg::AngleN(NN,TriangleNormal(*(*fi).FFp(1)).Normalize()) > NormalThrRad &&
 
 1597                     vcg::AngleN(NN,TriangleNormal(*(*fi).FFp(2)).Normalize()) > NormalThrRad )
 
 1602                     for(
int i=0;i<3;i++)
 
 1606                         bool ret = vcg::InterpolationParameters((*(*fi).FFp(i)),TriangleNormal(*(*fi).FFp(i)),p,L);
 
 1607                         if(ret && L[0]>eps && L[1]>eps && L[2]>eps)
 
 1609                             (*fi).FFp(i)->SetS();
 
 1610                             (*fi).FFp(i)->SetV();
 
 1612                             if(face::CheckFlipEdge<FaceType>( *fi, i ))  {
 
 1613                                 face::FlipEdge<FaceType>( *fi, i );
 
 1623         while( repeat && count );
 
 1628     static int RemoveTVertexByFlip(MeshType &m, 
float threshold=40, 
bool repeat=
true)
 
 1630         RequireFFAdjacency(m);
 
 1631         RequirePerVertexMark(m);
 
 1633         int count, total = 0;
 
 1641             for(
unsigned int index = 0 ; index < m.face.size(); ++index )
 
 1643                 FacePointer f = &(m.face[index]);    
float sides[3]; CoordType dummy;
 
 1644                 sides[0] = Distance(f->P(0), f->P(1));
 
 1645                 sides[1] = Distance(f->P(1), f->P(2));
 
 1646                 sides[2] = Distance(f->P(2), f->P(0));
 
 1648                 int i = std::find(sides, sides+3, std::max( std::max(sides[0],sides[1]), sides[2])) - (sides);
 
 1649                 if( tri::IsMarked(m,f->V2(i) )) 
continue;
 
 1651                 if( 
PSDist(f->P2(i),f->P(i),f->P1(i),dummy)*threshold <= sides[i] )
 
 1653                     tri::Mark(m,f->V2(i));
 
 1654                     if(face::CheckFlipEdge<FaceType>( *f, i ))  {
 
 1656                         FacePointer g = f->FFp(i); 
int k = f->FFi(i);
 
 1657                         Triangle3<ScalarType> t1(f->P(i), f->P1(i), f->P2(i)), t2(g->P(k), g->P1(k), g->P2(k)),
 
 1658                                 t3(f->P(i), g->P2(k), f->P2(i)), t4(g->P(k), f->P2(i), g->P2(k));
 
 1660                         if ( std::min( QualityFace(t1), QualityFace(t2) ) < std::min( QualityFace(t3), QualityFace(t4) ))
 
 1662                             face::FlipEdge<FaceType>( *f, i );
 
 1672         while( repeat && count );
 
 1676     static int RemoveTVertexByCollapse(MeshType &m, 
float threshold=40, 
bool repeat=
true)
 
 1678         RequirePerVertexMark(m);
 
 1680         int count, total = 0;
 
 1687             for(
unsigned int index = 0 ; index < m.face.size(); ++index )
 
 1689                 FacePointer f = &(m.face[index]);
 
 1693                 sides[0] = Distance(f->P(0), f->P(1));
 
 1694                 sides[1] = Distance(f->P(1), f->P(2));
 
 1695                 sides[2] = Distance(f->P(2), f->P(0));
 
 1696                 int i = std::find(sides, sides+3, std::max( std::max(sides[0],sides[1]), sides[2])) - (sides);
 
 1697                 if( tri::IsMarked(m,f->V2(i) )) 
continue;
 
 1699                 if( 
PSDist(f->P2(i),f->P(i),f->P1(i),dummy)*threshold <= sides[i] )
 
 1701                     tri::Mark(m,f->V2(i));
 
 1703                     int j = Distance(dummy,f->P(i))<Distance(dummy,f->P1(i))?i:(i+1)%3;
 
 1704                     f->P2(i) = f->P(j);  tri::Mark(m,f->V(j));
 
 1714         while( repeat && count );
 
 1719     static bool SelfIntersections(MeshType &m, std::vector<FaceType*> &ret)
 
 1721         RequirePerFaceMark(m);
 
 1723         int referredBit = FaceType::NewBitFlag();
 
 1724         tri::UpdateFlags<MeshType>::FaceClear(m,referredBit);
 
 1727         gM.Set(m.face.begin(),m.face.end());
 
 1729         for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) 
if(!(*fi).IsD())
 
 1731             (*fi).SetUserBit(referredBit);
 
 1732             Box3< ScalarType> bbox;
 
 1733             (*fi).GetBBox(bbox);
 
 1734             std::vector<FaceType*> inBox;
 
 1735             vcg::tri::GetInBoxFace(m, gM, bbox,inBox);
 
 1736             bool Intersected=
false;
 
 1737             typename std::vector<FaceType*>::iterator fib;
 
 1738             for(fib=inBox.begin();fib!=inBox.end();++fib)
 
 1740                 if(!(*fib)->IsUserBit(referredBit) && (*fib != &*fi) )
 
 1742                         ret.push_back(*fib);
 
 1744                             ret.push_back(&*fi);
 
 1752         FaceType::DeleteBitFlag(referredBit);
 
 1753         return (ret.size()>0);
 
 1761         int DeletedVertNum=0;
 
 1762         for (VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
 
 1763             if((*vi).IsD()) DeletedVertNum++;
 
 1765         int DeletedEdgeNum=0;
 
 1766         for (EdgeIterator ei = m.edge.begin(); ei != m.edge.end(); ++ei)
 
 1767             if((*ei).IsD()) DeletedEdgeNum++;
 
 1769         int DeletedFaceNum=0;
 
 1770         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1771             if((*fi).IsD()) DeletedFaceNum++;
 
 1773         if(
size_t(m.vn+DeletedVertNum) != m.vert.size()) 
return false;
 
 1774         if(
size_t(m.en+DeletedEdgeNum) != m.edge.size()) 
return false;
 
 1775         if(
size_t(m.fn+DeletedFaceNum) != m.face.size()) 
return false;
 
 1786         RequireFFAdjacency(m);
 
 1788         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1791                 for(
int i=0;i<3;++i)
 
 1792                     if(!FFCorrectness(*fi, i)) 
return false;
 
 1802         tri::RequirePerFaceWedgeTexCoord(m);
 
 1804         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1806             { FaceType &f=(*fi);
 
 1807                 if( ! ( (f.WT(0).N() == f.WT(1).N()) && (f.WT(0).N() == (*fi).WT(2).N()) )  )
 
 1810                 if((*fi).WT(0).N() <0) 
return false; 
 
 1820         tri::RequirePerFaceWedgeTexCoord(m);
 
 1822         for (FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
 
 1825                 if( (*fi).WT(0).P() == (*fi).WT(1).P() && (*fi).WT(0).P() == (*fi).WT(2).P() ) 
return false;
 
 1841         if(sv==3) 
return true;
 
 1842         if(sv==0) 
return (vcg::IntersectionTriangleTriangle<FaceType>((*f0),(*f1)));
 
 1848             int i0,i1; ScalarType a,b;
 
 1850             CoordType shP = f0->V(i0)->P()*0.5;
 
 1851             if(vcg::IntersectionSegmentTriangle(Segment3<ScalarType>((*f0).V1(i0)->P()*0.5+shP,(*f0).V2(i0)->P()*0.5+shP), *f1, a, b) )
 
 1854                 if(a+b>=1 || a<=EPSIL || b<=EPSIL ) 
return false;
 
 1857             if(vcg::IntersectionSegmentTriangle(Segment3<ScalarType>((*f1).V1(i1)->P()*0.5+shP,(*f1).V2(i1)->P()*0.5+shP), *f0, a, b) )
 
 1860                 if(a+b>=1 || a<=EPSIL || b<=EPSIL ) 
return false;
 
 1876         mergedCnt = ClusterVertex(m,radius);
 
 1881     static int ClusterVertex(MeshType &m, 
const ScalarType radius)
 
 1883         if(m.vn==0) 
return 0;
 
 1886         typedef vcg::SpatialHashTable<VertexType, ScalarType> SampleSHT;
 
 1888         tri::EmptyTMark<MeshType> markerFunctor;
 
 1889         std::vector<VertexType*> closests;
 
 1891         sht.Set(m.vert.begin(), m.vert.end());
 
 1893         for(VertexIterator viv = m.vert.begin(); viv!= m.vert.end(); ++viv)
 
 1894             if(!(*viv).IsD() && !(*viv).IsV())
 
 1899                 GridGetInBox(sht, markerFunctor, bb, closests);
 
 1901                 for(
size_t i=0; i<closests.size(); ++i)
 
 1903                     ScalarType dist = Distance(p,closests[i]->cP());
 
 1904                     if(dist < radius && !closests[i]->IsV())
 
 1908                         closests[i]->SetV();
 
 1917     static std::pair<int,int>  RemoveSmallConnectedComponentsSize(MeshType &m, 
int maxCCSize)
 
 1919         std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
 
 1920         int TotalCC=ConnectedComponents(m, CCV);
 
 1923         ConnectedComponentIterator<MeshType> ci;
 
 1924         for(
unsigned int i=0;i<CCV.size();++i)
 
 1926             std::vector<typename MeshType::FacePointer> FPV;
 
 1927             if(CCV[i].first<maxCCSize)
 
 1930                 for(ci.start(m,CCV[i].second);!ci.completed();++ci)
 
 1933                 typename std::vector<typename MeshType::FacePointer>::iterator fpvi;
 
 1934                 for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi)
 
 1938         return std::make_pair(TotalCC,DeletedCC);
 
 1946         std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
 
 1947         int TotalCC=ConnectedComponents(m, CCV);
 
 1950         for(
unsigned int i=0;i<CCV.size();++i)
 
 1953             std::vector<typename MeshType::FacePointer> FPV;
 
 1954             for(ci.start(m,CCV[i].second);!ci.completed();++ci)
 
 1957                 bb.
Add((*ci)->P(0));
 
 1958                 bb.
Add((*ci)->P(1));
 
 1959                 bb.
Add((*ci)->P(2));
 
 1961             if(bb.
Diag()<maxDiameter)
 
 1964                 typename std::vector<typename MeshType::FacePointer>::iterator fpvi;
 
 1965                 for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi)
 
 1969         return std::make_pair(TotalCC,DeletedCC);
 
 1976         std::vector< std::pair<int, typename MeshType::FacePointer> > CCV;
 
 1977         int TotalCC=ConnectedComponents(m, CCV);
 
 1980         for(
unsigned int i=0;i<CCV.size();++i)
 
 1983             std::vector<typename MeshType::FacePointer> FPV;
 
 1984             for(ci.start(m,CCV[i].second);!ci.completed();++ci)
 
 1987                 bb.
Add((*ci)->P(0));
 
 1988                 bb.
Add((*ci)->P(1));
 
 1989                 bb.
Add((*ci)->P(2));
 
 1991             if(bb.
Diag()>minDiameter)
 
 1994                 typename std::vector<typename MeshType::FacePointer>::iterator fpvi;
 
 1995                 for(fpvi=FPV.begin(); fpvi!=FPV.end(); ++fpvi)
 
 1999         return std::make_pair(TotalCC,DeletedCC);
 
 2012         typedef std::unordered_set<VertexPointer> VertexSet;
 
 2013         tri::RequireVFAdjacency(m);
 
 2014         tri::RequirePerFaceNormal(m);
 
 2015         tri::RequirePerVertexNormal(m);
 
 2020         if (cosThreshold > 0)
 
 2023 #pragma omp parallel for schedule(dynamic, 10) 
 2024         for (
int i = 0; i < m.face.size(); i++)
 
 2026             VertexSet nearVertex;
 
 2027             std::vector<CoordType> pointVec;
 
 2028             FacePointer f = &m.face[i];
 
 2029             for (
int j = 0; j < 3; j++)
 
 2031                 std::vector<VertexPointer> temp;
 
 2032                 vcg::face::VVStarVF<FaceType>(f->V(j), temp);
 
 2033                 typename std::vector<VertexPointer>::iterator iter = temp.begin();
 
 2034                 for (; iter != temp.end(); iter++)
 
 2036                     if ((*iter) != f->V1(j) && (*iter) != f->V2(j))
 
 2038                         if (nearVertex.insert((*iter)).second)
 
 2039                             pointVec.push_back((*iter)->P());
 
 2042                 nearVertex.insert(f->V(j));
 
 2043                 pointVec.push_back(f->P(j));
 
 2046             if (pointVec.size() > 3)
 
 2048                 vcg::Plane3<ScalarType> plane;
 
 2049                 vcg::FitPlaneToPointSet(pointVec, plane);
 
 2051                 for (
auto  nvp :  nearVertex)
 
 2052                     avgDot += plane.Direction().dot(nvp->N());
 
 2053                 avgDot /= nearVertex.size();
 
 2054                 typename MeshType::VertexType::NormalType normal;
 
 2056                     normal = -plane.Direction();
 
 2058                     normal = plane.Direction();
 
 2059                 if (normal.dot(f->N()) < cosThreshold)
 
 2070         RequirePerFaceMark(m2);
 
 2071         RequireCompactness(m1);
 
 2072         RequireCompactness(m2);
 
 2077         gM.Set(m2.face.begin(),m2.face.end());
 
 2079         for(
auto fi=m1.face.begin();fi!=m1.face.end();++fi)
 
 2082             (*fi).GetBBox(bbox);
 
 2083             std::vector<FaceType*> inBox;
 
 2084             vcg::tri::GetInBoxFace(m2, gM, bbox,inBox);
 
 2085             for(
auto fib=inBox.begin(); fib!=inBox.end(); ++fib)
 
void Add(const Box3< BoxScalarType > &b)
Definition: box3.h:104
 
BoxScalarType Diag() const
Return the lenght of the diagonal of the box .
Definition: box3.h:240
 
Class to safely add and delete elements in a mesh.
Definition: allocate.h:97
 
static void CompactFaceVector(MeshType &m, PointerUpdater< FacePointer > &pu)
Compact face vector by removing deleted elements.
Definition: allocate.h:1231
 
static void DeleteFace(MeshType &m, FaceType &f)
Definition: allocate.h:923
 
static void CompactVertexVector(MeshType &m, PointerUpdater< VertexPointer > &pu)
Compact vector of vertices removing deleted elements. Deleted elements are put to the end of the vect...
Definition: allocate.h:1084
 
static void DeleteVertex(MeshType &m, VertexType &v)
Definition: allocate.h:935
 
static VertexIterator AddVertices(MeshType &m, size_t n, PointerUpdater< VertexPointer > &pu)
Add n vertices to the mesh. Function to add n vertices to the mesh. The elements are added always to ...
Definition: allocate.h:189
 
static void DeleteEdge(MeshType &m, EdgeType &e)
Definition: allocate.h:946
 
static void MeshCopy(MeshLeft &ml, ConstMeshRight &mr, bool selected=false, const bool adjFlag=false)
Copy the second mesh over the first one. The first mesh is destroyed. If requested only the selected ...
Definition: append.h:601
 
static void Mesh(MeshLeft &ml, ConstMeshRight &mr, const bool selected=false, const bool adjFlag=false)
Append the second mesh to the first one.
Definition: append.h:253
 
Class of static functions to clean//restore meshs.
Definition: clean.h:165
 
static int RemoveDegenerateFace(MeshType &m)
Definition: clean.h:477
 
static int RemoveDuplicateFace(MeshType &m)
Definition: clean.h:334
 
static void SelectFoldedFaceFromOneRingFaces(MeshType &m, ScalarType cosThreshold)
Definition: clean.h:2010
 
static bool FlipNormalOutside(MeshType &m)
Definition: clean.h:1526
 
static int RemoveDuplicateVertex(MeshType &m, bool RemoveDegenerateFlag=true)
Definition: clean.h:206
 
static bool IsSizeConsistent(MeshType &m)
Definition: clean.h:1759
 
static int SelectIntersectingFaces(MeshType &m1, MeshType &m2)
Definition: clean.h:2068
 
static bool IsBitTriQuadOnly(const MeshType &m)
Definition: clean.h:882
 
static bool IsBitTriOnly(const MeshType &m)
Definition: clean.h:865
 
static bool HasZeroTexCoordFace(MeshType &m)
Definition: clean.h:1818
 
static std::pair< int, int > RemoveSmallConnectedComponentsDiameter(MeshType &m, ScalarType maxDiameter)
Remove the connected components smaller than a given diameter.
Definition: clean.h:1944
 
static size_t SplitManifoldComponents(MeshType &m, const ScalarType moveThreshold=0)
This function expand current selection to cover the whole connected component.
Definition: clean.h:679
 
static bool IsBitQuadOnly(const MeshType &m)
Definition: clean.h:834
 
static int CountNonManifoldEdgeEE(MeshType &m, bool SelectFlag=false)
Definition: clean.h:1020
 
static int RemoveUnreferencedVertex(MeshType &m, bool DeleteVertexFlag=true)
Definition: clean.h:396
 
static int SplitNonManifoldVertex(MeshType &m, ScalarType moveThreshold)
Removal of faces that were incident on a non manifold edge.
Definition: clean.h:617
 
static int MeshGenus(int nvert, int nedges, int nfaces, int numholes, int numcomponents)
Definition: clean.h:1366
 
static int CountBitLargePolygons(const MeshType &m)
Definition: clean.h:949
 
static bool HasConsistentPerFaceFauxFlag(const MeshType &m)
Definition: clean.h:1000
 
static bool HasConsistentPerWedgeTexCoord(MeshType &m)
Definition: clean.h:1800
 
static std::pair< int, int > RemoveHugeConnectedComponentsDiameter(MeshType &m, ScalarType minDiameter)
Remove the connected components greater than a given diameter.
Definition: clean.h:1974
 
static bool TestFaceFaceIntersection(FaceType *f0, FaceType *f1)
Definition: clean.h:1838
 
static void FlipMesh(MeshType &m, bool selected=false)
Flip the orientation of the whole mesh flipping all the faces (by swapping the first two vertices)
Definition: clean.h:1511
 
static int CountBitQuads(const MeshType &m)
Definition: clean.h:897
 
static int RemoveDegenerateVertex(MeshType &m)
Definition: clean.h:439
 
static int CountBitPolygons(const MeshType &m)
Definition: clean.h:926
 
static bool IsWaterTight(MeshType &m)
Definition: clean.h:1168
 
static int CountBitTris(const MeshType &m)
Definition: clean.h:912
 
static int RemoveDuplicateEdge(MeshType &m)
Definition: clean.h:363
 
static void IsRegularMesh(MeshType &m, bool &Regular, bool &Semiregular)
Definition: clean.h:1394
 
static int CountNonManifoldEdgeFF(MeshType &m, bool SelectFlag=false)
Definition: clean.h:1058
 
static int RemoveNonManifoldFace(MeshType &m)
Removal of faces that were incident on a non manifold edge.
Definition: clean.h:768
 
static int MergeCloseVertex(MeshType &m, const ScalarType radius)
Definition: clean.h:1873
 
static int CountNonManifoldVertexFF(MeshType &m, bool selectVert=true, bool clearSelection=true)
Definition: clean.h:1110
 
static bool IsFFAdjacencyConsistent(MeshType &m)
Definition: clean.h:1784
 
A stack for saving and restoring selection.
Definition: selection.h:43
 
bool pop(bool orFlag=false, bool andFlag=false)
Definition: selection.h:99
 
Management, updating and computation of per-vertex and per-face flags (like border flags).
Definition: flag.h:44
 
static void NormalizePerVertex(ComputeMeshType &m)
Normalize the length of the vertex normals.
Definition: normal.h:239
 
static void PerVertexAngleWeighted(ComputeMeshType &m)
Calculates the vertex normal as an angle weighted average. It does not need or exploit current face n...
Definition: normal.h:124
 
static void PerFaceNormalized(ComputeMeshType &m)
Equivalent to PerFace() and NormalizePerFace()
Definition: normal.h:276
 
static void PerVertexNormalized(ComputeMeshType &m)
Equivalent to PerVertex() and NormalizePerVertex()
Definition: normal.h:269
 
static void Clear(MeshType &m)
This function clears the selection flag for all the elements of a mesh (vertices, edges,...
Definition: selection.h:271
 
static size_t VertexClear(MeshType &m)
This function clear the selection flag for all the vertices.
Definition: selection.h:237
 
static size_t FaceClear(MeshType &m)
This function clears the selection flag for all the faces.
Definition: selection.h:253
 
static size_t FaceFromVertexLoose(MeshType &m, bool preserveSelection=false)
Select all the faces with at least one selected vertex.
Definition: selection.h:456
 
Generation of per-vertex and per-face topological information.
Definition: topology.h:43
 
static void VertexFace(MeshType &m)
Update the Vertex-Face topological relation.
Definition: topology.h:467
 
static void FillEdgeVector(MeshType &m, std::vector< PEdge > &edgeVec, bool includeFauxEdge=true)
Definition: topology.h:200
 
static void FaceFace(MeshType &m)
Update the Face-Face topological relation by allowing to retrieve for each face what other faces shar...
Definition: topology.h:395
 
bool IsManifold(FaceType const &f, const int j)
Definition: topology.h:41
 
int CountSharedVertex(FaceType *f0, FaceType *f1)
Definition: topology.h:1273
 
bool IsBorder(FaceType const &f, const int j)
Definition: topology.h:55
 
bool CheckOrientation(FaceType &f, int z)
Definition: topology.h:380
 
bool FindSharedVertex(FaceType *f0, FaceType *f1, int &i, int &j)
Definition: topology.h:1291
 
void VFStarVF(typename FaceType::VertexType *vp, std::vector< FaceType * > &faceVec, std::vector< int > &indexes)
Compute the set of faces adjacent to a given vertex using VF adjacency.
Definition: topology.h:993
 
Definition: namespaces.dox:6
 
P3ScalarType PSDist(const Point3< P3ScalarType > &p, const Point3< P3ScalarType > &v1, const Point3< P3ScalarType > &v2, Point3< P3ScalarType > &q)
Point(p) Edge(v1-v2) dist, q is the point in v1-v2 with min dist.
Definition: point3.h:522