1 /************************************************************************/
2 /*                                                                      */
3 /*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
4 /*                                                                      */
5 /*    This file is part of the VIGRA computer vision library.           */
6 /*    The VIGRA Website is                                              */
7 /*        http://hci.iwr.uni-heidelberg.de/vigra/                       */
8 /*    Please direct questions, bug reports, and contributions to        */
9 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
10 /*        vigra@informatik.uni-hamburg.de                               */
11 /*                                                                      */
12 /*    Permission is hereby granted, free of charge, to any person       */
13 /*    obtaining a copy of this software and associated documentation    */
14 /*    files (the "Software"), to deal in the Software without           */
15 /*    restriction, including without limitation the rights to use,      */
16 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
17 /*    sell copies of the Software, and to permit persons to whom the    */
18 /*    Software is furnished to do so, subject to the following          */
19 /*    conditions:                                                       */
20 /*                                                                      */
21 /*    The above copyright notice and this permission notice shall be    */
22 /*    included in all copies or substantial portions of the             */
23 /*    Software.                                                         */
24 /*                                                                      */
25 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
26 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
27 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
28 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
29 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
30 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
31 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
32 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */
33 /*                                                                      */
34 /************************************************************************/
35 
36 #ifndef VIGRA_VOXELNEIGHBORHOOD_HXX
37 #define VIGRA_VOXELNEIGHBORHOOD_HXX
38 
39 #include "tinyvector.hxx"
40 #include "pixelneighborhood.hxx"
41 
42 namespace vigra {
43 
44 /** \addtogroup VoxelNeighborhood Utilities to manage voxel neighborhoods
45 
46     6- and 26-neighborhood definitions and circulators.
47 
48     <b>\#include</b> \<vigra/voxelneighborhood.hxx\><br>
49 
50     <b>See also:</b> \ref vigra::NeighborhoodCirculator
51  */
52 //@{
53 
54     /// 3-dimensional difference vector
55     typedef vigra::TinyVector<int, 3> Diff3D;
56 
57 /********************************************************/
58 /*                                                      */
59 /*                      AtVolumeBorder                  */
60 /*                                                      */
61 /********************************************************/
62 
63 /** \brief Encode whether a voxel is near the volume border.
64 
65         //    This enum is used with \ref isAtVolumeBorder() and
66         //    \ref vigra::RestrictedNeighborhoodCirculator.
67 
68         //<b>\#include</b> \<vigra/voxelneighborhood.hxx\><br>
69         //Namespace: vigra
70 */
71 
72 typedef AtImageBorder AtVolumeBorder;
73 
74 
75 /** \brief Find out whether a voxel is at the volume border.
76 
77     This function checks if \a x == 0 or \a x == \a width - 1 and
78     \a y == 0 or \a y == \a height - 1 and so on and returns the appropriate value
79     of \ref vigra::AtVolumeBorder, or zero when the voxel is not at te volume border.
80     The behavior of the function is undefined if (x,y,z) is not inside the volume.
81 */
isAtVolumeBorder(int x,int y,int z,int width,int height,int depth)82 inline AtVolumeBorder isAtVolumeBorder(int x, int y, int z, int width, int height, int depth)
83 {
84     return static_cast<AtVolumeBorder>((x == 0
85                                          ? LeftBorder
86                                          : x == width-1
87                                              ? RightBorder
88                                              : NotAtBorder) |
89                                        (y == 0
90                                          ? TopBorder
91                                          : y == height-1
92                                              ? BottomBorder
93                                              : NotAtBorder) |
94                                        (z == 0
95                                          ? FrontBorder
96                                          : z == depth-1
97                                              ? RearBorder
98                                              : NotAtBorder));
99 }
100 
isAtVolumeBorder(Diff3D const & p,Diff3D const & shape)101 inline AtVolumeBorder isAtVolumeBorder(Diff3D const & p, Diff3D const & shape)
102 {
103     return isAtVolumeBorder(p[0], p[1], p[2], shape[0], shape[1], shape[2]);
104 }
105 
106 /** \brief Find out whether a voxel is at a scan-order relevant volume border.
107     This function checks if \a x == 0 or \a y == 0 or \a z == \a 0 and returns the
108         appropriate value of \ref vigra::AtVolumeBorder, or zero when the voxel is
109         not at te volume border.
110     The behavior of the function is undefined if (x,y,z) is not inside the volume.
111 */
isAtVolumeBorderCausal(int x,int y,int z,int width,int height,int)112 inline AtVolumeBorder isAtVolumeBorderCausal(int x, int y, int z, int width, int height, int /* depth */)
113 {
114     return static_cast<AtVolumeBorder>((x == 0
115                                          ? LeftBorder
116                                          : x == width-1
117                                              ? RightBorder
118                                              : NotAtBorder) |
119                                        (y == 0
120                                          ? TopBorder
121                                          : y == height-1
122                                              ? BottomBorder
123                                              : NotAtBorder) |
124                                        (z == 0
125                                          ? FrontBorder
126                                          : NotAtBorder));
127 }
128 /** TODO: Write new comment \brief Find out whether a voxel is at a scan-order relevant volume border.
129     This function checks if \a x == 0 or \a y == 0 or \a z == \a 0 and returns the
130         appropriate value of \ref vigra::AtVolumeBorder, or zero when the voxel is
131         not at te volume border.
132     The behavior of the function is undefined if (x,y,z) is not inside the volume.
133 */
isAtVolumeBorderAntiCausal(int x,int y,int z,int width,int height,int depth)134 inline AtVolumeBorder isAtVolumeBorderAntiCausal(int x, int y, int z, int width, int height, int depth)
135 {
136     return static_cast<AtVolumeBorder>((x == 0
137                                          ? LeftBorder
138                                          : x == width-1
139                                              ? RightBorder
140                                              : NotAtBorder) |
141                                        (y == 0
142                                          ? TopBorder
143                                          : y == height-1
144                                              ? BottomBorder
145                                              : NotAtBorder) |
146                                        (z == depth-1
147                                          ? RearBorder
148                                          : NotAtBorder));
149 }
150 
151 /********************************************************/
152 /*                                                      */
153 /*                   Neighborhood3DSix                  */
154 /*                                                      */
155 /********************************************************/
156 
157 /** 3D 6-Neighborhood. */
158 namespace Neighborhood3DSix
159 {
160 
161 /** \brief Encapsulation of direction management of neighbors for a 3D 6-neighborhood.
162 */
163 class NeighborCode3D
164 {
165     public:
166 
167     typedef Diff3D difference_type;
168 
169     /** provides enumeration of all directions.
170         DirectionCount may be used for portable loop termination conditions.
171     */
172     enum Direction {
173         Error = -1,
174         InFront= 0,
175         North,
176         West ,
177         Behind,
178         South,
179         East,
180         DirectionCount,
181         CausalFirst = InFront,
182         CausalLast  = West,
183         AntiCausalFirst = Behind,
184         AntiCausalLast  = East,
185 
186         InitialDirection = InFront,
187         OppositeDirPrefix = 1,
188         OppositeOffset = 3
189     };
190 
191     template <int DUMMY>
192     struct StaticData
193     {
194         static unsigned int b[];
195         static unsigned int c[];
196         static Direction bd[43][6];
197         static Direction bc[43][4];
198         static Diff3D d[];
199         static Diff3D rd[][6];
200     };
201 
directionBit(Direction d)202     static unsigned int directionBit(Direction d)
203     {
204         return StaticData<0>::b[d];
205     };
206 
207 
208     /** The number of valid neighbors if the current center is at the volume border.
209     */
nearBorderDirectionCount(AtVolumeBorder b)210     static unsigned int nearBorderDirectionCount(AtVolumeBorder b)
211     {
212         return StaticData<0>::c[b];
213     }
214 
215     /** The valid direction codes when the center is at the volume border.
216         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
217     */
nearBorderDirections(AtVolumeBorder b,int index)218     static Direction nearBorderDirections(AtVolumeBorder b, int index)
219     {
220         return StaticData<0>::bd[b][index];
221     }
222 
223     /** The valid direction three codes in anti causal direction (means: look back in scanline
224         direction)when the center is at the volume border.
225         Should be used with isAtVolumeBorderCausal to determine the Directions, as this
226         avoids using of the nonesense border ids (e.g. 0,1,8,9...) of this table.
227         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
228     */
nearBorderDirectionsCausal(AtVolumeBorder b,int index)229     static Direction nearBorderDirectionsCausal(AtVolumeBorder b, int index)
230     {
231         return StaticData<0>::bc[b][index];
232     }
233 
234     /** transform direction code into corresponding Diff3D offset.
235         (note: there is no bounds checking on the code you pass.)
236     */
diff(Direction code)237     static Diff3D const & diff(Direction code)
238     {
239         return StaticData<0>::d[code];
240     }
241 
242     /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
243         (note: there is no bounds checking on the code you pass.)
244     */
diff(int code)245     static Diff3D const & diff(int code) { return diff(static_cast<Direction>(code)); }
246 
247     /**  Equivalent to <tt>diff(code)[dim]</tt> */
diff(Direction code,int dim)248     static int diff(Direction code, int dim) { return diff(code)[dim]; }
249 
250     /** Get the relative offset from one neighbor to the other.
251         For example, <tt>relativeDiff(East, West) == multi_differencetype(-2,0,0)</tt>.
252         (note: there is no bounds checking on the code you pass.)
253     */
relativeDiff(Direction fromCode,Direction toCode)254     static Diff3D const & relativeDiff(Direction fromCode, Direction toCode)
255     {
256         return StaticData<0>::rd[fromCode][toCode];
257     }
258 
259     /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
260         (note: there is no bounds checking on the code you pass.)
261     */
relativeDiff(int fromCode,int toCode)262     static Diff3D const & relativeDiff(int fromCode, int toCode)
263     {
264         return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
265     }
266 
267     /**  X-component of diff() */
dX(Direction code)268     static int dX(Direction code) { return diff(code)[0]; }
269     /**  Y-component of diff() */
dY(Direction code)270     static int dY(Direction code) { return diff(code)[1]; }
271     /**  Z-component of diff() */
dZ(Direction code)272     static int dZ(Direction code) { return diff(code)[2]; }
273 
274     /**  X-component of diff() */
dX(int code)275     static int dX(int code) { return diff(code)[0]; }
276     /**  Y-component of diff() */
dY(int code)277     static int dY(int code) { return diff(code)[1]; }
278     /**  Z-component of diff() */
dZ(int code)279     static int dZ(int code) { return diff(code)[2]; }
280 
281 
282     /** transform Diff3D offset into corresponding direction code.
283         The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
284         is not in the 3DSix-Neighborhood.
285     */
code(Diff3D const & diff)286     static Direction code(Diff3D const & diff)
287     {
288         switch(diff[0]) {
289             case  0:
290             {
291                 switch(diff[1]) {
292                     case 0:
293                         switch(diff[2]) {
294                             case 1:
295                                 return Behind;
296                             case -1:
297                                 return InFront;
298                             default:
299                                 return Error;
300                         }
301 
302                     case 1:
303                         return (diff[2] == 0) ? South : Error;
304                     case -1:
305                         return (diff[2] == 0) ? North : Error;
306                     default:
307                         return Error;
308                 }
309         }
310         case -1:
311             return ((diff[1] == 0) && (diff[2] == 0)) ? West : Error;
312         case  1:
313             return ((diff[1] == 0) && (diff[2] == 0)) ? East : Error;
314         }
315         return Error;
316     }
317 
318     /** Check whether a code refers to a diagonal direction.
319         Useful if you want to abstract the differences between 6- and 26-neighborhood.
320         Always <tt>false</tt> for 6-neighborhood.
321     */
isDiagonal(Direction)322     static bool isDiagonal(Direction) { return false; }
323 
right()324     static Diff3D const & right()           { return diff(East); }          /**<  Offset to the right neighbor */
top()325     static Diff3D const & top()             { return diff(North); }         /**<  Offset to the top neighbor */
left()326     static Diff3D const & left()            { return diff(West); }          /**<  Offset to the left neighbor */
bottom()327     static Diff3D const & bottom()          { return diff(South); }         /**<  Offset to the bottom neighbor */
rear()328     static Diff3D const & rear()            { return diff(Behind); }        /**<  Offset to the rear neighbor */
front()329     static Diff3D const & front()           { return diff(InFront); }       /**<  Offset to the neighbor in front */
330 
east()331     static Diff3D const & east()            { return diff(East); }          /**<  Offset to the east neighbor */
north()332     static Diff3D const & north()           { return diff(North); }         /**<  Offset to the north neighbor */
west()333     static Diff3D const & west()            { return diff(West); }          /**<  Offset to the west neighbor */
south()334     static Diff3D const & south()           { return diff(South); }         /**<  Offset to the south neighbor */
behind()335     static Diff3D const & behind()          { return diff(Behind); }        /**<  Offset to the rear neighbor */
infront()336     static Diff3D const & infront()         { return diff(InFront); }       /**<  Offset to the neighbor in front */
337 
338 }; // class Neighborhood3DSix
339 
340 
341 /** Export NeighborCode3D::Direction into the scope of namespace Neighborhood3DSix.
342 */
343 typedef NeighborCode3D::Direction Direction;
344 
345 static const Direction East           = NeighborCode3D::East;               /**<  Export NeighborCode3D::East to namespace Neighborhood3DSix */
346 static const Direction North          = NeighborCode3D::North;              /**<  Export NeighborCode3D::North to namespace Neighborhood3DSix */
347 static const Direction West           = NeighborCode3D::West;               /**<  Export NeighborCode3D::West to namespace Neighborhood3DSix */
348 static const Direction South          = NeighborCode3D::South;              /**<  Export NeighborCode3D::South to namespace Neighborhood3DSix */
349 static const Direction Behind         = NeighborCode3D::Behind;             /**<  Export NeighborCode3D::Behind to namespace Neighborhood3DSix */
350 static const Direction InFront        = NeighborCode3D::InFront;            /**<  Export NeighborCode3D::InFront to namespace Neighborhood3DSix */
351 static const Direction DirectionCount = NeighborCode3D::DirectionCount;     /**<  Export NeighborCode3D::DirectionCount to namespace Neighborhood3DSix */
352 
353 template <int DUMMY>
354 unsigned int NeighborCode3D::StaticData<DUMMY>::b[] = {
355                                     1 << InFront,
356                                     1 << North,
357                                     1 << West,
358                                     1 << Behind,
359                                     1 << South,
360                                     1 << East
361                                   };
362 
363 template <int DUMMY>
364 unsigned int NeighborCode3D::StaticData<DUMMY>::c[] = {
365                                     6, 5, 5, 0, 5, 4, 4, 0, 5, 4,
366                                     4, 0, 0, 0, 0, 0, 5, 4, 4, 0,
367                                     4, 3, 3, 0, 4, 3, 3, 0, 0, 0,
368                                     0, 0, 5, 4, 4, 0, 4, 3, 3, 0,
369                                     4, 3, 3};
370 
371 template <int DUMMY>
372 Direction NeighborCode3D::StaticData<DUMMY>::bd[43][6] = {
373                 { InFront, North, West, Behind, South, East},   // 0 - NotAtBorder
374                 { InFront, North, West, Behind, South, Error},  // 1 - AtRightBorder
375                 { InFront, North, Behind, South, East, Error},  // 2 - AtLeftBorder
376                 { Error, Error, Error, Error, Error, Error},
377                 { InFront, West, Behind, South, East, Error},   // 4 - AtTopBorder
378                 { InFront, West, Behind, South, Error, Error},  // 5 - AtTopRightBorder
379                 { InFront, Behind, South, East, Error, Error},  // 6 - AtTopLeftBorder
380                 { Error, Error, Error, Error, Error, Error},
381                 { InFront, North, West, Behind, East, Error},   // 8 - AtBottomBorder
382                 { InFront, North, West, Behind, Error, Error},  // 9 - AtBottomRightBorder
383                 { InFront, North, Behind, East, Error, Error},  //10- AtBottomLeftBorder
384                 { Error, Error, Error, Error, Error, Error},
385                 { Error, Error, Error, Error, Error, Error},
386                 { Error, Error, Error, Error, Error, Error},
387                 { Error, Error, Error, Error, Error, Error},
388                 { Error, Error, Error, Error, Error, Error},
389                 { North, West, Behind, South, East, Error},     //16 - AtFrontBorder
390                 { North, West, Behind, South, Error, Error},    //17 - AtFrontRightBorder
391                 { North, Behind, South, East, Error, Error},    //18 - AtFrontLeftBorder
392                 { Error, Error, Error, Error, Error, Error},
393                 { West, Behind, South, East, Error,  Error},    //20 - AtTopFrontBorder
394                 { West, Behind, South, Error, Error, Error},    //21 - AtTopRightFrontBorder
395                 { Behind, South, East, Error, Error,  Error},   //22 - AtTopLeftFrontBorder
396                 { Error, Error, Error, Error, Error, Error},
397                 { North, West, Behind, East, Error, Error},     //24 - AtBottomFrontBorder
398                 { North, West, Behind, Error, Error, Error},    //25 - AtBottomRightFrontBorder
399                 { North, Behind, East, Error, Error, Error},    //26 - AtBottomLeftFrontBorder
400                 { Error, Error, Error, Error, Error, Error},
401                 { Error, Error, Error, Error, Error, Error},
402                 { Error, Error, Error, Error, Error, Error},
403                 { Error, Error, Error, Error, Error, Error},
404                 { Error, Error, Error, Error, Error, Error},
405                 { InFront, North, West, South, East,Error},     //32 - AtRearBorder
406                 { InFront, North, West, South, Error, Error},   //33 - AtRearRightBorder
407                 { InFront, North, South, East, Error, Error},   //34 - AtRearLeftBorder
408                 { Error, Error, Error, Error, Error, Error},
409                 { InFront, West, South, East, Error, Error},    //36 - AtTopRearBorder
410                 { InFront, West, South, Error, Error, Error},   //37 - AtTopRightRearBorder
411                 { InFront, South, East, Error, Error, Error},   //38 - AtTopLeftRearBorder
412                 { Error, Error, Error, Error, Error, Error},
413                 { InFront, North, West, East, Error, Error},    //40 - AtBottomRearBorder
414                 { InFront, North, West, Error, Error, Error},   //41 - AtBottomRightRearBorder
415                 { InFront, North, East, Error, Error, Error}    //42 - AtBottomLeftRearBorder
416                };
417 
418 template <int DUMMY>
419 Direction NeighborCode3D::StaticData<DUMMY>::bc[43][4] = {
420             { InFront, North, West, Error},                    // 0 - NotAtBorder
421             { InFront, North, West, Error},                    // 1 - AtRightBorder
422             { InFront, North, Error, Error},                   // 2 - AtLeftBorder
423             { Error, Error, Error, Error},
424             { InFront, West, Error, Error},                    // 4 - AtTopBorder
425             { InFront, West, Error, Error},                    // 5 - AtTopRightBorder
426             { InFront, Error,Error, Error},                    // 6 - AtTopLeftBorder
427             { Error, Error, Error, Error},
428             { InFront, North, West, Error},                    // 8 - AtBottomBorder
429             { InFront, North, West, Error},                    // 9 - AtBottomRightBorder
430             { InFront, North, Error, Error},                   //10- AtBottomLeftBorder
431             { Error, Error, Error, Error},
432             { Error, Error, Error, Error},
433             { Error, Error, Error, Error},
434             { Error, Error, Error, Error},
435             { Error, Error, Error, Error},
436             { North, West, Error, Error},                      //16 - AtFrontBorder
437             { North, West, Error, Error},                      //17 - AtFrontRightBorder
438             { North, Error, Error, Error},                     //18 - AtFrontLeftBorder
439             { Error, Error, Error, Error},
440             { West, Error, Error, Error},                      //20 - AtTopFrontBorder
441             { West, Error, Error, Error},                      //21 - AtTopRightFrontBorder
442             { Error, Error,  Error, Error},                    //22 - AtTopLeftFrontBorder
443             { Error, Error, Error, Error},
444             { North, West, Error, Error},                      //24 - AtBottomFrontBorder
445             { North, West, Error, Error},                      //25 - AtBottomRightFrontBorder
446             { North, Error, Error, Error},                     //26 - AtBottomLeftFrontBorder
447             { Error, Error, Error, Error},
448             { Error, Error, Error, Error},
449             { Error, Error, Error, Error},
450             { Error, Error, Error, Error},
451             { Error, Error, Error, Error},
452             { InFront, North, West, Error},                    //32 - AtRearBorder
453             { InFront, North, West, Error},                    //33 - AtRearRightBorder
454             { InFront, North, Error, Error},                   //34 - AtRearLeftBorder
455             { Error, Error, Error, Error},
456             { InFront, West, Error, Error},                    //36 - AtTopRearBorder
457             { InFront, West, Error, Error},                    //37 - AtTopRightRearBorder
458             { InFront, Error, Error, Error},                   //38 - AtTopLeftRearBorder
459             { Error, Error, Error, Error},
460             { InFront, North, West, Error},                    //40 - AtBottomRearBorder
461             { InFront, North, West, Error},                    //41 - AtBottomRightRearBorder
462             { InFront, North, Error, Error}                    //42 - AtBottomLeftRearBorder
463         };
464 
465 template <int DUMMY>
466 Diff3D NeighborCode3D::StaticData<DUMMY>::d[] = {
467                     Diff3D(  0,  0, -1),  //InFront
468                     Diff3D(  0, -1,  0),  //North
469                     Diff3D( -1,  0,  0),  //West
470                     Diff3D(  0,  0,  1),  //Behind
471                     Diff3D(  0,  1,  0),  //South
472                     Diff3D(  1,  0,  0)   //East
473                 };
474 
475 template <int DUMMY>
476 Diff3D NeighborCode3D::StaticData<DUMMY>::rd[][6] = {
477 //     InFront      -      North         -           West     -         Behind     -      South        -        East
478 { Diff3D( 0, 0, 0), Diff3D(0, -1, 1), Diff3D(-1, 0, 1), Diff3D( 0, 0, 2), Diff3D( 0, 1, 1),  Diff3D( 1, 0, 1)}, //InFront
479 { Diff3D( 0, 1,-1), Diff3D( 0, 0, 0), Diff3D(-1, 1, 0), Diff3D( 0, 1, 1), Diff3D( 0, 2, 0),  Diff3D( 1, 1, 0)}, //North
480 { Diff3D( 1, 0,-1), Diff3D( 1,-1, 0), Diff3D( 0, 0, 0), Diff3D( 1, 0, 1), Diff3D( 1, 1, 0),  Diff3D( 2, 0, 0)}, //West
481 { Diff3D( 0, 0,-2), Diff3D( 0,-1,-1), Diff3D(-1, 0,-1), Diff3D( 0, 0, 0), Diff3D( 0, 1,-1),  Diff3D( 1, 0,-1)}, //Behind
482 { Diff3D( 0,-1,-1), Diff3D( 0,-2, 0), Diff3D(-1,-1, 0), Diff3D( 0,-1, 1), Diff3D( 0, 0, 0),  Diff3D( 1,-1, 0)}, //South
483 { Diff3D(-1, 0,-1), Diff3D(-1,-1, 0), Diff3D(-2, 0, 0), Diff3D(-1, 0, 1), Diff3D(-1, 1, 0), Diff3D( 0, 0, 0) }  //East
484 };
485 
486 }//namespace Neighborhood3DSix
487 
488 /** Export \ref vigra::Neighborhood3DSix::NeighborCode3D into the scope of namespace vigra.
489 */
490 typedef Neighborhood3DSix::NeighborCode3D NeighborCode3DSix;
491 
492 /********************************************************/
493 /*                                                      */
494 /*                   Neighborhood3DTwentySix            */
495 /*                                                      */
496 /********************************************************/
497 /** 3D 26-Neighborhood. */
498 namespace Neighborhood3DTwentySix
499 {
500 
501 /** \brief Encapsulation of direction management of neighbors for a 3D 26-neighborhood.
502 */
503 class NeighborCode3D
504 {
505     public:
506 
507     typedef Diff3D difference_type;
508 
509    /** provides enumeration of all directions.
510        DirectionCount may be used for portable loop termination conditions.
511      */
512     enum Direction {
513         Error = -1,
514             InFrontNorthWest = 0,
515             InFrontNorth,
516             InFrontNorthEast,
517             InFrontWest,
518         InFront,
519             InFrontEast,
520             InFrontSouthWest,
521             InFrontSouth,
522             InFrontSouthEast,
523 
524             NorthWest,
525             North,
526             NorthEast,
527         West,
528             East,
529             SouthWest,
530             South,
531             SouthEast,
532 
533             BehindNorthWest,
534             BehindNorth,
535             BehindNorthEast,
536             BehindWest,
537         Behind,
538             BehindEast,
539             BehindSouthWest,
540             BehindSouth,
541             BehindSouthEast,
542 
543         DirectionCount,
544             CausalFirst = InFrontNorthWest,
545             CausalLast  = West,
546             AntiCausalFirst = BehindSouthEast,
547             AntiCausalLast  = East,
548 
549             InitialDirection = InFrontNorthWest,
550             OppositeDirPrefix = -1,
551             OppositeOffset = 25
552     };
553 
554     template <int DUMMY>
555     struct StaticData
556     {
557         static unsigned int b[];
558         static unsigned int c[];
559         static Direction bd[43][26];
560         static Direction bc[43][13];
561         static Diff3D d[];
562     };
563 
directionBit(Direction d)564     static unsigned int directionBit(Direction d)
565     {
566         return StaticData<0>::b[d];
567     };
568 
569 
570 
571     /** The number of valid neighbors if the current center is at the volume border.
572     */
nearBorderDirectionCount(AtVolumeBorder b)573     static unsigned int nearBorderDirectionCount(AtVolumeBorder b)
574     {
575         return StaticData<0>::c[b];
576     }
577 
578     /** The valid direction codes when the center is at the volume border.
579         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
580     */
nearBorderDirections(AtVolumeBorder b,int index)581     static Direction nearBorderDirections(AtVolumeBorder b, int index)
582     {
583         return StaticData<0>::bd[b][index];
584     }
585 
586     /** The valid direction three codes in anti causal direction (means: look back in scanline
587         direction)when the center is at the volume border.
588             Should be used with isAtVolumeBorderCausal to determine the Directions, as this
589             avoids using of the nonesense border ids (e.g. 0,1,8,9...) of this table.
590         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
591      */
nearBorderDirectionsCausal(AtVolumeBorder b,int index)592     static Direction nearBorderDirectionsCausal(AtVolumeBorder b, int index)
593     {
594         return StaticData<0>::bc[b][index];
595     }
596 
597     /** transform direction code into corresponding Diff3D offset.
598         (note: there is no bounds checking on the code you pass.)
599     */
diff(Direction code)600     static Diff3D const & diff(Direction code)
601     {
602         return StaticData<0>::d[code];
603     }
604 
605     /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
606         (note: there is no bounds checking on the code you pass.)
607     */
diff(int code)608     static Diff3D const & diff(int code) { return diff(static_cast<Direction>(code)); }
609 
610     /**  Equivalent to <tt>diff(code)[dim]</tt> */
diff(Direction code,int dim)611     static int diff(Direction code, int dim) { return diff(code)[dim]; }
612 
613     /** Get the relative offset from one neighbor to the other.
614     For example, <tt>relativeDiff(East, West) == multi_differencetype(-2,0,0)</tt>.
615     (note: there is no bounds checking on the code you pass.)
616     */
relativeDiff(Direction fromCode,Direction toCode)617     static Diff3D const relativeDiff(Direction fromCode, Direction toCode)
618     {
619         //Uncomment the following lines may cause the program to crash because of insufficient
620         //static allocatable memory on the stack
621         /*
622             static Diff3D d[][] = {
623                 //   InFront-NW    ---     InFront-N   ---     InFront-NE  ---    Infront-W    ---     InFront     ---   InFront-E     ---   InFront-SW    ---      InFront-S  ---   InFront-SE    ---    NorthWest   ---       North      ---    NorthEast    ---      West      ---       East       ---    SouthWest    ---    South        ---     SouthEast  ---     Behind-NW    ---     Behind-N    ---      Behind-NE  ---     Behind-W    ---      Behind     ---    Behind-E     ---    Behind-SW    ---      Behind-S   ---    Behind-SE
624                 {    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2, 2,  0),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 2,  1,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D( 2,  2,  1),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D( 2,  0,  2),    Diff3D( 0,  1,  2),    Diff3D( 1,  1,  2), Diff3D( 2,  1,  2),    Diff3D( 0,  2,  2),    Diff3D( 1,  2,  2),    Diff3D( 2,  2,  2)    },    //InFront-NW
625                 {    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1, 2,  0),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 1,  1,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D(-1,  1,  2),    Diff3D( 0,  1,  2), Diff3D( 1,  1,  2),    Diff3D(-1,  2,  2),    Diff3D( 0,  2,  2),    Diff3D( 1,  2,  2)    },    //InFront-N
626                 {    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0, 2,  0),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D( 0,  1,  1),    Diff3D(-2,  2,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D(-2,  1,  2),    Diff3D(-1,  1,  2), Diff3D( 0,  1,  2),    Diff3D(-2,  2,  2),    Diff3D(-1,  2,  2),    Diff3D( 0,  2,  2)    },    //InFront-NE
627                 {    Diff3D(0,  -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2, 1,  0),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D( 2,  1,  1),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2),    Diff3D( 2, -1,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2), Diff3D( 2,  0,  2),    Diff3D( 0,  1,  2),    Diff3D( 1,  1,  2),    Diff3D( 2,  1,  2)    },    //Infront-W
628                 {    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1, 1,  0),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2), Diff3D( 1,  0,  2),    Diff3D(-1,  1,  2),    Diff3D( 0,  1,  2),    Diff3D( 1,  1,  2)    },    //InFront
629                 {    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0, 1,  0),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1),    Diff3D(-2, -1,  2),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2), Diff3D( 0,  0,  2),    Diff3D(-2,  1,  2),    Diff3D(-1,  1,  2),    Diff3D( 0,  1,  2)    },    //InFront-E
630                 {    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2, 0,  0),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D( 2, -2,  1),    Diff3D( 0, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0, -2,  2),    Diff3D( 1, -2,  2),    Diff3D( 2, -2,  2),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2), Diff3D( 2, -1,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D( 2,  0,  2)    },    //InFront-SW
631                 {    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1, 0,  0),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D(-1, -1,  1),    Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1, -2,  2),    Diff3D( 0, -2,  2),    Diff3D( 1, -2,  2),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2), Diff3D( 1, -1,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2)    },    //InFront-S
632                 {    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0, 0,  0),    Diff3D(-2, -2,  1),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D(-2, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2, -2,  2),    Diff3D(-1, -2,  2),    Diff3D( 0, -2,  2),    Diff3D(-2, -1,  2),    Diff3D(-1, -1,  2), Diff3D( 0, -1,  2),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2)    },    //InFront-SE
633                 {    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D( 2, 2, -1),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2,  2,  0),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1), Diff3D( 2,  1,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D( 2,  2,  1)    },    //NorthWest
634                 {    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D( 1, 2, -1),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1), Diff3D( 1,  1,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1)    },    //North
635                 {    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2,  2, -1),    Diff3D(-1,  2, -1),    Diff3D( 0, 2, -1),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1), Diff3D( 0,  1,  1),    Diff3D(-2,  2,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1)    },    //NortEast
636                 {    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2, 1, -1),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1), Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D( 2,  1,  1)    },    //West
637                 {    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0, 1, -1),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1), Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1)    },    //East
638                 {    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D( 2, -2, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2, 0, -1),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D( 2, -2,  1),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1), Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1)    },    //SouthWest
639                 {    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1, 0, -1),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1), Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1)    },    //South
640                 {    Diff3D(-2, -2, -1),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0, 0, -1),    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2, -2,  1),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1), Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1)    },    //SouthEast
641                 {    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2,  0, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D( 2,  1, -2),    Diff3D( 0,  2, -2),    Diff3D( 1,  2, -2),    Diff3D( 2, 2, -2),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D( 2,  2, -1),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2,  2,  0)    },    //Behind-NW
642                 {    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D(-1,  2, -2),    Diff3D( 0,  2, -2),    Diff3D( 1, 2, -2),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0)    },    //Behind-N
643                 {    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D(-2,  1, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D(-2,  2, -2),    Diff3D(-1,  2, -2),    Diff3D( 0, 2, -2),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2,  2, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0)    },    //Behind-NE
644                 {    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D( 2, -1, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2,  0, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D( 2, 1, -2),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0), Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0)    },    //Behind-W
645                 {    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D( 1, 1, -2),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0), Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0)    },    //Behind
646                 {    Diff3D(-2, -1, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D(-2,  1, -2),    Diff3D(-1,  1, -2),    Diff3D( 0, 1, -2),    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0), Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0)    },    //Behind-E
647                 {    Diff3D( 0, -2, -2),    Diff3D( 1, -2, -2),    Diff3D( 2, -2, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D( 2, -1, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2, 0, -2),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D( 2, -2, -1),    Diff3D( 0, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0), Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0)    },    //Behind-SW
648                 {    Diff3D(-1, -2, -2),    Diff3D( 0, -2, -2),    Diff3D( 1, -2, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1, 0, -2),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D(-1, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0), Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0)    },    //Behind-S
649                 {    Diff3D(-2, -2, -2),    Diff3D(-1, -2, -2),    Diff3D( 0, -2, -2),    Diff3D(-2, -1, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0, 0, -2),    Diff3D(-2, -2, -1),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D(-2, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0), Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0), Diff3D( 0,  0,  0)    }        //Behind-SE
650             };
651             return d[fromCode][toCode];
652         */
653         return diff(toCode)-diff(fromCode);
654     }
655 
656    /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
657        (note: there is no bounds checking on the code you pass.)
658    */
relativeDiff(int fromCode,int toCode)659     static Diff3D const relativeDiff(int fromCode, int toCode)
660     {
661         return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
662     }
663 
664     /**  X-component of diff() */
dX(Direction code)665     static int dX(Direction code) { return diff(code)[0]; }
666     /**  Y-component of diff() */
dY(Direction code)667     static int dY(Direction code) { return diff(code)[1]; }
668     /**  Z-component of diff() */
dZ(Direction code)669     static int dZ(Direction code) { return diff(code)[2]; }
670 
671     /**  X-component of diff() */
dX(int code)672     static int dX(int code) { return diff(code)[0]; }
673     /**  Y-component of diff() */
dY(int code)674     static int dY(int code) { return diff(code)[1]; }
675     /**  Z-component of diff() */
dZ(int code)676     static int dZ(int code) { return diff(code)[2]; }
677 
678     /** transform 6-neighborhood code into 26-neighborhood code.
679      */
code(Neighborhood3DSix::Direction d)680     static Direction code(Neighborhood3DSix::Direction d)
681     {
682         switch (d){
683             case Neighborhood3DSix::InFront :
684                     return InFront;
685             case Neighborhood3DSix::North :
686                     return North;
687             case Neighborhood3DSix::West :
688                     return West;
689             case Neighborhood3DSix::East :
690                     return East;
691             case Neighborhood3DSix::South :
692                     return South;
693             case Neighborhood3DSix::Behind :
694                     return Behind;
695             default:
696                 vigra_fail("NeighborCode3D::code(): Internal error -- invalid direction code.");
697         }
698         return Error;
699     }
700 
701     /** transform Diff3D offset into corresponding direction code.
702        The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
703        is not in the 3DTwentySix-Neighborhood.
704     */
code(Diff3D const & diff)705     static Direction code(Diff3D const & diff)
706     {
707         switch(diff[0]){
708             case -1:
709                 switch(diff[1]){
710                     case -1:
711                         switch(diff[2]){
712                             case -1: return InFrontNorthWest; // ( -1, -1, -1)
713                             case  0: return NorthWest;        // ( -1, -1,  0)
714                             case  1: return BehindNorthWest;  // ( -1, -1,  1)
715                         }
716                     case  0:
717                         switch(diff[2]){
718                             case -1: return InFrontWest;      // ( -1,  0, -1)
719                             case  0: return West;             // ( -1,  0,  0)
720                             case  1: return BehindWest;       // ( -1,  0,  1)
721                         }
722                     case  1:
723                         switch(diff[2]){
724                             case -1: return InFrontSouthWest; // ( -1,  1, -1)
725                             case  0: return SouthWest;        // ( -1,  1,  0)
726                             case  1: return BehindSouthWest;  // ( -1,  1,  1)
727                         }
728                 }
729             case  0:
730                 switch(diff[1]){
731                     case -1:
732                         switch(diff[2]){
733                             case -1: return InFrontNorth;     // (  0,  0, -1)
734                             case  0: return North;            // (  0, -1,  0)
735                             case  1: return BehindNorth;      // (  0, -1,  1)
736                         }
737                     case  0:
738                         switch(diff[2]){
739                             case -1: return InFront;          // (  0,  0, -1)
740                             case  1: return Behind;           // (  0,  0,  1)
741                         }
742                     case  1:
743                         switch(diff[2]){
744                             case -1: return InFrontSouth;     // (  0,  1, -1)
745                             case  0: return South;            // (  0,  1,  0)
746                             case  1: return BehindSouth;      // (  0,  1,  1)
747                         }
748                 }
749             case  1:
750                 switch(diff[1]){
751                     case -1:
752                         switch(diff[2]){
753                             case -1: return InFrontNorthEast;  // (  1, -1, -1)
754                             case  0: return NorthEast;         // (  1, -1,  0)
755                             case  1: return BehindNorthEast;   // (  1, -1,  1)
756                         }
757                     case  0:
758                         switch(diff[2]){
759                             case -1: return InFrontEast;       // (  1,  0, -1)
760                             case  0: return East;              // (  1,  0,  0)
761                             case  1: return BehindEast;        // (  1,  0,  1)
762                         }
763                     case  1:
764                         switch(diff[2]){
765                             case -1: return InFrontSouthEast;  // (  1,  1, -1)
766                             case  0: return SouthEast;         // (  1,  1,  0)
767                             case  1: return BehindSouthEast;   // (  1,  1,  1)
768                         }
769                 }
770         }
771         return Error; // better safe than sorry
772     }
773 
774     /** Check whether a code refers to a diagonal direction.
775         Useful if you want to abstract the differences between 6- and 26-neighborhood.
776         Always <tt>false</tt> for 6-neighborhood.
777     */
isDiagonal(Direction dir)778     static bool isDiagonal(Direction dir) {
779         Diff3D d = diff(dir);
780         if (abs(d[0])+abs(d[1])+abs(d[2])==1)
781             return false;
782         else
783             return true;
784     }
785 
frontTopLeft()786     static Diff3D const & frontTopLeft()        { return diff(InFrontNorthWest); }    /**<  Offset to the front-top-left neighbor */
frontTop()787     static Diff3D const & frontTop()            { return diff(InFrontNorth); }        /**<  Offset to the front-top neighbor */
frontTopRight()788     static Diff3D const & frontTopRight()       { return diff(InFrontNorthEast); }    /**<  Offset to the front-top-right neighbor */
frontLeft()789     static Diff3D const & frontLeft()           { return diff(InFrontWest); }         /**<  Offset to the front-left neighbor */
front()790     static Diff3D const & front()               { return diff(InFront); }             /**<  Offset to the front neighbor */
frontRight()791     static Diff3D const & frontRight()          { return diff(InFrontEast); }         /**<  Offset to the front-right neighbor */
frontBottomLeft()792     static Diff3D const & frontBottomLeft()     { return diff(InFrontSouthWest); }    /**<  Offset to the front-bottom-left neighbor */
frontBottom()793     static Diff3D const & frontBottom()         { return diff(InFrontSouth); }        /**<  Offset to the front-bottom neighbor */
frontBottomRight()794     static Diff3D const & frontBottomRight()    { return diff(InFrontSouthEast); }    /**<  Offset to the front-bottom-right neighbor */
795 
topLeft()796     static Diff3D const & topLeft()             { return diff(NorthWest); }           /**<  Offset to the top-left neighbor */
top()797     static Diff3D const & top()                 { return diff(North); }               /**<  Offset to the top neighbor */
topRight()798     static Diff3D const & topRight()            { return diff(NorthEast); }           /**<  Offset to the top-right neighbor */
left()799     static Diff3D const & left()                { return diff(West); }                /**<  Offset to the left neighbor */
right()800     static Diff3D const & right()               { return diff(East); }                /**<  Offset to the right neighbor */
bottomLeft()801     static Diff3D const & bottomLeft()          { return diff(SouthWest); }           /**<  Offset to the bottom-left neighbor */
bottom()802     static Diff3D const & bottom()              { return diff(South); }               /**<  Offset to the bottom neighbor */
bottomRight()803     static Diff3D const & bottomRight()         { return diff(SouthEast); }           /**<  Offset to the bottom-right neighbor */
804 
rearTopLeft()805     static Diff3D const & rearTopLeft()         { return diff(BehindNorthWest); }     /**<  Offset to the rear-top-left neighbor */
rearTop()806     static Diff3D const & rearTop()             { return diff(BehindNorth); }         /**<  Offset to the rear-top neighbor */
rearTopRight()807     static Diff3D const & rearTopRight()        { return diff(BehindNorthEast); }     /**<  Offset to the rear-top-right neighbor */
rearLeft()808     static Diff3D const & rearLeft()            { return diff(BehindWest); }          /**<  Offset to the rear-left neighbor */
rear()809     static Diff3D const & rear()                { return diff(Behind); }              /**<  Offset to the rear neighbor */
rearRight()810     static Diff3D const & rearRight()           { return diff(BehindEast); }          /**<  Offset to the rear-right neighbor */
rearBottomLeft()811     static Diff3D const & rearBottomLeft()      { return diff(BehindSouthWest); }     /**<  Offset to the rear-bottom-left neighbor */
rearBottom()812     static Diff3D const & rearBottom()          { return diff(BehindSouth); }         /**<  Offset to the rear-bottom neighbor */
rearBottomRight()813     static Diff3D const & rearBottomRight()     { return diff(BehindSouthEast); }     /**<  Offset to the rear-bottom-right neighbor */
814 
815     //----- other namings
816 
infrontNorthWest()817     static Diff3D const & infrontNorthWest()    { return diff(InFrontNorthWest); }    /**<  Offset to the infront-north-west neighbor */
infrontNorth()818     static Diff3D const & infrontNorth()        { return diff(InFrontNorth); }        /**<  Offset to the infront-north neighbor */
infrontNorthEast()819     static Diff3D const & infrontNorthEast()    { return diff(InFrontNorthEast); }    /**<  Offset to the infront-north-east neighbor */
infrontWest()820     static Diff3D const & infrontWest()         { return diff(InFrontWest); }         /**<  Offset to the infront-west neighbor */
infront()821     static Diff3D const & infront()             { return diff(InFront); }             /**<  Offset to the infront neighbor */
infrontEast()822     static Diff3D const & infrontEast()         { return diff(InFrontEast); }         /**<  Offset to the infront-east neighbor */
infrontSouthWest()823     static Diff3D const & infrontSouthWest()    { return diff(InFrontSouthWest); }    /**<  Offset to the infront-south-west neighbor */
infrontSouth()824     static Diff3D const & infrontSouth()        { return diff(InFrontSouth); }        /**<  Offset to the infront-south neighbor */
infrontSouthEast()825     static Diff3D const & infrontSouthEast()    { return diff(InFrontSouthEast); }    /**<  Offset to the infront-south-east neighbor */
826 
northWest()827     static Diff3D const & northWest()           { return diff(NorthWest); }            /**<  Offset to the north-west neighbor */
north()828     static Diff3D const & north()               { return diff(North); }                /**<  Offset to the north neighbor */
northEast()829     static Diff3D const & northEast()           { return diff(NorthEast); }            /**<  Offset to the north-east neighbor */
west()830     static Diff3D const & west()                { return diff(West); }                 /**<  Offset to the west neighbor */
east()831     static Diff3D const & east()                { return diff(East); }                 /**<  Offset to the right neighbor */
southWest()832     static Diff3D const & southWest()           { return diff(SouthWest); }            /**<  Offset to the south-west neighbor */
south()833     static Diff3D const & south()               { return diff(South); }                /**<  Offset to the south neighbor */
southEast()834     static Diff3D const & southEast()           { return diff(SouthEast); }            /**<  Offset to the south-east neighbor */
835 
behindNorthWest()836     static Diff3D const & behindNorthWest()     { return diff(BehindNorthWest); }      /**<  Offset to the behind-north-west neighbor */
behindNorth()837     static Diff3D const & behindNorth()         { return diff(BehindNorth); }          /**<  Offset to the behind-north neighbor */
behindNorthEast()838     static Diff3D const & behindNorthEast()     { return diff(BehindNorthEast); }      /**<  Offset to the behind-north-east neighbor */
behindEast()839     static Diff3D const & behindEast()          { return diff(BehindWest); }           /**<  Offset to the behind-west neighbor */
behind()840     static Diff3D const & behind()              { return diff(Behind); }               /**<  Offset to the behind neighbor */
behindWest()841     static Diff3D const & behindWest()          { return diff(BehindEast); }           /**<  Offset to the behind-right neighbor */
behindSouthWest()842     static Diff3D const & behindSouthWest()     { return diff(BehindSouthWest); }      /**<  Offset to the behind-south-west neighbor */
behindSouth()843     static Diff3D const & behindSouth()         { return diff(BehindSouth); }          /**<  Offset to the behind-south neighbor */
behindSouthEast()844     static Diff3D const & behindSouthEast()     { return diff(BehindSouthEast); }      /**<  Offset to the behind-south-east neighbor */
845 }; // class Neighborhood3D
846 
847 
848 /** Export NeighborCode3D::Direction into the scope of namespace Neighborhood3DSix.
849  */
850 typedef NeighborCode3D::Direction Direction;
851 
852 static const Direction InFrontNorthWest   = NeighborCode3D::InFrontNorthWest;     /**<  Export NeighborCode3D::InFrontNorthWest to namespace Neighborhood3DTwentySix */
853 static const Direction InFrontNorth       = NeighborCode3D::InFrontNorth;         /**<  Export NeighborCode3D::InFrontNorth to namespace Neighborhood3DTwentySix */
854 static const Direction InFrontNorthEast   = NeighborCode3D::InFrontNorthEast;     /**<  Export NeighborCode3D::InFrontNorthEast to namespace Neighborhood3DTwentySix */
855 static const Direction InFrontWest        = NeighborCode3D::InFrontWest;          /**<  Export NeighborCode3D::InFrontWest to namespace Neighborhood3DTwentySix */
856 static const Direction InFront            = NeighborCode3D::InFront;              /**<  Export NeighborCode3D::InFront to namespace Neighborhood3DTwentySix */
857 static const Direction InFrontEast        = NeighborCode3D::InFrontEast;          /**<  Export NeighborCode3D::InFrontEast to namespace Neighborhood3DTwentySix */
858 static const Direction InFrontSouthWest   = NeighborCode3D::InFrontSouthWest;     /**<  Export NeighborCode3D::InFrontSouthWest to namespace Neighborhood3DTwentySix */
859 static const Direction InFrontSouth       = NeighborCode3D::InFrontSouth;         /**<  Export NeighborCode3D::InFrontSouth to namespace Neighborhood3DTwentySix */
860 static const Direction InFrontSouthEast   = NeighborCode3D::InFrontSouthEast;     /**<  Export NeighborCode3D::InFrontSouthEast to namespace Neighborhood3DTwentySix */
861 
862 static const Direction NorthWest          = NeighborCode3D::NorthWest;            /**<  Export NeighborCode3D::NorthWest to namespace Neighborhood3DTwentySix */
863 static const Direction North              = NeighborCode3D::North;                /**<  Export NeighborCode3D::North to namespace Neighborhood3DTwentySix */
864 static const Direction NorthEast          = NeighborCode3D::NorthEast;            /**<  Export NeighborCode3D::NorthEast to namespace Neighborhood3DTwentySix */
865 static const Direction West               = NeighborCode3D::West;                 /**<  Export NeighborCode3D::West to namespace Neighborhood3DTwentySix */
866 static const Direction East               = NeighborCode3D::East;                 /**<  Export NeighborCode3D::East to namespace Neighborhood3DTwentySix */
867 static const Direction SouthWest          = NeighborCode3D::SouthWest;            /**<  Export NeighborCode3D::SouthWest to namespace Neighborhood3DTwentySix */
868 static const Direction South              = NeighborCode3D::South;                /**<  Export NeighborCode3D::South to namespace Neighborhood3DTwentySix */
869 static const Direction SouthEast          = NeighborCode3D::SouthEast;            /**<  Export NeighborCode3D::SouthEast to namespace Neighborhood3DTwentySix */
870 
871 static const Direction BehindNorthWest    = NeighborCode3D::BehindNorthWest;      /**<  Export NeighborCode3D::BehindNorthWest to namespace Neighborhood3DTwentySix */
872 static const Direction BehindNorth        = NeighborCode3D::BehindNorth;          /**<  Export NeighborCode3D::BehindNorth to namespace Neighborhood3DTwentySix */
873 static const Direction BehindNorthEast    = NeighborCode3D::BehindNorthEast;      /**<  Export NeighborCode3D::BehindNorthEast to namespace Neighborhood3DTwentySix */
874 static const Direction BehindWest         = NeighborCode3D::BehindWest;           /**<  Export NeighborCode3D::BehindWest to namespace Neighborhood3DTwentySix */
875 static const Direction Behind             = NeighborCode3D::Behind;               /**<  Export NeighborCode3D::Behind to namespace Neighborhood3DTwentySix */
876 static const Direction BehindEast         = NeighborCode3D::BehindEast;           /**<  Export NeighborCode3D::BehindEast to namespace Neighborhood3DTwentySix */
877 static const Direction BehindSouthWest    = NeighborCode3D::BehindSouthWest;      /**<  Export NeighborCode3D::BehindSouthWest to namespace Neighborhood3DTwentySix */
878 static const Direction BehindSouth        = NeighborCode3D::BehindSouth;          /**<  Export NeighborCode3D::BehindSouth to namespace Neighborhood3DTwentySix */
879 static const Direction BehindSouthEast    = NeighborCode3D::BehindSouthEast;      /**<  Export NeighborCode3D::BehindSouthEast to namespace Neighborhood3DTwentySix */
880 
881 static const Direction DirectionCount     = NeighborCode3D::DirectionCount;       /**<  Export NeighborCode3D::DirectionCount to namespace Neighborhood3DTwentySix */
882 
883 template <int DUMMY>
884 unsigned int NeighborCode3D::StaticData<DUMMY>::b[] = {
885                 1 <<  InFrontNorthWest,
886                 1 <<  InFrontNorth,
887                 1 <<  InFrontNorthEast,
888                 1 <<  InFrontWest,
889                 1 <<  InFront,
890                 1 <<  InFrontEast,
891                 1 <<  InFrontSouthWest,
892                 1 <<  InFrontSouth,
893                 1 <<  InFrontSouthEast,
894 
895                 1 <<  NorthWest,
896                 1 <<  North,
897                 1 <<  NorthEast,
898                 1 <<  West,
899                 1 <<  East,
900                 1 <<  SouthWest,
901                 1 <<  South,
902                 1 <<  SouthEast,
903 
904                 1 <<  BehindNorthWest,
905                 1 <<  BehindNorth,
906                 1 <<  BehindNorthEast,
907                 1 <<  BehindWest,
908                 1 <<  Behind,
909                 1 <<  BehindEast,
910                 1 <<  BehindSouthWest,
911                 1 <<  BehindSouth,
912                 1 <<  BehindSouthEast
913             };
914 
915 template <int DUMMY>
916 unsigned int NeighborCode3D::StaticData<DUMMY>::c[] = {
917                                     26, 17, 17,  0, 17, 11, 11,  0, 17, 11,
918                                     11,  0,  0,  0,  0,  0, 17, 11, 11,  0,
919                                     11,  7,  7,  0, 11,  7,  7,  0,  0,  0,
920                                      0,  0, 17, 11, 11,  0, 11,  7,  7,  0,
921                                     11,  7,  7};
922 
923 template <int DUMMY>
924 Direction NeighborCode3D::StaticData<DUMMY>::bd[43][26] = {
925 //0 - NotAtBorder
926 {    InFrontNorthWest,   InFrontNorth,   InFrontNorthEast,
927     InFrontWest,        InFront,        InFrontEast,
928     InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,
929 
930     NorthWest, North, NorthEast,
931     West,             East,
932     SouthWest, South, SouthEast,
933 
934     BehindNorthWest, BehindNorth, BehindNorthEast,
935     BehindWest,      Behind,      BehindEast,
936     BehindSouthWest, BehindSouth, BehindSouthEast},
937 //1 - AtRightBorder
938 {   InFrontNorthWest, InFrontNorth, /*InFrontNorthEast,*/
939     InFrontWest,      InFront,      /*InFrontEast,*/
940     InFrontSouthWest, InFrontSouth, /*InFrontSouthEast,*/
941 
942     NorthWest, North, /*NorthEast,*/
943     West,             /*East,*/
944     SouthWest, South, /*SouthEast,*/
945 
946     BehindNorthWest, BehindNorth, /*BehindNorthEast,*/
947     BehindWest,      Behind,      /*BehindEast,*/
948     BehindSouthWest, BehindSouth, /*BehindSouthEast,*/
949     Error, Error, Error, Error, Error, Error, Error, Error, Error},
950 //2 - AtLeftBorder
951 {   /*InFrontNorthWest,*/   InFrontNorth, InFrontNorthEast,
952     /*InFrontWest,*/       InFront,      InFrontEast,
953     /*InFrontSouthWest,*/   InFrontSouth, InFrontSouthEast,
954 
955     /*NorthWest,*/ North, NorthEast,
956     /*West,*/            East,
957     /*SouthWest,*/ South, SouthEast,
958 
959     /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
960     /*BehindWest,*/     Behind,      BehindEast,
961     /*BehindSouthWest,*/ BehindSouth, BehindSouthEast,
962     Error, Error, Error, Error, Error, Error, Error, Error, Error},
963 //3 - Nothin'
964 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
965     Error, Error, Error, Error,        Error, Error, Error, Error,
966     Error, Error, Error, Error, Error, Error, Error, Error, Error},
967 //4 - AtTopBorder
968 {   /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,*/
969     InFrontWest,        InFront,      InFrontEast,
970     InFrontSouthWest, InFrontSouth,   InFrontSouthEast,
971 
972     /*NorthWest, North, NorthEast,*/
973     West,             East,
974     SouthWest, South, SouthEast,
975 
976     /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
977     BehindWest,                 Behind,                 BehindEast,
978     BehindSouthWest, BehindSouth, BehindSouthEast,
979     Error, Error, Error, Error, Error, Error, Error, Error, Error},
980 //5 - AtTopRightBorder
981 {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
982     InFrontWest,        InFront,        /*InFrontEast,*/
983     InFrontSouthWest, InFrontSouth,     /*InFrontSouthEast,*/
984 
985     /*NorthWest, North, NorthEast,*/
986     West,             /*East,*/
987     SouthWest, South, /*SouthEast,*/
988 
989     /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
990     BehindWest,        Behind,      /*BehindEast,*/
991     BehindSouthWest, BehindSouth,   /*BehindSouthEast,*/
992     Error, Error, Error, Error, Error, Error, Error, Error, Error,
993     Error, Error, Error, Error, Error, Error},
994 //6 - AtTopLeftBorder
995 {   /*InFrontNorthWest,     InFrontNorth,   InFrontNorthEast,*/
996     /*InFrontWest,*/        InFront,        InFrontEast,
997     /*InFrontSouthWest,*/   InFrontSouth,   InFrontSouthEast,
998 
999     /*NorthWest,    North,  NorthEast,*/
1000     /*West,*/               East,
1001     /*SouthWest,*/  South,  SouthEast,
1002 
1003     /*BehindNorthWest,      BehindNorth, BehindNorthEast,*/
1004     /*BehindWest, */        Behind,      BehindEast,
1005     /*BehindSouthWest,*/    BehindSouth, BehindSouthEast,
1006     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1007     Error, Error, Error, Error, Error, Error},
1008 //7 - Nothin'
1009 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1010     Error, Error, Error, Error, Error, Error, Error, Error,
1011     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1012 //8 - AtBottomBorder
1013 {   InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
1014     InFrontWest,      InFront,         InFrontEast,
1015     /*InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
1016 
1017     NorthWest,      North,  NorthEast,
1018     West,                   East,
1019     /*SouthWest,    South,  SouthEast,*/
1020 
1021     BehindNorthWest,    BehindNorth, BehindNorthEast,
1022     BehindWest,         Behind,      BehindEast,
1023     /*BehindSouthWest,  BehindSouth, BehindSouthEast*/
1024     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1025 //9 - AtBottomRightBorder
1026 {   InFrontNorthWest, InFrontNorth,    /*InFrontNorthEast,*/
1027     InFrontWest,      InFront,         /*InFrontEast,*/
1028     /*InFrontSouthWest, InFrontSouth,  InFrontSouthEast,*/
1029 
1030     NorthWest, North,   /*NorthEast,*/
1031     West,               /*East,*/
1032     /*SouthWest, South, SouthEast,*/
1033 
1034     BehindNorthWest, BehindNorth,   /*BehindNorthEast,*/
1035     BehindWest,      Behind,        /*BehindEast,*/
1036     /*BehindSouthWest, BehindSouth, BehindSouthEast*/
1037     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1038     Error, Error, Error, Error, Error, Error},
1039 //10 - AtBottomLeftBorder
1040 {   /*InFrontNorthWest,*/   InFrontNorth,   InFrontNorthEast,
1041     /*InFrontWest,*/        InFront,        InFrontEast,
1042     /*InFrontSouthWest,     InFrontSouth,   InFrontSouthEast,*/
1043 
1044     /*NorthWest,*/  North,  NorthEast,
1045     /*West,*/               East,
1046     /*SouthWest,    South,  SouthEast,*/
1047 
1048     /*BehindNorthWest,*/ BehindNorth,   BehindNorthEast,
1049     /*BehindWest,*/      Behind,        BehindEast,
1050     /*BehindSouthWest, BehindSouth,     BehindSouthEast*/
1051     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1052     Error, Error, Error, Error, Error, Error},
1053 //11 - Nothin'
1054 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1055     Error, Error, Error, Error, Error, Error, Error, Error,
1056     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1057 //12 - Nothin'
1058 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1059     Error, Error, Error, Error, Error, Error, Error, Error,
1060     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1061 //13 - Nothin'
1062 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1063     Error, Error, Error, Error, Error, Error, Error, Error,
1064     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1065 //14 - Nothin'
1066 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1067     Error, Error, Error, Error, Error, Error, Error, Error,
1068     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1069 //15 - Nothin'
1070 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1071     Error, Error, Error, Error, Error, Error, Error, Error,
1072     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1073 //16 - AtFrontBorder
1074 {   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
1075     InFrontWest,        InFront,         InFrontEast,
1076     InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
1077 
1078     NorthWest, North, NorthEast,
1079     West,             East,
1080     SouthWest, South, SouthEast,
1081 
1082     BehindNorthWest, BehindNorth, BehindNorthEast,
1083     BehindWest,      Behind,      BehindEast,
1084     BehindSouthWest, BehindSouth, BehindSouthEast,
1085     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1086 //17 - AtFrontRightBorder
1087 {   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
1088     InFrontWest,              InFront,                 InFrontEast,
1089     InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
1090 
1091     NorthWest, North, /*NorthEast,*/
1092     West,             /*East,*/
1093     SouthWest, South, /*SouthEast,*/
1094 
1095     BehindNorthWest, BehindNorth, /*BehindNorthEast,*/
1096     BehindWest,      Behind,      /*BehindEast,*/
1097     BehindSouthWest, BehindSouth, /*BehindSouthEast,*/
1098     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1099     Error, Error, Error, Error, Error, Error},
1100 //18 - AtFrontLeftBorder
1101 {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
1102     InFrontWest,        InFront,        InFrontEast,
1103     InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
1104 
1105     /*NorthWest,*/ North, NorthEast,
1106     /*West,*/             East,
1107     /*SouthWest,*/ South, SouthEast,
1108 
1109     /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
1110     /*BehindWest,*/      Behind,      BehindEast,
1111     /*BehindSouthWest,*/ BehindSouth, BehindSouthEast,
1112     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1113     Error, Error, Error, Error, Error, Error},
1114 //19 - Nothin'
1115 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1116     Error, Error, Error, Error, Error, Error, Error, Error,
1117     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1118 //20 - AtTopFrontBorder
1119 {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
1120     InFrontWest,        InFront,        InFrontEast,
1121     InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
1122 
1123     /*NorthWest,    North,  NorthEast,*/
1124     West,                   East,
1125     SouthWest,      South,  SouthEast,
1126 
1127     /*BehindNorthWest,  BehindNorth,    BehindNorthEast,*/
1128     BehindWest,         Behind,         BehindEast,
1129     BehindSouthWest,    BehindSouth,    BehindSouthEast,
1130     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1131     Error, Error, Error, Error, Error, Error},
1132 //21 - AtTopRightFrontBorder
1133 {   /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
1134     InFrontWest,        InFront,       InFrontEast,
1135     InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
1136 
1137     /*NorthWest, North, NorthEast,*/
1138     West,               /*East,*/
1139     SouthWest,   South, /*SouthEast,*/
1140 
1141     /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
1142     BehindWest,        Behind,      /*BehindEast,*/
1143     BehindSouthWest, BehindSouth,   /*BehindSouthEast,*/
1144     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1145     Error, Error, Error, Error, Error, Error,
1146     Error, Error, Error, Error},
1147 //22 - AtTopLeftFrontBorder
1148 {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
1149     InFrontWest,        InFront,        InFrontEast,
1150     InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
1151 
1152     /*NorthWest,    North, NorthEast,*/
1153     /*West,*/              East,
1154     /*SouthWest,*/  South, SouthEast,
1155 
1156     /*BehindNorthWest,      BehindNorth, BehindNorthEast,*/
1157     /*BehindWest,*/         Behind,      BehindEast,
1158     /*BehindSouthWest,*/    BehindSouth, BehindSouthEast,
1159     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1160     Error, Error, Error, Error, Error, Error,
1161     Error, Error, Error, Error},
1162 //23 - Nothin'
1163 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1164     Error, Error, Error, Error, Error, Error, Error, Error,
1165     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1166 //24 - AtBottomFrontBorder
1167 {   /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,
1168     InFrontWest,        InFront,      InFrontEast,
1169     InFrontSouthWest,   InFrontSouth, InFrontSouthEast,*/
1170 
1171     NorthWest,      North, NorthEast,
1172     West,                  East,
1173     /*SouthWest,    South, SouthEast,*/
1174 
1175     BehindNorthWest,    BehindNorth, BehindNorthEast,
1176     BehindWest,         Behind,      BehindEast,
1177     /*BehindSouthWest,  BehindSouth, BehindSouthEast*/
1178     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1179     Error, Error, Error, Error, Error, Error},
1180 //25 - AtBottomRightFrontBorder
1181 {   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
1182     InFrontWest,        InFront,         InFrontEast,
1183     InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
1184 
1185     NorthWest,      North,  /*NorthEast,*/
1186     West,                   /* East,*/
1187     /*SouthWest,    South,  SouthEast,*/
1188 
1189     BehindNorthWest,    BehindNorth, /*BehindNorthEast,*/
1190     BehindWest,         Behind,      /*BehindEast,*/
1191     /*BehindSouthWest,  BehindSouth, BehindSouthEast*/
1192     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1193     Error, Error, Error, Error, Error, Error,
1194     Error, Error, Error, Error},
1195 //26 - AtBottomLeftFrontBorder
1196 { /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,
1197     InFrontWest,      InFront,      InFrontEast,
1198     InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
1199 
1200     /*NorthWest,*/ North, NorthEast,
1201     /*West,*/             East,
1202     /*SouthWest,   South, SouthEast,*/
1203 
1204     /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
1205     /*BehindWest,*/      Behind,      BehindEast,
1206     /*BehindSouthWest,   BehindSouth, BehindSouthEast*/
1207     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1208     Error, Error, Error, Error, Error, Error,
1209     Error, Error, Error, Error},
1210 //27 - Nothin'
1211 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1212     Error, Error, Error, Error, Error, Error, Error, Error,
1213     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1214 //28 - Nothin'
1215 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1216     Error, Error, Error, Error, Error, Error, Error, Error,
1217     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1218 //29 - Nothin'
1219 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1220     Error, Error, Error, Error, Error, Error, Error, Error,
1221     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1222 //30 - Nothin'
1223 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1224     Error, Error, Error, Error, Error, Error, Error, Error,
1225     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1226 //31 - Nothin'
1227 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1228     Error, Error, Error, Error, Error, Error, Error, Error,
1229     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1230 //32 - AtRearBorder
1231 {   InFrontNorthWest, InFrontNorth, InFrontNorthEast,
1232     InFrontWest,      InFront,      InFrontEast,
1233     InFrontSouthWest, InFrontSouth, InFrontSouthEast,
1234 
1235     NorthWest, North, NorthEast,
1236     West,             East,
1237     SouthWest, South, SouthEast,
1238 
1239     /*BehindNorthWest, BehindNorth, BehindNorthEast,
1240     BehindWest,        Behind,      BehindEast,
1241     BehindSouthWest,   BehindSouth, BehindSouthEast,*/
1242     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1243 //33 - AtRearRightBorder
1244 {   InFrontNorthWest, InFrontNorth, /*InFrontNorthEast,*/
1245     InFrontWest,      InFront,      /*InFrontEast,*/
1246     InFrontSouthWest, InFrontSouth, /*InFrontSouthEast,*/
1247 
1248     NorthWest, North, /*NorthEast,*/
1249     West,             /*East,*/
1250     SouthWest, South, /*SouthEast,*/
1251 
1252     /*BehindNorthWest, BehindNorth, BehindNorthEast,
1253     BehindWest,        Behind,      BehindEast,
1254     BehindSouthWest,   BehindSouth, BehindSouthEast,*/
1255     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1256     Error, Error, Error, Error, Error, Error},
1257 //34 - AtRearLeftBorder
1258 {   /*InFrontNorthWest,*/ InFrontNorth, InFrontNorthEast,
1259     /*InFrontWest,*/      InFront,      InFrontEast,
1260     /*InFrontSouthWest,*/ InFrontSouth, InFrontSouthEast,
1261 
1262     /*NorthWest,*/ North, NorthEast,
1263     /*West,*/             East,
1264     /*SouthWest,*/ South, SouthEast,
1265 
1266     /*BehindNorthWest, BehindNorth,   BehindNorthEast,
1267     BehindWest,        Behind,        BehindEast,
1268     BehindSouthWest,   BehindSouth,   BehindSouthEast,*/
1269     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1270     Error, Error, Error, Error, Error, Error},
1271 //35 - Nothin'
1272 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1273     Error, Error, Error, Error, Error, Error, Error, Error,
1274     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1275 //36 - AtTopRearBorder
1276 {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
1277     InFrontWest,        InFront,        InFrontEast,
1278     InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,
1279 
1280     /*NorthWest,    North, NorthEast,*/
1281     West,                  East,
1282     SouthWest,      South, SouthEast,
1283 
1284     /*BehindNorthWest, BehindNorth,   BehindNorthEast,
1285     BehindWest,        Behind,        BehindEast,
1286     BehindSouthWest,   BehindSouth,   BehindSouthEast,*/
1287     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1288     Error, Error, Error, Error, Error, Error},
1289 //37 - AtTopRightRearBorder
1290 {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
1291     InFrontWest,        InFront,        /*InFrontEast,*/
1292     InFrontSouthWest,   InFrontSouth,   /*InFrontSouthEast,*/
1293 
1294     /*NorthWest, North, NorthEast,*/
1295     West,               /*East,*/
1296     SouthWest,   South, /*SouthEast,*/
1297 
1298     /*BehindNorthWest,  BehindNorth, BehindNorthEast,
1299     BehindWest,         Behind,      BehindEast,
1300     BehindSouthWest,    BehindSouth, BehindSouthEast,*/
1301     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1302     Error, Error, Error, Error, Error, Error,
1303     Error, Error, Error, Error},
1304 //38 - AtTopLeftRearBorder
1305 {   /*InFrontNorthWest,     InFrontNorth,    InFrontNorthEast,*/
1306     /*InFrontWest,*/        InFront,         InFrontEast,
1307     /*InFrontSouthWest,*/   InFrontSouth,   InFrontSouthEast,
1308 
1309     /*NorthWest,    North,  NorthEast,*/
1310     /*West,*/               East,
1311     /*SouthWest,*/  South,  SouthEast,
1312 
1313     /*BehindNorthWest,  BehindNorth,    BehindNorthEast,
1314     BehindWest,         Behind,         BehindEast,
1315     BehindSouthWest,    BehindSouth,    BehindSouthEast,*/
1316     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1317     Error, Error, Error, Error, Error, Error,
1318     Error, Error, Error, Error},
1319 //39 - Nothin'
1320 {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
1321     Error, Error, Error, Error, Error, Error, Error, Error,
1322     Error, Error, Error, Error, Error, Error, Error, Error, Error},
1323 //40 - AtBottomRearBorder
1324 {   InFrontNorthWest,   InFrontNorth,   InFrontNorthEast,
1325     InFrontWest,        InFront,        InFrontEast,
1326     /*InFrontSouthWest, InFrontSouth,   InFrontSouthEast,*/
1327 
1328     NorthWest,      North, NorthEast,
1329     West,                  East,
1330     /*SouthWest,    South, SouthEast,*/
1331 
1332     /*BehindNorthWest,  BehindNorth, BehindNorthEast,
1333     BehindWest,         Behind,      BehindEast,
1334     BehindSouthWest,    BehindSouth, BehindSouthEast,*/
1335     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1336     Error, Error, Error, Error, Error, Error},
1337 //41 - AtBottomRightRearBorder
1338 {   InFrontNorthWest,   InFrontNorth, /*InFrontNorthEast,*/
1339     InFrontWest,        InFront,      /*InFrontEast,*/
1340     /*InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
1341 
1342     NorthWest,   North, /*NorthEast,*/
1343     West,               /*East,*/
1344     /*SouthWest, South, SouthEast,*/
1345 
1346     /*BehindNorthWest, BehindNorth, BehindNorthEast,
1347     BehindWest,        Behind,      BehindEast,
1348     BehindSouthWest,   BehindSouth, BehindSouthEast,*/
1349     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1350     Error, Error, Error, Error, Error, Error,
1351     Error, Error, Error, Error},
1352 //42 - AtBottomLeftRearBorder
1353 {   /*InFrontNorthWest,*/   InFrontNorth,   InFrontNorthEast,
1354     /*InFrontWest,*/        InFront,        InFrontEast,
1355     /*InFrontSouthWest,     InFrontSouth,   InFrontSouthEast,*/
1356 
1357     /*NorthWest,*/  North,  NorthEast,
1358     /*West,*/               East,
1359     /*SouthWest,    South,  SouthEast,*/
1360 
1361     /*BehindNorthWest,  BehindNorth, BehindNorthEast,
1362     BehindWest,         Behind,      BehindEast,
1363     BehindSouthWest,    BehindSouth, BehindSouthEast,*/
1364     Error, Error, Error, Error, Error, Error, Error, Error, Error,
1365     Error, Error, Error, Error, Error, Error,
1366     Error, Error, Error, Error}
1367 };
1368 
1369 template <int DUMMY>
1370 Direction NeighborCode3D::StaticData<DUMMY>::bc[43][13] = {
1371 //0 - NotAtBorder -----> should never be used
1372     { InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
1373       InFrontWest,      InFront,         InFrontEast,
1374       InFrontSouthWest, InFrontSouth,    InFrontSouthEast,
1375 
1376       NorthWest,        North,           NorthEast,
1377       West},
1378 //1 - AtRightBorder
1379     { InFrontNorthWest, InFrontNorth,    /* InFrontNorthEast, */
1380       InFrontWest,      InFront,         /* InFrontEast, */
1381       InFrontSouthWest, InFrontSouth,    /* InFrontSouthEast, */
1382 
1383       NorthWest,        North,           /* NorthEast, */
1384       West,
1385       Error, Error, Error, Error},
1386 //2 - AtLeftBorder
1387     { /*InFrontNorthWest,*/ InFrontNorth,InFrontNorthEast,
1388       /*InFrontWest,*/  InFront,         InFrontEast,
1389       /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
1390 
1391       /*NorthWest,*/    North,           NorthEast,
1392       /*West*/
1393       Error, Error, Error, Error, Error},
1394 //3 - Nothin'
1395     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1396 //4 - AtTopBorder
1397     { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,*/
1398       InFrontWest,       InFront,        InFrontEast,
1399       InFrontSouthWest,  InFrontSouth,   InFrontSouthEast,
1400 
1401       /*NorthWest,       North,          NorthEast,*/
1402       West,
1403       Error, Error, Error, Error, Error, Error},
1404 //5 - AtTopRightBorder
1405     { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,*/
1406       InFrontWest,       InFront,        /*InFrontEast,*/
1407       InFrontSouthWest,  InFrontSouth,   /*InFrontSouthEast,*/
1408 
1409       /*NorthWest, North, NorthEast,*/
1410       West,
1411       Error, Error, Error, Error, Error, Error, Error, Error},
1412 //6 - AtTopLeftBorder
1413     { /*InFrontNorthWest,InFrontNorth,    InFrontNorthEast,*/
1414       /*InFrontWest,*/   InFront,         InFrontEast,
1415       /*InFrontSouthWest,*/InFrontSouth,  InFrontSouthEast,
1416 
1417       /*NorthWest,       North,           NorthEast,*/
1418       /*West,*/
1419       Error, Error, Error, Error, Error, Error, Error, Error, Error},
1420 //7 - Nothin'
1421     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1422 //8 - AtBottomBorder
1423     { InFrontNorthWest,  InFrontNorth,    InFrontNorthEast,
1424       InFrontWest,       InFront,         InFrontEast,
1425       /* InFrontSouthWest,  InFrontSouth,    InFrontSouthEast, */
1426 
1427       NorthWest,         North,           NorthEast,
1428       West,
1429       Error, Error, Error},
1430 //9 - AtBottomRightBorder
1431     { InFrontNorthWest, InFrontNorth,    /* InFrontNorthEast, */
1432       InFrontWest,      InFront,         /* InFrontEast, */
1433       /* InFrontSouthWest, InFrontSouth,    InFrontSouthEast, */
1434 
1435       NorthWest,        North,           /* NorthEast, */
1436       West,
1437       Error, Error, Error,Error, Error, Error},
1438 //10 - AtBottomLeftBorder
1439     { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
1440       /*InFrontWest,*/  InFront,         InFrontEast,
1441       /*InFrontSouthWest, InFrontSouth, InFrontSouthEast, */
1442 
1443       /*NorthWest,*/    North,           NorthEast,
1444       /*West*/
1445       Error, Error, Error, Error, Error, Error, Error},
1446 //11 - Nothin'
1447     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1448 //12 - Nothin'
1449     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1450 //13 - Nothin'
1451     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1452 //14 - Nothin'
1453     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1454 //15 - Nothin'
1455     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1456 //16 - AtFrontBorder
1457     { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
1458       InFrontWest,      InFront,         InFrontEast,
1459       InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
1460 
1461       NorthWest,        North,           NorthEast,
1462       West,
1463       Error, Error, Error, Error, Error, Error, Error, Error, Error},
1464 //17 - AtFrontRightBorder
1465     { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
1466       InFrontWest,      InFront,         InFrontEast,
1467       InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
1468 
1469       NorthWest,        North,           /*NorthEast,*/
1470       West,
1471       Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1472 //18 - AtFrontLeftBorder
1473     { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
1474       InFrontWest,      InFront,         InFrontEast,
1475       InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
1476 
1477       /*NorthWest,*/    North,           NorthEast,
1478       /*West,*/
1479       Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1480 //19 - Nothin'
1481     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1482 //20 - AtTopFrontBorder
1483     { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
1484       InFrontWest,      InFront,         InFrontEast,
1485       InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
1486 
1487       /*NorthWest, North, NorthEast,*/
1488       West,
1489       Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1490 //21 - AtTopRightFrontBorder
1491     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
1492       InFrontWest,        InFront,       InFrontEast,
1493       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
1494 
1495       /*NorthWest,        North,         NorthEast,*/
1496       West,
1497       Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1498 //22 - AtTopLeftFrontBorder
1499     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1500 //23 - Nothin
1501     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1502 //24 - AtBottomFrontBorder
1503     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
1504       InFrontWest,        InFront,       InFrontEast,
1505       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
1506 
1507       NorthWest,          North,         NorthEast,
1508       West,
1509       Error, Error, Error, Error, Error, Error, Error, Error, Error},
1510 //25 - AtBottomRightFrontBorder
1511     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
1512       InFrontWest,        InFront,       InFrontEast,
1513       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
1514 
1515       NorthWest,          North,         /*NorthEast,*/
1516       West,
1517       Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1518 //26 - AtBottomLeftFrontBorder
1519     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
1520       InFrontWest,        InFront,       InFrontEast,
1521       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
1522 
1523       /*NorthWest,*/      North,         NorthEast,
1524       /* West, */
1525       Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1526 //27 - Nothin
1527     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1528 //28 - Nothin
1529     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1530 //29 - Nothin
1531     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1532 //30 - Nothin
1533     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1534 //31 - Nothin
1535     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1536 //32 - AtRearBorder
1537     { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
1538       InFrontWest,        InFront,       InFrontEast,
1539       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
1540 
1541       NorthWest,          North,         NorthEast,
1542       West},
1543 //33 - AtRearRightBorder
1544     { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
1545       InFrontWest,        InFront,       InFrontEast,
1546       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
1547 
1548       NorthWest,          North,         NorthEast,
1549       West},
1550 //34 - AtRearLeftBorder
1551     { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
1552       /*InFrontWest,*/    InFront,       InFrontEast,
1553       /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
1554 
1555       /*NorthWest,*/      North,         NorthEast,
1556       /*West*/
1557       Error, Error, Error, Error, Error},
1558 //35 - Nothin
1559     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1560 //36 - AtTopRearBorder
1561     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
1562       InFrontWest,        InFront,       InFrontEast,
1563       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
1564 
1565       /*NorthWest,        North,         NorthEast,*/
1566       West,
1567       Error, Error, Error, Error, Error, Error},
1568 //37 - AtTopRightRearBorder
1569     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
1570       InFrontWest,        InFront,       /*InFrontEast,*/
1571       InFrontSouthWest,   InFrontSouth,  /*InFrontSouthEast,*/
1572 
1573       /*NorthWest,        North,         NorthEast,*/
1574       West,
1575       Error, Error, Error, Error, Error, Error, Error, Error},
1576 //38 - AtTopLeftRearBorder
1577     { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
1578       /*InFrontWest,*/    InFront,       InFrontEast,
1579       /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
1580 
1581       /*NorthWest, North, NorthEast,*/
1582       /*West,*/
1583       Error, Error, Error, Error, Error, Error, Error, Error, Error},
1584 //39 - Nothin
1585     { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},
1586 //40 - AtBottomRearBorder
1587     { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
1588       InFrontWest,        InFront,       InFrontEast,
1589       InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
1590 
1591       NorthWest,          North,         NorthEast,
1592       West},
1593 //41 - AtBottomRightRearBorder
1594     { InFrontNorthWest,  InFrontNorth,   InFrontNorthEast,
1595       InFrontWest,       InFront,        InFrontEast,
1596       InFrontSouthWest,  InFrontSouth,   InFrontSouthEast,
1597 
1598       NorthWest,         North,          NorthEast,
1599       West},
1600 //42 - AtBottomLeftRearBorder
1601     { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
1602       /*InFrontWest,*/   InFront,        InFrontEast,
1603       /*InFrontSouthWest,InFrontSouth,   InFrontSouthEast,*/
1604 
1605       /*NorthWest,*/     North,          NorthEast,
1606       /*West*/
1607       Error, Error, Error, Error, Error, Error, Error}
1608 };
1609 
1610 template <int DUMMY>
1611 Diff3D NeighborCode3D::StaticData<DUMMY>::d[] = {
1612                                 Diff3D( -1, -1, -1),  //InFrontNorthWest
1613                                 Diff3D(  0, -1, -1),  //InFrontNorth
1614                                 Diff3D(  1, -1, -1),  //InFrontNorthEast
1615                                 Diff3D( -1,  0, -1),  //InFrontWest
1616                                 Diff3D(  0,  0, -1),  //InFront
1617                                 Diff3D(  1,  0, -1),  //InFrontEast
1618                                 Diff3D( -1,  1, -1),  //InFrontSouthWest
1619                                 Diff3D(  0,  1, -1),  //InFrontSouth
1620                                 Diff3D(  1,  1, -1),  //InFrontSouthEast
1621 
1622                                 Diff3D( -1, -1,  0),  //NorthWest
1623                                 Diff3D(  0, -1,  0),  //North
1624                                 Diff3D(  1, -1,  0),  //NorthEast
1625                                 Diff3D( -1,  0,  0),  //West
1626                                 Diff3D(  1,  0,  0),  //East
1627                                 Diff3D( -1,  1,  0),  //SouthWest
1628                                 Diff3D(  0,  1,  0),  //South
1629                                 Diff3D(  1,  1,  0),  //SouthEast
1630 
1631                                 Diff3D( -1, -1,  1),  //BehindNorthWest
1632                                 Diff3D(  0, -1,  1),  //BehindNorth
1633                                 Diff3D(  1, -1,  1),  //BehindNorthEast
1634                                 Diff3D( -1,  0,  1),  //BehindWest
1635                                 Diff3D(  0,  0,  1),  //Behind
1636                                 Diff3D(  1,  0,  1),  //BehindEast
1637                                 Diff3D( -1,  1,  1),  //BehindSouthWest
1638                                 Diff3D(  0,  1,  1),  //BehindSouth
1639                                 Diff3D(  1,  1,  1),  //BehindSouthEast
1640                             };
1641 
1642 }//namespace Neighborhood3DTwentySix
1643 
1644 /** Export \ref vigra::Neighborhood3DTwentySix::NeighborCode3D into the scope of namespace vigra.
1645  */
1646 typedef Neighborhood3DTwentySix::NeighborCode3D NeighborCode3DTwentySix;
1647 
1648 //@}
1649 
1650 } // namespace vigra
1651 
1652 #endif /* VIGRA_VOXELNEIGHBORHOOD_HXX */
1653