1 #ifndef PARAM_FLIP 2 #define PARAM_FLIP 3 4 #include <vcg/complex/algorithms/local_optimization/tri_edge_flip.h> 5 6 namespace vcg{ 7 namespace tri{ 8 9 ///Flip function 10 template <class BaseMesh> 11 class ParamEdgeFlip : public vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<BaseMesh> > 12 { 13 typedef typename BaseMesh::VertexType::EdgeType EdgeType; 14 typedef typename BaseMesh::VertexType BaseVertex; 15 typedef typename BaseMesh::VertexType VertexType; 16 typedef typename BaseMesh::FaceType BaseFace; 17 typedef typename BaseMesh::FaceType FaceType; 18 typedef typename BaseMesh::CoordType CoordType; 19 typedef typename BaseMesh::ScalarType ScalarType; 20 typedef vcg::tri::PlanarEdgeFlip<BaseMesh, ParamEdgeFlip<BaseMesh> > Super; 21 ScalarType diff; 22 23 public: 24 EType()25 static EnergyType &EType(){static EnergyType E;return E;} 26 27 bool savedomain; 28 IsFeasible(BaseParameterClass *)29 bool IsFeasible(BaseParameterClass *) 30 { 31 if(!vcg::face::CheckFlipEdge(*this->_pos.F(), this->_pos.E())) 32 return false; 33 34 return (this->_priority>0); 35 } 36 ParamEdgeFlip()37 inline ParamEdgeFlip() {} 38 39 /*! 40 * Constructor with <I>pos</I> type 41 */ ParamEdgeFlip(const typename Super::PosType pos,int mark,BaseParameterClass * pp)42 inline ParamEdgeFlip(const typename Super::PosType pos, int mark,BaseParameterClass *pp) 43 { 44 this->_pos = pos; 45 this->_localMark = mark; 46 this->_priority = this->ComputePriority(pp); 47 savedomain=false; 48 } 49 50 ///do the effective flip 51 void ExecuteFlip(FaceType &f, const int &edge, BaseMesh *base_domain=NULL) 52 { 53 std::vector<FaceType*> faces; 54 faces.push_back(&f); 55 faces.push_back(f.FFp(edge)); 56 std::vector<VertexType*> HresVert; 57 getHresVertex<FaceType>(faces,HresVert); 58 ///parametrize H_res mesh respect to diamond 59 for (unsigned int i=0;i<HresVert.size();i++) 60 { 61 VertexType* v=HresVert[i]; 62 ///get father & bary 63 FaceType* father=v->father; 64 CoordType bary=v->Bary; 65 assert((father==faces[0])||(father==faces[1])); 66 vcg::Point2<ScalarType> t0=father->V(0)->T().P(); 67 vcg::Point2<ScalarType> t1=father->V(1)->T().P(); 68 vcg::Point2<ScalarType> t2=father->V(2)->T().P(); 69 70 //assert(testBaryCoords(bary)); 71 if(!testBaryCoords(bary)) 72 { 73 printf("BAry0 :%lf,%lf,%lf",bary.X(),bary.Y(),bary.Z()); 74 //system("pause"); 75 } 76 77 InterpolateUV<BaseMesh>(father,bary,v->T().U(),v->T().V()); 78 } 79 80 ///update VF topology 81 FaceType *f1=f.FFp(edge); 82 FaceType *f0=&f; 83 vcg::face::VFDetach(*f1,0); 84 vcg::face::VFDetach(*f1,1); 85 vcg::face::VFDetach(*f1,2); 86 vcg::face::VFDetach(*f0,0); 87 vcg::face::VFDetach(*f0,1); 88 vcg::face::VFDetach(*f0,2); 89 ///then do the effective flip 90 91 vcg::face::FlipEdge(f,edge); 92 93 94 95 vcg::face::VFAppend(f1,0); 96 vcg::face::VFAppend(f1,1); 97 vcg::face::VFAppend(f1,2); 98 vcg::face::VFAppend(f0,0); 99 vcg::face::VFAppend(f0,1); 100 vcg::face::VFAppend(f0,2); 101 ///edh updating topology 102 103 104 ///set son->father new link 105 for (unsigned int i=0;i<HresVert.size();i++) 106 { 107 VertexType* v=HresVert[i]; 108 ScalarType U=v->T().U(); 109 ScalarType V=v->T().V(); 110 CoordType bary; 111 int index; 112 bool found=GetBaryFaceFromUV(faces,U,V,bary,index); 113 if (!found) 114 { 115 printf("\n U : %lf; V : %lf \n",U,V); 116 //system("pause"); 117 } 118 //assert(found); 119 //assert(); 120 if(!testBaryCoords(bary)) 121 { 122 printf("\n PAR ERROR 1: bary coords exceeds: %f,%f,%f \n",bary.X(),bary.Y(),bary.Z()); 123 NormalizeBaryCoords(bary); 124 } 125 if (base_domain!=NULL) 126 AssingFather(*v,faces[index],bary,*base_domain); 127 else 128 { 129 v->father=faces[index]; 130 assert(!faces[index]->IsD()); 131 v->Bary=bary; 132 } 133 } 134 135 136 137 ///set father->son new link 138 for (unsigned int i=0;i<faces.size();i++) 139 faces[i]->vertices_bary.clear(); 140 141 for (unsigned int i=0;i<HresVert.size();i++) 142 { 143 VertexType *son=HresVert[i]; 144 FaceType *father=son->father; 145 CoordType bary=son->Bary; 146 father->vertices_bary.push_back(std::pair<BaseVertex*,vcg::Point3f>(son,bary)); 147 } 148 149 } 150 EdgeDiff()151 ScalarType EdgeDiff() 152 { 153 /* 154 1 155 /|\ 156 / | \ 157 2 f0|f1 3 158 \ | / 159 \|/ 160 0 161 */ 162 163 VertexType *v0, *v1, *v2, *v3; 164 int edge0 = this->_pos.E(); 165 v0 = this->_pos.F()->V0(edge0); 166 v1 = this->_pos.F()->V1(edge0); 167 v2 = this->_pos.F()->V2(edge0); 168 v3 = this->_pos.F()->FFp(edge0)->V2(this->_pos.F()->FFi(edge0)); 169 int edge1=this->_pos.F()->FFi(edge0); 170 FaceType* f0=this->_pos.F(); 171 FaceType* f1=this->_pos.F()->FFp(edge0); 172 173 ///parametrize all possible diamonds 174 ///diam0 & diam1 175 ///make a copy of the mesh 176 std::vector<FaceType*> OrdFace; 177 OrdFace.push_back(f0); 178 OrdFace.push_back(f1); 179 180 BaseMesh Diam; 181 BaseMesh DiamHres; 182 183 ///create a copy of the domain and of the H resolution 184 CopySubMeshLevels(OrdFace,Diam,DiamHres); 185 186 ///parametrize domains 187 ParametrizeDiamondEquilateral(Diam,edge0,edge1); 188 189 ///copy parametrization on original mesh 190 191 FaceType* on_edge[2]; 192 on_edge[0]=&Diam.face[0]; 193 on_edge[1]=&Diam.face[1]; 194 assert(Diam.face[0].FFp(edge0)==&Diam.face[1]);///test 195 assert(Diam.face[1].FFp(edge1)==&Diam.face[0]);///test 196 197 ///Evaluate length of shared edge 198 ScalarType L0=EstimateLengthByParam<BaseMesh>(Diam.face[0].V(edge0),Diam.face[0].V((edge0+1)%3),on_edge); 199 200 ///do the flip on the copied mesh do not affect the original mesh 201 ExecuteFlip(Diam.face[0],edge0); 202 203 UpdateTopologies(&Diam); 204 205 ///get the non border edge of face0 206 int NB_edge=-1; 207 if (!Diam.face[0].IsB(0)) 208 NB_edge=0; 209 else 210 if (!Diam.face[0].IsB(1)) 211 NB_edge=1; 212 else 213 if (!Diam.face[0].IsB(2)) 214 NB_edge=2; 215 assert(NB_edge!=-1); 216 217 ScalarType L1=EstimateLengthByParam<BaseMesh>(Diam.face[0].V(NB_edge),Diam.face[0].V((NB_edge+1)%3),on_edge); 218 219 ScalarType value=L0-L1; 220 diff=value; 221 this->_priority = 1.0/value; 222 return (this->_priority); 223 } 224 225 Execute(BaseMesh & m,BaseParameterClass *)226 void Execute(BaseMesh &m,BaseParameterClass *) 227 { 228 229 assert(this->_priority>0); 230 /* 231 1 232 /|\ 233 / | \ 234 2 f0|f1 3 235 \ | / 236 \|/ 237 0 238 */ 239 VertexType *v0, *v1, *v2, *v3; 240 int edge0 = this->_pos.E(); 241 v0 = this->_pos.F()->V0(edge0); 242 v1 = this->_pos.F()->V1(edge0); 243 v2 = this->_pos.F()->V2(edge0); 244 v3 = this->_pos.F()->FFp(edge0)->V2(this->_pos.F()->FFi(edge0)); 245 ///assign texcoords 246 ScalarType h=(sqrt((ScalarType)3.0)/(ScalarType)2.0); 247 v0->T().P()=vcg::Point2<ScalarType>(0,(ScalarType)-0.5); 248 v1->T().P()=vcg::Point2<ScalarType>(0,(ScalarType)0.5); 249 v2->T().P()=vcg::Point2<ScalarType>(-h,0); 250 v3->T().P()=vcg::Point2<ScalarType>(h,0); 251 252 #ifndef _MESHLAB 253 ///save domain if need for demos 254 if (savedomain) 255 { 256 BaseMesh hlev_mesh; 257 std::vector<FaceType*> faces; 258 FaceType* f=this->_pos.F(); 259 int edge=this->_pos.E(); 260 faces.push_back(f); 261 faces.push_back(f->FFp(edge)); 262 std::vector<VertexType*> HresVert; 263 getHresVertex<FaceType>(faces,HresVert); 264 265 ///parametrize H_res mesh respect to diamond 266 std::vector<VertexType*> OrderedVertices; 267 std::vector<FaceType*> OrderedFaces; 268 CopyMeshFromVertices(HresVert,OrderedVertices,OrderedFaces,hlev_mesh); 269 //for (int i=0;i<hlev_mesh.vert.size();i++) 270 //hlev_mesh.vert[i].C()=hlev_mesh.vert[i].OriginalCol; 271 272 vcg::tri::io::ExporterPLY<BaseMesh>::Save(hlev_mesh,"c:/export_submeshes/FLIPHlev3D.ply",vcg::tri::io::Mask::IOM_VERTCOLOR); 273 for (unsigned int i=0;i<hlev_mesh.vert.size();i++) 274 { 275 hlev_mesh.vert[i].P().X()=hlev_mesh.vert[i].T().U(); 276 hlev_mesh.vert[i].P().Y()=hlev_mesh.vert[i].T().V(); 277 hlev_mesh.vert[i].P().Z()=0; 278 } 279 vcg::tri::io::ExporterPLY<BaseMesh>::Save(hlev_mesh,"c:/export_submeshes/FLIPHlevUV.ply",vcg::tri::io::Mask::IOM_VERTCOLOR); 280 } 281 #endif 282 283 ExecuteFlip(*this->_pos.F(),this->_pos.E(),&m); 284 285 UpdateTopologies(&m); 286 287 ///stars optimization 288 /*int t0=clock();*/ 289 /*OptimizeStar<BaseMesh>(v0); 290 OptimizeStar<BaseMesh>(v1); 291 OptimizeStar<BaseMesh>(v2); 292 OptimizeStar<BaseMesh>(v3);*/ 293 294 SmartOptimizeStar<BaseMesh>(v0,m,Accuracy(),EType()); 295 SmartOptimizeStar<BaseMesh>(v1,m,Accuracy(),EType()); 296 SmartOptimizeStar<BaseMesh>(v2,m,Accuracy(),EType()); 297 SmartOptimizeStar<BaseMesh>(v3,m,Accuracy(),EType()); 298 /*int t1=clock(); 299 time_opt+=(t1-t0);*/ 300 } 301 ComputePriority(BaseParameterClass *)302 ScalarType ComputePriority(BaseParameterClass *) 303 { 304 this->_priority=EdgeDiff(); 305 return this->_priority; 306 } 307 getF()308 BaseFace *getF() 309 {return this->_pos.F();} 310 getE()311 int getE() 312 {return this->_pos.E();} 313 314 public: Accuracy()315 static int &Accuracy() 316 { 317 static int _acc; 318 return _acc; 319 } 320 321 }; 322 323 }//end namespace tri 324 }//end namespace vcg 325 326 #endif 327