Subversion Repositories gelsvn

Rev

Rev 61 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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