Subversion Repositories gelsvn

Rev

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

Rev 443 Rev 595
-
 
1
/* ----------------------------------------------------------------------- *
-
 
2
 * This file is part of GEL, http://www.imm.dtu.dk/GEL
-
 
3
 * Copyright (C) the authors and DTU Informatics
-
 
4
 * For license and list of authors, see ../../doc/intro.pdf
-
 
5
 * ----------------------------------------------------------------------- */
-
 
6
 
1
#ifndef __GEOMETRY_GRIDALGORITHM_H
7
#ifndef __GEOMETRY_GRIDALGORITHM_H
2
#define __GEOMETRY_GRIDALGORITHM_H
8
#define __GEOMETRY_GRIDALGORITHM_H
3
 
9
 
-
 
10
/**
-
 
11
 * @file GridAlgorithm.h
-
 
12
 * A number of algorithms for traversing a voxel grid. The algorithms are 
-
 
13
 * generally transformative and allow us to invoke a function on each.
-
 
14
 */
-
 
15
 
4
/*
16
/*
5
Functions:
17
Functions:
6
 
18
 
7
  void for_each_voxel(Grid& g, F& f);
19
  void for_each_voxel(Grid& g, F& f);
8
  void for_each_voxel(Grid& g,	const Vec3i& p0,	const Vec3i& p7, F& f);
20
  void for_each_voxel(Grid& g,	const Vec3i& p0,	const Vec3i& p7, F& f);
9
  void for_each_voxel_ordered(Grid& g, const Vec3i& p0, const Vec3i& p7, F& f);
21
  void for_each_voxel_ordered(Grid& g, const Vec3i& p0, const Vec3i& p7, F& f);
10
  void for_each_voxel_ordered(Grid& g,	F&);
22
  void for_each_voxel_ordered(Grid& g,	F&);
11
  void for_each_voxel_const(const Grid& g, 
23
  void for_each_voxel_const(const Grid& g, 
12
														const Vec3i& p0, const Vec3i& p7, F& f);
24
														const Vec3i& p0, const Vec3i& p7, F& f);
13
  void for_each_voxel_const(const Grid& g,	F& f);
25
  void for_each_voxel_const(const Grid& g,	F& f);
14
  void for_each_voxel_ordered_const(Grid& g, 
26
  void for_each_voxel_ordered_const(Grid& g, 
15
																		const Vec3i& p0, const Vec3i& p7, 
27
																		const Vec3i& p0, const Vec3i& p7, 
16
																		F& f);
28
																		F& f);
17
  void for_each_voxel_ordered_const(Grid& g, F& f);
29
  void for_each_voxel_ordered_const(Grid& g, F& f);
18
 
30
 
19
Purpose:  
31
Purpose:  
20
----------
32
----------
21
 
33
 
22
Visit all voxels (or voxels in a region og interest) in grid. A function 
34
Visit all voxels (or voxels in a region og interest) in grid. A function 
23
is invoked on each voxel. 
35
is invoked on each voxel. 
24
 
36
 
25
The "ordered" functions traverse the grid in a systematic way: A
37
The "ordered" functions traverse the grid in a systematic way: A
26
slice at a time and for each slice one row at a time. The other
38
slice at a time and for each slice one row at a time. The other
27
functions make no guarantees about how the volume (roi) is traversed. 
39
functions make no guarantees about how the volume (roi) is traversed. 
28
 
40
 
29
Types: 
41
Types: 
30
----------
42
----------
31
 
43
 
32
Grid - a grid type, either HGrid<T,CellT> or RGrid<T>
44
Grid - a grid type, either HGrid<T,CellT> or RGrid<T>
33
 
45
 
34
F - functor type a funtion or class with the function call operator 
46
F - functor type a funtion or class with the function call operator 
35
overloaded. The functor should look either like this
47
overloaded. The functor should look either like this
36
 
48
 
37
void fun(const Vec3i&, T& x)
49
void fun(const Vec3i&, T& x)
38
 
50
 
39
or this
51
or this
40
 
52
 
41
void fun(const Vec3i&, const T& x)
53
void fun(const Vec3i&, const T& x)
42
 
54
 
43
in the case of the const functions.
55
in the case of the const functions.
44
 
56
 
45
Arguments:
57
Arguments:
46
----------
58
----------
47
 
59
 
48
g  - The voxel grid, we wish to traverse.
60
g  - The voxel grid, we wish to traverse.
49
p0 - (xmin, ymin, zmin) coordinates of the window we wish to
61
p0 - (xmin, ymin, zmin) coordinates of the window we wish to
50
     traverse.
62
     traverse.
51
p7 - (xmax, ymax, zmax) coordinates of the window we wish to
63
p7 - (xmax, ymax, zmax) coordinates of the window we wish to
52
     traverse.
64
     traverse.
53
f  - functor.
65
f  - functor.
54
 
66
 
55
*/
67
*/
56
 
68
 
57
#include <iostream>
69
#include <iostream>
58
#include "RGrid.h"
70
#include "RGrid.h"
59
#include "HGrid.h"
71
#include "HGrid.h"
60
 
72
 
61
namespace Geometry 
73
namespace Geometry 
62
{
74
{
63
	template<class T, class F>
75
	template<class T, class F>
64
	void _for_each_voxel(T* data, 
76
	void _for_each_voxel(T* data, 
65
											 int x_dim, int xy_dim,
77
											 int x_dim, int xy_dim,
66
											 const CGLA::Vec3i& p0, 
78
											 const CGLA::Vec3i& p0, 
67
											 const CGLA::Vec3i& p7,
79
											 const CGLA::Vec3i& p7,
68
											 F& functor,
80
											 F& functor,
69
											 const CGLA::Vec3i& offset = CGLA::Vec3i(0))
81
											 const CGLA::Vec3i& offset = CGLA::Vec3i(0))
70
	{
82
	{
71
		const int Amin = p0[2]*xy_dim;
83
		const int Amin = p0[2]*xy_dim;
72
		const int Amax = p7[2]*xy_dim;
84
		const int Amax = p7[2]*xy_dim;
73
		int Bmin = Amin +p0[1]*x_dim;
85
		int Bmin = Amin +p0[1]*x_dim;
74
		int Bmax = Amin +p7[1]*x_dim; 
86
		int Bmax = Amin +p7[1]*x_dim; 
75
		CGLA::Vec3i p0o = p0+offset;
87
		CGLA::Vec3i p0o = p0+offset;
76
		CGLA::Vec3i p(p0o);
88
		CGLA::Vec3i p(p0o);
77
		for(int A=Amin; A<Amax; A+=xy_dim, ++p[2])
89
		for(int A=Amin; A<Amax; A+=xy_dim, ++p[2])
78
			{
90
			{
79
				p[1] = p0o[1];
91
				p[1] = p0o[1];
80
				for(int B = Bmin; B<Bmax; B+=x_dim, ++p[1])
92
				for(int B = Bmin; B<Bmax; B+=x_dim, ++p[1])
81
					{
93
					{
82
						p[0] = p0o[0];
94
						p[0] = p0o[0];
83
						int Cmin = B+p0[0];
95
						int Cmin = B+p0[0];
84
						int Cmax = B+p7[0];
96
						int Cmax = B+p7[0];
85
						for(int C=Cmin; C<Cmax; ++C, ++p[0])
97
						for(int C=Cmin; C<Cmax; ++C, ++p[0])
86
							functor(p, data[C]);
98
							functor(p, data[C]);
87
					}
99
					}
88
				Bmin += xy_dim;
100
				Bmin += xy_dim;
89
				Bmax += xy_dim;
101
				Bmax += xy_dim;
90
			}
102
			}
91
	}
103
	}
92
 
104
 
93
	template<class T, class F>
105
	template<class T, class F>
94
	void _for_each_voxel(T* data, 
106
	void _for_each_voxel(T* data, 
95
											 const CGLA::Vec3i& dims,
107
											 const CGLA::Vec3i& dims,
96
											 F& functor,
108
											 F& functor,
97
											 const CGLA::Vec3i& offset = CGLA::Vec3i(0))
109
											 const CGLA::Vec3i& offset = CGLA::Vec3i(0))
98
	{
110
	{
99
		int l=0;
111
		int l=0;
100
		CGLA::Vec3i p(offset);
112
		CGLA::Vec3i p(offset);
101
		CGLA::Vec3i p7(offset);
113
		CGLA::Vec3i p7(offset);
102
		p7 += dims;
114
		p7 += dims;
103
 
115
 
104
		for(;                   p[2]<p7[2]; ++p[2])
116
		for(;                   p[2]<p7[2]; ++p[2])
105
			for(p[1]=offset[1];   p[1]<p7[1]; ++p[1])
117
			for(p[1]=offset[1];   p[1]<p7[1]; ++p[1])
106
				for(p[0]=offset[0]; p[0]<p7[0]; ++p[0])
118
				for(p[0]=offset[0]; p[0]<p7[0]; ++p[0])
107
					functor(p, data[l++]);
119
					functor(p, data[l++]);
108
	}
120
	}
109
 
121
 
110
 
122
 
111
	/** Loop over all voxels in a sub-region (slice) of an
123
	/** Loop over all voxels in a sub-region (slice) of an
112
			RGrid and invoke a functor on each voxel. 
124
			RGrid and invoke a functor on each voxel. 
113
			The grid is the first argument, the slice is
125
			The grid is the first argument, the slice is
114
			specified by the two subsequent args, and the functor 
126
			specified by the two subsequent args, and the functor 
115
			is the last argument. */
127
			is the last argument. */
116
	template<class T, class F>
128
	template<class T, class F>
117
	void for_each_voxel(RGrid<T>& grid,
129
	void for_each_voxel(RGrid<T>& grid,
118
											const CGLA::Vec3i& p0, 
130
											const CGLA::Vec3i& p0, 
119
											const CGLA::Vec3i& p7,
131
											const CGLA::Vec3i& p7,
120
											F& functor)
132
											F& functor)
121
	{
133
	{
122
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
134
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
123
										CGLA::v_max(p0, CGLA::Vec3i(0)),
135
										CGLA::v_max(p0, CGLA::Vec3i(0)),
124
										CGLA::v_min(p7, grid.get_dims()), 
136
										CGLA::v_min(p7, grid.get_dims()), 
125
										functor);
137
										functor);
126
	}
138
	}
127
 
139
 
128
	/** Loop over all voxels in an entire	RGrid. 
140
	/** Loop over all voxels in an entire	RGrid. 
129
			Grid is the first argument, and a functor is 
141
			Grid is the first argument, and a functor is 
130
			the second.	For each voxel, an operation 
142
			the second.	For each voxel, an operation 
131
			specified by the functor is performed. */
143
			specified by the functor is performed. */
132
	template<class T, class F>
144
	template<class T, class F>
133
	void for_each_voxel(RGrid<T>& grid,	F& functor)
145
	void for_each_voxel(RGrid<T>& grid,	F& functor)
134
	{
146
	{
135
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
147
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
136
	}
148
	}
137
 
149
 
138
 
150
 
139
	/** For each voxel (ordered). The idea of ordered traversal is 
151
	/** For each voxel (ordered). The idea of ordered traversal is 
140
			that we traverse the volume in a systematic fashion as opposed
152
			that we traverse the volume in a systematic fashion as opposed
141
			to traversing simply according to the memory layout of the volume
153
			to traversing simply according to the memory layout of the volume
142
			data structure. This is important e.g. if we want to save the 
154
			data structure. This is important e.g. if we want to save the 
143
			volume in raw format. 
155
			volume in raw format. 
144
			For an RGrid, there is no difference though.
156
			For an RGrid, there is no difference though.
145
	*/ 
157
	*/ 
146
	template<class T, class F>
158
	template<class T, class F>
147
	void for_each_voxel_ordered(RGrid<T>& grid,
159
	void for_each_voxel_ordered(RGrid<T>& grid,
148
															const CGLA::Vec3i& p0, 
160
															const CGLA::Vec3i& p0, 
149
															const CGLA::Vec3i& p7,
161
															const CGLA::Vec3i& p7,
150
															F& functor)
162
															F& functor)
151
	{
163
	{
152
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
164
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
153
										CGLA::v_max(p0, CGLA::Vec3i(0)),
165
										CGLA::v_max(p0, CGLA::Vec3i(0)),
154
										CGLA::v_min(p7, grid.get_dims()), 
166
										CGLA::v_min(p7, grid.get_dims()), 
155
										functor);
167
										functor);
156
	}
168
	}
157
 
169
 
158
	template<class T, class F>
170
	template<class T, class F>
159
	void for_each_voxel_ordered(RGrid<T>& grid,	F& functor)
171
	void for_each_voxel_ordered(RGrid<T>& grid,	F& functor)
160
	{
172
	{
161
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
173
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
162
	}
174
	}
163
 
175
 
164
 
176
 
165
	template<class T, class CellT, class F>
177
	template<class T, class CellT, class F>
166
	void for_each_cell(HGrid<T,CellT>& grid,
178
	void for_each_cell(HGrid<T,CellT>& grid,
167
										 const CGLA::Vec3i& p0, 
179
										 const CGLA::Vec3i& p0, 
168
										 const CGLA::Vec3i& p7,
180
										 const CGLA::Vec3i& p7,
169
										 F& functor)
181
										 F& functor)
170
	{
182
	{
171
		CGLA::Vec3i p0t = p0/grid.get_bottom_dim();
183
		CGLA::Vec3i p0t = p0/grid.get_bottom_dim();
172
		CGLA::Vec3i p7t = CGLA::v_min(p7/grid.get_bottom_dim()+
184
		CGLA::Vec3i p7t = CGLA::v_min(p7/grid.get_bottom_dim()+
173
																	CGLA::Vec3i(1),
185
																	CGLA::Vec3i(1),
174
																	grid.get_top_dims());
186
																	grid.get_top_dims());
175
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; ++pt[2])
187
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; ++pt[2])
176
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; ++pt[1])
188
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; ++pt[1])
177
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; ++pt[0])
189
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; ++pt[0])
178
					functor(pt*CellT::get_dim(), grid.get_cell(pt));
190
					functor(pt*CellT::get_dim(), grid.get_cell(pt));
179
	}
191
	}
180
 
192
 
181
	template<class T, class CellT, class F>
193
	template<class T, class CellT, class F>
182
	void for_each_cell(HGrid<T,CellT>& grid,
194
	void for_each_cell(HGrid<T,CellT>& grid,
183
										 F& functor)
195
										 F& functor)
184
	{
196
	{
185
		CGLA::Vec3i p0t;
197
		CGLA::Vec3i p0t;
186
		CGLA::Vec3i p7t =	grid.get_dims();
198
		CGLA::Vec3i p7t =	grid.get_dims();
187
		const int inc = CellT::get_dim();
199
		const int inc = CellT::get_dim();
188
		int l=0;
200
		int l=0;
189
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; pt[2]+=inc)
201
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; pt[2]+=inc)
190
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; pt[1]+=inc)
202
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; pt[1]+=inc)
191
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; pt[0]+=inc)
203
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; pt[0]+=inc)
192
					functor(pt, grid.get_cell(l++));
204
					functor(pt, grid.get_cell(l++));
193
	}
205
	}
194
 
206
 
195
	
207
	
196
	template<class CellT, class F>
208
	template<class CellT, class F>
197
	class _HGridCellFunctor
209
	class _HGridCellFunctor
198
	{
210
	{
199
		const CGLA::Vec3i p0;
211
		const CGLA::Vec3i p0;
200
		const CGLA::Vec3i p7;
212
		const CGLA::Vec3i p7;
201
		F& functor;
213
		F& functor;
202
 
214
 
203
	public:
215
	public:
204
		_HGridCellFunctor(const CGLA::Vec3i _p0,
216
		_HGridCellFunctor(const CGLA::Vec3i _p0,
205
											const CGLA::Vec3i _p7,
217
											const CGLA::Vec3i _p7,
206
											F& _functor): p0(_p0), p7(_p7), functor(_functor) {}
218
											F& _functor): p0(_p0), p7(_p7), functor(_functor) {}
207
			
219
			
208
		void operator()(const CGLA::Vec3i& offset, 
220
		void operator()(const CGLA::Vec3i& offset, 
209
										CellT& cell)
221
										CellT& cell)
210
		{
222
		{
211
			CGLA::Vec3i p0c = CGLA::v_max(p0-offset, CGLA::Vec3i(0));
223
			CGLA::Vec3i p0c = CGLA::v_max(p0-offset, CGLA::Vec3i(0));
212
			CGLA::Vec3i p7c = CGLA::v_min(p7-offset, CGLA::Vec3i(CellT::get_dim()));
224
			CGLA::Vec3i p7c = CGLA::v_min(p7-offset, CGLA::Vec3i(CellT::get_dim()));
213
 
225
 
214
			if(cell.is_coalesced())
226
			if(cell.is_coalesced())
215
				cell.split();
227
				cell.split();
216
 
228
 
217
			_for_each_voxel(cell.get(), 
229
			_for_each_voxel(cell.get(), 
218
											CellT::get_dim(), 
230
											CellT::get_dim(), 
219
											CGLA::sqr(CellT::get_dim()),
231
											CGLA::sqr(CellT::get_dim()),
220
											p0c, p7c,	functor, offset);
232
											p0c, p7c,	functor, offset);
221
		}
233
		}
222
	};
234
	};
223
 
235
 
224
 
236
 
225
	template<class T, class CellT, class F>
237
	template<class T, class CellT, class F>
226
	void for_each_voxel(HGrid<T,CellT>& grid,
238
	void for_each_voxel(HGrid<T,CellT>& grid,
227
											const CGLA::Vec3i& _p0, 
239
											const CGLA::Vec3i& _p0, 
228
											const CGLA::Vec3i& _p7,
240
											const CGLA::Vec3i& _p7,
229
											F& functor)
241
											F& functor)
230
	{
242
	{
231
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
243
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
232
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
244
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
233
		_HGridCellFunctor<CellT,F> cell_functor(p0, p7, functor);
245
		_HGridCellFunctor<CellT,F> cell_functor(p0, p7, functor);
234
		for_each_cell(grid, p0, p7, cell_functor);
246
		for_each_cell(grid, p0, p7, cell_functor);
235
	}
247
	}
236
 
248
 
237
	template<class T, class CellT, class F>
249
	template<class T, class CellT, class F>
238
	void for_each_voxel(HGrid<T,CellT>& grid,	F& functor)
250
	void for_each_voxel(HGrid<T,CellT>& grid,	F& functor)
239
	{
251
	{
240
		_HGridCellFunctor<CellT,F> cell_functor(CGLA::Vec3i(0), 
252
		_HGridCellFunctor<CellT,F> cell_functor(CGLA::Vec3i(0), 
241
																						grid.get_dims(), functor);
253
																						grid.get_dims(), functor);
242
		for_each_cell(grid, cell_functor);
254
		for_each_cell(grid, cell_functor);
243
	}
255
	}
244
 
256
 
245
	template<class T, class CellT, class F>
257
	template<class T, class CellT, class F>
246
	void for_each_voxel_ordered(HGrid<T,CellT>& grid,
258
	void for_each_voxel_ordered(HGrid<T,CellT>& grid,
247
															const CGLA::Vec3i& _p0, 
259
															const CGLA::Vec3i& _p0, 
248
															const CGLA::Vec3i& _p7,
260
															const CGLA::Vec3i& _p7,
249
															F& functor)
261
															F& functor)
250
	{
262
	{
251
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
263
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
252
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
264
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
253
		for(int k=p0[2];k<p7[2];++k)
265
		for(int k=p0[2];k<p7[2];++k)
254
			for(int j=p0[1];j<p7[1];++j)
266
			for(int j=p0[1];j<p7[1];++j)
255
				for(int i=p0[0];i<p7[0];++i)
267
				for(int i=p0[0];i<p7[0];++i)
256
					{
268
					{
257
						CGLA::Vec3i p(i,j,k);
269
						CGLA::Vec3i p(i,j,k);
258
						float val = grid[p];
270
						float val = grid[p];
259
						float nval = val;
271
						float nval = val;
260
						functor(p, nval);
272
						functor(p, nval);
261
						if(nval != val)
273
						if(nval != val)
262
							grid.store(p, nval);
274
							grid.store(p, nval);
263
					}
275
					}
264
	}
276
	}
265
 
277
 
266
	template<class T, class CellT, class F>
278
	template<class T, class CellT, class F>
267
	void for_each_voxel_ordered(HGrid<T,CellT>& grid,	F& functor)
279
	void for_each_voxel_ordered(HGrid<T,CellT>& grid,	F& functor)
268
	{
280
	{
269
		for_each_voxel_ordered(grid, CGLA::Vec3i(0), grid.get_dims(), functor);
281
		for_each_voxel_ordered(grid, CGLA::Vec3i(0), grid.get_dims(), functor);
270
	}
282
	}
271
 
283
 
272
 
284
 
273
	template<typename T>
285
	template<typename T>
274
	class _AssignFun
286
	class _AssignFun
275
	{
287
	{
276
		T val;
288
		T val;
277
	public:
289
	public:
278
		_AssignFun(const T& _val): val(_val) {}
290
		_AssignFun(const T& _val): val(_val) {}
279
		void operator()(const CGLA::Vec3i& pi, T& vox_val)
291
		void operator()(const CGLA::Vec3i& pi, T& vox_val)
280
		{
292
		{
281
			vox_val = val;
293
			vox_val = val;
282
		}
294
		}
283
	};
295
	};
284
	
296
	
285
 	template<class G>
297
 	template<class G>
286
	void clear_region(G& grid, const typename G::DataType& value)
298
	void clear_region(G& grid, const typename G::DataType& value)
287
	{
299
	{
288
		_AssignFun<typename G::DataType> afun(value);
300
		_AssignFun<typename G::DataType> afun(value);
289
		for_each_voxel(grid, afun);
301
		for_each_voxel(grid, afun);
290
	}
302
	}
291
 
303
 
292
	template<class G>
304
	template<class G>
293
	void clear_region(G& grid, 
305
	void clear_region(G& grid, 
294
										const CGLA::Vec3i& p0,
306
										const CGLA::Vec3i& p0,
295
										const CGLA::Vec3i& p7,
307
										const CGLA::Vec3i& p7,
296
										const typename G::DataType& value)
308
										const typename G::DataType& value)
297
	{
309
	{
298
		_AssignFun<typename G::DataType>afun(value) ;
310
		_AssignFun<typename G::DataType>afun(value) ;
299
		for_each_voxel(grid, p0, p7, afun);
311
		for_each_voxel(grid, p0, p7, afun);
300
	}
312
	}
301
 
313
 
302
 
314
 
303
	//----------------------------------------------------------------------
315
	//----------------------------------------------------------------------
304
	// const versions.
316
	// const versions.
305
 
317
 
306
	/** Loop over all voxels in a sub-region (slice) of an
318
	/** Loop over all voxels in a sub-region (slice) of an
307
			RGrid and invoke a functor on each voxel. 
319
			RGrid and invoke a functor on each voxel. 
308
			The grid is the first argument, the slice is
320
			The grid is the first argument, the slice is
309
			specified by the two subsequent args, and the functor 
321
			specified by the two subsequent args, and the functor 
310
			is the last argument. */
322
			is the last argument. */
311
	template<class T, class F>
323
	template<class T, class F>
312
	void for_each_voxel_const(const RGrid<T>& grid,
324
	void for_each_voxel_const(const RGrid<T>& grid,
313
														const CGLA::Vec3i& p0, 
325
														const CGLA::Vec3i& p0, 
314
														const CGLA::Vec3i& p7,
326
														const CGLA::Vec3i& p7,
315
														F& functor)
327
														F& functor)
316
	{
328
	{
317
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
329
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
318
										CGLA::v_max(p0, CGLA::Vec3i(0)),
330
										CGLA::v_max(p0, CGLA::Vec3i(0)),
319
										CGLA::v_min(p7, grid.get_dims()), 
331
										CGLA::v_min(p7, grid.get_dims()), 
320
										functor);
332
										functor);
321
	}
333
	}
322
 
334
 
323
	/** Loop over all voxels in an entire	RGrid. 
335
	/** Loop over all voxels in an entire	RGrid. 
324
			Grid is the first argument, and a functor is 
336
			Grid is the first argument, and a functor is 
325
			the second.	For each voxel, an operation 
337
			the second.	For each voxel, an operation 
326
			specified by the functor is performed. */
338
			specified by the functor is performed. */
327
	template<class T, class F>
339
	template<class T, class F>
328
	void for_each_voxel_const(const RGrid<T>& grid,	F& functor)
340
	void for_each_voxel_const(const RGrid<T>& grid,	F& functor)
329
	{
341
	{
330
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
342
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
331
	}
343
	}
332
 
344
 
333
 
345
 
334
	/** For each voxel (ordered). The idea of ordered traversal is 
346
	/** For each voxel (ordered). The idea of ordered traversal is 
335
			that we traverse the volume in a systematic fashion as opposed
347
			that we traverse the volume in a systematic fashion as opposed
336
			to traversing simply according to the memory layout of the volume
348
			to traversing simply according to the memory layout of the volume
337
			data structure. This is important e.g. if we want to save the 
349
			data structure. This is important e.g. if we want to save the 
338
			volume in raw format. 
350
			volume in raw format. 
339
			For an RGrid, there is no difference though.
351
			For an RGrid, there is no difference though.
340
	*/ 
352
	*/ 
341
	template<class T, class F>
353
	template<class T, class F>
342
	void for_each_voxel_ordered_const(const RGrid<T>& grid,
354
	void for_each_voxel_ordered_const(const RGrid<T>& grid,
343
																		const CGLA::Vec3i& p0, 
355
																		const CGLA::Vec3i& p0, 
344
																		const CGLA::Vec3i& p7,
356
																		const CGLA::Vec3i& p7,
345
																		F& functor)
357
																		F& functor)
346
	{
358
	{
347
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
359
		_for_each_voxel(grid.get(), grid.get_x_dim(), grid.get_xy_dim(),
348
										CGLA::v_max(p0, CGLA::Vec3i(0)),
360
										CGLA::v_max(p0, CGLA::Vec3i(0)),
349
										CGLA::v_min(p7, grid.get_dims()), 
361
										CGLA::v_min(p7, grid.get_dims()), 
350
										functor);
362
										functor);
351
	}
363
	}
352
 
364
 
353
	template<class T, class F>
365
	template<class T, class F>
354
	void for_each_voxel_ordered_const(const RGrid<T>& grid,	F& functor)
366
	void for_each_voxel_ordered_const(const RGrid<T>& grid,	F& functor)
355
	{
367
	{
356
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
368
		_for_each_voxel(grid.get(), grid.get_dims(), functor);
357
	}
369
	}
358
 
370
 
359
 
371
 
360
	template<class T, class CellT, class F>
372
	template<class T, class CellT, class F>
361
	void for_each_cell_const(const HGrid<T,CellT>& grid,
373
	void for_each_cell_const(const HGrid<T,CellT>& grid,
362
													 const CGLA::Vec3i& p0, 
374
													 const CGLA::Vec3i& p0, 
363
													 const CGLA::Vec3i& p7,
375
													 const CGLA::Vec3i& p7,
364
													 F& functor)
376
													 F& functor)
365
	{
377
	{
366
		CGLA::Vec3i p0t = p0/grid.get_bottom_dim();
378
		CGLA::Vec3i p0t = p0/grid.get_bottom_dim();
367
		CGLA::Vec3i p7t = CGLA::v_min(p7/grid.get_bottom_dim()+
379
		CGLA::Vec3i p7t = CGLA::v_min(p7/grid.get_bottom_dim()+
368
																	CGLA::Vec3i(1),
380
																	CGLA::Vec3i(1),
369
																	grid.get_top_dims());
381
																	grid.get_top_dims());
370
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; ++pt[2])
382
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; ++pt[2])
371
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; ++pt[1])
383
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; ++pt[1])
372
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; ++pt[0])
384
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; ++pt[0])
373
					functor(pt*CellT::get_dim(), grid.get_cell(pt));
385
					functor(pt*CellT::get_dim(), grid.get_cell(pt));
374
	}
386
	}
375
 
387
 
376
	template<class T, class CellT, class F>
388
	template<class T, class CellT, class F>
377
	void for_each_cell_const(const HGrid<T,CellT>& grid,
389
	void for_each_cell_const(const HGrid<T,CellT>& grid,
378
													 F& functor)
390
													 F& functor)
379
	{
391
	{
380
		CGLA::Vec3i p0t;
392
		CGLA::Vec3i p0t;
381
		CGLA::Vec3i p7t =	grid.get_dims();
393
		CGLA::Vec3i p7t =	grid.get_dims();
382
		const int inc = CellT::get_dim();
394
		const int inc = CellT::get_dim();
383
		int l=0;
395
		int l=0;
384
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; pt[2]+=inc)
396
		for(CGLA::Vec3i pt(p0t); pt[2]<p7t[2]; pt[2]+=inc)
385
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; pt[1]+=inc)
397
			for(pt[1]=p0t[1];      pt[1]<p7t[1]; pt[1]+=inc)
386
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; pt[0]+=inc)
398
				for(pt[0]=p0t[0];    pt[0]<p7t[0]; pt[0]+=inc)
387
					functor(pt, grid.get_cell(l++));
399
					functor(pt, grid.get_cell(l++));
388
	}
400
	}
389
 
401
 
390
	
402
	
391
	template<class CellT, class F>
403
	template<class CellT, class F>
392
	class _HGridCellFunctorConst
404
	class _HGridCellFunctorConst
393
	{
405
	{
394
		const CGLA::Vec3i p0;
406
		const CGLA::Vec3i p0;
395
		const CGLA::Vec3i p7;
407
		const CGLA::Vec3i p7;
396
		F& functor;
408
		F& functor;
397
 
409
 
398
	public:
410
	public:
399
		_HGridCellFunctorConst(const CGLA::Vec3i _p0,
411
		_HGridCellFunctorConst(const CGLA::Vec3i _p0,
400
													 const CGLA::Vec3i _p7,
412
													 const CGLA::Vec3i _p7,
401
													 F& _functor): p0(_p0), p7(_p7), functor(_functor) {}
413
													 F& _functor): p0(_p0), p7(_p7), functor(_functor) {}
402
			
414
			
403
		void operator()(const CGLA::Vec3i& offset, 
415
		void operator()(const CGLA::Vec3i& offset, 
404
										const CellT& cell)
416
										const CellT& cell)
405
		{
417
		{
406
			CGLA::Vec3i p0c = CGLA::v_max(p0-offset, CGLA::Vec3i(0));
418
			CGLA::Vec3i p0c = CGLA::v_max(p0-offset, CGLA::Vec3i(0));
407
			CGLA::Vec3i p7c = CGLA::v_min(p7-offset, CGLA::Vec3i(CellT::get_dim()));
419
			CGLA::Vec3i p7c = CGLA::v_min(p7-offset, CGLA::Vec3i(CellT::get_dim()));
408
 
420
 
409
			if(cell.is_coalesced())
421
			if(cell.is_coalesced())
410
				{
422
				{
411
					typename CellT::DataType val = *cell.get();
423
					typename CellT::DataType val = *cell.get();
412
					for(CGLA::Vec3i p(p0c); p[2]<p7c[2]; ++p[2])
424
					for(CGLA::Vec3i p(p0c); p[2]<p7c[2]; ++p[2])
413
						for(p[1]=p0c[1];      p[1]<p7c[1]; ++p[1])
425
						for(p[1]=p0c[1];      p[1]<p7c[1]; ++p[1])
414
							for(p[0]=p0c[0];    p[0]<p7c[0]; ++p[0])
426
							for(p[0]=p0c[0];    p[0]<p7c[0]; ++p[0])
415
								functor(p+offset, val);
427
								functor(p+offset, val);
416
				}
428
				}
417
			_for_each_voxel(cell.get(), 
429
			_for_each_voxel(cell.get(), 
418
											CellT::get_dim(), 
430
											CellT::get_dim(), 
419
											CGLA::sqr(CellT::get_dim()),
431
											CGLA::sqr(CellT::get_dim()),
420
											p0c, p7c,	functor, offset);
432
											p0c, p7c,	functor, offset);
421
		}
433
		}
422
	};
434
	};
423
 
435
 
424
 
436
 
425
	template<class T, class CellT, class F>
437
	template<class T, class CellT, class F>
426
	void for_each_voxel_const(const HGrid<T,CellT>& grid,
438
	void for_each_voxel_const(const HGrid<T,CellT>& grid,
427
														const CGLA::Vec3i& _p0, 
439
														const CGLA::Vec3i& _p0, 
428
														const CGLA::Vec3i& _p7,
440
														const CGLA::Vec3i& _p7,
429
														F& functor)
441
														F& functor)
430
	{
442
	{
431
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
443
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
432
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
444
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
433
		_HGridCellFunctorConst<CellT,F> cell_functor(p0, p7, functor);
445
		_HGridCellFunctorConst<CellT,F> cell_functor(p0, p7, functor);
434
		for_each_cell_const(grid, p0, p7, cell_functor);
446
		for_each_cell_const(grid, p0, p7, cell_functor);
435
	}
447
	}
436
 
448
 
437
	template<class T, class CellT, class F>
449
	template<class T, class CellT, class F>
438
	void for_each_voxel_const(const HGrid<T,CellT>& grid,	F& functor)
450
	void for_each_voxel_const(const HGrid<T,CellT>& grid,	F& functor)
439
	{
451
	{
440
		_HGridCellFunctorConst<CellT,F> cell_functor(CGLA::Vec3i(0), 
452
		_HGridCellFunctorConst<CellT,F> cell_functor(CGLA::Vec3i(0), 
441
																								 grid.get_dims(), functor);
453
																								 grid.get_dims(), functor);
442
		for_each_cell_const(grid, cell_functor);
454
		for_each_cell_const(grid, cell_functor);
443
	}
455
	}
444
 
456
 
445
	template<class T, class CellT, class F>
457
	template<class T, class CellT, class F>
446
	void for_each_voxel_ordered_const(const HGrid<T,CellT>& grid,
458
	void for_each_voxel_ordered_const(const HGrid<T,CellT>& grid,
447
																		const CGLA::Vec3i& _p0, 
459
																		const CGLA::Vec3i& _p0, 
448
																		const CGLA::Vec3i& _p7,
460
																		const CGLA::Vec3i& _p7,
449
																		F& functor)
461
																		F& functor)
450
	{
462
	{
451
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
463
		CGLA::Vec3i p0 = CGLA::v_max(_p0, CGLA::Vec3i(0));
452
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
464
		CGLA::Vec3i p7 = CGLA::v_min(_p7, grid.get_dims());
453
		for(int k=p0[2];k<p7[2];++k)
465
		for(int k=p0[2];k<p7[2];++k)
454
			for(int j=p0[1];j<p7[1];++j)
466
			for(int j=p0[1];j<p7[1];++j)
455
				for(int i=p0[0];i<p7[0];++i)
467
				for(int i=p0[0];i<p7[0];++i)
456
					{
468
					{
457
						CGLA::Vec3i p(i,j,k);
469
						CGLA::Vec3i p(i,j,k);
458
						functor(p, grid[p]);
470
						functor(p, grid[p]);
459
					}
471
					}
460
	}
472
	}
461
 
473
 
462
	template<class T, class CellT, class F>
474
	template<class T, class CellT, class F>
463
	void for_each_voxel_ordered_const(const HGrid<T,CellT>& grid,	F& functor)
475
	void for_each_voxel_ordered_const(const HGrid<T,CellT>& grid,	F& functor)
464
	{
476
	{
465
		for_each_voxel_ordered_const(grid, 
477
		for_each_voxel_ordered_const(grid, 
466
																 CGLA::Vec3i(0), 
478
																 CGLA::Vec3i(0), 
467
																 grid.get_dims(), 
479
																 grid.get_dims(), 
468
																 functor);
480
																 functor);
469
	}
481
	}
470
 
482
 
471
 
483
 
472
}
484
}
473
 
485
 
474
#endif
486
#endif
475
 
487