[Polygon modification]

Added components to the face to handle generic polygons.
(compiled with .net and gcc)

This commit includes the following files:
vcg/complex/trimesh/base.h
Added deallocation of polygon data in the destructor

vcg/complex/trimesh/allocate.h
generalization from 3 to VN() vertices

vcg/complex/trimesh/update/topology.h
generalization from 3 to VN() vertices

vcg/complex/trimesh/update/flags.h
generalization from 3 to VN() vertices

vcg/simplex/face/pos.h
generalization from 3 to VN() vertices

vcg/simplex/faceplus/base.h
Added the method VN() to query the number of vertices
of the polygon (deafult 3) and methods Prev and Next

vcg/simplex/faceplus/component.h
added Alloc and Dealloc calls along the hierarchies
This commit is contained in:
ganovelli 2008-10-08 09:10:53 +00:00
parent ca01052454
commit 0d4b3fbed0
7 changed files with 134 additions and 82 deletions

View File

@ -364,7 +364,7 @@ namespace vcg {
*/
static FaceIterator AddFaces(MeshType &m, int n, PointerUpdater<FacePointer> &pu)
{
FaceIterator last;
FaceIterator last, fi;
if(n == 0) return m.face.end();
pu.Clear();
if(m.face.empty()) {
@ -378,6 +378,7 @@ namespace vcg {
m.face.resize(m.face.size()+n);
m.fn+=n;
typename std::set<typename MeshType::HandlesWrapper>::iterator ai;
for(ai = m.face_attr.begin(); ai != m.face_attr.end(); ++ai)
((typename MeshType::HandlesWrapper)(*ai)).Resize(m.face.size());
@ -387,24 +388,22 @@ namespace vcg {
if(pu.NeedUpdate())
{
FaceIterator fi;
for (fi=m.face.begin(); fi!=m.face.end(); ++fi)
int ii = 0;
FaceIterator fi = m.face.begin();
while(ii<m.fn-n) // cycle on all the faces wxcept the new ones
{
if(!(*fi).IsD())
{
if(HasFFAdjacency(m))
{
if ((*fi).cFFp(0)!=0) pu.Update((*fi).FFp(0));
if ((*fi).cFFp(1)!=0) pu.Update((*fi).FFp(1));
if ((*fi).cFFp(2)!=0) pu.Update((*fi).FFp(2));
}
for(int i = 0; i < (*fi).VN(); ++i)
if ((*fi).cFFp(i)!=0) pu.Update((*fi).FFp(i));
if(HasVFAdjacency(m))
{
//update pointers to chain of face incident in a vertex
//update them only if they are different from zero
if ((*fi).cVFp(0)!=0) pu.Update((*fi).VFp(0));
if ((*fi).cVFp(1)!=0) pu.Update((*fi).VFp(1));
if ((*fi).cVFp(2)!=0) pu.Update((*fi).VFp(2));
for(int i = 0; i < (*fi).VN(); ++i)
if ((*fi).cVFp(i)!=0) pu.Update((*fi).VFp(i));
}
++ii;
++fi;
}
VertexIterator vi;
for (vi=m.vert.begin(); vi!=m.vert.end(); ++vi)

View File

@ -271,6 +271,9 @@ public:
delete ((SimpleTempDataBase<FaceContainer>*)(*i)._handle);
for( i = mesh_attr.begin(); i != mesh_attr.end(); ++i)
delete ((AttributeBase*)(*i)._handle);
FaceIterator fi;
for(fi = face.begin(); fi != face.end(); ++fi) (*fi).Dealloc();
}
int Mem(const int & nv, const int & nf) const {
@ -311,6 +314,7 @@ static bool HasPerVertexQuality() { return VertexType::HasQuality(); }
static bool HasPerVertexTexCoord(){ return VertexType::HasTexCoord(); }
static bool HasPerVertexFlags() { return VertexType::HasFlags(); }
static bool HasPolyInfo() { return FaceType::HasPolyInfo() ; }
static bool HasPerFaceColor() { return FaceType::HasFaceColor() ; }
static bool HasPerFaceNormal() { return FaceType::HasFaceNormal() ; }
static bool HasPerFaceMark() { return FaceType::HasFaceMark() ; }

View File

@ -326,11 +326,15 @@ static void FaceBorderFromNone(MeshType &m)
if( m.fn == 0 )
return;
e.resize(m.fn*3); // Alloco il vettore ausiliario
FaceIterator fi;
int n_edges = 0;
for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
e.resize(n_edges);
p = e.begin();
for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
if( ! (*pf).IsD() )
for(int j=0;j<3;++j)
for(int j=0;j<(*pf).VN();++j)
{
(*p).Set(&(*pf),j);
(*pf).ClearB(j);
@ -373,11 +377,11 @@ static void VertexBorderFromFace(MeshType &m)
for(f=m.face.begin();f!=m.face.end();++f)
if(!(*f).IsD())
{
for(int z=0;z<3;++z)
for(int z=0;z<(*f).VN();++z)
if( (*f).IsB(z) )
{
(*f).V0(z)->SetB();
(*f).V1(z)->SetB();
(*f).V(z)->SetB();
(*f).V((*f).Next(z))->SetB();
}
}
}

View File

@ -136,8 +136,8 @@ void Set( FacePointer pf, const int nz )
assert(nz>=0);
assert(nz<3);
v[0] = pf->V0(nz);
v[1] = pf->V1(nz);
v[0] = pf->V(nz);
v[1] = pf->V(pf->Next(nz));
assert(v[0] != v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
if( v[0] > v[1] ) math::Swap(v[0],v[1]);
@ -163,11 +163,18 @@ static void FillEdgeVector(MeshType &m, std::vector<PEdge> &e)
{
FaceIterator pf;
typename std::vector<PEdge>::iterator p;
e.resize(m.fn*3); // Alloco il vettore ausiliario
// Alloco il vettore ausiliario
//e.resize(m.fn*3);
FaceIterator fi;
int n_edges = 0;
for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
e.resize(n_edges);
p = e.begin();
for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
if( ! (*pf).IsD() )
for(int j=0;j<3;++j)
for(int j=0;j<(*pf).VN();++j)
{
(*p).Set(&(*pf),j);
++p;
@ -198,16 +205,16 @@ static void FaceFace(MeshType &m)
for (q=ps;q<pe-1;++q) // Scansione facce associate
{
assert((*q).z>=0);
assert((*q).z< 3);
//assert((*q).z< 3);
q_next = q;
++q_next;
assert((*q_next).z>=0);
assert((*q_next).z< 3);
assert((*q_next).z< (*q_next).f->VN());
(*q).f->FFp(q->z) = (*q_next).f; // Collegamento in lista delle facce
(*q).f->FFi(q->z) = (*q_next).z;
}
assert((*q).z>=0);
assert((*q).z< 3);
assert((*q).z< (*q).f->VN());
(*q).f->FFp((*q).z) = ps->f;
(*q).f->FFi((*q).z) = ps->z;
ps = pe;
@ -240,7 +247,7 @@ static void VertexFace(MeshType &m)
for(fi=m.face.begin();fi!=m.face.end();++fi)
if( ! (*fi).IsD() )
{
for(int j=0;j<3;++j)
for(int j=0;j<(*fi).VN();++j)
{
(*fi).VFp(j) = (*fi).V(j)->VFp();
(*fi).VFi(j) = (*fi).V(j)->VFi();
@ -275,7 +282,7 @@ void Set( FacePointer pf, const int nz )
assert(nz<3);
v[0] = pf->WT(nz);
v[1] = pf->WT((nz+1)%3);
v[1] = pf->WT(pf->Next(nz));
assert(v[0] != v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
if( v[1] < v[0] ) swap(v[0],v[1]);
@ -318,13 +325,18 @@ static void FaceFaceFromTexCoord(MeshType &m)
if( m.fn == 0 ) return;
e.resize(m.fn*3); // Alloco il vettore ausiliario
// e.resize(m.fn*3); // Alloco il vettore ausiliario
FaceIterator fi;
int n_edges = 0;
for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(! (*fi).IsD()) n_edges+=(*fi).VN();
e.resize(n_edges);
p = e.begin();
for(pf=m.face.begin();pf!=m.face.end();++pf) // Lo riempio con i dati delle facce
if( ! (*pf).IsD() )
for(int j=0;j<3;++j)
for(int j=0;j<(*pf).VN();++j)
{
if( (*pf).WT(j) != (*pf).WT((j+1)%3) )
if( (*pf).WT(j) != (*pf).WT((*pf).Next(j)))
{
(*p).Set(&(*pf),j);
++p;
@ -351,12 +363,12 @@ static void FaceFaceFromTexCoord(MeshType &m)
q_next = q;
++q_next;
assert((*q_next).z>=0);
assert((*q_next).z< 3);
assert((*q_next).z< (*q_next).f->VN());
(*q).f->FFp(q->z) = (*q_next).f; // Collegamento in lista delle facce
(*q).f->FFi(q->z) = (*q_next).z;
}
assert((*q).z>=0);
assert((*q).z< 3);
assert((*q).z< (*q).f->VN());
(*q).f->FFp((*q).z) = ps->f;
(*q).f->FFi((*q).z) = ps->z;
ps = pe;
@ -409,7 +421,7 @@ static void TestFaceFace(MeshType &m)
{
if (!Fi->IsD())
{
for (int i=0;i<3;i++)
for (int i=0;i<(*Fi).VN();i++)
{
FaceType *f=Fi->FFp(i);
int e=Fi->FFi(i);

View File

@ -182,12 +182,8 @@ public:
{
f = fp;
v = vp;
if (f->V(0) == v)
z = 2;
else if (f->V(1) == v)
z = 0;
else if (f->V(2) == v)
z = 1;
for(int i = 0; i < f->VN(); ++i)
if (f->V(i) == v) { z = f->Prev(i); break;}
}
// Official Access functions functions
@ -201,9 +197,7 @@ public:
// It should holds that Vind != (z+1)%3 && Vind == z || Vind = z+2%3
int VInd()
{
if(v==f->V(0)) return 0;
if(v==f->V(1)) return 1;
if(v==f->V(2)) return 2;
for(int i = 0; i < f->VN(); ++i) if(v==f->V(i)) return i;
assert(0);
}
@ -264,19 +258,19 @@ public:
/// It moves on the adjacent face incident to v, via a different edge that j
void NextE()
{
assert( f->V(z)==v || f->V((z+1)%3)==v ); // L'edge j deve contenere v
assert( f->V(z)==v || f->V(f->Next(z))==v ); // L'edge j deve contenere v
FlipE();
FlipF();
assert( f->V(z)==v || f->V((z+1)%3)==v );
assert( f->V(z)==v || f->V(f->Next(z))==v );
}
// Cambia edge mantenendo la stessa faccia e lo stesso vertice
/// Changes edge maintaining the same face and the same vertex
void FlipE()
{
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
if(f->V((z+1)%3)==v) z=(z+1)%3;
else z=(z-1+3)%3;
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%3)==v));
if(f->V(f->Next(z))==v) z=f->Next(z);
else z= f->Prev(z);
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v));
}
// Cambia Faccia mantenendo lo stesso vertice e lo stesso edge
@ -289,49 +283,49 @@ public:
void FlipF()
{
assert( f->FFp(z)->FFp(f->FFi(z))==f ); // two manifoldness check
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z))==v));
FaceType *nf=f->FFp(z);
int nz=f->FFi(z);
assert(nf->V((nz+2)%3)!=v && (nf->V((nz+1)%3)==v || nf->V((nz+0)%3)==v));
assert(nf->V(f->Prev(nz))!=v && (nf->V(f->Next(nz))==v || nf->V((nz))==v));
f=nf;
z=nz;
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
}
/// Changes vertex maintaining the same face and the same edge
void FlipV()
{
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
if(f->V((z+1)%3)==v)
v=f->V((z+0)%3);
if(f->V(f->Next(z))==v)
v=f->V(z);
else
v=f->V((z+1)%3);
v=f->V(f->Next(z));
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
}
// return the vertex that it should have if we make FlipV;
VertexType *VFlip()
{
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
if(f->V((z+1)%3)==v) return f->V((z+0)%3);
else return f->V((z+1)%3);
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
if(f->V(f->Next(z))==v) return f->V(z);
else return f->V(f->Next(z));
}
// return the vertex that it should have if we make FlipV;
const VertexType *VFlip() const
{
assert(f->cV((z+2)%3)!=v && (f->cV((z+1)%3)==v || f->cV((z+0)%3)==v));
if(f->cV((z+1)%3)==v) return f->cV((z+0)%3);
else return f->cV((z+1)%3);
assert(f->cV(f->Prev(z))!=v && (f->cV(f->Next(z))==v || f->cV(z)==v));
if(f->cV(f->Next(z))==v) return f->cV(z);
else return f->cV(f->Next(z));
}
// return the face that it should have if we make FlipF;
const FaceType *FFlip() const
{
assert( f->FFp(z)->FFp(f->FFi(z))==f );
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V((z+0)%3)==v));
FaceType *nf=f->FFp(z);
return nf;
}
@ -352,7 +346,7 @@ public:
/// Finds the next half-edge border
void NextB( )
{
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
assert(f->FFp(z)==f); // f is border along j
// Si deve cambiare faccia intorno allo stesso vertice v
//finche' non si trova una faccia di bordo.
@ -361,10 +355,10 @@ public:
while(!IsBorder());
// L'edge j e' di bordo e deve contenere v
assert(IsBorder() &&( f->V(z)==v || f->V((z+1)%3)==v ));
assert(IsBorder() &&( f->V(z)==v || f->V(f->Next(z))==v ));
FlipV();
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
assert(f->FFp(z)==f); // f is border along j
}
@ -411,16 +405,14 @@ public:
void Set(FaceType * const fp, int const zp, VertexType * const vp)
{
f=fp;z=zp;v=vp;
assert(f->V((z+2)%3)!=v && (f->V((z+1)%3)==v || f->V((z+0)%3)==v));
assert(f->V(f->Prev(z))!=v && (f->V(f->Next(z))==v || f->V(z)==v));
}
void Set(FaceType * const pFace, VertexType * const pVertex)
{
f = pFace;
v = pVertex;
if (f->V(0) == v) z = 2;
else if (f->V(1) == v) z = 0;
else if (f->V(2) == v) z = 1;
for(int i = 0; i < f->VN(); ++i) if(f->V(i) == v ) {z = f->Prev(i);break;}
}
void Assert()

View File

@ -78,6 +78,7 @@ First working version!
#include <vcg/space/texcoord2.h>
#include <vcg/space/color4.h>
#include <vcg/simplex/faceplus/component.h>
#include <vcg/simplex/faceplus/component_polygon.h>
#include <vcg/container/derivation_chain.h>
namespace vcg {
@ -103,11 +104,15 @@ class FaceTypeHolder{
typedef BTT *TetraPointer;
template <class LeftF>
void ImportLocal(const LeftF & l){}
static void Name(std::vector<std::string> & name){}
static void Name(std::vector<std::string> & name){}
// prot
const int & VN() const { return 3;}
inline int Prev(const int & i){ return (i+(3-1))%3;}
inline int Next(const int & i){ return (i+1)%3;}
inline void Alloc(const int & ){}
inline void Dealloc(){}
};
/* The base class form which we start to add our components.
@ -123,14 +128,16 @@ we have to build the type a step a time (deriving from a single ancestor at a ti
*/
template <class BVT, class BET=DumClass, class BFT=DumClass, class BTT=DumClass>
class FaceBase: public face::EmptyVertexRef<
class FaceBase: public face::EmptyPolyInfo<
face::EmptyVertexRef<
face::EmptyAdj<
face::EmptyColorQuality<
face::EmptyNormal<
face::EmptyBitFlags<
face::EmptyMark<
face::EmptyWedgeTexCoord<
FaceTypeHolder <BVT, BET, BFT, BTT> > > > > > > >{
FaceTypeHolder <BVT, BET, BFT, BTT> > > > > > > > > {
};

View File

@ -123,6 +123,8 @@ public:
inline const typename T::CoordType &cP( const int j ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; }
template <class LeftF>
void ImportLocal(const LeftF & leftF) {T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasVertexRef() { return false; }
static void Name(std::vector<std::string> & name){T::Name(name);}
@ -173,6 +175,8 @@ public:
template <class LeftF>
void ImportLocal(const LeftF & leftF){ V(0) = NULL; V(1) = NULL; V(2) = NULL; T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasVertexRef() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("VertexRef"));T::Name(name);}
@ -213,6 +217,8 @@ public:
NormalType &cN() const { return _norm; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ N() = leftF.cN(); T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFaceNormal() { return true; }
// void ComputeNormal() { _norm = vcg::Normal<typename T::FaceType>(*(static_cast<typename T::FaceType *>(this))); }
// void ComputeNormalizedNormal() { _norm = vcg::NormalizedNormal(*this);}
@ -236,6 +242,8 @@ public:
NormalType cN() const { return _norm; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ N() = leftF.cN(); T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFaceNormal() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("NormalAbs"));T::Name(name);}
@ -250,7 +258,9 @@ public:
const NormalType cWN(const int j) const { return _wnorm[j]; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ WN() = leftF.cWN(); T::ImportLocal(leftF);}
static bool HasWedgeNormal() { return true; }
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasWedgeNormal() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("WedgeNormal"));T::Name(name);}
private:
@ -271,29 +281,33 @@ public: static void Name(std::vector<std::string> & name){name.push_back(std::st
/*-------------------------- TexCoord ----------------------------------------*/
template <class TT> class EmptyWedgeTexCoord: public TT {
template <class T> class EmptyWedgeTexCoord: public T {
public:
typedef int WedgeTexCoordType;
typedef vcg::TexCoord2<float,1> TexCoordType;
TexCoordType &WT(const int) { static TexCoordType dummy_texture; assert(0); return dummy_texture;}
TexCoordType const &cWT(const int) const { static TexCoordType dummy_texture; return dummy_texture;}
template <class LeftF>
void ImportLocal(const LeftF & leftF){ TT::ImportLocal(leftF);}
void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasWedgeTexCoord() { return false; }
static bool HasWedgeTexCoordOcc() { return false; }
static void Name(std::vector<std::string> & name){TT::Name(name);}
static void Name(std::vector<std::string> & name){T::Name(name);}
};
template <class A, class TT> class WedgeTexCoord: public TT {
template <class A, class T> class WedgeTexCoord: public T {
public:
typedef int WedgeTexCoordType;
typedef A TexCoordType;
TexCoordType &WT(const int i) { return _wt[i]; }
TexCoordType const &cWT(const int i) const { return _wt[i]; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ WT() = leftF.cWT();TT::ImportLocal(leftF);}
void ImportLocal(const LeftF & leftF){ WT() = leftF.cWT();T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasWedgeTexCoord() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("WedgeTexCoord"));TT::Name(name);}
static void Name(std::vector<std::string> & name){name.push_back(std::string("WedgeTexCoord"));T::Name(name);}
private:
TexCoordType _wt[3];
@ -317,6 +331,8 @@ public:
const int Flags() const { return 0; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFlags() { return false; }
static bool HasFlagsOcc() { return false; }
static void Name(std::vector<std::string> & name){T::Name(name);}
@ -331,6 +347,8 @@ public:
const int & cFlags() const {return _flags; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ Flags() = leftF.cFlags();T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFlags() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("BitFlags"));T::Name(name);}
@ -353,6 +371,10 @@ public:
static bool HasFaceQuality() { return false; }
static bool HasFaceColorOcc() { return false;}
static void Name(std::vector<std::string> & name){T::Name(name);}
template <class LeftF>
void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
};
template <class A, class T> class Color: public T {
@ -363,6 +385,8 @@ public:
const ColorType &cC() { return _color; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ C() = leftF.cC();T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFaceColor() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("Color"));T::Name(name);}
@ -403,6 +427,8 @@ public:
const QualityType &cQ() const { return _quality; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){ Q() = leftF.cQ();T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFaceQuality() { return true; }
static bool HasFaceQualityOcc() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("Quality"));T::Name(name);}
@ -431,6 +457,8 @@ public:
inline const int IMark() const {return 0;}
template <class LeftF>
void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static void Name(std::vector<std::string> & name){T::Name(name);}
};
@ -466,6 +494,8 @@ public:
const char &cFFi(const int j){static char z=0; return z;};
template <class LeftF>
void ImportLocal(const LeftF & leftF){ T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasVFAdjacency() { return false; }
static bool HasFFAdjacency() { return false; }
static bool HasFFAdjacencyOcc() { return false; }
@ -487,6 +517,8 @@ public:
char &VFi(const int j) {return _vfi[j]; }
template <class LeftF>
void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasVFAdjacency() { return true; }
static bool HasVFAdjacencyOcc() { return false; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("VFAdj"));T::Name(name);}
@ -518,6 +550,8 @@ public:
template <class LeftF>
void ImportLocal(const LeftF & leftF){T::ImportLocal(leftF);}
inline void Alloc(const int & ns){T::Alloc(ns);}
inline void Dealloc(){T::Dealloc();}
static bool HasFFAdjacency() { return true; }
static bool HasFFAdjacencyOcc() { return false; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("FFAdj"));T::Name(name);}