1 /**************************************************************************** 2 * VCGLib o o * 3 * Visual and Computer Graphics Library o o * 4 * _ O _ * 5 * Copyright(C) 2004-2016 \/)\/ * 6 * Visual Computing Lab /\/| * 7 * ISTI - Italian National Research Council | * 8 * \ * 9 * All rights reserved. * 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 * This program is distributed in the hope that it will be useful, * 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) * 20 * for more details. * 21 * * 22 ****************************************************************************/ 23 #ifndef __VCG_MESH 24 #error "This file should not be included alone. It is automatically included by complex.h" 25 #endif 26 #ifndef __VCG_FACE_PLUS 27 #define __VCG_FACE_PLUS 28 29 namespace vcg { 30 31 /*------------------------------------------------------------------*/ 32 /* 33 The base class of all the recusive definition chain. It is just a container of the typenames of the various simplexes. 34 These typenames must be known form all the derived classes. 35 */ 36 37 template <class UserTypes> 38 class FaceTypeHolder: public UserTypes { 39 public: 40 41 template <class LeftF> ImportData(const LeftF &)42 void ImportData(const LeftF & ){} Name(std::vector<std::string> &)43 static void Name(std::vector<std::string> & /* name */){} 44 45 46 // prot VN()47 inline int VN() const { return 3;} Prev(const int & i)48 inline int Prev(const int & i) const { return (i+(3-1))%3;} Next(const int & i)49 inline int Next(const int & i) const { return (i+1)%3;} Alloc(const int &)50 inline void Alloc(const int & ){} Dealloc()51 inline void Dealloc(){} 52 }; 53 54 /* The base class form which we start to add our components. 55 it has the empty definition for all the standard members (coords, color flags) 56 Note: 57 in order to avoid both virtual classes and ambiguous definitions all 58 the subsequent overrides must be done in a sequence of derivation. 59 60 In other words we cannot derive and add in a single derivation step 61 (with multiple ancestor), both the real (non-empty) normal and color but 62 we have to build the type a step a time (deriving from a single ancestor at a time). 63 64 65 */ 66 template <class UserTypes> 67 class FaceBase: public 68 face::EmptyCore< FaceTypeHolder <UserTypes> > { 69 }; 70 71 72 /* The Real Big Face class; 73 74 The class __FaceArityMax__ is the one that is the Last to be derived, 75 and therefore is the only one to know the real members 76 (after the many overrides) so all the functions with common behaviour 77 using the members defined in the various Empty/nonEmpty component classes 78 MUST be defined here. 79 80 I.e. IsD() that uses the overridden Flags() member must be defined here. 81 82 */ 83 84 template < class UserTypes, 85 template <typename> class A, template <typename> class B, 86 template <typename> class C, template <typename> class D, 87 template <typename> class E, template <typename> class F, 88 template <typename> class G, template <typename> class H, 89 template <typename> class I, template <typename> class J, 90 template <typename> class K, template <typename> class L > 91 class FaceArityMax: public L<Arity11<FaceBase<UserTypes>, A, B, C, D, E, F, G, H, I, J, K> > { 92 93 public: 94 typedef typename FaceArityMax::ScalarType ScalarType; 95 // ----- Flags stuff ----- 96 97 enum { 98 99 DELETED = 0x00000001, // Face is deleted from the mesh 100 NOTREAD = 0x00000002, // Face of the mesh is not readable 101 NOTWRITE = 0x00000004, // Face of the mesh is not writable 102 VISITED = 0x00000010, // Face has been visited. Usualy this is a per-algorithm used bit. 103 SELECTED = 0x00000020, // Face is selected. Algorithms should try to work only on selected face (if explicitly requested) 104 // Border _flags, it is assumed that BORDERi = BORDER0<<i 105 BORDER0 = 0x00000040, 106 BORDER1 = 0x00000080, 107 BORDER2 = 0x00000100, 108 BORDER012 = BORDER0 | BORDER1 | BORDER2 , 109 // Face Orientation Flags, used efficiently compute point face distance 110 NORMX = 0x00000200, 111 NORMY = 0x00000400, 112 NORMZ = 0x00000800, 113 // Face-Edge Selection Flags 114 FACEEDGESEL0 = 0x00008000, 115 FACEEDGESEL1 = 0x00010000, 116 FACEEDGESEL2 = 0x00020000, 117 FACEEDGESEL012 = FACEEDGESEL0 | FACEEDGESEL1 | FACEEDGESEL2 , 118 // Faux edges. (semantics: when a mesh is polygonal, edges which are inside a polygonal face are "faux" 119 FAUX0 = 0x00040000, 120 FAUX1 = 0x00080000, 121 FAUX2 = 0x00100000, 122 FAUX012 = FAUX0 | FAUX1 | FAUX2 , 123 // First user bit 124 USER0 = 0x00200000 125 }; 126 127 128 /// checks if the Face is deleted IsD()129 bool IsD() const {return (this->cFlags() & DELETED) != 0;} 130 /// checks if the Face is readable IsR()131 bool IsR() const {return (this->cFlags() & NOTREAD) == 0;} 132 /// checks if the Face is modifiable IsW()133 bool IsW() const {return (this->cFlags() & NOTWRITE)== 0;} 134 /// This funcion checks whether the Face is both readable and modifiable IsRW()135 bool IsRW() const {return (this->cFlags() & (NOTREAD | NOTWRITE)) == 0;} 136 /// checks if the Face is Modified IsS()137 bool IsS() const {return (this->cFlags() & SELECTED) != 0;} 138 /// checks if the Face is Modified IsV()139 bool IsV() const {return (this->cFlags() & VISITED) != 0;} 140 141 /** Set the flag value 142 @param flagp Valore da inserire nel flag 143 */ SetFlags(int flagp)144 void SetFlags(int flagp) {this->Flags()=flagp;} 145 146 /** Set the flag value 147 @param flagp Valore da inserire nel flag 148 */ ClearFlags()149 void ClearFlags() {this->Flags()=0;} 150 151 /// deletes the Face from the mesh SetD()152 void SetD() {this->Flags() |=DELETED;} 153 /// un-delete a Face ClearD()154 void ClearD() {this->Flags() &=(~DELETED);} 155 /// marks the Face as readable SetR()156 void SetR() {this->Flags() &=(~NOTREAD);} 157 /// marks the Face as not readable ClearR()158 void ClearR() {this->Flags() |=NOTREAD;} 159 /// marks the Face as writable SetW()160 void SetW() {this->Flags() &=(~NOTWRITE);} 161 /// marks the Face as notwritable ClearW()162 void ClearW() {this->Flags() |=NOTWRITE;} 163 /// select the Face SetS()164 void SetS() {this->Flags() |=SELECTED;} 165 /// Un-select a Face ClearS()166 void ClearS() {this->Flags() &= ~SELECTED;} 167 /// select the Face SetV()168 void SetV() {this->Flags() |=VISITED;} 169 /// Un-select a Face ClearV()170 void ClearV() {this->Flags() &= ~VISITED;} 171 172 /// This function checks if the face is selected IsB(int i)173 bool IsB(int i) const {return (this->cFlags() & (BORDER0<<i)) != 0;} 174 /// This function select the face SetB(int i)175 void SetB(int i) {this->Flags() |=(BORDER0<<i);} 176 /// This funcion execute the inverse operation of SetS() ClearB(int i)177 void ClearB(int i) {this->Flags() &= (~(BORDER0<<i));} 178 179 /// This function checks if the i-th face-edge is selected IsFaceEdgeS(int i)180 bool IsFaceEdgeS(int i) const {return (this->cFlags() & (FACEEDGESEL0<<i)) != 0;} 181 /// This function select the i-th face-edge SetFaceEdgeS(int i)182 void SetFaceEdgeS(int i){this->Flags() |=(FACEEDGESEL0<<i);} 183 /// This function de-select the i-th face-edge ClearFaceEdgeS(int i)184 void ClearFaceEdgeS(int i) {this->Flags() &= (~(FACEEDGESEL0<<i));} 185 186 /// This function checks if a given side of the face is a feature/internal edge 187 /// it is used by some importer to mark internal 188 /// edges of polygonal faces that have been triangulated IsF(int i)189 bool IsF(int i) const {return (this->cFlags() & (FAUX0<<i) ) != 0;} IsAnyF()190 bool IsAnyF() const {return (this->cFlags() & (FAUX0|FAUX1|FAUX2)) != 0;} 191 /// This function select the face SetF(int i)192 void SetF(int i) {this->Flags() |=(FAUX0<<i);} 193 /// This funcion execute the inverse operation of SetS() ClearF(int i)194 void ClearF(int i) {this->Flags() &= (~(FAUX0<<i));} ClearAllF()195 void ClearAllF() { this->Flags() &= (~(FAUX0|FAUX1|FAUX2)); } 196 197 /// Return the first bit that is not still used FirstUnusedBitFlag()198 static int &FirstUnusedBitFlag() 199 { 200 static int b =USER0; 201 return b; 202 } 203 204 /// Allocate a bit among the flags that can be used by user. It updates the FirstUnusedBitFlag. NewBitFlag()205 static inline int NewBitFlag() 206 { 207 int bitForTheUser = FirstUnusedBitFlag(); 208 FirstUnusedBitFlag()=FirstUnusedBitFlag()<<1; 209 return bitForTheUser; 210 } 211 212 /// De-allocate a pre allocated bit. It updates the FirstUnusedBitFlag. 213 // Note you must deallocate bit in the inverse order of the allocation (as in a stack) DeleteBitFlag(int bitval)214 static inline bool DeleteBitFlag(int bitval) 215 { 216 if(FirstUnusedBitFlag()>>1==bitval) { 217 FirstUnusedBitFlag() = FirstUnusedBitFlag()>>1; 218 return true; 219 } 220 assert(0); 221 return false; 222 } 223 224 /// This function checks if the given user bit is true IsUserBit(int userBit)225 bool IsUserBit(int userBit){return (this->Flags() & userBit) != 0;} 226 227 /// This function set the given user bit SetUserBit(int userBit)228 void SetUserBit(int userBit){this->Flags() |=userBit;} 229 230 /// This function clear the given user bit ClearUserBit(int userBit)231 void ClearUserBit(int userBit){this->Flags() &= (~userBit);} 232 233 GetBBox(Box3<ScalarType> & bb)234 void GetBBox(Box3<ScalarType>& bb ) const 235 { 236 if(this->IsD()) { 237 bb.SetNull(); 238 return; 239 } 240 bb.Set(this->cP(0)); 241 bb.Add(this->cP(1)); 242 bb.Add(this->cP(2)); 243 } 244 245 246 }; 247 248 249 /* 250 251 These are the three main classes that are used by the library user to define its own Facees. 252 The user MUST specify the names of all the type involved in a generic complex. 253 so for example when defining a Face of a trimesh you must know the name of the type of the edge and of the face. 254 Typical usage example: 255 256 A Face with coords, flags and normal for use in a standard trimesh: 257 258 class MyFaceNf : public FaceSimp2< VertProto, EdgeProto, MyFaceNf, face::Flag, face::Normal3f > {}; 259 260 261 A Face with coords, and normal for use in a tetrahedral mesh AND in a standard trimesh: 262 263 class TetraFace : public FaceSimp3< VertProto, EdgeProto, TetraFace, TetraProto, face::Coord3d, face::Normal3f > {}; 264 265 266 A summary of the components that can be added to a face (see components.h for details): 267 268 VertexRef 269 NormalFromVert, WedgeNormal 270 Normal3s, Normal3f, Normal3d 271 WedgeTexCoord2s, WedgeTexCoord2f, WedgeTexCoord2d 272 BitFlags 273 WedgeColor, Color4b 274 Qualitys, Qualityf, Qualityd 275 Mark //Incremental mark (int) 276 VFAdj //Topology vertex face adjacency 277 (pointers to next face in the ring of the vertex 278 FFAdj //topology: face face adj 279 pointers to adjacent faces 280 281 */ 282 283 template <class UserTypes, 284 template <typename> class A = DefaultDeriver, template <typename> class B = DefaultDeriver, 285 template <typename> class C = DefaultDeriver, template <typename> class D = DefaultDeriver, 286 template <typename> class E = DefaultDeriver, template <typename> class F = DefaultDeriver, 287 template <typename> class G = DefaultDeriver, template <typename> class H = DefaultDeriver, 288 template <typename> class I = DefaultDeriver, template <typename> class J = DefaultDeriver, 289 template <typename> class K = DefaultDeriver, template <typename> class L = DefaultDeriver > 290 class Face: public FaceArityMax<UserTypes, A, B, C, D, E, F, G, H, I, J, K, L> { 291 public: typedef AllTypes::AFaceType IAm; typedef UserTypes TypesPool;}; 292 293 294 }// end namespace 295 #endif 296 297