Subversion Repositories gelsvn

Rev

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

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