Subversion Repositories gelsvn

Rev

Rev 195 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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