You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
840 lines
30 KiB
840 lines
30 KiB
/**************************************************************************** |
|
* 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_FACE_PLUS_COMPONENT_OCF |
|
#define __VCG_FACE_PLUS_COMPONENT_OCF |
|
|
|
#include <vector> |
|
#include <string> |
|
|
|
#include <vcg/space/color4.h> |
|
#include <vcg/space/texcoord2.h> |
|
|
|
namespace vcg { |
|
namespace face { |
|
/* |
|
All the Components that can be added to a faceex should be defined in the namespace face: |
|
|
|
*/ |
|
|
|
template <class VALUE_TYPE> |
|
class vector_ocf: public std::vector<VALUE_TYPE> { |
|
typedef std::vector<VALUE_TYPE> BaseType; |
|
typedef typename vector_ocf<VALUE_TYPE>::iterator ThisTypeIterator; |
|
|
|
public: |
|
vector_ocf():std::vector<VALUE_TYPE>() |
|
{ |
|
_ColorEnabled=false; |
|
CurvatureDirEnabled = false; |
|
MarkEnabled=false; |
|
NormalEnabled=false; |
|
QualityEnabled=false; |
|
WedgeTexEnabled=false; |
|
WedgeColorEnabled=false; |
|
WedgeNormalEnabled=false; |
|
VFAdjacencyEnabled=false; |
|
FFAdjacencyEnabled=false; |
|
} |
|
|
|
// Auxiliary types to build internal vectors |
|
struct AdjTypePack { |
|
typename VALUE_TYPE::FacePointer _fp[3] ; |
|
char _zp[3] ; |
|
|
|
// Default constructor. |
|
// Needed because we need to know if adjacency is initialized or not |
|
// when resizing vectors and during an allocate face. |
|
AdjTypePack() { |
|
_fp[0]=0; |
|
_fp[1]=0; |
|
_fp[2]=0; |
|
} |
|
}; |
|
|
|
//template <class TexCoordType> |
|
class WedgeTexTypePack { |
|
public: |
|
WedgeTexTypePack() { |
|
wt[0].U()=.5;wt[0].V()=.5; |
|
wt[1].U()=.5;wt[1].V()=.5; |
|
wt[2].U()=.5;wt[2].V()=.5; |
|
wt[0].N()=-1; |
|
wt[1].N()=-1; |
|
wt[2].N()=-1; |
|
} |
|
|
|
typename VALUE_TYPE::TexCoordType wt[3]; |
|
}; |
|
|
|
class WedgeColorTypePack { |
|
public: |
|
WedgeColorTypePack() { |
|
typedef typename VALUE_TYPE::ColorType::ScalarType WedgeColorScalarType; |
|
for (int i=0; i<3; ++i) |
|
{ |
|
wc[i][0] = WedgeColorScalarType(255); |
|
wc[i][1] = WedgeColorScalarType(255); |
|
wc[i][2] = WedgeColorScalarType(255); |
|
wc[i][3] = WedgeColorScalarType(255); |
|
} |
|
} |
|
|
|
typename VALUE_TYPE::WedgeColorType wc[3]; |
|
}; |
|
|
|
class WedgeNormalTypePack { |
|
public: |
|
WedgeNormalTypePack() { |
|
typedef typename VALUE_TYPE::NormalType::ScalarType WedgeNormalScalarType; |
|
for (int i=0; i<3; ++i) |
|
{ |
|
wn[i][0] = WedgeNormalScalarType(0); |
|
wn[i][1] = WedgeNormalScalarType(0); |
|
wn[i][2] = WedgeNormalScalarType(1); |
|
} |
|
} |
|
|
|
typename VALUE_TYPE::WedgeNormalType wn[3]; |
|
}; |
|
|
|
|
|
//////////////////////////////////////// |
|
// All the standard methods of std::vector that can change the reallocation are |
|
// redefined in order to manage the additional data. |
|
void push_back(const VALUE_TYPE & v) |
|
{ |
|
BaseType::push_back(v); |
|
BaseType::back()._ovp = this; |
|
if (QualityEnabled) QV.push_back(0); |
|
if (_ColorEnabled) CV.push_back(vcg::Color4b(vcg::Color4b::White)); |
|
if (MarkEnabled) MV.push_back(0); |
|
if (NormalEnabled) NV.push_back(typename VALUE_TYPE::NormalType()); |
|
if (CurvatureDirEnabled) CDV.push_back(typename VALUE_TYPE::CurvatureDirType()); |
|
if (VFAdjacencyEnabled) AV.push_back(AdjTypePack()); |
|
if (FFAdjacencyEnabled) AF.push_back(AdjTypePack()); |
|
if (WedgeTexEnabled) WTV.push_back(WedgeTexTypePack()); |
|
if (WedgeColorEnabled) WCV.push_back(WedgeColorTypePack()); |
|
if (WedgeNormalEnabled) WNV.push_back(WedgeNormalTypePack()); |
|
} |
|
void pop_back(); |
|
void resize(size_t _size) |
|
{ |
|
size_t oldsize = BaseType::size(); |
|
BaseType::resize(_size); |
|
if(oldsize<_size){ |
|
ThisTypeIterator firstnew = BaseType::begin(); |
|
advance(firstnew,oldsize); |
|
_updateOVP(firstnew,(*this).end()); |
|
} |
|
if (QualityEnabled) QV.resize(_size,0); |
|
if (_ColorEnabled) CV.resize(_size); |
|
if (MarkEnabled) MV.resize(_size); |
|
if (NormalEnabled) NV.resize(_size); |
|
if (CurvatureDirEnabled)CDV.resize(_size); |
|
if (VFAdjacencyEnabled) AV.resize(_size); |
|
if (FFAdjacencyEnabled) AF.resize(_size); |
|
if (WedgeTexEnabled) WTV.resize(_size,WedgeTexTypePack()); |
|
if (WedgeColorEnabled) WCV.resize(_size); |
|
if (WedgeNormalEnabled) WNV.resize(_size); |
|
} |
|
void reserve(size_t _size) |
|
{ |
|
BaseType::reserve(_size); |
|
|
|
if (QualityEnabled) QV.reserve(_size); |
|
if (_ColorEnabled) CV.reserve(_size); |
|
if (MarkEnabled) MV.reserve(_size); |
|
if (NormalEnabled) NV.reserve(_size); |
|
if (CurvatureDirEnabled)CDV.reserve(_size); |
|
if (VFAdjacencyEnabled) AV.reserve(_size); |
|
if (FFAdjacencyEnabled) AF.reserve(_size); |
|
if (WedgeTexEnabled) WTV.reserve(_size); |
|
if (WedgeColorEnabled) WCV.reserve(_size); |
|
if (WedgeNormalEnabled) WNV.reserve(_size); |
|
|
|
if( BaseType::empty()) return ; |
|
|
|
ThisTypeIterator oldbegin=(*this).begin(); |
|
if(oldbegin!=(*this).begin()) _updateOVP((*this).begin(),(*this).end()); |
|
} |
|
|
|
void _updateOVP(ThisTypeIterator lbegin, ThisTypeIterator lend) |
|
{ |
|
ThisTypeIterator fi; |
|
//for(fi=(*this).begin();vi!=(*this).end();++vi) |
|
for(fi=lbegin;fi!=lend;++fi) |
|
(*fi)._ovp=this; |
|
} |
|
|
|
|
|
|
|
// this function is called by the specialized Reorder function, that is called whenever someone call the allocator::CompactVertVector |
|
void ReorderFace(std::vector<size_t> &newFaceIndex ) |
|
{ |
|
size_t i=0; |
|
if (QualityEnabled) assert( QV.size() == newFaceIndex.size() ); |
|
if (_ColorEnabled) assert( CV.size() == newFaceIndex.size() ); |
|
if (MarkEnabled) assert( MV.size() == newFaceIndex.size() ); |
|
if (NormalEnabled) assert( NV.size() == newFaceIndex.size() ); |
|
if (CurvatureDirEnabled)assert(CDV.size() == newFaceIndex.size() ); |
|
if (VFAdjacencyEnabled) assert( AV.size() == newFaceIndex.size() ); |
|
if (FFAdjacencyEnabled) assert( AF.size() == newFaceIndex.size() ); |
|
if (WedgeTexEnabled) assert(WTV.size() == newFaceIndex.size() ); |
|
if (WedgeColorEnabled) assert(WCV.size() == newFaceIndex.size() ); |
|
if (WedgeNormalEnabled) assert(WNV.size() == newFaceIndex.size() ); |
|
|
|
for(i=0;i<newFaceIndex.size();++i) |
|
{ |
|
if(newFaceIndex[i] != std::numeric_limits<size_t>::max() ) |
|
{ |
|
assert(newFaceIndex[i] <= i); |
|
if (QualityEnabled) QV[newFaceIndex[i]] = QV[i]; |
|
if (_ColorEnabled) CV[newFaceIndex[i]] = CV[i]; |
|
if (MarkEnabled) MV[newFaceIndex[i]] = MV[i]; |
|
if (NormalEnabled) NV[newFaceIndex[i]] = NV[i]; |
|
if (CurvatureDirEnabled) CDV[newFaceIndex[i]] = CDV[i]; |
|
if (VFAdjacencyEnabled) AV[newFaceIndex[i]] = AV[i]; |
|
if (FFAdjacencyEnabled) AF[newFaceIndex[i]] = AF[i]; |
|
if (WedgeTexEnabled) WTV[newFaceIndex[i]] = WTV[i]; |
|
if (WedgeColorEnabled) WCV[newFaceIndex[i]] = WCV[i]; |
|
if (WedgeNormalEnabled) WNV[newFaceIndex[i]] = WNV[i]; |
|
} |
|
} |
|
|
|
if (QualityEnabled) QV.resize(BaseType::size(),0); |
|
if (_ColorEnabled) CV.resize(BaseType::size()); |
|
if (MarkEnabled) MV.resize(BaseType::size()); |
|
if (NormalEnabled) NV.resize(BaseType::size()); |
|
if (CurvatureDirEnabled) CDV.resize(BaseType::size()); |
|
if (VFAdjacencyEnabled) AV.resize(BaseType::size()); |
|
if (FFAdjacencyEnabled) AF.resize(BaseType::size()); |
|
if (WedgeTexEnabled) WTV.resize(BaseType::size()); |
|
if (WedgeColorEnabled) WCV.resize(BaseType::size()); |
|
if (WedgeNormalEnabled) WNV.resize(BaseType::size()); |
|
} |
|
|
|
//////////////////////////////////////// |
|
// Enabling Functions |
|
|
|
bool IsQualityEnabled() const {return QualityEnabled;} |
|
void EnableQuality() { |
|
assert(VALUE_TYPE::HasQualityOcf()); |
|
QualityEnabled=true; |
|
QV.resize((*this).size(),0); |
|
} |
|
|
|
void DisableQuality() { |
|
assert(VALUE_TYPE::HasQualityOcf()); |
|
QualityEnabled=false; |
|
QV.clear(); |
|
} |
|
|
|
bool IsColorEnabled() const {return _ColorEnabled;} |
|
void EnableColor() { |
|
assert(VALUE_TYPE::HasColorOcf()); |
|
_ColorEnabled=true; |
|
CV.resize((*this).size(),vcg::Color4b::White); |
|
} |
|
|
|
void DisableColor() { |
|
assert(VALUE_TYPE::HasColorOcf()); |
|
_ColorEnabled=false; |
|
CV.clear(); |
|
} |
|
|
|
bool IsMarkEnabled() const {return MarkEnabled;} |
|
void EnableMark() { |
|
assert(VALUE_TYPE::HasMarkOcf()); |
|
MarkEnabled=true; |
|
MV.resize((*this).size(),0); |
|
} |
|
|
|
void DisableMark() { |
|
assert(VALUE_TYPE::HasMarkOcf()); |
|
MarkEnabled=false; |
|
MV.clear(); |
|
} |
|
|
|
bool IsNormalEnabled() const {return NormalEnabled;} |
|
void EnableNormal() { |
|
assert(VALUE_TYPE::HasNormalOcf()); |
|
NormalEnabled=true; |
|
NV.resize((*this).size()); |
|
} |
|
|
|
void DisableNormal() { |
|
assert(VALUE_TYPE::HasNormalOcf()); |
|
NormalEnabled=false; |
|
NV.clear(); |
|
} |
|
|
|
bool IsCurvatureDirEnabled() const {return CurvatureDirEnabled;} |
|
void EnableCurvatureDir() { |
|
assert(VALUE_TYPE::HasCurvatureDirOcf()); |
|
CurvatureDirEnabled=true; |
|
CDV.resize((*this).size()); |
|
} |
|
|
|
void DisableCurvatureDir() { |
|
assert(VALUE_TYPE::HasCurvatureDirOcf()); |
|
CurvatureDirEnabled=false; |
|
CDV.clear(); |
|
} |
|
|
|
|
|
bool IsVFAdjacencyEnabled() const {return VFAdjacencyEnabled;} |
|
void EnableVFAdjacency() { |
|
assert(VALUE_TYPE::HasVFAdjacencyOcf()); |
|
VFAdjacencyEnabled=true; |
|
AV.resize((*this).size()); |
|
} |
|
|
|
void DisableVFAdjacency() { |
|
assert(VALUE_TYPE::HasVFAdjacencyOcf()); |
|
VFAdjacencyEnabled=false; |
|
AV.clear(); |
|
} |
|
|
|
|
|
bool IsFFAdjacencyEnabled() const {return FFAdjacencyEnabled;} |
|
void EnableFFAdjacency() { |
|
assert(VALUE_TYPE::HasFFAdjacencyOcf()); |
|
FFAdjacencyEnabled=true; |
|
AF.resize((*this).size()); |
|
} |
|
|
|
void DisableFFAdjacency() { |
|
assert(VALUE_TYPE::HasFFAdjacencyOcf()); |
|
FFAdjacencyEnabled=false; |
|
AF.clear(); |
|
} |
|
|
|
bool IsWedgeTexCoordEnabled() const {return WedgeTexEnabled;} |
|
void EnableWedgeTexCoord() { |
|
assert(VALUE_TYPE::HasWedgeTexCoordOcf()); |
|
WedgeTexEnabled=true; |
|
WTV.resize((*this).size(),WedgeTexTypePack()); |
|
} |
|
|
|
void DisableWedgeTexCoord() { |
|
assert(VALUE_TYPE::HasWedgeTexCoordOcf()); |
|
WedgeTexEnabled=false; |
|
WTV.clear(); |
|
} |
|
|
|
bool IsWedgeColorEnabled() const {return WedgeColorEnabled;} |
|
void EnableWedgeColor() { |
|
assert(VALUE_TYPE::HasWedgeColorOcf()); |
|
WedgeColorEnabled=true; |
|
WCV.resize((*this).size(),WedgeColorTypePack()); |
|
} |
|
|
|
void DisableWedgeColor() { |
|
assert(VALUE_TYPE::HasWedgeColorOcf()); |
|
WedgeColorEnabled=false; |
|
WCV.clear(); |
|
} |
|
|
|
bool IsWedgeNormalEnabled() const {return WedgeNormalEnabled;} |
|
void EnableWedgeNormal() { |
|
assert(VALUE_TYPE::HasWedgeNormalOcf()); |
|
WedgeNormalEnabled=true; |
|
WNV.resize((*this).size(),WedgeNormalTypePack()); |
|
} |
|
|
|
void DisableWedgeNormal() { |
|
assert(VALUE_TYPE::HasWedgeNormalOcf()); |
|
WedgeNormalEnabled=false; |
|
WNV.clear(); |
|
} |
|
|
|
public: |
|
std::vector<typename VALUE_TYPE::ColorType> CV; |
|
std::vector<typename VALUE_TYPE::CurvatureDirType> CDV; |
|
std::vector<int> MV; |
|
std::vector<typename VALUE_TYPE::NormalType> NV; |
|
std::vector<typename VALUE_TYPE::QualityType> QV; |
|
std::vector<class WedgeColorTypePack> WCV; |
|
std::vector<class WedgeNormalTypePack> WNV; |
|
std::vector<class WedgeTexTypePack> WTV; |
|
std::vector<struct AdjTypePack> AV; |
|
std::vector<struct AdjTypePack> AF; |
|
|
|
bool _ColorEnabled; |
|
bool CurvatureDirEnabled; |
|
bool MarkEnabled; |
|
bool NormalEnabled; |
|
bool QualityEnabled; |
|
bool WedgeColorEnabled; |
|
bool WedgeNormalEnabled; |
|
bool WedgeTexEnabled; |
|
bool VFAdjacencyEnabled; |
|
bool FFAdjacencyEnabled; |
|
}; // end class vector_ocf |
|
|
|
|
|
/*----------------------------- VFADJ ------------------------------*/ |
|
template <class T> class VFAdjOcf: public T { |
|
public: |
|
typename T::FacePointer &VFp(const int j) { |
|
assert((*this).Base().VFAdjacencyEnabled); |
|
return (*this).Base().AV[(*this).Index()]._fp[j]; |
|
} |
|
|
|
typename T::FacePointer VFp(const int j) const { |
|
if(! (*this).Base().VFAdjacencyEnabled ) return 0; |
|
else return (*this).Base().AV[(*this).Index()]._fp[j]; |
|
} |
|
|
|
typename T::FacePointer cVFp(const int j) const { |
|
if(! (*this).Base().VFAdjacencyEnabled ) return 0; |
|
else return (*this).Base().AV[(*this).Index()]._fp[j]; |
|
} |
|
|
|
char &VFi(const int j) { |
|
assert((*this).Base().VFAdjacencyEnabled); |
|
return (*this).Base().AV[(*this).Index()]._zp[j]; |
|
} |
|
|
|
char VFi(const int j) const { |
|
assert((*this).Base().VFAdjacencyEnabled); |
|
return (*this).Base().AV[(*this).Index()]._zp[j]; |
|
} |
|
|
|
char cVFi(const int j) const { |
|
assert((*this).Base().VFAdjacencyEnabled); |
|
return (*this).Base().AV[(*this).Index()]._zp[j]; |
|
} |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
T::ImportData(rightF); |
|
} |
|
static bool HasVFAdjacency() { return true; } |
|
static bool HasVFAdjacencyOcf() { return true; } |
|
|
|
private: |
|
}; |
|
|
|
/*----------------------------- FFADJ ------------------------------*/ |
|
template <class T> class FFAdjOcf: public T { |
|
public: |
|
typename T::FacePointer &FFp(const int j) { |
|
assert((*this).Base().FFAdjacencyEnabled); |
|
return (*this).Base().AF[(*this).Index()]._fp[j]; |
|
} |
|
|
|
typename T::FacePointer FFp(const int j) const { |
|
if(! (*this).Base().FFAdjacencyEnabled ) return 0; |
|
else return (*this).Base().AF[(*this).Index()]._fp[j]; |
|
} |
|
|
|
typename T::FacePointer cFFp(const int j) const { |
|
if(! (*this).Base().FFAdjacencyEnabled ) return 0; |
|
else return (*this).Base().AF[(*this).Index()]._fp[j]; |
|
} |
|
|
|
char &FFi(const int j) { |
|
assert((*this).Base().FFAdjacencyEnabled); |
|
return (*this).Base().AF[(*this).Index()]._zp[j]; |
|
} |
|
|
|
char FFi(const int j) const { |
|
assert((*this).Base().FFAdjacencyEnabled); |
|
return (*this).Base().AF[(*this).Index()]._zp[j]; |
|
} |
|
|
|
char cFFi(const int j) const { |
|
assert((*this).Base().FFAdjacencyEnabled); |
|
return (*this).Base().AF[(*this).Index()]._zp[j]; |
|
} |
|
|
|
typename T::FacePointer &FFp1( const int j ) { return FFp((j+1)%3);} |
|
typename T::FacePointer &FFp2( const int j ) { return FFp((j+2)%3);} |
|
typename T::FacePointer FFp1( const int j ) const { return FFp((j+1)%3);} |
|
typename T::FacePointer FFp2( const int j ) const { return FFp((j+2)%3);} |
|
typename T::FacePointer cFFp1( const int j ) const { return FFp((j+1)%3);} |
|
typename T::FacePointer cFFp2( const int j ) const { return FFp((j+2)%3);} |
|
|
|
typename T::FacePointer &Neigh( const int j ) { return FFp(j);} |
|
typename T::FacePointer Neigh( const int j ) const { return FFp(j);} |
|
typename T::FacePointer cNeigh( const int j ) const { return FFp(j);} |
|
unsigned int SizeNeigh(){return 3;} |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
T::ImportData(rightF); |
|
} |
|
static bool HasFFAdjacency() { return true; } |
|
static bool HasFFAdjacencyOcf() { return true; } |
|
}; |
|
|
|
/*------------------------- Normal -----------------------------------------*/ |
|
template <class A, class T> class NormalOcf: public T { |
|
public: |
|
typedef A NormalType; |
|
inline bool IsNormalEnabled( ) const { return this->Base().IsNormalEnabled(); } |
|
static bool HasNormal() { return true; } |
|
static bool HasNormalOcf() { return true; } |
|
|
|
NormalType &N() { |
|
// you cannot use Normals before enabling them with: yourmesh.face.EnableNormal() |
|
assert((*this).Base().NormalEnabled); |
|
return (*this).Base().NV[(*this).Index()]; } |
|
|
|
const NormalType& N() const { |
|
// you cannot use Normals before enabling them with: yourmesh.face.EnableNormal() |
|
assert((*this).Base().NormalEnabled); |
|
return (*this).Base().NV[(*this).Index()]; } |
|
|
|
const NormalType& cN() const { |
|
// you cannot use Normals before enabling them with: yourmesh.face.EnableNormal() |
|
assert((*this).Base().NormalEnabled); |
|
return (*this).Base().NV[(*this).Index()]; } |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if((*this).IsNormalEnabled() && rightF.IsNormalEnabled()) |
|
N() = rightF.cN(); |
|
T::ImportData(rightF); |
|
} |
|
}; |
|
|
|
template <class T> class Normal3sOcf: public NormalOcf<vcg::Point3s, T> {}; |
|
template <class T> class Normal3fOcf: public NormalOcf<vcg::Point3f, T> {}; |
|
template <class T> class Normal3dOcf: public NormalOcf<vcg::Point3d, T> {}; |
|
|
|
/*------------------------- CurvatureDir -----------------------------------------*/ |
|
template <class S> |
|
struct CurvatureDirOcfBaseType{ |
|
typedef Point3<S> CurVecType; |
|
typedef S CurScalarType; |
|
CurvatureDirOcfBaseType () {} |
|
CurVecType max_dir,min_dir; // max and min curvature direction |
|
CurScalarType k1,k2;// max and min curvature values |
|
}; |
|
|
|
template <class A, class T> class CurvatureDirOcf: public T { |
|
public: |
|
typedef A CurvatureDirType; |
|
typedef typename CurvatureDirType::CurVecType CurVecType; |
|
typedef typename CurvatureDirType::CurScalarType CurScalarType; |
|
|
|
inline bool IsCurvatureDirEnabled( ) const { return this->Base().IsCurvatureDirEnabled(); } |
|
static bool HasCurvatureDir() { return true; } |
|
static bool HasCurvatureDirOcf() { return true; } |
|
|
|
CurVecType &PD1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].max_dir; } |
|
CurVecType &PD2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].min_dir; } |
|
const CurVecType& PD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].max_dir; } |
|
const CurVecType& PD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].min_dir; } |
|
const CurVecType& cPD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].max_dir; } |
|
const CurVecType& cPD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].min_dir; } |
|
|
|
CurScalarType &K1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].k1; } |
|
CurScalarType &K2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].k2; } |
|
const CurScalarType& K1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].k1; } |
|
const CurScalarType& K2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].k2; } |
|
const CurScalarType& cK1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].k1; } |
|
const CurScalarType& cK2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CDV[(*this).Index()].k2; } |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if((*this).IsCurvatureDirEnabled() && rightF.IsCurvatureDirEnabled()) { |
|
PD1().Import(rightF.cPD1()); |
|
PD2().Import(rightF.cPD2()); |
|
K1() = rightF.cK1(); |
|
K2() = rightF.cK2(); |
|
} |
|
T::ImportData(rightF); |
|
} |
|
|
|
}; |
|
|
|
template <class T> class CurvatureDirfOcf: public CurvatureDirOcf<CurvatureDirOcfBaseType<float>, T> { |
|
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirfOcf"));T::Name(name);} |
|
}; |
|
template <class T> class CurvatureDirdOcf: public CurvatureDirOcf<CurvatureDirOcfBaseType<double>, T> { |
|
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirdOcf"));T::Name(name);} |
|
}; |
|
|
|
///*-------------------------- QUALITY ----------------------------------*/ |
|
template <class A, class T> class QualityOcf: public T { |
|
public: |
|
typedef A QualityType; |
|
QualityType &Q() { |
|
assert((*this).Base().QualityEnabled); |
|
return (*this).Base().QV[(*this).Index()]; |
|
} |
|
const QualityType& Q() const { |
|
assert((*this).Base().QualityEnabled); |
|
return (*this).Base().QV[(*this).Index()]; |
|
} |
|
const QualityType& cQ() const { |
|
assert((*this).Base().QualityEnabled); |
|
return (*this).Base().QV[(*this).Index()]; |
|
} |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if((*this).IsQualityEnabled() && rightF.IsQualityEnabled()) |
|
Q() = rightF.cQ(); |
|
T::ImportData(rightF); |
|
} |
|
inline bool IsQualityEnabled( ) const { return this->Base().IsQualityEnabled(); } |
|
static bool HasQuality() { return true; } |
|
static bool HasQualityOcf() { return true; } |
|
}; |
|
|
|
template <class T> class QualityfOcf: public QualityOcf<float, T> {}; |
|
|
|
///*-------------------------- COLOR ----------------------------------*/ |
|
template <class A, class T> class ColorOcf: public T { |
|
public: |
|
typedef A ColorType; |
|
ColorType &C() { |
|
assert((*this).Base()._ColorEnabled); |
|
return (*this).Base().CV[(*this).Index()]; |
|
} |
|
const ColorType& C() const { |
|
assert((*this).Base()._ColorEnabled); |
|
return (*this).Base().CV[(*this).Index()]; |
|
} |
|
const ColorType& cC() const { |
|
assert((*this).Base()._ColorEnabled); |
|
return (*this).Base().CV[(*this).Index()]; |
|
} |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if((*this).IsColorEnabled() && rightF.IsColorEnabled()) |
|
C() = rightF.cC(); |
|
T::ImportData(rightF); |
|
} |
|
inline bool IsColorEnabled() const { return this->Base().IsColorEnabled();} |
|
static bool HasColor() { return true; } |
|
static bool HasColorOcf() { return true; } |
|
}; |
|
|
|
template <class T> class Color4bOcf: public ColorOcf<vcg::Color4b, T> {}; |
|
|
|
///*-------------------------- MARK ----------------------------------*/ |
|
template <class T> class MarkOcf: public T { |
|
public: |
|
inline int &IMark() { |
|
assert((*this).Base().MarkEnabled); |
|
return (*this).Base().MV[(*this).Index()]; |
|
} |
|
inline int IMark() const { |
|
assert((*this).Base().MarkEnabled); |
|
return (*this).Base().MV[(*this).Index()]; |
|
} |
|
inline int cIMark() const { |
|
assert((*this).Base().MarkEnabled); |
|
return (*this).Base().MV[(*this).Index()]; |
|
} |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if((*this).IsMarkEnabled() && rightF.IsMarkEnabled()) |
|
IMark() = rightF.cIMark(); |
|
T::ImportData(rightF); |
|
} |
|
inline bool IsMarkEnabled( ) const { return this->Base().IsMarkEnabled(); } |
|
static bool HasMark() { return true; } |
|
static bool HasMarkOcf() { return true; } |
|
inline void InitIMark() { IMark() = 0; } |
|
}; |
|
|
|
///*-------------------------- WEDGE TEXCOORD ----------------------------------*/ |
|
template <class A, class TT> class WedgeTexCoordOcf: public TT { |
|
public: |
|
WedgeTexCoordOcf(){ } |
|
typedef A TexCoordType; |
|
TexCoordType &WT(const int i) { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; } |
|
const TexCoordType& WT(const int i) const { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; } |
|
const TexCoordType& cWT(const int i) const { assert((*this).Base().WedgeTexEnabled); return (*this).Base().WTV[(*this).Index()].wt[i]; } |
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if(this->IsWedgeTexCoordEnabled() && rightF.IsWedgeTexCoordEnabled()) |
|
{ WT(0) = rightF.cWT(0); WT(1) = rightF.cWT(1); WT(2) = rightF.cWT(2); } |
|
TT::ImportData(rightF); |
|
} |
|
inline bool IsWedgeTexCoordEnabled( ) const { return this->Base().IsWedgeTexCoordEnabled(); } |
|
static bool HasWedgeTexCoord() { return true; } |
|
static bool HasWedgeTexCoordOcf() { return true; } |
|
}; |
|
|
|
template <class T> class WedgeTexCoordfOcf: public WedgeTexCoordOcf<TexCoord2<float,1>, T> {}; |
|
|
|
///*-------------------------- WEDGE COLOR ----------------------------------*/ |
|
template <class A, class TT> class WedgeColorOcf: public TT { |
|
public: |
|
WedgeColorOcf(){ } |
|
typedef A WedgeColorType; |
|
WedgeColorType &WC(const int i) { assert((*this).Base().WedgeColorEnabled); return (*this).Base().WCV[(*this).Index()].wc[i]; } |
|
const WedgeColorType& WC(const int i) const { assert((*this).Base().WedgeColorEnabled); return (*this).Base().WCV[(*this).Index()].wc[i]; } |
|
const WedgeColorType& cWC(const int i) const { assert((*this).Base().WedgeColorEnabled); return (*this).Base().WCV[(*this).Index()].wc[i]; } |
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if(this->IsWedgeColorEnabled() && rightF.IsWedgeColorEnabled()) |
|
{ WC(0) = rightF.cWC(0); WC(1) = rightF.cWC(1); WC(2) = rightF.cWC(2); } |
|
TT::ImportData(rightF); |
|
} |
|
inline bool IsWedgeColorEnabled( ) const { return this->Base().IsWedgeColorEnabled(); } |
|
static bool HasWedgeColor() { return true; } |
|
static bool HasWedgeColorOcf() { return true; } |
|
}; |
|
|
|
template <class T> class WedgeColor4bOcf: public WedgeColorOcf<vcg::Color4b, T> {}; |
|
|
|
///*-------------------------- WEDGE NORMAL ----------------------------------*/ |
|
template <class A, class TT> class WedgeNormalOcf: public TT { |
|
public: |
|
WedgeNormalOcf(){ } |
|
typedef A WedgeNormalType; |
|
WedgeNormalType &WN(const int i) { assert((*this).Base().WedgeNormalEnabled); return (*this).Base().WNV[(*this).Index()].wn[i]; } |
|
const WedgeNormalType & WN(const int i) const { assert((*this).Base().WedgeNormalEnabled); return (*this).Base().WNV[(*this).Index()].wn[i]; } |
|
const WedgeNormalType &cWN(const int i) const { assert((*this).Base().WedgeNormalEnabled); return (*this).Base().WNV[(*this).Index()].wn[i]; } |
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){ |
|
if(this->IsWedgeNormalEnabled() && rightF.IsWedgeNormalEnabled()) |
|
{ WN(0) = rightF.cWN(0); WN(1) = rightF.cWN(1); WN(2) = rightF.cWN(2); } |
|
TT::ImportData(rightF); |
|
} |
|
inline bool IsWedgeNormalEnabled( ) const { return this->Base().IsWedgeNormalEnabled(); } |
|
static bool HasWedgeNormal() { return true; } |
|
static bool HasWedgeNormalOcf() { return true; } |
|
}; |
|
|
|
template <class T> class WedgeNormal3sOcf: public WedgeNormalOcf<vcg::Point3s, T> {}; |
|
template <class T> class WedgeNormal3fOcf: public WedgeNormalOcf<vcg::Point3f, T> {}; |
|
template <class T> class WedgeNormal3dOcf: public WedgeNormalOcf<vcg::Point3d, T> {}; |
|
|
|
///*-------------------------- InfoOpt ----------------------------------*/ |
|
template < class T> class InfoOcf: public T { |
|
public: |
|
// You should never ever try to copy a vertex that has OCF stuff. |
|
// use ImportData function. |
|
inline InfoOcf &operator=(const InfoOcf & /*other*/) { |
|
assert(0); return *this; |
|
} |
|
|
|
|
|
vector_ocf<typename T::FaceType> &Base() const { return *_ovp;} |
|
|
|
template <class RightFaceType> |
|
void ImportData(const RightFaceType & rightF){T::ImportData(rightF);} |
|
|
|
static bool HasColorOcf() { return false; } |
|
static bool HasCurvatureDirOcf() { return false; } |
|
static bool HasMarkOcf() { return false; } |
|
static bool HasNormalOcf() { return false; } |
|
static bool HasQualityOcf() { return false; } |
|
static bool HasWedgeTexCoordOcf() { return false; } |
|
static bool HasWedgeColorOcf() { return false; } |
|
static bool HasWedgeNormalOcf() { return false; } |
|
static bool HasFFAdjacencyOcf() { return false; } |
|
static bool HasVFAdjacencyOcf() { return false; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
inline size_t Index() const { |
|
typename T::FaceType const *tp=static_cast<typename T::FaceType const *>(this); |
|
size_t tt2=tp- &*(_ovp->begin()); |
|
return tt2; |
|
} |
|
public: |
|
// ovp Optional Vector Pointer |
|
// Pointer to the base vector where each face element is stored. |
|
// used to access to the vectors of the other optional members. |
|
vector_ocf<typename T::FaceType> *_ovp; |
|
}; |
|
|
|
} // end namespace face |
|
|
|
template < class, class,class,class > class TriMesh; |
|
|
|
namespace tri |
|
{ |
|
template < class FaceType > |
|
bool FaceVectorHasVFAdjacency(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasVFAdjacencyOcf()) return fv.IsVFAdjacencyEnabled(); |
|
else return FaceType::HasVFAdjacency(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasFFAdjacency(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasFFAdjacencyOcf()) return fv.IsFFAdjacencyEnabled(); |
|
else return FaceType::HasFFAdjacency(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasPerWedgeTexCoord(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasWedgeTexCoordOcf()) return fv.IsWedgeTexCoordEnabled(); |
|
else return FaceType::HasWedgeTexCoord(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasPerFaceColor(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasColorOcf()) return fv.IsColorEnabled(); |
|
else return FaceType::HasColor(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasPerFaceQuality(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasQualityOcf()) return fv.IsQualityEnabled(); |
|
else return FaceType::HasQuality(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasPerFaceMark(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasMarkOcf()) return fv.IsMarkEnabled(); |
|
else return FaceType::HasMark(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasPerFaceCurvatureDir(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasCurvatureDirOcf()) return fv.IsCurvatureDirEnabled(); |
|
else return FaceType::HasCurvatureDir(); |
|
} |
|
template < class FaceType > |
|
bool FaceVectorHasPerFaceNormal(const face::vector_ocf<FaceType> &fv) |
|
{ |
|
if(FaceType::HasNormalOcf()) return fv.IsNormalEnabled(); |
|
else return FaceType::HasNormal(); |
|
} |
|
template < class FaceType > |
|
void ReorderFace( std::vector<size_t> &newFaceIndex, face::vector_ocf< FaceType > &faceVec) |
|
{ |
|
faceVec.ReorderFace(newFaceIndex); |
|
} |
|
|
|
} |
|
}// end namespace vcg |
|
#endif
|
|
|