Subversion Repositories gelsvn

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

#ifndef __ITERS_H
#define __ITERS_H

#include "CGLA/Vec3f.h"
#include <list>


namespace HMesh
{
        /* A nasty template trick:

                 The halfedge data structure is based on pointers. Thus, for instance,
                 a halfedge contains pointers to several other halfedges, a face, and
                 a vertex. However, the entities (faces, edges, vertices) are stored in
                 linked lists. This enables easy insertion and removal, but we would
                 like to be able to take the halfedge pointer stored in, say, a 
                 halfedge and find the position in the linked list in order to remove the
                 halfedge from the list. This is not possible since the list is implemented
                 using STL and what we need is really an iterator to the list element
                 containing the halfedge.

                 The solution is, of course, to store iterators instead of pointers, but
                 that solution is problematic because we cannot define an iterator to a 
                 list of halfedges in the definition of the halfedge class. The solution
                 is to let a template argument define the halfedge iterator type.
                 
                 Thus the Iters class instantiates HalfEdge_template with itself while it 
                 also defines the required iterators etc. Strange but legal C++.

                 This is the best solution I could come up with - since I really wanted 
                 to use STL to store the elements. The solution is similar to what is 
                 used in CGAL and OpenMesh both of which provided inspiration. */
        
        template<class R>
                struct Vertex_template
                {
                        typedef typename R::VertexIter VertexIter;
                        typedef typename R::FaceIter FaceIter;
                        typedef typename R::HalfEdgeIter HalfEdgeIter;

                        HalfEdgeIter he;
                        CGLA::Vec3f pos;

                        Vertex_template(const CGLA::Vec3f&);

                        bool is_boundary();
                        void check_boundary_consistency();

                        const CGLA::Vec3f& get_pos() const {return pos;}
                        void set_pos(const CGLA::Vec3f& _pos) {pos=_pos;}

                        int touched;
                };

        template<class R>
                struct HalfEdge_template
                {
                        typedef typename R::VertexIter VertexIter;
                        typedef typename R::FaceIter FaceIter;
                        typedef typename R::HalfEdgeIter HalfEdgeIter;

                        VertexIter   vert;
                        HalfEdgeIter next;
                        HalfEdgeIter prev;

                        FaceIter     face;
                        HalfEdgeIter opp;

                        bool is_boundary();
                        int touched;

                        HalfEdge_template();
                };

        template<class R>
                struct Face_template
                {
                        typedef typename R::VertexIter VertexIter;
                        typedef typename R::FaceIter FaceIter;
                        typedef typename R::HalfEdgeIter HalfEdgeIter;

                        HalfEdgeIter last;
                        int touched;

                        Face_template();
                };

        struct Iters
        {
                typedef Vertex_template<Iters> V;
                typedef HalfEdge_template<Iters> HE;
                typedef Face_template<Iters> F;
        
                typedef std::list<V> VertexList;
                typedef std::list<HE> HalfEdgeList;
                typedef std::list<F> FaceList;

                typedef VertexList::iterator VertexIter;
                typedef HalfEdgeList::iterator HalfEdgeIter;
                typedef FaceList::iterator FaceIter;
        };



}
#endif