1 #ifndef RGBINFO_H_
2 #define RGBINFO_H_
3 
4 /****************************************************************************
5 * Rgb Triangulations Plugin                                                 *
6 *                                                                           *
7 * Author: Daniele Panozzo (daniele.panozzo@gmail.com)                       *
8 * Copyright(C) 2007                                                         *
9 * DISI - Department of Computer Science                                     *
10 * University of Genova                                                      *
11 *                                                                           *
12 * All rights reserved.                                                      *
13 *                                                                           *
14 * This program is free software; you can redistribute it and/or modify      *
15 * it under the terms of the GNU General Public License as published by      *
16 * the Free Software Foundation; either version 2 of the License, or         *
17 * (at your option) any later version.                                       *
18 *                                                                           *
19 * This program is distributed in the hope that it will be useful,           *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
22 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
23 * for more details.                                                         *
24 ****************************************************************************/
25 
26 #include <common/meshmodel.h>
27 #include <iostream>
28 
29 namespace rgbt
30 {
31 using vcg::Point3f;
32 using std::list;
33 /// Represent a sorted pair of vertex
34 struct VertexPair
35 {
VertexPairVertexPair36     VertexPair() {}
37     /// Costruct a new pair
VertexPairVertexPair38     VertexPair(int v1, int v2)
39     {
40         assert(v1 != v2);
41         if (v1 <= v2)
42         {
43             this->v1 = v1;
44             this->v2 = v2;
45         }
46         else
47         {
48             this->v1 = v2;
49             this->v2 = v1;
50         }
51 
52     }
53 
54     friend int operator==(const VertexPair& l, const VertexPair& r)
55     {
56         return (l.v1 == r.v1 && l.v2 == r.v2);
57     }
58     /// First vertex
59     int v1;
60     /// Second vertex
61     int v2;
62 };
63 /// Additional information for a Vertex needed by the RGB triangulation
64 class VertexInfo
65 {
66 public:
67 
VertexInfo()68     VertexInfo()
69     {
70     	resetInfo();
71     }
72     /// Reset the Vertex at the original status
resetInfo()73     inline void resetInfo()
74     {
75     	level = 0;
76     	count = 0;
77     	isPinfReady = false;
78     	Point3f pzero = Point3f(0,0,0);
79     	pl = pzero;
80     	pinf = pzero;
81     	isMarked = false;
82     	isBorder = false;
83     }
84 
85     /// Set vertex level
setLevel(short int l)86     inline void setLevel(short int l)
87     {
88         level = l;
89     }
90 
91     /// Get vertex level
getLevel()92     inline const short int getLevel()
93     {
94         return level;
95     }
96     /// Get vertex control point at level l
getPl()97     inline const Point3f& getPl()
98     {
99     	return pl;
100     }
101     /// Set vertex control point at level l
setPl(Point3f & p)102     inline void setPl(Point3f& p)
103     {
104     	pl = p;
105     }
106     /// Get vertex control point at level inf
getPinf()107     inline const Point3f& getPinf()
108     {
109     	return pinf;
110     }
111     /// Set vertex control point at level inf
setPinf(Point3f & p)112     inline void setPinf(Point3f& p)
113     {
114     	pinf = p;
115     }
116     /// Get number of contribute already given
getCount()117     inline int getCount()
118     {
119     	return count;
120     }
121     /// Set number of contribute already given
setCount(int c)122     inline void setCount(int c)
123     {
124     	count = c;
125     }
126     /// Get the number of incident edges in the base mesh
getBaseArity()127     inline int getBaseArity()
128     {
129     	return arity;
130     }
131     /// Set the number of incident edges in the base mesh
setBaseArity(int a)132     inline void setBaseArity(int a)
133     {
134     	arity = a;
135     }
136 
137     /// Return true if Pinf is already computed
getIsPinfReady()138     inline bool getIsPinfReady()
139     {
140     	return isPinfReady;
141     }
142     /// Return the status of Pinf
setIsPinfReady(bool c)143     inline void setIsPinfReady(bool c)
144     {
145     	isPinfReady = c;
146     }
147     /// Return true if the vertex is Marked
getIsMarked()148     inline bool getIsMarked()
149     {
150     	return isMarked;
151     }
152     /// Set the mark
setIsMarked(bool c)153     inline void setIsMarked(bool c)
154     {
155     	isMarked = c;
156     }
157     /// Return true if the vertex is inserted in the current selective refinement
getIsNew()158     inline bool getIsNew()
159     {
160     	return isNew;
161     }
162     /// Set if the vertex is inserted in the current selective refinement
setIsNew(bool c)163     inline void setIsNew(bool c)
164     {
165     	isNew = c;
166     }
167 
168     /// Return true if the vertex is on the border
getIsBorder()169     inline bool getIsBorder()
170     {
171         return isBorder;
172     }
173     /// Set if the vertex is on the border
setIsBorder(bool c)174     inline void setIsBorder(bool c)
175     {
176         isBorder = c;
177     }
178 
179     /// List that contain the index of all the vertexes that has contributed to Pinf
taken()180     inline list<int>& taken()
181     {
182     	return cTaken;
183     }
184     /// List that contain the index of all the vertexes that depends on this vertex for Pinf
given()185     inline list<int>& given()
186     {
187     	return cGiven;
188     }
189 
190 
191 private:
192 	/// Level of vertex
193     short int level;
194     /// Point at insertion level
195     Point3f pl;
196     /// Point at inf level
197     Point3f pinf;
198     /// Count the numbers of p^l accumulated
199     int count;
200     /// Indicate if Pinf contaian a correct value or only the sum of p^l-1
201     bool isPinfReady;
202     /// Is used during recursive split of green edges performed during the calculation of control point for an odd vertex
203     bool isMarked;
204     /// Is used during recursive split of green edges performed during the calculation of control point for an odd vertex
205     bool isNew;
206     /// Contain the indexes of the vertex that has contributed to Pinf
207     list<int> cTaken;
208     /// Contain the indexes of the vertex that has this Pl added in the Pinf
209     list<int> cGiven;
210     /// Indicates if the vertex is on the border of the mesh
211     bool isBorder;
212     /// Number of incident edge in the base mesh
213     int arity;
214 
215 };
216 
217 /// Additional information for a Face needed by the RGB triangulation
218 class FaceInfo
219 {
220 public:
FaceInfo()221     FaceInfo() :
222         color(FACE_GREEN), level(0)
223     {
224 
225     }
226 
227     /// Color of a face
228     typedef enum
229     {
230         FACE_RED_GGR = 1, /*!< RED, starting from the highest level vertex in ccw order the edges are green, green, red*/
231         FACE_RED_RGG = 2, /*!< RED, starting from the highest level vertex in ccw order the edges are red, green, green*/
232         FACE_GREEN = 0, /*!< GREEN*/
233         FACE_BLUE_GGR = 3, /*!< BLUE, starting from the lowest level vertex in ccw order the edges are green, green, red*/
234         FACE_BLUE_RGG = 4, /*!< BLUE, starting from the lowest level vertex in ccw order the edges are red, green, green*/
235     } FaceColor;
236 
237     /// Edge Color
238     typedef enum
239     {
240         EDGE_RED = 0, /*!< RED*/
241         EDGE_GREEN = 1 /*!< GREEN*/
242     } EdgeColor;
243 
244     /// Set the face color
setColor(FaceColor fc)245     inline void setColor(FaceColor fc)
246     {
247         color = fc;
248     }
249 
250     /// Get the face color
getColor()251     inline const FaceColor getColor()
252     {
253         return color;
254     }
255 
256     /// Set the face level
setLevel(short int l)257     inline void setLevel(short int l)
258     {
259         level = l;
260     }
261 
262     /// Get the face level
getLevel()263     inline const short int getLevel()
264     {
265         return level;
266     }
267 
268 private:
269 	/// Face color
270     FaceColor color;
271     /// Face level
272     short int level;
273 };
274 
275 /// Container for all the informations needed by a rgb triangulation
276 class RgbInfo
277 {
278 public:
279 	typedef std::vector<VertexInfo> VERTEXC;
280 	typedef std::vector<FaceInfo> FACEC;
281 	/// Allocate information for nvert vertexes and nface faces
RgbInfo(int nvert,int nface)282     RgbInfo(int nvert, int nface)
283     {
284         vert.resize(nvert);
285         face.resize(nface);
286     }
~RgbInfo()287     virtual ~RgbInfo()
288     {
289     };
290     /// Vertex informations
291     VERTEXC vert;
292     /// Face informations
293     FACEC face;
294 };
295 
296 template<class TRI_MESH_TYPE> class RgbVertex;
297 /// Wrapper for RgbInfo and CMeshO that allow a trasparent access to geometrical, topological and rgb informations on a triangle
298 template<class TRI_MESH_TYPE> class RgbTriangle
299 {
300 public:
301 
302     typedef FaceInfo::FaceColor FaceColor;
303     typedef FaceInfo::EdgeColor EdgeColor;
304 
305     /// The tetrahedral mesh type
306     typedef TRI_MESH_TYPE TriMeshType;
307     /// The face type
308     typedef typename TriMeshType::FaceType FaceType;
309     /// The vertex type
310     typedef typename FaceType::VertexType VertexType;
311     /// The vertex type pointer
312     typedef typename FaceType::VertexType* VertexPointer;
313     /// Face Pointer
314     typedef typename TriMeshType::FacePointer FacePointer;
315 
316 	typedef typename VertexType::ScalarType ScalarType;
317 	typedef typename VertexType::CoordType CoordType;
318 
319 
320 
321     // Standard costructor for use in STL containers
RgbTriangle()322     RgbTriangle() {}
323     /// Costruct a new RGBTriangle for the triangle of index TriangleIndex
RgbTriangle(TriMeshType & M,RgbInfo & Info,int TriangleIndex)324     RgbTriangle(TriMeshType& M, RgbInfo& Info, int TriangleIndex) :
325         m(&M), rgbInfo(&Info), index(TriangleIndex)
326     {
327         assert(TriMeshType::HasFFTopology());
328         updateInfo();
329     }
330     /// Costruct a new RGBTriangle for the triangle of index TriangleIndex
RgbTriangle(TriMeshType * M,RgbInfo * Info,int TriangleIndex)331     RgbTriangle(TriMeshType* M, RgbInfo* Info, int TriangleIndex) :
332         m(M), rgbInfo(Info), index(TriangleIndex)
333     {
334         assert(TriMeshType::HasFFTopology());
335         updateInfo();
336     }
337 
338     /// Calculate all non-encoded information
updateInfo()339     inline void updateInfo()
340     {
341         vArray[0] = RgbVertex<TriMeshType>(*m, *rgbInfo, getIndex(face()->V(0)));
342         vArray[1] = RgbVertex<TriMeshType>(*m, *rgbInfo, getIndex(face()->V(1)));
343         vArray[2] = RgbVertex<TriMeshType>(*m, *rgbInfo, getIndex(face()->V(2)));
344 
345         int z;
346         switch (getFaceColor())
347         {
348         case FaceInfo::FACE_GREEN:
349             ec[0] = FaceInfo::EDGE_GREEN;
350             ec[1] = FaceInfo::EDGE_GREEN;
351             ec[2] = FaceInfo::EDGE_GREEN;
352             el[0] = getFaceLevel();
353             el[1] = getFaceLevel();
354             el[2] = getFaceLevel();
355             va[0] = 2;
356             va[1] = 2;
357             va[2] = 2;
358             break;
359         case FaceInfo::FACE_RED_GGR:
360             z = maxLevelVertex();
361             ec[(0+z)%3] = FaceInfo::EDGE_GREEN;
362             ec[(1+z)%3] = FaceInfo::EDGE_GREEN;
363             ec[(2+z)%3] = FaceInfo::EDGE_RED;
364             el[(0+z)%3] = getFaceLevel()+1;
365             el[(1+z)%3] = getFaceLevel();
366             el[(2+z)%3] = getFaceLevel();
367             va[(0+z)%3] = 3;
368             va[(1+z)%3] = 2;
369             va[(2+z)%3] = 1;
370 
371             break;
372         case FaceInfo::FACE_RED_RGG:
373             z = maxLevelVertex();
374             ec[(0+z)%3] = FaceInfo::EDGE_RED;
375             ec[(1+z)%3] = FaceInfo::EDGE_GREEN;
376             ec[(2+z)%3] = FaceInfo::EDGE_GREEN;
377             el[(0+z)%3] = getFaceLevel();
378             el[(1+z)%3] = getFaceLevel();
379             el[(2+z)%3] = getFaceLevel()+1;
380             va[(0+z)%3] = 3;
381             va[(1+z)%3] = 1;
382             va[(2+z)%3] = 2;
383             break;
384         case FaceInfo::FACE_BLUE_GGR:
385             z = minLevelVertex();
386             ec[(0+z)%3] = FaceInfo::EDGE_GREEN;
387             ec[(1+z)%3] = FaceInfo::EDGE_GREEN;
388             ec[(2+z)%3] = FaceInfo::EDGE_RED;
389             el[(0+z)%3] = getFaceLevel()+1;
390             el[(1+z)%3] = getFaceLevel()+1;
391             el[(2+z)%3] = getFaceLevel();
392             va[(0+z)%3] = 1;
393             va[(1+z)%3] = 4;
394             va[(2+z)%3] = 1;
395             break;
396         case FaceInfo::FACE_BLUE_RGG:
397             z = minLevelVertex();
398             ec[(0+z)%3] = FaceInfo::EDGE_RED;
399             ec[(1+z)%3] = FaceInfo::EDGE_GREEN;
400             ec[(2+z)%3] = FaceInfo::EDGE_GREEN;
401             el[(0+z)%3] = getFaceLevel();
402             el[(1+z)%3] = getFaceLevel()+1;
403             el[(2+z)%3] = getFaceLevel()+1;
404             va[(0+z)%3] = 1;
405             va[(1+z)%3] = 1;
406             va[(2+z)%3] = 4;
407             break;
408         }
409     }
410 
411     /// Return the i vertex of the triangle
V(int i)412     inline RgbVertex<TriMeshType>& V(int i)
413     {
414         assert(i>=0&& i<= 2);
415         return vArray[i];
416     }
417 
418     /// Get the vertex level of the vertex i
getVl(int i)419     inline int getVl(int i)
420     {
421         assert(i>=0&& i<= 2);
422         return V(i).info().getLevel();
423     }
424 
425     /// Set the vertex level of the vertex i, update = false disable the update of non-encoded info
426     inline void setVl(int i, int level, bool update = true)
427     {
428         assert(i>=0&& i<= 2);
429         V(i).info().setLevel(level);
430         if (update)
431             updateInfo();
432     }
433 
434     /// Get the vertex coordinates of the vertex i
getVertexCoord(int VertexIndex)435     inline CoordType& getVertexCoord(int VertexIndex)
436     {
437     	return face()->V(VertexIndex)->P();
438     }
439 
440     /// Set the vertex coordinates of the vertex i
setVertexCoord(int VertexIndex,CoordType c)441     inline void setVertexCoord(int VertexIndex, CoordType c)
442     {
443     	face()->V(VertexIndex)->P() = c;
444     }
445 
446     /// Get the vertex new flag of the vertex i
getVertexIsNew(int i)447     inline bool getVertexIsNew(int i)
448     {
449         assert(i>=0&& i<= 2);
450         return V(i).info().getIsNew();
451     }
452 
453     /// Set the vertex new flag of the vertex i
setVertexIsNew(int i,bool c)454     inline void setVertexIsNew(int i, bool c)
455     {
456         assert(i>=0&& i<= 2);
457         V(i).info().setIsNew(c);
458     }
459 
460     /// Return true if the vertex is on the border
getVertexIsBorder(int i)461     inline bool getVertexIsBorder(int i)
462     {
463         assert(i>=0&& i<= 2);
464         return V(i).info().getIsBorder();
465     }
466 
467     /// Return the number of border edges incident in v
getNumberOfBoundaryEdge(RgbVertex<TRI_MESH_TYPE> * v)468     inline int getNumberOfBoundaryEdge(RgbVertex<TRI_MESH_TYPE>* v)
469     {
470     	int t = 0;
471     	assert(v);
472     	assert(v->index == V(0).index || v->index == V(1).index || v->index == V(2).index);
473         for (int i = 0; i < 3; ++i)
474         {
475         	if (getEdgeIsBorder(i) && ((V(i).index == v->index) || (V((i+1)%3).index == v->index)))
476         		t++;
477 		}
478         assert(t>=0 && t<= 2);
479         return t;
480     }
481 
482     /// Set if the vertex is on the border
setVertexIsBorder(int i,bool c)483     inline void setVertexIsBorder(int i,bool c)
484     {
485         assert(i>=0&& i<= 2);
486         V(i).info().setIsBorder(c);
487     }
488     /// Return true if the edge is on the border
getEdgeIsBorder(int i)489     inline bool getEdgeIsBorder(int i)
490     {
491         assert(i>=0&& i<= 2);
492         return (FF(i).index == index);
493     }
494 
495 
496     /// Return the number of vertex at level l present in the triangle
countVertexAtLevel(int l)497     inline int countVertexAtLevel(int l)
498     {
499         int count = 0;
500         for (int i = 0; i < 3; ++i)
501         {
502             if (getVl(i) == l)
503                 ++count;
504         }
505         return count;
506     }
507 
508     /// Search for the VertexIndex index in the vertex of the triangle, result is the local index if exist
509     inline bool containVertex(int index, int* result = 0)
510     {
511         for (int i = 0; i < 3; ++i)
512         {
513             if (getVIndex(i) == index)
514             {
515                 if (result)
516                     *result = i;
517                 return true;
518             }
519         }
520         return false;
521     }
522 
523     /// Extract an edge as a sorted pair of vertex
extractVertexFromEdge(int i)524     inline VertexPair extractVertexFromEdge(int i)
525     {
526         assert(i>=0&& i<= 2);
527         return VertexPair(getIndex(face()->V(i)),getIndex(face()->V((i+1)%3)));
528     }
529 
530     /// Check if the edge vp is on the boundary of the triangle
531     inline bool containEdge(VertexPair vp, int* index = 0)
532     {
533         for (int i = 0; i < 3; ++i)
534         {
535             if (vp == extractVertexFromEdge(i))
536             {
537             	if (index)
538             		*index = i;
539                 return true;
540             }
541         }
542         return false;
543     }
544 
545     /// Extract a red edge (use only if the edge exist)
getRedEdge()546     inline VertexPair getRedEdge()
547     {
548         assert(getFaceColor() != FaceInfo::FACE_GREEN);
549 
550         for (int i = 0; i < 3; ++i)
551         {
552             if (getEdgeColor(i) == FaceInfo::EDGE_RED)
553                 return extractVertexFromEdge(i);
554         }
555         assert(0);
556 				return VertexPair();
557     }
558 
559     /// Get the face color
getFaceColor()560     inline FaceColor getFaceColor()
561     {
562         return info()->getColor();
563     }
564 
565     /// Set the face color
566     inline void setFaceColor(FaceColor fc, bool update = true)
567     {
568         using vcg::Color4b;
569         info()->setColor(fc);
570 
571 #ifdef RGBCOLOR
572 
573         Color4b& c = face()->C();
574 
575         switch (fc)
576         {
577         case FaceInfo::FACE_BLUE_GGR:
578         case FaceInfo::FACE_BLUE_RGG:
579             c.Import(Color4b(0,0,80,255));
580             break;
581         case FaceInfo::FACE_GREEN:
582             c.Import(Color4b(0,80,0,255));
583             break;
584         case FaceInfo::FACE_RED_GGR:
585         case FaceInfo::FACE_RED_RGG:
586             c.Import(Color4b(80,0,0,255));
587             break;
588         }
589 #endif
590 
591 #ifndef RGBCOLOR
592 
593         Color4b& c = face()->C();
594 
595         c.Import(Color4b(255,255,255,255));
596 #endif
597 
598 
599         if (update)
600             updateInfo();
601     }
602 
603     /// Check if the face is blue
isBlue()604     inline bool isBlue()
605     {
606         return ((getFaceColor() == FaceInfo::FACE_BLUE_GGR) || (getFaceColor() == FaceInfo::FACE_BLUE_RGG));
607     }
608 
609     /// Check if the face is red
isRed()610     inline bool isRed()
611     {
612         return ((getFaceColor() == FaceInfo::FACE_RED_GGR) || (getFaceColor() == FaceInfo::FACE_RED_RGG));
613     }
614 
615     /// Check if the face is green
isGreen()616     inline bool isGreen()
617     {
618         return (getFaceColor() == FaceInfo::FACE_GREEN);
619     }
620 
621     /// Get the face level
getFaceLevel()622     inline int getFaceLevel()
623     {
624         return info()->getLevel();
625     }
626 
627     /// Set the face level
628     inline void setFaceLevel(int level, bool update = true)
629     {
630         info()->setLevel(level);
631         if (update)
632             updateInfo();
633     }
634 
635     /// Return the triangle in relation FF and incident in the i-th edges
FF(int i)636     inline RgbTriangle<TriMeshType> FF(int i)
637     {
638         assert(i>=0&& i<= 2);
639         return RgbTriangle<TriMeshType>(m, rgbInfo, getIndex(face()->FFp(i)));
640     }
641 
642     /// Return the index (in respect of FF(i) of the common edge
FFi(int i)643     inline int FFi(int i)
644     {
645         assert(i>=0&& i<= 2);
646         return face()->FFi(i);
647     }
648 
649     /// Return a Pointer to the RgbInfo Face
info()650     inline FaceInfo* info()
651     {
652         return &(rgbInfo->face[index]);
653     }
654 
655     /// Return a Pointer to the VCG Face
face()656     inline FacePointer face()
657     {
658         return &(m->face[index]);
659     }
660 
661     /// Return the color of the i-th edge
getEdgeColor(int i)662     inline EdgeColor getEdgeColor(int i)
663     {
664         assert(i>=0 && i<= 2);
665         return ec[i];
666     }
667 
668     /// Return the level of the i-th edge
getEdgeLevel(int i)669     inline int getEdgeLevel(int i)
670     {
671         assert(i>=0 && i<= 2);
672         return el[i];
673     }
674 
675     /// Return the index of the max level vertex
maxLevelVertex()676     inline int maxLevelVertex()
677     {
678         int level = getVl(0);
679         int index = 0;
680         if (getVl(1) > level)
681         {
682             level = getVl(1);
683             index = 1;
684         }
685         if (getVl(2) > level)
686         {
687             level = getVl(2);
688             index = 2;
689         }
690         return index;
691     }
692 
693     /// Return the index of the min level vertex
minLevelVertex()694     inline int minLevelVertex()
695     {
696         int level = getVl(0);
697         int index = 0;
698         if (getVl(1) < level)
699         {
700             level = getVl(1);
701             index = 1;
702         }
703 
704         if (getVl(2) < level)
705         {
706             level = getVl(2);
707             index = 2;
708         }
709 
710         return index;
711     }
712 
713     /// Return the index of the min level edge
minLevelEdge()714     inline int minLevelEdge()
715     {
716         int level = getEdgeLevel(0);
717         int index = 0;
718         if (getEdgeLevel(1) < level)
719         {
720             level = getEdgeLevel(1);
721             index = 1;
722         }
723 
724         if (getEdgeLevel(2) < level)
725         {
726             level = getEdgeLevel(2);
727             index = 2;
728         }
729 
730         return index;
731     }
732 
733     /// Return the index of the max level edge
maxLevelEdge()734     inline int maxLevelEdge()
735     {
736         int level = getEdgeLevel(0);
737         int index = 0;
738         if (getEdgeLevel(1) > level)
739         {
740             level = getEdgeLevel(1);
741             index = 1;
742         }
743 
744         if (getEdgeLevel(2) > level)
745         {
746             level = getEdgeLevel(2);
747             index = 2;
748         }
749 
750         return index;
751     }
752 
753     /// Return the absolute index of the i-th vertex
getVIndex(int i)754     inline int getVIndex(int i)
755     {
756     	assert(i>=0 && i<= 2);
757     	assert (vArray[i].index == getIndex(face()->V(i)));
758     	return getIndex(face()->V(i));
759     }
760 
761     /// Return the level of the i-th edge
getAngle(int i)762     inline int getAngle(int i)
763     {
764         assert(i>=0 && i<= 2);
765         return va[i];
766     }
767 
768     /// VCG Mesh
769     TriMeshType* m;
770     /// Rgb information
771     RgbInfo* rgbInfo;
772     /// Absolute (and common to m and rgbInfo) index of the face
773     int index;
774     /// Utilities for extract the index of a face starting from a pointer
getIndex(FacePointer fp)775     inline int getIndex(FacePointer fp)
776     {
777         return fp->Index();
778     }
779     /// Utilities for extract the index of a vertex starting from a pointer
getIndex(VertexPointer vp)780     inline int getIndex(VertexPointer vp)
781     {
782         return vp - &(m->vert.front());
783     }
784 
785 private:
786     /// Vertex of the triangle (stored for efficiency in access)
787     RgbVertex<TriMeshType> vArray[3];
788     /// Color of the edges
789     EdgeColor ec[3];
790     /// Level of the edges
791     int el[3];
792     /// Angle size
793     int va[3];
794 
795 
796 };
797 
798 /// Wrapper for an edge identified by a triangle and an index
799 template<class TRI_MESH_TYPE>
800 class RgbEdge
801 {
802 public:
RgbEdge(RgbTriangle<TRI_MESH_TYPE> t,int index)803 	RgbEdge(RgbTriangle<TRI_MESH_TYPE> t, int index) : t(t), index(index) {};
804 	/// An rgb triangle incident
805 	RgbTriangle<TRI_MESH_TYPE> t;
806 	/// Edge index on t
807 	int index;
808 	/// additional index used by VF, if first == 0 the common vertex is the one with the lowest index
809 //	int first;
810 
getLevel()811 	inline int getLevel()
812 	{
813 		return t.getEdgeLevel(index);
814 	}
815 
816 //	inline
817 };
818 
819 /// Wrapper for RgbInfo and CMeshO that allow a trasparent access to geometrical, topological and rgb informations of a vertex
820 template<class TRI_MESH_TYPE> class RgbVertex
821 {
822 public:
823 
824     /// The tetrahedral mesh type
825     typedef TRI_MESH_TYPE TriMeshType;
826     /// The face type
827     typedef typename TriMeshType::FaceType FaceType;
828     /// The vertex type
829     typedef typename FaceType::VertexType VertexType;
830     /// The vertex type pointer
831     typedef typename FaceType::VertexType* VertexPointer;
832     /// Face Pointer
833     typedef typename TriMeshType::FacePointer FacePointer;
834 
835     typedef typename VertexType::ScalarType ScalarType;
836 	typedef typename VertexType::CoordType CoordType;
837 	/// Standard Costructor for use in STL container
RgbVertex()838     RgbVertex() {}
839 
840     /// Costruct a new RGBVertex for the vertex of index VertexIndex
RgbVertex(TriMeshType & M,RgbInfo & Info,int VertexIndex)841     RgbVertex(TriMeshType& M, RgbInfo& Info, int VertexIndex) :
842         m(&M), rgbInfo(&Info), index(VertexIndex)
843     {
844     }
845     /// Costruct a new RGBVertex for the vertex initialized with a vertex pointer
RgbVertex(TriMeshType & M,RgbInfo & Info,VertexPointer vp)846     RgbVertex(TriMeshType& M, RgbInfo& Info, VertexPointer vp) :
847         m(&M), rgbInfo(&Info)
848     {
849     	index = getIndex(vp);
850     }
851     /// Restore the RGB info of the Vertex at the original state
resetInfo()852     inline void resetInfo()
853     {
854     	rgbInfo->vert[index].resetInfo();
855     }
856     /// Return the RGB info associated at the vertex
info()857     inline VertexInfo& info()
858     {
859         return (rgbInfo->vert[index]);
860     }
861     /// Return the VCG info associated at the vertex
vert()862     inline VertexType& vert()
863     {
864         return (m->vert[index]);
865     }
866     /// Get vertex control point at level l
getPl()867     inline const Point3f& getPl()
868     {
869     	return info().getPl();
870     }
871     /// Set vertex control point at level l
setPl(Point3f & p)872     inline void setPl(Point3f& p)
873     {
874     	info().setPl(p);
875     }
876     /// Set vertex control point at level inf
getPinf()877     inline const Point3f& getPinf()
878     {
879     	return info().getPinf();
880     }
881     /// Set vertex control point at level inf
setPinf(Point3f & p)882     inline void setPinf(Point3f& p)
883     {
884     	info().setPinf(p);
885     }
886     /// Get number of contribute already given
getCount()887     inline int getCount()
888     {
889     	return info().getCount();
890     }
891     /// Set number of contribute already given
setCount(int c)892     inline void setCount(int c)
893     {
894     	info().setCount(c);
895     }
896 
897     /// Get the vertex coordinates
getCoord()898     inline CoordType& getCoord()
899     {
900     	return vert().P();
901     }
902 
903     /// Set the vertex coordinates
setCoord(CoordType c)904     inline void setCoord(CoordType c)
905     {
906     	vert().P() = c;
907     }
908     /// Return true if Pinf is already computed
getIsPinfReady()909     inline bool getIsPinfReady()
910     {
911     	return info().getIsPinfReady();
912     }
913     /// Return the status of Pinf
setIsPinfReady(bool c)914     inline void setIsPinfReady(bool c)
915     {
916     	info().setIsPinfReady(c);
917     }
918     /// Get the level of the vertex
getLevel()919     inline int getLevel()
920     {
921         return info().getLevel();
922     }
923     /// Set the level of the vertex
setLevel(int level)924     inline void setLevel(int level)
925     {
926         info().setLevel(level);
927     }
928     /// Return true if the vertex is Marked
getIsMarked()929     inline bool getIsMarked()
930     {
931     	return info().getIsMarked();
932     }
933     /// Set the mark
setIsMarked(bool c)934     inline void setIsMarked(bool c)
935     {
936     	info().setIsMarked(c);
937     }
938     /// Return true if the vertex is inserted in the current selective refinement
getIsNew()939     inline bool getIsNew()
940     {
941     	return info().getIsNew();
942     }
943     /// Set if the vertex is inserted in the current selective refinement
setIsNew(bool c)944     inline void setIsNew(bool c)
945     {
946     	info().setIsNew(c);
947     }
948 
949     /// Return true if the vertex is on the border
getIsBorder()950     inline bool getIsBorder()
951     {
952         return info().getIsBorder();
953     }
954     /// Set if the vertex is on the border
setIsBorder(bool c)955     inline void setIsBorder(bool c)
956     {
957         info().setIsBorder(c);
958     }
959 
960     /// Utilities for extract the index of a vertex starting from a pointer
getIndex(VertexPointer vp)961     inline int getIndex(VertexPointer vp)
962     {
963         return vp - &(m->vert.front());
964     }
965     /// List that contain the index of all the vertexes that has contributed to Pinf
taken()966     inline list<int>& taken()
967     {
968     	return info().taken();
969     }
970     /// List that contain the index of all the vertexes that depends on this vertex for Pinf
given()971     inline list<int>& given()
972     {
973     	return info().given();
974     }
975 
VFi()976     inline int VFi()
977     {
978     	return vert().VFi();
979     }
980 
vp()981     inline VertexType* vp()
982     {
983     	return &(m->vert[index]);
984     }
985 
VFp()986     inline RgbTriangle<TRI_MESH_TYPE> VFp()
987     {
988     	FacePointer fp = vert().VFp();
989     	return RgbTriangleC(m,rgbInfo,fp->Index());
990     }
991 
992     typedef RgbVertex<TRI_MESH_TYPE> RgbVertexC;
993     typedef RgbTriangle<TRI_MESH_TYPE> RgbTriangleC;
994     typedef RgbEdge<TRI_MESH_TYPE> RgbEdgeC;
995 
VF(std::vector<RgbEdgeC> & ledge)996 	void VF(std::vector<RgbEdgeC>& ledge)
997 	{
998 		if (ledge.size() == 0)
999 			ledge.reserve(6);
1000 		RgbTriangleC t = VFp();
1001 		int VertexIndex = VFi();
1002 	    bool isBorder = t.getVertexIsBorder(VertexIndex);
1003 
1004 	    vcg::face::Pos<FaceType> pos(t.face(),t.face()->V(VertexIndex));
1005 
1006 	    if (t.getNumberOfBoundaryEdge(&(t.V(VertexIndex))) >= 2)
1007 	    {
1008     		ledge.push_back(RgbEdgeC(t,VertexIndex));
1009 	    	return;
1010 	    }
1011 
1012 	    if (isBorder)       // if is border move cw until the border is found
1013 	    {
1014 	        pos.FlipE();
1015 	        pos.FlipF();
1016 
1017 	        while (!pos.IsBorder())
1018 	        {
1019 	            pos.FlipE();
1020 	            pos.FlipF();
1021 	        }
1022 
1023 	        pos.FlipE();
1024 	    }
1025 
1026 	    CMeshO::FacePointer first = pos.F();
1027 
1028 	    RgbTriangleC ttmp = RgbTriangleC(t.m,t.rgbInfo,pos.F()->Index());
1029 	    int itmp = 0;
1030 	    ttmp.containVertex(index,&itmp);
1031 		ledge.push_back(RgbEdgeC(ttmp,itmp));
1032 
1033 	    pos.FlipF();
1034 	    pos.FlipE();
1035 
1036 	    while(pos.F() != first)
1037 	    {
1038 		    ttmp = RgbTriangleC(t.m,t.rgbInfo,pos.F()->Index());
1039 		    ttmp.containVertex(index,&itmp);
1040 			ledge.push_back(RgbEdgeC(ttmp,itmp));
1041 
1042 	        if (pos.IsBorder())
1043 	            break;
1044 
1045 	        pos.FlipF();
1046 	        pos.FlipE();
1047 	    }
1048 
1049 	    int indexV = t.getVIndex(VertexIndex);
1050 	    int res;
1051 	    for (unsigned int i = 0; i < ledge.size(); ++i)
1052 	    {
1053 	        assert(ledge[i].t.containVertex(indexV,&res));
1054 	        if (!isBorder)
1055 	        {
1056 	            assert(ledge[i].t.FF((res+2)%3).face() == ledge[(i+1)%ledge.size()].t.face());
1057 	        }
1058 	        assert(!ledge[i].t.face()->IsD());
1059 	    }
1060 	}
1061 
1062     friend std::ostream& operator<<(std::ostream& os, RgbVertex<TriMeshType>& v)
1063     {
1064       os << "RgbVertexIndex " << v.index << "|";
1065 
1066       os << v.getCoord()[0] << " " << v.getCoord()[1] << " " << v.getCoord()[2];
1067 
1068       os << std::endl;
1069       return os;
1070     }
1071 
1072     /// Get the number of incident edges in the base mesh
getBaseArity()1073     inline int getBaseArity()
1074     {
1075     	return info().getBaseArity();
1076     }
1077     /// Set the number of incident edges in the base mesh
setBaseArity(int a)1078     inline void setBaseArity(int a)
1079     {
1080     	info().setBaseArity(a);
1081     }
1082 
1083 	/// VCG Mesh
1084     TriMeshType* m;
1085     /// Rgb information container
1086     RgbInfo* rgbInfo;
1087 public:
1088 	/// Absolute (and common to m and rgbInfo) index of the vertex
1089     int index;
1090 };
1091 
1092 }
1093 
1094 #endif /*RGBINFO_H_*/
1095