Merge pull request #93 from alemuntoni/const_correctness_copy_mesh

const-correctness for copy from a const right Mesh
This commit is contained in:
Alessandro Muntoni 2020-10-16 13:38:02 +02:00 committed by GitHub
commit 41351b9e72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 429 additions and 33 deletions

View File

@ -183,6 +183,7 @@ typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::VertexPointer VertexPointer; typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator; typedef typename MeshType::VertexIterator VertexIterator;
typedef typename MeshType::EdgeIterator EdgeIterator; typedef typename MeshType::EdgeIterator EdgeIterator;
typedef typename MeshType::EdgeType EdgeType;
typedef typename MeshType::FaceType FaceType; typedef typename MeshType::FaceType FaceType;
typedef typename MeshType::FacePointer FacePointer; typedef typename MeshType::FacePointer FacePointer;
typedef typename MeshType::FaceIterator FaceIterator; typedef typename MeshType::FaceIterator FaceIterator;
@ -269,39 +270,41 @@ static void Clear(MeshType &m)
} }
/// \brief This function returns the number of selected faces. /// \brief This function returns the number of selected faces.
static size_t FaceCount(MeshType &m) static size_t FaceCount(const MeshType &m)
{ {
size_t selCnt=0; size_t selCnt=0;
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) ForEachFace(m, [&](const FaceType& f){
if(!(*fi).IsD() && (*fi).IsS()) ++selCnt; if(f.IsS()) ++selCnt;
});
return selCnt; return selCnt;
} }
/// \brief This function returns the number of selected edges. /// \brief This function returns the number of selected edges.
static size_t EdgeCount(MeshType &m) static size_t EdgeCount(const MeshType &m)
{ {
size_t selCnt=0; size_t selCnt=0;
for(EdgeIterator ei=m.edge.begin();ei!=m.edge.end();++ei) ForEachEdge(m, [&](const EdgeType& e){
if(!(*ei).IsD() && (*ei).IsS()) ++selCnt; if(e.IsS()) ++selCnt;
});
return selCnt; return selCnt;
} }
/// \brief This function returns the number of selected vertices. /// \brief This function returns the number of selected vertices.
static size_t VertexCount(MeshType &m) static size_t VertexCount(const MeshType &m)
{ {
size_t selCnt=0; size_t selCnt=0;
for(VertexIterator vi=m.vert.begin();vi!=m.vert.end();++vi) ForEachVertex(m, [&](const VertexType& v){
if(!(*vi).IsD() && (*vi).IsS()) ++selCnt; if(v.IsS()) ++selCnt;
});
return selCnt; return selCnt;
} }
/// \brief This function returns the number of selected tetras. /// \brief This function returns the number of selected tetras.
static size_t TetraCount (MeshType & m) static size_t TetraCount (const MeshType & m)
{ {
size_t selCnt = 0; size_t selCnt = 0;
ForEachTetra(m, [&selCnt] (TetraType & t) { ForEachTetra(m, [&] (const TetraType & t) {
if (t.IsS()) if (t.IsS()) ++selCnt;
++selCnt;
}); });
return selCnt; return selCnt;

View File

@ -76,7 +76,7 @@ public:
std::vector<size_t> vert, face, edge, hedge, tetra; std::vector<size_t> vert, face, edge, hedge, tetra;
}; };
static void ImportVertexAdj(MeshLeft &ml, ConstMeshRight &mr, VertexLeft &vl, VertexRight &vr, Remap &remap ){ static void ImportVertexAdj(MeshLeft &ml, const ConstMeshRight &mr, VertexLeft &vl, const VertexRight &vr, Remap &remap ){
// Vertex to Edge Adj // Vertex to Edge Adj
if(HasVEAdjacency(ml) && HasVEAdjacency(mr) && vr.cVEp() != 0){ if(HasVEAdjacency(ml) && HasVEAdjacency(mr) && vr.cVEp() != 0){
size_t i = Index(mr,vr.cVEp()); size_t i = Index(mr,vr.cVEp());
@ -105,7 +105,7 @@ public:
} }
} }
static void ImportEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, EdgeLeft &el, const EdgeRight &er, Remap &remap) static void ImportEdgeAdj(MeshLeft &ml, const ConstMeshRight &mr, EdgeLeft &el, const EdgeRight &er, Remap &remap)
{ {
// Edge to Edge Adj // Edge to Edge Adj
if(HasEEAdjacency(ml) && HasEEAdjacency(mr)) if(HasEEAdjacency(ml) && HasEEAdjacency(mr))
@ -129,7 +129,7 @@ public:
} }
static void ImportFaceAdj(MeshLeft &ml, ConstMeshRight &mr, FaceLeft &fl, const FaceRight &fr, Remap &remap ) static void ImportFaceAdj(MeshLeft &ml, const ConstMeshRight &mr, FaceLeft &fl, const FaceRight &fr, Remap &remap )
{ {
// Face to Edge Adj // Face to Edge Adj
if(HasFEAdjacency(ml) && HasFEAdjacency(mr)){ if(HasFEAdjacency(ml) && HasFEAdjacency(mr)){
@ -183,7 +183,7 @@ public:
fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]]; fl.FHp() = &ml.hedge[remap.hedge[Index(mr,fr.cFHp())]];
} }
static void ImportHEdgeAdj(MeshLeft &ml, ConstMeshRight &mr, HEdgeLeft &hl, const HEdgeRight &hr, Remap &remap, bool /*sel*/ ){ static void ImportHEdgeAdj(MeshLeft &ml, const ConstMeshRight &mr, HEdgeLeft &hl, const HEdgeRight &hr, Remap &remap, bool /*sel*/ ){
// HEdge to Vertex Adj // HEdge to Vertex Adj
if(HasHVAdjacency(ml) && HasHVAdjacency(mr)) if(HasHVAdjacency(ml) && HasHVAdjacency(mr))
hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]]; hl.HVp() = &ml.vert[remap.vert[Index(mr,hr.cHVp())]];
@ -214,7 +214,7 @@ public:
hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]]; hl.HPp() = &ml.hedge[remap.hedge[Index(mr,hr.cHPp())]];
} }
static void ImportTetraAdj(MeshLeft &ml, ConstMeshRight &mr, TetraLeft &tl, const TetraRight &tr, Remap &remap ) static void ImportTetraAdj(MeshLeft &ml, const ConstMeshRight &mr, TetraLeft &tl, const TetraRight &tr, Remap &remap )
{ {
// Tetra to Tetra Adj // Tetra to Tetra Adj
if(HasTTAdjacency(ml) && HasTTAdjacency(mr)){ if(HasTTAdjacency(ml) && HasTTAdjacency(mr)){
@ -476,6 +476,270 @@ static void Mesh(MeshLeft& ml, ConstMeshRight& mr, const bool selected = false,
// } // }
} }
/**
* @brief MeshAppendConst
* @param ml
* @param mr
*
* This is function is similar with the Mesh function, but does not
* never update selections. In some cases, after the append,
* selection of vertices may be inconsistent with face selection,
* as explained above.
* To avoid this, before using this function, call the following functions:
*
* \code{.cpp}
* vcg::tri::UpdateSelection<MyMesh>::VertexFromEdgeLoose(mr,true);
* vcg::tri::UpdateSelection<MyMesh>::VertexFromFaceLoose(mr,true);
* \endcode
*
* or, use the Mesh function that takes a non-const Right Mesh argument.
*/
static void MeshAppendConst(
MeshLeft& ml,
const ConstMeshRight& mr,
const bool selected = false,
const bool adjFlag = false)
{
// phase 1. allocate on ml vert,edge,face, hedge to accomodat those of mr
// and build the remapping for all
Remap remap;
// vertex
remap.vert.resize(mr.vert.size(), Remap::InvalidIndex());
VertexIteratorLeft vp;
size_t svn = UpdateSelection<ConstMeshRight>::VertexCount(mr);
if(selected)
vp=Allocator<MeshLeft>::AddVertices(ml,int(svn));
else
vp=Allocator<MeshLeft>::AddVertices(ml,mr.vn);
ForEachVertex(mr, [&](const VertexRight& v)
{
if(!selected || v.IsS())
{
size_t ind=Index(mr,v);
remap.vert[ind]=int(Index(ml,*vp));
++vp;
}
});
// edge
remap.edge.resize(mr.edge.size(), Remap::InvalidIndex());
EdgeIteratorLeft ep;
size_t sen = UpdateSelection<ConstMeshRight>::EdgeCount(mr);
if(selected) ep=Allocator<MeshLeft>::AddEdges(ml,sen);
else ep=Allocator<MeshLeft>::AddEdges(ml,mr.en);
ForEachEdge(mr, [&](const EdgeRight& e)
{
if(!selected || e.IsS()){
size_t ind=Index(mr,e);
remap.edge[ind]=int(Index(ml,*ep));
++ep;
}
});
// face
remap.face.resize(mr.face.size(), Remap::InvalidIndex());
FaceIteratorLeft fp;
size_t sfn = UpdateSelection<ConstMeshRight>::FaceCount(mr);
if(selected) fp=Allocator<MeshLeft>::AddFaces(ml,sfn);
else fp=Allocator<MeshLeft>::AddFaces(ml,mr.fn);
ForEachFace(mr, [&](const FaceRight& f)
{
if(!selected || f.IsS()){
size_t ind=Index(mr,f);
remap.face[ind]=int(Index(ml,*fp));
++fp;
}
});
// hedge
remap.hedge.resize(mr.hedge.size(),Remap::InvalidIndex());
ForEachHEdge(mr, [&](const HEdgeRight& he)
{
if(!selected || he.IsS()){
size_t ind=Index(mr,he);
assert(remap.hedge[ind]==Remap::InvalidIndex());
HEdgeIteratorLeft hp = Allocator<MeshLeft>::AddHEdges(ml,1);
(*hp).ImportData(he);
remap.hedge[ind]=Index(ml,*hp);
}
});
remap.tetra.resize(mr.tetra.size(), Remap::InvalidIndex());
ForEachTetra(mr, [&](const TetraRight& t)
{
if (!selected || t.IsS()) {
size_t idx = Index(mr, t);
assert (remap.tetra[idx] == Remap::InvalidIndex());
TetraIteratorLeft tp = Allocator<MeshLeft>::AddTetras(ml, 1);
(*tp).ImportData(t);
remap.tetra[idx] = Index(ml, *tp);
}
});
// phase 2.
// copy data from mr to its corresponding elements in ml and adjacencies
// vertex
ForEachVertex(mr, [&](const VertexRight& v)
{
if(!selected || v.IsS()){
ml.vert[remap.vert[Index(mr,v)]].ImportData(v);
if(adjFlag) ImportVertexAdj(ml,mr,ml.vert[remap.vert[Index(mr,v)]],v,remap);
}
});
// edge
ForEachEdge(mr, [&](const EdgeRight& e)
{
if(!selected || e.IsS()){
ml.edge[remap.edge[Index(mr,e)]].ImportData(e);
// Edge to Vertex Adj
EdgeLeft &el = ml.edge[remap.edge[Index(mr,e)]];
if(HasEVAdjacency(ml) && HasEVAdjacency(mr)){
el.V(0) = &ml.vert[remap.vert[Index(mr,e.cV(0))]];
el.V(1) = &ml.vert[remap.vert[Index(mr,e.cV(1))]];
}
if(adjFlag) ImportEdgeAdj(ml,mr,el,e,remap);
}
});
// face
const size_t textureOffset = ml.textures.size();
bool WTFlag = HasPerWedgeTexCoord(mr) && (textureOffset>0);
ForEachFace(mr, [&](const FaceRight& f)
{
if(!selected || f.IsS())
{
FaceLeft &fl = ml.face[remap.face[Index(mr,f)]];
fl.Alloc(f.VN());
if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){
for(int i = 0; i < fl.VN(); ++i)
fl.V(i) = &ml.vert[remap.vert[Index(mr,f.cV(i))]];
}
fl.ImportData(f);
if(WTFlag)
for(int i = 0; i < fl.VN(); ++i)
fl.WT(i).n() += short(textureOffset);
if(adjFlag) ImportFaceAdj(ml,mr,ml.face[remap.face[Index(mr,f)]],f,remap);
}
});
// hedge
ForEachHEdge(mr, [&](const HEdgeRight& he)
{
if(!selected || he.IsS()){
ml.hedge[remap.hedge[Index(mr,he)]].ImportData(he);
ImportHEdgeAdj(ml,mr,ml.hedge[remap.hedge[Index(mr,he)]],he,remap,selected);
}
});
//tetra
ForEachTetra(mr, [&](const TetraRight& t)
{
if(!selected || t.IsS())
{
TetraLeft &tl = ml.tetra[remap.tetra[Index(mr,t)]];
if(HasFVAdjacency(ml) && HasFVAdjacency(mr)){
for(int i = 0; i < 4; ++i)
tl.V(i) = &ml.vert[remap.vert[Index(mr,t.cV(i))]];
}
tl.ImportData(t);
if(adjFlag) ImportTetraAdj(ml, mr, ml.tetra[remap.tetra[Index(mr,t)]], t, remap);
}
});
// phase 3.
// take care of other per mesh data: textures, attributes
// At the end concatenate the vector with texture names.
ml.textures.insert(ml.textures.end(),mr.textures.begin(),mr.textures.end());
// Attributes. Copy only those attributes that are present in both meshes
// Two attributes in different meshes are considered the same if they have the same
// name and the same type. This may be deceiving because they could in fact have
// different semantic, but this is up to the developer.
// If the left mesh has attributes that are not in the right mesh, their values for the elements
// of the right mesh will be uninitialized
unsigned int id_r;
typename std::set< PointerToAttribute >::iterator al, ar;
// per vertex attributes
for(al = ml.vert_attr.begin(); al != ml.vert_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.vert_attr.find(*al);
if(ar!= mr.vert_attr.end()){
id_r = 0;
for (auto v: mr.vert){
if( !v.IsD() && (!selected || v.IsS()))
(*al)._handle->CopyValue(remap.vert[Index(mr,v)], id_r, (*ar)._handle);
++id_r;
}
}
}
// per edge attributes
for(al = ml.edge_attr.begin(); al != ml.edge_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.edge_attr.find(*al);
if(ar!= mr.edge_attr.end()){
id_r = 0;
for (auto e: mr.edge){
if( !e.IsD() && (!selected || e.IsS()))
(*al)._handle->CopyValue(remap.edge[Index(mr,e)], id_r, (*ar)._handle);
++id_r;
}
}
}
// per face attributes
for(al = ml.face_attr.begin(); al != ml.face_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.face_attr.find(*al);
if(ar!= mr.face_attr.end()){
id_r = 0;
for (auto f: mr.face) {
if( !f.IsD() && (!selected || f.IsS()))
(*al)._handle->CopyValue(remap.face[Index(mr,f)], id_r, (*ar)._handle);
++id_r;
}
}
}
// per tetra attributes
for(al = ml.tetra_attr.begin(); al != ml.tetra_attr.end(); ++al)
if(!(*al)._name.empty()){
ar = mr.tetra_attr.find(*al);
if(ar!= mr.tetra_attr.end()){
id_r = 0;
for (auto t: mr.tetra) {
if( !t.IsD() && (!selected || t.IsS()))
(*al)._handle->CopyValue(remap.tetra[Index(mr, t)], id_r, (*ar)._handle);
++id_r;
}
}
}
// per mesh attributes
// if both ml and mr have an attribute with the same name, no action is done
// if mr has an attribute that is NOT present in ml, the attribute is added to ml
//for(ar = mr.mesh_attr.begin(); ar != mr.mesh_attr.end(); ++ar)
// if(!(*ar)._name.empty()){
// al = ml.mesh_attr.find(*ar);
// if(al== ml.mesh_attr.end())
// //...
// }
}
/*! \brief Copy the second mesh over the first one. /*! \brief Copy the second mesh over the first one.
The first mesh is destroyed. If requested only the selected elements are copied. The first mesh is destroyed. If requested only the selected elements are copied.
*/ */
@ -485,6 +749,13 @@ static void MeshCopy(MeshLeft& ml, ConstMeshRight& mr, bool selected=false, cons
Mesh(ml,mr,selected,adjFlag); Mesh(ml,mr,selected,adjFlag);
ml.bbox.Import(mr.bbox); ml.bbox.Import(mr.bbox);
} }
static void MeshCopyConst(MeshLeft& ml, const ConstMeshRight& mr, bool selected=false, const bool adjFlag = false)
{
ml.Clear();
MeshAppendConst(ml,mr,selected,adjFlag);
ml.bbox.Import(mr.bbox);
}
/*! \brief %Append only the selected elements of second mesh to the first one. /*! \brief %Append only the selected elements of second mesh to the first one.
It is just a wrap of the main Append::Mesh() It is just a wrap of the main Append::Mesh()

View File

@ -34,8 +34,24 @@ namespace tri {
@{ @{
*/ */
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachFacePos(MeshType &m, std::function<void (typename face::Pos<typename MeshType::FaceType> &)> action) inline void ForEachFacePos(const MeshType &m, Callable action)
{
typedef typename face::Pos<typename MeshType::FaceType> PosType;
for(auto fi=m.face.begin();fi!=m.face.end();++fi)
if(!(*fi).IsD())
{
for(int i=0;i<3;++i)
{
PosType pi(&*fi,i);
action(pi);
}
}
}
template <class MeshType, typename Callable>
inline void ForEachFacePos(MeshType &m, Callable action)
{ {
typedef typename face::Pos<typename MeshType::FaceType> PosType; typedef typename face::Pos<typename MeshType::FaceType> PosType;
@ -60,8 +76,8 @@ inline void ForEachFacePos(MeshType &m, std::function<void (typename face::Pos<t
* *
*/ */
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachFace(const MeshType &m, std::function<void (const typename MeshType::FaceType &)> action) inline void ForEachFace(const MeshType &m, Callable action)
{ {
if(m.fn == (int) m.face.size()) if(m.fn == (int) m.face.size())
{ {
@ -79,8 +95,8 @@ inline void ForEachFace(const MeshType &m, std::function<void (const typename Me
} }
} }
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachFace(MeshType &m, std::function<void (typename MeshType::FaceType &)> action) inline void ForEachFace(MeshType &m, Callable action)
{ {
if(m.fn == (int) m.face.size()) if(m.fn == (int) m.face.size())
{ {
@ -108,8 +124,27 @@ inline void ForEachFace(MeshType &m, std::function<void (typename MeshType::Face
* *
*/ */
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachVertex(MeshType &m, std::function<void (typename MeshType::VertexType &)> action) inline void ForEachVertex(const MeshType &m, Callable action)
{
if(m.vn == (int) m.vert.size())
{
for(auto vi=m.vert.begin();vi!=m.vert.end();++vi) {
action(*vi);
}
}
else
{
for(auto vi=m.vert.begin();vi!=m.vert.end();++vi)
if(!(*vi).IsD())
{
action(*vi);
}
}
}
template <class MeshType, typename Callable>
inline void ForEachVertex(MeshType &m, Callable action)
{ {
if(m.vn == (int) m.vert.size()) if(m.vn == (int) m.vert.size())
{ {
@ -127,6 +162,54 @@ inline void ForEachVertex(MeshType &m, std::function<void (typename MeshType::Ve
} }
} }
/**
* ForEachHEdge Helper
* to traverse all the half edges of a mesh you can simply write something like:
*
* ForEachHEdge(m, [&](const HEdgeType &he){
* MakeSomethingWithHEdge(he);
* });
*
*/
template <class MeshType, typename Callable>
inline void ForEachHEdge(const MeshType &m, Callable action)
{
if(m.hn == (int) m.hedge.size())
{
for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) {
action(*hei);
}
}
else
{
for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei)
if(!(*hei).IsD())
{
action(*hei);
}
}
}
template <class MeshType, typename Callable>
inline void ForEachHEdge(MeshType &m, Callable action)
{
if(m.hn == (int) m.hedge.size())
{
for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei) {
action(*hei);
}
}
else
{
for(auto hei=m.hedge.begin();hei!=m.hedge.end();++hei)
if(!(*hei).IsD())
{
action(*hei);
}
}
}
/** /**
* ForEachEdge Helper * ForEachEdge Helper
* to traverse all the vertexes of a mesh you can simply write something like: * to traverse all the vertexes of a mesh you can simply write something like:
@ -137,8 +220,27 @@ inline void ForEachVertex(MeshType &m, std::function<void (typename MeshType::Ve
* *
*/ */
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachEdge(MeshType &m, std::function<void (typename MeshType::EdgeType &)> action) inline void ForEachEdge(const MeshType &m, Callable action)
{
if(m.en == (int) m.edge.size())
{
for(auto ei=m.edge.begin();ei!=m.edge.end();++ei) {
action(*ei);
}
}
else
{
for(auto ei=m.edge.begin();ei!=m.edge.end();++ei)
if(!(*ei).IsD())
{
action(*ei);
}
}
}
template <class MeshType, typename Callable>
inline void ForEachEdge(MeshType &m, Callable action)
{ {
if(m.en == (int) m.edge.size()) if(m.en == (int) m.edge.size())
{ {
@ -166,8 +268,8 @@ inline void ForEachEdge(MeshType &m, std::function<void (typename MeshType::Edge
* *
*/ */
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachTetra(const MeshType &m, std::function<void (const typename MeshType::TetraType &)> action) inline void ForEachTetra(const MeshType &m, Callable action)
{ {
if(m.tn == (int) m.tetra.size()) if(m.tn == (int) m.tetra.size())
{ {
@ -185,8 +287,8 @@ inline void ForEachTetra(const MeshType &m, std::function<void (const typename M
} }
} }
template <class MeshType> template <class MeshType, typename Callable>
inline void ForEachTetra(MeshType &m, std::function<void (typename MeshType::TetraType &)> action) inline void ForEachTetra(MeshType &m, Callable action)
{ {
if(m.tn == (int) m.tetra.size()) if(m.tn == (int) m.tetra.size())
{ {

View File

@ -78,6 +78,7 @@ public:
typename T::EdgePointer &VEp(const int & ) { static typename T::EdgePointer ep=0; assert(0); return ep; } typename T::EdgePointer &VEp(const int & ) { static typename T::EdgePointer ep=0; assert(0); return ep; }
typename T::EdgePointer cVEp(const int & ) const { static typename T::EdgePointer ep=0; assert(0); return ep; } typename T::EdgePointer cVEp(const int & ) const { static typename T::EdgePointer ep=0; assert(0); return ep; }
int &VEi(const int &){static int z=0; assert(0); return z;} int &VEi(const int &){static int z=0; assert(0); return z;}
int VEi(const int &) const {static int z=0; assert(0); return z;}
int cVEi(const int &) const {static int z=0; assert(0); return z;} int cVEi(const int &) const {static int z=0; assert(0); return z;}
static bool HasVEAdjacency() { return false; } static bool HasVEAdjacency() { return false; }
@ -278,6 +279,7 @@ public:
typename T::EdgePointer &VEp(const int & i) {return _ep[i]; } typename T::EdgePointer &VEp(const int & i) {return _ep[i]; }
typename T::EdgePointer cVEp(const int & i) const {return _ep[i]; } typename T::EdgePointer cVEp(const int & i) const {return _ep[i]; }
int &VEi(const int & i){ return _zp[i];} int &VEi(const int & i){ return _zp[i];}
int VEi(const int & i)const {return _zp[i];}
int cVEi(const int &i )const {return _zp[i];} int cVEi(const int &i )const {return _zp[i];}
template < class LeftV> template < class LeftV>

View File

@ -114,6 +114,7 @@ public:
typename T::HEdgePointer &FHp() { static typename T::HEdgePointer fp=0; assert(0); return fp; } typename T::HEdgePointer &FHp() { static typename T::HEdgePointer fp=0; assert(0); return fp; }
typename T::HEdgePointer cFHp() const { static typename T::HEdgePointer fp=0; assert(0); return fp; } typename T::HEdgePointer cFHp() const { static typename T::HEdgePointer fp=0; assert(0); return fp; }
char &VFi(int) { static char z=0; assert(0); return z;} char &VFi(int) { static char z=0; assert(0); return z;}
char VFi(int) const { static char z=0; assert(0); return z;}
char &FFi(int) { static char z=0; assert(0); return z;} char &FFi(int) { static char z=0; assert(0); return z;}
char cVFi(int) const { static char z=0; assert(0); return z;} char cVFi(int) const { static char z=0; assert(0); return z;}
char cFFi(int) const { static char z=0; assert(0); return z;} char cFFi(int) const { static char z=0; assert(0); return z;}

View File

@ -408,6 +408,11 @@ public:
return (*this).Base().AV[(*this).Index()]._zp[j]; return (*this).Base().AV[(*this).Index()]._zp[j];
} }
char VFi(const int j) const {
assert((*this).Base().VFAdjacencyEnabled);
return (*this).Base().AV[(*this).Index()]._zp[j];
}
char cVFi(const int j) const { char cVFi(const int j) const {
assert((*this).Base().VFAdjacencyEnabled); assert((*this).Base().VFAdjacencyEnabled);
return (*this).Base().AV[(*this).Index()]._zp[j]; return (*this).Base().AV[(*this).Index()]._zp[j];

View File

@ -136,6 +136,7 @@ public:
typename T::FacePointer const VFp(const int j) const { assert(j>=0 && j<this->VN()); return _vfpP[j]; } typename T::FacePointer const VFp(const int j) const { assert(j>=0 && j<this->VN()); return _vfpP[j]; }
typename T::FacePointer const cVFp(const int j) const { assert(j>=0 && j<this->VN()); return _vfpP[j]; } typename T::FacePointer const cVFp(const int j) const { assert(j>=0 && j<this->VN()); return _vfpP[j]; }
char &VFi(const int j) {return _vfiP[j]; } char &VFi(const int j) {return _vfiP[j]; }
char VFi(const int j) const {return _vfiP[j]; }
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & leftF){T::ImportData(leftF);} void ImportData(const LeftF & leftF){T::ImportData(leftF);}
inline void Alloc(const int & ns) { inline void Alloc(const int & ns) {

View File

@ -47,7 +47,7 @@ public:
//Empty vertexref //Empty vertexref
inline typename T::VertexType * & V( const int ) { assert(0); static typename T::VertexType *vp=0; return vp; } inline typename T::VertexType * & V( const int ) { assert(0); static typename T::VertexType *vp=0; return vp; }
inline typename T::VertexType * const & V( const int ) const { assert(0); static typename T::VertexType *vp=0; return vp; } inline typename T::VertexType * const & V( const int ) const { assert(0); static typename T::VertexType *vp=0; return vp; }
inline const typename T::VertexType * cV( const int ) { assert(0); static typename T::VertexType *vp=0; return vp; } inline const typename T::VertexType * cV( const int ) const { assert(0); static typename T::VertexType *vp=0; return vp; }
inline typename T::CoordType & P( const int ) { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } inline typename T::CoordType & P( const int ) { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; }
inline const typename T::CoordType & P( const int ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } inline const typename T::CoordType & P( const int ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; }
inline const typename T::CoordType &cP( const int ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; } inline const typename T::CoordType &cP( const int ) const { assert(0); static typename T::CoordType coord(0, 0, 0); return coord; }
@ -112,6 +112,7 @@ public:
typename T::TetraPointer const cTTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; } typename T::TetraPointer const cTTp( const int ) const { static typename T::TetraPointer const tp=0; assert(0); return tp; }
char & VTi( const int ) { static char z=0; assert(0); return z; } char & VTi( const int ) { static char z=0; assert(0); return z; }
char VTi( const int ) const { static char z=0; assert(0); return z; }
char cVTi( const int ) const { static char z=0; assert(0); return z; } char cVTi( const int ) const { static char z=0; assert(0); return z; }
char & TTi( const int ) { static char z=0; assert(0); return z; } char & TTi( const int ) { static char z=0; assert(0); return z; }
char cTTi( const int ) const { static char z=0; assert(0); return z; } char cTTi( const int ) const { static char z=0; assert(0); return z; }

View File

@ -99,6 +99,7 @@ public:
typename TT::TetraPointer &VTp() { static typename TT::TetraPointer tp = 0; assert(0); return tp; } typename TT::TetraPointer &VTp() { static typename TT::TetraPointer tp = 0; assert(0); return tp; }
typename TT::TetraPointer cVTp() const { static typename TT::TetraPointer tp = 0; assert(0); return tp; } typename TT::TetraPointer cVTp() const { static typename TT::TetraPointer tp = 0; assert(0); return tp; }
int &VTi() { static int z = 0; assert(0); return z; } int &VTi() { static int z = 0; assert(0); return z; }
int VTi() const { static int z = 0; assert(0); return z; }
int cVTi() const { static int z = 0; assert(0); return z; } int cVTi() const { static int z = 0; assert(0); return z; }
static bool HasVTAdjacency() { return false; } static bool HasVTAdjacency() { return false; }
bool IsVTInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVTi()!=-1;} bool IsVTInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVTi()!=-1;}
@ -112,6 +113,7 @@ public:
typename TT::FacePointer &VFp() { static typename TT::FacePointer fp=0; assert(0); return fp; } typename TT::FacePointer &VFp() { static typename TT::FacePointer fp=0; assert(0); return fp; }
typename TT::FacePointer cVFp() const { static typename TT::FacePointer fp=0; assert(0); return fp; } typename TT::FacePointer cVFp() const { static typename TT::FacePointer fp=0; assert(0); return fp; }
int &VFi() { static int z=-1; assert(0); return z;} int &VFi() { static int z=-1; assert(0); return z;}
int VFi() const { static int z=-1; assert(0); return z;}
int cVFi() const { static int z=-1; assert(0); return z;} int cVFi() const { static int z=-1; assert(0); return z;}
bool IsNull() const { return true; } bool IsNull() const { return true; }
static bool HasVFAdjacency() { return false; } static bool HasVFAdjacency() { return false; }
@ -126,6 +128,7 @@ public:
typename TT::EdgePointer &VEp() { static typename TT::EdgePointer ep=0; assert(0); return ep; } typename TT::EdgePointer &VEp() { static typename TT::EdgePointer ep=0; assert(0); return ep; }
typename TT::EdgePointer cVEp() const { static typename TT::EdgePointer ep=0; assert(0); return ep; } typename TT::EdgePointer cVEp() const { static typename TT::EdgePointer ep=0; assert(0); return ep; }
int &VEi() { static int z=-1; return z;} int &VEi() { static int z=-1; return z;}
int VEi() const { static int z=-1; return z;}
int cVEi() const { static int z=-1; return z;} int cVEi() const { static int z=-1; return z;}
static bool HasVEAdjacency() { return false; } static bool HasVEAdjacency() { return false; }
bool IsVEInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVEi()!=-1;} bool IsVEInitialized() const {return static_cast<const typename TT::VertexType *>(this)->cVEi()!=-1;}
@ -138,6 +141,7 @@ public:
typename TT::HEdgePointer &VHp() { static typename TT::HEdgePointer ep=0; assert(0); return ep; } typename TT::HEdgePointer &VHp() { static typename TT::HEdgePointer ep=0; assert(0); return ep; }
typename TT::HEdgePointer cVHp() const { static typename TT::HEdgePointer ep=0; assert(0); return ep; } typename TT::HEdgePointer cVHp() const { static typename TT::HEdgePointer ep=0; assert(0); return ep; }
int &VHi() { static int z=0; return z;} int &VHi() { static int z=0; return z;}
int VHi() const { static int z=0; return z;}
int cVHi() const { static int z=0; return z;} int cVHi() const { static int z=0; return z;}
static bool HasVHAdjacency() { return false; } static bool HasVHAdjacency() { return false; }
@ -531,6 +535,7 @@ public:
typename T::EdgePointer &VEp() {return _ep; } typename T::EdgePointer &VEp() {return _ep; }
typename T::EdgePointer cVEp() const {return _ep; } typename T::EdgePointer cVEp() const {return _ep; }
int &VEi() {return _zp; } int &VEi() {return _zp; }
int VEi() const {return _zp; }
int cVEi() const {return _zp; } int cVEi() const {return _zp; }
template < class RightValueType> template < class RightValueType>
void ImportData(const RightValueType & rVert ) { T::ImportData( rVert); } void ImportData(const RightValueType & rVert ) { T::ImportData( rVert); }
@ -559,6 +564,7 @@ Note that if you use this component it is expected that on the Face you use also
typename T::FacePointer &VFp() { return _fp; } typename T::FacePointer &VFp() { return _fp; }
typename T::FacePointer cVFp() const { return _fp; } typename T::FacePointer cVFp() const { return _fp; }
int &VFi() { return _zp; } int &VFi() { return _zp; }
int VFi() const { return _zp; }
int cVFi() const { return _zp; } int cVFi() const { return _zp; }
bool IsNull() const { return _zp==-1;} bool IsNull() const { return _zp==-1;}
template < class RightValueType> template < class RightValueType>

View File

@ -285,6 +285,10 @@ public:
assert((*this).Base().VFAdjacencyEnabled); assert((*this).Base().VFAdjacencyEnabled);
return (*this).Base().AV[(*this).Index()]._zp; return (*this).Base().AV[(*this).Index()]._zp;
} }
int VFi() const {
assert((*this).Base().VFAdjacencyEnabled);
return (*this).Base().AV[(*this).Index()]._zp;
}
int cVFi() const { int cVFi() const {
if(! (*this).Base().VFAdjacencyEnabled ) return -1; if(! (*this).Base().VFAdjacencyEnabled ) return -1;
return (*this).Base().AV[(*this).Index()]._zp; return (*this).Base().AV[(*this).Index()]._zp;