vcglib/vcg/simplex/vertex/component_ocf.h

691 lines
23 KiB
C
Raw Normal View History

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. *
* *
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.16 2008/04/03 23:15:40 cignoni
added optional mark and cleaned up some nasty type bugs.
Revision 1.15 2008/03/17 11:39:15 ganovelli
added curvature and curvatruredir (compiled .net 2005 and gcc)
Revision 1.14 2008/03/11 09:22:07 cignoni
Completed the garbage collecting functions CompactVertexVector and CompactFaceVector.
Revision 1.13 2008/02/05 20:42:43 cignoni
Other small typos
Revision 1.12 2008/02/04 21:26:49 ganovelli
added ImportData which imports all local attributes into vertexplus and faceplus.
2008-12-19 11:31:56 +01:00
A local attribute is everything (N(), C(), Q()....) except pointers to other simplices
(i.e. FFAdj, VFAdj, VertexRef) which are set to NULL.
Added some function for const attributes
Revision 1.11 2007/12/11 18:25:31 cignoni
added missing include limits
Revision 1.10 2007/12/11 11:36:03 cignoni
Added the CompactVertexVector garbage collecting function.
Revision 1.9 2006/12/11 23:42:00 ganovelli
bug Index()() instead of Index()
Revision 1.8 2006/12/04 11:17:42 ganovelli
added forward declaration of TriMesh
Revision 1.7 2006/11/07 17:22:52 cignoni
many gcc compiling issues
Revision 1.6 2006/11/07 15:13:57 zifnab1974
Necessary changes for compilation with gcc 3.4.6. Especially the hash function is a problem
Revision 1.5 2006/11/07 11:29:24 cignoni
Corrected some errors in the reflections Has*** functions
Revision 1.4 2006/10/31 16:02:59 ganovelli
vesione 2005 compliant
Revision 1.3 2006/02/28 11:59:55 ponchio
g++ compliance:
begin() -> (*this).begin() and for end(), size(), Base(), Index()
Revision 1.2 2005/12/12 11:17:32 cignoni
Corrected update function, now only the needed simplexes should be updated.
Revision 1.1 2005/10/14 15:07:59 cignoni
First Really Working version
****************************************************************************/
/*
Note
OCF = Optional Component Fast (hopefully)
compare with OCC(Optional Component Compact)
Mainly the trick here is to store a base pointer in each simplex...
****************************************************************************/
#ifndef __VCG_VERTEX_PLUS_COMPONENT_OCF
#define __VCG_VERTEX_PLUS_COMPONENT_OCF
#include <vcg/simplex/vertex/component.h>
#include <vector>
#include <limits>
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:
vector_ocf():std::vector<VALUE_TYPE>(){
ColorEnabled = false;
CurvatureEnabled = false;
CurvatureDirEnabled = false;
MarkEnabled = false;
2008-12-19 11:31:56 +01:00
NormalEnabled = false;
QualityEnabled = false;
RadiusEnabled = false;
TexCoordEnabled = false;
2008-12-19 11:31:56 +01:00
VFAdjacencyEnabled = false;
}
// override di tutte le funzioni che possono spostare
// l'allocazione in memoria del container
void push_back(const VALUE_TYPE & v)
{
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());
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());
}
void pop_back();
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);
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);
if (ColorEnabled) CV.reserve(_size);
2008-12-19 11:31:56 +01:00
if (MarkEnabled) MV.reserve(_size);
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() {
assert(VALUE_TYPE::HasMarkOcf());
2008-12-19 11:31:56 +01:00
MarkEnabled=true;
MV.resize((*this).size());
}
void DisableMark() {
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();
}
bool IsVFAdjacencyEnabled() const {return VFAdjacencyEnabled;}
2008-12-19 11:31:56 +01:00
void EnableVFAdjacency() {
assert(VALUE_TYPE::HasVFAdjacencyOcf());
VFAdjacencyEnabled=true;
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();
}
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();
}
2008-12-19 11:31:56 +01:00
struct VFAdjType {
typename VALUE_TYPE::FacePointer _fp ;
int _zp ;
};
public:
std::vector<typename VALUE_TYPE::ColorType> CV;
std::vector<typename VALUE_TYPE::CurvatureType> CuV;
2008-12-19 11:31:56 +01:00
std::vector<typename VALUE_TYPE::CurvatureDirType> CuDV;
std::vector<int> MV;
std::vector<typename VALUE_TYPE::NormalType> NV;
std::vector<typename VALUE_TYPE::QualityType> QV;
2008-12-19 11:31:56 +01:00
std::vector<typename VALUE_TYPE::RadiusType> RadiusV;
std::vector<typename VALUE_TYPE::TexCoordType> TV;
2008-12-19 11:31:56 +01:00
std::vector<struct VFAdjType> AV;
bool ColorEnabled;
2008-12-19 11:31:56 +01:00
bool CurvatureEnabled;
bool CurvatureDirEnabled;
bool MarkEnabled;
bool NormalEnabled;
bool QualityEnabled;
2008-12-19 11:31:56 +01:00
bool RadiusEnabled;
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:
typename T::FacePointer &VFp() {
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;
}
int &VFi() {
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>
void ImportData(const LeftV & leftV)
2008-12-19 11:31:56 +01:00
{
T::ImportData(leftV);
2008-12-19 11:31:56 +01:00
}
static bool HasVFAdjacency() { return true; }
static bool HasVFAdjacencyOcf() { return true; }
[ 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
static bool IsVFAdjacencyEnabled(const typename T::VertexType *vp) {return vp->Base().VFAdjacencyEnabled;}
2008-12-19 11:31:56 +01:00
private:
};
/*------------------------- Normal -----------------------------------------*/
template <class A, class T> class NormalOcf: public T {
public:
typedef A NormalType;
static bool HasNormal() { return true; }
static bool HasNormalOcf() { return true; }
NormalType &N() {
// you cannot use Normals before enabling them with: yourmesh.vert.EnableNormal()
assert((*this).Base().NormalEnabled);
return (*this).Base().NV[(*this).Index()]; }
const NormalType &N() const {
// you cannot use Normals before enabling them with: yourmesh.vert.EnableNormal()
assert((*this).Base().NormalEnabled);
return (*this).Base().NV[(*this).Index()]; }
2009-06-28 05:18:49 +02:00
const NormalType &cN() const {
// you cannot use Normals before enabling them with: yourmesh.vert.EnableNormal()
assert((*this).Base().NormalEnabled);
return (*this).Base().NV[(*this).Index()]; }
2008-12-19 11:31:56 +01:00
template <class LeftV>
void ImportData(const LeftV & leftV){
2008-12-19 11:31:56 +01:00
if((*this).Base().NormalEnabled && leftV.Base().NormalEnabled ) // copy the data only if they are enabled in both vertices
N().Import(leftV.cN());
T::ImportData(leftV);}
2008-12-19 11:31:56 +01:00
};
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> {};
///*-------------------------- COLOR ----------------------------------*/
template <class A, class T> class ColorOcf: public T {
public:
typedef A ColorType;
2009-06-28 05:18:49 +02:00
ColorType &C() { assert((*this).Base().ColorEnabled); return (*this).Base().CV[(*this).Index()]; }
2008-12-19 11:31:56 +01:00
const ColorType &cC() const { assert((*this).Base().ColorEnabled); return (*this).Base().CV[(*this).Index()]; }
template <class LeftV>
void ImportData(const LeftV & leftV)
2008-12-19 11:31:56 +01:00
{
if((*this).Base().ColorEnabled && leftV.Base().ColorEnabled ) // copy the data only if they are enabled in both vertices
C() = leftV.cC();
T::ImportData(leftV);
2008-12-19 11:31:56 +01:00
}
static bool HasColor() { return true; }
static bool HasColorOcf() { assert(!T::HasColorOcf()); return true; }
};
template <class T> class Color4bOcf: public ColorOcf<vcg::Color4b, T> {};
///*-------------------------- 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()]; }
2010-11-06 17:38:15 +01:00
const QualityType &cQ() const { assert((*this).Base().QualityEnabled); return (*this).Base().QV[(*this).Index()]; }
2008-12-19 11:31:56 +01:00
template <class LeftV>
void ImportData(const LeftV & leftV)
2008-12-19 11:31:56 +01:00
{
// if((*this).Base().QualityEnabled && leftV.Base().QualityEnabled ) // copy the data only if they are enabled in both vertices
if((*this).Base().QualityEnabled && leftV.HasQuality() ) // copy the data only if they are enabled in both vertices
2008-12-19 11:31:56 +01:00
Q() = leftV.cQ();
T::ImportData(leftV);
2008-12-19 11:31:56 +01:00
}
static bool HasQuality() { return true; }
static bool HasQualityOcf() { assert(!T::HasQualityOcf()); return true; }
};
template <class T> class QualityfOcf: public QualityOcf<float, T> {};
///*-------------------------- TEXTURE ----------------------------------*/
template <class A, class TT> class TexCoordOcf: public TT {
public:
typedef A TexCoordType;
TexCoordType &T() { assert((*this).Base().TexCoordEnabled); return (*this).Base().TV[(*this).Index()]; }
const 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.Base().TexCoordEnabled ) // WRONG I do not know anything about leftV!
if((*this).Base().TexCoordEnabled) // 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; }
};
template <class T> class TexCoordfOcf: public TexCoordOcf<TexCoord2<float,1>, T> {};
2008-12-19 11:31:56 +01:00
///*-------------------------- MARK ----------------------------------*/
template <class T> class MarkOcf: public T {
public:
typedef int MarkType;
2008-12-19 11:31:56 +01:00
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()];
}
template <class LeftV>
void ImportData(const LeftV & leftV)
2008-12-19 11:31:56 +01:00
{
//if((*this).Base().MarkEnabled && leftV.Base().MarkEnabled ) // WRONG I do not know anything about leftV!
if((*this).Base().MarkEnabled) // copy the data only if they are enabled in both vertices
2008-12-19 11:31:56 +01:00
IMark() = leftV.IMark();
T::ImportData(leftV);
2008-12-19 11:31:56 +01:00
}
static bool HasMark() { return true; }
static bool HasMarkOcf() { return true; }
2008-12-19 11:31:56 +01:00
inline void InitIMark() { IMark() = 0; }
};
///*-------------------------- CURVATURE ----------------------------------*/
template <class A, class TT> class CurvatureOcf: public TT {
public:
typedef Point2<A> CurvatureType;
typedef typename CurvatureType::ScalarType ScalarType;
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];}
const ScalarType &cKh() const { assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][0];}
const ScalarType &cKg() const { assert((*this).Base().CurvatureEnabled); return (*this).Base().CuV[(*this).Index()][1];}
template <class LeftV>
void ImportData(const LeftV & leftV){
// if((*this).Base().CurvatureEnabled && leftV.Base().CurvatureEnabled ) // WRONG I do not know anything about leftV!
if((*this).Base().CurvatureEnabled && LeftV::IsCurvatureEnabled(&leftV))
2008-12-19 11:31:56 +01:00
{
(*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
}
static bool HasCurvature() { return true; }
[ 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
static bool IsCurvatureEnabled(const typename TT::VertexType *v) { return v->Base().CurvatureEnabled; }
2008-12-19 11:31:56 +01:00
static bool HasCurvatureOcf() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("CurvatureOcf"));TT::Name(name);}
private:
};
template <class T> class CurvaturefOcf: public CurvatureOcf<float, T> {};
template <class T> class CurvaturedOcf: public CurvatureOcf<double, T> {};
///*-------------------------- 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:
typedef A CurvatureDirType;
typedef typename CurvatureDirType::VecType VecType;
typedef typename CurvatureDirType::ScalarType ScalarType;
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;}
const VecType &cPD1() const {assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].max_dir;}
const VecType &cPD2() const {assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].min_dir;}
2008-12-19 11:31:56 +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;}
const ScalarType &cK1() const {assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k1;}
const ScalarType &cK2()const {assert((*this).Base().CurvatureDirEnabled); return (*this).Base().CuDV[(*this).Index()].k2;}
template <class LeftV>
void ImportData(const LeftV & leftV){
// if((*this).Base().CurvatureEnabled && leftV.Base().CurvatureEnabled ) // WRONG I do not know anything about leftV!
if((*this).Base().CurvatureDirEnabled && LeftV::IsCurvatureDirEnabled(&leftV))
{
(*this).PD1() = leftV.cPD1();
(*this).PD2() = leftV.cPD2();
(*this).K1() = leftV.cK1();
(*this).K2() = leftV.cK2();
}
TT::ImportData(leftV);
}
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);}
2008-12-19 11:31:56 +01:00
private:
};
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:
typedef A RadiusType;
typedef RadiusType ScalarType;
RadiusType &R(){ assert((*this).Base().RadiusEnabled); return (*this).Base().RadiusV[(*this).Index()];}
const RadiusType &cR() const { assert((*this).Base().RadiusEnabled); return (*this).Base().RadiusV[(*this).Index()];}
template <class LeftV>
void ImportData(const LeftV & leftV)
2008-12-19 11:31:56 +01:00
{
//if ((*this).Base().RadiusEnabled && leftV.Base().RadiusEnabled ) // WRONG I do not know anything about leftV!
if ((*this).Base().RadiusEnabled)
2008-12-19 11:31:56 +01:00
(*this).Base().RadiusV[(*this).Index()] = leftV.cR();
TT::ImportData(leftV);
2008-12-19 11:31:56 +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);}
private:
};
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:
// 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;
}
[ 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; }
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 >
bool VertexVectorHasPerVertexVFAdjacency(const vertex::vector_ocf<VertexType> &fv)
{
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
}
}// end namespace vcg
#endif