3
#include <wrap/callback.h>
5
template <class MeshType>
6
class BaryOptimizatorDual
8
typedef typename MeshType::VertexType VertexType;
9
typedef typename MeshType::FaceType FaceType;
10
typedef typename MeshType::CoordType CoordType;
11
typedef typename MeshType::ScalarType ScalarType;
12
typedef typename vcg::tri::AreaPreservingTexCoordOptimization<MeshType> OptType;
13
//typedef typename vcg::tri::MIPSTexCoordOptimization<MeshType> OptType1;
19
std::vector<FaceType*> ordered_faces;
24
///set of star meshes to optimize barycentryc coords locally
25
std::vector<param_domain> star_meshes;
26
std::vector<param_domain> diamond_meshes;
27
std::vector<param_domain> face_meshes;
28
///structures for the optimization
29
std::vector<MeshType*> HRES_meshes;
30
std::vector<std::vector<VertexType*> > Ord_HVert;
31
/*std::vector<std::vector<VertexType*> > HVert;*/
33
/*///subdomain in witch a vertex falls into
34
std::vector<param_domain*> subdomain;*/
36
///map fo correspondences between domain & entities
37
//std::map<VertexType*,param_domain*> starMap;
38
//std::map<std::pair<FaceType*,FaceType*>,param_domain*> diamondMap;
39
//std::map<FaceType*,param_domain*> faceMap;
41
///hight resolution mesh and domain mesh
45
///initialize star parametrization
46
void InitStarEquilateral()//const ScalarType &average_area=1)
50
for (unsigned int i=0;i<domain->vert.size();i++)
52
if (!(domain->vert[i].IsD()))
54
std::vector<VertexType*> starCenter;
55
starCenter.push_back(&domain->vert[i]);
57
star_meshes[index].domain=new MeshType();
60
CreateMeshVertexStar(starCenter,star_meshes[index].ordered_faces,*star_meshes[index].domain);
63
ParametrizeStarEquilateral<MeshType>(*star_meshes[index].domain,1.0);
65
/*///insert in search structure
66
starMap.insert(std::pair<VertexType*,param_domain*>(&domain->vert[i],&star_meshes[index]));*/
73
void InitDiamondEquilateral(const ScalarType &edge_len=1.0)
78
for (unsigned int i=0;i<domain->face.size();i++)
80
if (!(domain->face[i].IsD()))
82
FaceType *f0=&domain->face[i];
86
FaceType * f1=f0->FFp(j);
90
std::pair<FaceType*,FaceType*> entry=std::pair<FaceType*,FaceType*>(f0,f1);
91
/*diamondMap.insert(std::pair<std::pair<FaceType*,FaceType*> ,param_domain*>(entry,&diamond_meshes[index]));*/
98
std::vector<FaceType*> faces;
102
diamond_meshes[index].domain=new MeshType();
104
///create a copy of the mesh
105
std::vector<VertexType*> orderedVertex;
106
CopyMeshFromFaces<MeshType>(faces,orderedVertex,*diamond_meshes[index].domain);
107
UpdateTopologies<MeshType>(diamond_meshes[index].domain);
109
///set other components
110
diamond_meshes[index].ordered_faces.resize(2);
111
diamond_meshes[index].ordered_faces[0]=f0;
112
diamond_meshes[index].ordered_faces[1]=f1;
113
///parametrize locally
114
ParametrizeDiamondEquilateral<MeshType>(*diamond_meshes[index].domain,num0,num1,edge_len);
124
void InitFaceEquilateral(const ScalarType &edge_len=1)
128
for (unsigned int i=0;i<domain->face.size();i++)
130
if (!(domain->face[i].IsD()))
132
FaceType *f0=&domain->face[i];
134
std::vector<FaceType*> faces;
138
face_meshes[index].domain=new MeshType();
139
std::vector<VertexType*> orderedVertex;
140
CopyMeshFromFaces<MeshType>(faces,orderedVertex,*face_meshes[index].domain);
142
assert(face_meshes[index].domain->vn==3);
143
assert(face_meshes[index].domain->fn==1);
145
///initialize auxiliary structures
146
face_meshes[index].ordered_faces.resize(1);
147
face_meshes[index].ordered_faces[0]=f0;
150
ParametrizeFaceEquilateral<MeshType>(*face_meshes[index].domain,edge_len);
151
///add to search structures
152
/*faceMap.insert(std::pair<FaceType*,param_domain*>(f0,&face_meshes[index]));*/
158
///given a point and a face return the half-star in witch it falls
159
int getVertexStar(const CoordType &point,FaceType *f)
161
CoordType edge0=(f->P(0)+f->P(1))/2.0;
162
CoordType edge1=(f->P(1)+f->P(2))/2.0;
163
CoordType edge2=(f->P(2)+f->P(0))/2.0;
164
CoordType Center=(f->P(0)+f->P(1)+f->P(2))/3.0;
165
CoordType vect0=edge0-point;
166
CoordType vect1=Center-point;
167
CoordType vect2=edge2-point;
168
CoordType Norm=f->N();
169
ScalarType in0=(vect0^vect1)*Norm;
170
ScalarType in1=(vect1^vect2)*Norm;
171
if ((in0>=0)&&(in1>=0))
177
in0=(vect1^vect0)*Norm;
178
in1=(vect2^vect1)*Norm;
179
if ((in0>=0)&&(in1>=0))
185
in0=(vect1^vect0)*Norm;
186
in1=(vect2^vect1)*Norm;
187
assert((in0>=0)&&(in1>=0));
191
///given a point and a face return the half-diamond edge index in witch it falls
192
int getEdgeDiamond(const CoordType &point,FaceType *f)
194
CoordType Center=(f->P(0)+f->P(1)+f->P(2))/3.0;
195
CoordType vect0=f->P(1)-point;
196
CoordType vect1=Center-point;
197
CoordType vect2=f->P(0)-point;
198
CoordType Norm=f->N();
199
ScalarType in0=(vect0^vect1)*Norm;
200
ScalarType in1=(vect1^vect2)*Norm;
201
if ((in0>=0)&&(in1>=0))
207
in0=(vect0^vect1)*Norm;
208
in1=(vect1^vect2)*Norm;
209
if ((in0>=0)&&(in1>=0))
215
in0=(vect0^vect1)*Norm;
216
in1=(vect1^vect2)*Norm;
217
assert((in0>=0)&&(in1>=0));
222
///initialize Star Submeshes
223
void InitStarSubdivision()
229
///initialilze vector of meshes
230
HRES_meshes.resize(star_meshes.size());
231
Ord_HVert.resize(star_meshes.size());
232
/*HVert.resize(star_meshes.size());*/
233
for (unsigned int i=0;i<HRES_meshes.size();i++)
234
HRES_meshes[i]=new MeshType();
236
///for each vertex of base domain
237
for (unsigned int i=0;i<domain->vert.size();i++)
239
VertexType *center=&domain->vert[i];
242
///copy current parametrization of star
243
for (unsigned int k=0;k<star_meshes[index].ordered_faces.size();k++)
245
FaceType *param=&star_meshes[index].domain->face[k];
246
FaceType *original=star_meshes[index].ordered_faces[k];
247
for (int v=0;v<3;v++)
248
original->V(v)->T().P()=param->V(v)->T().P();
251
///get h res vertex on faces composing the star
252
std::vector<VertexType*> Hres,inDomain;
253
getHresVertex<FaceType>(star_meshes[index].ordered_faces,Hres);
255
///find out the vertices falling in the substar
256
/*HVert[index].reserve(Hres.size()/2);*/
257
for (unsigned int k=0;k<Hres.size();k++)
260
VertexType* test=Hres[k];
261
CoordType proj=Warp(test);
262
FaceType * father=test->father;
263
CoordType bary=test->Bary;
264
///get index of half-star
265
int index=getVertexStar(proj,father);
266
chosen=father->V(index);
267
///if is part of current half star
270
inDomain.push_back(test);
272
GetUV<MeshType>(father,bary,test->T().U(),test->T().V());
275
///create Hres mesh already parametrized
276
std::vector<FaceType*> OrderedFaces;
277
CopyMeshFromVertices<MeshType>(inDomain,Ord_HVert[index],OrderedFaces,*HRES_meshes[index]);
283
/////subdivide the mesh into Star subdomain
284
//void InitStarSubdivision()
287
// vcg::SimpleTempData<typename MeshType::VertContainer, param_domain* > domainVert(h_res_mesh->vert);
289
// for (int i=0;i<h_res_mesh->vert.size();i++)
291
// assert(!h_res_mesh->vert[i].IsD());
292
// ///get father and bary coordinate
293
// FaceType *father=h_res_mesh->vert[i].father;
294
// CoordType bary=h_res_mesh->vert[i].Bary;
296
// ///then get the substar falling into
298
// ///get nearest vertex
299
// VertexType* chosen;
300
// CoordType proj=Warp(&h_res_mesh->vert[i]);
301
// int index=getVertexStar(proj,father);
302
// ///chosen is the half-star center
303
// chosen=father->V(index);
305
// ///then get corresponding half-star reference parametrized mesh
306
// std::map<VertexType*,param_domain*>::iterator iteStar=starMap.find(chosen);
307
// assert(iteStar!=starMap.end());
308
// ///end parametrize it using that star
310
// ///get corresponding parametrizad face
311
// param_domain* pdomain=(*iteStar).second;
312
// FaceType *param_face=NULL;
314
// while ((f<pdomain->ordered_faces.size())&&(param_face==NULL))
316
// if (pdomain->ordered_faces[f]==father)
317
// param_face=&pdomain->domain.face[f];
320
// assert(param_face!=NULL);
321
// ///then translate barycentric into UV over the star
323
// GetUV<MeshType>(param_face,bary,u,v);
326
// h_res_mesh->vert[i].T().U()=u;
327
// h_res_mesh->vert[i].T().V()=v;
328
// h_res_mesh->vert[i].ClearS();
330
// ///set corresponding domain
331
// domainVert[i]=pdomain;
332
// subdomain[i]=pdomain;
335
// ///then set as selected border vertices
336
// for (int i=0;i<h_res_mesh->face.size();i++)
338
// VertexType *v0=h_res_mesh->face[i].V(0);
339
// VertexType *v1=h_res_mesh->face[i].V(1);
340
// VertexType *v2=h_res_mesh->face[i].V(2);
341
// if (!((domainVert[v0]==domainVert[v1])&&(domainVert[v1]==domainVert[v2])))
351
///initialize Star Submeshes
352
void InitDiamondSubdivision()
358
///initialilze vector of meshes
359
HRES_meshes.resize(diamond_meshes.size());
360
Ord_HVert.resize(diamond_meshes.size());
361
/*HVert.resize(star_meshes.size());*/
362
for (unsigned int i=0;i<HRES_meshes.size();i++)
363
HRES_meshes[i]=new MeshType();
365
///for each edge of base domain
366
for (unsigned int i=0;i<domain->face.size();i++)
368
FaceType *f0=&domain->face[i];
372
for (int eNum=0;eNum<3;eNum++)
374
FaceType * f1=f0->FFp(eNum);
377
///copy current parametrization of diamond
378
for (unsigned int k=0;k<diamond_meshes[index].ordered_faces.size();k++)
380
FaceType *param=&diamond_meshes[index].domain->face[k];
381
FaceType *original=diamond_meshes[index].ordered_faces[k];
382
for (int v=0;v<3;v++)
383
original->V(v)->T().P()=param->V(v)->T().P();
386
///get h res vertex on faces composing the diamond
387
std::vector<VertexType*> Hres,inDomain;
388
getHresVertex<FaceType>(diamond_meshes[index].ordered_faces,Hres);
390
///find out the vertices falling in the half-diamond
391
/*HVert[index].reserve(Hres.size()/2);*/
392
for (unsigned int k=0;k<Hres.size();k++)
394
//VertexType* chosen;
395
VertexType* test=Hres[k];
396
CoordType proj=Warp(test);
397
FaceType * father=test->father;
398
CoordType bary=test->Bary;
399
///get index of half-star
400
int index=getEdgeDiamond(proj,father);
401
///if is part of current half star
404
inDomain.push_back(test);
406
GetUV<MeshType>(father,bary,test->T().U(),test->T().V());
409
///create Hres mesh already parametrized
410
std::vector<FaceType*> OrderedFaces;
411
CopyMeshFromVertices<MeshType>(inDomain,Ord_HVert[index],OrderedFaces,*HRES_meshes[index]);
418
/////subdivide the mesh into subdomains
419
//void InitDiamondSubdivision()
422
// vcg::SimpleTempData<typename MeshType::VertContainer, param_domain* > domainVert(h_res_mesh->vert);
424
// for (int i=0;i<h_res_mesh->vert.size();i++)
426
// /*h_res_mesh->vert[i].C()=vcg::Color4b(255,255,255,255);*/
428
// assert(!h_res_mesh->vert[i].IsD());
429
// ///get father and bary coordinate
430
// FaceType *father=h_res_mesh->vert[i].father;
431
// CoordType bary=h_res_mesh->vert[i].Bary;
433
// ///get nearest edge
435
// CoordType proj=Warp(&h_res_mesh->vert[i]);
437
// chosen=getEdgeDiamond(proj,father);
438
// ///then get corresponding star
439
// FaceType *fadj=father->FFp(chosen);
440
// FaceType *f0=(father>fadj)? father:fadj;
441
// FaceType *f1=(father<fadj)? father:fadj;
443
// std::pair<FaceType*,FaceType*> keyF=std::pair<FaceType*,FaceType*>(f0,f1);
444
// std::map<std::pair<FaceType*,FaceType*> ,param_domain*>::iterator iteDiam=diamondMap.find(keyF);
445
// assert(iteDiam!=diamondMap.end());
447
// ///end parametrize it using that star
448
// param_domain* pdomain=(*iteDiam).second;
449
// FaceType *param_face=NULL;
451
// while ((f<pdomain->ordered_faces.size())&&(param_face==NULL))
453
// if (pdomain->ordered_faces[f]==father)
454
// param_face=&pdomain->domain.face[f];
457
// assert(param_face!=NULL);
458
// ///then translate barycentric into UV over the star
460
// GetUV<MeshType>(param_face,bary,u,v);
463
// h_res_mesh->vert[i].T().U()=u;
464
// h_res_mesh->vert[i].T().V()=v;
465
// h_res_mesh->vert[i].ClearS();
467
// ///set corresponding domain
468
// domainVert[i]=pdomain;
469
// subdomain[i]=pdomain;
472
// ///then set as selected border vertices
473
// for (int i=0;i<h_res_mesh->face.size();i++)
475
// VertexType *v0=h_res_mesh->face[i].V(0);
476
// VertexType *v1=h_res_mesh->face[i].V(1);
477
// VertexType *v2=h_res_mesh->face[i].V(2);
478
// if (!((domainVert[v0]==domainVert[v1])&&(domainVert[v1]==domainVert[v2])))
487
///initialize Star Submeshes
488
void InitFaceSubdivision()
494
///initialilze vector of meshes
495
HRES_meshes.resize(face_meshes.size());
496
Ord_HVert.resize(face_meshes.size());
498
for (unsigned int i=0;i<HRES_meshes.size();i++)
499
HRES_meshes[i]=new MeshType();
501
///for each face of base domain
502
for (unsigned int i=0;i<domain->face.size();i++)
504
FaceType *f0=&domain->face[i];
507
///copy current parametrization of face
508
FaceType *param=&face_meshes[index].domain->face[0];
509
FaceType *original=face_meshes[index].ordered_faces[0];
511
assert(face_meshes[index].domain->vn==3);
512
assert(face_meshes[index].domain->fn==1);
513
assert(face_meshes[index].ordered_faces.size()==1);
514
assert(original==f0);
516
for (int v=0;v<3;v++)
517
original->V(v)->T().P()=param->V(v)->T().P();
519
///get h res vertex on faces composing the diamond
520
std::vector<VertexType*> inDomain;
521
getHresVertex<FaceType>(face_meshes[index].ordered_faces,inDomain);
524
for (unsigned int k=0;k<inDomain.size();k++)
526
VertexType* test=inDomain[k];
527
FaceType * father=test->father;
529
CoordType bary=test->Bary;
530
GetUV<MeshType>(father,bary,test->T().U(),test->T().V());
532
///create Hres mesh already parametrized
533
std::vector<FaceType*> OrderedFaces;
534
CopyMeshFromVertices<MeshType>(inDomain,Ord_HVert[index],OrderedFaces,*HRES_meshes[index]);
539
/////subdivide the mesh into subdomains
540
//void InitFaceSubdivision()
543
// vcg::SimpleTempData<typename MeshType::VertContainer, param_domain* > domainVert(h_res_mesh->vert);
545
// for (int i=0;i<h_res_mesh->vert.size();i++)
548
// assert(!h_res_mesh->vert[i].IsD());
549
// ///get father and bary coordinate
550
// FaceType *father=h_res_mesh->vert[i].father;
551
// CoordType bary=h_res_mesh->vert[i].Bary;
553
// std::map<FaceType*,param_domain*>::iterator iteFace=faceMap.find(father);
554
// assert(iteFace!=faceMap.end());
556
// ///end parametrize it using that star
557
// param_domain* pdomain=(*iteFace).second;
558
// FaceType *param_face=&pdomain->domain.face[0];
559
// assert(father==pdomain->ordered_faces[0]);
561
// ///then translate barycentric into UV over the star
563
// GetUV<MeshType>(param_face,bary,u,v);
566
// h_res_mesh->vert[i].T().U()=u;
567
// h_res_mesh->vert[i].T().V()=v;
568
// h_res_mesh->vert[i].ClearS();
570
// ///set corresponding domain
571
// domainVert[i]=pdomain;
572
// subdomain[i]=pdomain;
575
// ///then set as selected border vertices
576
// for (int i=0;i<h_res_mesh->face.size();i++)
578
// VertexType *v0=h_res_mesh->face[i].V(0);
579
// VertexType *v1=h_res_mesh->face[i].V(1);
580
// VertexType *v2=h_res_mesh->face[i].V(2);
581
// if (!((domainVert[v0]==domainVert[v1])&&(domainVert[v1]==domainVert[v2])))
590
//void GetDomainHVert(param_domain* domain,std::vector<VertexType*> &HresVert)
593
// for (int i=0;i<h_res_mesh->vert.size();i++)
594
// if (subdomain[i]==domain)
595
// HresVert.push_back(&h_res_mesh->vert[i]);
598
////test current domains and unfold when is necessary and needed
599
//bool UnfoldDomain()
601
// std::set<param_domain*> folded_domains;
603
// ///set all vertices as non-visited
604
// for (int i=0;i<h_res_mesh->vert.size();i++)
605
// h_res_mesh->vert[i].ClearV();
607
// ///collect folded vertices
608
// bool folded=false;
609
// for (int i=0;i<h_res_mesh->face.size();i++)
611
// if (!(h_res_mesh->face[i].V(0)->IsS()&&
612
// h_res_mesh->face[i].V(1)->IsS()&&
613
// h_res_mesh->face[i].V(2)->IsS()))
615
// FaceType *f=&h_res_mesh->face[i];
616
// vcg::Point2<ScalarType> tex0=vcg::Point2<ScalarType>(f->V(0)->T().U(),f->V(0)->T().V());
617
// vcg::Point2<ScalarType> tex1=vcg::Point2<ScalarType>(f->V(1)->T().U(),f->V(1)->T().V());
618
// vcg::Point2<ScalarType> tex2=vcg::Point2<ScalarType>(f->V(2)->T().U(),f->V(2)->T().V());
619
// vcg::Triangle2<MeshType::ScalarType> t2d=vcg::Triangle2<MeshType::ScalarType>(tex0,tex1,tex2);
620
// ScalarType area=(tex1-tex0)^(tex2-tex0);
623
// h_res_mesh->face[i].V(0)->SetV();
624
// h_res_mesh->face[i].V(1)->SetV();
625
// h_res_mesh->face[i].V(2)->SetV();
633
// //printf("nothing to unfold\n");
637
// ///collect all domains in wich needed optimization
638
// for (int i=0;i<h_res_mesh->vert.size();i++)
639
// if (h_res_mesh->vert[i].IsV())
640
// folded_domains.insert(subdomain[i]);
643
// for (int i=0;i<h_res_mesh->vert.size();i++)
644
// h_res_mesh->vert[i].ClearV();
646
// ///for each one try to unfold
647
// std::set<param_domain*>::iterator iteParam;
648
// for (iteParam=folded_domains.begin();iteParam!=folded_domains.end();iteParam++)
650
// std::vector<VertexType*> HresVert;
651
// std::vector<VertexType*> ordVert;
652
// //HresVert.clear();
653
// ///get h resolution vertex
655
// //getHresVertex<FaceType>((*iteParam)->ordered_faces,HresVert);*/
656
// /*for (int i=0;i<h_res_mesh->vert.size();i++)
657
// if (subdomain[i]==(*iteParam))
658
// HresVert.push_back(&h_res_mesh->vert[i]);*/
660
// GetDomainHVert((*iteParam),HresVert);
662
// CopyMeshFromVertices<MeshType>(HresVert,ordVert,folded);
664
// bool done=UnFold<MeshType>(folded,(*iteParam)->ordered_faces.size());
665
// ///copy back values
669
// for (int i=0;i<folded.vert.size();i++)
670
// ordVert[i]->T().P()=folded.vert[i].T().P();
676
//void MinimizeStep(char *phasename,
677
// const ScalarType &conv_interval=0.00001,
678
// const int &max_step=500)
683
// std::vector<CoordType> oldPos;
684
// std::vector<FaceType*> oldFather;
685
// oldPos.resize(h_res_mesh->vert.size());
686
// oldFather.resize(h_res_mesh->vert.size());
688
// for (int i=0;i<h_res_mesh->vert.size();i++)
690
// oldPos[i]=h_res_mesh->vert[i].Bary;
691
// oldFather[i]=h_res_mesh->vert[i].father;
695
// ///fix selected vertices
696
// optimizer[0]->SetNothingAsFixed();
697
// for (int i=0;i<h_res_mesh->vert.size();i++)
698
// if (h_res_mesh->vert[i].IsS())
699
// optimizer[opt_type]->FixVertex(&h_res_mesh->vert[i]);
703
// //ScalarType speed=2.0/(sqrt((ScalarType)h_res_mesh->vn/(ScalarType)domain->vn))*optimize_speed_fact;
704
// //optimizer[opt_type]->SetSpeed(speed);
706
// /////then iterate until convergence
707
// //for (int i=0;i<max_step;i++)
708
// // optimizer[opt_type]->IterateBlind();
709
// ScalarType speed0=sqrt((ScalarType)domain->fn/(ScalarType)h_res_mesh->vn) * optimize_speed_fact;
710
// //ScalarType speed0=optimize_speed_fact;
711
// optimizer[opt_type]->SetSpeed(speed0);
712
// ///END SETTINS SPEED
714
// // opt.IterateUntilConvergence(0.001);//,itenum);
716
// int ite=optimizer[opt_type]->IterateUntilConvergence(speed0/10.0);//,itenum);
718
// /*optimizer[opt_type]->IterateUntilConvergence(conv_interval,max_step);*/
721
// //reassing fathers and bary coordinates
722
// for (int i=0;i<h_res_mesh->vert.size();i++)
724
// VertexType *vert=&h_res_mesh->vert[i];
725
// param_domain* pdomain=subdomain[i];
726
// ScalarType u=vert->T().U();
727
// ScalarType v=vert->T().V();
728
// ///then get face falling into and estimate (alpha,beta,gamma)
731
// inside &=GetBaryFaceFromUV(pdomain->domain,u,v,pdomain->ordered_faces,bary,chosen);
732
// vert->father=chosen;
738
// ScalarType max_diff=0;
739
// for (int i=0;i<h_res_mesh->vert.size();i++)
741
// //ScalarType displ=(oldPos[i]-ProjectPos(h_res_mesh->vert[i])).Norm();
742
// if (oldFather[i]!=h_res_mesh->vert[i].father)
746
// ScalarType displ = (oldPos[i]-h_res_mesh->vert[i].Bary).SquaredNorm();
747
// if (displ>max_diff) max_diff=displ;
750
// printf("%s : \n",phasename);
751
// printf(" diff:%6.5f \n",sqrt(max_diff) );
752
// printf("migr:%i \n",changed);
753
// printf("AREA distorsion:%lf \n",ApproxAreaDistortion<MeshType>(*h_res_mesh,domain->fn));
754
// printf("ANGLE distorsion:%lf \n",ApproxAngleDistortion<MeshType>(*h_res_mesh));
756
// printf("Point out of parametrization during optimization \n");*/
760
void MinimizeStep(const int &phaseNum)
765
for (unsigned int i=0;i<HRES_meshes.size();i++)
768
MeshType *currMesh=HRES_meshes[i];
771
UpdateTopologies<MeshType>(currMesh);
777
case 0:numDom=6;break;//star
778
case 1:numDom=2;break;//diam
779
case 2:numDom=1;break;//face
781
///save previous values
782
InitDampRestUV(*currMesh);
783
bool b=UnFold<MeshType>(*currMesh,numDom);
784
bool isOK=testParamCoords<MeshType>(*currMesh);
786
RestoreRestUV<MeshType>(*currMesh);
788
OptType opt(*currMesh);
789
opt.TargetCurrentGeometry();
790
opt.SetBorderAsFixed();
792
///save previous values
793
InitDampRestUV(*currMesh);
798
/*ScalarType edge_esteem=GetSmallestUVEdgeSize<MeshType>(*currMesh);
799
ScalarType speed0=edge_esteem*0.01;
800
ScalarType conv=edge_esteem*0.0005;*/
801
ScalarType edge_esteem=GetSmallestUVHeight(*currMesh);
804
ScalarType speed0=edge_esteem*0.1;
805
ScalarType conv=edge_esteem*0.002;
808
conv*=1.0/(ScalarType)((accuracy-1)*10.0);
810
opt.SetSpeed(speed0);
811
/*int ite=*/opt.IterateUntilConvergence(conv);
813
///test for uv errors
815
for (unsigned int j=0;j<currMesh->vert.size();j++)
817
VertexType *ParamVert=&currMesh->vert[j];
818
ScalarType u=ParamVert->T().U();
819
ScalarType v=ParamVert->T().V();
820
if ((!((u<=1.001)&&(u>=-1.001)))||
821
(!(v<=1.001)&&(v>=-1.001)))
825
// printf("error in minimization... recovering...\n");
827
for (unsigned int k=0;k<currMesh->vert.size();k++)
828
currMesh->vert[k].T().P()=currMesh->vert[k].RestUV;
832
//reassing fathers and bary coordinates
833
for (unsigned int j=0;j<currMesh->vert.size();j++)
835
VertexType *ParamVert=&currMesh->vert[j];
836
VertexType *OrigVert=Ord_HVert[i][j];
837
ScalarType u=ParamVert->T().U();
838
ScalarType v=ParamVert->T().V();
839
///then get face falling into and estimate (alpha,beta,gamma)
842
param_domain *currDom;
845
case 0:currDom=&star_meshes[i];break;//star
846
case 1:currDom=&diamond_meshes[i];break;//diam
847
case 2:currDom=&face_meshes[i];break;//face
849
/*assert(currDom->domain->vn==3);
850
assert(currDom->domain->fn==1);*/
851
bool inside=GetBaryFaceFromUV(*currDom->domain,u,v,currDom->ordered_faces,bary,chosen);
855
printf("\n OUTSIDE %f,%f \n",u,v);
857
vcg::Point2<ScalarType> UV=vcg::Point2<ScalarType>(u,v);
858
ForceInParam<MeshType>(UV,*currDom->domain);
861
inside=GetBaryFaceFromUV(*currDom->domain,u,v,currDom->ordered_faces,bary,chosen);
865
OrigVert->father=chosen;
869
///delete current mesh
870
delete(HRES_meshes[i]);
873
///clear father and bary
874
for (unsigned int i=0;i<domain->face.size();i++)
875
domain->face[i].vertices_bary.clear();
877
///set face-vertex link
878
for (unsigned int i=0;i<h_res_mesh->vert.size();i++)
880
BaseVertex *v=&h_res_mesh->vert[i];
883
BaseFace *f=v->father;
884
CoordType bary=v->Bary;
885
f->vertices_bary.push_back(std::pair<VertexType*,CoordType>(v,bary));
890
//void EndOptimization()
892
// ///clear father and bary
893
// for (unsigned int i=0;i<domain->face.size();i++)
894
// domain->face[i].vertices_bary.resize(0);
896
// ///set face-vertex link
897
// for (unsigned int i=0;i<h_res_mesh->vert.size();i++)
899
// BaseVertex *v=&h_res_mesh->vert[i];
900
// BaseFace *f=v->father;
901
// CoordType bary=v->Bary;
902
// f->vertices_bary.push_back(std::pair<VertexType*,CoordType>(v,bary));
908
vcg::CallBackPos *cb;
914
void Init(MeshType &_domain,
915
MeshType &_h_res_mesh,
916
vcg::CallBackPos *_cb,
923
vcg::tri::UpdateNormals<MeshType>::PerFaceNormalized(_domain);
926
h_res_mesh=&_h_res_mesh;
928
/*subdomain.resize(h_res_mesh->vert.size());*/
930
///get the average area per triangle
931
/*ScalarType area=Area<MeshType>(_h_res_mesh);*/
933
///get esteemation of average area per triangle
934
//ScalarType average_area=area/(ScalarType)_h_res_mesh.vn;
937
star_meshes.resize(domain->vn);
938
InitStarEquilateral();
939
/*InitStarSubdivision();*/
941
///initialize DIAMONDS
943
for (unsigned int i=0;i<domain->face.size();i++)
945
if (!(domain->face[i].IsD()))
947
FaceType *f0=&domain->face[i];
949
for (int j=0;j<3;j++)
951
FaceType * f1=f0->FFp(j);
957
diamond_meshes.resize(num_edges);
958
InitDiamondEquilateral();
961
face_meshes.resize(domain->fn);
962
InitFaceEquilateral();
965
for (unsigned int i=0;i<h_res_mesh->vert.size();i++)
966
h_res_mesh->vert[i].P()=h_res_mesh->vert[i].RPos;
968
//InitDampRestUV(*h_res_mesh);
972
void PrintAttributes()
974
/*ScalarType distArea=ApproxAreaDistortion<BaseMesh>(*h_res_mesh,domain->fn);
975
ScalarType distAngle=ApproxAngleDistortion<BaseMesh>(*h_res_mesh);
976
ScalarType distAggregate=geomAverage<ScalarType>(distArea+1.0,distAngle+1.0,3,1)-1;
977
printf("\n AREA distorsion:%lf;\n ANGLE distorsion:%lf;\n AGGREGATE distorsion:%lf \n\n",distArea,distAngle,distAggregate);*/
980
ScalarType ratio=(ScalarType)done/total;
981
int percent=(int)(ratio*(ScalarType)100);
982
ScalarType distArea=ApproxAreaDistortion<BaseMesh>(*h_res_mesh,domain->fn);
983
ScalarType distAngle=ApproxAngleDistortion<BaseMesh>(*h_res_mesh);
985
sprintf(ret," PERFORM GLOBAL OPTIMIZATION Area distorsion:%4f ; ANGLE distorsion:%4f ",distArea,distAngle);
989
void Optimize(ScalarType gap=0.5)
994
ScalarType distArea=ApproxAreaDistortion<BaseMesh>(*h_res_mesh,domain->fn);
995
ScalarType distAngle=ApproxAngleDistortion<BaseMesh>(*h_res_mesh);
996
ScalarType distAggregate0=geomAverage<ScalarType>(distArea+1.0,distAngle+1.0,3,1)-1;
998
bool ContinueOpt=true;
1000
PatchesOptimizer<BaseMesh> DomOpt(*domain,*h_res_mesh);
1004
DomOpt.OptimizePatches();
1010
///domain Optimization
1013
printf("\n DOING STAR\n");
1015
InitStarSubdivision();
1017
//PrintAttributes();
1019
printf("\n DOING DIAMOND\n");
1021
InitDiamondSubdivision();
1023
//PrintAttributes();
1025
printf("\n DOING FACES\n");
1027
InitFaceSubdivision();
1032
distArea=ApproxAreaDistortion<BaseMesh>(*h_res_mesh,domain->fn);
1033
distAngle=ApproxAngleDistortion<BaseMesh>(*h_res_mesh);
1034
ScalarType distAggregate1=geomAverage<ScalarType>(distArea+1.0,distAngle+1.0,3,1)-1;
1035
ScalarType NewGap=((distAggregate0-distAggregate1)*100.0)/distAggregate0;
1038
printf("\n Step %d Gap %lf \n",k,NewGap);
1042
distAggregate0=distAggregate1;
1044
///*EndOptimization();*/
1047
//printf("TIME OPTIMIZATION:%d \n",(t1-t0)/1000);
b'\\ No newline at end of file'