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 
_foreachternaryvoxelfunction_must_not_be_reduction()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>
57 struct TernaryForEachVoxelBody_Const : public ForEachVoxelBody<VoxelFunc>
58 {
59   const GenericImage<T1> &im1;
60   const GenericImage<T2> &im2;
61   const GenericImage<T3> &im3;
62 
63   /// Constructor
TernaryForEachVoxelBody_ConstTernaryForEachVoxelBody_Const64   TernaryForEachVoxelBody_Const(const GenericImage<T1> &im1,
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
TernaryForEachVoxelBody_ConstTernaryForEachVoxelBody_Const73   TernaryForEachVoxelBody_Const(const TernaryForEachVoxelBody_Const &o)
74   :
75     ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
76   {}
77 
78   /// Split constructor
TernaryForEachVoxelBody_ConstTernaryForEachVoxelBody_Const79   TernaryForEachVoxelBody_Const(TernaryForEachVoxelBody_Const &o, split s)
80   :
81     ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
82   {}
83 
84   /// Process entire image
operatorTernaryForEachVoxelBody_Const85   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
operatorTernaryForEachVoxelBody_Const104   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
operatorTernaryForEachVoxelBody_Const118   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
operatorTernaryForEachVoxelBody_Const140   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
TernaryForEachVoxelIfBody_ConstTernaryForEachVoxelIfBody_Const180   TernaryForEachVoxelIfBody_Const(const GenericImage<T1> &im1,
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
TernaryForEachVoxelIfBody_ConstTernaryForEachVoxelIfBody_Const189   TernaryForEachVoxelIfBody_Const(const TernaryForEachVoxelIfBody_Const &o)
190   :
191     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
192   {}
193 
194   /// Split constructor
TernaryForEachVoxelIfBody_ConstTernaryForEachVoxelIfBody_Const195   TernaryForEachVoxelIfBody_Const(TernaryForEachVoxelIfBody_Const &o, split s)
196   :
197     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
198   {}
199 
200   /// Process entire image
operatorTernaryForEachVoxelIfBody_Const201   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
operatorTernaryForEachVoxelIfBody_Const222   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
operatorTernaryForEachVoxelIfBody_Const238   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
operatorTernaryForEachVoxelIfBody_Const262   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>
ForEachScalar(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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);
303   blocked_range<int> re(0, im3->GetNumberOfVoxels());
304   body(re);
305   vf.join(body._VoxelFunc);
306 }
307 
308 // -----------------------------------------------------------------------------
309 template <class T1, class T2, class T3, class VoxelFunc>
ForEachScalar(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxel(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachScalar(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)412 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
413 {
414   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
415   blocked_range<int> re(0, im3.GetNumberOfVoxels());
416   body(re);
417   vf.join(body._VoxelFunc);
418 }
419 
420 // -----------------------------------------------------------------------------
421 template <class T1, class T2, class T3, class VoxelFunc>
ForEachScalar(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxel(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)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 {
435     TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ForEachVoxel(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)452 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
453 {
454   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
455   body(attr);
456   vf.join(body._VoxelFunc);
457 }
458 
459 // -----------------------------------------------------------------------------
460 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)469 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
470 {
471   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
472   body(re);
473   vf.join(body._VoxelFunc);
474 }
475 
476 // -----------------------------------------------------------------------------
477 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)486 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
487 {
488   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
489   body(re);
490   vf.join(body._VoxelFunc);
491 }
492 
493 // -----------------------------------------------------------------------------
494 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)503 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
504 {
505   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
506   body(re);
507   vf.join(body._VoxelFunc);
508 }
509 
510 // -----------------------------------------------------------------------------
511 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)528 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
529 {
530   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
531   blocked_range<int> re(0, im3->GetNumberOfVoxels());
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)547 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
548 {
549   NaryVoxelFunction::NOP of;
550   ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
551 }
552 
553 // -----------------------------------------------------------------------------
554 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
568     TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)586 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
587 {
588   NaryVoxelFunction::NOP of;
589   ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
590 }
591 
592 // -----------------------------------------------------------------------------
593 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)602 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
603 {
604   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)620 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
621 {
622   NaryVoxelFunction::NOP of;
623   ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
624 }
625 
626 // -----------------------------------------------------------------------------
627 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
638   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
656   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)672 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
673 {
674   NaryVoxelFunction::NOP of;
675   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
676 }
677 
678 // -----------------------------------------------------------------------------
679 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
690   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)706 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
707 {
708   NaryVoxelFunction::NOP of;
709   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
710 }
711 
712 // -----------------------------------------------------------------------------
713 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)726 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
727 {
728   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
729   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)745 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
746 {
747   NaryVoxelFunction::NOP of;
748   ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
749 }
750 
751 // -----------------------------------------------------------------------------
752 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
766     TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)784 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
785 {
786   NaryVoxelFunction::NOP of;
787   ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
788 }
789 
790 // -----------------------------------------------------------------------------
791 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)800 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
801 {
802   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)818 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
819 {
820   NaryVoxelFunction::NOP of;
821   ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
822 }
823 
824 // -----------------------------------------------------------------------------
825 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
836   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
854   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)870 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
871 {
872   NaryVoxelFunction::NOP of;
873   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
874 }
875 
876 // -----------------------------------------------------------------------------
877 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
888   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)904 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
905 {
906   NaryVoxelFunction::NOP of;
907   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
908 }
909 
910 // -----------------------------------------------------------------------------
911 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachScalar(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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);
931   blocked_range<int> re(0, im3->GetNumberOfVoxels());
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>
ParallelForEachScalar(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxel(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachScalar(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1053 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1054 {
1055   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
1056   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalar(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxel(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)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 {
1076     TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1093 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1094 {
1095   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1123 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1124 {
1125   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1140 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1141 {
1142   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1157 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1158 {
1159   TernaryForEachVoxelBody_Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)1182 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1183 {
1184   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)1205 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1206 {
1207   NaryVoxelFunction::NOP of;
1208   ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
1209 }
1210 
1211 // -----------------------------------------------------------------------------
1212 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
1226     TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)1248 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1249 {
1250   NaryVoxelFunction::NOP of;
1251   ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
1252 }
1253 
1254 // -----------------------------------------------------------------------------
1255 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)1264 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
1265 {
1266   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)1295 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1296 {
1297   NaryVoxelFunction::NOP of;
1298   ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
1299 }
1300 
1301 // -----------------------------------------------------------------------------
1302 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
1313   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)1333 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1334 {
1335   NaryVoxelFunction::NOP of;
1336   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1337 }
1338 
1339 // -----------------------------------------------------------------------------
1340 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
1351   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)1371 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1372 {
1373   NaryVoxelFunction::NOP of;
1374   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1375 }
1376 
1377 // -----------------------------------------------------------------------------
1378 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
1389   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3,VoxelFunc & vf)1409 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, const GenericImage<T3> *im3, VoxelFunc &vf)
1410 {
1411   NaryVoxelFunction::NOP of;
1412   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
1413 }
1414 
1415 // -----------------------------------------------------------------------------
1416 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,const GenericImage<T3> * im3)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>
ParallelForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)1429 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1430 {
1431   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
1432   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1452 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1453 {
1454   NaryVoxelFunction::NOP of;
1455   ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
1456 }
1457 
1458 // -----------------------------------------------------------------------------
1459 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
1473     TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1495 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1496 {
1497   NaryVoxelFunction::NOP of;
1498   ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
1499 }
1500 
1501 // -----------------------------------------------------------------------------
1502 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)1511 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
1512 {
1513   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1542 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1543 {
1544   NaryVoxelFunction::NOP of;
1545   ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
1546 }
1547 
1548 // -----------------------------------------------------------------------------
1549 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
1560   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1580 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1581 {
1582   NaryVoxelFunction::NOP of;
1583   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1584 }
1585 
1586 // -----------------------------------------------------------------------------
1587 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
1598   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1618 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1619 {
1620   NaryVoxelFunction::NOP of;
1621   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1622 }
1623 
1624 // -----------------------------------------------------------------------------
1625 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
1636   TernaryForEachVoxelIfBody_Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3,VoxelFunc & vf)1656 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, const GenericImage<T3> &im3, VoxelFunc &vf)
1657 {
1658   NaryVoxelFunction::NOP of;
1659   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
1660 }
1661 
1662 // -----------------------------------------------------------------------------
1663 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,const GenericImage<T3> & im3)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>
1679 struct TernaryForEachVoxelBody_2Const : public ForEachVoxelBody<VoxelFunc>
1680 {
1681   const GenericImage<T1> &im1;
1682   const GenericImage<T2> &im2;
1683         GenericImage<T3> &im3;
1684 
1685   /// Constructor
TernaryForEachVoxelBody_2ConstTernaryForEachVoxelBody_2Const1686   TernaryForEachVoxelBody_2Const(const GenericImage<T1> &im1,
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
TernaryForEachVoxelBody_2ConstTernaryForEachVoxelBody_2Const1695   TernaryForEachVoxelBody_2Const(const TernaryForEachVoxelBody_2Const &o)
1696   :
1697     ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
1698   {}
1699 
1700   /// Split constructor
TernaryForEachVoxelBody_2ConstTernaryForEachVoxelBody_2Const1701   TernaryForEachVoxelBody_2Const(TernaryForEachVoxelBody_2Const &o, split s)
1702   :
1703     ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
1704   {}
1705 
1706   /// Process entire image
operatorTernaryForEachVoxelBody_2Const1707   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
operatorTernaryForEachVoxelBody_2Const1726   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
operatorTernaryForEachVoxelBody_2Const1740   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
operatorTernaryForEachVoxelBody_2Const1762   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
TernaryForEachVoxelIfBody_2ConstTernaryForEachVoxelIfBody_2Const1802   TernaryForEachVoxelIfBody_2Const(const GenericImage<T1> &im1,
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
TernaryForEachVoxelIfBody_2ConstTernaryForEachVoxelIfBody_2Const1811   TernaryForEachVoxelIfBody_2Const(const TernaryForEachVoxelIfBody_2Const &o)
1812   :
1813     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
1814   {}
1815 
1816   /// Split constructor
TernaryForEachVoxelIfBody_2ConstTernaryForEachVoxelIfBody_2Const1817   TernaryForEachVoxelIfBody_2Const(TernaryForEachVoxelIfBody_2Const &o, split s)
1818   :
1819     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
1820   {}
1821 
1822   /// Process entire image
operatorTernaryForEachVoxelIfBody_2Const1823   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
operatorTernaryForEachVoxelIfBody_2Const1844   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
operatorTernaryForEachVoxelIfBody_2Const1860   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
operatorTernaryForEachVoxelIfBody_2Const1884   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>
ForEachScalar(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachScalar(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalar(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2034 void ForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2035 {
2036   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
2037   blocked_range<int> re(0, im3.GetNumberOfVoxels());
2038   body(re);
2039   vf.join(body._VoxelFunc);
2040 }
2041 
2042 // -----------------------------------------------------------------------------
2043 template <class T1, class T2, class T3, class VoxelFunc>
ForEachScalar(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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 {
2057     TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ForEachVoxel(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2074 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2075 {
2076   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
2077   body(attr);
2078   vf.join(body._VoxelFunc);
2079 }
2080 
2081 // -----------------------------------------------------------------------------
2082 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2091 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2092 {
2093   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
2094   body(re);
2095   vf.join(body._VoxelFunc);
2096 }
2097 
2098 // -----------------------------------------------------------------------------
2099 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2108 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2109 {
2110   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
2111   body(re);
2112   vf.join(body._VoxelFunc);
2113 }
2114 
2115 // -----------------------------------------------------------------------------
2116 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2125 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2126 {
2127   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
2128   body(re);
2129   vf.join(body._VoxelFunc);
2130 }
2131 
2132 // -----------------------------------------------------------------------------
2133 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2150 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2151 {
2152   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2169 void ForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2170 {
2171   NaryVoxelFunction::NOP of;
2172   ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2173 }
2174 
2175 // -----------------------------------------------------------------------------
2176 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
2190     TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2208 void ForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2209 {
2210   NaryVoxelFunction::NOP of;
2211   ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2212 }
2213 
2214 // -----------------------------------------------------------------------------
2215 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2224 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2225 {
2226   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2242 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2243 {
2244   NaryVoxelFunction::NOP of;
2245   ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
2246 }
2247 
2248 // -----------------------------------------------------------------------------
2249 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2258 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2259 {
2260   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2276 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2277 {
2278   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2294 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2295 {
2296   NaryVoxelFunction::NOP of;
2297   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2298 }
2299 
2300 // -----------------------------------------------------------------------------
2301 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2310 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2311 {
2312   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2328 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2329 {
2330   NaryVoxelFunction::NOP of;
2331   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2332 }
2333 
2334 // -----------------------------------------------------------------------------
2335 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)2348 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2349 {
2350   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
2351   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2367 void ForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2368 {
2369   NaryVoxelFunction::NOP of;
2370   ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
2371 }
2372 
2373 // -----------------------------------------------------------------------------
2374 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
2388     TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2406 void ForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2407 {
2408   NaryVoxelFunction::NOP of;
2409   ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
2410 }
2411 
2412 // -----------------------------------------------------------------------------
2413 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)2422 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2423 {
2424   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2440 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2441 {
2442   NaryVoxelFunction::NOP of;
2443   ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
2444 }
2445 
2446 // -----------------------------------------------------------------------------
2447 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)2456 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2457 {
2458   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)2474 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2475 {
2476   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2492 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2493 {
2494   NaryVoxelFunction::NOP of;
2495   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2496 }
2497 
2498 // -----------------------------------------------------------------------------
2499 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)2508 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
2509 {
2510   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2526 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2527 {
2528   NaryVoxelFunction::NOP of;
2529   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
2530 }
2531 
2532 // -----------------------------------------------------------------------------
2533 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalar(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachScalar(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalar(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2675 void ParallelForEachScalar(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2676 {
2677   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
2678   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalar(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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 {
2698     TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2715 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2716 {
2717   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2745 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2746 {
2747   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2762 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2763 {
2764   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)2779 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
2780 {
2781   TernaryForEachVoxelBody_2Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2804 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2805 {
2806   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalarIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2827 void ParallelForEachScalarIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2828 {
2829   NaryVoxelFunction::NOP of;
2830   ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
2831 }
2832 
2833 // -----------------------------------------------------------------------------
2834 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
2848     TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2870 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2871 {
2872   NaryVoxelFunction::NOP of;
2873   ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
2874 }
2875 
2876 // -----------------------------------------------------------------------------
2877 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2886 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2887 {
2888   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2917 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2918 {
2919   NaryVoxelFunction::NOP of;
2920   ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
2921 }
2922 
2923 // -----------------------------------------------------------------------------
2924 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2933 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2934 {
2935   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2955 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2956 {
2957   NaryVoxelFunction::NOP of;
2958   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2959 }
2960 
2961 // -----------------------------------------------------------------------------
2962 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)2971 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
2972 {
2973   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)2993 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
2994 {
2995   NaryVoxelFunction::NOP of;
2996   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
2997 }
2998 
2999 // -----------------------------------------------------------------------------
3000 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)3009 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3010 {
3011   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)3031 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, const GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3032 {
3033   NaryVoxelFunction::NOP of;
3034   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3035 }
3036 
3037 // -----------------------------------------------------------------------------
3038 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,const GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)3051 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3052 {
3053   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
3054   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalarIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3074 void ParallelForEachScalarIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3075 {
3076   NaryVoxelFunction::NOP of;
3077   ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
3078 }
3079 
3080 // -----------------------------------------------------------------------------
3081 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
3095     TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3117 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3118 {
3119   NaryVoxelFunction::NOP of;
3120   ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
3121 }
3122 
3123 // -----------------------------------------------------------------------------
3124 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)3133 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3134 {
3135   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3164 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3165 {
3166   NaryVoxelFunction::NOP of;
3167   ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
3168 }
3169 
3170 // -----------------------------------------------------------------------------
3171 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)3180 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3181 {
3182   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3202 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3203 {
3204   NaryVoxelFunction::NOP of;
3205   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3206 }
3207 
3208 // -----------------------------------------------------------------------------
3209 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)3218 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3219 {
3220   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3240 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3241 {
3242   NaryVoxelFunction::NOP of;
3243   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3244 }
3245 
3246 // -----------------------------------------------------------------------------
3247 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)3256 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3257 {
3258   TernaryForEachVoxelIfBody_2Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3278 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, const GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3279 {
3280   NaryVoxelFunction::NOP of;
3281   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
3282 }
3283 
3284 // -----------------------------------------------------------------------------
3285 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,const GenericImage<T2> & im2,GenericImage<T3> & im3)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>
3301 struct TernaryForEachVoxelBody_1Const : public ForEachVoxelBody<VoxelFunc>
3302 {
3303   const GenericImage<T1> &im1;
3304         GenericImage<T2> &im2;
3305         GenericImage<T3> &im3;
3306 
3307   /// Constructor
TernaryForEachVoxelBody_1ConstTernaryForEachVoxelBody_1Const3308   TernaryForEachVoxelBody_1Const(const GenericImage<T1> &im1,
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
TernaryForEachVoxelBody_1ConstTernaryForEachVoxelBody_1Const3317   TernaryForEachVoxelBody_1Const(const TernaryForEachVoxelBody_1Const &o)
3318   :
3319     ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
3320   {}
3321 
3322   /// Split constructor
TernaryForEachVoxelBody_1ConstTernaryForEachVoxelBody_1Const3323   TernaryForEachVoxelBody_1Const(TernaryForEachVoxelBody_1Const &o, split s)
3324   :
3325     ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
3326   {}
3327 
3328   /// Process entire image
operatorTernaryForEachVoxelBody_1Const3329   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
operatorTernaryForEachVoxelBody_1Const3348   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
operatorTernaryForEachVoxelBody_1Const3362   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
operatorTernaryForEachVoxelBody_1Const3384   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
TernaryForEachVoxelIfBody_1ConstTernaryForEachVoxelIfBody_1Const3424   TernaryForEachVoxelIfBody_1Const(const GenericImage<T1> &im1,
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
TernaryForEachVoxelIfBody_1ConstTernaryForEachVoxelIfBody_1Const3433   TernaryForEachVoxelIfBody_1Const(const TernaryForEachVoxelIfBody_1Const &o)
3434   :
3435     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
3436   {}
3437 
3438   /// Split constructor
TernaryForEachVoxelIfBody_1ConstTernaryForEachVoxelIfBody_1Const3439   TernaryForEachVoxelIfBody_1Const(TernaryForEachVoxelIfBody_1Const &o, split s)
3440   :
3441     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
3442   {}
3443 
3444   /// Process entire image
operatorTernaryForEachVoxelIfBody_1Const3445   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
operatorTernaryForEachVoxelIfBody_1Const3466   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
operatorTernaryForEachVoxelIfBody_1Const3482   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
operatorTernaryForEachVoxelIfBody_1Const3506   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>
ForEachScalar(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachScalar(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalar(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3656 void ForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3657 {
3658   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
3659   blocked_range<int> re(0, im3.GetNumberOfVoxels());
3660   body(re);
3661   vf.join(body._VoxelFunc);
3662 }
3663 
3664 // -----------------------------------------------------------------------------
3665 template <class T1, class T2, class T3, class VoxelFunc>
ForEachScalar(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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 {
3679     TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ForEachVoxel(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3696 void ForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3697 {
3698   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
3699   body(attr);
3700   vf.join(body._VoxelFunc);
3701 }
3702 
3703 // -----------------------------------------------------------------------------
3704 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3713 void ForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3714 {
3715   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
3716   body(re);
3717   vf.join(body._VoxelFunc);
3718 }
3719 
3720 // -----------------------------------------------------------------------------
3721 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3730 void ForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3731 {
3732   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
3733   body(re);
3734   vf.join(body._VoxelFunc);
3735 }
3736 
3737 // -----------------------------------------------------------------------------
3738 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3747 void ForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3748 {
3749   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
3750   body(re);
3751   vf.join(body._VoxelFunc);
3752 }
3753 
3754 // -----------------------------------------------------------------------------
3755 template <class T1, class T2, class T3, class VoxelFunc>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachScalarIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)3772 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3773 {
3774   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalarIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)3791 void ForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3792 {
3793   NaryVoxelFunction::NOP of;
3794   ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
3795 }
3796 
3797 // -----------------------------------------------------------------------------
3798 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
3812     TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)3830 void ForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3831 {
3832   NaryVoxelFunction::NOP of;
3833   ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
3834 }
3835 
3836 // -----------------------------------------------------------------------------
3837 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)3846 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3847 {
3848   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)3864 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3865 {
3866   NaryVoxelFunction::NOP of;
3867   ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
3868 }
3869 
3870 // -----------------------------------------------------------------------------
3871 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)3880 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3881 {
3882   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)3898 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3899 {
3900   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)3916 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3917 {
3918   NaryVoxelFunction::NOP of;
3919   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3920 }
3921 
3922 // -----------------------------------------------------------------------------
3923 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)3932 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
3933 {
3934   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)3950 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
3951 {
3952   NaryVoxelFunction::NOP of;
3953   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
3954 }
3955 
3956 // -----------------------------------------------------------------------------
3957 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalarIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)3970 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
3971 {
3972   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
3973   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachScalarIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)3989 void ForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
3990 {
3991   NaryVoxelFunction::NOP of;
3992   ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
3993 }
3994 
3995 // -----------------------------------------------------------------------------
3996 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
4010     TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4028 void ForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4029 {
4030   NaryVoxelFunction::NOP of;
4031   ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4032 }
4033 
4034 // -----------------------------------------------------------------------------
4035 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4044 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4045 {
4046   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4062 void ForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4063 {
4064   NaryVoxelFunction::NOP of;
4065   ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
4066 }
4067 
4068 // -----------------------------------------------------------------------------
4069 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4078 void ForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4079 {
4080   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4096 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4097 {
4098   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4114 void ForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4115 {
4116   NaryVoxelFunction::NOP of;
4117   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4118 }
4119 
4120 // -----------------------------------------------------------------------------
4121 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4130 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4131 {
4132   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4148 void ForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4149 {
4150   NaryVoxelFunction::NOP of;
4151   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4152 }
4153 
4154 // -----------------------------------------------------------------------------
4155 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalar(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachScalar(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalar(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4297 void ParallelForEachScalar(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4298 {
4299   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
4300   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalar(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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 {
4320     TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4337 void ParallelForEachVoxel(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4338 {
4339   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4367 void ParallelForEachVoxel(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4368 {
4369   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4384 void ParallelForEachVoxel(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4385 {
4386   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4401 void ParallelForEachVoxel(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4402 {
4403   TernaryForEachVoxelBody_1Const<T1, T2, T3, VoxelFunc> body(im1, im2, im3, vf);
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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalarIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)4426 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4427 {
4428   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalarIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)4449 void ParallelForEachScalarIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4450 {
4451   NaryVoxelFunction::NOP of;
4452   ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
4453 }
4454 
4455 // -----------------------------------------------------------------------------
4456 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
4470     TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)4492 void ParallelForEachVoxelIf(const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4493 {
4494   NaryVoxelFunction::NOP of;
4495   ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
4496 }
4497 
4498 // -----------------------------------------------------------------------------
4499 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)4508 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4509 {
4510   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)4539 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4540 {
4541   NaryVoxelFunction::NOP of;
4542   ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
4543 }
4544 
4545 // -----------------------------------------------------------------------------
4546 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)4555 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4556 {
4557   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)4577 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4578 {
4579   NaryVoxelFunction::NOP of;
4580   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4581 }
4582 
4583 // -----------------------------------------------------------------------------
4584 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)4593 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4594 {
4595   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)4615 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4616 {
4617   NaryVoxelFunction::NOP of;
4618   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4619 }
4620 
4621 // -----------------------------------------------------------------------------
4622 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)4631 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
4632 {
4633   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)4653 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
4654 {
4655   NaryVoxelFunction::NOP of;
4656   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
4657 }
4658 
4659 // -----------------------------------------------------------------------------
4660 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalarIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4673 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4674 {
4675   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
4676   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalarIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4696 void ParallelForEachScalarIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4697 {
4698   NaryVoxelFunction::NOP of;
4699   ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
4700 }
4701 
4702 // -----------------------------------------------------------------------------
4703 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
4717     TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4739 void ParallelForEachVoxelIf(const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4740 {
4741   NaryVoxelFunction::NOP of;
4742   ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
4743 }
4744 
4745 // -----------------------------------------------------------------------------
4746 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4755 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4756 {
4757   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4786 void ParallelForEachVoxelIf(const ImageAttributes &attr, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4787 {
4788   NaryVoxelFunction::NOP of;
4789   ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
4790 }
4791 
4792 // -----------------------------------------------------------------------------
4793 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4802 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4803 {
4804   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4824 void ParallelForEachVoxelIf(const blocked_range<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4825 {
4826   NaryVoxelFunction::NOP of;
4827   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4828 }
4829 
4830 // -----------------------------------------------------------------------------
4831 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4840 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4841 {
4842   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4862 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4863 {
4864   NaryVoxelFunction::NOP of;
4865   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4866 }
4867 
4868 // -----------------------------------------------------------------------------
4869 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)4878 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
4879 {
4880   TernaryForEachVoxelIfBody_1Const<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)4900 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, const GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
4901 {
4902   NaryVoxelFunction::NOP of;
4903   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
4904 }
4905 
4906 // -----------------------------------------------------------------------------
4907 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,const GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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
TernaryForEachVoxelBodyTernaryForEachVoxelBody4930   TernaryForEachVoxelBody(GenericImage<T1> &im1,
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
TernaryForEachVoxelBodyTernaryForEachVoxelBody4939   TernaryForEachVoxelBody(const TernaryForEachVoxelBody &o)
4940   :
4941     ForEachVoxelBody<VoxelFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
4942   {}
4943 
4944   /// Split constructor
TernaryForEachVoxelBodyTernaryForEachVoxelBody4945   TernaryForEachVoxelBody(TernaryForEachVoxelBody &o, split s)
4946   :
4947     ForEachVoxelBody<VoxelFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
4948   {}
4949 
4950   /// Process entire image
operatorTernaryForEachVoxelBody4951   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
operatorTernaryForEachVoxelBody4970   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
operatorTernaryForEachVoxelBody4984   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
operatorTernaryForEachVoxelBody5006   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
TernaryForEachVoxelIfBodyTernaryForEachVoxelIfBody5046   TernaryForEachVoxelIfBody(GenericImage<T1> &im1,
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
TernaryForEachVoxelIfBodyTernaryForEachVoxelIfBody5055   TernaryForEachVoxelIfBody(const TernaryForEachVoxelIfBody &o)
5056   :
5057     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o), im1(o.im1), im2(o.im2), im3(o.im3)
5058   {}
5059 
5060   /// Split constructor
TernaryForEachVoxelIfBodyTernaryForEachVoxelIfBody5061   TernaryForEachVoxelIfBody(TernaryForEachVoxelIfBody &o, split s)
5062   :
5063     ForEachVoxelIfBody<VoxelFunc, OutsideFunc>(o, s), im1(o.im1), im2(o.im2), im3(o.im3)
5064   {}
5065 
5066   /// Process entire image
operatorTernaryForEachVoxelIfBody5067   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
operatorTernaryForEachVoxelIfBody5088   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
operatorTernaryForEachVoxelIfBody5104   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
operatorTernaryForEachVoxelIfBody5128   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>
ForEachScalar(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachScalar(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxel(const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalar(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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);
5281   blocked_range<int> re(0, im3.GetNumberOfVoxels());
5282   body(re);
5283   vf.join(body._VoxelFunc);
5284 }
5285 
5286 // -----------------------------------------------------------------------------
5287 template <class T1, class T2, class T3, class VoxelFunc>
ForEachScalar(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxel(const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachScalarIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)5394 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5395 {
5396   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalarIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)5413 void ForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5414 {
5415   NaryVoxelFunction::NOP of;
5416   ForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
5417 }
5418 
5419 // -----------------------------------------------------------------------------
5420 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
5434     TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)5452 void ForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5453 {
5454   NaryVoxelFunction::NOP of;
5455   ForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
5456 }
5457 
5458 // -----------------------------------------------------------------------------
5459 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)5468 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5469 {
5470   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)5486 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5487 {
5488   NaryVoxelFunction::NOP of;
5489   ForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
5490 }
5491 
5492 // -----------------------------------------------------------------------------
5493 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)5502 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5503 {
5504   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)5520 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5521 {
5522   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)5538 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5539 {
5540   NaryVoxelFunction::NOP of;
5541   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
5542 }
5543 
5544 // -----------------------------------------------------------------------------
5545 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)5554 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
5555 {
5556   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)5572 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
5573 {
5574   NaryVoxelFunction::NOP of;
5575   ForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
5576 }
5577 
5578 // -----------------------------------------------------------------------------
5579 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ForEachScalarIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)5592 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5593 {
5594   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
5595   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ForEachScalarIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachScalarIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)5611 void ForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5612 {
5613   NaryVoxelFunction::NOP of;
5614   ForEachScalarIf<Domain>(im1, im2, im3, vf, of);
5615 }
5616 
5617 // -----------------------------------------------------------------------------
5618 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachScalarIf(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
5632     TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)5650 void ForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5651 {
5652   NaryVoxelFunction::NOP of;
5653   ForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
5654 }
5655 
5656 // -----------------------------------------------------------------------------
5657 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)5666 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5667 {
5668   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)5684 void ForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5685 {
5686   NaryVoxelFunction::NOP of;
5687   ForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
5688 }
5689 
5690 // -----------------------------------------------------------------------------
5691 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)5700 void ForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5701 {
5702   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)5718 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5719 {
5720   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)5736 void ForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5737 {
5738   NaryVoxelFunction::NOP of;
5739   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5740 }
5741 
5742 // -----------------------------------------------------------------------------
5743 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)5752 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
5753 {
5754   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)5770 void ForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
5771 {
5772   NaryVoxelFunction::NOP of;
5773   ForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
5774 }
5775 
5776 // -----------------------------------------------------------------------------
5777 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalar(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachScalar(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalar(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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);
5922   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalar(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxel(const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)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>
ParallelForEachVoxel(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalarIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)6048 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6049 {
6050   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalarIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)6071 void ParallelForEachScalarIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6072 {
6073   NaryVoxelFunction::NOP of;
6074   ParallelForEachScalarIf<Domain>(*im1, *im2, *im3, vf, of);
6075 }
6076 
6077 // -----------------------------------------------------------------------------
6078 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)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 {
6092     TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)6114 void ParallelForEachVoxelIf(GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6115 {
6116   NaryVoxelFunction::NOP of;
6117   ParallelForEachVoxelIf<Domain>(*im1, *im2, *im3, vf, of);
6118 }
6119 
6120 // -----------------------------------------------------------------------------
6121 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)6130 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6131 {
6132   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)6161 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6162 {
6163   NaryVoxelFunction::NOP of;
6164   ParallelForEachVoxelIf<Domain>(attr, *im1, *im2, *im3, vf, of);
6165 }
6166 
6167 // -----------------------------------------------------------------------------
6168 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)6177 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6178 {
6179   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)6199 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6200 {
6201   NaryVoxelFunction::NOP of;
6202   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6203 }
6204 
6205 // -----------------------------------------------------------------------------
6206 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)6215 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6216 {
6217   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)6237 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6238 {
6239   NaryVoxelFunction::NOP of;
6240   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6241 }
6242 
6243 // -----------------------------------------------------------------------------
6244 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf,OutsideFunc & of)6253 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf, OutsideFunc &of)
6254 {
6255   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(*im1, *im2, *im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3,VoxelFunc & vf)6275 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> *im1, GenericImage<T2> *im2, GenericImage<T3> *im3, VoxelFunc &vf)
6276 {
6277   NaryVoxelFunction::NOP of;
6278   ParallelForEachVoxelIf<Domain>(re, *im1, *im2, *im3, vf, of);
6279 }
6280 
6281 // -----------------------------------------------------------------------------
6282 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> * im1,GenericImage<T2> * im2,GenericImage<T3> * im3)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>
ParallelForEachScalarIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)6295 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6296 {
6297   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
6298   blocked_range<int> re(0, im3.GetNumberOfVoxels());
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>
ParallelForEachScalarIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachScalarIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)6318 void ParallelForEachScalarIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6319 {
6320   NaryVoxelFunction::NOP of;
6321   ParallelForEachScalarIf<Domain>(im1, im2, im3, vf, of);
6322 }
6323 
6324 // -----------------------------------------------------------------------------
6325 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachScalarIf(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)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 {
6339     TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)6361 void ParallelForEachVoxelIf(GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6362 {
6363   NaryVoxelFunction::NOP of;
6364   ParallelForEachVoxelIf<Domain>(im1, im2, im3, vf, of);
6365 }
6366 
6367 // -----------------------------------------------------------------------------
6368 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)6377 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6378 {
6379   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)6408 void ParallelForEachVoxelIf(const ImageAttributes &attr, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6409 {
6410   NaryVoxelFunction::NOP of;
6411   ParallelForEachVoxelIf<Domain>(attr, im1, im2, im3, vf, of);
6412 }
6413 
6414 // -----------------------------------------------------------------------------
6415 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const ImageAttributes & attr,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)6424 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6425 {
6426   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)6446 void ParallelForEachVoxelIf(const blocked_range<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6447 {
6448   NaryVoxelFunction::NOP of;
6449   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6450 }
6451 
6452 // -----------------------------------------------------------------------------
6453 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)6462 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6463 {
6464   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)6484 void ParallelForEachVoxelIf(const blocked_range2d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6485 {
6486   NaryVoxelFunction::NOP of;
6487   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6488 }
6489 
6490 // -----------------------------------------------------------------------------
6491 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range2d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf,OutsideFunc & of)6500 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf, OutsideFunc &of)
6501 {
6502   TernaryForEachVoxelIfBody<T1, T2, T3, VoxelFunc, OutsideFunc, Domain> body(im1, im2, im3, vf, of);
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>
ParallelForEachVoxelIf(VoxelFunc vf,OutsideFunc of,const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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>
ParallelForEachVoxelIf(const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3,VoxelFunc & vf)6522 void ParallelForEachVoxelIf(const blocked_range3d<int> &re, GenericImage<T1> &im1, GenericImage<T2> &im2, GenericImage<T3> &im3, VoxelFunc &vf)
6523 {
6524   NaryVoxelFunction::NOP of;
6525   ParallelForEachVoxelIf<Domain>(re, im1, im2, im3, vf, of);
6526 }
6527 
6528 // -----------------------------------------------------------------------------
6529 template <class Domain, class T1, class T2, class T3, class VoxelFunc>
ParallelForEachVoxelIf(VoxelFunc vf,const blocked_range3d<int> & re,GenericImage<T1> & im1,GenericImage<T2> & im2,GenericImage<T3> & im3)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
6540