3
#include <vcg/complex/trimesh/refine.h>
4
#include <vcg/simplex/face/pos.h>
5
#include <vcg/space/color4.h>
6
#include <vcg/space/intersection2.h>
11
class DiamondParametrizator
13
typedef IsoParametrization::CoordType CoordType;
14
typedef IsoParametrization::ScalarType ScalarType;
16
IsoParametrization *isoParam;
18
///data used for splitting
19
typedef std::pair<int,int> EdgeKey;
22
typedef struct InterpData
26
vcg::Point2<float> UV;
29
std::map<EdgeKey,InterpData> alphaMap;
31
///data used to store an retrieve edges
32
//typedef std::pair<AbstractFace*,int> TriEdge;
33
//std::vector<DiamondPatch> DDAdiacency;
34
//std::map<TriEdge,int> edgeMap;
37
template <class FaceType>
38
int AssignDiamond(FaceType *face)
40
ScalarType val=(ScalarType)1.0/(ScalarType)3.0;
41
CoordType bary3d(val,val,val);
43
vcg::Point2<ScalarType> UV_interp;
44
isoParam->Phi(face,bary3d,I_interp,UV_interp);
45
int D_interp=isoParam->getHDiamIndex(I_interp,UV_interp);
46
face->WT(0).N()=D_interp;
47
face->WT(1).N()=D_interp;
48
face->WT(2).N()=D_interp;
52
///associate the diamond in which a face belongs to
53
void AssociateDiamond()
55
ParamMesh *to_param=isoParam->ParaMesh();
56
typedef ParamMesh::FaceType FaceType;
58
///first step first associating initial faces to diamond
59
for (unsigned int i=0;i<to_param->face.size();i++)
61
FaceType *curr=&to_param->face[i];
63
curr->C()=colorDiam[curr->WT(0).N()];
67
void InterpEdge(const ParamFace *f,const int &index_edge,
68
const float &alpha,int &I,vcg::Point2<ScalarType> &UV)
73
int index0=index_edge;
74
int index1=(index_edge+1)%3;
75
CoordType bary=CoordType(0,0,0);
76
assert((alpha>=0)&&(alpha<=1));
78
bary.V(index1)=((ScalarType)1.0-alpha);
79
isoParam->Phi(f,bary,I,UV);
80
assert((UV.X()>=0)&&(UV.Y()>=0)&&(UV.X()<=1)&&(UV.Y()<=1)&&(UV.X()+UV.Y()<=1+eps));
83
template <class FaceType>
84
vcg::Point2f QuadCoord(FaceType * curr,const int &vert_num)
86
typedef typename FaceType::VertexType VertexType;
87
typedef typename FaceType::ScalarType ScalarType;
89
VertexType* v=curr->V(vert_num);
91
int DiamIndex=curr->WT(0).N(); ///get index of diamond associated to the face
92
assert((curr->WT(0).N()==curr->WT(1).N())&&(curr->WT(1).N()==curr->WT(2).N()));
94
///transform to quad coordinates
96
vcg::Point2f UV=v->T().P();
98
///transform in diamond coordinates
99
vcg::Point2f UVDiam,UVQuad;
100
isoParam->GE1(I,UV,DiamIndex,UVDiam);
102
///transform in quad coordinates
103
isoParam->GE1Quad(DiamIndex,UVDiam,UVQuad);
108
template <class FaceType>
109
bool To_Split(FaceType * curr,const float &border,
110
bool to_split[3],InterpData Idata[3])
116
typedef typename FaceType::VertexType VertexType;
117
typedef typename FaceType::ScalarType ScalarType;
119
/*ParamMesh *to_param=isoParam->ParaMesh();*/
121
/*int DiamIndex=curr->WT(0).N(); *////get index of diamond associated to the face
122
assert((curr->WT(0).N()==curr->WT(1).N())&&(curr->WT(1).N()==curr->WT(2).N()));
124
vcg::Point2f UVQuad[3];
126
UVQuad[0]=QuadCoord(curr,0);
127
UVQuad[1]=QuadCoord(curr,1);
128
UVQuad[2]=QuadCoord(curr,2);
131
vcg::Box2<ScalarType> bbox,bbox0;
132
bbox.Add(vcg::Point2f(-border,-border));
133
bbox.Add(vcg::Point2f(1+border,1+border));
134
bbox0.Add(vcg::Point2f(0,0));
135
bbox0.Add(vcg::Point2f(1,1));
137
if (bbox.IsIn(UVQuad[0])&&bbox.IsIn(UVQuad[1])&&bbox.IsIn(UVQuad[2]))
138
return false; ///no intersection is possible
140
///else test which edges must be splitted
141
//vcg::Segment2<float> border_seg[4];
142
vcg::Line2<float> border_seg[4];
143
border_seg[0].Set(vcg::Point2f(0,0),vcg::Point2f(1,0));
144
border_seg[1].Set(vcg::Point2f(1,0),vcg::Point2f(0,1));
145
border_seg[2].Set(vcg::Point2f(0,1),vcg::Point2f(1,0));
146
border_seg[3].Set(vcg::Point2f(0,0),vcg::Point2f(0,1));
147
bool intersected=false;
148
for (int edge=0;edge<3;edge++)
150
vcg::Segment2<float> curr_edge=vcg::Segment2<float>(UVQuad[edge],UVQuad[(edge+1)%3]);
151
float dist_medium=1.0;
152
for (int j=0;j<4;j++)
154
vcg::Point2f p_inters;
155
vcg::Line2<float> curr_border=border_seg[j];
156
bool intersect=LineSegmentIntersection(curr_border,curr_edge,p_inters);
158
float l_test0=(curr_edge.P0()-p_inters).Norm();
159
float l_test1=(curr_edge.P1()-p_inters).Norm();
160
float l_test=std::min(l_test0,l_test1);
162
const ScalarType _EPS=(ScalarType)0.0001;
163
if ((intersect)&&(l_test>=_EPS))
165
float lenght=curr_edge.Length();
166
float dist=((curr_edge.P0()-p_inters).Norm());
167
float Ndist=dist/lenght;
168
float alpha=1.0-Ndist;
169
float dist_medium1=fabs(alpha-0.5);
171
if (dist_medium1<dist_medium)
173
dist_medium=dist_medium1;
176
InterpEdge(curr,edge,alpha,I,UV);
177
Idata[edge].alpha=alpha;
191
// Basic subdivision class
192
// This class must provide methods for finding the position of the newly created vertices
193
// In this implemenation we simply put the new vertex in the MidPoint position.
194
// Color and TexCoords are interpolated accordingly.
195
template<class MESH_TYPE>
196
struct SplitMidPoint : public std::unary_function<vcg::face::Pos<typename MESH_TYPE::FaceType> , typename MESH_TYPE::CoordType >
198
typedef typename MESH_TYPE::VertexType VertexType;
199
typedef typename MESH_TYPE::FaceType FaceType;
200
typedef typename MESH_TYPE::CoordType CoordType;
202
std::map<EdgeKey,InterpData> *alphaMap;
203
IsoParametrization *isoParam;
207
void operator()(typename MESH_TYPE::VertexType &nv, vcg::face::Pos<typename MESH_TYPE::FaceType> ep)
211
ParamMesh *to_param=isoParam->ParaMesh();
213
///get eth value on which the edge must be splitted
214
VertexType* v0=ep.f->V(ep.z);
215
VertexType* v1=ep.f->V1(ep.z);
217
int i0=IndexFromPointer(v0,to_param);
218
int i1=IndexFromPointer(v1,to_param);
223
int index1=(ep.z+1)%3;
229
std::swap(index0,index1);
233
std::map<EdgeKey,InterpData>::iterator ItE=alphaMap->find(k);
234
assert(ItE!=alphaMap->end());
235
InterpData interp=(*ItE).second;
236
float alpha=interp.alpha;
237
assert((alpha>=0)&&(alpha<=1));
238
nv.P()= v0->P()*alpha+v1->P()*(1.0-alpha);
239
nv.RPos= v0->RPos*alpha+v1->RPos*(1.0-alpha);
241
if( MESH_TYPE::HasPerVertexNormal())
242
nv.N()=v0->N()*alpha+v1->N()*((ScalarType)1.0-alpha);
243
if( MESH_TYPE::HasPerVertexColor())
245
CoordType color=CoordType(v0->C().X(),v0->C().Y(),v0->C().Z());
246
color=color*alpha+color*((ScalarType)1.0-alpha);
247
nv.C()=vcg::Color4b((unsigned char)color.X(),(unsigned char)color.Y(),(unsigned char)color.Z(),(unsigned char)255);
251
nv.T().P()=interp.UV;
254
vcg::TexCoord2<float> WedgeInterp(vcg::TexCoord2<float> &t0, vcg::TexCoord2<float> &t1)
256
vcg::TexCoord2<float> tmp;
257
assert(t0.n()== t1.n());
259
tmp.t()=(t0.t()+t1.t())/2.0;
266
template <class MESH_TYPE>//, class FLT>
269
typedef typename MESH_TYPE::VertexType VertexType;
270
typedef typename MESH_TYPE::FaceType FaceType;
272
std::map<EdgeKey,InterpData> *alphaMap;
273
IsoParametrization *isoParam;
275
bool operator()(vcg::face::Pos<typename MESH_TYPE::FaceType> ep) const
277
ParamMesh *to_param=isoParam->ParaMesh();
279
VertexType* v0=ep.f->V(ep.z);
280
VertexType* v1=ep.f->V1(ep.z);
282
int i0=IndexFromPointer(v0,to_param);
283
int i1=IndexFromPointer(v1,to_param);
295
std::map<EdgeKey,InterpData>::iterator ItE=alphaMap->find(k);
296
bool to_split=(ItE!=alphaMap->end());
301
static int IndexFromPointer(ParamVertex * v,ParamMesh *mesh)
303
int index=v-&(*mesh->vert.begin());
307
void InsertInterpData(ParamFace *curr,const int &edge,
308
ParamMesh *to_param,InterpData &Idata)
310
ParamVertex *v0=curr->V(edge);
311
ParamVertex *v1=curr->V1(edge);
312
int i0=IndexFromPointer(v0,to_param);
313
int i1=IndexFromPointer(v1,to_param);
318
Idata.alpha=(ScalarType)1.0-Idata.alpha;
319
assert((Idata.alpha>=0)&&(Idata.alpha<=1));
321
EdgeKey k=EdgeKey(i0,i1);
322
std::map<EdgeKey,InterpData>::iterator ItE=alphaMap.find(k);
323
if(ItE!=alphaMap.end())
325
if (fabs((*ItE).second.alpha-0.5)>fabs(Idata.alpha-0.5))
327
(*ItE).second.alpha=Idata.alpha;
328
(*ItE).second.I=Idata.I;
329
(*ItE).second.UV=Idata.UV;
333
alphaMap.insert(std::pair<EdgeKey,InterpData>(k,Idata));
336
bool Split(const ScalarType &border)
340
ParamMesh *to_param=isoParam->ParaMesh();
342
typedef ParamMesh::VertexType VertexType;
343
typedef ParamMesh::FaceType FaceType;
344
SplitMidPoint<ParamMesh> splMd;
345
EdgePredicate<ParamMesh> eP;
347
///second step.. test the split if needed
348
for (unsigned int i=0;i<to_param->face.size();i++)
350
///get the current face and test the edges
351
FaceType * curr=&to_param->face[i];
354
bool is_out=To_Split<FaceType>(curr,border,to_split,Idata);
356
for (int edge=0;edge<3;edge++)
358
InsertInterpData(curr,edge,to_param,Idata[edge]);
362
splMd.isoParam=isoParam;
363
splMd.alphaMap=&alphaMap;
364
eP.isoParam=isoParam;
365
eP.alphaMap=&alphaMap;
367
/*int f0=to_param->fn;*/
368
bool done=vcg::RefineE<ParamMesh,SplitMidPoint<ParamMesh>,EdgePredicate<ParamMesh> >(*to_param,splMd,eP);
370
printf("FACE ADDED %d \n",to_param->fn-f0);
376
void SetWedgeCoords(const ScalarType &border)
378
typedef ParamMesh::VertexType VertexType;
379
typedef ParamMesh::FaceType FaceType;
381
ParamMesh *to_param=isoParam->ParaMesh();
383
for (unsigned int i=0;i<to_param->face.size();i++)
385
///get the current face and test the edges
386
FaceType * curr=&to_param->face[i];
387
for (int j=0;j<3;j++)
389
vcg::Point2f QCoord=QuadCoord(curr,j);
390
///transform from [ -border,1 + border] to [0,1]
391
QCoord+=vcg::Point2f(border,border);
392
QCoord/=(ScalarType)1.0+(ScalarType)2.0*border;
393
assert((QCoord.X()>=0)&&(QCoord.X()<=1)&&(QCoord.Y()>=0)&&(QCoord.Y()<=1));
394
curr->WT(j).P()=QCoord;
395
///and finally set for global texture coords
404
std::vector<vcg::Color4b > colorDiam;
406
///initialize the parameterization
407
void Init(IsoParametrization *_isoParam)
412
///COUNT THE NUMBER OF EDGES
414
for (unsigned int i=0;i<isoParam->AbsMesh()->face.size();i++)
416
AbstractFace *f=&isoParam->AbsMesh()->face[i];
417
for (int j=0;j<3;j++)
422
colorDiam.resize(num_diamonds);
424
for (unsigned int i=0;i<colorDiam.size();i++)
425
colorDiam[i]=vcg::Color4b(rand()%255,rand()%255,rand()%255,255);
431
// ParamMesh *to_param=isoParam->ParaMesh();
432
// //vcg::tri::UpdateNormals<ParamMesh>::PerFaceNormalized(*to_param);
433
// glDepthRange(0.01,1.0);
434
// glEnable(GL_LIGHTING);
435
// glEnable(GL_LIGHT0);
436
// glEnable(GL_NORMALIZE);
437
// glBegin(GL_TRIANGLES);
438
// for (int i=0;i<to_param->face.size();i++)
441
// /*vcg::glColor(to_param->face[i].C());*/
443
// CoordType p0=to_param->face[i].V(0)->P();
444
// CoordType p1=to_param->face[i].V(1)->P();
445
// CoordType p2=to_param->face[i].V(2)->P();
446
// CoordType norm=(p1-p0)^(p2-p0);
448
// vcg::glNormal(norm);
449
// vcg::Point2f t0=to_param->face[i].WT(0).P();
450
// vcg::Point2f t1=to_param->face[i].WT(1).P();
451
// vcg::Point2f t2=to_param->face[i].WT(2).P();
452
// vcg::Color4b c0,c1,c2;
453
// if ((t0.X()< 0)||(t0.Y()< 0)||(t0.X()>1.0)||(t0.Y()>1.0))
454
// c0=vcg::Color4b(0,0,255,255);
456
// c0=vcg::Color4b(t0.X()*255.0,t0.Y()*255.0,0,255);
457
// if ((t1.X()< 0)||(t1.Y()< 0)||(t1.X()>1.0)||(t1.Y()>1.0))
458
// c1=vcg::Color4b(0,0,255,255);
460
// c1=vcg::Color4b(t1.X()*255.0,t1.Y()*255.0,0,255);
461
// if ((t2.X()< 0)||(t2.Y()< 0)||(t2.X()>1.0)||(t2.Y()>1.0))
462
// c2=vcg::Color4b(0,0,255,255);
464
// c2=vcg::Color4b(t2.X()*255.0,t2.Y()*255.0,0,255);
466
// vcg::glVertex(to_param->face[i].V(0)->P());
468
// vcg::glVertex(to_param->face[i].V(1)->P());
470
// vcg::glVertex(to_param->face[i].V(2)->P());
474
// /*glDepthRange(0,0.99999);
475
// glDisable(GL_LIGHTING);
476
// glDisable(GL_LIGHT0);
477
// glDisable(GL_NORMALIZE);
480
// for (int i=0;i<to_param->face.size();i++)
482
// glBegin(GL_LINE_LOOP);
483
// CoordType p0=to_param->face[i].V(0)->P();
484
// CoordType p1=to_param->face[i].V(1)->P();
485
// CoordType p2=to_param->face[i].V(2)->P();
486
// vcg::glVertex(to_param->face[i].V(0)->P());
487
// vcg::glVertex(to_param->face[i].V(1)->P());
488
// vcg::glVertex(to_param->face[i].V(2)->P());
492
// glDepthRange(0.0,1.0);
497
///set the vertex coordinates
498
void SetCoordinates(const ScalarType &border=0.01)
500
std::vector<vcg::Color4b > colorDiam;
502
//ParamMesh *to_param=isoParam->ParaMesh();
504
typedef ParamMesh::FaceType FaceType;
505
typedef ParamMesh::VertexType VertexType;
508
/*int n0=to_param->fn;*/
517
SetWedgeCoords(border);
b'\\ No newline at end of file'