Subversion Repositories gelsvn

Rev

Rev 122 | 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
 
120 jab 128
	typedef Face_template<Iters> Face;
129
	typedef HalfEdge_template<Iters> HalfEdge;
130
	typedef Vertex_template<Iters> Vertex;
39 bj 131
 
120 jab 132
	typedef Iters::FaceList FaceList;
133
	typedef Iters::HalfEdgeList HalfEdgeList;
134
	typedef Iters::VertexList VertexList;
135
 
136
	typedef Iters::FaceIter FaceIter;
137
	typedef Iters::HalfEdgeIter HalfEdgeIter;
138
	typedef Iters::VertexIter VertexIter;
139
 
122 jab 140
	inline FaceIter get_null_face_iter()
141
			{
142
					static FaceList l;
143
					return l.end();
144
			}
145
 
146
	inline VertexIter get_null_vertex_iter()
147
			{
148
					static VertexList l;
149
					return l.end();
150
			}
151
 
152
 
153
	inline HalfEdgeIter get_null_halfedge_iter()
154
			{
155
					static HalfEdgeList l;
156
					return l.end();
157
			}
158
 
159
 
121 jab 160
#define NULL_FACE_ITER HMesh::get_null_face_iter() 
161
#define NULL_HALFEDGE_ITER HMesh::get_null_halfedge_iter() 
162
#define NULL_VERTEX_ITER HMesh::get_null_vertex_iter()
120 jab 163
 
164
 
39 bj 165
}
166
#endif