Subversion Repositories gelsvn

Rev

Rev 67 | Blame | Compare with Previous | 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. */

                /** \struct Vertex
                 */
                template<class R>
                struct Vertex_template
                {
                                typedef typename R::VertexIter VertexIter;
                                typedef typename R::FaceIter FaceIter;
                                typedef typename R::HalfEdgeIter HalfEdgeIter;

                                /// Constructor, argument is vertex position
                                Vertex_template(const CGLA::Vec3f&);

                                /// Outgoing halfedge
                                HalfEdgeIter he;

                                /// Geometric vertex position
                                CGLA::Vec3f pos;

                                /// General purpose integer. Normally used as index or flag.
                                int touched;
                };

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

                                /// Constructor
                                HalfEdge_template();

                                /// Vertex pointed to by this halfedge.
                                VertexIter   vert;

                                /// Next halfedge in face loop.
                                HalfEdgeIter next;

                                /// Previous halfedge in face loop.
                                HalfEdgeIter prev;

                                /// Face owning this halfedge
                                FaceIter     face;

                                /// Opposite halfedge
                                HalfEdgeIter opp;

                                /// General purpose integer. Normally used as index or flag.
                                int touched;

                };

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

                                /// Constructor
                                Face_template();

                                /// Last is just some halfedge in the face loop.
                                HalfEdgeIter last;

                                /// General purpose integer. Normally used as index or flag.
                                int touched;
                };

                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