From be7c2536f7d1943e5cb9c705f2763c96e8455ea8 Mon Sep 17 00:00:00 2001 From: nicopietroni Date: Wed, 17 Oct 2012 11:23:43 +0000 Subject: [PATCH] added export to polygonal mesh --- wrap/miq/quadrangulator.h | 800 +++++++++++++++++++------------------- 1 file changed, 401 insertions(+), 399 deletions(-) diff --git a/wrap/miq/quadrangulator.h b/wrap/miq/quadrangulator.h index 7169ae03..1fd3aa8a 100644 --- a/wrap/miq/quadrangulator.h +++ b/wrap/miq/quadrangulator.h @@ -9,53 +9,28 @@ #include #include -///return the list of faces that share a specified vertex -///together with indexes those faces are sorted in ccw -template -void SortedStar(const vcg::face::Pos &ep, - std::vector< typename FaceType::VertexType*> &star) + +template +inline void ExtractVertex(const MeshType & srcMesh, + const typename MeshType::FaceType & f, + int whichWedge, + const MeshType &dstMesh, + typename MeshType::VertexType & v) { - typedef typename FaceType::VertexType VertexType; - FaceType *f_init=ep.f; - int edge_init=ep.z; - vcg::face::JumpingPos VFI(f_init,edge_init); - bool complete_turn=false; - do - { - ///take the current face - FaceType *curr_f=VFI.F(); - int curr_edge=VFI.E(); - assert((curr_edge>=0)&&(curr_edge<=4)); - star.push_back(VFI.F()->V1(curr_edge)); - //go to next one - VFI.NextFE(); - FaceType *next_f=VFI.F(); - ///test the complete turn - complete_turn=(next_f==f_init); - }while (!complete_turn); + (void)srcMesh; + (void)dstMesh; + + //v.P() = f.cP(whichWedge); + v.ImportData(*f.cV(whichWedge)); + v.T() = f.cWT(whichWedge); } template -inline void ExtractVertex(const MeshType & srcMesh, - const typename MeshType::FaceType & f, - int whichWedge, - const MeshType &dstMesh, - typename MeshType::VertexType & v) - { - (void)srcMesh; - (void)dstMesh; - - //v.P() = f.cP(whichWedge); - v.ImportData(*f.cV(whichWedge)); - v.T() = f.cWT(whichWedge); - } - -template -inline bool CompareVertex(const MeshType & m, - const typename MeshType::VertexType & vA, - const typename MeshType::VertexType & vB) +inline bool CompareVertex(const MeshType & m, + const typename MeshType::VertexType & vA, + const typename MeshType::VertexType & vB) { - (void)m; + (void)m; return ((vA.cT() == vB.cT())&&(vA.cP()==vB.cP())); } @@ -65,453 +40,480 @@ class Quadrangulator { public: - typedef typename TriMesh::FaceType TriFaceType; - typedef typename TriMesh::VertexType TriVertexType; - typedef typename TriMesh::CoordType CoordType; - typedef typename TriMesh::ScalarType ScalarType; + typedef typename TriMesh::FaceType TriFaceType; + typedef typename TriMesh::VertexType TriVertexType; + typedef typename TriMesh::CoordType CoordType; + typedef typename TriMesh::ScalarType ScalarType; - typedef typename PolyMesh::FaceType PolyFaceType; - typedef typename PolyMesh::VertexType PolyVertexType; - typedef typename PolyMesh::CoordType PolyCoordType; - typedef typename PolyMesh::ScalarType PolyScalarType; - + typedef typename PolyMesh::FaceType PolyFaceType; + typedef typename PolyMesh::VertexType PolyVertexType; + typedef typename PolyMesh::CoordType PolyCoordType; + typedef typename PolyMesh::ScalarType PolyScalarType; - ///the set of all edges that belongs to integer lines - std::set > IntegerEdges; - ///the set of all integer vertices and the other vertices on integer lines which is connectes to - std::map > IntegerLineAdj; - ///the set of integer vertices - std::set IntegerVertices; - ///temporary polygons - std::vector > polygons; - - ///drawing debug structures - std::vector > IntegerLines; - std::vector IntegerVertex; + ///the set of all edges that belongs to integer lines + std::set > IntegerEdges; - static bool ToSplit(const vcg::Point2 &uv0, - const vcg::Point2 &uv1, - int Dir, - int IntegerLine, - ScalarType &alpha, - ScalarType tolerance=0.0001) - { - ScalarType lineF=(ScalarType)IntegerLine; - ScalarType val0=std::min(uv0.V(Dir),uv1.V(Dir)); - ScalarType val1=std::max(uv0.V(Dir),uv1.V(Dir)); - if (lineF<(val0+tolerance))return false; - if (lineF>(val1-tolerance))return false; - ScalarType dist=fabs(uv0.V(Dir)-uv1.V(Dir)); - if (dist > IntegerLineAdj; + ///the set of integer vertices + std::set IntegerVertices; + ///temporary polygons + std::vector > polygons; - ///return true if the edge has to be splitted, - ///by considering the tolerance to the closest integer - static bool ToSplit(const vcg::face::Pos &ep, - ScalarType &alpha, - ScalarType factor=1.0, - ScalarType tolerance=0.0001) - { + ///drawing debug structures + std::vector > IntegerLines; + std::vector IntegerVertex; + + static bool ToSplit(const vcg::Point2 &uv0, + const vcg::Point2 &uv1, + int Dir, + int IntegerLine, + ScalarType &alpha, + ScalarType tolerance=0.0001) + { + ScalarType lineF=(ScalarType)IntegerLine; + ScalarType val0=std::min(uv0.V(Dir),uv1.V(Dir)); + ScalarType val1=std::max(uv0.V(Dir),uv1.V(Dir)); + if (lineF<(val0+tolerance))return false; + if (lineF>(val1-tolerance))return false; + ScalarType dist=fabs(uv0.V(Dir)-uv1.V(Dir)); + if (dist &ep, + ScalarType &alpha, + ScalarType factor=1.0, + ScalarType tolerance=0.0001) + { //TriFaceType *f=ep.f; //int z=ep.z; - TriVertexType* v0=ep.f->V(ep.z); - TriVertexType* v1=ep.f->V1(ep.z); - vcg::Point2 uv0=v0->T().P()*factor; - vcg::Point2 uv1=v1->T().P()*factor; - - ///then test integer for each direction - for (int dir=0;dir<2;dir++) - { - int Int0=std::min((int)uv0.V(dir),(int)uv1.V(dir)); - int Int1=std::max((int)uv0.V(dir),(int)uv1.V(dir)); + TriVertexType* v0=ep.f->V(ep.z); + TriVertexType* v1=ep.f->V1(ep.z); + vcg::Point2 uv0=v0->T().P()*factor; + vcg::Point2 uv1=v1->T().P()*factor; - for (int i=Int0;i<=Int1;i++) - { - bool to_split=ToSplit(uv0,uv1,dir,i,alpha,tolerance); - if (to_split)return true; - } - } - return false; - } + ///then test integer for each direction + for (int dir=0;dir<2;dir++) + { + int Int0=std::min((int)uv0.V(dir),(int)uv1.V(dir)); + int Int1=std::max((int)uv0.V(dir),(int)uv1.V(dir)); + + for (int i=Int0;i<=Int1;i++) + { + bool to_split=ToSplit(uv0,uv1,dir,i,alpha,tolerance); + if (to_split)return true; + } + } + return false; + } - // Basic subdivision class - // This class must provide methods for finding the position of the newly created vertices - // In this implemenation we simply put the new vertex in the MidPoint position. - // Color and TexCoords are interpolated accordingly. - template - struct SplitMidPoint : public std::unary_function , typename MESH_TYPE::CoordType > - { - typedef typename MESH_TYPE::VertexType VertexType; - typedef typename MESH_TYPE::FaceType FaceType; - typedef typename MESH_TYPE::CoordType CoordType; + // Basic subdivision class + // This class must provide methods for finding the position of the newly created vertices + // In this implemenation we simply put the new vertex in the MidPoint position. + // Color and TexCoords are interpolated accordingly. + template + struct SplitMidPoint : public std::unary_function , typename MESH_TYPE::CoordType > + { + typedef typename MESH_TYPE::VertexType VertexType; + typedef typename MESH_TYPE::FaceType FaceType; + typedef typename MESH_TYPE::CoordType CoordType; - ScalarType factor; - ScalarType tolerance; - ScalarType alpha; + ScalarType factor; + ScalarType tolerance; + ScalarType alpha; - void operator()(typename MESH_TYPE::VertexType &nv, - vcg::face::Pos ep) - { - bool to_split=ToSplit(ep,alpha,factor,tolerance); - assert(to_split); + void operator()(typename MESH_TYPE::VertexType &nv, + vcg::face::Pos ep) + { + bool to_split=ToSplit(ep,alpha,factor,tolerance); + assert(to_split); - ///get the value on which the edge must be splitted - VertexType* v0=ep.f->V(ep.z); - VertexType* v1=ep.f->V1(ep.z); + ///get the value on which the edge must be splitted + VertexType* v0=ep.f->V(ep.z); + VertexType* v1=ep.f->V1(ep.z); - nv.P()= v0->P()*alpha+v1->P()*(1.0-alpha); - //nv.N()= v0->N()*alpha+v1->N()*(1.0-alpha); - nv.T().P()=v0->T().P()*alpha+v1->T().P()*(1.0-alpha); - } + nv.P()= v0->P()*alpha+v1->P()*(1.0-alpha); + //nv.N()= v0->N()*alpha+v1->N()*(1.0-alpha); + nv.T().P()=v0->T().P()*alpha+v1->T().P()*(1.0-alpha); + } - vcg::TexCoord2 WedgeInterp(vcg::TexCoord2 &t0, - vcg::TexCoord2 &t1) - { - vcg::TexCoord2 tmp; + vcg::TexCoord2 WedgeInterp(vcg::TexCoord2 &t0, + vcg::TexCoord2 &t1) + { + vcg::TexCoord2 tmp; if (t0.n() != t1.n()) cerr << "Failed assertion: Quadrangulator::WedgeInterp1" << endl; // assert(t0.n()== t1.n()); TODO put back - tmp.n()=t0.n(); + tmp.n()=t0.n(); // assert(alpha>=0); TODO put back if (alpha<0) cerr << "Failed assertion: Quadrangulator::WedgeInterp2" << endl; - tmp.t()=(alpha*t0.t()+(1.0-alpha)*t1.t()); - return tmp; - } + tmp.t()=(alpha*t0.t()+(1.0-alpha)*t1.t()); + return tmp; + } - SplitMidPoint(){alpha=-1;} - }; + SplitMidPoint(){alpha=-1;} + }; - template - class EdgePredicate - { - typedef typename MESH_TYPE::VertexType VertexType; - typedef typename MESH_TYPE::FaceType FaceType; - typedef typename MESH_TYPE::ScalarType ScalarType; + template + class EdgePredicate + { + typedef typename MESH_TYPE::VertexType VertexType; + typedef typename MESH_TYPE::FaceType FaceType; + typedef typename MESH_TYPE::ScalarType ScalarType; - public: - ScalarType factor; - ScalarType tolerance; + public: + ScalarType factor; + ScalarType tolerance; - bool operator()(vcg::face::Pos ep) const - { - ScalarType alpha; - return(ToSplit(ep,alpha,factor,tolerance)); - } - }; + bool operator()(vcg::face::Pos ep) const + { + ScalarType alpha; + return(ToSplit(ep,alpha,factor,tolerance)); + } + }; - void SplitTris(TriMesh &to_split, - ScalarType factor=1.0, - ScalarType tolerance=0.0001) - { - bool done=true; - SplitMidPoint splMd; - EdgePredicate eP; + void SplitTris(TriMesh &to_split, + ScalarType factor=1.0, + ScalarType tolerance=0.0001) + { + bool done=true; + SplitMidPoint splMd; + EdgePredicate eP; - splMd.tolerance=tolerance; - splMd.factor=factor; - eP.tolerance=tolerance; - eP.factor=factor; + splMd.tolerance=tolerance; + splMd.factor=factor; + eP.tolerance=tolerance; + eP.factor=factor; - while (done) + while (done) done=vcg::tri::RefineE,EdgePredicate >(to_split,splMd,eP); for (unsigned int i=0;iT().P(); - } - - - bool IsOnIntegerLine(vcg::Point2 uv0, - vcg::Point2 uv1, - ScalarType tolerance=0.0001) - { - for (int dir=0;dir<2;dir++) - { - ScalarType val0=uv0.V(dir); - ScalarType val1=uv1.V(dir); - int integer0=floor(uv0.V(dir)+0.5); - int integer1=floor(uv1.V(dir)+0.5); - if (integer0!=integer1)continue; - if ((fabs(val0-(ScalarType)integer0))>tolerance)continue; - if ((fabs(val1-(ScalarType)integer1))>tolerance)continue; - return true; - } - return false; - } - - bool IsOnIntegerVertex(vcg::Point2 uv, - ScalarType tolerance=0.0001) - { - for (int dir=0;dir<2;dir++) - { - ScalarType val0=uv.V(dir); - int integer0=floor(val0+0.5); - if ((fabs(val0-(ScalarType)integer0))>tolerance)return false; - } - return true; - } - - void InitIntegerVectors() - { - IntegerLines=std::vector >(IntegerEdges.begin(),IntegerEdges.end()); - IntegerVertex=std::vector (IntegerVertices.begin(),IntegerVertices.end()); - } + for (int j=0;j<3;j++) to_split.face[i].WT(j).P()=to_split.face[i].V(j)->T().P(); + } - void EraseIntegerEdge(const vcg::face::Pos &ep) - { - std::pair edge(ep.F(),ep.E()); - assert(IntegerEdges.count(edge)!=0); - IntegerEdges.erase(edge); - } - - void EraseIntegerEdge(const std::vector > &to_erase) - { + + bool IsOnIntegerLine(vcg::Point2 uv0, + vcg::Point2 uv1, + ScalarType tolerance=0.0001) + { + for (int dir=0;dir<2;dir++) + { + ScalarType val0=uv0.V(dir); + ScalarType val1=uv1.V(dir); + int integer0=floor(uv0.V(dir)+0.5); + int integer1=floor(uv1.V(dir)+0.5); + if (integer0!=integer1)continue; + if ((fabs(val0-(ScalarType)integer0))>tolerance)continue; + if ((fabs(val1-(ScalarType)integer1))>tolerance)continue; + return true; + } + return false; + } + + bool IsOnIntegerVertex(vcg::Point2 uv, + ScalarType tolerance=0.0001) + { + for (int dir=0;dir<2;dir++) + { + ScalarType val0=uv.V(dir); + int integer0=floor(val0+0.5); + if ((fabs(val0-(ScalarType)integer0))>tolerance)return false; + } + return true; + } + + void InitIntegerVectors() + { + IntegerLines=std::vector >(IntegerEdges.begin(),IntegerEdges.end()); + IntegerVertex=std::vector (IntegerVertices.begin(),IntegerVertices.end()); + } + + void EraseIntegerEdge(const vcg::face::Pos &ep) + { + std::pair edge(ep.F(),ep.E()); + assert(IntegerEdges.count(edge)!=0); + IntegerEdges.erase(edge); + } + + void EraseIntegerEdge(const std::vector > &to_erase) + { for (unsigned int i=0;i pair_type; typedef typename std::vector< pair_type > vect_type; typename vect_type::iterator IteIntl; for (IteIntl=IntegerLines.begin(); - IteIntl!=IntegerLines.end(); - IteIntl++) - { + IteIntl!=IntegerLines.end(); + IteIntl++) + { int E=(*IteIntl).second; TriFaceType *F=(*IteIntl).first; - TriFaceType *F1=F->FFp(E); - if (F==F1) continue; - int E1=F->FFi(E); - std::pair curr_edge(F1,E1); - assert(IntegerEdges.count(curr_edge)!=0); + TriFaceType *F1=F->FFp(E); + if (F==F1) continue; + int E1=F->FFi(E); + std::pair curr_edge(F1,E1); + assert(IntegerEdges.count(curr_edge)!=0); } - } + } - void InitIntegerEdgesVert(TriMesh &Tmesh, - ScalarType factor=1.0, - ScalarType tolerance=0.0001) - { - IntegerEdges.clear(); + void InitIntegerEdgesVert(TriMesh &Tmesh, + ScalarType factor=1.0, + ScalarType tolerance=0.0001) + { + IntegerEdges.clear(); for (unsigned int i=0;iIsD())continue; - for (int j=0;j<3;j++) - { - TriFaceType *f1=f->FFp(j); - int e1=f->FFi(j); - bool IsBorder=f->IsB(j); - TriVertexType *v0=f->V0(j); - TriVertexType *v1=f->V1(j); - vcg::Point2 uv0=f->WT(j).P()*factor; - vcg::Point2 uv1=f->WT((j+1)%3).P()*factor; - if (IsOnIntegerLine(uv0,uv1,tolerance)||IsBorder) - { - //IntegerEdges.insert(std::pair(v0,v1)); - IntegerEdges.insert(std::pair(f,j)); - if (!IsBorder) - IntegerEdges.insert(std::pair(f1,e1)); - else - { - IntegerVertices.insert(v0); - IntegerVertices.insert(v1); - } - } - if (IsOnIntegerVertex(uv0)) - IntegerVertices.insert(v0); - - if (IsOnIntegerVertex(uv1)) - IntegerVertices.insert(v1); + { + TriFaceType *f=&Tmesh.face[i]; + if (f->IsD())continue; + for (int j=0;j<3;j++) + { + TriFaceType *f1=f->FFp(j); + int e1=f->FFi(j); + bool IsBorder=f->IsB(j); + TriVertexType *v0=f->V0(j); + TriVertexType *v1=f->V1(j); + vcg::Point2 uv0=f->WT(j).P()*factor; + vcg::Point2 uv1=f->WT((j+1)%3).P()*factor; + if (IsOnIntegerLine(uv0,uv1,tolerance)||IsBorder) + { + //IntegerEdges.insert(std::pair(v0,v1)); + IntegerEdges.insert(std::pair(f,j)); + if (!IsBorder) + IntegerEdges.insert(std::pair(f1,e1)); + else + { + IntegerVertices.insert(v0); + IntegerVertices.insert(v1); + } + } + if (IsOnIntegerVertex(uv0)) + IntegerVertices.insert(v0); - } - } - //InitIntegerNeigh(Tmesh); - InitIntegerVectors(); + if (IsOnIntegerVertex(uv1)) + IntegerVertices.insert(v1); + + } + } + //InitIntegerNeigh(Tmesh); + InitIntegerVectors(); TestIntegerEdges(); - } - - - ///return the first and the last edge - ///following an integer line - ///until if reach anothe integer edge - bool OneIntegerStep(vcg::face::Pos &ep) - { - TriFaceType *f_init=ep.f; - TriFaceType *currF=f_init; + } + + + ///return the first and the last edge + ///following an integer line + ///until if reach anothe integer edge + bool OneIntegerStep(vcg::face::Pos &ep) + { + TriFaceType *f_init=ep.f; + TriFaceType *currF=f_init; //int edge_init=ep.z; - //ep.V()=f_init->V(edge_init); - TriVertexType* v_init=ep.V(); - bool complete_turn=false; - do - { - ep.FlipE(); - ///see if found an integer vert - currF=ep.F(); - int currE=ep.E(); - assert((currE>=0)&&(currE<=4)); - - std::pair curr_edge(currF,currE); - - if (IntegerEdges.count(curr_edge)!=0) - { - ///go to the other side - ep.FlipV(); - assert(ep.V()!=v_init); - return true; - } - ep.FlipF(); - ///see if there's a border - bool jumped=(currF==ep.F()); - if (jumped) - return false; - ///test the complete turn - complete_turn=(ep.F()==f_init); - }while (!complete_turn); - return false; - } + //ep.V()=f_init->V(edge_init); + TriVertexType* v_init=ep.V(); + bool complete_turn=false; + do + { + ep.FlipE(); + ///see if found an integer vert + currF=ep.F(); + int currE=ep.E(); + assert((currE>=0)&&(currE<=4)); - ///find a polygon starting from half edge ep, return true if found - bool FindPolygon(vcg::face::Pos &ep, - std::vector &poly) - { + std::pair curr_edge(currF,currE); - poly.clear(); - TriVertexType* v_init=ep.V(); - ///it must start from an integer vert - assert(IntegerVertices.count(v_init)!=0); - poly.push_back(v_init); - std::vector > to_erase; - to_erase.push_back(std::pair(ep.F(),ep.E())); - do - { - bool done=OneIntegerStep(ep); - if (!done) - { - EraseIntegerEdge(to_erase); - return false; - } - to_erase.push_back(std::pair(ep.F(),ep.E())); - TriVertexType* v_curr=ep.V(); - if ((IntegerVertices.count(v_curr)!=0)&& - (v_curr!=v_init)) - poly.push_back(v_curr); - }while(ep.V()!=v_init); + if (IntegerEdges.count(curr_edge)!=0) + { + ///go to the other side + ep.FlipV(); + assert(ep.V()!=v_init); + return true; + } + ep.FlipF(); + ///see if there's a border + bool jumped=(currF==ep.F()); + if (jumped) + return false; + ///test the complete turn + complete_turn=(ep.F()==f_init); + }while (!complete_turn); + return false; + } + + ///find a polygon starting from half edge ep, return true if found + bool FindPolygon(vcg::face::Pos &ep, + std::vector &poly) + { + + poly.clear(); + TriVertexType* v_init=ep.V(); + ///it must start from an integer vert + assert(IntegerVertices.count(v_init)!=0); + poly.push_back(v_init); + std::vector > to_erase; + to_erase.push_back(std::pair(ep.F(),ep.E())); + do + { + bool done=OneIntegerStep(ep); + if (!done) + { + EraseIntegerEdge(to_erase); + return false; + } + to_erase.push_back(std::pair(ep.F(),ep.E())); + TriVertexType* v_curr=ep.V(); + if ((IntegerVertices.count(v_curr)!=0)&& + (v_curr!=v_init)) + poly.push_back(v_curr); + }while(ep.V()!=v_init); EraseIntegerEdge(to_erase); return true; - } + } - void FindPolygons(TriMesh &Tmesh, - std::vector > &polygons) - { - //int limit=2; + void FindPolygons(TriMesh &Tmesh, + std::vector > &polygons) + { + //int limit=2; for (unsigned int i=0;iV0(j); + { + TriFaceType * f=&Tmesh.face[i]; + for (int j=0;j<3;j++) + { + TriVertexType* v0=f->V0(j); //TriVertexType* v1=f->V1(j); - - //std::pair edge(v0,v1);*/ - std::pair edge(f,j); - if (IntegerEdges.count(edge)==0)continue;///edge already used or not integer - if (IntegerVertices.count(v0)==0)continue; ///must start from integer vert - ///create the pos - vcg::face::Pos ep(f,j); - std::vector poly; - bool found=FindPolygon(ep,poly); - if (found) + //std::pair edge(v0,v1);*/ + std::pair edge(f,j); + if (IntegerEdges.count(edge)==0)continue;///edge already used or not integer + if (IntegerVertices.count(v0)==0)continue; ///must start from integer vert + ///create the pos + vcg::face::Pos ep(f,j); + std::vector poly; + + bool found=FindPolygon(ep,poly); + if (found) { std::reverse(poly.begin(),poly.end());///REVERSE ORDER - polygons.push_back(poly); + polygons.push_back(poly); } - } - } - - } + } + } - void InitVertexQuadMesh(TriMesh &Tmesh) - { + } + + void InitVertexQuadMesh(TriMesh &Tmesh) + { FindPolygons(Tmesh,polygons); - } + } public: - - void TestIsProper(TriMesh &Tmesh) - { - ///test manifoldness - int test=vcg::tri::Clean::CountNonManifoldVertexFF(Tmesh); + + void TestIsProper(TriMesh &Tmesh) + { + ///test manifoldness + int test=vcg::tri::Clean::CountNonManifoldVertexFF(Tmesh); //assert(test==0); if (test != 0) cerr << "Assertion failed: TestIsProper NonManifoldVertices!" << endl; - test=vcg::tri::Clean::CountNonManifoldEdgeFF(Tmesh); + test=vcg::tri::Clean::CountNonManifoldEdgeFF(Tmesh); //assert(test==0); if (test != 0) cerr << "Assertion failed: TestIsProper NonManifoldEdges" << endl; for (unsigned int i=0;iIsD()); - for (int z=0;z<3;z++) - { + { + TriFaceType *f=&Tmesh.face[i]; + assert (!f->IsD()); + for (int z=0;z<3;z++) + { //int indexOpp=f->FFi(z); TriFaceType *Fopp=f->FFp(z); - if (Fopp==f) continue; + if (Fopp==f) continue; //assert( f->FFp(z)->FFp(f->FFi(z))==f ); if (f->FFp(z)->FFp(f->FFi(z))!=f) cerr << "Assertion failed: TestIsProper f->FFp(z)->FFp(f->FFi(z))!=f " << endl; - } - } - } + } + } + } - void Quadrangulate(TriMesh &Tmesh, - PolyMesh &Pmesh, - ScalarType factor=1.0, - ScalarType tolerance=0.000001) - { + void Quadrangulate(TriMesh &Tmesh, + PolyMesh &Pmesh, + ScalarType factor=1.0, + ScalarType tolerance=0.000001) + { TestIsProper(Tmesh); - vcg::tri::AttributeSeam::SplitVertex(Tmesh, ExtractVertex, CompareVertex); + vcg::tri::AttributeSeam::SplitVertex(Tmesh, ExtractVertex, CompareVertex); vcg::tri::Allocator::CompactVertexVector(Tmesh); vcg::tri::Allocator::CompactFaceVector(Tmesh); vcg::tri::UpdateTopology::FaceFace(Tmesh); (void)Pmesh; TestIsProper(Tmesh); - ///then split the tris - SplitTris(Tmesh,factor,tolerance); - ///join the vertices back! - ScalarType EPS=(ScalarType)0.00000001; - vcg::tri::Clean::MergeCloseVertex(Tmesh,EPS); - + ///then split the tris + SplitTris(Tmesh,factor,tolerance); + ///join the vertices back! + ScalarType EPS=(ScalarType)0.00000001; + vcg::tri::Clean::MergeCloseVertex(Tmesh,EPS); + vcg::tri::UpdateNormal::PerFaceNormalized(Tmesh); // update Normals vcg::tri::UpdateNormal::PerVertexNormalized(Tmesh);// update Normals - ///compact the mesh - vcg::tri::Allocator::CompactVertexVector(Tmesh); - vcg::tri::Allocator::CompactFaceVector(Tmesh); - vcg::tri::UpdateTopology::FaceFace(Tmesh); // update Topology - vcg::tri::UpdateTopology::TestFaceFace(Tmesh); //and test it - ///set flags - vcg::tri::UpdateFlags::VertexClearV(Tmesh); - vcg::tri::UpdateFlags::FaceBorderFromFF(Tmesh); - vcg::tri::UpdateFlags::VertexBorderFromFace(Tmesh); - ///test manifoldness + ///compact the mesh + vcg::tri::Allocator::CompactVertexVector(Tmesh); + vcg::tri::Allocator::CompactFaceVector(Tmesh); + vcg::tri::UpdateTopology::FaceFace(Tmesh); // update Topology + vcg::tri::UpdateTopology::TestFaceFace(Tmesh); //and test it + ///set flags + vcg::tri::UpdateFlags::VertexClearV(Tmesh); + vcg::tri::UpdateFlags::FaceBorderFromFF(Tmesh); + vcg::tri::UpdateFlags::VertexBorderFromFace(Tmesh); + ///test manifoldness TestIsProper(Tmesh); - vcg::tri::UpdateFlags::VertexClearV(Tmesh); + vcg::tri::UpdateFlags::VertexClearV(Tmesh); - InitIntegerEdgesVert(Tmesh,factor,tolerance); - InitVertexQuadMesh(Tmesh); - } + InitIntegerEdgesVert(Tmesh,factor,tolerance); + InitVertexQuadMesh(Tmesh); + + ///then add to the polygonal mesh + Pmesh.Clear(); + ///first create vertices + vcg::tri::Allocator::AddVertices(Pmesh,IntegerVertex.size()); + std::map VertMap; + for(unsigned int i=0;iP(); + CoordType norm=IntegerVertex[i]->N(); + Pmesh.vert[i].P()=typename PolyMesh::CoordType(pos.X(),pos.Y(),pos.Z()); + Pmesh.vert[i].N()=typename PolyMesh::CoordType(norm.X(),norm.Y(),norm.Z()); + VertMap[IntegerVertex[i]]=i; + } + ///then add polygonal mesh + vcg::tri::Allocator::AddFaces(Pmesh,polygons.size()); + for (unsigned int i=0;i