aimsalgo 6.0.0
Neuroimaging image processing
geodesic_mesh_elements.h
Go to the documentation of this file.
1//Copyright (C) 2008 Danil Kirsanov, MIT License
2#ifndef GEODESIC_MESH_ELEMENTS_20071231
3#define GEODESIC_MESH_ELEMENTS_20071231
4
5// here we define the building elements of the mesh:
6// 3D-points, vertices, edges, faces, and surface points
7
8#include <assert.h>
9#include <cstddef>
10
11namespace geodesic{
12
13class Vertex;
14class Edge;
15class Face;
16class Mesh;
17class MeshElementBase;
18
24
25template <class Data> //simple vector that stores info about mesh references
26class SimpleVector //for efficiency, it uses an outside memory allocator
27{
28public:
30 m_size(0),
31 m_begin(NULL)
32 {};
33
34 typedef Data* iterator;
35
36 unsigned size(){return m_size;};
37 iterator begin(){return m_begin;};
38 iterator end(){return m_begin + m_size;};
39
40 template<class DataPointer>
41 void set_allocation(DataPointer begin, unsigned size)
42 {
43 assert(begin != NULL || size == 0);
44 m_size = size;
45 m_begin = (iterator)begin;
46 }
47
48 Data& operator[](unsigned i)
49 {
50 assert(i < m_size);
51 return *(m_begin + i);
52 }
53
54 void clear()
55 {
56 m_size = 0;
57 m_begin = NULL;
58 }
59
60private:
61 unsigned m_size;
62 Data* m_begin;
63};
64
72
73class MeshElementBase //prototype of vertices, edges and faces
74{
75public:
79
84
88
89 unsigned& id(){return m_id;};
90 PointType type(){return m_type;};
91
92protected:
93 vertex_pointer_vector m_adjacent_vertices; //list of the adjacent vertices
94 edge_pointer_vector m_adjacent_edges; //list of the adjacent edges
95 face_pointer_vector m_adjacent_faces; //list of the adjacent faces
96
97 unsigned m_id; //unique id
98 PointType m_type; //vertex, edge or face
99};
100
101class Point3D //point in 3D and corresponding operations
102{
103public:
106 {
107 x() = p->x();
108 y() = p->y();
109 z() = p->z();
110 };
111
112 double* xyz(){return m_coordinates;};
113 double& x(){return *m_coordinates;};
114 double& y(){return *(m_coordinates+1);};
115 double& z(){return *(m_coordinates+2);};
116
117 void set(double new_x, double new_y, double new_z)
118 {
119 x() = new_x;
120 y() = new_y;
121 z() = new_z;
122 }
123
124 void set(double* data)
125 {
126 x() = *data;
127 y() = *(data+1);
128 z() = *(data+2);
129 }
130
131 double distance(double* v)
132 {
133 double dx = m_coordinates[0] - v[0];
134 double dy = m_coordinates[1] - v[1];
135 double dz = m_coordinates[2] - v[2];
136
137 return sqrt(dx*dx + dy*dy + dz*dz);
138 };
139
140 double distance(Point3D* v)
141 {
142 return distance(v->xyz());
143 };
144
145 void add(Point3D* v)
146 {
147 x() += v->x();
148 y() += v->y();
149 z() += v->z();
150 };
151
152 void multiply(double v)
153 {
154 x() *= v;
155 y() *= v;
156 z() *= v;
157 };
158
159private:
160 double m_coordinates[3]; //xyz
161};
162
163class Vertex: public MeshElementBase, public Point3D
164{
165public:
167 {
168 m_type = VERTEX;
169 };
170
172
173 bool& saddle_or_boundary(){return m_saddle_or_boundary;};
174private:
175 //this flag speeds up exact geodesic algorithm
176 bool m_saddle_or_boundary; //it is true if total adjacent angle is larger than 2*PI or this vertex belongs to the mesh boundary
177};
178
179
181{
182public:
184 {
185 m_type = FACE;
186 };
187
188 ~Face(){};
189
193
195 {
196 for(unsigned i=0; i<3; ++i)
197 {
198 if(adjacent_vertices()[i]->id() == v->id())
199 {
200 return m_corner_angles[i];
201 }
202 }
203 assert(0);
204 return 0;
205 }
206
207 double* corner_angles(){return m_corner_angles;};
208
209private:
210 double m_corner_angles[3]; //triangle angles in radians; angles correspond to vertices in m_adjacent_vertices
211};
212
214{
215public:
217 {
218 m_type = EDGE;
219 };
220
221 ~Edge(){};
222
223 double& length(){return m_length;};
224
226 {
227 if(adjacent_faces().size() == 1)
228 {
229 assert(adjacent_faces()[0]->id() == f->id());
230 return NULL;
231 }
232
233 assert(adjacent_faces()[0]->id() == f->id() ||
234 adjacent_faces()[1]->id() == f->id());
235
236 return adjacent_faces()[0]->id() == f->id() ?
237 adjacent_faces()[1] : adjacent_faces()[0];
238 };
239
241 {
242 assert(belongs(v));
243
244 return adjacent_vertices()[0]->id() == v->id() ?
246 };
247
249 {
250 return adjacent_vertices()[0]->id() == v->id() ||
251 adjacent_vertices()[1]->id() == v->id();
252 }
253
254 bool is_boundary(){return adjacent_faces().size() == 1;};
255
258
260 double& x,
261 double& y)
262 {
263 double d0 = point->distance(v0());
264 if(d0 < 1e-50)
265 {
266 x = 0.0;
267 y = 0.0;
268 return;
269 }
270
271 double d1 = point->distance(v1());
272 if(d1 < 1e-50)
273 {
274 x = m_length;
275 y = 0.0;
276 return;
277 }
278
279 x = m_length/2.0 + (d0*d0 - d1*d1)/(2.0*m_length);
280 y = sqrt(std::max(0.0, d0*d0 - x*x));
281 return;
282 }
283
284private:
285 double m_length; //length of the edge
286};
287
288class SurfacePoint:public Point3D //point on the surface of the mesh
289{
290public:
292 m_p(NULL)
293 {};
294
295 SurfacePoint(vertex_pointer v): //set the surface point in the vertex
297 m_p(v)
298 {};
299
300 SurfacePoint(face_pointer f): //set the surface point in the center of the face
301 m_p(f)
302 {
303 set(0,0,0);
304 add(f->adjacent_vertices()[0]);
305 add(f->adjacent_vertices()[1]);
306 add(f->adjacent_vertices()[2]);
307 multiply(1./3.);
308 };
309
310 SurfacePoint(edge_pointer e, //set the surface point in the middle of the edge
311 double a = 0.5):
312 m_p(e)
313 {
314 double b = 1 - a;
315
318
319 x() = b*v0->x() + a*v1->x();
320 y() = b*v0->y() + a*v1->y();
321 z() = b*v0->z() + a*v1->z();
322 };
323
325 double x,
326 double y,
327 double z,
329 m_p(g)
330 {
331 set(x,y,z);
332 t=t;
333 };
334
336 {
337 *this = p;
338 }
339
341
342 PointType type(){return m_p ? m_p->type() : UNDEFINED_POINT;};
344protected:
345 base_pointer m_p; //could be face, vertex or edge pointer
346};
347
349{
350 for(unsigned i=0; i<3; ++i)
351 {
353 if(!e->belongs(v))
354 {
355 return e;
356 }
357 }
358 assert(0);
359 return NULL;
360}
361
363{
364 for(unsigned i=0; i<3; ++i)
365 {
367 if(!e->belongs(v))
368 {
369 return v;
370 }
371 }
372 assert(0);
373 return NULL;
374}
375
377{
378 assert(e->belongs(v));
379
380 for(unsigned i=0; i<3; ++i)
381 {
382 edge_pointer next = adjacent_edges()[i];
383 if(e->id() != next->id() && next->belongs(v))
384 {
385 return next;
386 }
387 }
388 assert(0);
389 return NULL;
390}
391
392struct HalfEdge //prototype of the edge; used for mesh construction
393{
394 unsigned face_id;
395 unsigned vertex_0; //adjacent vertices sorted by id value
396 unsigned vertex_1; //they are sorted, vertex_0 < vertex_1
397};
398
399inline bool operator < (const HalfEdge &x, const HalfEdge &y)
400{
401 if(x.vertex_0 == y.vertex_0)
402 {
403 return x.vertex_1 < y.vertex_1;
404 }
405 else
406 {
407 return x.vertex_0 < y.vertex_0;
408 }
409}
410
411inline bool operator != (const HalfEdge &x, const HalfEdge &y)
412{
413 return x.vertex_0 != y.vertex_0 || x.vertex_1 != y.vertex_1;
414}
415
416inline bool operator == (const HalfEdge &x, const HalfEdge &y)
417{
418 return x.vertex_0 == y.vertex_0 && x.vertex_1 == y.vertex_1;
419}
420
421} //geodesic
422
423#endif
bool belongs(vertex_pointer v)
vertex_pointer opposite_vertex(vertex_pointer v)
void local_coordinates(Point3D *point, double &x, double &y)
face_pointer opposite_face(face_pointer f)
vertex_pointer opposite_vertex(edge_pointer e)
edge_pointer opposite_edge(vertex_pointer v)
edge_pointer next_edge(edge_pointer e, vertex_pointer v)
double vertex_angle(vertex_pointer v)
edge_pointer_vector m_adjacent_edges
SimpleVector< edge_pointer > edge_pointer_vector
edge_pointer_vector & adjacent_edges()
vertex_pointer_vector & adjacent_vertices()
SimpleVector< face_pointer > face_pointer_vector
face_pointer_vector m_adjacent_faces
SimpleVector< vertex_pointer > vertex_pointer_vector
face_pointer_vector & adjacent_faces()
vertex_pointer_vector m_adjacent_vertices
void set(double new_x, double new_y, double new_z)
double distance(double *v)
double distance(Point3D *v)
void set_allocation(DataPointer begin, unsigned size)
SurfacePoint(base_pointer g, double x, double y, double z, PointType t=UNDEFINED_POINT)
SurfacePoint(edge_pointer e, double a=0.5)
void initialize(SurfacePoint const &p)
MeshElementBase * base_pointer
bool operator<(const HalfEdge &x, const HalfEdge &y)
bool operator==(const HalfEdge &x, const HalfEdge &y)
bool operator!=(const HalfEdge &x, const HalfEdge &y)
Vertex * vertex_pointer