Subversion Repositories gelsvn

Rev

Rev 89 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
39 bj 1
#ifndef __ITERS_H
2
#define __ITERS_H
3
 
4
#include "CGLA/Vec3f.h"
5
#include <list>
6
 
7
 
8
namespace HMesh
9
{
62 jab 10
		/* A nasty template trick:
39 bj 11
 
62 jab 12
		The halfedge data structure is based on pointers. Thus, for instance,
13
		a halfedge contains pointers to several other halfedges, a face, and
14
		a vertex. However, the entities (faces, edges, vertices) are stored in
15
		linked lists. This enables easy insertion and removal, but we would
16
		like to be able to take the halfedge pointer stored in, say, a 
17
		halfedge and find the position in the linked list in order to remove the
18
		halfedge from the list. This is not possible since the list is implemented
19
		using STL and what we need is really an iterator to the list element
20
		containing the halfedge.
39 bj 21
 
62 jab 22
		The solution is, of course, to store iterators instead of pointers, but
23
		that solution is problematic because we cannot define an iterator to a 
24
		list of halfedges in the definition of the halfedge class. The solution
25
		is to let a template argument define the halfedge iterator type.
39 bj 26
 
62 jab 27
		Thus the Iters class instantiates HalfEdge_template with itself while it 
28
		also defines the required iterators etc. Strange but legal C++.
39 bj 29
 
62 jab 30
		This is the best solution I could come up with - since I really wanted 
31
		to use STL to store the elements. The solution is similar to what is 
32
		used in CGAL and OpenMesh both of which provided inspiration. */
89 jab 33
 
115 jab 34
 
35
		/** Type used for the touch variables of halfedges, vertices, and faces.
36
				The touch variables are used to contain various data such as counters,
37
				indices, flags. In some cases it is useful to touch with the value
38
				of a pointer cast to an integer. However, this means that the 
39
				integer size must be the same as the pointer size. Using "intptr_t"
40
				ensures this. */
41
		typedef intptr_t TouchType;
42
 
89 jab 43
		/** \struct Vertex
44
		 */
62 jab 45
		template<class R>
39 bj 46
		struct Vertex_template
47
		{
62 jab 48
				typedef typename R::VertexIter VertexIter;
49
				typedef typename R::FaceIter FaceIter;
50
				typedef typename R::HalfEdgeIter HalfEdgeIter;
39 bj 51
 
62 jab 52
				/// Constructor, argument is vertex position
53
				Vertex_template(const CGLA::Vec3f&);
39 bj 54
 
62 jab 55
				/// Outgoing halfedge
56
				HalfEdgeIter he;
39 bj 57
 
62 jab 58
				/// Geometric vertex position
59
				CGLA::Vec3f pos;
39 bj 60
 
62 jab 61
				/// General purpose integer. Normally used as index or flag.
115 jab 62
				TouchType touched;
39 bj 63
		};
64
 
62 jab 65
		template<class R>
39 bj 66
		struct HalfEdge_template
67
		{
62 jab 68
				typedef typename R::VertexIter VertexIter;
69
				typedef typename R::FaceIter FaceIter;
70
				typedef typename R::HalfEdgeIter HalfEdgeIter;
39 bj 71
 
62 jab 72
				/// Constructor
73
				HalfEdge_template();
39 bj 74
 
62 jab 75
				/// Vertex pointed to by this halfedge.
76
				VertexIter   vert;
39 bj 77
 
62 jab 78
				/// Next halfedge in face loop.
79
				HalfEdgeIter next;
39 bj 80
 
62 jab 81
				/// Previous halfedge in face loop.
82
				HalfEdgeIter prev;
83
 
84
				/// Face owning this halfedge
85
				FaceIter     face;
86
 
87
				/// Opposite halfedge
88
				HalfEdgeIter opp;
89
 
90
				/// General purpose integer. Normally used as index or flag.
115 jab 91
				TouchType touched;
62 jab 92
 
39 bj 93
		};
94
 
62 jab 95
		template<class R>
39 bj 96
		struct Face_template
97
		{
62 jab 98
				typedef typename R::VertexIter VertexIter;
99
				typedef typename R::FaceIter FaceIter;
100
				typedef typename R::HalfEdgeIter HalfEdgeIter;
39 bj 101
 
62 jab 102
				/// Constructor
103
				Face_template();
39 bj 104
 
62 jab 105
				/// Last is just some halfedge in the face loop.
106
				HalfEdgeIter last;
107
 
108
				/// General purpose integer. Normally used as index or flag.
115 jab 109
				TouchType touched;
39 bj 110
		};
111
 
62 jab 112
		struct Iters
113
		{
114
				typedef Vertex_template<Iters> V;
115
				typedef HalfEdge_template<Iters> HE;
116
				typedef Face_template<Iters> F;
39 bj 117
 
62 jab 118
				typedef std::list<V> VertexList;
119
				typedef std::list<HE> HalfEdgeList;
120
				typedef std::list<F> FaceList;
39 bj 121
 
62 jab 122
				typedef VertexList::iterator VertexIter;
123
				typedef HalfEdgeList::iterator HalfEdgeIter;
124
				typedef FaceList::iterator FaceIter;
125
		};
39 bj 126
 
127
 
128
 
129
}
130
#endif