ForEachTernaryVoxelFunction.h
1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * ATTENTION: This source file has been automatically generated using the code
20  * generator mirtkForEachVoxelFunction.py! This generator is
21  * invoked during CMake configuration of the build system when this
22  * source file is missing from the project.
23  *
24  * DO NOT modify this file manually. Instead, modify the code
25  * generator, remove any existing mirtkForEach*VoxelFunction.h
26  * header file from the include/ directory and then re-run CMake.
27  * This will invoke the code generator to re-generate the source files.
28  */
29 
30 #ifndef MIRTK_ForEachTernaryVoxelFunction_H
31 #define MIRTK_ForEachTernaryVoxelFunction_H
32 
33 #include "mirtk/Stream.h"
34 #include "mirtk/VoxelFunction.h"
35 
36 
37 namespace mirtk {
38 
39 
40 inline void _foreachternaryvoxelfunction_must_not_be_reduction()
41 {
42  cerr << "(Parallel)ForEachVoxel(If): Voxel reductions must be passed by reference!"
43  " Pass voxel functor object(s) as last argument(s) instead of first." << endl;
44  exit(1);
45 }
46 
47 
48 // =============================================================================
49 // 3 const images
50 // =============================================================================
51 
52 // -----------------------------------------------------------------------------
53 /**
54  * ForEachVoxel body for voxel function of 3 const images
55  */
56 template <class T1, class T2, class T3, class VoxelFunc>
58 {
59  const GenericImage<T1> &im1;
60  const GenericImage<T2> &im2;
61  const GenericImage<T3> &im3;
62 
63  /// Constructor
65  const GenericImage<T2> &im2,
66  const GenericImage<T3> &im3,
67  VoxelFunc &vf)
68  :
69  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3)
70  {}
71 
72  /// Copy constructor
74  :
75  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
76  {}
77 
78  /// Split constructor
80  :
81  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
82  {}
83 
84  /// Process entire image
85  void operator ()(const ImageAttributes &attr) const
86  {
87  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
88  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
89  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
90 
91  const int T = (attr._dt ? attr._t : 1);
92 
93  for (int l = 0; l < T; ++l)
94  for (int k = 0; k < attr._z; ++k)
95  for (int j = 0; j < attr._y; ++j)
96  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
97  // const_cast such that voxel functions need only implement
98  // non-const operator() which is required for parallel_reduce
99  const_cast<TernaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3);
100  }
101  }
102 
103  /// Process image region using linear index
104  void operator ()(const blocked_range<int> &re) const
105  {
106  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
107  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
108  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
109 
110  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
111  // const_cast such that voxel functions need only implement
112  // non-const operator() which is required for parallel_reduce
113  const_cast<TernaryForEachVoxelBody_Const *>(this)->_VoxelFunc(im3, idx, p1, p2, p3);
114  }
115  }
116 
117  /// Process 2D image region
118  void operator ()(const blocked_range2d<int> &re) const
119  {
120  const int bi = re.cols().begin();
121  const int bj = re.rows().begin();
122  const int ei = re.cols().end();
123  const int ej = re.rows().end();
124 
125  const int s1 = im3.GetX() - (ei - bi);
126 
127  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
128  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
129  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
130 
131  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
132  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
133  // const_cast such that voxel functions need only implement
134  // non-const operator() which is required for parallel_reduce
135  const_cast<TernaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3);
136  }
137  }
138 
139  /// Process 3D image region
140  void operator ()(const blocked_range3d<int> &re) const
141  {
142  const int bi = re.cols ().begin();
143  const int bj = re.rows ().begin();
144  const int bk = re.pages().begin();
145  const int ei = re.cols ().end();
146  const int ej = re.rows ().end();
147  const int ek = re.pages().end();
148 
149  const int s1 = im3.GetX() - (ei - bi);
150  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
151 
152  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
153  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
154  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
155 
156  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
157  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
158  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
159  // const_cast such that voxel functions need only implement
160  // non-const operator() which is required for parallel_reduce
161  const_cast<TernaryForEachVoxelBody_Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3);
162  }
163  }
164 };
165 
166 // -----------------------------------------------------------------------------
167 /**
168  * ForEachVoxel body for inside and outside unary voxel function of 3 const images
169  */
170 template <class T1, class T2, class T3,
171  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
172  class Domain = ForEachVoxelDomain::Foreground>
173 struct TernaryForEachVoxelIfBody_Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
174 {
175  const GenericImage<T1> &im1;
176  const GenericImage<T2> &im2;
177  const GenericImage<T3> &im3;
178 
179  /// Constructor
181  const GenericImage<T2> &im2,
182  const GenericImage<T3> &im3,
183  VoxelFunc &vf, OutsideFunc &of)
184  :
185  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3)
186  {}
187 
188  /// Copy constructor
190  :
191  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
192  {}
193 
194  /// Split constructor
196  :
197  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
198  {}
199 
200  /// Process entire image
201  void operator ()(const ImageAttributes &attr) const
202  {
203  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
204  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
205  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
206 
207  const int T = (attr._dt ? attr._t : 1);
208 
209  for (int l = 0; l < T; ++l)
210  for (int k = 0; k < attr._z; ++k)
211  for (int j = 0; j < attr._y; ++j)
212  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
213  if (Domain::IsInside(im3, i, j, k, l, p3)) {
214  // const_cast such that voxel functions need only implement
215  // non-const operator() which is required for parallel_reduce
216  const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3);
217  } else const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3);
218  }
219  }
220 
221  /// Process image region using linear index
222  void operator ()(const blocked_range<int> &re) const
223  {
224  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
225  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
226  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
227 
228  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
229  if (Domain::IsInside(im3, idx, p3)) {
230  // const_cast such that voxel functions need only implement
231  // non-const operator() which is required for parallel_reduce
232  const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (im3, idx, p1, p2, p3);
233  } else const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(im3, idx, p1, p2, p3);
234  }
235  }
236 
237  /// Process 2D image region
238  void operator ()(const blocked_range2d<int> &re) const
239  {
240  const int bi = re.cols().begin();
241  const int bj = re.rows().begin();
242  const int ei = re.cols().end();
243  const int ej = re.rows().end();
244 
245  const int s1 = im3.GetX() - (ei - bi);
246 
247  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
248  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
249  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
250 
251  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
252  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
253  if (Domain::IsInside(im3, i, j, this->_k, this->_l, p3)) {
254  // const_cast such that voxel functions need only implement
255  // non-const operator() which is required for parallel_reduce
256  const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3);
257  } else const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3);
258  }
259  }
260 
261  /// Process 3D image region
262  void operator ()(const blocked_range3d<int> &re) const
263  {
264  const int bi = re.cols ().begin();
265  const int bj = re.rows ().begin();
266  const int bk = re.pages().begin();
267  const int ei = re.cols ().end();
268  const int ej = re.rows ().end();
269  const int ek = re.pages().end();
270 
271  const int s1 = im3.GetX() - (ei - bi);
272  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
273 
274  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
275  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
276  const T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
277 
278  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
279  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
280  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
281  if (Domain::IsInside(im3, i, j, k, this->_l, p3)) {
282  // const_cast such that voxel functions need only implement
283  // non-const operator() which is required for parallel_reduce
284  const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3);
285  } else const_cast<TernaryForEachVoxelIfBody_Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3);
286  }
287  }
288 };
289 
290 // -----------------------------------------------------------------------------
291 // ForEachVoxel
292 // -----------------------------------------------------------------------------
293 
294 //
295 // Image arguments by pointer
296 //
297 
298 // -----------------------------------------------------------------------------
299 template <class T1, class T2, class T3, class VoxelFunc>
300 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
301 {
302  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
304  body(re);
305  vf.join(body._VoxelFunc);
306 }
307 
308 // -----------------------------------------------------------------------------
309 template <class T1, class T2, class T3, class VoxelFunc>
310 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
311 {
312  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
313  ForEachScalar(*im1, *im2, *im3, vf);
314 }
315 
316 // -----------------------------------------------------------------------------
317 template <class T1, class T2, class T3, class VoxelFunc>
318 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
319 {
320  if (im3->GetTSize()) {
321  ForEachScalar(*im1, *im2, *im3, vf);
322  } else {
323  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
324  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
325  body(re);
326  vf.join(body._VoxelFunc);
327  }
328 }
329 
330 // -----------------------------------------------------------------------------
331 template <class T1, class T2, class T3, class VoxelFunc>
332 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
333 {
334  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
335  ForEachVoxel(*im1, *im2, *im3, vf);
336 }
337 
338 // -----------------------------------------------------------------------------
339 template <class T1, class T2, class T3, class VoxelFunc>
340 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
341 {
342  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
343  body(attr);
344  vf.join(body._VoxelFunc);
345 }
346 
347 // -----------------------------------------------------------------------------
348 template <class T1, class T2, class T3, class VoxelFunc>
349 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
350 {
351  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
352  ForEachVoxel(attr, *im1, *im2, *im3, vf);
353 }
354 
355 // -----------------------------------------------------------------------------
356 template <class T1, class T2, class T3, class VoxelFunc>
357 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
358 {
359  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
360  body(re);
361  vf.join(body._VoxelFunc);
362 }
363 
364 // -----------------------------------------------------------------------------
365 template <class T1, class T2, class T3, class VoxelFunc>
366 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
367 {
368  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
369  ForEachVoxel(re, *im1, *im2, *im3, vf);
370 }
371 
372 // -----------------------------------------------------------------------------
373 template <class T1, class T2, class T3, class VoxelFunc>
374 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
375 {
376  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
377  body(re);
378  vf.join(body._VoxelFunc);
379 }
380 
381 // -----------------------------------------------------------------------------
382 template <class T1, class T2, class T3, class VoxelFunc>
383 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
384 {
385  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
386  ForEachVoxel(re, *im1, *im2, *im3, vf);
387 }
388 
389 // -----------------------------------------------------------------------------
390 template <class T1, class T2, class T3, class VoxelFunc>
391 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
392 {
393  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
394  body(re);
395  vf.join(body._VoxelFunc);
396 }
397 
398 // -----------------------------------------------------------------------------
399 template <class T1, class T2, class T3, class VoxelFunc>
400 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
401 {
402  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
403  ForEachVoxel(re, *im1, *im2, *im3, vf);
404 }
405 
406 //
407 // Image arguments by reference
408 //
409 
410 // -----------------------------------------------------------------------------
411 template <class T1, class T2, class T3, class VoxelFunc>
412 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
413 {
416  body(re);
417  vf.join(body._VoxelFunc);
418 }
419 
420 // -----------------------------------------------------------------------------
421 template <class T1, class T2, class T3, class VoxelFunc>
422 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
423 {
424  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
425  ForEachScalar(im1, im2, im3, vf);
426 }
427 
428 // -----------------------------------------------------------------------------
429 template <class T1, class T2, class T3, class VoxelFunc>
430 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
431 {
432  if (im3.GetTSize()) {
433  ForEachScalar(im1, im2, im3, vf);
434  } else {
436  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
437  body(re);
438  vf.join(body._VoxelFunc);
439  }
440 }
441 
442 // -----------------------------------------------------------------------------
443 template <class T1, class T2, class T3, class VoxelFunc>
444 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
445 {
446  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
447  ForEachVoxel(im1, im2, im3, vf);
448 }
449 
450 // -----------------------------------------------------------------------------
451 template <class T1, class T2, class T3, class VoxelFunc>
452 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
453 {
455  body(attr);
456  vf.join(body._VoxelFunc);
457 }
458 
459 // -----------------------------------------------------------------------------
460 template <class T1, class T2, class T3, class VoxelFunc>
461 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
462 {
463  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
464  ForEachVoxel(attr, im1, im2, im3, vf);
465 }
466 
467 // -----------------------------------------------------------------------------
468 template <class T1, class T2, class T3, class VoxelFunc>
469 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
470 {
472  body(re);
473  vf.join(body._VoxelFunc);
474 }
475 
476 // -----------------------------------------------------------------------------
477 template <class T1, class T2, class T3, class VoxelFunc>
478 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
479 {
480  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
481  ForEachVoxel(re, im1, im2, im3, vf);
482 }
483 
484 // -----------------------------------------------------------------------------
485 template <class T1, class T2, class T3, class VoxelFunc>
486 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
487 {
489  body(re);
490  vf.join(body._VoxelFunc);
491 }
492 
493 // -----------------------------------------------------------------------------
494 template <class T1, class T2, class T3, class VoxelFunc>
495 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
496 {
497  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
498  ForEachVoxel(re, im1, im2, im3, vf);
499 }
500 
501 // -----------------------------------------------------------------------------
502 template <class T1, class T2, class T3, class VoxelFunc>
503 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
504 {
506  body(re);
507  vf.join(body._VoxelFunc);
508 }
509 
510 // -----------------------------------------------------------------------------
511 template <class T1, class T2, class T3, class VoxelFunc>
512 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
513 {
514  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
515  ForEachVoxel(re, im1, im2, im3, vf);
516 }
517 
518 // -----------------------------------------------------------------------------
519 // ForEachVoxelIf
520 // -----------------------------------------------------------------------------
521 
522 //
523 // Image arguments by pointer
524 //
525 
526 // -----------------------------------------------------------------------------
527 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
528 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
529 {
532  body(re);
533  vf.join(body._VoxelFunc);
534  of.join(body._OutsideFunc);
535 }
536 
537 // -----------------------------------------------------------------------------
538 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
539 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
540 {
541  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
542  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
543 }
544 
545 // -----------------------------------------------------------------------------
546 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
547 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
548 {
550  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
551 }
552 
553 // -----------------------------------------------------------------------------
554 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
555 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
556 {
557  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
558  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
559 }
560 
561 // -----------------------------------------------------------------------------
562 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
563 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
564 {
565  if (im3->GetTSize()) {
566  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
567  } else {
569  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
570  body(re);
571  vf.join(body._VoxelFunc);
572  of.join(body._OutsideFunc);
573  }
574 }
575 
576 // -----------------------------------------------------------------------------
577 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
578 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
579 {
580  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
581  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
582 }
583 
584 // -----------------------------------------------------------------------------
585 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
586 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
587 {
589  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
590 }
591 
592 // -----------------------------------------------------------------------------
593 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
594 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
595 {
596  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
597  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
598 }
599 
600 // -----------------------------------------------------------------------------
601 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
602 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
603 {
605  body(attr);
606  vf.join(body._VoxelFunc);
607  of.join(body._OutsideFunc);
608 }
609 
610 // -----------------------------------------------------------------------------
611 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
612 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
613 {
614  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
615  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
616 }
617 
618 // -----------------------------------------------------------------------------
619 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
620 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
621 {
623  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
624 }
625 
626 // -----------------------------------------------------------------------------
627 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
628 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
629 {
630  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
631  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
632 }
633 
634 // -----------------------------------------------------------------------------
635 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
636 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
637 {
639  body(re);
640  vf.join(body._VoxelFunc);
641  of.join(body._OutsideFunc);
642 }
643 
644 // -----------------------------------------------------------------------------
645 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
646 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
647 {
648  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
649  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
650 }
651 
652 // -----------------------------------------------------------------------------
653 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
654 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
655 {
657  body(re);
658  vf.join(body._VoxelFunc);
659  of.join(body._OutsideFunc);
660 }
661 
662 // -----------------------------------------------------------------------------
663 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
664 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
665 {
666  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
667  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
668 }
669 
670 // -----------------------------------------------------------------------------
671 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
672 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
673 {
675  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
676 }
677 
678 // -----------------------------------------------------------------------------
679 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
680 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
681 {
682  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
683  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
684 }
685 
686 // -----------------------------------------------------------------------------
687 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
688 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
689 {
691  body(re);
692  vf.join(body._VoxelFunc);
693  of.join(body._OutsideFunc);
694 }
695 
696 // -----------------------------------------------------------------------------
697 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
698 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
699 {
700  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
701  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
702 }
703 
704 // -----------------------------------------------------------------------------
705 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
706 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
707 {
709  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
710 }
711 
712 // -----------------------------------------------------------------------------
713 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
714 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
715 {
716  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
717  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
718 }
719 
720 //
721 // Image arguments by reference
722 //
723 
724 // -----------------------------------------------------------------------------
725 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
726 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
727 {
730  body(re);
731  vf.join(body._VoxelFunc);
732  of.join(body._OutsideFunc);
733 }
734 
735 // -----------------------------------------------------------------------------
736 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
737 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
738 {
739  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
740  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
741 }
742 
743 // -----------------------------------------------------------------------------
744 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
745 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
746 {
748  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
749 }
750 
751 // -----------------------------------------------------------------------------
752 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
753 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
754 {
755  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
756  ForEachScalarIf<Domain>(im1, im2, im3, vf);
757 }
758 
759 // -----------------------------------------------------------------------------
760 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
761 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
762 {
763  if (im3.GetTSize()) {
764  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
765  } else {
767  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
768  body(re);
769  vf.join(body._VoxelFunc);
770  of.join(body._OutsideFunc);
771  }
772 }
773 
774 // -----------------------------------------------------------------------------
775 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
776 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
777 {
778  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
779  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
780 }
781 
782 // -----------------------------------------------------------------------------
783 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
784 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
785 {
787  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
788 }
789 
790 // -----------------------------------------------------------------------------
791 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
792 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
793 {
794  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
795  ForEachVoxelIf<Domain>(im1, im2, im3, vf);
796 }
797 
798 // -----------------------------------------------------------------------------
799 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
800 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
801 {
803  body(attr);
804  vf.join(body._VoxelFunc);
805  of.join(body._OutsideFunc);
806 }
807 
808 // -----------------------------------------------------------------------------
809 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
810 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
811 {
812  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
813  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
814 }
815 
816 // -----------------------------------------------------------------------------
817 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
818 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
819 {
821  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
822 }
823 
824 // -----------------------------------------------------------------------------
825 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
826 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
827 {
828  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
829  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
830 }
831 
832 // -----------------------------------------------------------------------------
833 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
834 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
835 {
837  body(re);
838  vf.join(body._VoxelFunc);
839  of.join(body._OutsideFunc);
840 }
841 
842 // -----------------------------------------------------------------------------
843 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
844 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
845 {
846  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
847  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
848 }
849 
850 // -----------------------------------------------------------------------------
851 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
852 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
853 {
855  body(re);
856  vf.join(body._VoxelFunc);
857  of.join(body._OutsideFunc);
858 }
859 
860 // -----------------------------------------------------------------------------
861 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
862 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
863 {
864  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
865  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
866 }
867 
868 // -----------------------------------------------------------------------------
869 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
870 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
871 {
873  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
874 }
875 
876 // -----------------------------------------------------------------------------
877 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
878 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
879 {
880  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
881  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
882 }
883 
884 // -----------------------------------------------------------------------------
885 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
886 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
887 {
889  body(re);
890  vf.join(body._VoxelFunc);
891  of.join(body._OutsideFunc);
892 }
893 
894 // -----------------------------------------------------------------------------
895 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
896 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
897 {
898  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
899  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
900 }
901 
902 // -----------------------------------------------------------------------------
903 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
904 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
905 {
907  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
908 }
909 
910 // -----------------------------------------------------------------------------
911 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
912 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
913 {
914  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
915  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
916 }
917 
918 // -----------------------------------------------------------------------------
919 // ParallelForEachVoxel
920 // -----------------------------------------------------------------------------
921 
922 //
923 // Image arguments by pointer
924 //
925 
926 // -----------------------------------------------------------------------------
927 template <class T1, class T2, class T3, class VoxelFunc>
928 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
929 {
930  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
932  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
933  else parallel_for (re, body);
934 }
935 
936 // -----------------------------------------------------------------------------
937 template <class T1, class T2, class T3, class VoxelFunc>
938 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
939 {
940  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
941  ParallelForEachScalar(*im1, *im2, *im3, vf);
942 }
943 
944 // -----------------------------------------------------------------------------
945 template <class T1, class T2, class T3, class VoxelFunc>
946 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
947 {
948  if (im3->GetTSize()) {
949  ParallelForEachScalar(*im1, *im2, *im3, vf);
950  } else {
951  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
952  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
953  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
954  else parallel_for (re, body);
955  }
956 }
957 
958 // -----------------------------------------------------------------------------
959 template <class T1, class T2, class T3, class VoxelFunc>
960 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
961 {
962  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
963  ParallelForEachVoxel(*im1, *im2, *im3, vf);
964 }
965 
966 // -----------------------------------------------------------------------------
967 template <class T1, class T2, class T3, class VoxelFunc>
968 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
969 {
970  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
971  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
972  if (VoxelFunc::IsReduction()) {
973  if (attr._dt) {
974  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
975  } else {
976  parallel_reduce(re, body);
977  }
978  vf.join(body._VoxelFunc);
979  } else {
980  if (attr._dt) {
981  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
982  } else {
983  parallel_for(re, body);
984  }
985  }
986 }
987 
988 // -----------------------------------------------------------------------------
989 template <class T1, class T2, class T3, class VoxelFunc>
990 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
991 {
992  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
993  ParallelForEachVoxel(attr, *im1, *im2, *im3, vf);
994 }
995 
996 // -----------------------------------------------------------------------------
997 template <class T1, class T2, class T3, class VoxelFunc>
998 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
999 {
1000  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1001  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1002  else parallel_for (re, body);
1003 }
1004 
1005 // -----------------------------------------------------------------------------
1006 template <class T1, class T2, class T3, class VoxelFunc>
1007 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1008 {
1009  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1010  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
1011 }
1012 
1013 // -----------------------------------------------------------------------------
1014 template <class T1, class T2, class T3, class VoxelFunc>
1015 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1016 {
1017  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1018  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1019  else parallel_for (re, body);
1020 }
1021 
1022 // -----------------------------------------------------------------------------
1023 template <class T1, class T2, class T3, class VoxelFunc>
1024 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1025 {
1026  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1027  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
1028 }
1029 
1030 // -----------------------------------------------------------------------------
1031 template <class T1, class T2, class T3, class VoxelFunc>
1032 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1033 {
1034  TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1035  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1036  else parallel_for (re, body);
1037 }
1038 
1039 // -----------------------------------------------------------------------------
1040 template <class T1, class T2, class T3, class VoxelFunc>
1041 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1042 {
1043  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1044  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
1045 }
1046 
1047 //
1048 // Image arguments by reference
1049 //
1050 
1051 // -----------------------------------------------------------------------------
1052 template <class T1, class T2, class T3, class VoxelFunc>
1053 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1054 {
1057  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1058  else parallel_for (re, body);
1059 }
1060 
1061 // -----------------------------------------------------------------------------
1062 template <class T1, class T2, class T3, class VoxelFunc>
1063 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1064 {
1065  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1066  ParallelForEachScalar(im1, im2, im3, vf);
1067 }
1068 
1069 // -----------------------------------------------------------------------------
1070 template <class T1, class T2, class T3, class VoxelFunc>
1071 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1072 {
1073  if (im3.GetTSize()) {
1074  ParallelForEachScalar(im1, im2, im3, vf);
1075  } else {
1077  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
1078  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1079  else parallel_for (re, body);
1080  }
1081 }
1082 
1083 // -----------------------------------------------------------------------------
1084 template <class T1, class T2, class T3, class VoxelFunc>
1085 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1086 {
1087  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1088  ParallelForEachVoxel(im1, im2, im3, vf);
1089 }
1090 
1091 // -----------------------------------------------------------------------------
1092 template <class T1, class T2, class T3, class VoxelFunc>
1093 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1094 {
1096  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1097  if (VoxelFunc::IsReduction()) {
1098  if (attr._dt) {
1099  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1100  } else {
1101  parallel_reduce(re, body);
1102  }
1103  vf.join(body._VoxelFunc);
1104  } else {
1105  if (attr._dt) {
1106  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1107  } else {
1108  parallel_for(re, body);
1109  }
1110  }
1111 }
1112 
1113 // -----------------------------------------------------------------------------
1114 template <class T1, class T2, class T3, class VoxelFunc>
1115 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1116 {
1117  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1118  ParallelForEachVoxel(attr, im1, im2, im3, vf);
1119 }
1120 
1121 // -----------------------------------------------------------------------------
1122 template <class T1, class T2, class T3, class VoxelFunc>
1123 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1124 {
1126  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1127  else parallel_for (re, body);
1128 }
1129 
1130 // -----------------------------------------------------------------------------
1131 template <class T1, class T2, class T3, class VoxelFunc>
1132 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1133 {
1134  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1135  ParallelForEachVoxel(re, im1, im2, im3, vf);
1136 }
1137 
1138 // -----------------------------------------------------------------------------
1139 template <class T1, class T2, class T3, class VoxelFunc>
1140 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1141 {
1143  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1144  else parallel_for (re, body);
1145 }
1146 
1147 // -----------------------------------------------------------------------------
1148 template <class T1, class T2, class T3, class VoxelFunc>
1149 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1150 {
1151  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1152  ParallelForEachVoxel(re, im1, im2, im3, vf);
1153 }
1154 
1155 // -----------------------------------------------------------------------------
1156 template <class T1, class T2, class T3, class VoxelFunc>
1157 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1158 {
1160  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
1161  else parallel_for (re, body);
1162 }
1163 
1164 // -----------------------------------------------------------------------------
1165 template <class T1, class T2, class T3, class VoxelFunc>
1166 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1167 {
1168  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1169  ParallelForEachVoxel(re, im1, im2, im3, vf);
1170 }
1171 
1172 // -----------------------------------------------------------------------------
1173 // ParallelForEachVoxelIf
1174 // -----------------------------------------------------------------------------
1175 
1176 //
1177 // Image arguments by pointer
1178 //
1179 
1180 // -----------------------------------------------------------------------------
1181 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1182 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1183 {
1185  blocked_range<int> re(0, im3->GetNumberOfVoxels());
1186  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1187  parallel_reduce(re, body);
1188  vf.join(body._VoxelFunc);
1189  of.join(body._OutsideFunc);
1190  } else {
1191  parallel_for(re, body);
1192  }
1193 }
1194 
1195 // -----------------------------------------------------------------------------
1196 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1197 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1198 {
1199  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1200  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
1201 }
1202 
1203 // -----------------------------------------------------------------------------
1204 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1205 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1206 {
1208  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
1209 }
1210 
1211 // -----------------------------------------------------------------------------
1212 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1213 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1214 {
1215  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1216  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
1217 }
1218 
1219 // -----------------------------------------------------------------------------
1220 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1221 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1222 {
1223  if (im3->GetTSize()) {
1224  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
1225  } else {
1227  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
1228  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1229  parallel_reduce(re, body);
1230  vf.join(body._VoxelFunc);
1231  of.join(body._OutsideFunc);
1232  } else {
1233  parallel_for(re, body);
1234  }
1235  }
1236 }
1237 
1238 // -----------------------------------------------------------------------------
1239 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1240 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1241 {
1242  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1243  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
1244 }
1245 
1246 // -----------------------------------------------------------------------------
1247 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1248 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1249 {
1251  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
1252 }
1253 
1254 // -----------------------------------------------------------------------------
1255 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1256 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1257 {
1258  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1259  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
1260 }
1261 
1262 // -----------------------------------------------------------------------------
1263 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1264 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1265 {
1267  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1268  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1269  if (attr._dt) {
1270  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1271  } else {
1272  parallel_reduce(re, body);
1273  }
1274  vf.join(body._VoxelFunc);
1275  of.join(body._OutsideFunc);
1276  } else {
1277  if (attr._dt) {
1278  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1279  } else {
1280  parallel_for(re, body);
1281  }
1282  }
1283 }
1284 
1285 // -----------------------------------------------------------------------------
1286 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1287 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1288 {
1289  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1290  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
1291 }
1292 
1293 // -----------------------------------------------------------------------------
1294 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1295 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1296 {
1298  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
1299 }
1300 
1301 // -----------------------------------------------------------------------------
1302 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1303 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1304 {
1305  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1306  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
1307 }
1308 
1309 // -----------------------------------------------------------------------------
1310 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1311 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1312 {
1314  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1315  parallel_reduce(re, body);
1316  vf.join(body._VoxelFunc);
1317  of.join(body._OutsideFunc);
1318  } else {
1319  parallel_for(re, body);
1320  }
1321 }
1322 
1323 // -----------------------------------------------------------------------------
1324 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1325 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1326 {
1327  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1328  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1329 }
1330 
1331 // -----------------------------------------------------------------------------
1332 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1333 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1334 {
1336  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1337 }
1338 
1339 // -----------------------------------------------------------------------------
1340 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1341 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1342 {
1343  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1344  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
1345 }
1346 
1347 // -----------------------------------------------------------------------------
1348 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1349 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1350 {
1352  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1353  parallel_reduce(re, body);
1354  vf.join(body._VoxelFunc);
1355  of.join(body._OutsideFunc);
1356  } else {
1357  parallel_for(re, body);
1358  }
1359 }
1360 
1361 // -----------------------------------------------------------------------------
1362 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1363 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1364 {
1365  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1366  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1367 }
1368 
1369 // -----------------------------------------------------------------------------
1370 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1371 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1372 {
1374  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1375 }
1376 
1377 // -----------------------------------------------------------------------------
1378 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1379 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1380 {
1381  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1382  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
1383 }
1384 
1385 // -----------------------------------------------------------------------------
1386 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1387 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1388 {
1390  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1391  parallel_reduce(re, body);
1392  vf.join(body._VoxelFunc);
1393  of.join(body._OutsideFunc);
1394  } else {
1395  parallel_for(re, body);
1396  }
1397 }
1398 
1399 // -----------------------------------------------------------------------------
1400 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1401 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1402 {
1403  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1404  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1405 }
1406 
1407 // -----------------------------------------------------------------------------
1408 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1409 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1410 {
1412  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1413 }
1414 
1415 // -----------------------------------------------------------------------------
1416 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1417 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3)
1418 {
1419  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1420  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
1421 }
1422 
1423 //
1424 // Image arguments by reference
1425 //
1426 
1427 // -----------------------------------------------------------------------------
1428 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1429 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1430 {
1433  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1434  parallel_reduce(re, body);
1435  vf.join(body._VoxelFunc);
1436  of.join(body._OutsideFunc);
1437  } else {
1438  parallel_for(re, body);
1439  }
1440 }
1441 
1442 // -----------------------------------------------------------------------------
1443 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1444 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1445 {
1446  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1447  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
1448 }
1449 
1450 // -----------------------------------------------------------------------------
1451 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1452 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1453 {
1455  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
1456 }
1457 
1458 // -----------------------------------------------------------------------------
1459 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1460 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1461 {
1462  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1463  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf);
1464 }
1465 
1466 // -----------------------------------------------------------------------------
1467 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1468 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1469 {
1470  if (im3.GetTSize()) {
1471  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
1472  } else {
1474  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
1475  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1476  parallel_reduce(re, body);
1477  vf.join(body._VoxelFunc);
1478  of.join(body._OutsideFunc);
1479  } else {
1480  parallel_for(re, body);
1481  }
1482  }
1483 }
1484 
1485 // -----------------------------------------------------------------------------
1486 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1487 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1488 {
1489  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1490  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
1491 }
1492 
1493 // -----------------------------------------------------------------------------
1494 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1495 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1496 {
1498  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
1499 }
1500 
1501 // -----------------------------------------------------------------------------
1502 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1503 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1504 {
1505  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1506  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf);
1507 }
1508 
1509 // -----------------------------------------------------------------------------
1510 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1511 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1512 {
1514  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
1515  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1516  if (attr._dt) {
1517  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
1518  } else {
1519  parallel_reduce(re, body);
1520  }
1521  vf.join(body._VoxelFunc);
1522  of.join(body._OutsideFunc);
1523  } else {
1524  if (attr._dt) {
1525  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
1526  } else {
1527  parallel_for(re, body);
1528  }
1529  }
1530 }
1531 
1532 // -----------------------------------------------------------------------------
1533 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1534 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1535 {
1536  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1537  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
1538 }
1539 
1540 // -----------------------------------------------------------------------------
1541 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1542 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1543 {
1545  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
1546 }
1547 
1548 // -----------------------------------------------------------------------------
1549 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1550 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1551 {
1552  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1553  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
1554 }
1555 
1556 // -----------------------------------------------------------------------------
1557 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1558 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1559 {
1561  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1562  parallel_reduce(re, body);
1563  vf.join(body._VoxelFunc);
1564  of.join(body._OutsideFunc);
1565  } else {
1566  parallel_for(re, body);
1567  }
1568 }
1569 
1570 // -----------------------------------------------------------------------------
1571 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1572 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1573 {
1574  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1575  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1576 }
1577 
1578 // -----------------------------------------------------------------------------
1579 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1580 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1581 {
1583  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1584 }
1585 
1586 // -----------------------------------------------------------------------------
1587 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1588 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1589 {
1590  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1591  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
1592 }
1593 
1594 // -----------------------------------------------------------------------------
1595 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1596 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1597 {
1599  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1600  parallel_reduce(re, body);
1601  vf.join(body._VoxelFunc);
1602  of.join(body._OutsideFunc);
1603  } else {
1604  parallel_for(re, body);
1605  }
1606 }
1607 
1608 // -----------------------------------------------------------------------------
1609 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1610 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1611 {
1612  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1613  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1614 }
1615 
1616 // -----------------------------------------------------------------------------
1617 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1618 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1619 {
1621  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1622 }
1623 
1624 // -----------------------------------------------------------------------------
1625 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1626 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1627 {
1628  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1629  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
1630 }
1631 
1632 // -----------------------------------------------------------------------------
1633 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1634 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1635 {
1637  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
1638  parallel_reduce(re, body);
1639  vf.join(body._VoxelFunc);
1640  of.join(body._OutsideFunc);
1641  } else {
1642  parallel_for(re, body);
1643  }
1644 }
1645 
1646 // -----------------------------------------------------------------------------
1647 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
1648 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1649 {
1650  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1651  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1652 }
1653 
1654 // -----------------------------------------------------------------------------
1655 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1656 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1657 {
1659  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1660 }
1661 
1662 // -----------------------------------------------------------------------------
1663 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
1664 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3)
1665 {
1666  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1667  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
1668 }
1669 
1670 // =============================================================================
1671 // 2 const, 1 non-const images
1672 // =============================================================================
1673 
1674 // -----------------------------------------------------------------------------
1675 /**
1676  * ForEachVoxel body for voxel function of 2 const, 1 non-const images
1677  */
1678 template <class T1, class T2, class T3, class VoxelFunc>
1680 {
1681  const GenericImage<T1> &im1;
1682  const GenericImage<T2> &im2;
1683  GenericImage<T3> &im3;
1684 
1685  /// Constructor
1687  const GenericImage<T2> &im2,
1688  GenericImage<T3> &im3,
1689  VoxelFunc &vf)
1690  :
1691  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3)
1692  {}
1693 
1694  /// Copy constructor
1696  :
1697  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
1698  {}
1699 
1700  /// Split constructor
1702  :
1703  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
1704  {}
1705 
1706  /// Process entire image
1707  void operator ()(const ImageAttributes &attr) const
1708  {
1709  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1710  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1711  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
1712 
1713  const int T = (attr._dt ? attr._t : 1);
1714 
1715  for (int l = 0; l < T; ++l)
1716  for (int k = 0; k < attr._z; ++k)
1717  for (int j = 0; j < attr._y; ++j)
1718  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
1719  // const_cast such that voxel functions need only implement
1720  // non-const operator() which is required for parallel_reduce
1721  const_cast<TernaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3);
1722  }
1723  }
1724 
1725  /// Process image region using linear index
1726  void operator ()(const blocked_range<int> &re) const
1727  {
1728  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1729  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1730  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
1731 
1732  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
1733  // const_cast such that voxel functions need only implement
1734  // non-const operator() which is required for parallel_reduce
1735  const_cast<TernaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(im3, idx, p1, p2, p3);
1736  }
1737  }
1738 
1739  /// Process 2D image region
1740  void operator ()(const blocked_range2d<int> &re) const
1741  {
1742  const int bi = re.cols().begin();
1743  const int bj = re.rows().begin();
1744  const int ei = re.cols().end();
1745  const int ej = re.rows().end();
1746 
1747  const int s1 = im3.GetX() - (ei - bi);
1748 
1749  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1750  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1751  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1752 
1753  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
1754  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
1755  // const_cast such that voxel functions need only implement
1756  // non-const operator() which is required for parallel_reduce
1757  const_cast<TernaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3);
1758  }
1759  }
1760 
1761  /// Process 3D image region
1762  void operator ()(const blocked_range3d<int> &re) const
1763  {
1764  const int bi = re.cols ().begin();
1765  const int bj = re.rows ().begin();
1766  const int bk = re.pages().begin();
1767  const int ei = re.cols ().end();
1768  const int ej = re.rows ().end();
1769  const int ek = re.pages().end();
1770 
1771  const int s1 = im3.GetX() - (ei - bi);
1772  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
1773 
1774  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1775  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1776  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
1777 
1778  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
1779  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
1780  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
1781  // const_cast such that voxel functions need only implement
1782  // non-const operator() which is required for parallel_reduce
1783  const_cast<TernaryForEachVoxelBody_2Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3);
1784  }
1785  }
1786 };
1787 
1788 // -----------------------------------------------------------------------------
1789 /**
1790  * ForEachVoxel body for inside and outside unary voxel function of 2 const, 1 non-const images
1791  */
1792 template <class T1, class T2, class T3,
1793  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
1794  class Domain = ForEachVoxelDomain::Foreground>
1795 struct TernaryForEachVoxelIfBody_2Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
1796 {
1797  const GenericImage<T1> &im1;
1798  const GenericImage<T2> &im2;
1799  GenericImage<T3> &im3;
1800 
1801  /// Constructor
1803  const GenericImage<T2> &im2,
1804  GenericImage<T3> &im3,
1805  VoxelFunc &vf, OutsideFunc &of)
1806  :
1807  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3)
1808  {}
1809 
1810  /// Copy constructor
1812  :
1813  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
1814  {}
1815 
1816  /// Split constructor
1818  :
1819  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
1820  {}
1821 
1822  /// Process entire image
1823  void operator ()(const ImageAttributes &attr) const
1824  {
1825  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
1826  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
1827  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
1828 
1829  const int T = (attr._dt ? attr._t : 1);
1830 
1831  for (int l = 0; l < T; ++l)
1832  for (int k = 0; k < attr._z; ++k)
1833  for (int j = 0; j < attr._y; ++j)
1834  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
1835  if (Domain::IsInside(im3, i, j, k, l, p3)) {
1836  // const_cast such that voxel functions need only implement
1837  // non-const operator() which is required for parallel_reduce
1838  const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3);
1839  } else const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3);
1840  }
1841  }
1842 
1843  /// Process image region using linear index
1844  void operator ()(const blocked_range<int> &re) const
1845  {
1846  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
1847  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
1848  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
1849 
1850  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
1851  if (Domain::IsInside(im3, idx, p3)) {
1852  // const_cast such that voxel functions need only implement
1853  // non-const operator() which is required for parallel_reduce
1854  const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (im3, idx, p1, p2, p3);
1855  } else const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(im3, idx, p1, p2, p3);
1856  }
1857  }
1858 
1859  /// Process 2D image region
1860  void operator ()(const blocked_range2d<int> &re) const
1861  {
1862  const int bi = re.cols().begin();
1863  const int bj = re.rows().begin();
1864  const int ei = re.cols().end();
1865  const int ej = re.rows().end();
1866 
1867  const int s1 = im3.GetX() - (ei - bi);
1868 
1869  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1870  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1871  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
1872 
1873  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
1874  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
1875  if (Domain::IsInside(im3, i, j, this->_k, this->_l, p3)) {
1876  // const_cast such that voxel functions need only implement
1877  // non-const operator() which is required for parallel_reduce
1878  const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3);
1879  } else const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3);
1880  }
1881  }
1882 
1883  /// Process 3D image region
1884  void operator ()(const blocked_range3d<int> &re) const
1885  {
1886  const int bi = re.cols ().begin();
1887  const int bj = re.rows ().begin();
1888  const int bk = re.pages().begin();
1889  const int ei = re.cols ().end();
1890  const int ej = re.rows ().end();
1891  const int ek = re.pages().end();
1892 
1893  const int s1 = im3.GetX() - (ei - bi);
1894  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
1895 
1896  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
1897  const T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
1898  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
1899 
1900  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
1901  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
1902  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
1903  if (Domain::IsInside(im3, i, j, k, this->_l, p3)) {
1904  // const_cast such that voxel functions need only implement
1905  // non-const operator() which is required for parallel_reduce
1906  const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3);
1907  } else const_cast<TernaryForEachVoxelIfBody_2Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3);
1908  }
1909  }
1910 };
1911 
1912 // -----------------------------------------------------------------------------
1913 // ForEachVoxel
1914 // -----------------------------------------------------------------------------
1915 
1916 //
1917 // Image arguments by pointer
1918 //
1919 
1920 // -----------------------------------------------------------------------------
1921 template <class T1, class T2, class T3, class VoxelFunc>
1922 void ForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
1923 {
1924  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1925  blocked_range<int> re(0, im3->GetNumberOfVoxels());
1926  body(re);
1927  vf.join(body._VoxelFunc);
1928 }
1929 
1930 // -----------------------------------------------------------------------------
1931 template <class T1, class T2, class T3, class VoxelFunc>
1932 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
1933 {
1934  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1935  ForEachScalar(*im1, *im2, *im3, vf);
1936 }
1937 
1938 // -----------------------------------------------------------------------------
1939 template <class T1, class T2, class T3, class VoxelFunc>
1940 void ForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
1941 {
1942  if (im3->GetTSize()) {
1943  ForEachScalar(*im1, *im2, *im3, vf);
1944  } else {
1945  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1946  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
1947  body(re);
1948  vf.join(body._VoxelFunc);
1949  }
1950 }
1951 
1952 // -----------------------------------------------------------------------------
1953 template <class T1, class T2, class T3, class VoxelFunc>
1954 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
1955 {
1956  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1957  ForEachVoxel(*im1, *im2, *im3, vf);
1958 }
1959 
1960 // -----------------------------------------------------------------------------
1961 template <class T1, class T2, class T3, class VoxelFunc>
1962 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
1963 {
1964  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1965  body(attr);
1966  vf.join(body._VoxelFunc);
1967 }
1968 
1969 // -----------------------------------------------------------------------------
1970 template <class T1, class T2, class T3, class VoxelFunc>
1971 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
1972 {
1973  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1974  ForEachVoxel(attr, *im1, *im2, *im3, vf);
1975 }
1976 
1977 // -----------------------------------------------------------------------------
1978 template <class T1, class T2, class T3, class VoxelFunc>
1979 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
1980 {
1981  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1982  body(re);
1983  vf.join(body._VoxelFunc);
1984 }
1985 
1986 // -----------------------------------------------------------------------------
1987 template <class T1, class T2, class T3, class VoxelFunc>
1988 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
1989 {
1990  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
1991  ForEachVoxel(re, *im1, *im2, *im3, vf);
1992 }
1993 
1994 // -----------------------------------------------------------------------------
1995 template <class T1, class T2, class T3, class VoxelFunc>
1996 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
1997 {
1998  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
1999  body(re);
2000  vf.join(body._VoxelFunc);
2001 }
2002 
2003 // -----------------------------------------------------------------------------
2004 template <class T1, class T2, class T3, class VoxelFunc>
2005 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2006 {
2007  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2008  ForEachVoxel(re, *im1, *im2, *im3, vf);
2009 }
2010 
2011 // -----------------------------------------------------------------------------
2012 template <class T1, class T2, class T3, class VoxelFunc>
2013 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2014 {
2015  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2016  body(re);
2017  vf.join(body._VoxelFunc);
2018 }
2019 
2020 // -----------------------------------------------------------------------------
2021 template <class T1, class T2, class T3, class VoxelFunc>
2022 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2023 {
2024  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2025  ForEachVoxel(re, *im1, *im2, *im3, vf);
2026 }
2027 
2028 //
2029 // Image arguments by reference
2030 //
2031 
2032 // -----------------------------------------------------------------------------
2033 template <class T1, class T2, class T3, class VoxelFunc>
2034 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2035 {
2038  body(re);
2039  vf.join(body._VoxelFunc);
2040 }
2041 
2042 // -----------------------------------------------------------------------------
2043 template <class T1, class T2, class T3, class VoxelFunc>
2044 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2045 {
2046  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2047  ForEachScalar(im1, im2, im3, vf);
2048 }
2049 
2050 // -----------------------------------------------------------------------------
2051 template <class T1, class T2, class T3, class VoxelFunc>
2052 void ForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2053 {
2054  if (im3.GetTSize()) {
2055  ForEachScalar(im1, im2, im3, vf);
2056  } else {
2058  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
2059  body(re);
2060  vf.join(body._VoxelFunc);
2061  }
2062 }
2063 
2064 // -----------------------------------------------------------------------------
2065 template <class T1, class T2, class T3, class VoxelFunc>
2066 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2067 {
2068  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2069  ForEachVoxel(im1, im2, im3, vf);
2070 }
2071 
2072 // -----------------------------------------------------------------------------
2073 template <class T1, class T2, class T3, class VoxelFunc>
2074 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2075 {
2077  body(attr);
2078  vf.join(body._VoxelFunc);
2079 }
2080 
2081 // -----------------------------------------------------------------------------
2082 template <class T1, class T2, class T3, class VoxelFunc>
2083 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2084 {
2085  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2086  ForEachVoxel(attr, im1, im2, im3, vf);
2087 }
2088 
2089 // -----------------------------------------------------------------------------
2090 template <class T1, class T2, class T3, class VoxelFunc>
2091 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2092 {
2094  body(re);
2095  vf.join(body._VoxelFunc);
2096 }
2097 
2098 // -----------------------------------------------------------------------------
2099 template <class T1, class T2, class T3, class VoxelFunc>
2100 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2101 {
2102  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2103  ForEachVoxel(re, im1, im2, im3, vf);
2104 }
2105 
2106 // -----------------------------------------------------------------------------
2107 template <class T1, class T2, class T3, class VoxelFunc>
2108 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2109 {
2111  body(re);
2112  vf.join(body._VoxelFunc);
2113 }
2114 
2115 // -----------------------------------------------------------------------------
2116 template <class T1, class T2, class T3, class VoxelFunc>
2117 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2118 {
2119  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2120  ForEachVoxel(re, im1, im2, im3, vf);
2121 }
2122 
2123 // -----------------------------------------------------------------------------
2124 template <class T1, class T2, class T3, class VoxelFunc>
2125 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2126 {
2128  body(re);
2129  vf.join(body._VoxelFunc);
2130 }
2131 
2132 // -----------------------------------------------------------------------------
2133 template <class T1, class T2, class T3, class VoxelFunc>
2134 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2135 {
2136  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2137  ForEachVoxel(re, im1, im2, im3, vf);
2138 }
2139 
2140 // -----------------------------------------------------------------------------
2141 // ForEachVoxelIf
2142 // -----------------------------------------------------------------------------
2143 
2144 //
2145 // Image arguments by pointer
2146 //
2147 
2148 // -----------------------------------------------------------------------------
2149 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2150 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2151 {
2153  blocked_range<int> re(0, im3->GetNumberOfVoxels());
2154  body(re);
2155  vf.join(body._VoxelFunc);
2156  of.join(body._OutsideFunc);
2157 }
2158 
2159 // -----------------------------------------------------------------------------
2160 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2161 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2162 {
2163  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2164  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2165 }
2166 
2167 // -----------------------------------------------------------------------------
2168 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2169 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2170 {
2172  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2173 }
2174 
2175 // -----------------------------------------------------------------------------
2176 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2177 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2178 {
2179  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2180  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
2181 }
2182 
2183 // -----------------------------------------------------------------------------
2184 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2185 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2186 {
2187  if (im3->GetTSize()) {
2188  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2189  } else {
2191  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
2192  body(re);
2193  vf.join(body._VoxelFunc);
2194  of.join(body._OutsideFunc);
2195  }
2196 }
2197 
2198 // -----------------------------------------------------------------------------
2199 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2200 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2201 {
2202  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2203  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2204 }
2205 
2206 // -----------------------------------------------------------------------------
2207 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2208 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2209 {
2211  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2212 }
2213 
2214 // -----------------------------------------------------------------------------
2215 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2216 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2217 {
2218  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2219  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
2220 }
2221 
2222 // -----------------------------------------------------------------------------
2223 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2224 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2225 {
2227  body(attr);
2228  vf.join(body._VoxelFunc);
2229  of.join(body._OutsideFunc);
2230 }
2231 
2232 // -----------------------------------------------------------------------------
2233 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2234 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2235 {
2236  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2237  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
2238 }
2239 
2240 // -----------------------------------------------------------------------------
2241 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2242 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2243 {
2245  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
2246 }
2247 
2248 // -----------------------------------------------------------------------------
2249 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2250 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2251 {
2252  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2253  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
2254 }
2255 
2256 // -----------------------------------------------------------------------------
2257 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2258 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2259 {
2261  body(re);
2262  vf.join(body._VoxelFunc);
2263  of.join(body._OutsideFunc);
2264 }
2265 
2266 // -----------------------------------------------------------------------------
2267 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2268 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2269 {
2270  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2271  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2272 }
2273 
2274 // -----------------------------------------------------------------------------
2275 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2276 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2277 {
2279  body(re);
2280  vf.join(body._VoxelFunc);
2281  of.join(body._OutsideFunc);
2282 }
2283 
2284 // -----------------------------------------------------------------------------
2285 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2286 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2287 {
2288  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2289  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2290 }
2291 
2292 // -----------------------------------------------------------------------------
2293 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2294 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2295 {
2297  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2298 }
2299 
2300 // -----------------------------------------------------------------------------
2301 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2302 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2303 {
2304  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2305  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
2306 }
2307 
2308 // -----------------------------------------------------------------------------
2309 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2310 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2311 {
2313  body(re);
2314  vf.join(body._VoxelFunc);
2315  of.join(body._OutsideFunc);
2316 }
2317 
2318 // -----------------------------------------------------------------------------
2319 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2320 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2321 {
2322  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2323  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2324 }
2325 
2326 // -----------------------------------------------------------------------------
2327 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2328 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2329 {
2331  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2332 }
2333 
2334 // -----------------------------------------------------------------------------
2335 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2336 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2337 {
2338  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2339  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
2340 }
2341 
2342 //
2343 // Image arguments by reference
2344 //
2345 
2346 // -----------------------------------------------------------------------------
2347 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2348 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2349 {
2352  body(re);
2353  vf.join(body._VoxelFunc);
2354  of.join(body._OutsideFunc);
2355 }
2356 
2357 // -----------------------------------------------------------------------------
2358 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2359 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2360 {
2361  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2362  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
2363 }
2364 
2365 // -----------------------------------------------------------------------------
2366 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2367 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2368 {
2370  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
2371 }
2372 
2373 // -----------------------------------------------------------------------------
2374 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2375 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2376 {
2377  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2378  ForEachScalarIf<Domain>(im1, im2, im3, vf);
2379 }
2380 
2381 // -----------------------------------------------------------------------------
2382 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2383 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2384 {
2385  if (im3.GetTSize()) {
2386  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
2387  } else {
2389  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
2390  body(re);
2391  vf.join(body._VoxelFunc);
2392  of.join(body._OutsideFunc);
2393  }
2394 }
2395 
2396 // -----------------------------------------------------------------------------
2397 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2398 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2399 {
2400  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2401  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
2402 }
2403 
2404 // -----------------------------------------------------------------------------
2405 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2406 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2407 {
2409  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
2410 }
2411 
2412 // -----------------------------------------------------------------------------
2413 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2414 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2415 {
2416  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2417  ForEachVoxelIf<Domain>(im1, im2, im3, vf);
2418 }
2419 
2420 // -----------------------------------------------------------------------------
2421 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2422 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2423 {
2425  body(attr);
2426  vf.join(body._VoxelFunc);
2427  of.join(body._OutsideFunc);
2428 }
2429 
2430 // -----------------------------------------------------------------------------
2431 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2432 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2433 {
2434  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2435  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
2436 }
2437 
2438 // -----------------------------------------------------------------------------
2439 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2440 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2441 {
2443  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
2444 }
2445 
2446 // -----------------------------------------------------------------------------
2447 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2448 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2449 {
2450  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2451  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
2452 }
2453 
2454 // -----------------------------------------------------------------------------
2455 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2456 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2457 {
2459  body(re);
2460  vf.join(body._VoxelFunc);
2461  of.join(body._OutsideFunc);
2462 }
2463 
2464 // -----------------------------------------------------------------------------
2465 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2466 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2467 {
2468  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2469  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2470 }
2471 
2472 // -----------------------------------------------------------------------------
2473 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2474 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2475 {
2477  body(re);
2478  vf.join(body._VoxelFunc);
2479  of.join(body._OutsideFunc);
2480 }
2481 
2482 // -----------------------------------------------------------------------------
2483 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2484 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2485 {
2486  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2487  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2488 }
2489 
2490 // -----------------------------------------------------------------------------
2491 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2492 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2493 {
2495  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2496 }
2497 
2498 // -----------------------------------------------------------------------------
2499 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2500 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2501 {
2502  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2503  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
2504 }
2505 
2506 // -----------------------------------------------------------------------------
2507 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2508 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2509 {
2511  body(re);
2512  vf.join(body._VoxelFunc);
2513  of.join(body._OutsideFunc);
2514 }
2515 
2516 // -----------------------------------------------------------------------------
2517 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2518 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2519 {
2520  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2521  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2522 }
2523 
2524 // -----------------------------------------------------------------------------
2525 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2526 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2527 {
2529  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2530 }
2531 
2532 // -----------------------------------------------------------------------------
2533 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2534 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2535 {
2536  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2537  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
2538 }
2539 
2540 // -----------------------------------------------------------------------------
2541 // ParallelForEachVoxel
2542 // -----------------------------------------------------------------------------
2543 
2544 //
2545 // Image arguments by pointer
2546 //
2547 
2548 // -----------------------------------------------------------------------------
2549 template <class T1, class T2, class T3, class VoxelFunc>
2550 void ParallelForEachScalar(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2551 {
2552  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2553  blocked_range<int> re(0, im3->GetNumberOfVoxels());
2554  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2555  else parallel_for (re, body);
2556 }
2557 
2558 // -----------------------------------------------------------------------------
2559 template <class T1, class T2, class T3, class VoxelFunc>
2560 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2561 {
2562  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2563  ParallelForEachScalar(*im1, *im2, *im3, vf);
2564 }
2565 
2566 // -----------------------------------------------------------------------------
2567 template <class T1, class T2, class T3, class VoxelFunc>
2568 void ParallelForEachVoxel(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2569 {
2570  if (im3->GetTSize()) {
2571  ParallelForEachScalar(*im1, *im2, *im3, vf);
2572  } else {
2573  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2574  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
2575  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2576  else parallel_for (re, body);
2577  }
2578 }
2579 
2580 // -----------------------------------------------------------------------------
2581 template <class T1, class T2, class T3, class VoxelFunc>
2582 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2583 {
2584  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2585  ParallelForEachVoxel(*im1, *im2, *im3, vf);
2586 }
2587 
2588 // -----------------------------------------------------------------------------
2589 template <class T1, class T2, class T3, class VoxelFunc>
2590 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2591 {
2592  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2593  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2594  if (VoxelFunc::IsReduction()) {
2595  if (attr._dt) {
2596  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2597  } else {
2598  parallel_reduce(re, body);
2599  }
2600  vf.join(body._VoxelFunc);
2601  } else {
2602  if (attr._dt) {
2603  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2604  } else {
2605  parallel_for(re, body);
2606  }
2607  }
2608 }
2609 
2610 // -----------------------------------------------------------------------------
2611 template <class T1, class T2, class T3, class VoxelFunc>
2612 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2613 {
2614  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2615  ParallelForEachVoxel(attr, *im1, *im2, *im3, vf);
2616 }
2617 
2618 // -----------------------------------------------------------------------------
2619 template <class T1, class T2, class T3, class VoxelFunc>
2620 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2621 {
2622  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2623  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2624  else parallel_for (re, body);
2625 }
2626 
2627 // -----------------------------------------------------------------------------
2628 template <class T1, class T2, class T3, class VoxelFunc>
2629 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2630 {
2631  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2632  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
2633 }
2634 
2635 // -----------------------------------------------------------------------------
2636 template <class T1, class T2, class T3, class VoxelFunc>
2637 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2638 {
2639  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2640  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2641  else parallel_for (re, body);
2642 }
2643 
2644 // -----------------------------------------------------------------------------
2645 template <class T1, class T2, class T3, class VoxelFunc>
2646 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2647 {
2648  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2649  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
2650 }
2651 
2652 // -----------------------------------------------------------------------------
2653 template <class T1, class T2, class T3, class VoxelFunc>
2654 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2655 {
2656  TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
2657  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2658  else parallel_for (re, body);
2659 }
2660 
2661 // -----------------------------------------------------------------------------
2662 template <class T1, class T2, class T3, class VoxelFunc>
2663 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2664 {
2665  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2666  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
2667 }
2668 
2669 //
2670 // Image arguments by reference
2671 //
2672 
2673 // -----------------------------------------------------------------------------
2674 template <class T1, class T2, class T3, class VoxelFunc>
2675 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2676 {
2679  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2680  else parallel_for (re, body);
2681 }
2682 
2683 // -----------------------------------------------------------------------------
2684 template <class T1, class T2, class T3, class VoxelFunc>
2685 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2686 {
2687  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2688  ParallelForEachScalar(im1, im2, im3, vf);
2689 }
2690 
2691 // -----------------------------------------------------------------------------
2692 template <class T1, class T2, class T3, class VoxelFunc>
2693 void ParallelForEachVoxel(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2694 {
2695  if (im3.GetTSize()) {
2696  ParallelForEachScalar(im1, im2, im3, vf);
2697  } else {
2699  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
2700  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2701  else parallel_for (re, body);
2702  }
2703 }
2704 
2705 // -----------------------------------------------------------------------------
2706 template <class T1, class T2, class T3, class VoxelFunc>
2707 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2708 {
2709  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2710  ParallelForEachVoxel(im1, im2, im3, vf);
2711 }
2712 
2713 // -----------------------------------------------------------------------------
2714 template <class T1, class T2, class T3, class VoxelFunc>
2715 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2716 {
2718  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2719  if (VoxelFunc::IsReduction()) {
2720  if (attr._dt) {
2721  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2722  } else {
2723  parallel_reduce(re, body);
2724  }
2725  vf.join(body._VoxelFunc);
2726  } else {
2727  if (attr._dt) {
2728  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2729  } else {
2730  parallel_for(re, body);
2731  }
2732  }
2733 }
2734 
2735 // -----------------------------------------------------------------------------
2736 template <class T1, class T2, class T3, class VoxelFunc>
2737 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2738 {
2739  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2740  ParallelForEachVoxel(attr, im1, im2, im3, vf);
2741 }
2742 
2743 // -----------------------------------------------------------------------------
2744 template <class T1, class T2, class T3, class VoxelFunc>
2745 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2746 {
2748  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2749  else parallel_for (re, body);
2750 }
2751 
2752 // -----------------------------------------------------------------------------
2753 template <class T1, class T2, class T3, class VoxelFunc>
2754 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2755 {
2756  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2757  ParallelForEachVoxel(re, im1, im2, im3, vf);
2758 }
2759 
2760 // -----------------------------------------------------------------------------
2761 template <class T1, class T2, class T3, class VoxelFunc>
2762 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2763 {
2765  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2766  else parallel_for (re, body);
2767 }
2768 
2769 // -----------------------------------------------------------------------------
2770 template <class T1, class T2, class T3, class VoxelFunc>
2771 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2772 {
2773  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2774  ParallelForEachVoxel(re, im1, im2, im3, vf);
2775 }
2776 
2777 // -----------------------------------------------------------------------------
2778 template <class T1, class T2, class T3, class VoxelFunc>
2779 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2780 {
2782  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
2783  else parallel_for (re, body);
2784 }
2785 
2786 // -----------------------------------------------------------------------------
2787 template <class T1, class T2, class T3, class VoxelFunc>
2788 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
2789 {
2790  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2791  ParallelForEachVoxel(re, im1, im2, im3, vf);
2792 }
2793 
2794 // -----------------------------------------------------------------------------
2795 // ParallelForEachVoxelIf
2796 // -----------------------------------------------------------------------------
2797 
2798 //
2799 // Image arguments by pointer
2800 //
2801 
2802 // -----------------------------------------------------------------------------
2803 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2804 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2805 {
2807  blocked_range<int> re(0, im3->GetNumberOfVoxels());
2808  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2809  parallel_reduce(re, body);
2810  vf.join(body._VoxelFunc);
2811  of.join(body._OutsideFunc);
2812  } else {
2813  parallel_for(re, body);
2814  }
2815 }
2816 
2817 // -----------------------------------------------------------------------------
2818 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2819 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2820 {
2821  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2822  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2823 }
2824 
2825 // -----------------------------------------------------------------------------
2826 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2827 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2828 {
2830  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2831 }
2832 
2833 // -----------------------------------------------------------------------------
2834 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2835 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2836 {
2837  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2838  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
2839 }
2840 
2841 // -----------------------------------------------------------------------------
2842 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2843 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2844 {
2845  if (im3->GetTSize()) {
2846  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2847  } else {
2849  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
2850  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2851  parallel_reduce(re, body);
2852  vf.join(body._VoxelFunc);
2853  of.join(body._OutsideFunc);
2854  } else {
2855  parallel_for(re, body);
2856  }
2857  }
2858 }
2859 
2860 // -----------------------------------------------------------------------------
2861 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2862 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2863 {
2864  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2865  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2866 }
2867 
2868 // -----------------------------------------------------------------------------
2869 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2870 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2871 {
2873  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2874 }
2875 
2876 // -----------------------------------------------------------------------------
2877 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2878 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2879 {
2880  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2881  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
2882 }
2883 
2884 // -----------------------------------------------------------------------------
2885 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2886 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2887 {
2889  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
2890  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2891  if (attr._dt) {
2892  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
2893  } else {
2894  parallel_reduce(re, body);
2895  }
2896  vf.join(body._VoxelFunc);
2897  of.join(body._OutsideFunc);
2898  } else {
2899  if (attr._dt) {
2900  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
2901  } else {
2902  parallel_for(re, body);
2903  }
2904  }
2905 }
2906 
2907 // -----------------------------------------------------------------------------
2908 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2909 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2910 {
2911  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2912  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
2913 }
2914 
2915 // -----------------------------------------------------------------------------
2916 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2917 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2918 {
2920  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
2921 }
2922 
2923 // -----------------------------------------------------------------------------
2924 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2925 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2926 {
2927  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2928  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
2929 }
2930 
2931 // -----------------------------------------------------------------------------
2932 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2933 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2934 {
2936  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2937  parallel_reduce(re, body);
2938  vf.join(body._VoxelFunc);
2939  of.join(body._OutsideFunc);
2940  } else {
2941  parallel_for(re, body);
2942  }
2943 }
2944 
2945 // -----------------------------------------------------------------------------
2946 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2947 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2948 {
2949  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2950  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2951 }
2952 
2953 // -----------------------------------------------------------------------------
2954 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2955 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2956 {
2958  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2959 }
2960 
2961 // -----------------------------------------------------------------------------
2962 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2963 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2964 {
2965  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2966  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
2967 }
2968 
2969 // -----------------------------------------------------------------------------
2970 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2971 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2972 {
2974  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
2975  parallel_reduce(re, body);
2976  vf.join(body._VoxelFunc);
2977  of.join(body._OutsideFunc);
2978  } else {
2979  parallel_for(re, body);
2980  }
2981 }
2982 
2983 // -----------------------------------------------------------------------------
2984 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
2985 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
2986 {
2987  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
2988  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2989 }
2990 
2991 // -----------------------------------------------------------------------------
2992 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
2993 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2994 {
2996  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2997 }
2998 
2999 // -----------------------------------------------------------------------------
3000 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3001 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
3002 {
3003  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3004  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
3005 }
3006 
3007 // -----------------------------------------------------------------------------
3008 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3009 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3010 {
3012  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3013  parallel_reduce(re, body);
3014  vf.join(body._VoxelFunc);
3015  of.join(body._OutsideFunc);
3016  } else {
3017  parallel_for(re, body);
3018  }
3019 }
3020 
3021 // -----------------------------------------------------------------------------
3022 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3023 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
3024 {
3025  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3026  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3027 }
3028 
3029 // -----------------------------------------------------------------------------
3030 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3031 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3032 {
3034  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3035 }
3036 
3037 // -----------------------------------------------------------------------------
3038 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3039 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3)
3040 {
3041  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3042  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
3043 }
3044 
3045 //
3046 // Image arguments by reference
3047 //
3048 
3049 // -----------------------------------------------------------------------------
3050 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3051 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3052 {
3055  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3056  parallel_reduce(re, body);
3057  vf.join(body._VoxelFunc);
3058  of.join(body._OutsideFunc);
3059  } else {
3060  parallel_for(re, body);
3061  }
3062 }
3063 
3064 // -----------------------------------------------------------------------------
3065 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3066 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3067 {
3068  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3069  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
3070 }
3071 
3072 // -----------------------------------------------------------------------------
3073 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3074 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3075 {
3077  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
3078 }
3079 
3080 // -----------------------------------------------------------------------------
3081 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3082 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3083 {
3084  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3085  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf);
3086 }
3087 
3088 // -----------------------------------------------------------------------------
3089 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3090 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3091 {
3092  if (im3.GetTSize()) {
3093  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
3094  } else {
3096  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
3097  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3098  parallel_reduce(re, body);
3099  vf.join(body._VoxelFunc);
3100  of.join(body._OutsideFunc);
3101  } else {
3102  parallel_for(re, body);
3103  }
3104  }
3105 }
3106 
3107 // -----------------------------------------------------------------------------
3108 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3109 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3110 {
3111  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3112  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
3113 }
3114 
3115 // -----------------------------------------------------------------------------
3116 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3117 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3118 {
3120  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
3121 }
3122 
3123 // -----------------------------------------------------------------------------
3124 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3125 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3126 {
3127  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3128  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf);
3129 }
3130 
3131 // -----------------------------------------------------------------------------
3132 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3133 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3134 {
3136  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
3137  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3138  if (attr._dt) {
3139  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
3140  } else {
3141  parallel_reduce(re, body);
3142  }
3143  vf.join(body._VoxelFunc);
3144  of.join(body._OutsideFunc);
3145  } else {
3146  if (attr._dt) {
3147  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
3148  } else {
3149  parallel_for(re, body);
3150  }
3151  }
3152 }
3153 
3154 // -----------------------------------------------------------------------------
3155 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3156 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3157 {
3158  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3159  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
3160 }
3161 
3162 // -----------------------------------------------------------------------------
3163 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3164 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3165 {
3167  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
3168 }
3169 
3170 // -----------------------------------------------------------------------------
3171 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3172 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3173 {
3174  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3175  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
3176 }
3177 
3178 // -----------------------------------------------------------------------------
3179 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3180 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3181 {
3183  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3184  parallel_reduce(re, body);
3185  vf.join(body._VoxelFunc);
3186  of.join(body._OutsideFunc);
3187  } else {
3188  parallel_for(re, body);
3189  }
3190 }
3191 
3192 // -----------------------------------------------------------------------------
3193 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3194 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3195 {
3196  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3197  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3198 }
3199 
3200 // -----------------------------------------------------------------------------
3201 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3202 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3203 {
3205  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3206 }
3207 
3208 // -----------------------------------------------------------------------------
3209 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3210 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3211 {
3212  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3213  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
3214 }
3215 
3216 // -----------------------------------------------------------------------------
3217 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3218 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3219 {
3221  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3222  parallel_reduce(re, body);
3223  vf.join(body._VoxelFunc);
3224  of.join(body._OutsideFunc);
3225  } else {
3226  parallel_for(re, body);
3227  }
3228 }
3229 
3230 // -----------------------------------------------------------------------------
3231 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3232 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3233 {
3234  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3235  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3236 }
3237 
3238 // -----------------------------------------------------------------------------
3239 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3240 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3241 {
3243  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3244 }
3245 
3246 // -----------------------------------------------------------------------------
3247 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3248 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3249 {
3250  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3251  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
3252 }
3253 
3254 // -----------------------------------------------------------------------------
3255 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3256 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3257 {
3259  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
3260  parallel_reduce(re, body);
3261  vf.join(body._VoxelFunc);
3262  of.join(body._OutsideFunc);
3263  } else {
3264  parallel_for(re, body);
3265  }
3266 }
3267 
3268 // -----------------------------------------------------------------------------
3269 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3270 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3271 {
3272  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3273  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3274 }
3275 
3276 // -----------------------------------------------------------------------------
3277 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3278 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3279 {
3281  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3282 }
3283 
3284 // -----------------------------------------------------------------------------
3285 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3286 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3)
3287 {
3288  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3289  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
3290 }
3291 
3292 // =============================================================================
3293 // 1 const, 2 non-const images
3294 // =============================================================================
3295 
3296 // -----------------------------------------------------------------------------
3297 /**
3298  * ForEachVoxel body for voxel function of 1 const, 2 non-const images
3299  */
3300 template <class T1, class T2, class T3, class VoxelFunc>
3302 {
3303  const GenericImage<T1> &im1;
3304  GenericImage<T2> &im2;
3305  GenericImage<T3> &im3;
3306 
3307  /// Constructor
3309  GenericImage<T2> &im2,
3310  GenericImage<T3> &im3,
3311  VoxelFunc &vf)
3312  :
3313  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3)
3314  {}
3315 
3316  /// Copy constructor
3318  :
3319  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
3320  {}
3321 
3322  /// Split constructor
3324  :
3325  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
3326  {}
3327 
3328  /// Process entire image
3329  void operator ()(const ImageAttributes &attr) const
3330  {
3331  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3332  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3333  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
3334 
3335  const int T = (attr._dt ? attr._t : 1);
3336 
3337  for (int l = 0; l < T; ++l)
3338  for (int k = 0; k < attr._z; ++k)
3339  for (int j = 0; j < attr._y; ++j)
3340  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
3341  // const_cast such that voxel functions need only implement
3342  // non-const operator() which is required for parallel_reduce
3343  const_cast<TernaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3);
3344  }
3345  }
3346 
3347  /// Process image region using linear index
3348  void operator ()(const blocked_range<int> &re) const
3349  {
3350  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3351  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3352  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
3353 
3354  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
3355  // const_cast such that voxel functions need only implement
3356  // non-const operator() which is required for parallel_reduce
3357  const_cast<TernaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(im3, idx, p1, p2, p3);
3358  }
3359  }
3360 
3361  /// Process 2D image region
3362  void operator ()(const blocked_range2d<int> &re) const
3363  {
3364  const int bi = re.cols().begin();
3365  const int bj = re.rows().begin();
3366  const int ei = re.cols().end();
3367  const int ej = re.rows().end();
3368 
3369  const int s1 = im3.GetX() - (ei - bi);
3370 
3371  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3372  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3373  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3374 
3375  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
3376  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
3377  // const_cast such that voxel functions need only implement
3378  // non-const operator() which is required for parallel_reduce
3379  const_cast<TernaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3);
3380  }
3381  }
3382 
3383  /// Process 3D image region
3384  void operator ()(const blocked_range3d<int> &re) const
3385  {
3386  const int bi = re.cols ().begin();
3387  const int bj = re.rows ().begin();
3388  const int bk = re.pages().begin();
3389  const int ei = re.cols ().end();
3390  const int ej = re.rows ().end();
3391  const int ek = re.pages().end();
3392 
3393  const int s1 = im3.GetX() - (ei - bi);
3394  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
3395 
3396  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3397  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3398  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
3399 
3400  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
3401  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
3402  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
3403  // const_cast such that voxel functions need only implement
3404  // non-const operator() which is required for parallel_reduce
3405  const_cast<TernaryForEachVoxelBody_1Const *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3);
3406  }
3407  }
3408 };
3409 
3410 // -----------------------------------------------------------------------------
3411 /**
3412  * ForEachVoxel body for inside and outside unary voxel function of 1 const, 2 non-const images
3413  */
3414 template <class T1, class T2, class T3,
3415  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
3416  class Domain = ForEachVoxelDomain::Foreground>
3417 struct TernaryForEachVoxelIfBody_1Const : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
3418 {
3419  const GenericImage<T1> &im1;
3420  GenericImage<T2> &im2;
3421  GenericImage<T3> &im3;
3422 
3423  /// Constructor
3425  GenericImage<T2> &im2,
3426  GenericImage<T3> &im3,
3427  VoxelFunc &vf, OutsideFunc &of)
3428  :
3429  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3)
3430  {}
3431 
3432  /// Copy constructor
3434  :
3435  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
3436  {}
3437 
3438  /// Split constructor
3440  :
3441  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
3442  {}
3443 
3444  /// Process entire image
3445  void operator ()(const ImageAttributes &attr) const
3446  {
3447  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
3448  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
3449  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
3450 
3451  const int T = (attr._dt ? attr._t : 1);
3452 
3453  for (int l = 0; l < T; ++l)
3454  for (int k = 0; k < attr._z; ++k)
3455  for (int j = 0; j < attr._y; ++j)
3456  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
3457  if (Domain::IsInside(im3, i, j, k, l, p3)) {
3458  // const_cast such that voxel functions need only implement
3459  // non-const operator() which is required for parallel_reduce
3460  const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3);
3461  } else const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3);
3462  }
3463  }
3464 
3465  /// Process image region using linear index
3466  void operator ()(const blocked_range<int> &re) const
3467  {
3468  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
3469  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
3470  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
3471 
3472  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
3473  if (Domain::IsInside(im3, idx, p3)) {
3474  // const_cast such that voxel functions need only implement
3475  // non-const operator() which is required for parallel_reduce
3476  const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (im3, idx, p1, p2, p3);
3477  } else const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(im3, idx, p1, p2, p3);
3478  }
3479  }
3480 
3481  /// Process 2D image region
3482  void operator ()(const blocked_range2d<int> &re) const
3483  {
3484  const int bi = re.cols().begin();
3485  const int bj = re.rows().begin();
3486  const int ei = re.cols().end();
3487  const int ej = re.rows().end();
3488 
3489  const int s1 = im3.GetX() - (ei - bi);
3490 
3491  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3492  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3493  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
3494 
3495  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
3496  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
3497  if (Domain::IsInside(im3, i, j, this->_k, this->_l, p3)) {
3498  // const_cast such that voxel functions need only implement
3499  // non-const operator() which is required for parallel_reduce
3500  const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3);
3501  } else const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3);
3502  }
3503  }
3504 
3505  /// Process 3D image region
3506  void operator ()(const blocked_range3d<int> &re) const
3507  {
3508  const int bi = re.cols ().begin();
3509  const int bj = re.rows ().begin();
3510  const int bk = re.pages().begin();
3511  const int ei = re.cols ().end();
3512  const int ej = re.rows ().end();
3513  const int ek = re.pages().end();
3514 
3515  const int s1 = im3.GetX() - (ei - bi);
3516  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
3517 
3518  const T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
3519  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
3520  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
3521 
3522  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
3523  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
3524  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
3525  if (Domain::IsInside(im3, i, j, k, this->_l, p3)) {
3526  // const_cast such that voxel functions need only implement
3527  // non-const operator() which is required for parallel_reduce
3528  const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3);
3529  } else const_cast<TernaryForEachVoxelIfBody_1Const *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3);
3530  }
3531  }
3532 };
3533 
3534 // -----------------------------------------------------------------------------
3535 // ForEachVoxel
3536 // -----------------------------------------------------------------------------
3537 
3538 //
3539 // Image arguments by pointer
3540 //
3541 
3542 // -----------------------------------------------------------------------------
3543 template <class T1, class T2, class T3, class VoxelFunc>
3544 void ForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3545 {
3546  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
3547  blocked_range<int> re(0, im3->GetNumberOfVoxels());
3548  body(re);
3549  vf.join(body._VoxelFunc);
3550 }
3551 
3552 // -----------------------------------------------------------------------------
3553 template <class T1, class T2, class T3, class VoxelFunc>
3554 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3555 {
3556  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3557  ForEachScalar(*im1, *im2, *im3, vf);
3558 }
3559 
3560 // -----------------------------------------------------------------------------
3561 template <class T1, class T2, class T3, class VoxelFunc>
3562 void ForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3563 {
3564  if (im3->GetTSize()) {
3565  ForEachScalar(*im1, *im2, *im3, vf);
3566  } else {
3567  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
3568  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
3569  body(re);
3570  vf.join(body._VoxelFunc);
3571  }
3572 }
3573 
3574 // -----------------------------------------------------------------------------
3575 template <class T1, class T2, class T3, class VoxelFunc>
3576 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3577 {
3578  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3579  ForEachVoxel(*im1, *im2, *im3, vf);
3580 }
3581 
3582 // -----------------------------------------------------------------------------
3583 template <class T1, class T2, class T3, class VoxelFunc>
3584 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3585 {
3586  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
3587  body(attr);
3588  vf.join(body._VoxelFunc);
3589 }
3590 
3591 // -----------------------------------------------------------------------------
3592 template <class T1, class T2, class T3, class VoxelFunc>
3593 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3594 {
3595  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3596  ForEachVoxel(attr, *im1, *im2, *im3, vf);
3597 }
3598 
3599 // -----------------------------------------------------------------------------
3600 template <class T1, class T2, class T3, class VoxelFunc>
3601 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3602 {
3603  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
3604  body(re);
3605  vf.join(body._VoxelFunc);
3606 }
3607 
3608 // -----------------------------------------------------------------------------
3609 template <class T1, class T2, class T3, class VoxelFunc>
3610 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3611 {
3612  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3613  ForEachVoxel(re, *im1, *im2, *im3, vf);
3614 }
3615 
3616 // -----------------------------------------------------------------------------
3617 template <class T1, class T2, class T3, class VoxelFunc>
3618 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3619 {
3620  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
3621  body(re);
3622  vf.join(body._VoxelFunc);
3623 }
3624 
3625 // -----------------------------------------------------------------------------
3626 template <class T1, class T2, class T3, class VoxelFunc>
3627 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3628 {
3629  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3630  ForEachVoxel(re, *im1, *im2, *im3, vf);
3631 }
3632 
3633 // -----------------------------------------------------------------------------
3634 template <class T1, class T2, class T3, class VoxelFunc>
3635 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3636 {
3637  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
3638  body(re);
3639  vf.join(body._VoxelFunc);
3640 }
3641 
3642 // -----------------------------------------------------------------------------
3643 template <class T1, class T2, class T3, class VoxelFunc>
3644 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3645 {
3646  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3647  ForEachVoxel(re, *im1, *im2, *im3, vf);
3648 }
3649 
3650 //
3651 // Image arguments by reference
3652 //
3653 
3654 // -----------------------------------------------------------------------------
3655 template <class T1, class T2, class T3, class VoxelFunc>
3656 void ForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3657 {
3660  body(re);
3661  vf.join(body._VoxelFunc);
3662 }
3663 
3664 // -----------------------------------------------------------------------------
3665 template <class T1, class T2, class T3, class VoxelFunc>
3666 void ForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3667 {
3668  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3669  ForEachScalar(im1, im2, im3, vf);
3670 }
3671 
3672 // -----------------------------------------------------------------------------
3673 template <class T1, class T2, class T3, class VoxelFunc>
3674 void ForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3675 {
3676  if (im3.GetTSize()) {
3677  ForEachScalar(im1, im2, im3, vf);
3678  } else {
3680  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
3681  body(re);
3682  vf.join(body._VoxelFunc);
3683  }
3684 }
3685 
3686 // -----------------------------------------------------------------------------
3687 template <class T1, class T2, class T3, class VoxelFunc>
3688 void ForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3689 {
3690  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3691  ForEachVoxel(im1, im2, im3, vf);
3692 }
3693 
3694 // -----------------------------------------------------------------------------
3695 template <class T1, class T2, class T3, class VoxelFunc>
3696 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3697 {
3699  body(attr);
3700  vf.join(body._VoxelFunc);
3701 }
3702 
3703 // -----------------------------------------------------------------------------
3704 template <class T1, class T2, class T3, class VoxelFunc>
3705 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3706 {
3707  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3708  ForEachVoxel(attr, im1, im2, im3, vf);
3709 }
3710 
3711 // -----------------------------------------------------------------------------
3712 template <class T1, class T2, class T3, class VoxelFunc>
3713 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3714 {
3716  body(re);
3717  vf.join(body._VoxelFunc);
3718 }
3719 
3720 // -----------------------------------------------------------------------------
3721 template <class T1, class T2, class T3, class VoxelFunc>
3722 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3723 {
3724  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3725  ForEachVoxel(re, im1, im2, im3, vf);
3726 }
3727 
3728 // -----------------------------------------------------------------------------
3729 template <class T1, class T2, class T3, class VoxelFunc>
3730 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3731 {
3733  body(re);
3734  vf.join(body._VoxelFunc);
3735 }
3736 
3737 // -----------------------------------------------------------------------------
3738 template <class T1, class T2, class T3, class VoxelFunc>
3739 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3740 {
3741  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3742  ForEachVoxel(re, im1, im2, im3, vf);
3743 }
3744 
3745 // -----------------------------------------------------------------------------
3746 template <class T1, class T2, class T3, class VoxelFunc>
3747 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3748 {
3750  body(re);
3751  vf.join(body._VoxelFunc);
3752 }
3753 
3754 // -----------------------------------------------------------------------------
3755 template <class T1, class T2, class T3, class VoxelFunc>
3756 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3757 {
3758  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3759  ForEachVoxel(re, im1, im2, im3, vf);
3760 }
3761 
3762 // -----------------------------------------------------------------------------
3763 // ForEachVoxelIf
3764 // -----------------------------------------------------------------------------
3765 
3766 //
3767 // Image arguments by pointer
3768 //
3769 
3770 // -----------------------------------------------------------------------------
3771 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3772 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3773 {
3775  blocked_range<int> re(0, im3->GetNumberOfVoxels());
3776  body(re);
3777  vf.join(body._VoxelFunc);
3778  of.join(body._OutsideFunc);
3779 }
3780 
3781 // -----------------------------------------------------------------------------
3782 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3783 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3784 {
3785  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3786  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
3787 }
3788 
3789 // -----------------------------------------------------------------------------
3790 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3791 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3792 {
3794  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
3795 }
3796 
3797 // -----------------------------------------------------------------------------
3798 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3799 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3800 {
3801  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3802  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
3803 }
3804 
3805 // -----------------------------------------------------------------------------
3806 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3807 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3808 {
3809  if (im3->GetTSize()) {
3810  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
3811  } else {
3813  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
3814  body(re);
3815  vf.join(body._VoxelFunc);
3816  of.join(body._OutsideFunc);
3817  }
3818 }
3819 
3820 // -----------------------------------------------------------------------------
3821 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3822 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3823 {
3824  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3825  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
3826 }
3827 
3828 // -----------------------------------------------------------------------------
3829 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3830 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3831 {
3833  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
3834 }
3835 
3836 // -----------------------------------------------------------------------------
3837 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3838 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3839 {
3840  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3841  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
3842 }
3843 
3844 // -----------------------------------------------------------------------------
3845 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3846 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3847 {
3849  body(attr);
3850  vf.join(body._VoxelFunc);
3851  of.join(body._OutsideFunc);
3852 }
3853 
3854 // -----------------------------------------------------------------------------
3855 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3856 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3857 {
3858  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3859  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
3860 }
3861 
3862 // -----------------------------------------------------------------------------
3863 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3864 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3865 {
3867  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
3868 }
3869 
3870 // -----------------------------------------------------------------------------
3871 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3872 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3873 {
3874  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3875  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
3876 }
3877 
3878 // -----------------------------------------------------------------------------
3879 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3880 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3881 {
3883  body(re);
3884  vf.join(body._VoxelFunc);
3885  of.join(body._OutsideFunc);
3886 }
3887 
3888 // -----------------------------------------------------------------------------
3889 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3890 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3891 {
3892  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3893  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3894 }
3895 
3896 // -----------------------------------------------------------------------------
3897 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3898 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3899 {
3901  body(re);
3902  vf.join(body._VoxelFunc);
3903  of.join(body._OutsideFunc);
3904 }
3905 
3906 // -----------------------------------------------------------------------------
3907 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3908 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3909 {
3910  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3911  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3912 }
3913 
3914 // -----------------------------------------------------------------------------
3915 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3916 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3917 {
3919  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3920 }
3921 
3922 // -----------------------------------------------------------------------------
3923 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3924 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3925 {
3926  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3927  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
3928 }
3929 
3930 // -----------------------------------------------------------------------------
3931 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3932 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3933 {
3935  body(re);
3936  vf.join(body._VoxelFunc);
3937  of.join(body._OutsideFunc);
3938 }
3939 
3940 // -----------------------------------------------------------------------------
3941 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3942 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3943 {
3944  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3945  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
3946 }
3947 
3948 // -----------------------------------------------------------------------------
3949 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3950 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3951 {
3953  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3954 }
3955 
3956 // -----------------------------------------------------------------------------
3957 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3958 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
3959 {
3960  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3961  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
3962 }
3963 
3964 //
3965 // Image arguments by reference
3966 //
3967 
3968 // -----------------------------------------------------------------------------
3969 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3970 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3971 {
3974  body(re);
3975  vf.join(body._VoxelFunc);
3976  of.join(body._OutsideFunc);
3977 }
3978 
3979 // -----------------------------------------------------------------------------
3980 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
3981 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3982 {
3983  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
3984  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
3985 }
3986 
3987 // -----------------------------------------------------------------------------
3988 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3989 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3990 {
3992  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
3993 }
3994 
3995 // -----------------------------------------------------------------------------
3996 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
3997 void ForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
3998 {
3999  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4000  ForEachScalarIf<Domain>(im1, im2, im3, vf);
4001 }
4002 
4003 // -----------------------------------------------------------------------------
4004 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4005 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4006 {
4007  if (im3.GetTSize()) {
4008  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4009  } else {
4011  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
4012  body(re);
4013  vf.join(body._VoxelFunc);
4014  of.join(body._OutsideFunc);
4015  }
4016 }
4017 
4018 // -----------------------------------------------------------------------------
4019 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4020 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4021 {
4022  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4023  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4024 }
4025 
4026 // -----------------------------------------------------------------------------
4027 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4028 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4029 {
4031  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4032 }
4033 
4034 // -----------------------------------------------------------------------------
4035 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4036 void ForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4037 {
4038  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4039  ForEachVoxelIf<Domain>(im1, im2, im3, vf);
4040 }
4041 
4042 // -----------------------------------------------------------------------------
4043 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4044 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4045 {
4047  body(attr);
4048  vf.join(body._VoxelFunc);
4049  of.join(body._OutsideFunc);
4050 }
4051 
4052 // -----------------------------------------------------------------------------
4053 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4054 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4055 {
4056  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4057  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
4058 }
4059 
4060 // -----------------------------------------------------------------------------
4061 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4062 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4063 {
4065  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
4066 }
4067 
4068 // -----------------------------------------------------------------------------
4069 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4070 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4071 {
4072  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4073  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
4074 }
4075 
4076 // -----------------------------------------------------------------------------
4077 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4078 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4079 {
4081  body(re);
4082  vf.join(body._VoxelFunc);
4083  of.join(body._OutsideFunc);
4084 }
4085 
4086 // -----------------------------------------------------------------------------
4087 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4088 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4089 {
4090  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4091  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4092 }
4093 
4094 // -----------------------------------------------------------------------------
4095 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4096 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4097 {
4099  body(re);
4100  vf.join(body._VoxelFunc);
4101  of.join(body._OutsideFunc);
4102 }
4103 
4104 // -----------------------------------------------------------------------------
4105 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4106 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4107 {
4108  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4109  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4110 }
4111 
4112 // -----------------------------------------------------------------------------
4113 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4114 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4115 {
4117  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4118 }
4119 
4120 // -----------------------------------------------------------------------------
4121 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4122 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4123 {
4124  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4125  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
4126 }
4127 
4128 // -----------------------------------------------------------------------------
4129 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4130 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4131 {
4133  body(re);
4134  vf.join(body._VoxelFunc);
4135  of.join(body._OutsideFunc);
4136 }
4137 
4138 // -----------------------------------------------------------------------------
4139 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4140 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4141 {
4142  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4143  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4144 }
4145 
4146 // -----------------------------------------------------------------------------
4147 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4148 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4149 {
4151  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4152 }
4153 
4154 // -----------------------------------------------------------------------------
4155 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4156 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4157 {
4158  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4159  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
4160 }
4161 
4162 // -----------------------------------------------------------------------------
4163 // ParallelForEachVoxel
4164 // -----------------------------------------------------------------------------
4165 
4166 //
4167 // Image arguments by pointer
4168 //
4169 
4170 // -----------------------------------------------------------------------------
4171 template <class T1, class T2, class T3, class VoxelFunc>
4172 void ParallelForEachScalar(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4173 {
4174  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
4175  blocked_range<int> re(0, im3->GetNumberOfVoxels());
4176  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4177  else parallel_for (re, body);
4178 }
4179 
4180 // -----------------------------------------------------------------------------
4181 template <class T1, class T2, class T3, class VoxelFunc>
4182 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4183 {
4184  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4185  ParallelForEachScalar(*im1, *im2, *im3, vf);
4186 }
4187 
4188 // -----------------------------------------------------------------------------
4189 template <class T1, class T2, class T3, class VoxelFunc>
4190 void ParallelForEachVoxel(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4191 {
4192  if (im3->GetTSize()) {
4193  ParallelForEachScalar(*im1, *im2, *im3, vf);
4194  } else {
4195  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
4196  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
4197  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4198  else parallel_for (re, body);
4199  }
4200 }
4201 
4202 // -----------------------------------------------------------------------------
4203 template <class T1, class T2, class T3, class VoxelFunc>
4204 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4205 {
4206  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4207  ParallelForEachVoxel(*im1, *im2, *im3, vf);
4208 }
4209 
4210 // -----------------------------------------------------------------------------
4211 template <class T1, class T2, class T3, class VoxelFunc>
4212 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4213 {
4214  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
4215  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4216  if (VoxelFunc::IsReduction()) {
4217  if (attr._dt) {
4218  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4219  } else {
4220  parallel_reduce(re, body);
4221  }
4222  vf.join(body._VoxelFunc);
4223  } else {
4224  if (attr._dt) {
4225  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4226  } else {
4227  parallel_for(re, body);
4228  }
4229  }
4230 }
4231 
4232 // -----------------------------------------------------------------------------
4233 template <class T1, class T2, class T3, class VoxelFunc>
4234 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4235 {
4236  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4237  ParallelForEachVoxel(attr, *im1, *im2, *im3, vf);
4238 }
4239 
4240 // -----------------------------------------------------------------------------
4241 template <class T1, class T2, class T3, class VoxelFunc>
4242 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4243 {
4244  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
4245  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4246  else parallel_for (re, body);
4247 }
4248 
4249 // -----------------------------------------------------------------------------
4250 template <class T1, class T2, class T3, class VoxelFunc>
4251 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4252 {
4253  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4254  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
4255 }
4256 
4257 // -----------------------------------------------------------------------------
4258 template <class T1, class T2, class T3, class VoxelFunc>
4259 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4260 {
4261  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
4262  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4263  else parallel_for (re, body);
4264 }
4265 
4266 // -----------------------------------------------------------------------------
4267 template <class T1, class T2, class T3, class VoxelFunc>
4268 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4269 {
4270  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4271  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
4272 }
4273 
4274 // -----------------------------------------------------------------------------
4275 template <class T1, class T2, class T3, class VoxelFunc>
4276 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4277 {
4278  TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
4279  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4280  else parallel_for (re, body);
4281 }
4282 
4283 // -----------------------------------------------------------------------------
4284 template <class T1, class T2, class T3, class VoxelFunc>
4285 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4286 {
4287  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4288  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
4289 }
4290 
4291 //
4292 // Image arguments by reference
4293 //
4294 
4295 // -----------------------------------------------------------------------------
4296 template <class T1, class T2, class T3, class VoxelFunc>
4297 void ParallelForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4298 {
4301  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4302  else parallel_for (re, body);
4303 }
4304 
4305 // -----------------------------------------------------------------------------
4306 template <class T1, class T2, class T3, class VoxelFunc>
4307 void ParallelForEachScalar(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4308 {
4309  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4310  ParallelForEachScalar(im1, im2, im3, vf);
4311 }
4312 
4313 // -----------------------------------------------------------------------------
4314 template <class T1, class T2, class T3, class VoxelFunc>
4315 void ParallelForEachVoxel(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4316 {
4317  if (im3.GetTSize()) {
4318  ParallelForEachScalar(im1, im2, im3, vf);
4319  } else {
4321  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
4322  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4323  else parallel_for (re, body);
4324  }
4325 }
4326 
4327 // -----------------------------------------------------------------------------
4328 template <class T1, class T2, class T3, class VoxelFunc>
4329 void ParallelForEachVoxel(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4330 {
4331  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4332  ParallelForEachVoxel(im1, im2, im3, vf);
4333 }
4334 
4335 // -----------------------------------------------------------------------------
4336 template <class T1, class T2, class T3, class VoxelFunc>
4337 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4338 {
4340  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4341  if (VoxelFunc::IsReduction()) {
4342  if (attr._dt) {
4343  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4344  } else {
4345  parallel_reduce(re, body);
4346  }
4347  vf.join(body._VoxelFunc);
4348  } else {
4349  if (attr._dt) {
4350  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4351  } else {
4352  parallel_for(re, body);
4353  }
4354  }
4355 }
4356 
4357 // -----------------------------------------------------------------------------
4358 template <class T1, class T2, class T3, class VoxelFunc>
4359 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4360 {
4361  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4362  ParallelForEachVoxel(attr, im1, im2, im3, vf);
4363 }
4364 
4365 // -----------------------------------------------------------------------------
4366 template <class T1, class T2, class T3, class VoxelFunc>
4367 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4368 {
4370  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4371  else parallel_for (re, body);
4372 }
4373 
4374 // -----------------------------------------------------------------------------
4375 template <class T1, class T2, class T3, class VoxelFunc>
4376 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4377 {
4378  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4379  ParallelForEachVoxel(re, im1, im2, im3, vf);
4380 }
4381 
4382 // -----------------------------------------------------------------------------
4383 template <class T1, class T2, class T3, class VoxelFunc>
4384 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4385 {
4387  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4388  else parallel_for (re, body);
4389 }
4390 
4391 // -----------------------------------------------------------------------------
4392 template <class T1, class T2, class T3, class VoxelFunc>
4393 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4394 {
4395  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4396  ParallelForEachVoxel(re, im1, im2, im3, vf);
4397 }
4398 
4399 // -----------------------------------------------------------------------------
4400 template <class T1, class T2, class T3, class VoxelFunc>
4401 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4402 {
4404  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
4405  else parallel_for (re, body);
4406 }
4407 
4408 // -----------------------------------------------------------------------------
4409 template <class T1, class T2, class T3, class VoxelFunc>
4410 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4411 {
4412  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4413  ParallelForEachVoxel(re, im1, im2, im3, vf);
4414 }
4415 
4416 // -----------------------------------------------------------------------------
4417 // ParallelForEachVoxelIf
4418 // -----------------------------------------------------------------------------
4419 
4420 //
4421 // Image arguments by pointer
4422 //
4423 
4424 // -----------------------------------------------------------------------------
4425 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4426 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4427 {
4429  blocked_range<int> re(0, im3->GetNumberOfVoxels());
4430  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4431  parallel_reduce(re, body);
4432  vf.join(body._VoxelFunc);
4433  of.join(body._OutsideFunc);
4434  } else {
4435  parallel_for(re, body);
4436  }
4437 }
4438 
4439 // -----------------------------------------------------------------------------
4440 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4441 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4442 {
4443  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4444  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
4445 }
4446 
4447 // -----------------------------------------------------------------------------
4448 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4449 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4450 {
4452  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
4453 }
4454 
4455 // -----------------------------------------------------------------------------
4456 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4457 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4458 {
4459  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4460  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
4461 }
4462 
4463 // -----------------------------------------------------------------------------
4464 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4465 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4466 {
4467  if (im3->GetTSize()) {
4468  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
4469  } else {
4471  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
4472  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4473  parallel_reduce(re, body);
4474  vf.join(body._VoxelFunc);
4475  of.join(body._OutsideFunc);
4476  } else {
4477  parallel_for(re, body);
4478  }
4479  }
4480 }
4481 
4482 // -----------------------------------------------------------------------------
4483 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4484 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4485 {
4486  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4487  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
4488 }
4489 
4490 // -----------------------------------------------------------------------------
4491 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4492 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4493 {
4495  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
4496 }
4497 
4498 // -----------------------------------------------------------------------------
4499 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4500 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4501 {
4502  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4503  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
4504 }
4505 
4506 // -----------------------------------------------------------------------------
4507 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4508 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4509 {
4511  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4512  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4513  if (attr._dt) {
4514  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4515  } else {
4516  parallel_reduce(re, body);
4517  }
4518  vf.join(body._VoxelFunc);
4519  of.join(body._OutsideFunc);
4520  } else {
4521  if (attr._dt) {
4522  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4523  } else {
4524  parallel_for(re, body);
4525  }
4526  }
4527 }
4528 
4529 // -----------------------------------------------------------------------------
4530 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4531 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4532 {
4533  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4534  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
4535 }
4536 
4537 // -----------------------------------------------------------------------------
4538 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4539 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4540 {
4542  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
4543 }
4544 
4545 // -----------------------------------------------------------------------------
4546 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4547 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4548 {
4549  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4550  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
4551 }
4552 
4553 // -----------------------------------------------------------------------------
4554 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4555 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4556 {
4558  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4559  parallel_reduce(re, body);
4560  vf.join(body._VoxelFunc);
4561  of.join(body._OutsideFunc);
4562  } else {
4563  parallel_for(re, body);
4564  }
4565 }
4566 
4567 // -----------------------------------------------------------------------------
4568 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4569 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4570 {
4571  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4572  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4573 }
4574 
4575 // -----------------------------------------------------------------------------
4576 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4577 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4578 {
4580  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4581 }
4582 
4583 // -----------------------------------------------------------------------------
4584 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4585 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4586 {
4587  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4588  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
4589 }
4590 
4591 // -----------------------------------------------------------------------------
4592 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4593 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4594 {
4596  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4597  parallel_reduce(re, body);
4598  vf.join(body._VoxelFunc);
4599  of.join(body._OutsideFunc);
4600  } else {
4601  parallel_for(re, body);
4602  }
4603 }
4604 
4605 // -----------------------------------------------------------------------------
4606 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4607 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4608 {
4609  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4610  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4611 }
4612 
4613 // -----------------------------------------------------------------------------
4614 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4615 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4616 {
4618  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4619 }
4620 
4621 // -----------------------------------------------------------------------------
4622 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4623 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4624 {
4625  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4626  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
4627 }
4628 
4629 // -----------------------------------------------------------------------------
4630 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4631 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4632 {
4634  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4635  parallel_reduce(re, body);
4636  vf.join(body._VoxelFunc);
4637  of.join(body._OutsideFunc);
4638  } else {
4639  parallel_for(re, body);
4640  }
4641 }
4642 
4643 // -----------------------------------------------------------------------------
4644 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4645 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4646 {
4647  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4648  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4649 }
4650 
4651 // -----------------------------------------------------------------------------
4652 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4653 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4654 {
4656  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4657 }
4658 
4659 // -----------------------------------------------------------------------------
4660 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4661 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
4662 {
4663  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4664  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
4665 }
4666 
4667 //
4668 // Image arguments by reference
4669 //
4670 
4671 // -----------------------------------------------------------------------------
4672 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4673 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4674 {
4677  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4678  parallel_reduce(re, body);
4679  vf.join(body._VoxelFunc);
4680  of.join(body._OutsideFunc);
4681  } else {
4682  parallel_for(re, body);
4683  }
4684 }
4685 
4686 // -----------------------------------------------------------------------------
4687 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4688 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4689 {
4690  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4691  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
4692 }
4693 
4694 // -----------------------------------------------------------------------------
4695 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4696 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4697 {
4699  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
4700 }
4701 
4702 // -----------------------------------------------------------------------------
4703 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4704 void ParallelForEachScalarIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4705 {
4706  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4707  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf);
4708 }
4709 
4710 // -----------------------------------------------------------------------------
4711 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4712 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4713 {
4714  if (im3.GetTSize()) {
4715  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4716  } else {
4718  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
4719  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4720  parallel_reduce(re, body);
4721  vf.join(body._VoxelFunc);
4722  of.join(body._OutsideFunc);
4723  } else {
4724  parallel_for(re, body);
4725  }
4726  }
4727 }
4728 
4729 // -----------------------------------------------------------------------------
4730 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4731 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4732 {
4733  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4734  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4735 }
4736 
4737 // -----------------------------------------------------------------------------
4738 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4739 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4740 {
4742  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4743 }
4744 
4745 // -----------------------------------------------------------------------------
4746 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4747 void ParallelForEachVoxelIf(VoxelFunc vf, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4748 {
4749  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4750  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf);
4751 }
4752 
4753 // -----------------------------------------------------------------------------
4754 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4755 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4756 {
4758  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
4759  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4760  if (attr._dt) {
4761  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
4762  } else {
4763  parallel_reduce(re, body);
4764  }
4765  vf.join(body._VoxelFunc);
4766  of.join(body._OutsideFunc);
4767  } else {
4768  if (attr._dt) {
4769  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
4770  } else {
4771  parallel_for(re, body);
4772  }
4773  }
4774 }
4775 
4776 // -----------------------------------------------------------------------------
4777 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4778 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4779 {
4780  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4781  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
4782 }
4783 
4784 // -----------------------------------------------------------------------------
4785 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4786 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4787 {
4789  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
4790 }
4791 
4792 // -----------------------------------------------------------------------------
4793 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4794 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4795 {
4796  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4797  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
4798 }
4799 
4800 // -----------------------------------------------------------------------------
4801 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4802 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4803 {
4805  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4806  parallel_reduce(re, body);
4807  vf.join(body._VoxelFunc);
4808  of.join(body._OutsideFunc);
4809  } else {
4810  parallel_for(re, body);
4811  }
4812 }
4813 
4814 // -----------------------------------------------------------------------------
4815 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4816 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4817 {
4818  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4819  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4820 }
4821 
4822 // -----------------------------------------------------------------------------
4823 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4824 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4825 {
4827  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4828 }
4829 
4830 // -----------------------------------------------------------------------------
4831 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4832 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4833 {
4834  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4835  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
4836 }
4837 
4838 // -----------------------------------------------------------------------------
4839 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4840 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4841 {
4843  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4844  parallel_reduce(re, body);
4845  vf.join(body._VoxelFunc);
4846  of.join(body._OutsideFunc);
4847  } else {
4848  parallel_for(re, body);
4849  }
4850 }
4851 
4852 // -----------------------------------------------------------------------------
4853 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4854 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4855 {
4856  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4857  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4858 }
4859 
4860 // -----------------------------------------------------------------------------
4861 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4862 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4863 {
4865  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4866 }
4867 
4868 // -----------------------------------------------------------------------------
4869 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4870 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4871 {
4872  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4873  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
4874 }
4875 
4876 // -----------------------------------------------------------------------------
4877 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4878 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4879 {
4881  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
4882  parallel_reduce(re, body);
4883  vf.join(body._VoxelFunc);
4884  of.join(body._OutsideFunc);
4885  } else {
4886  parallel_for(re, body);
4887  }
4888 }
4889 
4890 // -----------------------------------------------------------------------------
4891 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
4892 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4893 {
4894  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4895  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4896 }
4897 
4898 // -----------------------------------------------------------------------------
4899 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4900 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4901 {
4903  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4904 }
4905 
4906 // -----------------------------------------------------------------------------
4907 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
4908 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
4909 {
4910  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
4911  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
4912 }
4913 
4914 // =============================================================================
4915 // 3 non-const images
4916 // =============================================================================
4917 
4918 // -----------------------------------------------------------------------------
4919 /**
4920  * ForEachVoxel body for voxel function of 3 non-const images
4921  */
4922 template <class T1, class T2, class T3, class VoxelFunc>
4923 struct TernaryForEachVoxelBody : public ForEachVoxelBody<VoxelFunc>
4924 {
4925  GenericImage<T1> &im1;
4926  GenericImage<T2> &im2;
4927  GenericImage<T3> &im3;
4928 
4929  /// Constructor
4931  GenericImage<T2> &im2,
4932  GenericImage<T3> &im3,
4933  VoxelFunc &vf)
4934  :
4935  ForEachVoxelBody<VoxelFunc>(vf, im1.Attributes()), im1(im1), im2(im2), im3(im3)
4936  {}
4937 
4938  /// Copy constructor
4940  :
4941  ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
4942  {}
4943 
4944  /// Split constructor
4946  :
4947  ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
4948  {}
4949 
4950  /// Process entire image
4951  void operator ()(const ImageAttributes &attr) const
4952  {
4953  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
4954  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
4955  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
4956 
4957  const int T = (attr._dt ? attr._t : 1);
4958 
4959  for (int l = 0; l < T; ++l)
4960  for (int k = 0; k < attr._z; ++k)
4961  for (int j = 0; j < attr._y; ++j)
4962  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
4963  // const_cast such that voxel functions need only implement
4964  // non-const operator() which is required for parallel_reduce
4965  const_cast<TernaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, l, p1, p2, p3);
4966  }
4967  }
4968 
4969  /// Process image region using linear index
4970  void operator ()(const blocked_range<int> &re) const
4971  {
4972  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
4973  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
4974  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
4975 
4976  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
4977  // const_cast such that voxel functions need only implement
4978  // non-const operator() which is required for parallel_reduce
4979  const_cast<TernaryForEachVoxelBody *>(this)->_VoxelFunc(im3, idx, p1, p2, p3);
4980  }
4981  }
4982 
4983  /// Process 2D image region
4984  void operator ()(const blocked_range2d<int> &re) const
4985  {
4986  const int bi = re.cols().begin();
4987  const int bj = re.rows().begin();
4988  const int ei = re.cols().end();
4989  const int ej = re.rows().end();
4990 
4991  const int s1 = im3.GetX() - (ei - bi);
4992 
4993  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
4994  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
4995  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
4996 
4997  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
4998  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
4999  // const_cast such that voxel functions need only implement
5000  // non-const operator() which is required for parallel_reduce
5001  const_cast<TernaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, this->_k, this->_l, p1, p2, p3);
5002  }
5003  }
5004 
5005  /// Process 3D image region
5006  void operator ()(const blocked_range3d<int> &re) const
5007  {
5008  const int bi = re.cols ().begin();
5009  const int bj = re.rows ().begin();
5010  const int bk = re.pages().begin();
5011  const int ei = re.cols ().end();
5012  const int ej = re.rows ().end();
5013  const int ek = re.pages().end();
5014 
5015  const int s1 = im3.GetX() - (ei - bi);
5016  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
5017 
5018  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
5019  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
5020  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
5021 
5022  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
5023  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
5024  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
5025  // const_cast such that voxel functions need only implement
5026  // non-const operator() which is required for parallel_reduce
5027  const_cast<TernaryForEachVoxelBody *>(this)->_VoxelFunc(i, j, k, this->_l, p1, p2, p3);
5028  }
5029  }
5030 };
5031 
5032 // -----------------------------------------------------------------------------
5033 /**
5034  * ForEachVoxel body for inside and outside unary voxel function of 3 non-const images
5035  */
5036 template <class T1, class T2, class T3,
5037  class VoxelFunc, class OutsideFunc = NaryVoxelFunction::NOP,
5038  class Domain = ForEachVoxelDomain::Foreground>
5039 struct TernaryForEachVoxelIfBody : public ForEachVoxelIfBody<VoxelFunc, OutsideFunc>
5040 {
5041  GenericImage<T1> &im1;
5042  GenericImage<T2> &im2;
5043  GenericImage<T3> &im3;
5044 
5045  /// Constructor
5047  GenericImage<T2> &im2,
5048  GenericImage<T3> &im3,
5049  VoxelFunc &vf, OutsideFunc &of)
5050  :
5051  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(vf, of, im1.Attributes()), im1(im1), im2(im2), im3(im3)
5052  {}
5053 
5054  /// Copy constructor
5056  :
5057  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
5058  {}
5059 
5060  /// Split constructor
5062  :
5063  ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
5064  {}
5065 
5066  /// Process entire image
5067  void operator ()(const ImageAttributes &attr) const
5068  {
5069  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels();
5070  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels();
5071  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels();
5072 
5073  const int T = (attr._dt ? attr._t : 1);
5074 
5075  for (int l = 0; l < T; ++l)
5076  for (int k = 0; k < attr._z; ++k)
5077  for (int j = 0; j < attr._y; ++j)
5078  for (int i = 0; i < attr._x; ++i, ++p1, ++p2, ++p3) {
5079  if (Domain::IsInside(im3, i, j, k, l, p3)) {
5080  // const_cast such that voxel functions need only implement
5081  // non-const operator() which is required for parallel_reduce
5082  const_cast<TernaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, l, p1, p2, p3);
5083  } else const_cast<TernaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, l, p1, p2, p3);
5084  }
5085  }
5086 
5087  /// Process image region using linear index
5088  void operator ()(const blocked_range<int> &re) const
5089  {
5090  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels() + re.begin();
5091  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels() + re.begin();
5092  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels() + re.begin();
5093 
5094  for (int idx = re.begin(); idx < re.end(); ++idx, p1 += 1, p2 += 1, p3 += 1) {
5095  if (Domain::IsInside(im3, idx, p3)) {
5096  // const_cast such that voxel functions need only implement
5097  // non-const operator() which is required for parallel_reduce
5098  const_cast<TernaryForEachVoxelIfBody *>(this)->_VoxelFunc (im3, idx, p1, p2, p3);
5099  } else const_cast<TernaryForEachVoxelIfBody *>(this)->_OutsideFunc(im3, idx, p1, p2, p3);
5100  }
5101  }
5102 
5103  /// Process 2D image region
5104  void operator ()(const blocked_range2d<int> &re) const
5105  {
5106  const int bi = re.cols().begin();
5107  const int bj = re.rows().begin();
5108  const int ei = re.cols().end();
5109  const int ej = re.rows().end();
5110 
5111  const int s1 = im3.GetX() - (ei - bi);
5112 
5113  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5114  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5115  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, this->_k, this->_l);
5116 
5117  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
5118  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
5119  if (Domain::IsInside(im3, i, j, this->_k, this->_l, p3)) {
5120  // const_cast such that voxel functions need only implement
5121  // non-const operator() which is required for parallel_reduce
5122  const_cast<TernaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, this->_k, this->_l, p1, p2, p3);
5123  } else const_cast<TernaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, this->_k, this->_l, p1, p2, p3);
5124  }
5125  }
5126 
5127  /// Process 3D image region
5128  void operator ()(const blocked_range3d<int> &re) const
5129  {
5130  const int bi = re.cols ().begin();
5131  const int bj = re.rows ().begin();
5132  const int bk = re.pages().begin();
5133  const int ei = re.cols ().end();
5134  const int ej = re.rows ().end();
5135  const int ek = re.pages().end();
5136 
5137  const int s1 = im3.GetX() - (ei - bi);
5138  const int s2 = (im3.GetY() - (ej - bj)) * im3.GetX();
5139 
5140  T1 *p1 = im1.IsEmpty() ? NULL : im1.GetPointerToVoxels(bi, bj, bk, this->_l);
5141  T2 *p2 = im2.IsEmpty() ? NULL : im2.GetPointerToVoxels(bi, bj, bk, this->_l);
5142  T3 *p3 = im3.IsEmpty() ? NULL : im3.GetPointerToVoxels(bi, bj, bk, this->_l);
5143 
5144  for (int k = bk; k < ek; ++k, p1 += s2, p2 += s2, p3 += s2)
5145  for (int j = bj; j < ej; ++j, p1 += s1, p2 += s1, p3 += s1)
5146  for (int i = bi; i < ei; ++i, p1 += 1, p2 += 1, p3 += 1) {
5147  if (Domain::IsInside(im3, i, j, k, this->_l, p3)) {
5148  // const_cast such that voxel functions need only implement
5149  // non-const operator() which is required for parallel_reduce
5150  const_cast<TernaryForEachVoxelIfBody *>(this)->_VoxelFunc (i, j, k, this->_l, p1, p2, p3);
5151  } else const_cast<TernaryForEachVoxelIfBody *>(this)->_OutsideFunc(i, j, k, this->_l, p1, p2, p3);
5152  }
5153  }
5154 };
5155 
5156 // -----------------------------------------------------------------------------
5157 // ForEachVoxel
5158 // -----------------------------------------------------------------------------
5159 
5160 //
5161 // Image arguments by pointer
5162 //
5163 
5164 // -----------------------------------------------------------------------------
5165 template <class T1, class T2, class T3, class VoxelFunc>
5166 void ForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5167 {
5168  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5169  blocked_range<int> re(0, im3->GetNumberOfVoxels());
5170  body(re);
5171  vf.join(body._VoxelFunc);
5172 }
5173 
5174 // -----------------------------------------------------------------------------
5175 template <class T1, class T2, class T3, class VoxelFunc>
5176 void ForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5177 {
5178  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5179  ForEachScalar(*im1, *im2, *im3, vf);
5180 }
5181 
5182 // -----------------------------------------------------------------------------
5183 template <class T1, class T2, class T3, class VoxelFunc>
5184 void ForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5185 {
5186  if (im3->GetTSize()) {
5187  ForEachScalar(*im1, *im2, *im3, vf);
5188  } else {
5189  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5190  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
5191  body(re);
5192  vf.join(body._VoxelFunc);
5193  }
5194 }
5195 
5196 // -----------------------------------------------------------------------------
5197 template <class T1, class T2, class T3, class VoxelFunc>
5198 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5199 {
5200  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5201  ForEachVoxel(*im1, *im2, *im3, vf);
5202 }
5203 
5204 // -----------------------------------------------------------------------------
5205 template <class T1, class T2, class T3, class VoxelFunc>
5206 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5207 {
5208  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5209  body(attr);
5210  vf.join(body._VoxelFunc);
5211 }
5212 
5213 // -----------------------------------------------------------------------------
5214 template <class T1, class T2, class T3, class VoxelFunc>
5215 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5216 {
5217  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5218  ForEachVoxel(attr, *im1, *im2, *im3, vf);
5219 }
5220 
5221 // -----------------------------------------------------------------------------
5222 template <class T1, class T2, class T3, class VoxelFunc>
5223 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5224 {
5225  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5226  body(re);
5227  vf.join(body._VoxelFunc);
5228 }
5229 
5230 // -----------------------------------------------------------------------------
5231 template <class T1, class T2, class T3, class VoxelFunc>
5232 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5233 {
5234  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5235  ForEachVoxel(re, *im1, *im2, *im3, vf);
5236 }
5237 
5238 // -----------------------------------------------------------------------------
5239 template <class T1, class T2, class T3, class VoxelFunc>
5240 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5241 {
5242  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5243  body(re);
5244  vf.join(body._VoxelFunc);
5245 }
5246 
5247 // -----------------------------------------------------------------------------
5248 template <class T1, class T2, class T3, class VoxelFunc>
5249 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5250 {
5251  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5252  ForEachVoxel(re, *im1, *im2, *im3, vf);
5253 }
5254 
5255 // -----------------------------------------------------------------------------
5256 template <class T1, class T2, class T3, class VoxelFunc>
5257 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5258 {
5259  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5260  body(re);
5261  vf.join(body._VoxelFunc);
5262 }
5263 
5264 // -----------------------------------------------------------------------------
5265 template <class T1, class T2, class T3, class VoxelFunc>
5266 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5267 {
5268  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5269  ForEachVoxel(re, *im1, *im2, *im3, vf);
5270 }
5271 
5272 //
5273 // Image arguments by reference
5274 //
5275 
5276 // -----------------------------------------------------------------------------
5277 template <class T1, class T2, class T3, class VoxelFunc>
5278 void ForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5279 {
5280  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5282  body(re);
5283  vf.join(body._VoxelFunc);
5284 }
5285 
5286 // -----------------------------------------------------------------------------
5287 template <class T1, class T2, class T3, class VoxelFunc>
5288 void ForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5289 {
5290  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5291  ForEachScalar(im1, im2, im3, vf);
5292 }
5293 
5294 // -----------------------------------------------------------------------------
5295 template <class T1, class T2, class T3, class VoxelFunc>
5296 void ForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5297 {
5298  if (im3.GetTSize()) {
5299  ForEachScalar(im1, im2, im3, vf);
5300  } else {
5301  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5302  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
5303  body(re);
5304  vf.join(body._VoxelFunc);
5305  }
5306 }
5307 
5308 // -----------------------------------------------------------------------------
5309 template <class T1, class T2, class T3, class VoxelFunc>
5310 void ForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5311 {
5312  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5313  ForEachVoxel(im1, im2, im3, vf);
5314 }
5315 
5316 // -----------------------------------------------------------------------------
5317 template <class T1, class T2, class T3, class VoxelFunc>
5318 void ForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5319 {
5320  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5321  body(attr);
5322  vf.join(body._VoxelFunc);
5323 }
5324 
5325 // -----------------------------------------------------------------------------
5326 template <class T1, class T2, class T3, class VoxelFunc>
5327 void ForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5328 {
5329  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5330  ForEachVoxel(attr, im1, im2, im3, vf);
5331 }
5332 
5333 // -----------------------------------------------------------------------------
5334 template <class T1, class T2, class T3, class VoxelFunc>
5335 void ForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5336 {
5337  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5338  body(re);
5339  vf.join(body._VoxelFunc);
5340 }
5341 
5342 // -----------------------------------------------------------------------------
5343 template <class T1, class T2, class T3, class VoxelFunc>
5344 void ForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5345 {
5346  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5347  ForEachVoxel(re, im1, im2, im3, vf);
5348 }
5349 
5350 // -----------------------------------------------------------------------------
5351 template <class T1, class T2, class T3, class VoxelFunc>
5352 void ForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5353 {
5354  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5355  body(re);
5356  vf.join(body._VoxelFunc);
5357 }
5358 
5359 // -----------------------------------------------------------------------------
5360 template <class T1, class T2, class T3, class VoxelFunc>
5361 void ForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5362 {
5363  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5364  ForEachVoxel(re, im1, im2, im3, vf);
5365 }
5366 
5367 // -----------------------------------------------------------------------------
5368 template <class T1, class T2, class T3, class VoxelFunc>
5369 void ForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5370 {
5371  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5372  body(re);
5373  vf.join(body._VoxelFunc);
5374 }
5375 
5376 // -----------------------------------------------------------------------------
5377 template <class T1, class T2, class T3, class VoxelFunc>
5378 void ForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5379 {
5380  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5381  ForEachVoxel(re, im1, im2, im3, vf);
5382 }
5383 
5384 // -----------------------------------------------------------------------------
5385 // ForEachVoxelIf
5386 // -----------------------------------------------------------------------------
5387 
5388 //
5389 // Image arguments by pointer
5390 //
5391 
5392 // -----------------------------------------------------------------------------
5393 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5394 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5395 {
5397  blocked_range<int> re(0, im3->GetNumberOfVoxels());
5398  body(re);
5399  vf.join(body._VoxelFunc);
5400  of.join(body._OutsideFunc);
5401 }
5402 
5403 // -----------------------------------------------------------------------------
5404 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5405 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5406 {
5407  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5408  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
5409 }
5410 
5411 // -----------------------------------------------------------------------------
5412 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5413 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5414 {
5416  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
5417 }
5418 
5419 // -----------------------------------------------------------------------------
5420 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5421 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5422 {
5423  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5424  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
5425 }
5426 
5427 // -----------------------------------------------------------------------------
5428 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5429 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5430 {
5431  if (im3->GetTSize()) {
5432  ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
5433  } else {
5435  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
5436  body(re);
5437  vf.join(body._VoxelFunc);
5438  of.join(body._OutsideFunc);
5439  }
5440 }
5441 
5442 // -----------------------------------------------------------------------------
5443 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5444 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5445 {
5446  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5447  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
5448 }
5449 
5450 // -----------------------------------------------------------------------------
5451 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5452 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5453 {
5455  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
5456 }
5457 
5458 // -----------------------------------------------------------------------------
5459 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5460 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5461 {
5462  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5463  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
5464 }
5465 
5466 // -----------------------------------------------------------------------------
5467 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5468 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5469 {
5471  body(attr);
5472  vf.join(body._VoxelFunc);
5473  of.join(body._OutsideFunc);
5474 }
5475 
5476 // -----------------------------------------------------------------------------
5477 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5478 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5479 {
5480  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5481  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
5482 }
5483 
5484 // -----------------------------------------------------------------------------
5485 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5486 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5487 {
5489  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
5490 }
5491 
5492 // -----------------------------------------------------------------------------
5493 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5494 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5495 {
5496  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5497  ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
5498 }
5499 
5500 // -----------------------------------------------------------------------------
5501 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5502 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5503 {
5505  body(re);
5506  vf.join(body._VoxelFunc);
5507  of.join(body._OutsideFunc);
5508 }
5509 
5510 // -----------------------------------------------------------------------------
5511 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5512 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5513 {
5514  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5515  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
5516 }
5517 
5518 // -----------------------------------------------------------------------------
5519 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5520 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5521 {
5523  body(re);
5524  vf.join(body._VoxelFunc);
5525  of.join(body._OutsideFunc);
5526 }
5527 
5528 // -----------------------------------------------------------------------------
5529 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5530 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5531 {
5532  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5533  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
5534 }
5535 
5536 // -----------------------------------------------------------------------------
5537 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5538 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5539 {
5541  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
5542 }
5543 
5544 // -----------------------------------------------------------------------------
5545 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5546 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5547 {
5548  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5549  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
5550 }
5551 
5552 // -----------------------------------------------------------------------------
5553 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5554 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5555 {
5557  body(re);
5558  vf.join(body._VoxelFunc);
5559  of.join(body._OutsideFunc);
5560 }
5561 
5562 // -----------------------------------------------------------------------------
5563 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5564 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5565 {
5566  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5567  ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
5568 }
5569 
5570 // -----------------------------------------------------------------------------
5571 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5572 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5573 {
5575  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
5576 }
5577 
5578 // -----------------------------------------------------------------------------
5579 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5580 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5581 {
5582  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5583  ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
5584 }
5585 
5586 //
5587 // Image arguments by reference
5588 //
5589 
5590 // -----------------------------------------------------------------------------
5591 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5592 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5593 {
5596  body(re);
5597  vf.join(body._VoxelFunc);
5598  of.join(body._OutsideFunc);
5599 }
5600 
5601 // -----------------------------------------------------------------------------
5602 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5603 void ForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5604 {
5605  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5606  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
5607 }
5608 
5609 // -----------------------------------------------------------------------------
5610 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5611 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5612 {
5614  ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
5615 }
5616 
5617 // -----------------------------------------------------------------------------
5618 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5619 void ForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5620 {
5621  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5622  ForEachScalarIf<Domain>(im1, im2, im3, vf);
5623 }
5624 
5625 // -----------------------------------------------------------------------------
5626 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5627 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5628 {
5629  if (im3.GetTSize()) {
5630  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
5631  } else {
5633  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
5634  body(re);
5635  vf.join(body._VoxelFunc);
5636  of.join(body._OutsideFunc);
5637  }
5638 }
5639 
5640 // -----------------------------------------------------------------------------
5641 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5642 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5643 {
5644  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5645  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
5646 }
5647 
5648 // -----------------------------------------------------------------------------
5649 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5650 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5651 {
5653  ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
5654 }
5655 
5656 // -----------------------------------------------------------------------------
5657 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5658 void ForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5659 {
5660  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5661  ForEachVoxelIf<Domain>(im1, im2, im3, vf);
5662 }
5663 
5664 // -----------------------------------------------------------------------------
5665 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5666 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5667 {
5669  body(attr);
5670  vf.join(body._VoxelFunc);
5671  of.join(body._OutsideFunc);
5672 }
5673 
5674 // -----------------------------------------------------------------------------
5675 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5676 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5677 {
5678  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5679  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
5680 }
5681 
5682 // -----------------------------------------------------------------------------
5683 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5684 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5685 {
5687  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
5688 }
5689 
5690 // -----------------------------------------------------------------------------
5691 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5692 void ForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5693 {
5694  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5695  ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
5696 }
5697 
5698 // -----------------------------------------------------------------------------
5699 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5700 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5701 {
5703  body(re);
5704  vf.join(body._VoxelFunc);
5705  of.join(body._OutsideFunc);
5706 }
5707 
5708 // -----------------------------------------------------------------------------
5709 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5710 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5711 {
5712  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5713  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5714 }
5715 
5716 // -----------------------------------------------------------------------------
5717 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5718 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5719 {
5721  body(re);
5722  vf.join(body._VoxelFunc);
5723  of.join(body._OutsideFunc);
5724 }
5725 
5726 // -----------------------------------------------------------------------------
5727 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5728 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5729 {
5730  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5731  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5732 }
5733 
5734 // -----------------------------------------------------------------------------
5735 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5736 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5737 {
5739  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5740 }
5741 
5742 // -----------------------------------------------------------------------------
5743 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5744 void ForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5745 {
5746  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5747  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
5748 }
5749 
5750 // -----------------------------------------------------------------------------
5751 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5752 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5753 {
5755  body(re);
5756  vf.join(body._VoxelFunc);
5757  of.join(body._OutsideFunc);
5758 }
5759 
5760 // -----------------------------------------------------------------------------
5761 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
5762 void ForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5763 {
5764  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5765  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5766 }
5767 
5768 // -----------------------------------------------------------------------------
5769 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5770 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5771 {
5773  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5774 }
5775 
5776 // -----------------------------------------------------------------------------
5777 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
5778 void ForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5779 {
5780  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5781  ForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
5782 }
5783 
5784 // -----------------------------------------------------------------------------
5785 // ParallelForEachVoxel
5786 // -----------------------------------------------------------------------------
5787 
5788 //
5789 // Image arguments by pointer
5790 //
5791 
5792 // -----------------------------------------------------------------------------
5793 template <class T1, class T2, class T3, class VoxelFunc>
5794 void ParallelForEachScalar(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5795 {
5796  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5797  blocked_range<int> re(0, im3->GetNumberOfVoxels());
5798  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5799  else parallel_for (re, body);
5800 }
5801 
5802 // -----------------------------------------------------------------------------
5803 template <class T1, class T2, class T3, class VoxelFunc>
5804 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5805 {
5806  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5807  ParallelForEachScalar(*im1, *im2, *im3, vf);
5808 }
5809 
5810 // -----------------------------------------------------------------------------
5811 template <class T1, class T2, class T3, class VoxelFunc>
5812 void ParallelForEachVoxel(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5813 {
5814  if (im3->GetTSize()) {
5815  ParallelForEachScalar(*im1, *im2, *im3, vf);
5816  } else {
5817  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5818  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
5819  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5820  else parallel_for (re, body);
5821  }
5822 }
5823 
5824 // -----------------------------------------------------------------------------
5825 template <class T1, class T2, class T3, class VoxelFunc>
5826 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5827 {
5828  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5829  ParallelForEachVoxel(*im1, *im2, *im3, vf);
5830 }
5831 
5832 // -----------------------------------------------------------------------------
5833 template <class T1, class T2, class T3, class VoxelFunc>
5834 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5835 {
5836  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5837  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
5838  if (VoxelFunc::IsReduction()) {
5839  if (attr._dt) {
5840  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
5841  } else {
5842  parallel_reduce(re, body);
5843  }
5844  vf.join(body._VoxelFunc);
5845  } else {
5846  if (attr._dt) {
5847  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
5848  } else {
5849  parallel_for(re, body);
5850  }
5851  }
5852 }
5853 
5854 // -----------------------------------------------------------------------------
5855 template <class T1, class T2, class T3, class VoxelFunc>
5856 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5857 {
5858  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5859  ParallelForEachVoxel(attr, *im1, *im2, *im3, vf);
5860 }
5861 
5862 // -----------------------------------------------------------------------------
5863 template <class T1, class T2, class T3, class VoxelFunc>
5864 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5865 {
5866  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5867  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5868  else parallel_for (re, body);
5869 }
5870 
5871 // -----------------------------------------------------------------------------
5872 template <class T1, class T2, class T3, class VoxelFunc>
5873 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5874 {
5875  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5876  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
5877 }
5878 
5879 // -----------------------------------------------------------------------------
5880 template <class T1, class T2, class T3, class VoxelFunc>
5881 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5882 {
5883  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5884  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5885  else parallel_for (re, body);
5886 }
5887 
5888 // -----------------------------------------------------------------------------
5889 template <class T1, class T2, class T3, class VoxelFunc>
5890 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5891 {
5892  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5893  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
5894 }
5895 
5896 // -----------------------------------------------------------------------------
5897 template <class T1, class T2, class T3, class VoxelFunc>
5898 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5899 {
5900  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(*im1, *im2, *im3, vf);
5901  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5902  else parallel_for (re, body);
5903 }
5904 
5905 // -----------------------------------------------------------------------------
5906 template <class T1, class T2, class T3, class VoxelFunc>
5907 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
5908 {
5909  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5910  ParallelForEachVoxel(re, *im1, *im2, *im3, vf);
5911 }
5912 
5913 //
5914 // Image arguments by reference
5915 //
5916 
5917 // -----------------------------------------------------------------------------
5918 template <class T1, class T2, class T3, class VoxelFunc>
5919 void ParallelForEachScalar(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5920 {
5921  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5923  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5924  else parallel_for (re, body);
5925 }
5926 
5927 // -----------------------------------------------------------------------------
5928 template <class T1, class T2, class T3, class VoxelFunc>
5929 void ParallelForEachScalar(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5930 {
5931  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5932  ParallelForEachScalar(im1, im2, im3, vf);
5933 }
5934 
5935 // -----------------------------------------------------------------------------
5936 template <class T1, class T2, class T3, class VoxelFunc>
5937 void ParallelForEachVoxel(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5938 {
5939  if (im3.GetTSize()) {
5940  ParallelForEachScalar(im1, im2, im3, vf);
5941  } else {
5942  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5943  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
5944  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5945  else parallel_for (re, body);
5946  }
5947 }
5948 
5949 // -----------------------------------------------------------------------------
5950 template <class T1, class T2, class T3, class VoxelFunc>
5951 void ParallelForEachVoxel(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5952 {
5953  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5954  ParallelForEachVoxel(im1, im2, im3, vf);
5955 }
5956 
5957 // -----------------------------------------------------------------------------
5958 template <class T1, class T2, class T3, class VoxelFunc>
5959 void ParallelForEachVoxel(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5960 {
5961  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5962  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
5963  if (VoxelFunc::IsReduction()) {
5964  if (attr._dt) {
5965  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
5966  } else {
5967  parallel_reduce(re, body);
5968  }
5969  vf.join(body._VoxelFunc);
5970  } else {
5971  if (attr._dt) {
5972  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
5973  } else {
5974  parallel_for(re, body);
5975  }
5976  }
5977 }
5978 
5979 // -----------------------------------------------------------------------------
5980 template <class T1, class T2, class T3, class VoxelFunc>
5981 void ParallelForEachVoxel(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5982 {
5983  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
5984  ParallelForEachVoxel(attr, im1, im2, im3, vf);
5985 }
5986 
5987 // -----------------------------------------------------------------------------
5988 template <class T1, class T2, class T3, class VoxelFunc>
5989 void ParallelForEachVoxel(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5990 {
5991  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
5992  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
5993  else parallel_for (re, body);
5994 }
5995 
5996 // -----------------------------------------------------------------------------
5997 template <class T1, class T2, class T3, class VoxelFunc>
5998 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
5999 {
6000  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6001  ParallelForEachVoxel(re, im1, im2, im3, vf);
6002 }
6003 
6004 // -----------------------------------------------------------------------------
6005 template <class T1, class T2, class T3, class VoxelFunc>
6006 void ParallelForEachVoxel(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6007 {
6008  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
6009  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6010  else parallel_for (re, body);
6011 }
6012 
6013 // -----------------------------------------------------------------------------
6014 template <class T1, class T2, class T3, class VoxelFunc>
6015 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6016 {
6017  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6018  ParallelForEachVoxel(re, im1, im2, im3, vf);
6019 }
6020 
6021 // -----------------------------------------------------------------------------
6022 template <class T1, class T2, class T3, class VoxelFunc>
6023 void ParallelForEachVoxel(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6024 {
6025  TernaryForEachVoxelBody<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
6026  if (VoxelFunc::IsReduction()) { parallel_reduce(re, body); vf.join(body._VoxelFunc); }
6027  else parallel_for (re, body);
6028 }
6029 
6030 // -----------------------------------------------------------------------------
6031 template <class T1, class T2, class T3, class VoxelFunc>
6032 void ParallelForEachVoxel(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6033 {
6034  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6035  ParallelForEachVoxel(re, im1, im2, im3, vf);
6036 }
6037 
6038 // -----------------------------------------------------------------------------
6039 // ParallelForEachVoxelIf
6040 // -----------------------------------------------------------------------------
6041 
6042 //
6043 // Image arguments by pointer
6044 //
6045 
6046 // -----------------------------------------------------------------------------
6047 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6048 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6049 {
6051  blocked_range<int> re(0, im3->GetNumberOfVoxels());
6052  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6053  parallel_reduce(re, body);
6054  vf.join(body._VoxelFunc);
6055  of.join(body._OutsideFunc);
6056  } else {
6057  parallel_for(re, body);
6058  }
6059 }
6060 
6061 // -----------------------------------------------------------------------------
6062 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6063 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6064 {
6065  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6066  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
6067 }
6068 
6069 // -----------------------------------------------------------------------------
6070 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6071 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6072 {
6074  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
6075 }
6076 
6077 // -----------------------------------------------------------------------------
6078 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6079 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6080 {
6081  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6082  ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf);
6083 }
6084 
6085 // -----------------------------------------------------------------------------
6086 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6087 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6088 {
6089  if (im3->GetTSize()) {
6090  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
6091  } else {
6093  blocked_range<int> re(0, im3->GetNumberOfVoxels() / im3->GetT());
6094  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6095  parallel_reduce(re, body);
6096  vf.join(body._VoxelFunc);
6097  of.join(body._OutsideFunc);
6098  } else {
6099  parallel_for(re, body);
6100  }
6101  }
6102 }
6103 
6104 // -----------------------------------------------------------------------------
6105 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6106 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6107 {
6108  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6109  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
6110 }
6111 
6112 // -----------------------------------------------------------------------------
6113 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6114 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6115 {
6117  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
6118 }
6119 
6120 // -----------------------------------------------------------------------------
6121 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6122 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6123 {
6124  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6125  ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf);
6126 }
6127 
6128 // -----------------------------------------------------------------------------
6129 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6130 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6131 {
6133  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6134  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6135  if (attr._dt) {
6136  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6137  } else {
6138  parallel_reduce(re, body);
6139  }
6140  vf.join(body._VoxelFunc);
6141  of.join(body._OutsideFunc);
6142  } else {
6143  if (attr._dt) {
6144  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6145  } else {
6146  parallel_for(re, body);
6147  }
6148  }
6149 }
6150 
6151 // -----------------------------------------------------------------------------
6152 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6153 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6154 {
6155  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6156  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
6157 }
6158 
6159 // -----------------------------------------------------------------------------
6160 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6161 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6162 {
6164  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
6165 }
6166 
6167 // -----------------------------------------------------------------------------
6168 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6169 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6170 {
6171  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6172  ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf);
6173 }
6174 
6175 // -----------------------------------------------------------------------------
6176 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6177 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6178 {
6180  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6181  parallel_reduce(re, body);
6182  vf.join(body._VoxelFunc);
6183  of.join(body._OutsideFunc);
6184  } else {
6185  parallel_for(re, body);
6186  }
6187 }
6188 
6189 // -----------------------------------------------------------------------------
6190 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6191 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6192 {
6193  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6194  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6195 }
6196 
6197 // -----------------------------------------------------------------------------
6198 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6199 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6200 {
6202  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6203 }
6204 
6205 // -----------------------------------------------------------------------------
6206 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6207 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6208 {
6209  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6210  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
6211 }
6212 
6213 // -----------------------------------------------------------------------------
6214 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6215 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6216 {
6218  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6219  parallel_reduce(re, body);
6220  vf.join(body._VoxelFunc);
6221  of.join(body._OutsideFunc);
6222  } else {
6223  parallel_for(re, body);
6224  }
6225 }
6226 
6227 // -----------------------------------------------------------------------------
6228 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6229 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6230 {
6231  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6232  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6233 }
6234 
6235 // -----------------------------------------------------------------------------
6236 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6237 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6238 {
6240  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6241 }
6242 
6243 // -----------------------------------------------------------------------------
6244 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6245 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6246 {
6247  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6248  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
6249 }
6250 
6251 // -----------------------------------------------------------------------------
6252 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6253 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6254 {
6256  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6257  parallel_reduce(re, body);
6258  vf.join(body._VoxelFunc);
6259  of.join(body._OutsideFunc);
6260  } else {
6261  parallel_for(re, body);
6262  }
6263 }
6264 
6265 // -----------------------------------------------------------------------------
6266 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6267 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6268 {
6269  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6270  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6271 }
6272 
6273 // -----------------------------------------------------------------------------
6274 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6275 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6276 {
6278  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6279 }
6280 
6281 // -----------------------------------------------------------------------------
6282 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6283 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3)
6284 {
6285  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6286  ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf);
6287 }
6288 
6289 //
6290 // Image arguments by reference
6291 //
6292 
6293 // -----------------------------------------------------------------------------
6294 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6295 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6296 {
6299  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6300  parallel_reduce(re, body);
6301  vf.join(body._VoxelFunc);
6302  of.join(body._OutsideFunc);
6303  } else {
6304  parallel_for(re, body);
6305  }
6306 }
6307 
6308 // -----------------------------------------------------------------------------
6309 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6310 void ParallelForEachScalarIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6311 {
6312  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6313  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
6314 }
6315 
6316 // -----------------------------------------------------------------------------
6317 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6318 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6319 {
6321  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
6322 }
6323 
6324 // -----------------------------------------------------------------------------
6325 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6326 void ParallelForEachScalarIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6327 {
6328  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6329  ParallelForEachScalarIf<Domain>(im1, im2, im3, vf);
6330 }
6331 
6332 // -----------------------------------------------------------------------------
6333 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6334 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6335 {
6336  if (im3.GetTSize()) {
6337  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
6338  } else {
6340  blocked_range<int> re(0, im3.GetNumberOfVoxels() / im3.GetT());
6341  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6342  parallel_reduce(re, body);
6343  vf.join(body._VoxelFunc);
6344  of.join(body._OutsideFunc);
6345  } else {
6346  parallel_for(re, body);
6347  }
6348  }
6349 }
6350 
6351 // -----------------------------------------------------------------------------
6352 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6353 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6354 {
6355  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6356  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
6357 }
6358 
6359 // -----------------------------------------------------------------------------
6360 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6361 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6362 {
6364  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
6365 }
6366 
6367 // -----------------------------------------------------------------------------
6368 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6369 void ParallelForEachVoxelIf(VoxelFunc vf, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6370 {
6371  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6372  ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf);
6373 }
6374 
6375 // -----------------------------------------------------------------------------
6376 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6377 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6378 {
6380  blocked_range3d<int> re(0, attr._z, 0, attr._y, 0, attr._x);
6381  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6382  if (attr._dt) {
6383  for (body._l = 0; body._l < attr._t; ++body._l) parallel_reduce(re, body);
6384  } else {
6385  parallel_reduce(re, body);
6386  }
6387  vf.join(body._VoxelFunc);
6388  of.join(body._OutsideFunc);
6389  } else {
6390  if (attr._dt) {
6391  for (body._l = 0; body._l < attr._t; ++body._l) parallel_for(re, body);
6392  } else {
6393  parallel_for(re, body);
6394  }
6395  }
6396 }
6397 
6398 // -----------------------------------------------------------------------------
6399 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6400 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6401 {
6402  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6403  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
6404 }
6405 
6406 // -----------------------------------------------------------------------------
6407 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6408 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6409 {
6411  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
6412 }
6413 
6414 // -----------------------------------------------------------------------------
6415 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6416 void ParallelForEachVoxelIf(VoxelFunc vf, const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6417 {
6418  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6419  ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf);
6420 }
6421 
6422 // -----------------------------------------------------------------------------
6423 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6424 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6425 {
6427  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6428  parallel_reduce(re, body);
6429  vf.join(body._VoxelFunc);
6430  of.join(body._OutsideFunc);
6431  } else {
6432  parallel_for(re, body);
6433  }
6434 }
6435 
6436 // -----------------------------------------------------------------------------
6437 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6438 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6439 {
6440  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6441  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6442 }
6443 
6444 // -----------------------------------------------------------------------------
6445 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6446 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6447 {
6449  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6450 }
6451 
6452 // -----------------------------------------------------------------------------
6453 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6454 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6455 {
6456  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6457  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
6458 }
6459 
6460 // -----------------------------------------------------------------------------
6461 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6462 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6463 {
6465  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6466  parallel_reduce(re, body);
6467  vf.join(body._VoxelFunc);
6468  of.join(body._OutsideFunc);
6469  } else {
6470  parallel_for(re, body);
6471  }
6472 }
6473 
6474 // -----------------------------------------------------------------------------
6475 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6476 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6477 {
6478  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6479  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6480 }
6481 
6482 // -----------------------------------------------------------------------------
6483 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6484 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6485 {
6487  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6488 }
6489 
6490 // -----------------------------------------------------------------------------
6491 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6492 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6493 {
6494  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6495  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
6496 }
6497 
6498 // -----------------------------------------------------------------------------
6499 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6500 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6501 {
6503  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) {
6504  parallel_reduce(re, body);
6505  vf.join(body._VoxelFunc);
6506  of.join(body._OutsideFunc);
6507  } else {
6508  parallel_for(re, body);
6509  }
6510 }
6511 
6512 // -----------------------------------------------------------------------------
6513 template <class Domain, class T1, class T2, class T3, class VoxelFunc, class OutsideFunc>
6514 void ParallelForEachVoxelIf(VoxelFunc vf, OutsideFunc of, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6515 {
6516  if (VoxelFunc::IsReduction() || OutsideFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6517  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6518 }
6519 
6520 // -----------------------------------------------------------------------------
6521 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6522 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6523 {
6525  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6526 }
6527 
6528 // -----------------------------------------------------------------------------
6529 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
6530 void ParallelForEachVoxelIf(VoxelFunc vf, const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3)
6531 {
6532  if (VoxelFunc::IsReduction()) _foreachternaryvoxelfunction_must_not_be_reduction();
6533  ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf);
6534 }
6535 
6536 
6537 } // namespace mirtk
6538 
6539 #endif
double _dt
Voxel t-dimensions (in ms)
Dummy type used to distinguish split constructor from copy constructor.
Definition: Parallel.h:143
TernaryForEachVoxelBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, VoxelFunc &vf)
Constructor.
void operator()(const ImageAttributes &attr) const
Process entire image.
Two-dimensional range.
Definition: Parallel.h:168
TernaryForEachVoxelBody_1Const(TernaryForEachVoxelBody_1Const &o, split s)
Split constructor.
bool IsEmpty() const
Whether image is uninitialized.
Definition: BaseImage.h:1283
TernaryForEachVoxelBody_Const(const TernaryForEachVoxelBody_Const &o)
Copy constructor.
TernaryForEachVoxelIfBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, VoxelFunc &vf, OutsideFunc &of)
Constructor.
TernaryForEachVoxelBody_2Const(const TernaryForEachVoxelBody_2Const &o)
Copy constructor.
int _y
Image y-dimension (in voxels)
TernaryForEachVoxelIfBody_1Const(const TernaryForEachVoxelIfBody_1Const &o)
Copy constructor.
One-dimensional range.
Definition: Parallel.h:155
VoxelFunc _VoxelFunc
Functor executed for each voxel.
TernaryForEachVoxelBody_Const(TernaryForEachVoxelBody_Const &o, split s)
Split constructor.
TernaryForEachVoxelIfBody(TernaryForEachVoxelIfBody &o, split s)
Split constructor.
TernaryForEachVoxelIfBody(const TernaryForEachVoxelIfBody &o)
Copy constructor.
Definition: IOConfig.h:41
VoxelType * GetPointerToVoxels(int=0, int=0, int=0, int=0)
Definition: GenericImage.h:849
int GetX() const
Returns the number of voxels in the x-direction.
Definition: BaseImage.h:904
TernaryForEachVoxelIfBody_Const(TernaryForEachVoxelIfBody_Const &o, split s)
Split constructor.
int _z
Image z-dimension (in voxels)
int _l
Indices for fixed dimensions.
int _t
Image t-dimension (in voxels)
int GetT() const
Returns the number of voxels in the t-direction.
Definition: BaseImage.h:922
TernaryForEachVoxelBody(TernaryForEachVoxelBody &o, split s)
Split constructor.
TernaryForEachVoxelBody(const TernaryForEachVoxelBody &o)
Copy constructor.
int GetY() const
Returns the number of voxels in the y-direction.
Definition: BaseImage.h:910
Three-dimensional range.
Definition: Parallel.h:197
int GetNumberOfVoxels() const
Definition: BaseImage.h:1741
TernaryForEachVoxelIfBody_2Const(TernaryForEachVoxelIfBody_2Const &o, split s)
Split constructor.
TernaryForEachVoxelBody_2Const(TernaryForEachVoxelBody_2Const &o, split s)
Split constructor.
OutsideFunc _OutsideFunc
Functor executed for each background voxel.
TernaryForEachVoxelBody_2Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, GenericImage< T3 > &im3, VoxelFunc &vf)
Constructor.
TernaryForEachVoxelIfBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, VoxelFunc &vf, OutsideFunc &of)
Constructor.
double GetTSize() const
Returns the size of a voxel in the t-direction.
Definition: BaseImage.h:970
TernaryForEachVoxelBody(GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, VoxelFunc &vf)
Constructor.
TernaryForEachVoxelIfBody_2Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, GenericImage< T3 > &im3, VoxelFunc &vf, OutsideFunc &of)
Constructor.
int _x
Image x-dimension (in voxels)
TernaryForEachVoxelBody_Const(const GenericImage< T1 > &im1, const GenericImage< T2 > &im2, const GenericImage< T3 > &im3, VoxelFunc &vf)
Constructor.
TernaryForEachVoxelIfBody_1Const(const GenericImage< T1 > &im1, GenericImage< T2 > &im2, GenericImage< T3 > &im3, VoxelFunc &vf, OutsideFunc &of)
Constructor.
void parallel_reduce(const Range &range, Body &body)
parallel_reduce dummy template function which executes the body serially
Definition: Parallel.h:238
TernaryForEachVoxelIfBody_2Const(const TernaryForEachVoxelIfBody_2Const &o)
Copy constructor.
TernaryForEachVoxelIfBody_1Const(TernaryForEachVoxelIfBody_1Const &o, split s)
Split constructor.
void parallel_for(const Range &range, const Body &body)
parallel_for dummy template function which executes the body serially
Definition: Parallel.h:232
TernaryForEachVoxelBody_1Const(const TernaryForEachVoxelBody_1Const &o)
Copy constructor.
TernaryForEachVoxelIfBody_Const(const TernaryForEachVoxelIfBody_Const &o)
Copy constructor.