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