2008-12-19 11:31:56 +01:00
|
|
|
/****************************************************************************
|
|
|
|
* VCGLib o o *
|
|
|
|
* Visual and Computer Graphics Library o o *
|
|
|
|
* _ O _ *
|
|
|
|
* Copyright(C) 2004 \/)\/ *
|
|
|
|
* 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. *
|
|
|
|
* *
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
OCF = Optional Component Fast (hopefully)
|
|
|
|
compare with OCC(Optional Component Compact)
|
2012-10-25 23:29:10 +02:00
|
|
|
*/
|
|
|
|
#ifndef __VCG_MESH
|
|
|
|
#error "This file should not be included alone. It is automatically included by complex.h"
|
|
|
|
#endif
|
2008-12-19 11:31:56 +01:00
|
|
|
#ifndef __VCG_VERTEX_PLUS_COMPONENT_OCF
|
|
|
|
#define __VCG_VERTEX_PLUS_COMPONENT_OCF
|
2012-10-15 11:17:48 +02:00
|
|
|
#ifndef __VCG_MESH
|
|
|
|
#error "This file should not be included alone. It is automatically included by complex.h"
|
|
|
|
#endif
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
namespace vcg {
|
|
|
|
namespace vertex {
|
|
|
|
/*
|
|
|
|
All the Components that can be added to a vertex should be defined in the namespace vert:
|
|
|
|
|
|
|
|
*/
|
|
|
|
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:
|
2012-10-15 11:17:48 +02:00
|
|
|
vector_ocf():std::vector<VALUE_TYPE>()
|
|
|
|
{
|
|
|
|
ColorEnabled = false;
|
2010-04-20 02:57:25 +02:00
|
|
|
CurvatureEnabled = false;
|
|
|
|
CurvatureDirEnabled = false;
|
|
|
|
MarkEnabled = false;
|
2012-10-15 11:17:48 +02:00
|
|
|
NormalEnabled = false;
|
2010-04-20 02:57:25 +02:00
|
|
|
QualityEnabled = false;
|
|
|
|
RadiusEnabled = false;
|
|
|
|
TexCoordEnabled = false;
|
2012-10-15 11:17:48 +02:00
|
|
|
VFAdjacencyEnabled = false;
|
|
|
|
}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-10-15 11:17:48 +02:00
|
|
|
////////////////////////////////////////
|
|
|
|
// 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)
|
2008-12-19 11:31:56 +01:00
|
|
|
{
|
|
|
|
BaseType::push_back(v);
|
|
|
|
BaseType::back()._ovp = this;
|
|
|
|
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());
|
2009-06-29 05:33:56 +02:00
|
|
|
if (TexCoordEnabled) TV.push_back(typename VALUE_TYPE::TexCoordType());
|
2008-12-19 11:31:56 +01:00
|
|
|
if (VFAdjacencyEnabled) AV.push_back(VFAdjType());
|
|
|
|
if (CurvatureEnabled) CuV.push_back(typename VALUE_TYPE::CurvatureType());
|
|
|
|
if (CurvatureDirEnabled) CuDV.push_back(typename VALUE_TYPE::CurvatureDirType());
|
|
|
|
if (RadiusEnabled) RadiusV.push_back(typename VALUE_TYPE::RadiusType());
|
|
|
|
}
|
2012-10-15 11:17:48 +02:00
|
|
|
|
2008-12-19 11:31:56 +01:00
|
|
|
void pop_back();
|
2012-10-15 11:17:48 +02:00
|
|
|
|
2008-12-19 11:31:56 +01:00
|
|
|
void resize(const unsigned int & _size)
|
|
|
|
{
|
|
|
|
const unsigned int oldsize = BaseType::size();
|
|
|
|
BaseType::resize(_size);
|
|
|
|
if(oldsize<_size){
|
|
|
|
ThisTypeIterator firstnew = BaseType::begin();
|
|
|
|
advance(firstnew,oldsize);
|
|
|
|
_updateOVP(firstnew,(*this).end());
|
|
|
|
}
|
|
|
|
if (ColorEnabled) CV.resize(_size);
|
|
|
|
if (MarkEnabled) MV.resize(_size);
|
|
|
|
if (NormalEnabled) NV.resize(_size);
|
2009-06-29 05:33:56 +02:00
|
|
|
if (TexCoordEnabled) TV.resize(_size);
|
2008-12-19 11:31:56 +01:00
|
|
|
if (VFAdjacencyEnabled) AV.resize(_size);
|
|
|
|
if (CurvatureEnabled) CuV.resize(_size);
|
|
|
|
if (CurvatureDirEnabled) CuDV.resize(_size);
|
|
|
|
if (RadiusEnabled) RadiusV.resize(_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void reserve(const unsigned int & _size)
|
|
|
|
{
|
|
|
|
BaseType::reserve(_size);
|
2009-06-29 05:33:56 +02:00
|
|
|
if (ColorEnabled) CV.reserve(_size);
|
2008-12-19 11:31:56 +01:00
|
|
|
if (MarkEnabled) MV.reserve(_size);
|
2009-06-29 05:33:56 +02:00
|
|
|
if (NormalEnabled) NV.reserve(_size);
|
|
|
|
if (TexCoordEnabled) TV.reserve(_size);
|
2008-12-19 11:31:56 +01:00
|
|
|
if (VFAdjacencyEnabled) AV.reserve(_size);
|
|
|
|
if (CurvatureEnabled) CuV.reserve(_size);
|
|
|
|
if (CurvatureDirEnabled) CuDV.reserve(_size);
|
|
|
|
if (RadiusEnabled) RadiusV.reserve(_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void _updateOVP(ThisTypeIterator lbegin, ThisTypeIterator lend)
|
|
|
|
{
|
|
|
|
ThisTypeIterator vi;
|
|
|
|
for(vi=lbegin;vi!=lend;++vi)
|
|
|
|
(*vi)._ovp=this;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////
|
|
|
|
// Enabling Eunctions
|
|
|
|
|
|
|
|
bool IsQualityEnabled() const {return QualityEnabled;}
|
|
|
|
void EnableQuality() {
|
|
|
|
assert(VALUE_TYPE::HasQualityOcf());
|
|
|
|
QualityEnabled=true;
|
|
|
|
QV.resize((*this).size());
|
|
|
|
}
|
|
|
|
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());
|
|
|
|
}
|
|
|
|
void DisableColor() {
|
|
|
|
assert(VALUE_TYPE::HasColorOcf());
|
|
|
|
ColorEnabled=false;
|
|
|
|
CV.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsMarkEnabled() const {return MarkEnabled;}
|
|
|
|
void EnableMark() {
|
2008-12-21 02:39:46 +01:00
|
|
|
assert(VALUE_TYPE::HasMarkOcf());
|
2008-12-19 11:31:56 +01:00
|
|
|
MarkEnabled=true;
|
|
|
|
MV.resize((*this).size());
|
|
|
|
}
|
|
|
|
void DisableMark() {
|
2008-12-21 02:39:46 +01:00
|
|
|
assert(VALUE_TYPE::HasMarkOcf());
|
2008-12-19 11:31:56 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2009-10-29 18:16:41 +01:00
|
|
|
bool IsVFAdjacencyEnabled() const {return VFAdjacencyEnabled;}
|
2008-12-19 11:31:56 +01:00
|
|
|
void EnableVFAdjacency() {
|
|
|
|
assert(VALUE_TYPE::HasVFAdjacencyOcf());
|
|
|
|
VFAdjacencyEnabled=true;
|
2012-02-09 18:53:08 +01:00
|
|
|
VFAdjType zero; zero._fp=0; zero._zp=-1;
|
|
|
|
AV.resize((*this).size(),zero);
|
2008-12-19 11:31:56 +01:00
|
|
|
}
|
|
|
|
void DisableVFAdjacency() {
|
|
|
|
assert(VALUE_TYPE::HasVFAdjacencyOcf());
|
|
|
|
VFAdjacencyEnabled=false;
|
|
|
|
AV.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsCurvatureEnabled() const {return CurvatureEnabled;}
|
|
|
|
void EnableCurvature() {
|
|
|
|
assert(VALUE_TYPE::HasCurvatureOcf());
|
|
|
|
CurvatureEnabled=true;
|
|
|
|
CuV.resize((*this).size());
|
|
|
|
}
|
|
|
|
void DisableCurvature() {
|
|
|
|
assert(VALUE_TYPE::HasCurvatureOcf());
|
|
|
|
CurvatureEnabled=false;
|
|
|
|
CuV.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsCurvatureDirEnabled() const {return CurvatureDirEnabled;}
|
|
|
|
void EnableCurvatureDir() {
|
|
|
|
assert(VALUE_TYPE::HasCurvatureDirOcf());
|
|
|
|
CurvatureDirEnabled=true;
|
|
|
|
CuDV.resize((*this).size());
|
|
|
|
}
|
|
|
|
void DisableCurvatureDir() {
|
|
|
|
assert(VALUE_TYPE::HasCurvatureDirOcf());
|
|
|
|
CurvatureDirEnabled=false;
|
|
|
|
CuDV.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsRadiusEnabled() const {return RadiusEnabled;}
|
|
|
|
void EnableRadius() {
|
|
|
|
assert(VALUE_TYPE::HasRadiusOcf());
|
|
|
|
RadiusEnabled=true;
|
|
|
|
RadiusV.resize((*this).size());
|
|
|
|
}
|
|
|
|
void DisableRadius() {
|
|
|
|
assert(VALUE_TYPE::HasRadiusOcf());
|
|
|
|
RadiusEnabled=false;
|
|
|
|
RadiusV.clear();
|
|
|
|
}
|
|
|
|
|
2009-06-23 22:45:44 +02:00
|
|
|
|
|
|
|
bool IsTexCoordEnabled() const {return TexCoordEnabled;}
|
|
|
|
void EnableTexCoord() {
|
|
|
|
assert(VALUE_TYPE::HasTexCoordOcf());
|
|
|
|
TexCoordEnabled=true;
|
|
|
|
TV.resize((*this).size());
|
|
|
|
}
|
|
|
|
void DisableTexCoord() {
|
|
|
|
assert(VALUE_TYPE::HasTexCoordOcf());
|
|
|
|
TexCoordEnabled=false;
|
|
|
|
TV.clear();
|
|
|
|
}
|
2012-11-15 20:04:08 +01:00
|
|
|
|
2008-12-19 11:31:56 +01:00
|
|
|
struct VFAdjType {
|
|
|
|
typename VALUE_TYPE::FacePointer _fp ;
|
|
|
|
int _zp ;
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
2010-04-20 02:57:25 +02:00
|
|
|
std::vector<typename VALUE_TYPE::ColorType> CV;
|
|
|
|
std::vector<typename VALUE_TYPE::CurvatureType> CuV;
|
2012-10-15 11:17:48 +02:00
|
|
|
std::vector<typename VALUE_TYPE::CurvatureDirType> CuDV;
|
2010-04-20 02:57:25 +02:00
|
|
|
std::vector<int> MV;
|
|
|
|
std::vector<typename VALUE_TYPE::NormalType> NV;
|
|
|
|
std::vector<typename VALUE_TYPE::QualityType> QV;
|
2012-10-15 11:17:48 +02:00
|
|
|
std::vector<typename VALUE_TYPE::RadiusType> RadiusV;
|
|
|
|
std::vector<typename VALUE_TYPE::TexCoordType> TV;
|
|
|
|
std::vector<struct VFAdjType> AV;
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2010-04-20 02:57:25 +02:00
|
|
|
bool ColorEnabled;
|
2012-10-15 11:17:48 +02:00
|
|
|
bool CurvatureEnabled;
|
|
|
|
bool CurvatureDirEnabled;
|
2010-04-20 02:57:25 +02:00
|
|
|
bool MarkEnabled;
|
|
|
|
bool NormalEnabled;
|
|
|
|
bool QualityEnabled;
|
2012-10-15 11:17:48 +02:00
|
|
|
bool RadiusEnabled;
|
2010-04-20 02:57:25 +02:00
|
|
|
bool TexCoordEnabled;
|
|
|
|
bool VFAdjacencyEnabled;
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//template<> void EnableAttribute<typename VALUE_TYPE::NormalType>(){ NormalEnabled=true;}
|
|
|
|
|
|
|
|
/*------------------------- COORD -----------------------------------------*/
|
|
|
|
/*----------------------------- VFADJ ------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
template <class T> class VFAdjOcf: public T {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typename T::FacePointer &VFp() {
|
2008-12-19 11:31:56 +01:00
|
|
|
assert((*this).Base().VFAdjacencyEnabled);
|
|
|
|
return (*this).Base().AV[(*this).Index()]._fp;
|
|
|
|
}
|
|
|
|
typename T::FacePointer cVFp() const {
|
|
|
|
if(! (*this).Base().VFAdjacencyEnabled ) return 0;
|
|
|
|
else return (*this).Base().AV[(*this).Index()]._fp;
|
|
|
|
}
|
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
int &VFi() {
|
2010-02-22 18:37:51 +01:00
|
|
|
assert((*this).Base().VFAdjacencyEnabled);
|
|
|
|
return (*this).Base().AV[(*this).Index()]._zp;
|
|
|
|
}
|
|
|
|
int cVFi() const {
|
|
|
|
if(! (*this).Base().VFAdjacencyEnabled ) return -1;
|
|
|
|
return (*this).Base().AV[(*this).Index()]._zp;
|
|
|
|
}
|
|
|
|
template <class LeftV>
|
2010-06-16 18:24:26 +02:00
|
|
|
void ImportData(const LeftV & leftV)
|
2008-12-19 11:31:56 +01:00
|
|
|
{
|
2010-06-16 18:24:26 +02:00
|
|
|
T::ImportData(leftV);
|
2008-12-19 11:31:56 +01:00
|
|
|
}
|
|
|
|
|
2010-03-03 17:01:39 +01:00
|
|
|
static bool HasVFAdjacency() { return true; }
|
|
|
|
static bool HasVFAdjacencyOcf() { return true; }
|
2012-07-02 16:38:10 +02:00
|
|
|
static bool IsVFAdjacencyEnabled(const typename T::VertexType *vp) {return vp->Base().VFAdjacencyEnabled;}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-07-02 16:38:10 +02:00
|
|
|
static void Name(std::vector<std::string> & name){name.push_back(std::string("VFAdjOcf"));T::Name(name);}
|
2008-12-19 11:31:56 +01:00
|
|
|
private:
|
|
|
|
};
|
|
|
|
|
|
|
|
/*------------------------- Normal -----------------------------------------*/
|
|
|
|
|
|
|
|
template <class A, class T> class NormalOcf: public T {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef A NormalType;
|
|
|
|
static bool HasNormal() { return true; }
|
|
|
|
static bool HasNormalOcf() { return true; }
|
|
|
|
|
|
|
|
NormalType &N() { assert((*this).Base().NormalEnabled); return (*this).Base().NV[(*this).Index()]; }
|
|
|
|
NormalType cN() const { assert((*this).Base().NormalEnabled); return (*this).Base().NV[(*this).Index()]; }
|
|
|
|
|
|
|
|
template <class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV){
|
|
|
|
if((*this).Base().NormalEnabled && LeftV::HasNormal() )
|
|
|
|
N().Import(leftV.cN());
|
|
|
|
T::ImportData(leftV);}
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
2012-07-02 16:38:10 +02:00
|
|
|
template <class T> class Normal3sOcf: public NormalOcf<vcg::Point3s, T> {public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal3sOcf"));T::Name(name);}};
|
|
|
|
template <class T> class Normal3fOcf: public NormalOcf<vcg::Point3f, T> {public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal3fOcf"));T::Name(name);}};
|
|
|
|
template <class T> class Normal3dOcf: public NormalOcf<vcg::Point3d, T> {public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Normal3dOcf"));T::Name(name);}};
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
///*-------------------------- COLOR ----------------------------------*/
|
|
|
|
|
|
|
|
template <class A, class T> class ColorOcf: public T {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef A ColorType;
|
|
|
|
ColorType &C() { assert((*this).Base().ColorEnabled); return (*this).Base().CV[(*this).Index()]; }
|
|
|
|
ColorType cC() const { assert((*this).Base().ColorEnabled); return (*this).Base().CV[(*this).Index()]; }
|
|
|
|
template <class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV)
|
|
|
|
{
|
|
|
|
if((*this).Base().ColorEnabled && LeftV::HasColor() )
|
|
|
|
C() = leftV.cC();
|
|
|
|
T::ImportData(leftV);
|
|
|
|
}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
static bool HasColor() { return true; }
|
|
|
|
static bool HasColorOcf() { assert(!T::HasColorOcf()); return true; }
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
2012-07-02 16:38:10 +02:00
|
|
|
template <class T> class Color4bOcf: public ColorOcf<vcg::Color4b, T> {
|
2012-08-22 20:36:59 +02:00
|
|
|
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Color4bOcf"));T::Name(name);}
|
2012-07-02 16:38:10 +02:00
|
|
|
};
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
///*-------------------------- QUALITY ----------------------------------*/
|
|
|
|
|
|
|
|
template <class A, class T> class QualityOcf: public T {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef A QualityType;
|
|
|
|
QualityType &Q() { assert((*this).Base().QualityEnabled); return (*this).Base().QV[(*this).Index()]; }
|
|
|
|
QualityType cQ() const { assert((*this).Base().QualityEnabled); return (*this).Base().QV[(*this).Index()]; }
|
|
|
|
template <class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV)
|
|
|
|
{
|
|
|
|
if((*this).Base().QualityEnabled && LeftV::HasQuality() ) // copy the data only if they are enabled in both vertices
|
|
|
|
Q() = leftV.cQ();
|
|
|
|
T::ImportData(leftV);
|
|
|
|
}
|
|
|
|
static bool HasQuality() { return true; }
|
|
|
|
static bool HasQualityOcf() { assert(!T::HasQualityOcf()); return true; }
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
2012-07-02 16:38:10 +02:00
|
|
|
template <class T> class QualityfOcf: public QualityOcf<float, T> {
|
|
|
|
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("QualityfOcf"));T::Name(name);}
|
|
|
|
};
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2009-06-23 22:45:44 +02:00
|
|
|
|
|
|
|
///*-------------------------- TEXTURE ----------------------------------*/
|
|
|
|
|
|
|
|
template <class A, class TT> class TexCoordOcf: public TT {
|
|
|
|
public:
|
|
|
|
typedef A TexCoordType;
|
2012-11-15 20:04:08 +01:00
|
|
|
TexCoordType &T() { assert((*this).Base().TexCoordEnabled); return (*this).Base().TV[(*this).Index()]; }
|
|
|
|
TexCoordType cT() const { assert((*this).Base().TexCoordEnabled); return (*this).Base().TV[(*this).Index()]; }
|
|
|
|
template < class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV)
|
|
|
|
{
|
|
|
|
if((*this).Base().TexCoordEnabled && LeftV::HasTexCoord()) // copy the data only if they are enabled in both vertices
|
|
|
|
T() = leftV.cT();
|
|
|
|
TT::ImportData(leftV);
|
|
|
|
}
|
|
|
|
static bool HasTexCoord() { return true; }
|
|
|
|
static bool HasTexCoordOcf() { assert(!TT::HasTexCoordOcf()); return true; }
|
2009-06-23 22:45:44 +02:00
|
|
|
};
|
|
|
|
|
2012-07-02 16:38:10 +02:00
|
|
|
template <class T> class TexCoordfOcf: public TexCoordOcf<TexCoord2<float,1>, T> {
|
2012-07-03 13:12:21 +02:00
|
|
|
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("TexCoordfOcf"));T::Name(name);}
|
2012-07-02 16:38:10 +02:00
|
|
|
};
|
2009-06-23 22:45:44 +02:00
|
|
|
|
2008-12-19 11:31:56 +01:00
|
|
|
///*-------------------------- MARK ----------------------------------*/
|
|
|
|
|
|
|
|
template <class T> class MarkOcf: public T {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef int MarkType;
|
|
|
|
inline int &IMark() { assert((*this).Base().MarkEnabled); return (*this).Base().MV[(*this).Index()]; }
|
|
|
|
inline int cIMark() const { assert((*this).Base().MarkEnabled); return (*this).Base().MV[(*this).Index()]; }
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
template <class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV)
|
|
|
|
{
|
|
|
|
if((*this).Base().MarkEnabled && LeftV::HasMark()) // copy the data only if they are enabled in both vertices
|
|
|
|
IMark() = leftV.cIMark();
|
|
|
|
T::ImportData(leftV);
|
|
|
|
}
|
|
|
|
static bool HasMark() { return true; }
|
|
|
|
static bool HasMarkOcf() { return true; }
|
|
|
|
inline void InitIMark() { IMark() = 0; }
|
|
|
|
static void Name(std::vector<std::string> & name){name.push_back(std::string("IMark"));T::Name(name);}
|
2012-07-02 16:38:10 +02:00
|
|
|
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
///*-------------------------- CURVATURE ----------------------------------*/
|
|
|
|
|
|
|
|
template <class A, class TT> class CurvatureOcf: public TT {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef Point2<A> CurvatureType;
|
|
|
|
typedef typename CurvatureType::ScalarType ScalarType;
|
2010-03-03 17:01:39 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
ScalarType &Kh(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][0];}
|
|
|
|
ScalarType &Kg(){ assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][1];}
|
|
|
|
ScalarType cKh() const { assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][0];}
|
|
|
|
ScalarType cKg() const { assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][1];}
|
2012-07-02 16:38:10 +02:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
template <class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV){
|
|
|
|
if((*this).Base().CurvatureEnabled && LeftV::HasCurvature())
|
|
|
|
{
|
|
|
|
(*this).Base().CuV[(*this).Index()][0] = leftV.cKh();
|
|
|
|
(*this).Base().CuV[(*this).Index()][1] = leftV.cKg();
|
|
|
|
}
|
|
|
|
TT::ImportData(leftV);
|
|
|
|
}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
static bool HasCurvature() { return true; }
|
|
|
|
static bool HasCurvatureOcf() { return true; }
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
2012-07-03 13:12:21 +02:00
|
|
|
template <class T> class CurvaturefOcf: public CurvatureOcf<float, T> {public: static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvaturefOcf"));T::Name(name);} };
|
|
|
|
template <class T> class CurvaturedOcf: public CurvatureOcf<double, T> {public: static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvaturedOcf"));T::Name(name);} };
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
///*-------------------------- CURVATURE DIR ----------------------------------*/
|
|
|
|
|
|
|
|
template <class S>
|
|
|
|
struct CurvatureDirTypeOcf{
|
|
|
|
typedef Point3<S> VecType;
|
|
|
|
typedef S ScalarType;
|
|
|
|
CurvatureDirTypeOcf () {}
|
|
|
|
Point3<S>max_dir,min_dir;
|
|
|
|
S k1,k2;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <class A, class TT> class CurvatureDirOcf: public TT {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef A CurvatureDirType;
|
|
|
|
typedef typename CurvatureDirType::VecType VecType;
|
|
|
|
typedef typename CurvatureDirType::ScalarType ScalarType;
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
VecType &PD1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;}
|
|
|
|
VecType &PD2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;}
|
|
|
|
VecType cPD1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;}
|
|
|
|
VecType cPD2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
ScalarType &K1() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;}
|
|
|
|
ScalarType &K2() { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;}
|
|
|
|
ScalarType cK1() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;}
|
|
|
|
ScalarType cK2() const { assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2010-03-03 17:01:39 +01:00
|
|
|
template <class LeftV>
|
2012-11-15 20:04:08 +01:00
|
|
|
void ImportData(const LeftV & leftV){
|
|
|
|
if((*this).Base().IsCurvatureDirEnabled() && LeftV::HasCurvatureDir())
|
|
|
|
{
|
|
|
|
(*this).PD1() = leftV.cPD1();
|
|
|
|
(*this).PD2() = leftV.cPD2();
|
|
|
|
(*this).K1() = leftV.cK1();
|
|
|
|
(*this).K2() = leftV.cK2();
|
|
|
|
}
|
|
|
|
TT::ImportData(leftV);
|
2010-03-03 17:01:39 +01:00
|
|
|
}
|
|
|
|
static bool HasCurvatureDir() { return true; }
|
|
|
|
static bool HasCurvatureDirOcf() { return true; }
|
|
|
|
static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirOcf"));TT::Name(name);}
|
2012-11-15 20:04:08 +01:00
|
|
|
};
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
template <class T> class CurvatureDirfOcf: public CurvatureDirOcf<CurvatureDirTypeOcf<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<CurvatureDirTypeOcf<double>, T> {
|
|
|
|
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureDirdOcf"));T::Name(name);}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
///*-------------------------- RADIUS ----------------------------------*/
|
|
|
|
|
|
|
|
template <class A, class TT> class RadiusOcf: public TT {
|
|
|
|
public:
|
2012-11-15 20:04:08 +01:00
|
|
|
typedef A RadiusType;
|
|
|
|
typedef RadiusType ScalarType;
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
RadiusType &R() { assert((*this).Base().RadiusEnabled); return (*this).Base().RadiusV[(*this).Index()];}
|
|
|
|
RadiusType cR() const { assert((*this).Base().RadiusEnabled); return (*this).Base().RadiusV[(*this).Index()];}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
template <class LeftV>
|
|
|
|
void ImportData(const LeftV & leftV)
|
|
|
|
{
|
|
|
|
if ((*this).Base().RadiusEnabled && LeftV::HasRadius())
|
|
|
|
(*this).Base().RadiusV[(*this).Index()] = leftV.cR();
|
|
|
|
TT::ImportData(leftV);
|
|
|
|
}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-11-15 20:04:08 +01:00
|
|
|
static bool HasRadius() { return true; }
|
|
|
|
static bool HasRadiusOcf() { return true; }
|
|
|
|
static void Name(std::vector<std::string> & name){name.push_back(std::string("RadiusOcf")); TT::Name(name);}
|
2008-12-19 11:31:56 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class T> class RadiusfOcf: public RadiusOcf<float, T> {};
|
|
|
|
template <class T> class RadiusdOcf: public RadiusOcf<double, T> {};
|
|
|
|
|
|
|
|
|
|
|
|
///*-------------------------- InfoOpt ----------------------------------*/
|
|
|
|
|
|
|
|
template < class T> class InfoOcf: public T {
|
|
|
|
public:
|
2010-02-11 01:14:35 +01:00
|
|
|
// You should never ever try to copy a vertex that has OCF stuff.
|
2010-06-16 18:24:26 +02:00
|
|
|
// use ImportData function.
|
2010-02-22 18:37:51 +01:00
|
|
|
inline InfoOcf &operator=(const InfoOcf & /*other*/) {
|
2010-02-11 01:14:35 +01:00
|
|
|
assert(0); return *this;
|
|
|
|
}
|
|
|
|
|
[ Changes in definition of TriMesh: PART I ]
Note for the developers: the change to make to existing projects is very little
but strictly necessary to compile. This change IS NOT backward compliant.
==== OLD ==== way to define a TriMesh:
// forward declarations
class MyVertex;
class MyEdge;
class MyFace;
class MyVertex: public VertexSimp2 < MyVertex, MyEdge, MyFace, vertex::Coord3f,...other components>{};
class MyFace: public FaceSimp2 < MyVertex, MyEdge, MyFace, face::VertexRef,...other components>{};
class MyMesh: public TriMesh<vector<MyVertex>,vector<MyFace> >{};
==== NEW ==== way to define a TriMesh:
// forward declarations
class MyVertex;
class MyEdge;
class MyFace;
// declaration of which types is used as VertexType, which type is used as FaceType and so on...
class MyUsedTypes: public vcg::UsedType < vcg::Use<MyVertex>::AsVertexType,
vcg::Use<MyFace>::AsFaceType>{};
class MyVertex: public Vertex < MyUsedTypes, vertex::Coord3f,...other components>{};
class MyFace: public Face < MyUsedTypes, face::VertexRef,...other components>{};
class MyMesh: public TriMesh<vector<MyVertex>,vector<MyFace> >{};
===== classes introduced
[vcg::UsedType] : it is a class containing all the types that must be passed to the definition of Vertex, Face, Edge... This
class replaces the list of typenames to pass as first templates and the need to specify the maximal simplicial. So
<MyVertex, MyEdge, MyFace becomes <MyUsedTypes<
and
VertexSimp2 becomes Vertex
[vcg::Use] : an auxiliary class to give a simple way to specify the role of a type
Note 2: the order of templates parameters to vcg::UsedTypes is unimportant, e.g:
class MyUsedTypes: public vcg::UsedType <vcg::Use<MyVertex>::AsVertexType,
vcg::Use<MyEdge>::AsEdgeType,
vcg::Use<MyFace>::AsFaceType>{};
is the same as:
class MyUsedTypes: public vcg::UsedType <vcg::Use<MyFace>::AsFaceType,
vcg::Use<MyEdge>::AsEdgeType,
vcg::Use<MyVertex>::AsVertexType>{};
Note 3: you only need to specify the type you use. If you do not have edges you do not need
to include vcg::Use<MyEdge>::AsEdgeType in the template list of UsedTypes.
==== the Part II will be a tiny change to the class TriMesh it self.
2010-03-15 11:42:52 +01:00
|
|
|
vector_ocf<typename T::VertexType> &Base() const { return *_ovp;}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
inline int Index() const {
|
[ Changes in definition of TriMesh: PART I ]
Note for the developers: the change to make to existing projects is very little
but strictly necessary to compile. This change IS NOT backward compliant.
==== OLD ==== way to define a TriMesh:
// forward declarations
class MyVertex;
class MyEdge;
class MyFace;
class MyVertex: public VertexSimp2 < MyVertex, MyEdge, MyFace, vertex::Coord3f,...other components>{};
class MyFace: public FaceSimp2 < MyVertex, MyEdge, MyFace, face::VertexRef,...other components>{};
class MyMesh: public TriMesh<vector<MyVertex>,vector<MyFace> >{};
==== NEW ==== way to define a TriMesh:
// forward declarations
class MyVertex;
class MyEdge;
class MyFace;
// declaration of which types is used as VertexType, which type is used as FaceType and so on...
class MyUsedTypes: public vcg::UsedType < vcg::Use<MyVertex>::AsVertexType,
vcg::Use<MyFace>::AsFaceType>{};
class MyVertex: public Vertex < MyUsedTypes, vertex::Coord3f,...other components>{};
class MyFace: public Face < MyUsedTypes, face::VertexRef,...other components>{};
class MyMesh: public TriMesh<vector<MyVertex>,vector<MyFace> >{};
===== classes introduced
[vcg::UsedType] : it is a class containing all the types that must be passed to the definition of Vertex, Face, Edge... This
class replaces the list of typenames to pass as first templates and the need to specify the maximal simplicial. So
<MyVertex, MyEdge, MyFace becomes <MyUsedTypes<
and
VertexSimp2 becomes Vertex
[vcg::Use] : an auxiliary class to give a simple way to specify the role of a type
Note 2: the order of templates parameters to vcg::UsedTypes is unimportant, e.g:
class MyUsedTypes: public vcg::UsedType <vcg::Use<MyVertex>::AsVertexType,
vcg::Use<MyEdge>::AsEdgeType,
vcg::Use<MyFace>::AsFaceType>{};
is the same as:
class MyUsedTypes: public vcg::UsedType <vcg::Use<MyFace>::AsFaceType,
vcg::Use<MyEdge>::AsEdgeType,
vcg::Use<MyVertex>::AsVertexType>{};
Note 3: you only need to specify the type you use. If you do not have edges you do not need
to include vcg::Use<MyEdge>::AsEdgeType in the template list of UsedTypes.
==== the Part II will be a tiny change to the class TriMesh it self.
2010-03-15 11:42:52 +01:00
|
|
|
typename T::VertexType const *tp=static_cast<typename T::VertexType const*>(this);
|
2008-12-19 11:31:56 +01:00
|
|
|
int tt2=tp- &*(_ovp->begin());
|
|
|
|
return tt2;
|
|
|
|
}
|
|
|
|
public:
|
[ Changes in definition of TriMesh: PART I ]
Note for the developers: the change to make to existing projects is very little
but strictly necessary to compile. This change IS NOT backward compliant.
==== OLD ==== way to define a TriMesh:
// forward declarations
class MyVertex;
class MyEdge;
class MyFace;
class MyVertex: public VertexSimp2 < MyVertex, MyEdge, MyFace, vertex::Coord3f,...other components>{};
class MyFace: public FaceSimp2 < MyVertex, MyEdge, MyFace, face::VertexRef,...other components>{};
class MyMesh: public TriMesh<vector<MyVertex>,vector<MyFace> >{};
==== NEW ==== way to define a TriMesh:
// forward declarations
class MyVertex;
class MyEdge;
class MyFace;
// declaration of which types is used as VertexType, which type is used as FaceType and so on...
class MyUsedTypes: public vcg::UsedType < vcg::Use<MyVertex>::AsVertexType,
vcg::Use<MyFace>::AsFaceType>{};
class MyVertex: public Vertex < MyUsedTypes, vertex::Coord3f,...other components>{};
class MyFace: public Face < MyUsedTypes, face::VertexRef,...other components>{};
class MyMesh: public TriMesh<vector<MyVertex>,vector<MyFace> >{};
===== classes introduced
[vcg::UsedType] : it is a class containing all the types that must be passed to the definition of Vertex, Face, Edge... This
class replaces the list of typenames to pass as first templates and the need to specify the maximal simplicial. So
<MyVertex, MyEdge, MyFace becomes <MyUsedTypes<
and
VertexSimp2 becomes Vertex
[vcg::Use] : an auxiliary class to give a simple way to specify the role of a type
Note 2: the order of templates parameters to vcg::UsedTypes is unimportant, e.g:
class MyUsedTypes: public vcg::UsedType <vcg::Use<MyVertex>::AsVertexType,
vcg::Use<MyEdge>::AsEdgeType,
vcg::Use<MyFace>::AsFaceType>{};
is the same as:
class MyUsedTypes: public vcg::UsedType <vcg::Use<MyFace>::AsFaceType,
vcg::Use<MyEdge>::AsEdgeType,
vcg::Use<MyVertex>::AsVertexType>{};
Note 3: you only need to specify the type you use. If you do not have edges you do not need
to include vcg::Use<MyEdge>::AsEdgeType in the template list of UsedTypes.
==== the Part II will be a tiny change to the class TriMesh it self.
2010-03-15 11:42:52 +01:00
|
|
|
vector_ocf<typename T::VertexType> *_ovp;
|
2008-12-19 11:31:56 +01:00
|
|
|
|
|
|
|
static bool HasQualityOcf() { return false; }
|
2012-11-15 20:04:08 +01:00
|
|
|
static bool HasRadiusOcf() { return false; }
|
|
|
|
static bool HasColorOcf() { return false; }
|
|
|
|
static bool HasNormalOcf() { return false; }
|
|
|
|
static bool HasCurvatureOcf() { return false; }
|
|
|
|
static bool HasCurvatureDirOcf() { return false; }
|
2009-06-23 22:45:44 +02:00
|
|
|
static bool HasTexCoordOcf() { return false; }
|
2008-12-19 11:31:56 +01:00
|
|
|
static bool HasVFAdjacencyOcf() { return false; }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} // end namespace vert
|
|
|
|
|
|
|
|
|
|
|
|
namespace tri
|
|
|
|
{
|
Corrected a significant bug in the reflection types for ocf components.
Changed the basic reflection mechanism: Instead of having a function templates over all the four containers now we template over Trimesh and we rely on a second function templated on face/vert that wants a vector<face> ; this second function only is eventually overloaded by another function that needs a vector_ocf of faces.
That is Before we had:
- in complex.h
template < class CType0, class CType1, class CType2 , class CType3>
bool HasPerFaceVFAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::FaceContainer::value_type::HasVFAdjacency();}
- in the component_ocf.h
template < class VertContainerType, class FaceType, class Container1, class Container2 >
bool HasPerFaceVFAdjacency (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, Container1, Container2 > & m)
{
if(FaceType::HasVFAdjacencyOcf()) return m.face.IsVFAdjacencyEnabled();
else return FaceType::FaceType::HasVFAdjacency();
}
While now we have:
- in complex.h
template < class FaceType > bool FaceVectorHasPerFaceVFAdjacency (const std::vector<FaceType > &) { return FaceType::HasVFAdjacency(); }
template < class TriMeshType> bool HasPerFaceVFAdjacency (const TriMeshType &m) { return tri::FaceVectorHasPerFaceVFAdjacency (m.vert); }
- and in component_ocf.h
template < class FaceType >
bool FaceVectorHasPerFaceVFAdjacency(const face::vector_ocf<FaceType> &fv)
{
if(FaceType::HasVFAdjacencyOcf()) return fv.IsVFAdjacencyEnabled();
else return FaceType::HasVFAdjacency();
}
2012-03-31 03:16:58 +02:00
|
|
|
template < class VertexType >
|
2012-11-14 13:37:18 +01:00
|
|
|
bool VertexVectorHasVFAdjacency(const vertex::vector_ocf<VertexType> &fv)
|
Corrected a significant bug in the reflection types for ocf components.
Changed the basic reflection mechanism: Instead of having a function templates over all the four containers now we template over Trimesh and we rely on a second function templated on face/vert that wants a vector<face> ; this second function only is eventually overloaded by another function that needs a vector_ocf of faces.
That is Before we had:
- in complex.h
template < class CType0, class CType1, class CType2 , class CType3>
bool HasPerFaceVFAdjacency (const TriMesh < CType0, CType1, CType2, CType3> & /*m*/) {return TriMesh < CType0 , CType1, CType2, CType3>::FaceContainer::value_type::HasVFAdjacency();}
- in the component_ocf.h
template < class VertContainerType, class FaceType, class Container1, class Container2 >
bool HasPerFaceVFAdjacency (const TriMesh < VertContainerType , face::vector_ocf< FaceType >, Container1, Container2 > & m)
{
if(FaceType::HasVFAdjacencyOcf()) return m.face.IsVFAdjacencyEnabled();
else return FaceType::FaceType::HasVFAdjacency();
}
While now we have:
- in complex.h
template < class FaceType > bool FaceVectorHasPerFaceVFAdjacency (const std::vector<FaceType > &) { return FaceType::HasVFAdjacency(); }
template < class TriMeshType> bool HasPerFaceVFAdjacency (const TriMeshType &m) { return tri::FaceVectorHasPerFaceVFAdjacency (m.vert); }
- and in component_ocf.h
template < class FaceType >
bool FaceVectorHasPerFaceVFAdjacency(const face::vector_ocf<FaceType> &fv)
{
if(FaceType::HasVFAdjacencyOcf()) return fv.IsVFAdjacencyEnabled();
else return FaceType::HasVFAdjacency();
}
2012-03-31 03:16:58 +02:00
|
|
|
{
|
|
|
|
if(VertexType::HasVFAdjacencyOcf()) return fv.IsVFAdjacencyEnabled();
|
|
|
|
else return VertexType::HasVFAdjacency();
|
|
|
|
}
|
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexRadius(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasRadiusOcf()) return fv.IsRadiusEnabled();
|
|
|
|
else return VertexType::HasRadius();
|
|
|
|
}
|
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexQuality(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasQualityOcf()) return fv.IsQualityEnabled();
|
|
|
|
else return VertexType::HasQuality();
|
|
|
|
}
|
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexNormal(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasNormalOcf()) return fv.IsNormalEnabled();
|
|
|
|
else return VertexType::HasNormal();
|
|
|
|
}
|
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexColor(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasColorOcf()) return fv.IsColorEnabled();
|
|
|
|
else return VertexType::HasColor();
|
|
|
|
}
|
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexCurvature(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasCurvatureOcf()) return fv.IsCurvatureEnabled();
|
|
|
|
else return VertexType::HasCurvature();
|
|
|
|
}
|
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexCurvatureDir(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasCurvatureDirOcf()) return fv.IsCurvatureDirEnabled();
|
|
|
|
else return VertexType::HasCurvatureDir();
|
|
|
|
}
|
2008-12-19 11:31:56 +01:00
|
|
|
|
2012-04-10 18:47:15 +02:00
|
|
|
template < class VertexType >
|
|
|
|
bool VertexVectorHasPerVertexTexCoord(const vertex::vector_ocf<VertexType> &fv)
|
|
|
|
{
|
|
|
|
if(VertexType::HasTexCoordOcf()) return fv.IsTexCoordEnabled();
|
|
|
|
else return VertexType::HasTexCoord();
|
|
|
|
}
|
2008-12-19 11:31:56 +01:00
|
|
|
}
|
|
|
|
}// end namespace vcg
|
|
|
|
#endif
|