diff --git a/vcg/complex/trimesh/hole.h b/vcg/complex/trimesh/hole.h index e8a8768b..71d4d963 100644 --- a/vcg/complex/trimesh/hole.h +++ b/vcg/complex/trimesh/hole.h @@ -24,6 +24,9 @@ History $Log: not supported by cvs2svn $ +Revision 1.17 2006/11/24 10:42:39 mariolatronico +Now compiles on gcc under linux. + Revision 1.16 2006/11/22 13:43:28 giec Code refactory and added minimum weight triangolation. @@ -83,82 +86,11 @@ First Non working Version #include #include #include +#include -#define FLT_MAX 3.402823466e+38F /* max float rappresentable */ -/* -Questa Classe serve per gestire la non duplicazione degli edge durante la chiusura -di un buco. -*/ namespace vcg { namespace tri { - - template - class HoleInfo - { - public: - HoleInfo(){} - HoleInfo(face::Pos const &pHole, int const pHoleSize, Box3 &pHoleBB) - { - p=pHole; - size=pHoleSize; - bb=pHoleBB; - } - - HoleInfo(face::Pos const &pHole, int const pHoleSize, Box3 &pHoleBB, int FI) - { - p=pHole; - size=pHoleSize; - bb=pHoleBB; - faceindex = FI; - } - - - typename face::Pos p; - int size; - Box3 bb; - int faceindex; - - void Refresh(MESH &m) - { - p.f = (typename MESH::FacePointer)(faceindex + &(*(m.face.begin()))); - } - - bool operator < (const HoleInfo & hh) const {return size < hh.size;} - bool operator > (const HoleInfo & hh) const {return size > hh.size;} - bool operator == (const HoleInfo & hh) const {return size == hh.size;} - bool operator != (const HoleInfo & hh) const {return size != hh.size;} - bool operator >= (const HoleInfo & hh) const {return size >= hh.size;} - bool operator <= (const HoleInfo & hh) const {return size <= hh.size;} - - typename MESH::ScalarType Perimeter() - { - typename MESH::ScalarType sum=0; - face::Pos ip = p; - do - { - sum+=Distance(ip.v->cP(),ip.VFlip()->cP()); - ip.NextB(); - } - while (ip != p); - return sum; - } - - }; - - //function prototype - template - int GetHoleInfo(MESH &m,bool Selected ,std::vector >& VHI); - - template - void triangulate(std::vector &m,int i, int j, std::vector< std::vector > vi, - std::vector > vv); - - template - void getBoundHole (face::Pos sp,std::vector >&ret); - - - /* Un ear e' identificato da due hedge pos. i vertici dell'ear sono @@ -169,7 +101,7 @@ namespace vcg { e che e1.FlipV() == e0; Situazioni ear non manifold, e degeneri (buco triangolare) - T XXXXXXXXXXXXX A /XXXXX B en/XXXXX + T XXXXXXXXXXXXX A /XXXXX B en/XXXXX /XXXXXXXXXXXXXXX /XXXXXX /XXXXXX XXXXXXep==en XXX ep\ /en XXXX /e1 XXXX XXXXXX ----/| XX ------ ----/| XX ------ ----/|XXX @@ -179,17 +111,17 @@ namespace vcg { XXX \|/XXXXXXXX XXX \|/XXXXXXXX XXX \|/XXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXX */ - template class TrivialEar + template class TrivialEar { public: - face::Pos e0; - face::Pos e1; - typedef typename MSH_TYPE::ScalarType ScalarType; + face::Pos e0; + face::Pos e1; + typedef typename MESH::ScalarType ScalarType; ScalarType quality; ScalarType angle; - std::vector* vf; + std::vector* vf; TrivialEar(){} - TrivialEar(const face::Pos & ep) + TrivialEar(const face::Pos & ep) { e0=ep; assert(e0.IsBorder()); @@ -199,7 +131,7 @@ namespace vcg { ComputeAngle(); } - void SetAdiacenseRing(std::vector* ar){vf = ar;} + void SetAdiacenseRing(std::vector* ar){vf = ar;} void ComputeAngle() { @@ -207,18 +139,18 @@ namespace vcg { Point3f p2 = e1.v->P() - e0.v->P(); ScalarType w = p2.Norm()*p1.Norm(); - if(w==0) angle =90; + if(w==0) angle = acos(0.0f); ScalarType p = (p2*p1); p= p/w; - p = acos(p); if(p < -1) p = -1; if(p > 1) p = 1; + p = acos(p); Point3f t = p2^p1; ScalarType n = t* e0.v->N(); if(n<0) { - p = 2.0 *(float)M_PI - p; + p = (2.0 *(float)M_PI) - p; } angle = p; } @@ -239,14 +171,14 @@ namespace vcg { quality = area / ( (l1 *l1) + (l2 * l2) + (l3 * l3) ); }; - bool IsUpToDate() {return (e0.IsBorder() && e1.IsBorder());}; + bool IsUpToDate() {return ( e0.IsBorder() && e1.IsBorder());}; - bool IsConvex(){return (angle > (float)M_PI);} + bool IsConvex(){return(angle > (float)M_PI);} bool Degen() { - face::Pos ep=e0; ep.FlipV(); ep.NextB(); ep.FlipV(); // he precedente a e0 - face::Pos en=e1; en.NextB(); // he successivo a e1 + face::Pos ep=e0; ep.FlipV(); ep.NextB(); ep.FlipV(); // he precedente a e0 + face::Pos en=e1; en.NextB(); // he successivo a e1 // caso ear degenere per buco triangolare if(ep==en) return true;//provo a togliere sto controllo @@ -258,7 +190,7 @@ namespace vcg { return false; } - virtual bool Close(TrivialEar &ne0, TrivialEar &ne1, typename MSH_TYPE::FaceType * f) + virtual bool Close(TrivialEar &ne0, TrivialEar &ne1, typename MESH::FaceType * f) { // simple topological check if(e0.f==e1.f) { @@ -267,8 +199,8 @@ namespace vcg { } //usato per generare una delle due nuove orecchie. - face::Pos ep=e0; ep.FlipV(); ep.NextB(); ep.FlipV(); // he precedente a e0 - face::Pos en=e1; en.NextB(); // he successivo a e1 + face::Pos ep=e0; ep.FlipV(); ep.NextB(); ep.FlipV(); // he precedente a e0 + face::Pos en=e1; en.NextB(); // he successivo a e1 (*f).V(0) = e0.VFlip(); (*f).V(1) = e0.v; @@ -302,7 +234,7 @@ namespace vcg { else if(ep.v==en.v) { printf("Ear Non manif A\n"); - face::Pos enold=en; + face::Pos enold=en; en.NextB(); f->FFp(2)=enold.f; f->FFi(2)=enold.z; @@ -315,7 +247,7 @@ namespace vcg { else if(ep.VFlip()==e1.v) { printf("Ear Non manif B\n"); - face::Pos epold=ep; + face::Pos epold=ep; ep.FlipV(); ep.NextB(); ep.FlipV(); f->FFp(2)=epold.f; f->FFi(2)=epold.z; @@ -324,11 +256,10 @@ namespace vcg { ne0=TrivialEar(ep); ne1=TrivialEar(en); } - else // caso standard - // Now compute the new ears; + else // caso standard // Now compute the new ears; { ne0=TrivialEar(ep); - ne1=TrivialEar(face::Pos(f,2,e1.v)); + ne1=TrivialEar(face::Pos(f,2,e1.v)); } return true; @@ -336,13 +267,13 @@ namespace vcg { }; //Ear with FillHoleMinimumWeight's quality policy - template class MinimumWeightEar : public TrivialEar + template class MinimumWeightEar : public TrivialEar { public: - typename MSH_TYPE::ScalarType dihedral; - typename MSH_TYPE::ScalarType area; + typename MESH::ScalarType dihedral; + typename MESH::ScalarType area; MinimumWeightEar(){} - MinimumWeightEar(const face::Pos & ep) + MinimumWeightEar(const face::Pos & ep) { this->e0=ep; assert(this->e0.IsBorder()); @@ -362,7 +293,7 @@ namespace vcg { { //comute quality by (dihedral ancgle, area/sum(edge^2) ) Point3f n1 = (this->e0.v->N() + this->e1.v->N() + this->e0.VFlip()->N() ) / 3; - face::Pos tmp = this->e1; + face::Pos tmp = this->e1; tmp.FlipE();tmp.FlipV(); Point3f n2=(this->e1.VFlip()->N() + this->e1.v->N() + tmp.v->N() ) / 3; tmp = this->e0; @@ -370,7 +301,7 @@ namespace vcg { Point3f n3=(this->e0.VFlip()->N() + this->e0.v->N() + tmp.v->N() ) / 3; dihedral = std::max(Angle(n1,n2),Angle(n1,n3)); - typename MSH_TYPE::ScalarType ar; + typename MESH::ScalarType ar; ar = ( (this->e0.VFlip()->P() - this->e0.v->P()) ^ ( this->e1.v->P() - this->e0.v->P()) ).Norm() ; area = ar ; @@ -378,12 +309,12 @@ namespace vcg { }; //Ear for selfintersection algorithm - template class SelfIntersectionEar : public TrivialEar + template class SelfIntersectionEar : public TrivialEar { public: SelfIntersectionEar(){} - SelfIntersectionEar(const face::Pos & ep) + SelfIntersectionEar(const face::Pos & ep) { this->e0=ep; assert(this->e0.IsBorder()); @@ -393,7 +324,7 @@ namespace vcg { this->ComputeAngle(); } - virtual bool Close(SelfIntersectionEar &ne0, SelfIntersectionEar &ne1, typename MSH_TYPE::FaceType * f) + virtual bool Close(SelfIntersectionEar &ne0, SelfIntersectionEar &ne1, typename MESH::FaceType * f) { // simple topological check if(this->e0.f==this->e1.f) { @@ -401,8 +332,8 @@ namespace vcg { return false; } - face::Pos ep=this->e0; ep.FlipV(); ep.NextB(); ep.FlipV(); // he precedente a e0 - face::Pos en=this->e1; en.NextB(); // he successivo a e1 + face::Pos ep=this->e0; ep.FlipV(); ep.NextB(); ep.FlipV(); // he precedente a e0 + face::Pos en=this->e1; en.NextB(); // he successivo a e1 //costruisco la faccia e poi testo, o copio o butto via. (*f).V(0) = this->e0.VFlip(); (*f).V(1) = this->e0.v; @@ -421,14 +352,14 @@ namespace vcg { this->e0.f->FFp(this->e0.z)=f; this->e0.f->FFi(this->e0.z)=0; - + this->e1.f->FFp(this->e1.z)=f; this->e1.f->FFi(this->e1.z)=1; - typename std::vector::iterator it; + typename std::vector::iterator it; for(it = (* this->vf).begin();it!= (* this->vf).end();++it) { if(!it->IsD()) - if( tri::Clean::TestIntersection(&(*f),&(*it))) + if( tri::Clean::TestIntersection(&(*f),&(*it))) { this->e0.f->FFp(this->e0.z)= this->e0.f; this->e0.f->FFi(this->e0.z)=a1; @@ -453,7 +384,7 @@ namespace vcg { else if(ep.v==en.v) { printf("Ear Non manif A\n"); - face::Pos enold=en; + face::Pos enold=en; en.NextB(); f->FFp(2)=enold.f; f->FFi(2)=enold.z; @@ -468,7 +399,7 @@ namespace vcg { else if(ep.VFlip()==this->e1.v) { printf("Ear Non manif B\n"); - face::Pos epold=ep; + face::Pos epold=ep; ep.FlipV(); ep.NextB(); ep.FlipV(); f->FFp(2)=epold.f; f->FFi(2)=epold.z; @@ -483,7 +414,7 @@ namespace vcg { { ne0=SelfIntersectionEar(ep); ne0.SetAdiacenseRing(this->vf); - ne1=SelfIntersectionEar(face::Pos(f,2,this->e1.v)); + ne1=SelfIntersectionEar(face::Pos(f,2,this->e1.v)); ne1.SetAdiacenseRing(this->vf); } return true; @@ -496,21 +427,75 @@ namespace vcg { // Controlla che non si generino nuove situazioni non manifold chiudendo orecchie // che sottendono un edge che gia'esiste. - template - void FillHoleEar(MESH &m, tri::HoleInfo &h ,int UBIT, std::vector *vf =0) +template +class Hole +{ +public: + typedef typename MESH::VertexType VertexType; + typedef typename MESH::VertexPointer VertexPointer; + typedef typename MESH::ScalarType ScalarType; + typedef typename MESH::FaceType FaceType; + typedef typename MESH::FacePointer FacePointer; + typedef typename MESH::FaceIterator FaceIterator; + typedef typename MESH::CoordType CoordType; + typedef typename vcg::Box3 Box3Type; + typedef typename face::Pos PosType; + +public: + + class Info + { + public: + Info(){} + Info(PosType const &pHole, int const pHoleSize, Box3 &pHoleBB) + { + p=pHole; + size=pHoleSize; + bb=pHoleBB; + } + + PosType p; + int size; + Box3Type bb; + + bool operator < (const Info & hh) const {return size < hh.size;} + bool operator > (const Info & hh) const {return size > hh.size;} + bool operator == (const Info & hh) const {return size == hh.size;} + bool operator != (const Info & hh) const {return size != hh.size;} + bool operator >= (const Info & hh) const {return size >= hh.size;} + bool operator <= (const Info & hh) const {return size <= hh.size;} + + ScalarType Perimeter() + { + ScalarType sum=0; + PosType ip = p; + do + { + sum+=Distance(ip.v->cP(),ip.VFlip()->cP()); + ip.NextB(); + } + while (ip != p); + return sum; + } + + }; + + + +template + void FillHoleEar(MESH &m, Info &h ,int UBIT, std::vector &app,std::vector *vf =0) { //Aggiungo le facce e aggiorno il puntatore alla faccia! - std::vector app; - app.push_back( &h.p.f ); - typename MESH::FaceIterator f = tri::Allocator::AddFaces(m, h.size-2, app); - h.Refresh(m); + FaceIterator f = tri::Allocator::AddFaces(m, h.size-2, app); + assert(h.p.f >= &*m.face.begin()); + assert(h.p.f < &*m.face.end()); assert(h.p.IsBorder());//test fondamentale altrimenti qualcosa s'e' rotto! std::vector H; //vettore di orecchie H.reserve(h.size); //prendo le informazioni sul buco - face::Pos ff = h.p; - face::Pos fp = h.p; + PosType ff = h.p; + PosType fp = h.p; do{ EAR app = EAR(fp); app.SetAdiacenseRing(vf); @@ -521,7 +506,7 @@ namespace vcg { bool fitted = false; int cnt=h.size; - typename MESH::FaceIterator tmp; + FaceIterator tmp; make_heap(H.begin(), H.end()); //finche' il buco non e' chiuso o non ci sono piu' orecchie da analizzare. @@ -529,15 +514,10 @@ namespace vcg { { pop_heap(H.begin(), H.end()); EAR en0,en1; - typename MESH::FaceIterator Fadd = f; - if(H.back().IsUpToDate() && H.back().IsConvex()) + FaceIterator Fadd = f; + if(H.back().IsUpToDate() && !H.back().IsConvex()) { - if(H.back().Degen()){ - // Nota che nel caso di ear degeneri si DEVE permettere la creazione di un edge che gia'esiste. - printf("\n -> Evitata orecchia brutta!"); - } - else - { + if(!H.back().Degen()){ if(H.back().Close(en0,en1,&*f)) { if(!en0.IsNull()){ @@ -561,7 +541,6 @@ namespace vcg { if(H.back().Close(en0,en1,&*f)) { --cnt; - tmp = f; if(vf != 0)(*vf).push_back(*f); ++f; } @@ -580,22 +559,31 @@ namespace vcg { } } - template - void holeFillingEar(MESH &m, int sizeHole,bool Selected = false) - { - std::vector > vinfo; - int UBIT = GetHoleInfo(m, Selected,vinfo); - typename std::vector >::iterator ith; - typename tri::HoleInfo app; + + template//!!! + void EarCuttingFill(MESH &m, int sizeHole,bool Selected = false) + { + std::vector< Info > vinfo; + int UBIT = GetInfo(m, Selected,vinfo); + + std::vector::iterator ith; + //Info app; + int ind=0; + + std::vector vfp; + for(ith = vinfo.begin(); ith!= vinfo.end(); ++ith) + vfp.push_back( &(*ith).p.f ); + for(ith = vinfo.begin(); ith!= vinfo.end(); ++ith) { - app=(tri::HoleInfo)*ith; - if(app.size < sizeHole){ - FillHoleEar(m, app,UBIT); + ind++; + if((*ith).size < sizeHole){ + FillHoleEar< EAR >(m, *ith,UBIT,vfp); } } - typename MESH::FaceIterator fi; + + FaceIterator fi; for(fi = m.face.begin(); fi!=m.face.end(); ++fi) { if(!(*fi).IsD()) @@ -603,26 +591,36 @@ namespace vcg { } } - template - void holeFillingIntersection(MESH &m, int sizeHole,bool Selected = false) + + + template + void EarCuttingIntersectionFill(MESH &m, int sizeHole,bool Selected = false) { - std::vector > vinfo; - int UBIT = GetHoleInfo(m, Selected,vinfo); - std::vector vf; - face::Possp; - face::Posap; - typename std::vector >::iterator ith; - tri::HoleInfo app; + std::vector vinfo; + int UBIT = GetInfo(m, Selected,vinfo); + std::vector vf; + PosType sp; + PosType ap; + std::vector::iterator ith; + Info app; + + std::vector vfp; for(ith = vinfo.begin(); ith!= vinfo.end(); ++ith) { - app=(tri::HoleInfo)*ith; + app=(Info)*ith; + vfp.push_back( &app.p.f ); + } + + for(ith = vinfo.begin(); ith!= vinfo.end(); ++ith) + { + app=(Info)*ith; if(app.size < sizeHole){ - app.Refresh(m); + //colleziono il ring intorno al buco per poi fare il test sul'intersezione sp = app.p; do { - ap = sp; + ap = sp; do { ap.FlipE(); @@ -633,11 +631,11 @@ namespace vcg { }while(sp != app.p); - FillHoleEar(m, app,UBIT,&vf); + FillHoleEar(m, app,UBIT,vfp,&vf); vf.clear(); } } - typename MESH::FaceIterator fi; + FaceIterator fi; for(fi = m.face.begin(); fi!=m.face.end(); ++fi) { if(!(*fi).IsD()) @@ -645,11 +643,12 @@ namespace vcg { } } - template - int GetHoleInfo(MESH &m,bool Selected ,std::vector >& VHI) + + + int GetInfo(MESH &m,bool Selected ,std::vector& VHI) { - typename MESH::FaceIterator fi; - int UBIT = MESH::FaceType::LastBitFlag(); + FaceIterator fi; + int UBIT = FaceType::LastBitFlag(); for(fi = m.face.begin(); fi!=m.face.end(); ++fi) { @@ -670,11 +669,11 @@ namespace vcg { { if( (*fi).IsB(j) ) {//Trovato una faccia di bordo non ancora visitata. - face::Pos sp(&*fi, j, (*fi).V(j)); - face::Pos fp=sp; + PosType sp(&*fi, j, (*fi).V(j)); + PosType fp=sp; int holesize=0; - Box3 hbox; + Box3Type hbox; hbox.Add(sp.v->cP()); do @@ -686,10 +685,8 @@ namespace vcg { assert(sp.IsBorder()); }while(sp != fp); - int tmp = ((int)(sp.f - &(*(m.face.begin())))); - //ho recuperato l'inofrmazione su tutto il buco - VHI.push_back( tri::HoleInfo(sp,holesize,hbox, tmp) ); + VHI.push_back( Info(sp,holesize,hbox) ); } }//for sugli edge del triangolo }//se e' gia stato visitato @@ -718,37 +715,34 @@ namespace vcg { float ang; float ar; }; + /* - \ / \/ - v1*---------*v4 - / \ / -hole/ \ / - / \ / - /ear \ / --*---------*- -/ v3 v2\ - */ - template - float ComputeDihedralAngle(typename MESH::VertexPointer v1,typename MESH::VertexPointer v2, - typename MESH::VertexPointer v3,typename MESH::VertexPointer v4) + \ / \/ + v1*---------*v4 + / \ / + / \ / + / \ / + /ear \ / +*---------*- +| v3 v2\ +*/ + + float ComputeDihedralAngle(CoordType p1,CoordType p2,CoordType p3,CoordType p4) { - typename MESH::CoordType n1 = ((v1->P() - v2->P()) ^ (v3->P() - v1->P()) ).Normalize(); - typename MESH::CoordType n2 = ((v2->P() - v1->P()) ^ (v4->P() - v2->P()) ).Normalize(); - typename MESH::ScalarType t = (n1 * n2 ) ; - return ( acos(t)* 180.0 / M_PI); + CoordType n1 = ((p1 - p2) ^ (p3 - p1) ).Normalize(); + CoordType n2 = ((p2 - p1) ^ (p4 - p2) ).Normalize(); + ScalarType t = (n1 * n2 ) ; + return math::ToDeg(acos(t)); } - template - bool existEdge(face::Pos pi,face::Pos pf) +bool existEdge(PosType pi,PosType pf) { - face::Pos app = pi; - face::Pos appF = pi; - face::Pos tmp; + PosType app = pi; + PosType appF = pi; + PosType tmp; assert(pi.IsBorder()); - appF.NextB(); appF.FlipV(); - do { tmp = app; @@ -763,17 +757,16 @@ hole/ \ / return false; } - template - Weight computeWeight( int i, int j, int k, - std::vector > pv, + Weight computeWeight( int i, int j, int k, + std::vector pv, std::vector< std::vector< int > > v) { - face::Pos pi = pv[i]; - face::Pos pj = pv[j]; - face::Pos pk = pv[k]; + PosType pi = pv[i]; + PosType pj = pv[j]; + PosType pk = pv[k]; //test complex edge - if(existEdge(pi,pj) || existEdge(pj,pk)|| existEdge(pk,pi) ) + if(existEdge(pi,pj) || existEdge(pj,pk)|| existEdge(pk,pi) ) { return Weight(); } @@ -784,43 +777,42 @@ hole/ \ / //calcolo il massimo angolo diedrale, se esiste. float angle = 0.0f; - face::Pos px; + PosType px; if(i + 1 == j) { px = pj; px.FlipE(); px.FlipV(); - angle = std::max(angle , ComputeDihedralAngle(pi.v, pj.v, pk.v, px.v) ); + angle = std::max(angle , ComputeDihedralAngle(pi.v->P(), pj.v->P(), pk.v->P(), px.v->P()) ); } else { - angle = std::max( angle, ComputeDihedralAngle(pi.v,pj.v, pk.v, pv[ v[i][j] ].v)); + angle = std::max( angle, ComputeDihedralAngle(pi.v->P(),pj.v->P(), pk.v->P(), pv[ v[i][j] ].v->P())); } if(j + 1 == k) { px = pk; px.FlipE(); px.FlipV(); - angle = std::max(angle , ComputeDihedralAngle(pj.v, pk.v, pi.v, px.v) ); + angle = std::max(angle , ComputeDihedralAngle(pj.v->P(), pk.v->P(), pi.v->P(), px.v->P()) ); } else { - angle = std::max( angle, ComputeDihedralAngle(pj.v,pk.v, pi.v, pv[ v[j][k] ].v)); + angle = std::max( angle, ComputeDihedralAngle(pj.v->P(),pk.v->P(), pi.v->P(), pv[ v[j][k] ].v->P())); } if( i == 0 && k == (int)v.size() - 1) { px = pi; px.FlipE(); px.FlipV(); - angle = std::max(angle , ComputeDihedralAngle(pk.v, pi.v, pj.v,px.v ) ); + angle = std::max(angle , ComputeDihedralAngle(pk.v->P(), pi.v->P(), pj.v->P(),px.v->P() ) ); } - typename MESH::ScalarType area = ( (pj.v->P() - pi.v->P()) ^ (pk.v->P() - pi.v->P()) ).Norm() * 0.5; + typename ScalarType area = ( (pj.v->P() - pi.v->P()) ^ (pk.v->P() - pi.v->P()) ).Norm() * 0.5; return Weight(angle, area); } - template - std::vector calculateMinimumWeightTriangulation(MESH &m, std::vector > vv ) + std::vector calculateMinimumWeightTriangulation(MESH &m, std::vector vv ) { std::vector< std::vector< Weight > > w; //matrice dei pesi minimali di ogni orecchio preso in conzideraione std::vector< std::vector< int > > vi;//memorizza l'indice del terzo vertice del triangolo @@ -853,7 +845,7 @@ hole/ \ / { Weight a = w[i][m]; Weight b = w[m][i+j]; - Weight newval = a + b + computeWeight( i, m, i+j, vv, vi); + Weight newval = a + b + computeWeight( i, m, i+j, vv, vi); if ( newval < minval ) { minval = newval; @@ -868,18 +860,17 @@ hole/ \ / //Triangulate int i, j; i=0; j=nv-1; - std::vector vf; + std::vector vf; vf.clear(); - triangulate(vf, i, j, vi, vv); - + triangulate(vf, i, j, vi, vv); return vf; } - template - void triangulate(std::vector &m,int i, int j, std::vector< std::vector > vi, - std::vector > vv) + + void triangulate(std::vector &m,int i, int j, std::vector< std::vector > vi, + std::vector vv) { if(i + 1 == j){return;} if(i==j)return; @@ -892,34 +883,33 @@ hole/ \ / m.push_back(vv[k].v); m.push_back(vv[j].v); - triangulate(m, i, k, vi, vv); - triangulate(m, k, j, vi, vv); + triangulate(m, i, k, vi, vv); + triangulate(m, k, j, vi, vv); } - template - void FillHoleMinimumWeight(MESH &m, bool Selected) +void MinimumWeightFill(MESH &m, bool Selected) { - typename MESH::FaceIterator fi; - std::vector > vvi; - std::vector vfp; + FaceIterator fi; + std::vector vvi; + std::vector vfp; - std::vector > vinfo; - typename std::vector >::iterator VIT; - int UBIT = GetHoleInfo(m, Selected,vinfo); + std::vector vinfo; + typename std::vector::iterator VIT; + int UBIT = GetInfo(m, Selected,vinfo); for(VIT = vinfo.begin(); VIT != vinfo.end();++VIT) { vvi.push_back(VIT->p); } - typename std::vector >::iterator ith; - typename std::vector >::iterator ithn; - typename std::vector::iterator itf; + typename std::vector::iterator ith; + typename std::vector::iterator ithn; + typename std::vector::iterator itf; - std::vector > app; - face::Pos ps; - std::vector tr; - std::vector vf; + std::vector app; + PosType ps; + std::vector tr; + std::vector vf; for(ith = vvi.begin(); ith!= vvi.end(); ++ith) { @@ -932,13 +922,18 @@ hole/ \ / vfp.push_back(&(ithn->f)); ps = *ith; - getBoundHole(ps,app); + getBoundHole(ps,app); + + if(app.size() >= 200) + { + continue; + } vf = calculateMinimumWeightTriangulation(m, app); if(vf.size() == 0)continue;//non e' stata trovata la triangolazione - typename MESH::FaceIterator f = tri::Allocator::AddFaces(m, app.size()-2, vfp); + FaceIterator f = tri::Allocator::AddFaces(m, app.size()-2, vfp); for(itf = vf.begin();itf != vf.end(); ) { @@ -947,13 +942,15 @@ hole/ \ / (*f).V(2) = (*itf++); ++f; } + } + } - template - void getBoundHole (face::Pos sp,std::vector >&ret) + + void getBoundHole (PosType sp,std::vector&ret) { - face::Pos fp = sp; + PosType fp = sp; //take vertex around the hole do { @@ -963,6 +960,14 @@ hole/ \ / }while(sp != fp); } +};//close class Hole + + + + + + + } // end namespace } #endif