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_FACE_PLUS_COMPONENT_OCF
24 #define __VCG_FACE_PLUS_COMPONENT_OCF
25 #ifndef __VCG_MESH
26 #error "This file should not be included alone. It is automatically included by complex.h"
27 #endif
28 
29 namespace vcg {
30   namespace face {
31 /*
32 All the Components that can be added to a faceex should be defined in the namespace face:
33 
34 */
35 
36 template <class VALUE_TYPE>
37 class vector_ocf: public std::vector<VALUE_TYPE> {
38   typedef std::vector<VALUE_TYPE> BaseType;
39     typedef typename vector_ocf<VALUE_TYPE>::iterator ThisTypeIterator;
40 
41 public:
vector_ocf()42   vector_ocf():std::vector<VALUE_TYPE>()
43   {
44     _ColorEnabled=false;
45     CurvatureDirEnabled = false;
46     MarkEnabled=false;
47     NormalEnabled=false;
48     QualityEnabled=false;
49     WedgeTexEnabled=false;
50     WedgeColorEnabled=false;
51     WedgeNormalEnabled=false;
52     VFAdjacencyEnabled=false;
53     FFAdjacencyEnabled=false;
54   }
55 
56 // Auxiliary types to build internal vectors
57 struct AdjTypePack {
58   typename VALUE_TYPE::FacePointer _fp[3] ;
59   char _zp[3] ;
60 
61   // Default constructor.
62   // Needed because we need to know if adjacency is initialized or not
63   // when resizing vectors and during an allocate face.
AdjTypePackAdjTypePack64   AdjTypePack() {
65         _fp[0]=0;
66         _fp[1]=0;
67         _fp[2]=0;
68   }
69   };
70 
71 //template <class TexCoordType>
72 class WedgeTexTypePack {
73 public:
WedgeTexTypePack()74   WedgeTexTypePack() {
75     wt[0].U()=.5;wt[0].V()=.5;
76     wt[1].U()=.5;wt[1].V()=.5;
77     wt[2].U()=.5;wt[2].V()=.5;
78     wt[0].N()=-1;
79     wt[1].N()=-1;
80     wt[2].N()=-1;
81   }
82 
83   typename VALUE_TYPE::TexCoordType wt[3];
84 };
85 
86 class WedgeColorTypePack {
87 public:
WedgeColorTypePack()88   WedgeColorTypePack() {
89   typedef typename VALUE_TYPE::ColorType::ScalarType WedgeColorScalarType;
90     for (int i=0; i<3; ++i)
91     {
92     wc[i][0] = WedgeColorScalarType(255);
93     wc[i][1] = WedgeColorScalarType(255);
94     wc[i][2] = WedgeColorScalarType(255);
95     wc[i][3] = WedgeColorScalarType(255);
96     }
97   }
98 
99   typename VALUE_TYPE::ColorType wc[3];
100 };
101 
102 class WedgeNormalTypePack {
103 public:
WedgeNormalTypePack()104   WedgeNormalTypePack() {
105   typedef typename VALUE_TYPE::NormalType::ScalarType WedgeNormalScalarType;
106     for (int i=0; i<3; ++i)
107     {
108     wn[i][0] = WedgeNormalScalarType(0);
109     wn[i][1] = WedgeNormalScalarType(0);
110     wn[i][2] = WedgeNormalScalarType(1);
111     }
112   }
113 
114   typename VALUE_TYPE::NormalType wn[3];
115 };
116 
117 
118 ////////////////////////////////////////
119 // All the standard methods of std::vector that can change the reallocation are
120 // redefined in order to manage the additional data.
push_back(const VALUE_TYPE & v)121     void push_back(const VALUE_TYPE & v)
122   {
123     BaseType::push_back(v);
124     BaseType::back()._ovp = this;
125     if (QualityEnabled)     QV.push_back(0);
126     if (_ColorEnabled)       CV.push_back(vcg::Color4b(vcg::Color4b::White));
127     if (MarkEnabled)        MV.push_back(0);
128     if (NormalEnabled)      NV.push_back(typename VALUE_TYPE::NormalType());
129     if (CurvatureDirEnabled)    CDV.push_back(typename VALUE_TYPE::CurvatureDirType());
130     if (VFAdjacencyEnabled) AV.push_back(AdjTypePack());
131     if (FFAdjacencyEnabled) AF.push_back(AdjTypePack());
132     if (WedgeTexEnabled)    WTV.push_back(WedgeTexTypePack());
133     if (WedgeColorEnabled)  WCV.push_back(WedgeColorTypePack());
134     if (WedgeNormalEnabled) WNV.push_back(WedgeNormalTypePack());
135   }
136     void pop_back();
resize(size_t _size)137   void resize(size_t _size)
138   {
139       size_t oldsize = BaseType::size();
140     BaseType::resize(_size);
141       if(oldsize<_size){
142           ThisTypeIterator firstnew = BaseType::begin();
143           advance(firstnew,oldsize);
144           _updateOVP(firstnew,(*this).end());
145       }
146     if (QualityEnabled)     QV.resize(_size,0);
147     if (_ColorEnabled)       CV.resize(_size);
148     if (MarkEnabled)        MV.resize(_size);
149     if (NormalEnabled)      NV.resize(_size);
150     if (CurvatureDirEnabled)CDV.resize(_size);
151     if (VFAdjacencyEnabled) AV.resize(_size);
152     if (FFAdjacencyEnabled) AF.resize(_size);
153     if (WedgeTexEnabled)    WTV.resize(_size,WedgeTexTypePack());
154     if (WedgeColorEnabled)  WCV.resize(_size);
155     if (WedgeNormalEnabled) WNV.resize(_size);
156    }
reserve(size_t _size)157   void reserve(size_t _size)
158   {
159     BaseType::reserve(_size);
160 
161     if (QualityEnabled)     QV.reserve(_size);
162     if (_ColorEnabled)      CV.reserve(_size);
163     if (MarkEnabled)        MV.reserve(_size);
164     if (NormalEnabled)      NV.reserve(_size);
165     if (CurvatureDirEnabled)CDV.reserve(_size);
166     if (VFAdjacencyEnabled) AV.reserve(_size);
167     if (FFAdjacencyEnabled) AF.reserve(_size);
168     if (WedgeTexEnabled)    WTV.reserve(_size);
169     if (WedgeColorEnabled)  WCV.reserve(_size);
170     if (WedgeNormalEnabled) WNV.reserve(_size);
171 
172     if( BaseType::empty()) return ;
173 
174     ThisTypeIterator oldbegin=(*this).begin();
175     if(oldbegin!=(*this).begin()) _updateOVP((*this).begin(),(*this).end());
176   }
177 
_updateOVP(ThisTypeIterator lbegin,ThisTypeIterator lend)178  void _updateOVP(ThisTypeIterator lbegin, ThisTypeIterator lend)
179 {
180     ThisTypeIterator fi;
181     //for(fi=(*this).begin();vi!=(*this).end();++vi)
182     for(fi=lbegin;fi!=lend;++fi)
183         (*fi)._ovp=this;
184  }
185 
186 
187 
188 // this function is called by the specialized Reorder function, that is called whenever someone call the allocator::CompactVertVector
ReorderFace(std::vector<size_t> & newFaceIndex)189 void ReorderFace(std::vector<size_t> &newFaceIndex )
190 {
191     size_t i=0;
192     if (QualityEnabled)     assert( QV.size() == newFaceIndex.size() );
193     if (_ColorEnabled)       assert( CV.size() == newFaceIndex.size() );
194     if (MarkEnabled)        assert( MV.size() == newFaceIndex.size() );
195     if (NormalEnabled)      assert( NV.size() == newFaceIndex.size() );
196     if (CurvatureDirEnabled)assert(CDV.size() == newFaceIndex.size() );
197     if (VFAdjacencyEnabled) assert( AV.size() == newFaceIndex.size() );
198     if (FFAdjacencyEnabled) assert( AF.size() == newFaceIndex.size() );
199     if (WedgeTexEnabled)    assert(WTV.size() == newFaceIndex.size() );
200     if (WedgeColorEnabled)  assert(WCV.size() == newFaceIndex.size() );
201     if (WedgeNormalEnabled) assert(WNV.size() == newFaceIndex.size() );
202 
203     for(i=0;i<newFaceIndex.size();++i)
204         {
205             if(newFaceIndex[i] != std::numeric_limits<size_t>::max() )
206                 {
207                     assert(newFaceIndex[i] <= i);
208                     if (QualityEnabled)      QV[newFaceIndex[i]] =  QV[i];
209                     if (_ColorEnabled)        CV[newFaceIndex[i]] =  CV[i];
210                     if (MarkEnabled)         MV[newFaceIndex[i]] =  MV[i];
211                     if (NormalEnabled)       NV[newFaceIndex[i]] =  NV[i];
212                     if (CurvatureDirEnabled) CDV[newFaceIndex[i]] =  CDV[i];
213                     if (VFAdjacencyEnabled)  AV[newFaceIndex[i]] =  AV[i];
214                     if (FFAdjacencyEnabled)  AF[newFaceIndex[i]] =  AF[i];
215                     if (WedgeTexEnabled)    WTV[newFaceIndex[i]] = WTV[i];
216                     if (WedgeColorEnabled)  WCV[newFaceIndex[i]] = WCV[i];
217                     if (WedgeNormalEnabled) WNV[newFaceIndex[i]] = WNV[i];
218                 }
219         }
220 
221     if (QualityEnabled)      QV.resize(BaseType::size(),0);
222     if (_ColorEnabled)       CV.resize(BaseType::size());
223     if (MarkEnabled)         MV.resize(BaseType::size());
224     if (NormalEnabled)       NV.resize(BaseType::size());
225     if (CurvatureDirEnabled) CDV.resize(BaseType::size());
226     if (VFAdjacencyEnabled)  AV.resize(BaseType::size());
227     if (FFAdjacencyEnabled)  AF.resize(BaseType::size());
228     if (WedgeTexEnabled)    WTV.resize(BaseType::size());
229     if (WedgeColorEnabled)  WCV.resize(BaseType::size());
230     if (WedgeNormalEnabled) WNV.resize(BaseType::size());
231 }
232 
233 ////////////////////////////////////////
234 // Enabling Functions
235 
IsQualityEnabled()236 bool IsQualityEnabled() const {return QualityEnabled;}
EnableQuality()237 void EnableQuality() {
238     assert(VALUE_TYPE::HasQualityOcf());
239     QualityEnabled=true;
240     QV.resize((*this).size(),0);
241 }
242 
DisableQuality()243 void DisableQuality() {
244     assert(VALUE_TYPE::HasQualityOcf());
245     QualityEnabled=false;
246     QV.clear();
247 }
248 
IsColorEnabled()249 bool IsColorEnabled() const {return _ColorEnabled;}
EnableColor()250 void EnableColor() {
251   assert(VALUE_TYPE::HasColorOcf());
252   _ColorEnabled=true;
253   CV.resize((*this).size(),vcg::Color4b::White);
254 }
255 
DisableColor()256 void DisableColor() {
257   assert(VALUE_TYPE::HasColorOcf());
258   _ColorEnabled=false;
259   CV.clear();
260 }
261 
IsMarkEnabled()262 bool IsMarkEnabled() const {return MarkEnabled;}
EnableMark()263 void EnableMark() {
264   assert(VALUE_TYPE::HasMarkOcf());
265   MarkEnabled=true;
266   MV.resize((*this).size(),0);
267 }
268 
DisableMark()269 void DisableMark() {
270   assert(VALUE_TYPE::HasMarkOcf());
271   MarkEnabled=false;
272   MV.clear();
273 }
274 
IsNormalEnabled()275 bool IsNormalEnabled() const {return NormalEnabled;}
EnableNormal()276 void EnableNormal() {
277   assert(VALUE_TYPE::HasNormalOcf());
278   NormalEnabled=true;
279   NV.resize((*this).size());
280 }
281 
DisableNormal()282 void DisableNormal() {
283   assert(VALUE_TYPE::HasNormalOcf());
284   NormalEnabled=false;
285   NV.clear();
286 }
287 
IsCurvatureDirEnabled()288 bool IsCurvatureDirEnabled() const {return CurvatureDirEnabled;}
EnableCurvatureDir()289 void EnableCurvatureDir() {
290   assert(VALUE_TYPE::HasCurvatureDirOcf());
291   CurvatureDirEnabled=true;
292   CDV.resize((*this).size());
293 }
294 
DisableCurvatureDir()295 void DisableCurvatureDir() {
296   assert(VALUE_TYPE::HasCurvatureDirOcf());
297   CurvatureDirEnabled=false;
298   CDV.clear();
299 }
300 
301 
IsVFAdjacencyEnabled()302 bool IsVFAdjacencyEnabled() const {return VFAdjacencyEnabled;}
EnableVFAdjacency()303 void EnableVFAdjacency() {
304   assert(VALUE_TYPE::HasVFAdjacencyOcf());
305   VFAdjacencyEnabled=true;
306   AV.resize((*this).size());
307 }
308 
DisableVFAdjacency()309 void DisableVFAdjacency() {
310   assert(VALUE_TYPE::HasVFAdjacencyOcf());
311   VFAdjacencyEnabled=false;
312   AV.clear();
313 }
314 
315 
IsFFAdjacencyEnabled()316 bool IsFFAdjacencyEnabled() const {return FFAdjacencyEnabled;}
EnableFFAdjacency()317 void EnableFFAdjacency() {
318   assert(VALUE_TYPE::HasFFAdjacencyOcf());
319   FFAdjacencyEnabled=true;
320   AF.resize((*this).size());
321 }
322 
DisableFFAdjacency()323 void DisableFFAdjacency() {
324   assert(VALUE_TYPE::HasFFAdjacencyOcf());
325   FFAdjacencyEnabled=false;
326   AF.clear();
327 }
328 
IsWedgeTexCoordEnabled()329 bool IsWedgeTexCoordEnabled() const {return WedgeTexEnabled;}
EnableWedgeTexCoord()330 void EnableWedgeTexCoord() {
331   assert(VALUE_TYPE::HasWedgeTexCoordOcf());
332   WedgeTexEnabled=true;
333   WTV.resize((*this).size(),WedgeTexTypePack());
334 }
335 
DisableWedgeTexCoord()336 void DisableWedgeTexCoord() {
337   assert(VALUE_TYPE::HasWedgeTexCoordOcf());
338   WedgeTexEnabled=false;
339   WTV.clear();
340 }
341 
IsWedgeColorEnabled()342 bool IsWedgeColorEnabled() const {return WedgeColorEnabled;}
EnableWedgeColor()343 void EnableWedgeColor() {
344   assert(VALUE_TYPE::HasWedgeColorOcf());
345   WedgeColorEnabled=true;
346   WCV.resize((*this).size(),WedgeColorTypePack());
347 }
348 
DisableWedgeColor()349 void DisableWedgeColor() {
350   assert(VALUE_TYPE::HasWedgeColorOcf());
351   WedgeColorEnabled=false;
352   WCV.clear();
353 }
354 
IsWedgeNormalEnabled()355 bool IsWedgeNormalEnabled() const {return WedgeNormalEnabled;}
EnableWedgeNormal()356 void EnableWedgeNormal() {
357   assert(VALUE_TYPE::HasWedgeNormalOcf());
358   WedgeNormalEnabled=true;
359   WNV.resize((*this).size(),WedgeNormalTypePack());
360 }
361 
DisableWedgeNormal()362 void DisableWedgeNormal() {
363   assert(VALUE_TYPE::HasWedgeNormalOcf());
364   WedgeNormalEnabled=false;
365   WNV.clear();
366 }
367 
368 public:
369   std::vector<typename VALUE_TYPE::ColorType> CV;
370   std::vector<typename VALUE_TYPE::CurvatureDirType> CDV;
371   std::vector<int> MV;
372   std::vector<typename VALUE_TYPE::NormalType> NV;
373   std::vector<float> QV;
374   std::vector<class WedgeColorTypePack> WCV;
375   std::vector<class WedgeNormalTypePack> WNV;
376   std::vector<class WedgeTexTypePack> WTV;
377   std::vector<struct AdjTypePack> AV;
378   std::vector<struct AdjTypePack> AF;
379 
380   bool _ColorEnabled;
381   bool CurvatureDirEnabled;
382   bool MarkEnabled;
383   bool NormalEnabled;
384   bool QualityEnabled;
385   bool WedgeColorEnabled;
386   bool WedgeNormalEnabled;
387   bool WedgeTexEnabled;
388   bool VFAdjacencyEnabled;
389   bool FFAdjacencyEnabled;
390 }; // end class vector_ocf
391 
392 
393 /*----------------------------- VFADJ ------------------------------*/
394 template <class T> class VFAdjOcf: public T {
395 public:
VFp(const int j)396   typename T::FacePointer &VFp(const int j) {
397     assert((*this).Base().VFAdjacencyEnabled);
398     return (*this).Base().AV[(*this).Index()]._fp[j];
399   }
400 
cVFp(const int j)401   typename T::FacePointer cVFp(const int j) const {
402     if(! (*this).Base().VFAdjacencyEnabled ) return 0;
403     else return (*this).Base().AV[(*this).Index()]._fp[j];
404   }
405 
VFi(const int j)406   char &VFi(const int j) {
407     assert((*this).Base().VFAdjacencyEnabled);
408     return (*this).Base().AV[(*this).Index()]._zp[j];
409   }
410 
cVFi(const int j)411   char cVFi(const int j) const {
412     assert((*this).Base().VFAdjacencyEnabled);
413     return (*this).Base().AV[(*this).Index()]._zp[j];
414   }
415 
416     template <class RightFaceType>
ImportData(const RightFaceType & rightF)417     void ImportData(const RightFaceType & rightF){
418         T::ImportData(rightF);
419     }
HasVFAdjacency()420   static bool HasVFAdjacency()   {   return true; }
HasVFAdjacencyOcf()421   static bool HasVFAdjacencyOcf()   { return true; }
422 
423 private:
424 };
425 
426 /*----------------------------- FFADJ ------------------------------*/
427 template <class T> class FFAdjOcf: public T {
428 public:
FFp(const int j)429   typename T::FacePointer &FFp(const int j) {
430     assert((*this).Base().FFAdjacencyEnabled);
431     return (*this).Base().AF[(*this).Index()]._fp[j];
432   }
433 
cFFp(const int j)434   typename T::FacePointer cFFp(const int j) const {
435     if(! (*this).Base().FFAdjacencyEnabled ) return 0;
436     else return (*this).Base().AF[(*this).Index()]._fp[j];
437   }
438 
FFi(const int j)439   char &FFi(const int j)       {
440     assert((*this).Base().FFAdjacencyEnabled);
441     return (*this).Base().AF[(*this).Index()]._zp[j];
442   }
cFFi(const int j)443   char cFFi(const int j) const {
444     assert((*this).Base().FFAdjacencyEnabled);
445     return (*this).Base().AF[(*this).Index()]._zp[j];
446   }
447 
FFp1(const int j)448   typename T::FacePointer  &FFp1( const int j )       { return FFp((j+1)%3);}
FFp2(const int j)449   typename T::FacePointer  &FFp2( const int j )       { return FFp((j+2)%3);}
cFFp1(const int j)450   typename T::FacePointer  cFFp1( const int j ) const { return FFp((j+1)%3);}
cFFp2(const int j)451   typename T::FacePointer  cFFp2( const int j ) const { return FFp((j+2)%3);}
452 
Neigh(const int j)453   typename T::FacePointer  &Neigh( const int j )		{ return FFp(j);}
cNeigh(const int j)454   typename T::FacePointer  cNeigh( const int j ) const { return cFFp(j);}
SizeNeigh()455   unsigned int SizeNeigh(){return 3;}
456 
457   template <class RightFaceType>
ImportData(const RightFaceType & rightF)458   void ImportData(const RightFaceType & rightF){
459     T::ImportData(rightF);
460   }
HasFFAdjacency()461   static bool HasFFAdjacency()   {   return true; }
HasFFAdjacencyOcf()462   static bool HasFFAdjacencyOcf()   { return true; }
463 };
464 
465 /*------------------------- Normal -----------------------------------------*/
466 template <class A, class T> class NormalOcf: public T {
467 public:
468   typedef A NormalType;
IsNormalEnabled()469   inline bool IsNormalEnabled( )        const  { return this->Base().IsNormalEnabled(); }
HasNormal()470   static bool HasNormal()   { return true; }
HasNormalOcf()471   static bool HasNormalOcf()   { return true; }
472 
N()473   NormalType &N()       {
474     // you cannot use Normals before enabling them with: yourmesh.face.EnableNormal()
475     assert((*this).Base().NormalEnabled);
476     return (*this).Base().NV[(*this).Index()];  }
cN()477   NormalType cN() const {
478     // you cannot use Normals before enabling them with: yourmesh.face.EnableNormal()
479     assert((*this).Base().NormalEnabled);
480     return (*this).Base().NV[(*this).Index()];  }
481 
482   template <class RightFaceType>
ImportData(const RightFaceType & rightF)483   void ImportData(const RightFaceType & rightF){
484     if((*this).IsNormalEnabled() && rightF.IsNormalEnabled())
485       N() = rightF.cN();
486     T::ImportData(rightF);
487   }
488 };
489 
490 template <class T> class Normal3sOcf: public NormalOcf<vcg::Point3s, T> {};
491 template <class T> class Normal3fOcf: public NormalOcf<vcg::Point3f, T> {};
492 template <class T> class Normal3dOcf: public NormalOcf<vcg::Point3d, T> {};
493 
494 /*------------------------- CurvatureDir -----------------------------------------*/
495 template <class S>
496 struct CurvatureDirOcfBaseType{
497         typedef Point3<S> CurVecType;
498         typedef  S   CurScalarType;
CurvatureDirOcfBaseTypeCurvatureDirOcfBaseType499         CurvatureDirOcfBaseType () {}
500         CurVecType max_dir,min_dir; // max and min curvature direction
501         CurScalarType k1,k2;// max and min curvature values
502 };
503 
504 template <class A, class T> class CurvatureDirOcf: public T {
505 public:
506   typedef A CurvatureDirType;
507   typedef typename CurvatureDirType::CurVecType CurVecType;
508   typedef typename CurvatureDirType::CurScalarType CurScalarType;
509 
IsCurvatureDirEnabled()510   inline bool IsCurvatureDirEnabled( )  const  { return this->Base().IsCurvatureDirEnabled(); }
HasCurvatureDir()511   static bool HasCurvatureDir()   { return true; }
HasCurvatureDirOcf()512   static bool HasCurvatureDirOcf()   { return true; }
513 
PD1()514   CurVecType &PD1()       { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].max_dir; }
PD2()515   CurVecType &PD2()       { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].min_dir; }
cPD1()516   CurVecType cPD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].max_dir; }
cPD2()517   CurVecType cPD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].min_dir; }
518 
K1()519   CurScalarType &K1()       { assert((*this).Base().NormalEnabled); return (*this).Base().CDV[(*this).Index()].k1; }
K2()520   CurScalarType &K2()       { assert((*this).Base().NormalEnabled); return (*this).Base().CDV[(*this).Index()].k2; }
cK1()521   CurScalarType cK1() const { assert((*this).Base().NormalEnabled); return (*this).Base().CDV[(*this).Index()].k1; }
cK2()522   CurScalarType cK2() const { assert((*this).Base().NormalEnabled); return (*this).Base().CDV[(*this).Index()].k2; }
523 
524   template <class RightFaceType>
ImportData(const RightFaceType & rightF)525   void ImportData(const RightFaceType & rightF){
526     if((*this).IsCurvatureDirEnabled() && rightF.IsCurvatureDirEnabled()) {
527       PD1().Import(rightF.cPD1());
528       PD2().Import(rightF.cPD2());
529       K1() = rightF.cK1();
530       K2() = rightF.cK2();
531     }
532     T::ImportData(rightF);
533   }
534 
535 };
536 
537 template <class T> class CurvatureDirfOcf: public CurvatureDirOcf<CurvatureDirOcfBaseType<float>, T> {
Name(std::vector<std::string> & name)538 public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirfOcf"));T::Name(name);}
539 };
540 template <class T> class CurvatureDirdOcf: public CurvatureDirOcf<CurvatureDirOcfBaseType<double>, T> {
Name(std::vector<std::string> & name)541 public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirdOcf"));T::Name(name);}
542 };
543 
544 ///*-------------------------- QUALITY ----------------------------------*/
545 template <class A, class T> class QualityOcf: public T {
546 public:
547   typedef A QualityType;
Q()548   QualityType &Q()        {
549     assert((*this).Base().QualityEnabled);
550     return (*this).Base().QV[(*this).Index()];
551   }
cQ()552   QualityType cQ() const  {
553     assert((*this).Base().QualityEnabled);
554     return (*this).Base().QV[(*this).Index()];
555   }
556 
557   template <class RightFaceType>
ImportData(const RightFaceType & rightF)558   void ImportData(const RightFaceType & rightF){
559     if((*this).IsQualityEnabled() && rightF.IsQualityEnabled())
560       Q() = rightF.cQ();
561     T::ImportData(rightF);
562   }
IsQualityEnabled()563   inline bool IsQualityEnabled( )       const  { return this->Base().IsQualityEnabled(); }
HasQuality()564   static bool HasQuality()   { return true; }
HasQualityOcf()565   static bool HasQualityOcf()   { return true; }
566 };
567 
568 template <class T> class QualityfOcf: public QualityOcf<float, T> {};
569 
570 ///*-------------------------- COLOR ----------------------------------*/
571 template <class A, class T> class ColorOcf: public T {
572 public:
573   typedef A ColorType;
C()574   ColorType &C()        {
575     assert((*this).Base()._ColorEnabled);
576     return (*this).Base().CV[(*this).Index()];
577   }
cC()578   ColorType cC() const  {
579     assert((*this).Base()._ColorEnabled);
580     return (*this).Base().CV[(*this).Index()];
581   }
582 
583   template <class RightFaceType>
ImportData(const RightFaceType & rightF)584   void ImportData(const RightFaceType & rightF){
585     if((*this).IsColorEnabled() && rightF.IsColorEnabled())
586       C() = rightF.cC();
587     T::ImportData(rightF);
588   }
IsColorEnabled()589   inline bool IsColorEnabled()          const  { return this->Base().IsColorEnabled();}
HasColor()590   static bool HasColor()   { return true; }
HasColorOcf()591   static bool HasColorOcf()   { return true; }
592 };
593 
594 template <class T> class Color4bOcf: public ColorOcf<vcg::Color4b, T> {};
595 
596 ///*-------------------------- MARK  ----------------------------------*/
597 template <class T> class MarkOcf: public T {
598 public:
IMark()599   inline int &IMark()       {
600     assert((*this).Base().MarkEnabled);
601     return (*this).Base().MV[(*this).Index()];
602   }
cIMark()603   inline int cIMark() const {
604     assert((*this).Base().MarkEnabled);
605     return (*this).Base().MV[(*this).Index()];
606   }
607 
608   template <class RightFaceType>
ImportData(const RightFaceType & rightF)609   void ImportData(const RightFaceType & rightF){
610     if((*this).IsMarkEnabled() && rightF.IsMarkEnabled())
611       IMark() = rightF.cIMark();
612     T::ImportData(rightF);
613   }
IsMarkEnabled()614   inline bool IsMarkEnabled( )          const  { return this->Base().IsMarkEnabled(); }
HasMark()615   static bool HasMark()   { return true; }
HasMarkOcf()616   static bool HasMarkOcf()   { return true; }
InitIMark()617   inline void InitIMark()    { IMark() = 0; }
618 };
619 
620 ///*-------------------------- WEDGE TEXCOORD  ----------------------------------*/
621 template <class A, class TT> class WedgeTexCoordOcf: public TT {
622 public:
WedgeTexCoordOcf()623   WedgeTexCoordOcf(){ }
624   typedef A TexCoordType;
WT(const int i)625   TexCoordType &WT(const int i)       { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; }
cWT(const int i)626   TexCoordType cWT(const int i) const { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; }
627   template <class RightFaceType>
ImportData(const RightFaceType & rightF)628   void ImportData(const RightFaceType & rightF){
629     if(this->IsWedgeTexCoordEnabled() && rightF.IsWedgeTexCoordEnabled())
630     { WT(0) = rightF.cWT(0); WT(1) = rightF.cWT(1); WT(2) = rightF.cWT(2); }
631     TT::ImportData(rightF);
632   }
IsWedgeTexCoordEnabled()633   inline bool IsWedgeTexCoordEnabled( ) const { return this->Base().IsWedgeTexCoordEnabled(); }
HasWedgeTexCoord()634   static bool HasWedgeTexCoord()   { return true; }
HasWedgeTexCoordOcf()635   static bool HasWedgeTexCoordOcf()   { return true; }
636 };
637 
638 template <class T> class WedgeTexCoordfOcf: public WedgeTexCoordOcf<TexCoord2<float,1>, T> {};
639 
640 ///*-------------------------- WEDGE COLOR  ----------------------------------*/
641 template <class A, class TT> class WedgeColorOcf: public TT {
642 public:
WedgeColorOcf()643   WedgeColorOcf(){ }
644   typedef A WedgeColorType;
WC(const int i)645   WedgeColorType &WC(const int i)              { assert((*this).Base().WedgeColorEnabled); return (*this).Base().WCV[(*this).Index()].wc[i]; }
cWC(const int i)646   const WedgeColorType cWC(const int i) const { assert((*this).Base().WedgeColorEnabled); return (*this).Base().WCV[(*this).Index()].wc[i]; }
647   template <class RightFaceType>
ImportData(const RightFaceType & rightF)648   void ImportData(const RightFaceType & rightF){
649     if(this->IsWedgeColorEnabled() && rightF.IsWedgeColorEnabled())
650     { WC(0) = rightF.cWC(0); WC(1) = rightF.cWC(1); WC(2) = rightF.cWC(2); }
651     TT::ImportData(rightF);
652   }
IsWedgeColorEnabled()653   inline bool IsWedgeColorEnabled( )    const { return this->Base().IsWedgeColorEnabled(); }
HasWedgeColor()654   static bool HasWedgeColor()   { return true; }
HasWedgeColorOcf()655   static bool HasWedgeColorOcf()   { return true; }
656 };
657 
658 template <class T> class WedgeColor4bOcf: public WedgeColorOcf<vcg::Color4b, T> {};
659 
660 ///*-------------------------- WEDGE NORMAL ----------------------------------*/
661 template <class A, class TT> class WedgeNormalOcf: public TT {
662 public:
WedgeNormalOcf()663   WedgeNormalOcf(){ }
664   typedef A WedgeNormalType;
WN(const int i)665   WedgeNormalType &WN(const int i)              { assert((*this).Base().WedgeNormalEnabled); return (*this).Base().WNV[(*this).Index()].wn[i]; }
cWN(const int i)666   WedgeNormalType const &cWN(const int i) const { assert((*this).Base().WedgeNormalEnabled); return (*this).Base().WNV[(*this).Index()].wn[i]; }
667   template <class RightFaceType>
ImportData(const RightFaceType & rightF)668   void ImportData(const RightFaceType & rightF){
669     if(this->IsWedgeNormalEnabled() && rightF.IsWedgeNormalEnabled())
670     { WN(0) = rightF.cWN(0); WN(1) = rightF.cWN(1); WN(2) = rightF.cWN(2); }
671     TT::ImportData(rightF);
672   }
IsWedgeNormalEnabled()673   inline bool IsWedgeNormalEnabled( )   const { return this->Base().IsWedgeNormalEnabled(); }
HasWedgeNormal()674   static bool HasWedgeNormal()   { return true; }
HasWedgeNormalOcf()675   static bool HasWedgeNormalOcf()   { return true; }
676 };
677 
678 template <class T> class WedgeNormal3sOcf: public WedgeNormalOcf<vcg::Point3s, T> {};
679 template <class T> class WedgeNormal3fOcf: public WedgeNormalOcf<vcg::Point3f, T> {};
680 template <class T> class WedgeNormal3dOcf: public WedgeNormalOcf<vcg::Point3d, T> {};
681 
682 ///*-------------------------- InfoOpt  ----------------------------------*/
683 template < class T> class InfoOcf: public T {
684 public:
685   // You should never ever try to copy a vertex that has OCF stuff.
686   // use ImportData function.
687   inline InfoOcf &operator=(const InfoOcf & /*other*/) {
688     assert(0); return *this;
689   }
690 
691 
Base()692   vector_ocf<typename T::FaceType> &Base() const { return *_ovp;}
693 
694   template <class RightFaceType>
ImportData(const RightFaceType & rightF)695   void ImportData(const RightFaceType & rightF){T::ImportData(rightF);}
696 
HasColorOcf()697   static bool HasColorOcf()        { return false; }
HasCurvatureDirOcf()698   static bool HasCurvatureDirOcf() { return false; }
HasMarkOcf()699   static bool HasMarkOcf()         { return false; }
HasNormalOcf()700   static bool HasNormalOcf()       { return false; }
HasQualityOcf()701   static bool HasQualityOcf()      { return false; }
HasWedgeTexCoordOcf()702   static bool HasWedgeTexCoordOcf()    { return false; }
HasWedgeColorOcf()703   static bool HasWedgeColorOcf()       { return false; }
HasWedgeNormalOcf()704   static bool HasWedgeNormalOcf()      { return false; }
HasFFAdjacencyOcf()705   static bool HasFFAdjacencyOcf()      { return false; }
HasVFAdjacencyOcf()706   static bool HasVFAdjacencyOcf()      { return false; }
707 
708 
709 
710 
711 
712 
713 
Index()714   inline size_t Index() const {
715     typename T::FaceType const *tp=static_cast<typename T::FaceType const *>(this);
716     size_t tt2=tp- &*(_ovp->begin());
717     return tt2;
718   }
719 public:
720   // ovp Optional Vector Pointer
721   // Pointer to the base vector where each face element is stored.
722   // used to access to the vectors of the other optional members.
723   vector_ocf<typename T::FaceType> *_ovp;
724 };
725 
726   } // end namespace face
727 
728   template < class, class,class,class > class TriMesh;
729 
730   namespace tri
731   {
732   template < class FaceType >
FaceVectorHasVFAdjacency(const face::vector_ocf<FaceType> & fv)733   bool FaceVectorHasVFAdjacency(const face::vector_ocf<FaceType> &fv)
734   {
735     if(FaceType::HasVFAdjacencyOcf()) return fv.IsVFAdjacencyEnabled();
736     else return FaceType::HasVFAdjacency();
737   }
738   template < class FaceType >
FaceVectorHasFFAdjacency(const face::vector_ocf<FaceType> & fv)739   bool FaceVectorHasFFAdjacency(const face::vector_ocf<FaceType> &fv)
740   {
741     if(FaceType::HasFFAdjacencyOcf()) return fv.IsFFAdjacencyEnabled();
742     else return FaceType::HasFFAdjacency();
743   }
744   template < class FaceType >
FaceVectorHasPerWedgeTexCoord(const face::vector_ocf<FaceType> & fv)745   bool FaceVectorHasPerWedgeTexCoord(const face::vector_ocf<FaceType> &fv)
746   {
747     if(FaceType::HasWedgeTexCoordOcf()) return fv.IsWedgeTexCoordEnabled();
748     else return FaceType::HasWedgeTexCoord();
749   }
750   template < class FaceType >
FaceVectorHasPerFaceColor(const face::vector_ocf<FaceType> & fv)751   bool FaceVectorHasPerFaceColor(const face::vector_ocf<FaceType> &fv)
752   {
753     if(FaceType::HasColorOcf()) return fv.IsColorEnabled();
754     else return FaceType::HasColor();
755   }
756   template < class FaceType >
FaceVectorHasPerFaceQuality(const face::vector_ocf<FaceType> & fv)757   bool FaceVectorHasPerFaceQuality(const face::vector_ocf<FaceType> &fv)
758   {
759     if(FaceType::HasQualityOcf()) return fv.IsQualityEnabled();
760     else return FaceType::HasQuality();
761   }
762   template < class FaceType >
FaceVectorHasPerFaceMark(const face::vector_ocf<FaceType> & fv)763   bool FaceVectorHasPerFaceMark(const face::vector_ocf<FaceType> &fv)
764   {
765     if(FaceType::HasMarkOcf()) return fv.IsMarkEnabled();
766     else return FaceType::HasMark();
767   }
768   template < class FaceType >
FaceVectorHasPerFaceCurvatureDir(const face::vector_ocf<FaceType> & fv)769   bool FaceVectorHasPerFaceCurvatureDir(const face::vector_ocf<FaceType> &fv)
770   {
771     if(FaceType::HasCurvatureDirOcf()) return fv.IsCurvatureDirEnabled();
772     else return FaceType::HasCurvatureDir();
773   }
774   template < class FaceType >
FaceVectorHasPerFaceNormal(const face::vector_ocf<FaceType> & fv)775   bool FaceVectorHasPerFaceNormal(const face::vector_ocf<FaceType> &fv)
776   {
777     if(FaceType::HasNormalOcf()) return fv.IsNormalEnabled();
778     else return FaceType::HasNormal();
779   }
780   template < class FaceType >
ReorderFace(std::vector<size_t> & newFaceIndex,face::vector_ocf<FaceType> & faceVec)781   void ReorderFace( std::vector<size_t>  &newFaceIndex, face::vector_ocf< FaceType > &faceVec)
782   {
783     faceVec.ReorderFace(newFaceIndex);
784   }
785 
786   }
787 }// end namespace vcg
788 #endif
789