This commit is contained in:
Gianpaolo Palma 2018-07-12 10:56:14 +02:00
commit 22311c5340
5 changed files with 2644 additions and 2358 deletions

View File

@ -37,6 +37,68 @@
namespace vcg { namespace vcg {
namespace tri{ namespace tri{
template <class ConnectedEdgeMeshType>
class EdgeConnectedComponentIterator
{
public:
typedef ConnectedEdgeMeshType MeshType;
typedef typename MeshType::VertexType VertexType;
typedef typename MeshType::VertexPointer VertexPointer;
typedef typename MeshType::VertexIterator VertexIterator;
typedef typename MeshType::ScalarType ScalarType;
typedef typename MeshType::EdgeType EdgeType;
typedef typename MeshType::EdgePointer EdgePointer;
typedef typename MeshType::EdgeIterator EdgeIterator;
typedef typename MeshType::ConstEdgeIterator ConstEdgeIterator;
typedef typename MeshType::EdgeContainer EdgeContainer;
public:
void operator ++()
{
EdgePointer ep = se.top();
se.pop();
for(int i = 0; i < 2; ++i)
{
edge::VEIterator<EdgeType> vei(ep->V(i));
while (!vei.End())
{
if (!tri::IsMarked(*mp, vei.E()))
{
tri::Mark(*mp, vei.E());
se.push(vei.E());
}
++vei;
}
}
}
void start(MeshType &m, EdgePointer e)
{
tri::RequirePerEdgeMark(m);
mp=&m;
while(!se.empty())
se.pop();
UnMarkAll(m);
tri::Mark(m, e);
se.push(e);
}
bool completed() {
return se.empty();
}
EdgePointer operator *()
{
return se.top();
}
private:
std::stack<EdgePointer> se;
MeshType *mp;
};
template <class ConnectedMeshType> template <class ConnectedMeshType>
class ConnectedComponentIterator class ConnectedComponentIterator
{ {
@ -1119,6 +1181,47 @@ public:
return int(CCV.size()); return int(CCV.size());
} }
static int edgeMeshConnectedComponents(MeshType & poly, std::vector<std::pair<int, typename MeshType::EdgePointer> > &eCC)
{
typedef typename MeshType::EdgePointer EdgePointer;
tri::UpdateTopology<MeshType>::VertexEdge(poly);
tri::UpdateFlags<MeshType>::EdgeClear(poly);
eCC.clear();
std::stack<EdgePointer> stack;
for (auto ei = poly.edge.begin(); ei != poly.edge.end(); ++ei)
if (!ei->IsD() && !ei->IsV())
{
ei->SetV();
std::pair<int, EdgePointer> cc(1, &*ei);
stack.push(&*ei);
while (!stack.empty())
{
EdgePointer ep = stack.top();
stack.pop();
for (int i = 0; i < 2; ++i)
{
edge::VEIterator<typename MeshType::EdgeType> vei(ep->V(i));
while (!vei.End())
{
if (!vei.E()->IsV())
{
vei.E()->SetV();
stack.push(vei.E());
cc.first += 1;
}
++vei;
}
}
}
eCC.push_back(cc);
}
return int(eCC.size());
}
static void ComputeValence( MeshType &m, typename MeshType::PerVertexIntHandle &h) static void ComputeValence( MeshType &m, typename MeshType::PerVertexIntHandle &h)
{ {
for(VertexIterator vi=m.vert.begin(); vi!= m.vert.end();++vi) for(VertexIterator vi=m.vert.begin(); vi!= m.vert.end();++vi)

View File

@ -51,11 +51,11 @@ namespace tri {
/*@{*/ /*@{*/
/* MeshTypeHolder is a class which is used to define the types in the mesh /* MeshTypeHolder is a class which is used to define the types in the mesh
*/ */
template <class TYPESPOOL> template <class TYPESPOOL>
struct BaseMeshTypeHolder{ struct BaseMeshTypeHolder{
typedef bool ScalarType; typedef bool ScalarType;
typedef std::vector< typename TYPESPOOL::VertexType > CONTV; typedef std::vector< typename TYPESPOOL::VertexType > CONTV;
@ -76,6 +76,7 @@ namespace tri {
typedef CONTE EdgeContainer; typedef CONTE EdgeContainer;
typedef typename CONTE::value_type EdgeType; typedef typename CONTE::value_type EdgeType;
typedef typename TYPESPOOL::EdgePointer EdgePointer; typedef typename TYPESPOOL::EdgePointer EdgePointer;
typedef const typename TYPESPOOL::EdgePointer ConstEdgePointer;
typedef typename CONTE::iterator EdgeIterator; typedef typename CONTE::iterator EdgeIterator;
typedef typename CONTE::const_iterator ConstEdgeIterator; typedef typename CONTE::const_iterator ConstEdgeIterator;
@ -100,15 +101,15 @@ namespace tri {
typedef typename CONTT::const_iterator ConstTetraIterator; typedef typename CONTT::const_iterator ConstTetraIterator;
}; };
template <class T, typename CONT, class TRAIT > template <class T, typename CONT, class TRAIT >
struct MeshTypeHolder: public T {}; struct MeshTypeHolder: public T {};
template <class T, typename CONT> template <class T, typename CONT>
struct MeshTypeHolder<T, CONT, AllTypes::AVertexType>: public T { struct MeshTypeHolder<T, CONT, AllTypes::AVertexType>: public T {
typedef CONT VertContainer; typedef CONT VertContainer;
typedef typename VertContainer::value_type VertexType; typedef typename VertContainer::value_type VertexType;
typedef VertexType * VertexPointer; typedef VertexType * VertexPointer;
@ -117,47 +118,48 @@ namespace tri {
typedef typename VertexType::CoordType CoordType; typedef typename VertexType::CoordType CoordType;
typedef typename VertContainer::iterator VertexIterator; typedef typename VertContainer::iterator VertexIterator;
typedef typename VertContainer::const_iterator ConstVertexIterator; typedef typename VertContainer::const_iterator ConstVertexIterator;
}; };
template <typename T, class CONT> template <typename T, class CONT>
struct MeshTypeHolder< T, CONT, AllTypes::AEdgeType>: public T{ struct MeshTypeHolder< T, CONT, AllTypes::AEdgeType>: public T{
typedef CONT EdgeContainer; typedef CONT EdgeContainer;
typedef typename EdgeContainer::value_type EdgeType; typedef typename EdgeContainer::value_type EdgeType;
typedef typename EdgeContainer::value_type * EdgePointer; typedef EdgeType * EdgePointer;
typedef const EdgeType * ConstEdgePointer;
typedef typename EdgeContainer::iterator EdgeIterator; typedef typename EdgeContainer::iterator EdgeIterator;
typedef typename EdgeContainer::const_iterator ConstEdgeIterator; typedef typename EdgeContainer::const_iterator ConstEdgeIterator;
}; };
template <typename T, class CONT> template <typename T, class CONT>
struct MeshTypeHolder< T, CONT, AllTypes::AFaceType>:public T { struct MeshTypeHolder< T, CONT, AllTypes::AFaceType>:public T {
typedef CONT FaceContainer; typedef CONT FaceContainer;
typedef typename FaceContainer::value_type FaceType; typedef typename FaceContainer::value_type FaceType;
typedef typename FaceContainer::const_iterator ConstFaceIterator; typedef typename FaceContainer::const_iterator ConstFaceIterator;
typedef typename FaceContainer::iterator FaceIterator; typedef typename FaceContainer::iterator FaceIterator;
typedef FaceType * FacePointer; typedef FaceType * FacePointer;
typedef const FaceType * ConstFacePointer; typedef const FaceType * ConstFacePointer;
}; };
template <typename T, class CONT> template <typename T, class CONT>
struct MeshTypeHolder< T, CONT, AllTypes::AHEdgeType>: public T{ struct MeshTypeHolder< T, CONT, AllTypes::AHEdgeType>: public T{
typedef CONT HEdgeContainer; typedef CONT HEdgeContainer;
typedef typename HEdgeContainer::value_type HEdgeType; typedef typename HEdgeContainer::value_type HEdgeType;
typedef typename HEdgeContainer::value_type * HEdgePointer; typedef typename HEdgeContainer::value_type * HEdgePointer;
typedef typename HEdgeContainer::iterator HEdgeIterator; typedef typename HEdgeContainer::iterator HEdgeIterator;
typedef typename HEdgeContainer::const_iterator ConstHEdgeIterator; typedef typename HEdgeContainer::const_iterator ConstHEdgeIterator;
}; };
template <typename T, class CONT> template <typename T, class CONT>
struct MeshTypeHolder<T, CONT, AllTypes::ATetraType> : public T struct MeshTypeHolder<T, CONT, AllTypes::ATetraType> : public T
{ {
typedef CONT TetraContainer; typedef CONT TetraContainer;
typedef typename TetraContainer::value_type TetraType; typedef typename TetraContainer::value_type TetraType;
typedef TetraType *TetraPointer; typedef TetraType *TetraPointer;
typedef const TetraType *ConstTetraPointer; typedef const TetraType *ConstTetraPointer;
typedef typename TetraContainer::iterator TetraIterator; typedef typename TetraContainer::iterator TetraIterator;
typedef typename TetraContainer::const_iterator ConstTetraIterator; typedef typename TetraContainer::const_iterator ConstTetraIterator;
}; };
template <typename T, typename CONT> struct Der: public MeshTypeHolder<T,CONT, typename CONT::value_type::IAm>{}; template <typename T, typename CONT> struct Der: public MeshTypeHolder<T,CONT, typename CONT::value_type::IAm>{};
struct DummyContainer{struct value_type{ typedef int IAm;}; }; struct DummyContainer{struct value_type{ typedef int IAm;}; };
@ -169,7 +171,7 @@ As explained in \ref basic_concepts, this class is templated over a list of cont
template < class Container0 = DummyContainer, class Container1 = DummyContainer, class Container2 = DummyContainer, class Container3 = DummyContainer, class Container4 = DummyContainer > template < class Container0 = DummyContainer, class Container1 = DummyContainer, class Container2 = DummyContainer, class Container3 = DummyContainer, class Container4 = DummyContainer >
class TriMesh class TriMesh
: public MArity5< BaseMeshTypeHolder<typename Container0::value_type::TypesPool>, Container0, Der ,Container1, Der, Container2, Der, Container3, Der, Container4, Der >{ : public MArity5< BaseMeshTypeHolder<typename Container0::value_type::TypesPool>, Container0, Der ,Container1, Der, Container2, Der, Container3, Der, Container4, Der >{
public: public:
typedef typename TriMesh::ScalarType ScalarType; typedef typename TriMesh::ScalarType ScalarType;
typedef typename TriMesh::VertContainer VertContainer; typedef typename TriMesh::VertContainer VertContainer;
@ -188,6 +190,7 @@ class TriMesh
// types for edge // types for edge
typedef typename TriMesh::EdgeType EdgeType; typedef typename TriMesh::EdgeType EdgeType;
typedef typename TriMesh::EdgePointer EdgePointer; typedef typename TriMesh::EdgePointer EdgePointer;
typedef typename TriMesh::ConstEdgePointer ConstEdgePointer;
typedef typename TriMesh::EdgeIterator EdgeIterator; typedef typename TriMesh::EdgeIterator EdgeIterator;
typedef typename TriMesh::ConstEdgeIterator ConstEdgeIterator; typedef typename TriMesh::ConstEdgeIterator ConstEdgeIterator;
@ -414,8 +417,8 @@ public:
face.clear(); face.clear();
edge.clear(); edge.clear();
tetra.clear(); tetra.clear();
// textures.clear(); // textures.clear();
// normalmaps.clear(); // normalmaps.clear();
vn = 0; vn = 0;
en = 0; en = 0;
fn = 0; fn = 0;
@ -489,6 +492,15 @@ template <class MeshType> inline void InitVertexIMark(MeshType & m)
if( !(*vi).IsD() && (*vi).IsRW() ) if( !(*vi).IsD() && (*vi).IsRW() )
(*vi).InitIMark(); (*vi).InitIMark();
} }
/// Initialize the imark-system of the edges
template <class MeshType> inline void InitEdgeIMark(MeshType & m)
{
typename MeshType::EdgeIterator ei;
for (ei = m.edge.begin(); ei != m.edge.end(); ++ei)
if( !(*ei).IsD() && (*ei).IsRW() )
(*ei).InitIMark();
}
///initialize the imark-sysyem of the tetras ///initialize the imark-sysyem of the tetras
template <class MeshType> template <class MeshType>
@ -511,6 +523,11 @@ template <class MeshType> inline int & IMark(MeshType & m){return m.imark;}
@param v Vertex pointer */ @param v Vertex pointer */
template <class MeshType> inline bool IsMarked(MeshType & m, typename MeshType::ConstVertexPointer v ) { return v->cIMark() == m.imark; } template <class MeshType> inline bool IsMarked(MeshType & m, typename MeshType::ConstVertexPointer v ) { return v->cIMark() == m.imark; }
/** \brief Check if the edge incremental mark matches the one of the mesh.
@param m the mesh containing the element
@param e edge pointer */
template <class MeshType> inline bool IsMarked(MeshType & m, typename MeshType::ConstEdgePointer e ) { return e->cIMark() == m.imark; }
/** \brief Check if the face incremental mark matches the one of the mesh. /** \brief Check if the face incremental mark matches the one of the mesh.
@param m the mesh containing the element @param m the mesh containing the element
@param f Face pointer */ @param f Face pointer */
@ -527,6 +544,11 @@ inline bool IsMarked(MeshType &m, typename MeshType::ConstTetraPointer t) { retu
@param v Vertex pointer */ @param v Vertex pointer */
template <class MeshType> inline void Mark(MeshType & m, typename MeshType::VertexPointer v ) { v->IMark() = m.imark; } template <class MeshType> inline void Mark(MeshType & m, typename MeshType::VertexPointer v ) { v->IMark() = m.imark; }
/** \brief Set the edge incremental mark of the edge to the one of the mesh.
@param m the mesh containing the element
@param e edge pointer */
template <class MeshType> inline void Mark(MeshType & m, typename MeshType::EdgePointer e ) { e->IMark() = m.imark; }
/** \brief Set the face incremental mark of the vertex to the one of the mesh. /** \brief Set the face incremental mark of the vertex to the one of the mesh.
@param m the mesh containing the element @param m the mesh containing the element
@param f Vertex pointer */ @param f Vertex pointer */

View File

@ -27,9 +27,9 @@
#define __VCG_EDGE_PLUS_COMPONENT #define __VCG_EDGE_PLUS_COMPONENT
namespace vcg { namespace vcg {
namespace edge { namespace edge {
/** \addtogroup EdgeComponentGroup /** \addtogroup EdgeComponentGroup
@{ @{
*/ */
@ -38,10 +38,10 @@ Some naming Rules
All the Components that can be added to a vertex should be defined in the namespace edge: All the Components that can be added to a vertex should be defined in the namespace edge:
*/ */
/*------------------------- EMPTY CORE COMPONENTS -----------------------------------------*/ /*------------------------- EMPTY CORE COMPONENTS -----------------------------------------*/
template <class T> class EmptyCore: public T template <class T> class EmptyCore: public T
{ {
public: public:
inline typename T::VertexType * & V( const int j ) { (void)j; assert(0); static typename T::VertexType *vp=0; return vp; } inline typename T::VertexType * & V( const int j ) { (void)j; assert(0); static typename T::VertexType *vp=0; return vp; }
inline typename T::VertexType * const & V( const int j ) const { (void)j; assert(0); static typename T::VertexType *vp=0; return vp; } inline typename T::VertexType * const & V( const int j ) const { (void)j; assert(0); static typename T::VertexType *vp=0; return vp; }
@ -67,6 +67,8 @@ public:
inline int cIMark() const { assert(0); static int tmp=-1; return tmp;} inline int cIMark() const { assert(0); static int tmp=-1; return tmp;}
inline int &IMark() { assert(0); static int tmp=-1; return tmp;} inline int &IMark() { assert(0); static int tmp=-1; return tmp;}
static bool HasMark() { return false; } static bool HasMark() { return false; }
inline bool IsMarkEnabled( ) const { return T::EdgeType::HasMark(); }
typedef int FlagType; typedef int FlagType;
int &Flags() { static int dummyflags(0); assert(0); return dummyflags; } int &Flags() { static int dummyflags(0); assert(0); return dummyflags; }
@ -98,10 +100,10 @@ public:
template <class LeftF> template <class LeftF>
void ImportData(const LeftF & leftF) {T::ImportData(leftF);} void ImportData(const LeftF & leftF) {T::ImportData(leftF);}
static void Name(std::vector<std::string> & name){T::Name(name);} static void Name(std::vector<std::string> & name){T::Name(name);}
}; };
/*-------------------------- VertexRef ----------------------------------------*/ /*-------------------------- VertexRef ----------------------------------------*/
/*! \brief The references to the two vertexes of a edge /*! \brief The references to the two vertexes of a edge
* *
* Stored as pointers to the VertexType * Stored as pointers to the VertexType
*/ */
@ -150,7 +152,7 @@ public:
static void Name(std::vector<std::string> & name){name.push_back(std::string("VertexRef"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("VertexRef"));T::Name(name);}
private: private:
typename T::VertexType *v[2]; typename T::VertexType *v[2];
}; };
@ -170,17 +172,23 @@ public:
static bool HasMarkOcc() { return true; } static bool HasMarkOcc() { return true; }
inline void InitIMark() { _imark = 0; } inline void InitIMark() { _imark = 0; }
inline int & IMark() { return _imark;} inline int & IMark() { return _imark;}
inline const int & IMark() const {return _imark;} inline int cIMark() const { return _imark;}
template < class LeftV>
void ImportData(const LeftV & left ) { IMark() = left.IMark(); T::ImportData( left); } template < class RightValueType>
void ImportData(const RightValueType & rightE )
{
if(rightE.IsMarkEnabled())
IMark() = rightE.cIMark();
T::ImportData(rightE);
}
static void Name(std::vector<std::string> & name){name.push_back(std::string("Mark"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("Mark"));T::Name(name);}
private: private:
int _imark; int _imark;
}; };
/*------------------------- FLAGS -----------------------------------------*/ /*------------------------- FLAGS -----------------------------------------*/
/*! \brief \em Component: Per edge \b Flags /*! \brief \em Component: Per edge \b Flags
* *
* This component stores a 32 bit array of bit flags. These bit flags are used for keeping track of selection, deletion, visiting etc. \sa \ref flags for more details on common uses of flags. * This component stores a 32 bit array of bit flags. These bit flags are used for keeping track of selection, deletion, visiting etc. \sa \ref flags for more details on common uses of flags.
*/ */
@ -200,7 +208,7 @@ private:
}; };
/*-------------------------- Color ----------------------------------*/ /*-------------------------- Color ----------------------------------*/
/*! \brief \em Component: Per edge \b Color /*! \brief \em Component: Per edge \b Color
* *
* Usually most of the library expects a color stored as 4 unsigned chars (so the component you use is a \c vertex::Color4b) * Usually most of the library expects a color stored as 4 unsigned chars (so the component you use is a \c vertex::Color4b)
* but you can also use float for the color components. * but you can also use float for the color components.
@ -222,11 +230,11 @@ private:
}; };
template <class TT> class Color4b: public edge::Color<vcg::Color4b, TT> { template <class TT> class Color4b: public edge::Color<vcg::Color4b, TT> {
public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Color4b"));TT::Name(name);} public: static void Name(std::vector<std::string> & name){name.push_back(std::string("Color4b"));TT::Name(name);}
}; };
/*-------------------------- Quality ----------------------------------*/ /*-------------------------- Quality ----------------------------------*/
/*! \brief \em Component: Per edge \b quality /*! \brief \em Component: Per edge \b quality
* *
* The Quality Component is a generic place for storing a float. The term 'quality' is a bit misleading and it is due to its original storic meaning. You should intend it as a general purpose container. * The Quality Component is a generic place for storing a float. The term 'quality' is a bit misleading and it is due to its original storic meaning. You should intend it as a general purpose container.
* \sa vcg::tri::UpdateColor for methods transforming quality into colors * \sa vcg::tri::UpdateColor for methods transforming quality into colors
@ -257,15 +265,15 @@ public: static void Name(std::vector<std::string> & name){name.push_back(std::st
}; };
/*----------------------------- VEADJ ------------------------------*/ /*----------------------------- VEADJ ------------------------------*/
/*! \brief \em Component: Per vertex \b Vertex-Edge adjacency relation companion component /*! \brief \em Component: Per vertex \b Vertex-Edge adjacency relation companion component
This component implement one element of the list of edges incident on a vertex. This component implement one element of the list of edges incident on a vertex.
You must use this component only toghether with the corresponding \ref vcg::vertex::VEAdj component in the vertex type You must use this component only toghether with the corresponding \ref vcg::vertex::VEAdj component in the vertex type
\sa vcg::tri::UpdateTopology for functions that compute this relation \sa vcg::tri::UpdateTopology for functions that compute this relation
\sa iterators \sa iterators
*/ */
template <class T> class VEAdj: public T { template <class T> class VEAdj: public T {
public: public:
VEAdj(){_ep[0]=0;_ep[1]=0;_zp[0]=-1;_zp[1]=-1;} VEAdj(){_ep[0]=0;_ep[1]=0;_zp[0]=-1;_zp[1]=-1;}
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]; }
@ -278,13 +286,13 @@ public: static void Name(std::vector<std::string> & name){name.push_back(std::st
static bool HasVEAdjacencyOcc() { return true; } static bool HasVEAdjacencyOcc() { return true; }
static void Name(std::vector<std::string> & name){name.push_back(std::string("VEAdj"));T::Name(name);} static void Name(std::vector<std::string> & name){name.push_back(std::string("VEAdj"));T::Name(name);}
private: private:
typename T::EdgePointer _ep[2] ; typename T::EdgePointer _ep[2] ;
int _zp[2] ; int _zp[2] ;
}; };
/*----------------------------- EEADJ ------------------------------*/ /*----------------------------- EEADJ ------------------------------*/
/*! \brief \em Component: \b Edge-Edge adjacency relation /*! \brief \em Component: \b Edge-Edge adjacency relation
This component implement store the pointer (and index) of the adjacent edges. This component implement store the pointer (and index) of the adjacent edges.
If the vertex is 1-manifold (as in a classical polyline) If the vertex is 1-manifold (as in a classical polyline)
it holds that: it holds that:
@ -334,7 +342,7 @@ private:
}; };
/*----------------------------- EFADJ ------------------------------*/ /*----------------------------- EFADJ ------------------------------*/
/*! \brief \em Component: \b Edge-Face adjacency relation /*! \brief \em Component: \b Edge-Face adjacency relation
This component implement store the pointer to a face sharing this edge. This component implement store the pointer to a face sharing this edge.
\sa vcg::tri::UpdateTopology for functions that compute this relation \sa vcg::tri::UpdateTopology for functions that compute this relation
@ -359,7 +367,7 @@ private:
int _zp ; int _zp ;
}; };
/** @} */ // End Doxygen EdgeComponentGroup /** @} */ // End Doxygen EdgeComponentGroup
} // end namespace edge } // end namespace edge
}// end namespace vcg }// end namespace vcg
#endif #endif

View File

@ -46,6 +46,7 @@ class VTIterator
public: public:
/// The tetrahedron type /// The tetrahedron type
typedef MTTYPE TetraType; typedef MTTYPE TetraType;
typedef typename TetraType::VertexType VertexType;
private: private:
/// Pointer to a tetrahedron /// Pointer to a tetrahedron
TetraType *_vt; TetraType *_vt;
@ -54,11 +55,16 @@ private:
/// Default Constructor /// Default Constructor
public: public:
VTIterator() : _vt(0), _vi(-1){} VTIterator() : _vt(0), _vi(-1){}
/// Constructor which associates the EdgePos elementet with a face and its edge /// Constructor
VTIterator(TetraType * const tp, int const zp) VTIterator(TetraType * const tp, int const zp)
{ {
_vt=tp; _vt=tp->V(zp)->VTp();
_vi=zp; _vi=tp->V(zp)->VTi();
}
VTIterator(VertexType * const vp)
{
_vt = vp->VTp();
_vi = vp->VTi();
} }
~VTIterator(){}; ~VTIterator(){};
@ -118,6 +124,7 @@ void VVStarVT( typename TetraType::VertexPointer vp, std::vector<typename TetraT
starVec.resize(new_end - starVec.begin()); starVec.resize(new_end - starVec.begin());
} }
/** Templated over the class tetrahedron, it stores a \em position over a tetrahedron in a mesh. /** Templated over the class tetrahedron, it stores a \em position over a tetrahedron in a mesh.
It contain a pointer to the current tetrahedron, It contain a pointer to the current tetrahedron,
the index of one face,edge and a edge's incident vertex. the index of one face,edge and a edge's incident vertex.

View File

@ -0,0 +1,146 @@
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/**
@name Load and Save in Tetgen File format
*/
//@{
#ifndef __VCGLIB_TETRAEXPORT_VTK
#define __VCGLIB_TETRAEXPORT_VTK
#include <wrap/io_trimesh/precision.h>
#include <stdio.h>
namespace vcg
{
namespace tetra
{
namespace io
{
template <class SaveMeshType>
class ExporterVTK
{
public:
typedef ::vcg::ply::PropDescriptor PropDescriptor;
typedef typename SaveMeshType::VertexPointer VertexPointer;
typedef typename SaveMeshType::ScalarType ScalarType;
typedef typename SaveMeshType::VertexType VertexType;
typedef typename SaveMeshType::TetraType TetraType;
typedef typename SaveMeshType::TetraPointer TetraPointer;
typedef typename SaveMeshType::VertexIterator VertexIterator;
typedef typename SaveMeshType::TetraIterator TetraIterator;
enum
{
VTK_VERTEX = 1,
VTK_POLY_VERTEX,
VTK_LINE,
VTK_POLY_LINE,
VTK_TRIANGLE,
VTK_TRIANGLE_STRIP,
VTK_POLYGON,
VTK_PIXEL,
VTK_QUAD,
VTK_TETRA,
VTK_VOXEL,
VTK_HEXAHEDRON,
VTK_WEDGE,
VTK_PYRAMID
};
static bool Save(SaveMeshType &m, const char *filename) // V1.0
{
FILE *vtkFile;
const int DGT = vcg::tri::io::Precision<ScalarType>::digits();
const char* vttp = vcg::tri::io::Precision<ScalarType>::typeName();
std::string vtkName(filename);
vtkFile = fopen(vtkName.c_str(), "wb");
if (vtkFile == NULL)
return 1;
fprintf(vtkFile, "# vtk DataFile Version 2.0\n");
fprintf(vtkFile, "VCG_mesh\n");
fprintf(vtkFile, "ASCII\n");
fprintf(vtkFile, "DATASET UNSTRUCTURED_GRID\n");
fprintf(vtkFile, "POINTS %d %s\n", m.VN(), vttp);
int vi = 0;
SimpleTempData<typename SaveMeshType::VertContainer, int> indices(m.vert);
int maxQ = 0;
ForEachVertex(m, [&](VertexType &v) {
indices[&v] = vi++;
fprintf(vtkFile, "%g %g %g\n", v.P().X(), v.P().Y(), v.P().Z());
});
fprintf(vtkFile, "CELLS %d %d\n", m.TN(), m.TN()*5);
int ti = 0;
ForEachTetra(m, [&](SaveMeshType::TetraType &t) {
++ti;
fprintf(vtkFile, "%d %d %d %d %d\n", 4, indices[t.V(0)], indices[t.V(1)], indices[t.V(2)], indices[t.V(3)]);
});
fprintf(vtkFile, "CELL_TYPES %d\n", m.TN());
ForEachTetra(m, [&](SaveMeshType::TetraType &t) {
fprintf(vtkFile, "%d\n", VTK_TETRA);
});
if( HasPerVertexQuality(m))
{
fprintf(vtkFile, "POINT_DATA %d\n", m.VN());
fprintf(vtkFile, "SCALARS vquality %s 1\n", vttp);
fprintf(vtkFile, "LOOKUP_TABLE default\n");
ForEachVertex(m, [&](VertexType &v) {
fprintf(vtkFile, "%g\n", v.Q());
});
}
if( HasPerTetraQuality(m))
{
fprintf(vtkFile, "CELL_DATA %d\n", m.TN());
fprintf(vtkFile, "SCALARS tquality %s 1\n", vttp);
fprintf(vtkFile, "LOOKUP_TABLE default\n");
ForEachTetra(m, [&](TetraType &t) {
fprintf(vtkFile, "%g\n", t.Q());
});
}
fclose(vtkFile);
return 0;
}
}; // end class
} // namespace io
} // namespace tetra
} // end namespace vcg
#endif