File: component.h

package info (click to toggle)
meshlab 2020.09%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 45,132 kB
  • sloc: cpp: 400,238; ansic: 31,952; javascript: 1,578; sh: 387; yacc: 238; lex: 139; python: 86; makefile: 30
file content (612 lines) | stat: -rw-r--r-- 27,751 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
/****************************************************************************
* VCGLib                                                            o o     *
* Visual and Computer Graphics Library                            o     o   *
*                                                                _   O  _   *
* Copyright(C) 2004-2016                                           \/)\/    *
* Visual Computing Lab                                            /\/|      *
* ISTI - Italian National Research Council                           |      *
*                                                                    \      *
* All rights reserved.                                                      *
*                                                                           *
* This program is free software; you can redistribute it and/or modify      *
* it under the terms of the GNU General Public License as published by      *
* the Free Software Foundation; either version 2 of the License, or         *
* (at your option) any later version.                                       *
*                                                                           *
* This program is distributed in the hope that it will be useful,           *
* but WITHOUT ANY WARRANTY; without even the implied warranty of            *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
* for more details.                                                         *
*                                                                           *
****************************************************************************/
#ifndef __VCG_MESH
#error "This file should not be included alone. It is automatically included by complex.h"
#endif
#ifndef __VCG_VERTEX_PLUS_COMPONENT
#define __VCG_VERTEX_PLUS_COMPONENT

namespace vcg {
namespace vertex {
/** \addtogroup VertexComponentGroup
  @{

*/
/*------------------------- Base Classes  -----------------------------------------*/

  template <class S>
  struct CurvatureDirBaseType{
          typedef Point3<S> VecType;
          typedef  S   ScalarType;
          CurvatureDirBaseType () {}
          Point3<S>max_dir,min_dir; // max and min curvature direction
          S k1,k2;// max and min curvature values
  };

/*------------------------- EMPTY CORE COMPONENTS -----------------------------------------*/

template <class TT> class EmptyCore: public TT {
public:
  typedef int FlagType;
  int &Flags()       { assert(0); static int dummyflags(0);  return dummyflags; }
  int cFlags() const { return 0; }
  static bool HasFlags()   { return false; }

  typedef vcg::Point3f CoordType;
  typedef CoordType::ScalarType      ScalarType;
  CoordType &P()       { assert(0); static CoordType coord(0, 0, 0); return coord; }
  CoordType cP() const { assert(0); static CoordType coord(0, 0, 0);  assert(0); return coord; }
  static bool HasCoord()   { return false; }
  inline bool IsCoordEnabled() const { return TT::VertexType::HasCoord();}

  typedef vcg::Point3s NormalType;
  NormalType &N()       { assert(0); static NormalType dummy_normal(0, 0, 0); return dummy_normal; }
  NormalType cN() const { assert(0); static NormalType dummy_normal(0, 0, 0); return dummy_normal; }
  static bool HasNormal()    { return false; }
  inline bool IsNormalEnabled() const { return TT::VertexType::HasNormal();}

  typedef float QualityType;
  QualityType &Q()       { assert(0); static QualityType dummyQuality(0); return dummyQuality; }
  QualityType cQ() const { assert(0); static QualityType dummyQuality(0); return dummyQuality; }
  static bool HasQuality()   { return false; }
  inline bool IsQualityEnabled() const { return TT::VertexType::HasQuality();}

  typedef vcg::Color4b ColorType;
  ColorType &C()       { static ColorType dumcolor(vcg::Color4b::White); assert(0); return dumcolor; }
  ColorType cC() const { static ColorType dumcolor(vcg::Color4b::White);  assert(0); return dumcolor; }
  static bool HasColor()   { return false; }
  inline bool IsColorEnabled() const { return TT::VertexType::HasColor();}

  typedef int  MarkType;
  void InitIMark()    {  }
  int cIMark()  const { assert(0); static int tmp=-1; return tmp;}
  int &IMark()        { assert(0); static int tmp=-1; return tmp;}
  static bool HasMark()   { return false; }
  inline bool IsMarkEnabled() const { return TT::VertexType::HasMark();}

  typedef ScalarType RadiusType;
  RadiusType &R()       { static ScalarType v = 0.0; assert(0 && "the radius component is not available"); return v; }
  RadiusType cR() const { static const ScalarType v = 0.0; assert(0 && "the radius component is not available"); return v; }
  static bool HasRadius()     { return false; }
  inline bool IsRadiusEnabled() const { return TT::VertexType::HasRadius();}

  typedef vcg::TexCoord2<float,1> TexCoordType;
  TexCoordType &T()       { static TexCoordType dummy_texcoord;  assert(0); return dummy_texcoord; }
  TexCoordType cT() const { static TexCoordType dummy_texcoord;  assert(0); return dummy_texcoord; }
  static bool HasTexCoord()   { return false; }
  inline bool IsTexCoordEnabled() const { return TT::VertexType::HasTexCoord();}

  typename TT::TetraPointer &VTp()        { static typename TT::TetraPointer tp = 0;  assert(0); return tp; }
  typename TT::TetraPointer cVTp() const  { static typename TT::TetraPointer tp = 0;  assert(0); return tp; }
  int &VTi()       { static int z = 0; assert(0); return z; }
  int cVTi() const { static int z = 0; assert(0); return z; }
  static bool HasVTAdjacency() { return false; }
  bool IsVTInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVTi()!=-1;}
  void VTClear() {
    if(IsVTInitialized()) {
      static_cast<typename TT::VertexPointer>(this)->VTp()=0;
      static_cast<typename TT::VertexPointer>(this)->VTi()=-1;
    }
  }

  typename TT::FacePointer &VFp()       { static typename TT::FacePointer fp=0;  assert(0); return fp; }
  typename TT::FacePointer cVFp() const { static typename TT::FacePointer fp=0;  assert(0); return fp; }
  int &VFi()       { static int z=-1; assert(0); return z;}
  int cVFi() const { static int z=-1; assert(0); return z;}
  bool IsNull() const { return true; }
  static bool HasVFAdjacency()   { return false; }
  bool IsVFInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVFi()!=-1;}
  void VFClear() {
    if(IsVFInitialized()) {
      static_cast<typename TT::VertexPointer>(this)->VFp()=0;
      static_cast<typename TT::VertexPointer>(this)->VFi()=-1;
    }
  }

  typename TT::EdgePointer &VEp()       { static typename TT::EdgePointer ep=0;  assert(0); return ep; }
  typename TT::EdgePointer cVEp() const { static typename TT::EdgePointer ep=0;  assert(0); return ep; }
  int &VEi()       { static int z=-1; return z;}
  int cVEi() const { static int z=-1; return z;}
  static bool HasVEAdjacency()   {   return false; }
  bool IsVEInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVEi()!=-1;}
  void VEClear() {
    if(IsVEInitialized()) {
      static_cast<typename TT::VertexPointer>(this)->VEp()=0;
      static_cast<typename TT::VertexPointer>(this)->VEi()=-1;
    }
  }
  typename TT::HEdgePointer &VHp()       { static typename TT::HEdgePointer ep=0;  assert(0); return ep; }
  typename TT::HEdgePointer cVHp() const { static typename TT::HEdgePointer ep=0;  assert(0); return ep; }
  int &VHi()       { static int z=0; return z;}
  int cVHi() const { static int z=0; return z;}
  static bool HasVHAdjacency()   {   return false; }

  typedef float   CurScalarType;
  typedef float   ScalarTypeCur;
  typedef Point3f CurVecType;
  typedef Point2f CurvatureType;
  float &Kh()       { static float dummy = 0.f; assert(0);return dummy;}
  float &Kg()       { static float dummy = 0.f; assert(0);return dummy;}
  float cKh() const { static float dummy = 0.f; assert(0); return dummy;}
  float cKg() const { static float dummy = 0.f; assert(0); return dummy;}

  typedef CurvatureDirBaseType<float> CurvatureDirType;
  CurVecType &PD1()       {static CurVecType v(0,0,0); assert(0);return v;}
  CurVecType &PD2()       {static CurVecType v(0,0,0); assert(0);return v;}
  CurVecType cPD1() const {static CurVecType v(0,0,0); assert(0);return v;}
  CurVecType cPD2() const {static CurVecType v(0,0,0); assert(0);return v;}

  CurScalarType &K1()       { static ScalarType v = 0.0;assert(0);return v;}
  CurScalarType &K2()       { static ScalarType v = 0.0;assert(0);return v;}
  CurScalarType cK1() const {static ScalarType v = 0.0;assert(0);return v;}
  CurScalarType cK2() const  {static ScalarType v = 0.0;assert(0);return v;}

  static bool HasCurvature()			{ return false; }
  static bool HasCurvatureDir()			{ return false; }
  inline bool IsCurvatureEnabled() const { return TT::VertexType::HasCurvature();}
  inline bool IsCurvatureDirEnabled() const { return TT::VertexType::HasCurvatureDir();}

  template < class RightValueType>
  void ImportData(const RightValueType  & /*rVert*/ ) {
//			TT::ImportData( rVert);
  }
  static void Name(std::vector<std::string> & name){TT::Name(name);}
};

/*-------------------------- COORD ----------------------------------------*/
/*! \brief \em Generic Component: \b Geometric \b Position of the vertex
  Templated on the coordinate class. In practice you use one of the two specialized class Coord3f and Coord3d
  You can access to the coordinate of a vertex by mean of the P(),cP() member functions.
  */
template <class A, class T> class Coord: public T {
public:
  typedef A CoordType;
  typedef typename A::ScalarType      ScalarType;
  /// Return a const reference to the coordinate of the vertex
  inline const CoordType &P() const { return _coord; }
  /// Return a reference to the coordinate of the vertex
  inline       CoordType &P()       { return _coord; }
  /// Return a const reference to the coordinate of the vertex
  inline       CoordType cP() const { return _coord; }

  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ) { if(rVert.IsCoordEnabled()) P().Import(rVert.cP()); T::ImportData( rVert); }
  static bool HasCoord()   { return true; }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("Coord"));T::Name(name);}

private:
  CoordType _coord;
};
/// Specialized Coord Component in floating point precision.
template <class T> class Coord3f: public Coord<vcg::Point3f, T> {
public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("Coord3f"));T::Name(name);}
};
/// Specialized Coord Component in double point precision.
template <class T> class Coord3d: public Coord<vcg::Point3d, T> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Coord3d"));T::Name(name);}
};

/*-------------------------- NORMAL ----------------------------------------*/
  /*! \brief \em Generic Component: \b %Normal of the vertex

    Templated on the Point3 class used to store the normal.
    In practice you use one of the two specialized class Normal3f and Normal3d.

    You can access to the normal of a vertex by mean of the N(),cN() member functions.

    \note Many algorithms assume that, for sake of precision coherence,
    the type of the normal is the same with respect to the type coord component.
    */

template <class A, class T> class Normal: public T {
public:
  typedef A NormalType;
  /// Return a const reference to the normal of the vertex
  inline const NormalType &N() const { return _norm; }
  /// Return a  reference to the normal of the vertex
  inline       NormalType &N()       { return _norm; }
  /// Return a const reference to the normal of the vertex
  inline       NormalType cN() const { return _norm; }
  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ){
    if(rVert.IsNormalEnabled())  N().Import(rVert.cN());
    T::ImportData( rVert);
  }
  static bool HasNormal()   { return true; }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal"));T::Name(name);}

private:
  NormalType _norm;
};

template <class T> class Normal3s: public Normal<vcg::Point3s, T> {
public:static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal3s"));T::Name(name);}
};
/// Specialized Normal component in floating point precision.
template <class T> class Normal3f: public Normal<vcg::Point3f, T> {
public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal3f"));T::Name(name);}
};
/// Specialized Normal component in double point precision.
template <class T> class Normal3d: public Normal<vcg::Point3d, T> {
public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal3d"));T::Name(name);}
};


/*-------------------------- INCREMENTAL MARK  ----------------------------------------*/
  /*! \brief Per vertex \b Incremental \b Mark

      It is just an int that allows to efficently un-mark the whole mesh. \sa UnmarkAll
      */

template <class T> class Mark: public T {
public:
  Mark():_imark(0){}
  /// Return a const reference to the incremental mark value
  inline const int &IMark() const { return _imark;}
  /// Return a reference to the incremental mark value
  inline       int &IMark()       { return _imark;}
  /// Return a const reference to the incremental mark value
  inline       int cIMark() const { return _imark;}
  static bool HasMark()      { return true; }
  inline void InitIMark()    { _imark = 0; }
  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ) { if(rVert.IsMarkEnabled())  IMark() = rVert.cIMark(); T::ImportData( rVert); }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("Mark"));T::Name(name);}

 private:
    int _imark;
};

/*-------------------------- TEXCOORD ----------------------------------------*/
  /*! \brief \em Generic Component: Per vertex \b Texture Coords

      Note that to have multiple different TexCoord for a single vertex
      (as it happens on atlas where a vertex can belong to two triangles
       mapped on different portionof the texture) you have two options:
      - explicit duplication of vertexes
      - use PerWedge Texture coords

      It is templated on the TextureCoord type. Usually you use the specialized classes TexCoord2f or TexCoord2d;
      See the TexCoord2 class to see how to access to texture coordinate values.

      */

template <class A, class TT> class TexCoord: public TT {
public:
  typedef A TexCoordType;

  /// Return a const reference to the Texture Coordinate
  const TexCoordType &T() const { return _t; }
        TexCoordType &T()       { return _t; }
        TexCoordType cT() const { return _t; }
    template < class RightValueType>
    void ImportData(const RightValueType  & rVert ) { if(rVert.IsTexCoordEnabled()) T().Import(rVert.cT()); TT::ImportData(rVert); }
  static bool HasTexCoord()   { return true; }
    static void Name(std::vector<std::string> & name){name.push_back(std::string("TexCoord"));TT::Name(name);}

private:
  TexCoordType _t;
};


template <class TT> class TexCoord2s: public TexCoord<TexCoord2<short,1>, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("TexCoord2s"));TT::Name(name);}
};
/// Specialized Texture component in floating point precision.
template <class TT> class TexCoord2f: public TexCoord<TexCoord2<float,1>, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("TexCoord2f"));TT::Name(name);}
};
/// Specialized Texture component in double precision.
template <class TT> class TexCoord2d: public TexCoord<TexCoord2<double,1>, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("TexCoord2d"));TT::Name(name);}
};

/*------------------------- FLAGS -----------------------------------------*/
  /*! \brief \em Component: Per vertex \b Flags

      This component stores a 32 bit array of bit flags.
      These bit flags are used for keeping track of selection, deletion, visiting etc. \sa \ref flags for more details on common uses of flags.
      */

template <class T> class BitFlags:  public T {
public:
  BitFlags(){_flags=0;}
  typedef int FlagType;
  inline const int &Flags() const {return _flags; }
  inline       int &Flags()       {return _flags; }
  inline       int cFlags() const {return _flags; }
  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ) { if(RightValueType::HasFlags()) Flags() = rVert.cFlags(); T::ImportData( rVert); }
  static bool HasFlags()   { return true; }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("BitFlags"));T::Name(name);}

private:
  int  _flags;
};


/*-------------------------- Color  ----------------------------------*/
  /*! \brief \em Component: Per vertex \b Color
   *
   * Usually most of the library expects a color stored as 4 unsigned chars (so the component you use is a \c vertex::Color4b)
   * but you can also use float for the color components.
   */
template <class A, class T> class Color: public T {
public:
  Color():_color(vcg::Color4b::White) {}
  typedef A ColorType;
  inline const ColorType &C() const { return _color; }
  inline       ColorType &C()       { return _color; }
  inline       ColorType cC() const { return _color; }
  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ) { if(rVert.IsColorEnabled()) C() = rVert.cC();  T::ImportData( rVert); }
  static bool HasColor()   { return true; }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("Color"));T::Name(name);}

private:
  ColorType _color;
};

template <class TT> class Color4b: public Color<vcg::Color4b, TT> {
    public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Color4b"));TT::Name(name);}
};

/*-------------------------- Quality  ----------------------------------*/
  /*! \brief \em Component: Per vertex \b quality
The Quality Component is a generic place for storing a float. The term 'quality' is a bit misleading and it is due to its original storic meaning. You should intend it as a general purpose container.
\sa vcg::tri::UpdateColor for methods transforming quality into colors
\sa vcg::tri::UpdateQuality for methods to manage it

*/

template <class A, class TT> class Quality: public TT {
public:
  typedef A QualityType;
  Quality():_quality(0) {}

  inline const QualityType &Q() const { return _quality; }
  inline       QualityType &Q()       { return _quality; }
  inline       QualityType cQ() const {return _quality; }
  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ) { if(rVert.IsQualityEnabled()) Q() = rVert.cQ(); TT::ImportData( rVert); }
  static bool HasQuality()   { return true; }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("Quality"));TT::Name(name);}

private:
  QualityType _quality;
};

template <class TT> class Qualitys: public Quality<short, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Qualitys"));TT::Name(name);}
};
template <class TT> class Qualityf: public Quality<float, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Qualityf"));TT::Name(name);}
};
template <class TT> class Qualityd: public Quality<double, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Qualityd"));TT::Name(name);}
};

  /*-------------------------- Curvature   ----------------------------------*/

  /*! \brief \em Component: Per vertex basic \b curvature
    This component keeps the mean an gaussian curvature for a vertex. Used by some of the algorithms of vcg::tri::UpdateCurvature to store the computed curvatures.
      */
  template <class A, class TT> class Curvature: public TT {
  public:
    typedef Point2<A> CurvatureType;
    typedef typename CurvatureType::ScalarType ScalarTypeCur;
    const ScalarTypeCur &Kh() const { return _hk[0]; }
    const ScalarTypeCur &Kg() const { return _hk[1]; }
          ScalarTypeCur &Kh()       { return _hk[0]; }
          ScalarTypeCur &Kg()       { return _hk[1]; }
          ScalarTypeCur cKh() const { return _hk[0]; }
          ScalarTypeCur cKg() const { return _hk[1]; }

          template < class RightValueType>
          void ImportData(const RightValueType  & rVert ) {
            if(rVert.IsCurvatureEnabled()) {
              Kh() = rVert.cKh();
              Kg() = rVert.cKg();
            }
            TT::ImportData( rVert);
          }

    static bool HasCurvature()   { return true; }
    static void Name(std::vector<std::string> & name){name.push_back(std::string("Curvature"));TT::Name(name);}

  private:
    Point2<A> _hk;
  };


  template <class T> class Curvaturef: public Curvature< float, T> {
  public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("Curvaturef"));T::Name(name);}
  };
  template <class T> class Curvatured: public Curvature<double , T> {
  public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("Curvatured"));T::Name(name);}
  };

/*-------------------------- Curvature Direction ----------------------------------*/

  /*! \brief \em Component: Per vertex \b curvature \b directions
    This component keep the principal curvature directions. Used by some of the algorithms of vcg::tri::UpdateCurvature to store the computed curvatures.
      */

template <class A, class TT> class CurvatureDir: public TT {
public:
  typedef A CurvatureDirType;
    typedef typename CurvatureDirType::VecType CurVecType;
    typedef typename CurvatureDirType::ScalarType CurScalarType;

    CurVecType &PD1(){ return _curv.max_dir; }
    CurVecType &PD2(){ return _curv.min_dir; }
    const CurVecType &cPD1() const { return _curv.max_dir; }
    const CurVecType &cPD2() const { return _curv.min_dir; }

    CurScalarType &K1(){ return _curv.k1; }
    CurScalarType &K2(){ return _curv.k2; }
    const CurScalarType &cK1() const { return _curv.k1; }
    const CurScalarType &cK2() const { return _curv.k2; }
    template < class RightValueType>
    void ImportData(const RightValueType  & rVert ) {
      if(rVert.IsCurvatureDirEnabled()) {
        PD1().Import(rVert.cPD1());
        PD2().Import(rVert.cPD2());
        K1()  = rVert.cK1();  K2()  = rVert.cK2();
      }
      TT::ImportData( rVert);
    }

    static bool HasCurvatureDir()   { return true; }
    static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDir"));TT::Name(name);}

private:
  CurvatureDirType _curv;
};


template <class T> class CurvatureDirf: public CurvatureDir<CurvatureDirBaseType<float>, T> {
public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirf"));T::Name(name);}
};
template <class T> class CurvatureDird: public CurvatureDir<CurvatureDirBaseType<double>, T> {
public:	static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDird"));T::Name(name);}
};

/*-------------------------- Radius  ----------------------------------*/
  /*! \brief \em Component: Per vertex \b radius

    This component keep a floating point value meant to be the average distance from the surrounding vertices. Used in point clouds by some of the point splatting and MLS surface algorithms.
      */
  template <class A, class TT> class Radius: public TT {
  public:
    typedef A RadiusType;
    const RadiusType &R() const { return _radius; }
          RadiusType &R()       { return _radius; }
          RadiusType cR() const {return _radius; }
    template < class RightValueType>
    void ImportData(const RightValueType  & rVert ) { if(rVert.IsRadiusEnabled()) R() = rVert.cR(); TT::ImportData( rVert); }
    static bool HasRadius()   { return true; }
    static void Name(std::vector<std::string> & name){name.push_back(std::string("Radius"));TT::Name(name);}

  private:
    RadiusType _radius;
  };

template <class TT> class Radiusf: public Radius<float, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Radiusf"));TT::Name(name);}
};


/*----------------------------- VEADJ ------------------------------*/
/*! \brief \em Component: Per vertex \b Vertex-Edge adjacency relation
    It stores a pointer to the first Edge of a list edges that is stored in a distributed way on the edges themselves.

\sa vcg::tri::UpdateTopology for functions that compute this relation
\sa iterators
*/

template <class T> class VEAdj: public T {
public:
  VEAdj(){_ep=0;_zp=-1;}
  typename T::EdgePointer &VEp()       {return _ep; }
  typename T::EdgePointer cVEp() const {return _ep; }
  int &VEi()       {return _zp; }
  int cVEi() const {return _zp; }
  template < class RightValueType>
  void ImportData(const RightValueType  & rVert ) {  T::ImportData( rVert); }
  static bool HasVEAdjacency()   {   return true; }
  static void Name(std::vector<std::string> & name){name.push_back(std::string("VEAdj"));T::Name(name);}

private:
  typename T::EdgePointer _ep ;
  int _zp ;
};

/*----------------------------- VFADJ ------------------------------*/
  /*! \brief \em Component: Per vertex \b Vertex-Face adjacency relation

It stores a pointer to the first face of a list of faces that is stored in a distributed way on the faces themselves.
Note that if you use this component it is expected that on the Face you use also the corresponding vcg::face::VFAdj component.

  \sa vcg::tri::UpdateTopology for functions that compute this relation
  \sa vcg::face::VFAdj
  \sa iterators
  */

  template <class T> class VFAdj: public T {
  public:
    VFAdj(){_fp=0;_zp=-1;}
    typename T::FacePointer &VFp()        { return _fp; }
    typename T::FacePointer cVFp() const  { return _fp; }
    int &VFi()       { return _zp; }
    int cVFi() const { return _zp; }
    bool IsNull() const { return _zp==-1;}
    template < class RightValueType>
    void ImportData(const RightValueType  & rVert ) { T::ImportData( rVert); }
    static bool HasVFAdjacency()   {   return true; }
    static void Name(std::vector<std::string> & name){name.push_back(std::string("VFAdj"));T::Name(name);}

  private:
    typename T::FacePointer _fp ;
    int _zp ;
  };

/*----------------------------- VHADJ ------------------------------*/

template <class T> class VHAdj: public T {
public:
    VHAdj(){_hp=0;_zp=-1;}
    typename T::HEdgePointer &VHp()       {return _hp; }
    typename T::HEdgePointer cVHp() const {return _hp; }
    int &VHi() {return _zp; }
    template < class RightValueType>
    void ImportData(const RightValueType  & rVert ) {  T::ImportData( rVert); }
    static bool HasVHAdjacency()   {   return true; }
    static void Name(std::vector<std::string> & name){name.push_back(std::string("VHAdj"));T::Name(name);}

private:
    typename T::HEdgePointer _hp ;
    int _zp ;
};

/*----------------------------- VTADJ ------------------------------*/

template <class T> class VTAdj: public T {
public:
    VTAdj() { _tp = 0; _zp=-1;}
    typename T::TetraPointer &VTp()       { return _tp; }
    typename T::TetraPointer cVTp() const { return _tp; }
    int &VTi() {return _zp; }
    int cVTi() const { return _zp; }
    static bool HasVTAdjacency() { return true; }
    static void Name( std::vector< std::string > & name ) { name.push_back( std::string("VTAdj") ); T::Name(name); }

private:
    typename T::TetraPointer _tp ;
    int _zp ;
};

  /** @} */   // End Doxygen VertexComponentGroup
  } // end namespace vert
}// end namespace vcg
#endif