From 9d41b0f0d166ddaa27e8efe6a5f4d139e48cc3f0 Mon Sep 17 00:00:00 2001 From: Nico Pietroni nicopietroni Date: Fri, 16 Oct 2009 14:58:15 +0000 Subject: [PATCH] --- .../dual_coord_optimization.h | 5 +- .../filter_isoparametrization.cpp | 14 +- .../local_optimization.h | 18 +- .../local_parametrization.h | 45 +- .../mesh_operators.h | 775 +++++++++--------- .../filter_isoparametrization/opt_patch.h | 88 +- .../param_collapse.h | 60 +- .../filter_isoparametrization/param_flip.h | 32 +- .../parametrizator.h | 50 +- 9 files changed, 606 insertions(+), 481 deletions(-) diff --git a/src/meshlabplugins/filter_isoparametrization/dual_coord_optimization.h b/src/meshlabplugins/filter_isoparametrization/dual_coord_optimization.h index e2905747f..373be02ed 100644 --- a/src/meshlabplugins/filter_isoparametrization/dual_coord_optimization.h +++ b/src/meshlabplugins/filter_isoparametrization/dual_coord_optimization.h @@ -490,8 +490,9 @@ void MinimizeStep(const int &phaseNum) //assert(0); } assert(inside); - OrigVert->father=chosen; - OrigVert->Bary=bary; + //OrigVert->father=chosen; + //OrigVert->Bary=bary; + AssingFather(*OrigVert,chosen,bary,*domain); } } ///delete current mesh diff --git a/src/meshlabplugins/filter_isoparametrization/filter_isoparametrization.cpp b/src/meshlabplugins/filter_isoparametrization/filter_isoparametrization.cpp index 84aff88a5..4963391bd 100644 --- a/src/meshlabplugins/filter_isoparametrization/filter_isoparametrization.cpp +++ b/src/meshlabplugins/filter_isoparametrization/filter_isoparametrization.cpp @@ -124,9 +124,10 @@ void FilterIsoParametrization::initParameterSet(QAction *a, MeshDocument& /*md*/ "2: Area + Angle : stop at minimum area and angle distorsion
" "3: Regularity : stop at minimum number of irregular vertices
" "4: L2 : stop at minimum OneWay L2 Stretch Eff"))); - + //par.addParam(new RichDynamicFloat("convergenceSpeed", 1, 1,4, "Convergence Speed", "This parameter controls the convergence speed/precision of the optimization of the texture coordinates. Larger the number slower the processing and ,eventually, slighly better results"); par.addParam(new RichInt("convergenceSpeed",2, "Convergence Speed", "This parameter controls the convergence speed/precision of the optimization of the texture coordinates. Larger the number slower the processing and ,eventually, slighly better results")); + par.addParam(new RichBool("DoubleStep",true,"Double Step","Use this bool to divide the parameterization in 2 steps. Double step makes the overall process faster and robust, but it may increase the distorsion")); break; } case ISOP_REMESHING : @@ -211,6 +212,7 @@ bool FilterIsoParametrization::applyFilter(QAction *filter, MeshDocument& md, Ri int targetAbstractMaxFaceNum = par.getInt("targetAbstractMaxFaceNum"); int convergenceSpeed = par.getInt("convergenceSpeed"); int stopCriteria=par.getEnum("stopCriteria"); + bool doublestep=par.getBool("DoubleStep"); IsoParametrizator Parametrizator; bool isTXTenabled=m->hasDataMask(MeshModel::MM_VERTTEXCOORD); @@ -241,7 +243,8 @@ bool FilterIsoParametrization::applyFilter(QAction *filter, MeshDocument& md, Ri case 3:Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_L2,convergenceSpeed);break; default:Parametrizator.SetParameters(cb,targetAbstractMinFaceNum,tolerance,IsoParametrizator::SM_Euristic,convergenceSpeed);break; } - bool done=Parametrizator.Parametrize(mesh); + bool done=Parametrizator.Parametrize(mesh,doublestep); + float aggregate,L2; int n_faces; Parametrizator.getValues(aggregate,L2,n_faces); @@ -263,7 +266,12 @@ bool FilterIsoParametrization::applyFilter(QAction *filter, MeshDocument& md, Ri } Parametrizator.ExportMeshes(para_mesh,abs_mesh); isoPHandle=vcg::tri::Allocator::AddPerMeshAttribute(*mesh,"isoparametrization"); - isoPHandle().Init(&abs_mesh,¶_mesh); + bool isOK=isoPHandle().Init(&abs_mesh,¶_mesh); + if (!isOK) + { + Log("Problems gathering parameterization \n"); + return false; + } if (!isTXTenabled) m->clearDataMask(MeshModel::MM_VERTTEXCOORD); if (!isVMarkenabled) diff --git a/src/meshlabplugins/filter_isoparametrization/local_optimization.h b/src/meshlabplugins/filter_isoparametrization/local_optimization.h index 90dd97202..acd6fd014 100644 --- a/src/meshlabplugins/filter_isoparametrization/local_optimization.h +++ b/src/meshlabplugins/filter_isoparametrization/local_optimization.h @@ -106,7 +106,7 @@ typename MeshType::ScalarType StarDistorsion(typename MeshType::VertexType *v) ///optimize a single star template -void OptimizeStar(typename MeshType::VertexType *v,int accuracy=1) +void OptimizeStar(typename MeshType::VertexType *v,MeshType &domain,int accuracy=1) { typedef typename MeshType::VertexType VertexType; typedef typename MeshType::FaceType FaceType; @@ -229,8 +229,10 @@ void OptimizeStar(typename MeshType::VertexType *v,int accuracy=1) ///restore old coordinates and return for (unsigned int k=0;kIsD()); + hlev_mesh.vert[k].Bary=oldBary[k];*/ + AssingFather(hlev_mesh.vert[k],oldFath[k],oldBary[k],domain); } CoordType val; bool found1=GetCoordFromUV(hlev_mesh,0,0,val,true); @@ -239,8 +241,10 @@ void OptimizeStar(typename MeshType::VertexType *v,int accuracy=1) return; } - to_reassing->father=chosen; - to_reassing->Bary=bary; + //to_reassing->father=chosen; + //assert(!chosen->IsD()); + //to_reassing->Bary=bary; + AssingFather(*to_reassing,chosen,bary,domain); } ///clear father and bary @@ -272,7 +276,7 @@ void OptimizeStar(typename MeshType::VertexType *v,int accuracy=1) template -bool SmartOptimizeStar(typename MeshType::VertexType *center,int accuracy=1) +bool SmartOptimizeStar(typename MeshType::VertexType *center,MeshType &base_domain,int accuracy=1) { typedef typename MeshType::VertexType VertexType; typedef typename MeshType::FaceType FaceType; @@ -293,7 +297,7 @@ bool SmartOptimizeStar(typename MeshType::VertexType *center,int accuracy=1) if (ratio<=1) return false; else - OptimizeStar(center,accuracy); + OptimizeStar(center,base_domain,accuracy); return true; } #endif diff --git a/src/meshlabplugins/filter_isoparametrization/local_parametrization.h b/src/meshlabplugins/filter_isoparametrization/local_parametrization.h index a6e1293f3..9d3d0cb27 100644 --- a/src/meshlabplugins/filter_isoparametrization/local_parametrization.h +++ b/src/meshlabplugins/filter_isoparametrization/local_parametrization.h @@ -739,6 +739,26 @@ bool NormalizeBaryCoords(CoordType &bary) return true; } +template +void AssingFather(typename MeshType::VertexType &v, + typename MeshType::FaceType *father, + typename MeshType::CoordType &bary, + MeshType &domain) +{ + const MeshType::ScalarType eps=0.00001; + assert((father-&(*domain.face.begin()))IsD())); + assert(!(father==NULL)); + assert((bary.X()>=0)&&(bary.X()<=1)&& + (bary.Y()>=0)&&(bary.Y()<=1)&& + (bary.Z()>=0)&&(bary.Z()<=1)&& + ((bary.X()+bary.Y()+bary.Z())<=1+eps)&& + ((bary.X()+bary.Y()+bary.Z())>=1-eps)); + + v.father=father; + v.Bary=bary; +} + template bool testParametrization(MeshType &domain, MeshType &Hlev) @@ -751,25 +771,33 @@ bool testParametrization(MeshType &domain, int num_del=0; int num_null=0; int fath_son=0; + int wrong_address=0; for (unsigned int i=0;ifather==NULL) + bool isGoodAddr=true; + if ((v->father-&(*domain.face.begin()))>=domain.face.size()) + { + printf("\n ADDRESS EXCEEDS OF %d \n",v->father-&(*domain.face.begin())); + wrong_address++; + is_good=false; + isGoodAddr=false; + } + if ((isGoodAddr)&&(v->father==NULL)) { //printf("\n PAR ERROR : father NULL\n"); num_null++; is_good=false; } - if (v->father->IsD()) + if ((isGoodAddr)&&(v->father->IsD())) { //printf("\n PAR ERROR : father DELETED \n"); num_del++; is_good=false; } - if (!(((v->Bary.X()>=0)&&(v->Bary.X()<=1))&& + if ((isGoodAddr)&&(!(((v->Bary.X()>=0)&&(v->Bary.X()<=1))&& ((v->Bary.Y()>=0)&&(v->Bary.Y()<=1))&& - ((v->Bary.Z()>=0)&&(v->Bary.Z()<=1)))) + ((v->Bary.Z()>=0)&&(v->Bary.Z()<=1))))) { printf("\n PAR ERROR : bary coords exceeds: %f,%f,%f \n",v->Bary.X(),v->Bary.Y(),v->Bary.Z()); is_good=false; @@ -798,6 +826,11 @@ bool testParametrization(MeshType &domain, printf("\n PAR ERROR %d Father isNull \n",num_null); if (fath_son>0) printf("\n PAR ERROR %d Father<->son \n",fath_son); + if (wrong_address>0) + { + printf("\n PAR ERROR %d Wrong Address Num Faces %d\n",wrong_address,domain.fn); + system("pause"); + } return (is_good); } @@ -961,7 +994,7 @@ void ParametrizeStarEquilateral(MeshType ¶metrized, } ///final assert parametrization - assert(!NonFolded(parametrized)); + assert(NonFolded(parametrized)); } diff --git a/src/meshlabplugins/filter_isoparametrization/mesh_operators.h b/src/meshlabplugins/filter_isoparametrization/mesh_operators.h index 01c8fda71..ec908bfa9 100644 --- a/src/meshlabplugins/filter_isoparametrization/mesh_operators.h +++ b/src/meshlabplugins/filter_isoparametrization/mesh_operators.h @@ -33,9 +33,9 @@ void UpdateTopologies(MeshType *mesh) template void FindNotBorderVertices(MeshType &mesh, - std::vector &vertices) + std::vector &vertices) { - typename MeshType::VertexIterator Vi; + typename MeshType::VertexIterator Vi; for (Vi=mesh.vert.begin();Vi!=mesh.vert.end();Vi++) if ((!(*Vi).IsD())&&(!(*Vi).IsB())) vertices.push_back(&(*Vi)); @@ -48,7 +48,7 @@ typename MeshType::ScalarType AspectRatio(const MeshType &mesh) { typedef typename MeshType::ScalarType ScalarType; ScalarType res=0; - typename MeshType::ConstFaceIterator Fi; + typename MeshType::ConstFaceIterator Fi; for (Fi=mesh.face.begin();Fi!=mesh.face.end();Fi++) if ((!(*Fi).IsD())) res+=vcg::QualityRadii((*Fi).P(0),(*Fi).P(1),(*Fi).P(2)); @@ -78,15 +78,15 @@ typename MeshType::ScalarType Area(MeshType &mesh) typedef typename MeshType::ScalarType ScalarType; ScalarType res=0.0; for (unsigned int i=0;iIsD()) { - typename MeshType::FaceType *f=&mesh.face[i]; - if (!f->IsD()) - { - ScalarType area=((f->P(1)-f->P(0))^(f->P(2)-f->P(0))).Norm(); - //ScalarType area=((f->V(1)->RPos-f->V(0)->RPos)^(f->V(2)->RPos-f->V(0)->RPos)).Norm(); - res+=area; - } + ScalarType area=((f->P(1)-f->P(0))^(f->P(2)-f->P(0))).Norm(); + //ScalarType area=((f->V(1)->RPos-f->V(0)->RPos)^(f->V(2)->RPos-f->V(0)->RPos)).Norm(); + res+=area; } + } return (res); } @@ -97,14 +97,14 @@ typename FaceType::ScalarType Area(std::vector &faces) typedef typename FaceType::ScalarType ScalarType; ScalarType res=0.0; for (unsigned int i=0;iIsD()) { - FaceType *f=faces[i]; - if (!f->IsD()) - { - ScalarType area=((f->P(1)-f->P(0))^(f->P(2)-f->P(0))).Norm(); - res+=area; - } + ScalarType area=((f->P(1)-f->P(0))^(f->P(2)-f->P(0))).Norm(); + res+=area; } + } return (res); } @@ -139,7 +139,7 @@ typename MeshType::ScalarType AreaDispersion(MeshType &mesh) ScalarType res=0; for (unsigned int i=0;iIsD())) { ScalarType area=((f->P(1)-f->P(0))^(f->P(2)-f->P(0))).Norm(); @@ -153,11 +153,11 @@ typename MeshType::ScalarType AreaDispersion(MeshType &mesh) template void FindVertices(const std::vector &faces, - std::vector &vertices) + std::vector &vertices) { typedef typename FaceType::VertexType VertexType; - - typename std::vector::const_iterator iteF; + + typename std::vector::const_iterator iteF; for (iteF=faces.begin();iteF!=faces.end();iteF++) { assert(!(*iteF)->IsD()); @@ -168,21 +168,21 @@ void FindVertices(const std::vector &faces, } } std::sort(vertices.begin(),vertices.end()); - typename std::vector::iterator new_end=std::unique(vertices.begin(),vertices.end()); + typename std::vector::iterator new_end=std::unique(vertices.begin(),vertices.end()); int dist=distance(vertices.begin(),new_end); vertices.resize(dist); } template void FindSortedBorderVertices(const MeshType &/*mesh*/, - typename MeshType::VertexType *Start, - std::vector &vertices) + typename MeshType::VertexType *Start, + std::vector &vertices) { typedef typename MeshType::CoordType CoordType; typedef typename MeshType::ScalarType ScalarType; typedef typename MeshType::VertexType VertexType; typedef typename MeshType::FaceType FaceType; - + ///find first half edge border vcg::face::VFIterator vfi(Start); FaceType *f=(vfi.F()); @@ -192,9 +192,9 @@ void FindSortedBorderVertices(const MeshType &/*mesh*/, vcg::face::Pos pos=vcg::face::Pos(f,edge,Start); do - pos.NextE(); + pos.NextE(); while(!pos.IsBorder()); - + ///then follow the border and put vertices into the vector do { assert(!pos.V()->IsD()); @@ -206,87 +206,87 @@ void FindSortedBorderVertices(const MeshType &/*mesh*/, template void CopyMeshFromFaces(const std::vector &faces, - std::vector &orderedVertex, - MeshType & new_mesh) + std::vector &orderedVertex, + MeshType & new_mesh) { - typedef typename MeshType::CoordType CoordType; - typedef typename MeshType::ScalarType ScalarType; - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + typedef typename MeshType::ScalarType ScalarType; + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; - ///get set of faces - std::map vertexmap; - std::vector vertices; - FindVertices(faces,vertices); + ///get set of faces + std::map vertexmap; + std::vector vertices; + FindVertices(faces,vertices); - ///initialization of new mesh - new_mesh.Clear(); - new_mesh.vn=0; - new_mesh.fn=0; - new_mesh.face.resize(faces.size()); - new_mesh.vert.resize(vertices.size()); - new_mesh.vn=vertices.size(); - new_mesh.fn=faces.size(); + ///initialization of new mesh + new_mesh.Clear(); + new_mesh.vn=0; + new_mesh.fn=0; + new_mesh.face.resize(faces.size()); + new_mesh.vert.resize(vertices.size()); + new_mesh.vn=vertices.size(); + new_mesh.fn=faces.size(); - ///add new vertices - typename std::vector::const_iterator iteV; - int i=0; - for (iteV=vertices.begin();iteV!=vertices.end();iteV++) - { - ///copy position - assert(!(*iteV)->IsD()); - new_mesh.vert[i].P()=(*iteV)->P(); - new_mesh.vert[i].RPos=(*iteV)->RPos; - new_mesh.vert[i].T().P()=(*iteV)->T().P(); - new_mesh.vert[i].N()=(*iteV)->N(); - /*assert(new_mesh.vert[i].brother!=NULL);*/ - //if (MeshType::Has_Auxiliary()) - new_mesh.vert[i].brother=(*iteV)->brother; - new_mesh.vert[i].ClearFlags(); + ///add new vertices + typename std::vector::const_iterator iteV; + int i=0; + for (iteV=vertices.begin();iteV!=vertices.end();iteV++) + { + ///copy position + assert(!(*iteV)->IsD()); + new_mesh.vert[i].P()=(*iteV)->P(); + new_mesh.vert[i].RPos=(*iteV)->RPos; + new_mesh.vert[i].T().P()=(*iteV)->T().P(); + new_mesh.vert[i].N()=(*iteV)->N(); + /*assert(new_mesh.vert[i].brother!=NULL);*/ + //if (MeshType::Has_Auxiliary()) + new_mesh.vert[i].brother=(*iteV)->brother; + new_mesh.vert[i].ClearFlags(); - orderedVertex.push_back((*iteV)); - vertexmap.insert(std::pair((*iteV),&new_mesh.vert[i])); - i++; - } + orderedVertex.push_back((*iteV)); + vertexmap.insert(std::pair((*iteV),&new_mesh.vert[i])); + i++; + } - ///setting of new faces - typename std::vector::const_iterator iteF; - typename std::vector::iterator iteF1; - for (iteF=faces.begin(),iteF1=new_mesh.face.begin() - ;iteF!=faces.end();iteF++,iteF1++) - { - (*iteF1).areadelta=(*iteF)->areadelta; - /* if ((*iteF1).areadelta>1) - assert(0);*/ - ///for each vertex get new reference - ///and associate face-vertex - for (int j=0;j<3;j++) - { - VertexType* v=(*iteF)->V(j); - typename std::map::iterator iteMap=vertexmap.find(v); - assert(iteMap!=vertexmap.end()); - (*iteF1).V(j)=(*iteMap).second; - } - } + ///setting of new faces + typename std::vector::const_iterator iteF; + typename std::vector::iterator iteF1; + for (iteF=faces.begin(),iteF1=new_mesh.face.begin() + ;iteF!=faces.end();iteF++,iteF1++) + { + (*iteF1).areadelta=(*iteF)->areadelta; + /* if ((*iteF1).areadelta>1) + assert(0);*/ + ///for each vertex get new reference + ///and associate face-vertex + for (int j=0;j<3;j++) + { + VertexType* v=(*iteF)->V(j); + typename std::map::iterator iteMap=vertexmap.find(v); + assert(iteMap!=vertexmap.end()); + (*iteF1).V(j)=(*iteMap).second; + } + } +} +template +inline void getHresVertex(std::vector &domain, + std::vector &Hres) +{ + for (unsigned int i=0;ivertices_bary.size();j++) + if (f->vertices_bary[j].first->father==f) + Hres.push_back(f->vertices_bary[j].first); + } } - template - inline void getHresVertex(std::vector &domain, - std::vector &Hres) - { - for (unsigned int i=0;ivertices_bary.size();j++) - if (f->vertices_bary[j].first->father==f) - Hres.push_back(f->vertices_bary[j].first); - } - } ///copy mesh low level & high level ///putting the link between them toghether template void CopySubMeshLevels(std::vector &faces, - MeshType &Domain,MeshType &hlevMesh) + MeshType &Domain,MeshType &hlevMesh) { typedef typename MeshType::CoordType CoordType; typedef typename MeshType::ScalarType ScalarType; @@ -299,11 +299,11 @@ void CopySubMeshLevels(std::vector &faces, ///update topologies UpdateTopologies(&Domain); - + ///get the high resolution mesh std::vector HresVert; getHresVertex(faces,HresVert); - + ///copy mesh from vertices std::vector OrderedFaces; CopyMeshFromVertices(HresVert,ordVertexH,OrderedFaces,hlevMesh); @@ -313,14 +313,18 @@ void CopySubMeshLevels(std::vector &faces, for (unsigned int i=0;i::iterator iteFath; + typename std::vector::iterator iteFath; iteFath=std::find(faces.begin(),faces.end(),father); if (iteFath!=faces.end()) { int position=std::distance(faces.begin(),iteFath); + AssingFather(hlevMesh.vert[i],&Domain.face[position],bary,Domain); ///associate new father - hlevMesh.vert[i].father=&Domain.face[position]; + //hlevMesh.vert[i].father=&Domain.face[position]; + //assert(!Domain.face[position].IsD()); + } } @@ -333,107 +337,107 @@ void CopySubMeshLevels(std::vector &faces, VertexType *son=&hlevMesh.vert[i]; FaceType *father=son->father; CoordType bary=son->Bary; - father->vertices_bary.push_back(std::pair(son,bary)); + father->vertices_bary.push_back(std::pair(son,bary)); } } ///return in result the intersection, while in_v0 and in_v1 return ///faces shareb by each vertex template inline bool getSharedFace(typename MeshType::VertexType *v0, - typename MeshType::VertexType *v1, - std::vector &result, - std::vector &in_v0, - std::vector &in_v1) - { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; + typename MeshType::VertexType *v1, + std::vector &result, + std::vector &in_v0, + std::vector &in_v1) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; - result.clear(); - result.reserve(2); - vcg::face::VFIterator vfi0(v0); //initialize the iterator to the first vertex - vcg::face::VFIterator vfi1(v1); //initialize the iterator to the first vertex - vcg::face::VFIterator vfi2(v0); //initialize the iterator to the first vertex + result.clear(); + result.reserve(2); + vcg::face::VFIterator vfi0(v0); //initialize the iterator to the first vertex + vcg::face::VFIterator vfi1(v1); //initialize the iterator to the first vertex + vcg::face::VFIterator vfi2(v0); //initialize the iterator to the first vertex - std::set faces0; + std::set faces0; - ///faces in v0 - for(;!vfi0.End();++vfi0) - faces0.insert(vfi0.F()); + ///faces in v0 + for(;!vfi0.End();++vfi0) + faces0.insert(vfi0.F()); - ///faces in v1 + intersection between both - for(;!vfi1.End();++vfi1) - if (faces0.count(vfi1.F())!=0) - result.push_back(vfi1.F()); - else - in_v1.push_back(vfi1.F()); + ///faces in v1 + intersection between both + for(;!vfi1.End();++vfi1) + if (faces0.count(vfi1.F())!=0) + result.push_back(vfi1.F()); + else + in_v1.push_back(vfi1.F()); - ///faces in v0 - bool non_shared=(result.size()==0); - if (non_shared) - return false; - bool border=(result.size()==1); - for(;!vfi2.End();++vfi2) - { - if (non_shared) - in_v0.push_back(vfi2.F()); - else - { - if ((!border)&&((result[0]!=vfi2.F())&&(result[1]!=vfi2.F()))) - in_v0.push_back(vfi2.F()); - else - if ((border)&&((result[0]!=vfi2.F()))) - in_v0.push_back(vfi2.F()); - } - } - } + ///faces in v0 + bool non_shared=(result.size()==0); + if (non_shared) + return false; + bool border=(result.size()==1); + for(;!vfi2.End();++vfi2) + { + if (non_shared) + in_v0.push_back(vfi2.F()); + else + { + if ((!border)&&((result[0]!=vfi2.F())&&(result[1]!=vfi2.F()))) + in_v0.push_back(vfi2.F()); + else + if ((border)&&((result[0]!=vfi2.F()))) + in_v0.push_back(vfi2.F()); + } + } +} template inline void getSharedFace(std::vector &vertices, - std::vector &faces) - { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; + std::vector &faces) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; - typename std::vector::const_iterator vi; + typename std::vector::const_iterator vi; - for (vi=vertices.begin();vi!=vertices.end();vi++) - { - assert(!(*vi)->IsD()); - int num=0; - vcg::face::VFIterator vfi(*vi); - while (!vfi.End()) - { - assert(!vfi.F()->IsD()); - faces.push_back(vfi.F()); - num++; - ++vfi; - } - } + for (vi=vertices.begin();vi!=vertices.end();vi++) + { + assert(!(*vi)->IsD()); + int num=0; + vcg::face::VFIterator vfi(*vi); + while (!vfi.End()) + { + assert(!vfi.F()->IsD()); + faces.push_back(vfi.F()); + num++; + ++vfi; + } + } - ///sort and unique - std::sort(faces.begin(),faces.end()); - typename std::vector::iterator new_end=std::unique(faces.begin(),faces.end()); - int dist=distance(faces.begin(),new_end); - faces.resize(dist); - } + ///sort and unique + std::sort(faces.begin(),faces.end()); + typename std::vector::iterator new_end=std::unique(faces.begin(),faces.end()); + int dist=distance(faces.begin(),new_end); + faces.resize(dist); +} ///create a mesh considering just the faces that share all three vertex template void CopyMeshFromVertices(std::vector &vertices, - std::vector &OrderedVertices, - std::vector &OrderedFaces, - MeshType & new_mesh) + std::vector &OrderedVertices, + std::vector &OrderedFaces, + MeshType & new_mesh) { - typedef typename MeshType::CoordType CoordType; - typedef typename MeshType::ScalarType ScalarType; - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + typedef typename MeshType::ScalarType ScalarType; + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; - typename std::vector::const_iterator iteV; + typename std::vector::const_iterator iteV; for (iteV=vertices.begin();iteV!=vertices.end();iteV++) (*iteV)->ClearV(); @@ -443,22 +447,22 @@ void CopyMeshFromVertices(std::vector &vertices, std::map vertexmap; ///get set of faces - std::vector faces; + std::vector faces; getSharedFace(vertices,faces); - + ///initialization of new mesh new_mesh.Clear(); new_mesh.vn=0; new_mesh.fn=0; ///set vertices as selected - + for (iteV=vertices.begin();iteV!=vertices.end();iteV++) (*iteV)->SetV(); ///getting inside faces - typename std::vector::const_iterator iteF; + typename std::vector::const_iterator iteF; for (iteF=faces.begin();iteF!=faces.end();iteF++) { ///for each vertex get new reference @@ -470,7 +474,7 @@ void CopyMeshFromVertices(std::vector &vertices, if (inside) OrderedFaces.push_back((*iteF)); } - + ///find internal vertices FindVertices(OrderedFaces,OrderedVertices); @@ -482,7 +486,7 @@ void CopyMeshFromVertices(std::vector &vertices, ///setting of internal vertices int i=0; - typename std::vector::iterator iteVI; + typename std::vector::iterator iteVI; for (iteVI=OrderedVertices.begin();iteVI!=OrderedVertices.end();iteVI++) { ///copy position @@ -491,6 +495,7 @@ void CopyMeshFromVertices(std::vector &vertices, new_mesh.vert[i].RPos=(*iteVI)->RPos; new_mesh.vert[i].T().P()=(*iteVI)->T().P(); new_mesh.vert[i].father=(*iteVI)->father; + assert(!(*iteVI)->father->IsD()); new_mesh.vert[i].Bary=(*iteVI)->Bary; //new_mesh.vert[i].Damp=(*iteVI)->Damp; new_mesh.vert[i].RestUV=(*iteVI)->RestUV; @@ -504,7 +509,7 @@ void CopyMeshFromVertices(std::vector &vertices, } ///setting of new faces - typename std::vector::iterator iteF1; + typename std::vector::iterator iteF1; for (iteF=OrderedFaces.begin(),iteF1=new_mesh.face.begin() ;iteF!=OrderedFaces.end();iteF++,iteF1++) { @@ -513,7 +518,7 @@ void CopyMeshFromVertices(std::vector &vertices, for (int j=0;j<3;j++) { VertexType* v=(*iteF)->V(j); - typename std::map::iterator iteMap=vertexmap.find(v); + typename std::map::iterator iteMap=vertexmap.find(v); assert(iteMap!=vertexmap.end()); (*iteF1).V(j)=(*iteMap).second; } @@ -541,26 +546,26 @@ void CopyMeshFromVertices(std::vector &vertices, template inline void getSharedVertex(const std::vector &faces, - std::vector &vertices) + std::vector &vertices) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + + typename std::vector::const_iterator fi; + for (fi=faces.begin();fi!=faces.end();fi++) { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; - - typename std::vector::const_iterator fi; - for (fi=faces.begin();fi!=faces.end();fi++) - { - assert(!(*fi)->IsD()); - for (int j=0;j<3;j++) - vertices.push_back((*fi)->V(j)); - } - - ///sort and unique - std::sort(vertices.begin(),vertices.end()); - typename std::vector::iterator new_end=std::unique(vertices.begin(),vertices.end()); - int dist=distance(vertices.begin(),new_end); - vertices.resize(dist); + assert(!(*fi)->IsD()); + for (int j=0;j<3;j++) + vertices.push_back((*fi)->V(j)); } + + ///sort and unique + std::sort(vertices.begin(),vertices.end()); + typename std::vector::iterator new_end=std::unique(vertices.begin(),vertices.end()); + int dist=distance(vertices.begin(),new_end); + vertices.resize(dist); +} // //template //inline ScalarType GeoDesic() @@ -570,210 +575,210 @@ inline void getSharedVertex(const std::vector &fac //} template inline int EdgeIndex(const FaceType* test_face, - const typename FaceType::VertexType* v0, - const typename FaceType::VertexType* v1) + const typename FaceType::VertexType* v0, + const typename FaceType::VertexType* v1) { ///get edge index int edge_index=0; if (((test_face->cV(1)==v0)&&(test_face->cV(2)==v1))|| - ((test_face->cV(2)==v0)&&(test_face->cV(1)==v1))) + ((test_face->cV(2)==v0)&&(test_face->cV(1)==v1))) edge_index=1; else - if (((test_face->cV(2)==v0)&&(test_face->cV(0)==v1))|| - ((test_face->cV(0)==v0)&&(test_face->cV(2)==v1))) - edge_index=2; - else - assert(((test_face->cV(0)==v0)&&(test_face->cV(1)==v1))|| + if (((test_face->cV(2)==v0)&&(test_face->cV(0)==v1))|| + ((test_face->cV(0)==v0)&&(test_face->cV(2)==v1))) + edge_index=2; + else + assert(((test_face->cV(0)==v0)&&(test_face->cV(1)==v1))|| ((test_face->cV(1)==v0)&&(test_face->cV(0)==v1))); return edge_index; } - ////ATTENTIOn to change if v0 is border - template - inline void getVertexStar(typename MeshType::VertexType *v, - std::vector &star) +////ATTENTIOn to change if v0 is border +template +inline void getVertexStar(typename MeshType::VertexType *v, + std::vector &star) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + + assert(!v->IsB()); + vcg::face::VFIterator vfi(v); + ///get a face and an edge + FaceType *f=vfi.F(); + int edge=vfi.I(); + vcg::face::Pos pos=vcg::face::Pos(f,edge,v); + do { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; + pos.FlipV(); + if (!pos.V()->IsD()) + star.push_back(pos.V()); + pos.FlipV(); - assert(!v->IsB()); - vcg::face::VFIterator vfi(v); - ///get a face and an edge - FaceType *f=vfi.F(); - int edge=vfi.I(); - vcg::face::Pos pos=vcg::face::Pos(f,edge,v); - do - { - pos.FlipV(); - if (!pos.V()->IsD()) - star.push_back(pos.V()); - pos.FlipV(); - - pos.NextE(); - } - while (pos.F()!=f); + pos.NextE(); } + while (pos.F()!=f); +} - ////ATTENTIOn to change if v0 is border - template - inline void getSharedVertexStar(typename MeshType::VertexType *v0, - typename MeshType::VertexType *v1, - std::vector &shared) +////ATTENTIOn to change if v0 is border +template +inline void getSharedVertexStar(typename MeshType::VertexType *v0, + typename MeshType::VertexType *v1, + std::vector &shared) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + typedef typename std::vector::iterator iteVert; + std::vector star0; + std::vector star1; + getVertexStar(v0,star0); + getVertexStar(v1,star1); + std::sort(star0.begin(),star0.end()); + std::sort(star1.begin(),star1.end()); + shared.resize(std::max(star0.size(),star1.size())); + iteVert intersEnd=std::set_intersection(star0.begin(),star0.end(),star1.begin(),star1.end(),shared.begin()); + int dist=distance(shared.begin(),intersEnd); + shared.resize(dist); +} + +template +inline typename MeshType::ScalarType StarAspectRatio(const std::vector &starCenters) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + typedef typename MeshType::ScalarType ScalarType; + + std::vector orderedFaces; + getSharedFace(starCenters,orderedFaces); + + ScalarType res=0.0; + + typename std::vector::iterator Fi; + for (Fi=orderedFaces.begin();Fi!=orderedFaces.end();Fi++) + res+=vcg::QualityRadii((*Fi)->P(0),(*Fi)->P(1),(*Fi)->P(2)); + + return (res/(ScalarType)orderedFaces.size()); +} + +template +inline typename MeshType::ScalarType StarDispersion(const std::vector &starCenters) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + typedef typename MeshType::ScalarType ScalarType; + + std::vector orderedFaces; + getSharedFace(starCenters,orderedFaces); + + ScalarType average_area=0.0; + + typename std::vector::iterator Fi; + for (Fi=orderedFaces.begin();Fi!=orderedFaces.end();Fi++) + average_area+=(((*Fi)->P(1)-(*Fi)->P(0))^((*Fi)->P(2)-(*Fi)->P(0))).Norm(); + + average_area/=(ScalarType)orderedFaces.size(); + + ScalarType res=0; + for (Fi=orderedFaces.begin();Fi!=orderedFaces.end();Fi++) { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; - typedef typename std::vector::iterator iteVert; - std::vector star0; - std::vector star1; - getVertexStar(v0,star0); - getVertexStar(v1,star1); - std::sort(star0.begin(),star0.end()); - std::sort(star1.begin(),star1.end()); - shared.resize(std::max(star0.size(),star1.size())); - iteVert intersEnd=std::set_intersection(star0.begin(),star0.end(),star1.begin(),star1.end(),shared.begin()); - int dist=distance(shared.begin(),intersEnd); - shared.resize(dist); + ScalarType area=(((*Fi)->P(1)-(*Fi)->P(0))^((*Fi)->P(2)-(*Fi)->P(0))).Norm(); + res+=std::max((area/average_area),(average_area/area)); } + return (res/(ScalarType)orderedFaces.size()); +} - template - inline typename MeshType::ScalarType StarAspectRatio(const std::vector &starCenters) +template +inline void CreateMeshVertexStar(std::vector &starCenters, + std::vector &orderedFaces, + MeshType &created) +{ + ///get faces referenced by vertices + std::vector orderedVertex; + getSharedFace(starCenters,orderedFaces); + CopyMeshFromFaces(orderedFaces,orderedVertex,created); +} + +template +inline void CreateMeshVertexStar(std::vector &starCenters, + std::vector &orderedFaces, + std::vector &orderedVertex, + MeshType &created) +{ + ///get faces referenced by vertices + getSharedFace(starCenters,orderedFaces); + CopyMeshFromFaces(orderedFaces,orderedVertex,created); +} + +template +inline void getAroundFaceVertices(typename MeshType::VertexType *v0, + typename MeshType::VertexType *v1, + std::vector &result, + std::vector &on_edge, + std::vector &in_v0, + std::vector &in_v1) +{ + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::CoordType CoordType; + + getSharedFace(v0,v1,on_edge,in_v0,in_v1); + + std::set Added; + + CoordType Center=CoordType(0,0,0); + int num=0; + + ///get all vertices around the collapse + for (int i=0;i orderedFaces; - getSharedFace(starCenters,orderedFaces); - - ScalarType res=0.0; - - typename std::vector::iterator Fi; - for (Fi=orderedFaces.begin();Fi!=orderedFaces.end();Fi++) - res+=vcg::QualityRadii((*Fi)->P(0),(*Fi)->P(1),(*Fi)->P(2)); - - return (res/(ScalarType)orderedFaces.size()); - } - - template - inline typename MeshType::ScalarType StarDispersion(const std::vector &starCenters) - { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; - typedef typename MeshType::ScalarType ScalarType; - - std::vector orderedFaces; - getSharedFace(starCenters,orderedFaces); - - ScalarType average_area=0.0; - - typename std::vector::iterator Fi; - for (Fi=orderedFaces.begin();Fi!=orderedFaces.end();Fi++) - average_area+=(((*Fi)->P(1)-(*Fi)->P(0))^((*Fi)->P(2)-(*Fi)->P(0))).Norm(); - - average_area/=(ScalarType)orderedFaces.size(); - - ScalarType res=0; - for (Fi=orderedFaces.begin();Fi!=orderedFaces.end();Fi++) - { - ScalarType area=(((*Fi)->P(1)-(*Fi)->P(0))^((*Fi)->P(2)-(*Fi)->P(0))).Norm(); - res+=std::max((area/average_area),(average_area/area)); - } - return (res/(ScalarType)orderedFaces.size()); - } - - template - inline void CreateMeshVertexStar(std::vector &starCenters, - std::vector &orderedFaces, - MeshType &created) - { - ///get faces referenced by vertices - std::vector orderedVertex; - getSharedFace(starCenters,orderedFaces); - CopyMeshFromFaces(orderedFaces,orderedVertex,created); - } - - template - inline void CreateMeshVertexStar(std::vector &starCenters, - std::vector &orderedFaces, - std::vector &orderedVertex, - MeshType &created) - { - ///get faces referenced by vertices - getSharedFace(starCenters,orderedFaces); - CopyMeshFromFaces(orderedFaces,orderedVertex,created); - } - - template - inline void getAroundFaceVertices(typename MeshType::VertexType *v0, - typename MeshType::VertexType *v1, - std::vector &result, - std::vector &on_edge, - std::vector &in_v0, - std::vector &in_v1) - { - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::CoordType CoordType; - - getSharedFace(v0,v1,on_edge,in_v0,in_v1); - - std::set Added; - - CoordType Center=CoordType(0,0,0); - int num=0; - - ///get all vertices around the collapse - for (int i=0;i, bool > done=Added.Add(in_v0[i].V(j)); - if (done.second) - result.push_back(in_v0[i].V(j)); - } - } - - ///get all vertices around the collapse - for (int i=0;i, bool > done=Added.Add(in_v1[i].V(j)); - if (done.second) - result.push_back(in_v1[i].V(j)); - } - } - } - - template - inline void CopyHlevMesh(std::vector &faces, - MeshType &hlev_mesh, - std::vector &ordered_vertex) - { - typedef typename MeshType::FaceType FaceType; - typedef typename MeshType::VertexType VertexType; - typedef typename MeshType::CoordType CoordType; - std::vector vertices; - - ///collect vertices to create the sub mesh - for (unsigned int i=0;ivertices_bary.size();j++) + for (int j=0;j<3;j++) + if ((in_v0[i].V(j)!=v0)&&(in_v0[i].V(j)!=v1)) { - VertexType *v=f->vertices_bary[j].first; - vertices.push_back(v); + std::pair< std::set, bool > done=Added.Add(in_v0[i].V(j)); + if (done.second) + result.push_back(in_v0[i].V(j)); } - } - std::vector OrderedFaces; - CopyMeshFromVertices(vertices,ordered_vertex,OrderedFaces,hlev_mesh); } - + + ///get all vertices around the collapse + for (int i=0;i, bool > done=Added.Add(in_v1[i].V(j)); + if (done.second) + result.push_back(in_v1[i].V(j)); + } + } +} + +template +inline void CopyHlevMesh(std::vector &faces, + MeshType &hlev_mesh, + std::vector &ordered_vertex) +{ + typedef typename MeshType::FaceType FaceType; + typedef typename MeshType::VertexType VertexType; + typedef typename MeshType::CoordType CoordType; + std::vector vertices; + + ///collect vertices to create the sub mesh + for (unsigned int i=0;ivertices_bary.size();j++) + { + VertexType *v=f->vertices_bary[j].first; + vertices.push_back(v); + } + } + std::vector OrderedFaces; + CopyMeshFromVertices(vertices,ordered_vertex,OrderedFaces,hlev_mesh); +} + #endif diff --git a/src/meshlabplugins/filter_isoparametrization/opt_patch.h b/src/meshlabplugins/filter_isoparametrization/opt_patch.h index 88509f657..79694dc53 100644 --- a/src/meshlabplugins/filter_isoparametrization/opt_patch.h +++ b/src/meshlabplugins/filter_isoparametrization/opt_patch.h @@ -20,7 +20,7 @@ public: VertexType* to_optimize; std::vector Hres_vert; MeshType *parametrized_domain; - //MeshType *base_domain; + MeshType *base_domain; MeshType hres_mesh; }; @@ -80,27 +80,28 @@ public: CoordType bary; int index; inside &=GetBaryFaceFromUV(*inf.parametrized_domain,u,v,bary,index); + FaceType* chosen; if (!inside)///ack { - x[0]=std::numeric_limits::max(); - x[1]=std::numeric_limits::max(); - return; + chosen=test->father; + bary=test->Bary; + } + else + { + chosen=&inf.parametrized_domain->face[index]; } - FaceType* chosen=&inf.parametrized_domain->face[index]; chosen->vertices_bary.push_back(std::pair(test,bary)); test->father=chosen; + assert(!chosen->IsD()); test->Bary=bary; } - - /*///ack - if (!inside) + if (!inside)///ack { - x[0]=std::numeric_limits::max(); - x[1]=std::numeric_limits::max(); - return; - }*/ - //assert(inside); + x[0]=std::numeric_limits::max(); + x[1]=std::numeric_limits::max(); + return; + } ScalarType maxEdge=0; ScalarType minEdge=std::numeric_limits::max(); @@ -148,12 +149,6 @@ public: x[0]=((maxArea/minArea)*(ScalarType)2.0); x[1]=pow(maxEdge/minEdge,(ScalarType)2.0); - /*if (x[0]>MaxVal) - x[0]=MaxVal; - if (x[1]>MaxVal) - x[1]=MaxVal;*/ - /*x[0]=(maxArea-minArea); - x[1]=pow(maxEdge-minEdge,2);*/ } static ScalarType LengthPath(VertexType *v0,VertexType *v1) @@ -267,7 +262,7 @@ public: } ///optimize UV of central vertex - static void OptimizeUV(VertexType *center) + static void OptimizeUV(VertexType *center,MeshType &base_domain) { ///parametrize base domain star and subvertices ParametrizeStarEquilateral(center,true); @@ -281,10 +276,18 @@ public: ///get Hres Vertices std::vector Hres_vert; - getHresVertex(faces,Hres_vert); + getHresVertex(faces,Hres_vert); + ///make a copy of base mesh std::vector ordFaces; CreateMeshVertexStar(vertices,ordFaces,domain); + assert(ordFaces.size()==domain.face.size()); + assert(ordFaces.size()==faces.size()); + /* assert(Test(ordFaces,faces)); + assert(Test1(ordFaces,domain.face)); + assert(Test1(faces,domain.face));*/ + /*assert(Test2(domain,Hres_vert.size()));*/ + UpdateTopologies(&domain); ///minimization @@ -292,6 +295,7 @@ public: ///setting parameters for minimization //Minf.base_domain=base_domain; Minf.parametrized_domain=&domain; + //Minf.base_domain=&base_mesh; Minf.Hres_vert=std::vector(Hres_vert.begin(),Hres_vert.end()); ///create a copy of hres mesh @@ -322,19 +326,18 @@ public: opts[3]=(float)1E-20; opts[4]=(float)LM_DIFF_DELTA; - /*energy1(p,x,2,2,&Minf);*/ - - /*int num=*/slevmar_dif(Equi_energy,p,x,2,2,1000,opts,info,NULL,NULL,&Minf); - - + + ///copy back values //clear old values for (unsigned int i=0;ivertices_bary.resize(0); + //reassing + int num=0; for (unsigned int i=0;ivertices_bary.push_back(std::pair(vert,bary)); - vert->father=ordFaces[i]; - vert->Bary=bary; + /*vert->father=ordFaces[i]; + assert(!ordFaces[i]->IsD()); + vert->Bary=bary;*/ + AssingFather(*vert,ordFaces[i],bary,base_domain); + num++; } } - /*Minf.to_optimize->T().U()=p[0]; - Minf.to_optimize->T().V()=p[1];*/ + //assert(num==Minf.Hres_vert.size()); + if (num!=Minf.Hres_vert.size()) + { + printf("num0 %d \n",num); + printf("num1 %d \n",Minf.Hres_vert.size()); + } + center->RPos=Minf.to_optimize->RPos; delete(x); delete(p); @@ -377,9 +388,9 @@ public: std::vector Operations; - void Execute(VertexType *center) + void Execute(VertexType *center) { - OptimizeUV(center); + OptimizeUV(center,base_mesh); std::vector neigh; getVertexStar(center,neigh); @@ -469,7 +480,20 @@ void OptimizePatches() #endif } + PatchesOptimizer(MeshType &_base_mesh,MeshType &_final_mesh):base_mesh(_base_mesh),final_mesh(_final_mesh),markers(_base_mesh.vert){} + + static MeshType* &HresMesh() + { + static MeshType* mesh; + return mesh; + } + + static MeshType* &BaseMesh() + { + static MeshType* mesh; + return mesh; + } }; #endif diff --git a/src/meshlabplugins/filter_isoparametrization/param_collapse.h b/src/meshlabplugins/filter_isoparametrization/param_collapse.h index d57fd5778..d3f89c6d9 100644 --- a/src/meshlabplugins/filter_isoparametrization/param_collapse.h +++ b/src/meshlabplugins/filter_isoparametrization/param_collapse.h @@ -93,7 +93,7 @@ public: } static void SetBaryFromUV(BaseMesh &domain, - std::vector &vertices) + std::vector &vertices) { ///set a vector of pointer to face std::vector OrdFace; @@ -107,10 +107,12 @@ public: FaceType *chosen; ScalarType u=vertices[i]->T().U(); ScalarType v=vertices[i]->T().V(); - GetBaryFaceFromUV(domain,u,v,OrdFace,bary1,chosen); + GetBaryFaceFromUV(domain,u,v,OrdFace,bary1,chosen); assert(fabs(bary1.X()+bary1.Y()+bary1.Z()-1.0)<=0.0001); - vertices[i]->father=chosen; - vertices[i]->Bary=bary1; + /*vertices[i]->father=chosen; + assert(!chosen->IsD()); + vertices[i]->Bary=bary1;*/ + AssingFather(vertices[i],chosen,bary1,domain); } } @@ -154,7 +156,7 @@ public: } ///find best position - inline CoordType FindBestPos() + inline CoordType FindBestPos(BaseMesh &m) { minInfo0 Minf; ///create the submesh @@ -256,9 +258,11 @@ public: for (unsigned int i=0;ifather=swap[i].first; - Minf.HiVertex[i]->Bary=swap[i].second; + assert(!swap[i].first->IsD()); + Minf.HiVertex[i]->Bary=swap[i].second;*/ + AssingFather(*Minf.HiVertex[i],swap[i].first,swap[i].second,m); } return (bestPos); @@ -270,9 +274,9 @@ public: //return( Distance(pos.V(0)->cP(),pos.V(1)->cP())); } - CoordType ComputeMinimal() + CoordType ComputeMinimal(BaseMesh &m) { - CoordType bestPos=FindBestPos(); + CoordType bestPos=FindBestPos(m); return bestPos; } @@ -465,7 +469,8 @@ void AphaBetaToUV(EdgeType &pos, } void UVToAlphaBeta(std::vector &HresVert, - BaseMesh ¶m,std::vector &orderedFaces) + BaseMesh ¶m,std::vector &orderedFaces, + BaseMesh &base_mesh) { ///for each parametrized vertex for (unsigned int i=0;i &HresVert, ///set father-son relation chosen->vertices_bary.push_back(std::pair(brother,bary1)); - brother->father=chosen; - brother->Bary=bary1; + AssingFather(*brother,chosen,bary1,base_mesh); + /*brother->father=chosen; + assert(!chosen->IsD()); + brother->Bary=bary1;*/ ///set new parametrization value GetUV(¶m.face[index],bary1,u,v); @@ -580,7 +587,7 @@ void Execute(BaseMesh &m) ///compute new position CoordType oldRPos=(pos.V(0)->RPos+pos.V(1)->RPos)/2.0; CoordType newPos; - newPos=ComputeMinimal();// + newPos=ComputeMinimal(m);// //vcg::tri::UpdateTopology::TestVertexFace(m); ///TEST BaseMesh param0,param1; @@ -597,7 +604,7 @@ void Execute(BaseMesh &m) ///INITIAL AREA ScalarType area0=Area(orderedFaces0); - + ///do the collapse DoCollapse(m, this->pos, newPos); // v0 is deleted and v1 take the new position //vcg::tri::UpdateTopology::TestVertexFace(m); ///TEST @@ -621,7 +628,7 @@ void Execute(BaseMesh &m) //TRANSFORM TO UV AphaBetaToUV(this->pos,orderedFaces0,param0,HresVert); - + //DELETE SONS ClearVert_Bary(orderedFaces0); //---------------------------/// @@ -631,11 +638,12 @@ void Execute(BaseMesh &m) //---------------------------/// ///REPROJECT BACK TO ORIGINAL FATHER #3 - UVToAlphaBeta(HresVert,param1,orderedFaces1); - - ///UPTIMIZE UV - PatchesOptimizer::OptimizeUV(this->pos.V(1)); + + UVToAlphaBeta(HresVert,param1,orderedFaces1,m); + + PatchesOptimizer::OptimizeUV(this->pos.V(1),m); + //---------------------------/// ///get the non border one that is the one survived unsigned int k=0; @@ -648,12 +656,14 @@ void Execute(BaseMesh &m) ///ASSIGN REST POSITION CENTRAL VERTEX //AssignRPos(pos.V(1),param1.vert[k].T().U(),param1.vert[k].T().V(),orderedFaces1,param0); //---------------------------/// - + ///FINAL OPTIMIZATION /*int t0=clock();*/ + this->pos.V(1)->RPos=oldRPos; - bool b=SmartOptimizeStar(this->pos.V(1),Accuracy()); - + + bool b=SmartOptimizeStar(this->pos.V(1),m,Accuracy()); + /*int t1=clock(); time_opt+=(t1-t0);*/ } @@ -664,6 +674,12 @@ public: static int _acc; return _acc; } + + static BaseMesh* &HresMesh() + { + static BaseMesh* mesh; + return mesh; + } BaseVertex *getV(int num) { diff --git a/src/meshlabplugins/filter_isoparametrization/param_flip.h b/src/meshlabplugins/filter_isoparametrization/param_flip.h index e60457a36..6fcbbbbb1 100644 --- a/src/meshlabplugins/filter_isoparametrization/param_flip.h +++ b/src/meshlabplugins/filter_isoparametrization/param_flip.h @@ -16,7 +16,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip > Super; ScalarType diff; - + public: bool savedomain; @@ -43,7 +43,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip faces; faces.push_back(&f); @@ -112,8 +112,14 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlipfather=faces[index]; - v->Bary=bary; + if (base_domain!=NULL) + AssingFather(*v,faces[index],bary,*base_domain); + else + { + v->father=faces[index]; + assert(!faces[index]->IsD()); + v->Bary=bary; + } } @@ -264,7 +270,7 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip_pos.F(),this->_pos.E()); + ExecuteFlip(*this->_pos.F(),this->_pos.E(),&m); UpdateTopologies(&m); @@ -275,10 +281,10 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip(v2); OptimizeStar(v3);*/ - SmartOptimizeStar(v0); - SmartOptimizeStar(v1); - SmartOptimizeStar(v2); - SmartOptimizeStar(v3); + SmartOptimizeStar(v0,m,Accuracy()); + SmartOptimizeStar(v1,m,Accuracy()); + SmartOptimizeStar(v2,m,Accuracy()); + SmartOptimizeStar(v3,m,Accuracy()); /*int t1=clock(); time_opt+=(t1-t0);*/ } @@ -294,6 +300,14 @@ class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip_pos.E();} + + public: + static int &Accuracy() + { + static int _acc; + return _acc; + } + }; #endif diff --git a/src/meshlabplugins/filter_isoparametrization/parametrizator.h b/src/meshlabplugins/filter_isoparametrization/parametrizator.h index da98cb5b9..075e94947 100644 --- a/src/meshlabplugins/filter_isoparametrization/parametrizator.h +++ b/src/meshlabplugins/filter_isoparametrization/parametrizator.h @@ -130,10 +130,12 @@ private: for (unsigned int i=0;iIsD()); CoordType bary=CoordType(0,0,0); bary.V(base_mesh.vert[i].VFi())=1; - final_mesh.vert[i].Bary=bary; + //final_mesh.vert[i].Bary=bary; + AssingFather(final_mesh.vert[i],base_mesh.vert[i].VFp(),bary,base_mesh); } ///initialize area per vertex @@ -176,7 +178,11 @@ private: vcg::LocalOptimization DeciSession(base_mesh); DeciSession.Init(); MyTriEdgeCollapse::Accuracy()=accuracy; + MyTriEdgeCollapse::HresMesh()=&final_mesh; + PatchesOptimizer::HresMesh()=&final_mesh; + PatchesOptimizer::BaseMesh()=&base_mesh; + MyTriEdgeFlip::Accuracy()=accuracy; int flip_todo=4; int next_flip_num=targetFaces; @@ -243,10 +249,13 @@ private: curr_limit--; } - + + DeciSession.SetTargetSimplices(next_num); not_heap_empty=DeciSession.DoOptimization(); - + + + if (do_flip) { FlipStep(); @@ -275,6 +284,8 @@ private: DeciSession.h.clear(); DeciSession.Init(); } + + testParametrization(base_mesh,final_mesh); } } @@ -293,11 +304,12 @@ private: CoordType bary=CoordType(0,0,0); bary[index]=1.f; f->vertices_bary.push_back(std::pair(vb,bary)); - vb->father=f; - vb->Bary=bary; + AssingFather(*vb,f,bary,base_mesh); + /*vb->father=f; + assert(!f->IsD()); + vb->Bary=bary;*/ v->brother=NULL; } - testParametrization(base_mesh,final_mesh); } typedef struct vert_para @@ -329,7 +341,7 @@ private: std::sort(ord_vertex.begin(),ord_vertex.end()); for (unsigned int i=0;i(ord_vertex[i].v); + SmartOptimizeStar(ord_vertex[i].v,base_mesh,MyTriEdgeCollapse::Accuracy()); } @@ -408,11 +420,12 @@ private: { BaseVertex* son=base_mesh.face[i].vertices_bary[j].first; CoordType bary=base_mesh.face[i].vertices_bary[j].second; - son->father=&base_mesh.face[i]; - son->Bary=bary; + /*son->father=&base_mesh.face[i]; + assert(!base_mesh.face[i].IsD()); + son->Bary=bary;*/ + AssingFather(*son,&base_mesh.face[i],bary,base_mesh); } } - testParametrization(base_mesh,final_mesh); } ///save the current status of the parameterization @@ -480,8 +493,11 @@ private: CoordType bary=to_restore->face[i].vertices_bary[j].second; base_mesh.face[i].vertices_bary[j].first=vert; base_mesh.face[i].vertices_bary[j].second=bary; - vert->father=&base_mesh.face[i]; - vert->Bary=bary; + AssingFather(*vert,&base_mesh.face[i],bary,base_mesh); + + //vert->father=&base_mesh.face[i]; + //assert(!base_mesh.face[i].IsD()); + //vert->Bary=bary; } } UpdateTopologies(&base_mesh); @@ -714,8 +730,10 @@ public: CoordType bary2=CoordType(UV_final.X(),UV_final.Y(),1-UV_final.X()-UV_final.Y()); isOK=NormalizeBaryCoords(bary2); assert(isOK); - final_mesh.vert[i].father=&base_mesh.face[I_final]; - final_mesh.vert[i].Bary=bary2; + //final_mesh.vert[i].father=&base_mesh.face[I_final]; + //assert(!base_mesh.face[I_final].IsD()); + //final_mesh.vert[i].Bary=bary2; + AssingFather(final_mesh.vert[i],&base_mesh.face[I_final],bary2,base_mesh); } ///set father to son link @@ -936,6 +954,7 @@ public: vert->RPos=pos; vert->Bary=bary; vert->father=&base_mesh.face[index_face]; + assert(!base_mesh.face[index_face].IsD()); col=vcg::Color4b(col0,col1,col2,255); vert->OriginalCol=col; /*if (i==final_mesh.vert.size()-1) @@ -1034,6 +1053,7 @@ public: for (unsigned int i=0;i::iterator cur = faceMap.find(final_mesh.vert[i].father); + assert(cur!= faceMap.end()); CoordType bary=final_mesh.vert[i].Bary; int index=(*cur).second; para_mesh.vert[i].T().N()=index;