DGtal  0.9.2
KhalimskyPreSpaceND.ih
1 /**
2  * This program is free software: you can redistribute it and/or modify
3  * it under the terms of the GNU Lesser General Public License as
4  * published by the Free Software Foundation, either version 3 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  **/
16 
17 /**
18  * @file KhalimskyPreSpaceND.ih
19  * @author Roland Denis ( \c roland.denis@univ-smb.fr )
20  * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
21  *
22  * @date 2016/02/18
23  *
24  * Implementation of inline methods defined in KhalimskyPreSpaceND.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <DGtal/kernel/NumberTraits.h>
32 //////////////////////////////////////////////////////////////////////////////
33 
34 
35 ///////////////////////////////////////////////////////////////////////////////
36 // IMPLEMENTATION of inline methods.
37 ///////////////////////////////////////////////////////////////////////////////
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 // KhalimskyPreCell
41 ///////////////////////////////////////////////////////////////////////////////
42 //-----------------------------------------------------------------------------
43 template < DGtal::Dimension dim, typename TInteger >
44 inline
45 DGtal::KhalimskyPreCell< dim, TInteger >::
46 KhalimskyPreCell( Integer /* dummy */ )
47 {
48  coordinates.reset();
49 }
50 //-----------------------------------------------------------------------------
51 template < DGtal::Dimension dim, typename TInteger >
52 inline
53 DGtal::KhalimskyPreCell< dim, TInteger >::
54 KhalimskyPreCell( Point const& p )
55  : coordinates( p )
56 {
57 }
58 //-----------------------------------------------------------------------------
59 template < DGtal::Dimension dim, typename TInteger >
60 inline
61 DGtal::KhalimskyPreCell< dim, TInteger > const &
62 DGtal::KhalimskyPreCell< dim, TInteger >::
63 preCell () const
64 {
65  return *this;
66 }
67 //-----------------------------------------------------------------------------
68 template < DGtal::Dimension dim, typename TInteger >
69 inline
70 bool
71 DGtal::KhalimskyPreCell< dim, TInteger >::
72 operator==( const KhalimskyPreCell & other ) const
73 {
74  return coordinates == other.coordinates;
75 }
76 //-----------------------------------------------------------------------------
77 template < DGtal::Dimension dim, typename TInteger >
78 inline
79 bool
80 DGtal::KhalimskyPreCell< dim, TInteger >::
81 operator!=( const KhalimskyPreCell & other ) const
82 {
83  return coordinates != other.coordinates;
84 }
85 //-----------------------------------------------------------------------------
86 template < DGtal::Dimension dim, typename TInteger >
87 inline
88 bool
89 DGtal::KhalimskyPreCell< dim, TInteger >::
90 operator<( const KhalimskyPreCell & other ) const
91 {
92  return coordinates < other.coordinates;
93 }
94 //-----------------------------------------------------------------------------
95 template < DGtal::Dimension dim, typename TInteger >
96 inline
97 std::ostream &
98 DGtal::operator<<( std::ostream & out,
99  const KhalimskyPreCell< dim, TInteger > & object )
100 {
101  out << "(" << object.coordinates[ 0 ];
102  for ( DGtal::Dimension i = 1; i < dim; ++i )
103  out << "," << object.coordinates[ i ];
104  out << ")";
105  return out;
106 }
107 
108 //------------------------------------------------------------------------------
109 template < DGtal::Dimension dim, typename TInteger >
110 inline
111 std::string
112 DGtal::KhalimskyPreCell<dim, TInteger>::
113 className() const
114 {
115  return "KhalimskyPreCell";
116 }
117 
118 ///////////////////////////////////////////////////////////////////////////////
119 // SignedKhalimskyPreCell
120 ///////////////////////////////////////////////////////////////////////////////
121 //-----------------------------------------------------------------------------
122 template < DGtal::Dimension dim, typename TInteger >
123 inline
124 DGtal::SignedKhalimskyPreCell< dim, TInteger >::
125 SignedKhalimskyPreCell( Integer /* dummy */ )
126  : positive( true )
127 {
128  coordinates.reset();
129 }
130 //-----------------------------------------------------------------------------
131 template < DGtal::Dimension dim, typename TInteger >
132 inline
133 DGtal::SignedKhalimskyPreCell< dim, TInteger >::
134 SignedKhalimskyPreCell( Point const& p, bool aPositive )
135  : coordinates( p )
136  , positive( aPositive )
137 {
138 }
139 //-----------------------------------------------------------------------------
140 template < DGtal::Dimension dim, typename TInteger >
141 inline
142 DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
143 DGtal::SignedKhalimskyPreCell< dim, TInteger >::
144 preCell() const
145 {
146  return *this;
147 }
148 //-----------------------------------------------------------------------------
149 template < DGtal::Dimension dim, typename TInteger >
150 inline
151 bool
152 DGtal::SignedKhalimskyPreCell< dim, TInteger >::
153 operator==( const SignedKhalimskyPreCell & other ) const
154 {
155  return ( positive == other.positive )
156  && ( coordinates == other.coordinates );
157 }
158 //-----------------------------------------------------------------------------
159 template < DGtal::Dimension dim, typename TInteger >
160 inline
161 bool
162 DGtal::SignedKhalimskyPreCell< dim, TInteger >::
163 operator!=( const SignedKhalimskyPreCell & other ) const
164 {
165  return ( positive != other.positive )
166  || ( coordinates != other.coordinates );
167 }
168 //-----------------------------------------------------------------------------
169 template < DGtal::Dimension dim, typename TInteger >
170 inline
171 bool
172 DGtal::SignedKhalimskyPreCell< dim, TInteger >::
173 operator<( const SignedKhalimskyPreCell & other ) const
174 {
175  return ( positive < other.positive )
176  || ( ( positive == other.positive )
177  && ( coordinates < other.coordinates ) );
178 }
179 //-----------------------------------------------------------------------------
180 template < DGtal::Dimension dim,
181  typename TInteger >
182 inline
183 std::ostream &
184 DGtal::operator<<( std::ostream & out,
185  const SignedKhalimskyPreCell< dim, TInteger > & object )
186 {
187  out << "(" << object.coordinates[ 0 ];
188  for ( DGtal::Dimension i = 1; i < dim; ++i )
189  out << "," << object.coordinates[ i ];
190  out << "," << ( object.positive ? '+' : '-' );
191  out << ")";
192  return out;
193 }
194 
195 //------------------------------------------------------------------------------
196 template < DGtal::Dimension dim, typename TInteger >
197 inline
198 std::string
199 DGtal::SignedKhalimskyPreCell<dim, TInteger>::
200 className() const
201 {
202  return "SignedKhalimskyPreCell";
203 }
204 
205 ///////////////////////////////////////////////////////////////////////////////
206 // PreCellDirectionIterator
207 ///////////////////////////////////////////////////////////////////////////////
208 //-----------------------------------------------------------------------------
209 template < DGtal::Dimension dim, typename TInteger >
210 inline
211 DGtal::PreCellDirectionIterator< dim, TInteger >::
212 PreCellDirectionIterator( Cell cell, bool open )
213  : myDir( 0 ), myCell( cell ), myOpen( open )
214 {
215  find();
216 }
217 //-----------------------------------------------------------------------------
218 template < DGtal::Dimension dim, typename TInteger >
219 inline
220 DGtal::PreCellDirectionIterator< dim, TInteger >::
221 PreCellDirectionIterator( SCell scell, bool open )
222  : myDir( 0 ), myCell( scell.coordinates ), myOpen( open )
223 {
224  find();
225 }
226 //-----------------------------------------------------------------------------
227 template < DGtal::Dimension dim, typename TInteger >
228 inline
229 DGtal::Dimension
230 DGtal::PreCellDirectionIterator< dim, TInteger >::
231 operator*() const
232 {
233  return myDir;
234 }
235 //-----------------------------------------------------------------------------
236 template < DGtal::Dimension dim, typename TInteger >
237 inline
238 DGtal::PreCellDirectionIterator< dim, TInteger > &
239 DGtal::PreCellDirectionIterator< dim, TInteger >::
240 operator++()
241 {
242  ++myDir;
243  find();
244  return *this;
245 }
246 //-----------------------------------------------------------------------------
247 template < DGtal::Dimension dim, typename TInteger >
248 inline
249 bool
250 DGtal::PreCellDirectionIterator< dim, TInteger >::
251 operator!=( const Integer ) const
252 {
253  return myDir < dim;
254 }
255 //-----------------------------------------------------------------------------
256 template < DGtal::Dimension dim, typename TInteger >
257 inline
258 bool
259 DGtal::PreCellDirectionIterator< dim, TInteger >::
260 end() const
261 {
262  return myDir >= dim;
263 }
264 //-----------------------------------------------------------------------------
265 template < DGtal::Dimension dim, typename TInteger >
266 inline
267 bool
268 DGtal::PreCellDirectionIterator< dim, TInteger >::
269 operator!=( const PreCellDirectionIterator & other ) const
270 {
271  return myDir != other.myDir;
272 }
273 //-----------------------------------------------------------------------------
274 template < DGtal::Dimension dim, typename TInteger >
275 inline
276 bool
277 DGtal::PreCellDirectionIterator< dim, TInteger >::
278 operator==( const PreCellDirectionIterator & other ) const
279 {
280  return myDir == other.myDir;
281 }
282 //-----------------------------------------------------------------------------
283 template < DGtal::Dimension dim, typename TInteger >
284 inline
285 void
286 DGtal::PreCellDirectionIterator< dim, TInteger >::
287 find()
288 {
289  if ( myOpen ) // loop on open coordinates
290  while ( myDir != dim && NumberTraits<Integer>::even( myCell.coordinates[ myDir ] ) )
291  ++myDir;
292  else // myOpen is false, loop on closed coordinates
293  while ( myDir != dim && NumberTraits<Integer>::odd( myCell.coordinates[ myDir ] ) )
294  ++myDir;
295 }
296 
297 ///////////////////////////////////////////////////////////////////////////////
298 // KhalimskyPreSpaceND
299 ///////////////////////////////////////////////////////////////////////////////
300 ///////////////////////////////////////////////////////////////////////////////
301 template < DGtal::Dimension dim, typename TInteger>
302 inline
303 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
304 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
305 uCell( const Point & kp )
306 {
307  return Cell( kp );
308 }
309 //-----------------------------------------------------------------------------
310 template < DGtal::Dimension dim, typename TInteger>
311 inline
312 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
313 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
314 uCell( Point p, const Cell & c )
315 {
316  for ( DGtal::Dimension i = 0; i < dimension; ++i )
317  {
318  p[ i ] += p[ i ] + ( NumberTraits<Integer>::odd( c.coordinates[ i ] ) ? 1 : 0 );
319  }
320  return uCell( p );
321 }
322 //-----------------------------------------------------------------------------
323 template < DGtal::Dimension dim, typename TInteger>
324 inline
325 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
326 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
327 sCell( const Point & kp, Sign sign )
328 {
329  return SCell( kp, sign == POS );
330 }
331 //-----------------------------------------------------------------------------
332 template < DGtal::Dimension dim, typename TInteger>
333 inline
334 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
335 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
336 sCell( Point p, const SCell & c )
337 {
338  for ( DGtal::Dimension i = 0; i < DIM; ++i )
339  p[ i ] += p[ i ] + ( NumberTraits<Integer>::odd( c.coordinates[ i ] ) ? 1 : 0 );
340  return sCell( p, c.positive );
341 }
342 //-----------------------------------------------------------------------------
343 template < DGtal::Dimension dim, typename TInteger>
344 inline
345 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
346 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
347 uSpel( Point p )
348 {
349  for ( DGtal::Dimension i = 0; i < DIM; ++i )
350  p[ i ] += p[ i ] + 1;
351  return uCell( p );
352 }
353 //-----------------------------------------------------------------------------
354 template < DGtal::Dimension dim, typename TInteger>
355 inline
356 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
357 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
358 sSpel( Point p, Sign sign )
359 {
360  for ( DGtal::Dimension i = 0; i < DIM; ++i )
361  p[ i ] += p[ i ] + 1;
362  return sCell( p, sign );
363 }
364 //-----------------------------------------------------------------------------
365 template < DGtal::Dimension dim, typename TInteger>
366 inline
367 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
368 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
369 uPointel( Point p )
370 {
371  for ( DGtal::Dimension i = 0; i < DIM; ++i )
372  p[ i ] += p[ i ];
373  return uCell( p );
374 }
375 //-----------------------------------------------------------------------------
376 template < DGtal::Dimension dim, typename TInteger>
377 inline
378 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
379 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
380 sPointel( Point p, Sign sign )
381 {
382  for ( DGtal::Dimension i = 0; i < DIM; ++i )
383  p[ i ] += p[ i ];
384  return sCell( p, sign );
385 }
386 //-----------------------------------------------------------------------------
387 ///////////////////////////////////////////////////////////////////////////////
388 //-----------------------------------------------------------------------------
389 template < DGtal::Dimension dim, typename TInteger>
390 inline
391 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
392 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
393 uKCoord( const Cell & c, DGtal::Dimension k )
394 {
395  ASSERT( k < DIM );
396  return c.coordinates[ k ];
397 }
398 //-----------------------------------------------------------------------------
399 template < DGtal::Dimension dim, typename TInteger>
400 inline
401 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
402 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
403 uCoord( const Cell & c, DGtal::Dimension k )
404 {
405  ASSERT( k < DIM );
406  return c.coordinates[ k ] >> 1;
407 }
408 //-----------------------------------------------------------------------------
409 template < DGtal::Dimension dim, typename TInteger>
410 inline
411 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point const &
412 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
413 uKCoords( const Cell & c )
414 {
415  return c.coordinates;
416 }
417 //-----------------------------------------------------------------------------
418 template < DGtal::Dimension dim, typename TInteger>
419 inline
420 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point
421 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
422 uCoords( const Cell & c )
423 {
424  Point dp = uKCoords( c );
425  for ( DGtal::Dimension i = 0; i < DIM; ++i )
426  dp[ i ] >>= 1;
427  return dp;
428 }
429 //-----------------------------------------------------------------------------
430 template < DGtal::Dimension dim, typename TInteger>
431 inline
432 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
433 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
434 sKCoord( const SCell & c, DGtal::Dimension k )
435 {
436  ASSERT( k < DIM );
437  return c.coordinates[ k ];
438 }
439 //-----------------------------------------------------------------------------
440 template < DGtal::Dimension dim, typename TInteger>
441 inline
442 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Integer
443 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
444 sCoord( const SCell & c, DGtal::Dimension k )
445 {
446  ASSERT( k < DIM );
447  return c.coordinates[ k ] >> 1;
448 }
449 //-----------------------------------------------------------------------------
450 template < DGtal::Dimension dim, typename TInteger>
451 inline
452 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point const &
453 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
454 sKCoords( const SCell & c )
455 {
456  return c.coordinates;
457 }
458 //-----------------------------------------------------------------------------
459 template < DGtal::Dimension dim, typename TInteger>
460 inline
461 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Point
462 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
463 sCoords( const SCell & c )
464 {
465  Point dp = sKCoords( c );
466  for ( DGtal::Dimension i = 0; i < DIM; ++i )
467  dp[ i ] >>= 1;
468  return dp;
469 }
470 //-----------------------------------------------------------------------------
471 template < DGtal::Dimension dim, typename TInteger>
472 inline
473 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Sign
474 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
475 sSign( const SCell & c )
476 {
477  return c.positive ? POS : NEG;
478 }
479 //-----------------------------------------------------------------------------
480 template < DGtal::Dimension dim, typename TInteger>
481 inline
482 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
483 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
484 signs( const Cell & p, Sign s )
485 {
486  return sCell( p.coordinates, s );
487 }
488 //-----------------------------------------------------------------------------
489 template < DGtal::Dimension dim, typename TInteger>
490 inline
491 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
492 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
493 unsigns( const SCell & p )
494 {
495  return uCell( p.coordinates );
496 }
497 //-----------------------------------------------------------------------------
498 template < DGtal::Dimension dim, typename TInteger>
499 inline
500 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::SCell
501 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
502 sOpp( const SCell & p )
503 {
504  return sCell( p.coordinates, ! p.positive );
505 }
506 //-----------------------------------------------------------------------------
507 template < DGtal::Dimension dim, typename TInteger>
508 inline
509 void
510 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
511 uSetKCoord( Cell & c, DGtal::Dimension k, Integer i )
512 {
513  ASSERT( k < DIM );
514  c.coordinates[ k ] = i;
515 }
516 //-----------------------------------------------------------------------------
517 template < DGtal::Dimension dim, typename TInteger>
518 inline
519 void
520 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
521 sSetKCoord( SCell & c, DGtal::Dimension k, Integer i )
522 {
523  ASSERT( k < DIM );
524  c.coordinates[ k ] = i;
525 }
526 //-----------------------------------------------------------------------------
527 template < DGtal::Dimension dim, typename TInteger>
528 inline
529 void
530 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
531 uSetCoord( Cell & c, DGtal::Dimension k, Integer i )
532 {
533  ASSERT( k < DIM );
534  c.coordinates[ k ] = 2 * i + ( NumberTraits<Integer>::odd( c.coordinates[ k ] ) ? 1 : 0 );
535 }
536 //-----------------------------------------------------------------------------
537 template < DGtal::Dimension dim, typename TInteger>
538 inline
539 void
540 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
541 sSetCoord( SCell & c, DGtal::Dimension k, Integer i )
542 {
543  ASSERT( k < DIM );
544  c.coordinates[ k ] = 2 * i + ( NumberTraits<Integer>::odd( c.coordinates[ k ] ) ? 1 : 0 );
545 }
546 //-----------------------------------------------------------------------------
547 template < DGtal::Dimension dim, typename TInteger>
548 inline
549 void
550 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
551 uSetKCoords( Cell & c, const Point & kp )
552 {
553  c.coordinates = kp;
554 }
555 //-----------------------------------------------------------------------------
556 template < DGtal::Dimension dim, typename TInteger>
557 inline
558 void
559 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
560 sSetKCoords( SCell & c, const Point & kp )
561 {
562  c.coordinates = kp;
563 }
564 //-----------------------------------------------------------------------------
565 template < DGtal::Dimension dim, typename TInteger>
566 inline
567 void
568 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
569 uSetCoords( Cell & c, const Point & p )
570 {
571  for ( DGtal::Dimension k = 0; k < DIM; ++k )
572  uSetCoord( c, k, p[k] );
573 }
574 //-----------------------------------------------------------------------------
575 template < DGtal::Dimension dim, typename TInteger>
576 inline
577 void
578 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
579 sSetCoords( SCell & c, const Point & p )
580 {
581  for ( DGtal::Dimension k = 0; k < DIM; ++k )
582  sSetCoord( c, k, p[k] );
583 }
584 //-----------------------------------------------------------------------------
585 template < DGtal::Dimension dim, typename TInteger>
586 inline
587 void
588 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
589 sSetSign( SCell & c, Sign s )
590 {
591  c.positive = ( s == POS );
592 }
593 //-----------------------------------------------------------------------------
594 // ------------------------- Cell topology services -----------------------
595 //-----------------------------------------------------------------------------
596 template < DGtal::Dimension dim, typename TInteger>
597 inline
598 TInteger
599 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
600 uTopology( const Cell & p )
601 {
602  Integer i = NumberTraits<Integer>::ZERO;
603  Integer j = NumberTraits<Integer>::ONE;
604  for ( DGtal::Dimension k = 0; k < DIM; ++k )
605  {
606  if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
607  i |= j;
608  j *= 2;
609  }
610  return i;
611 }
612 //-----------------------------------------------------------------------------
613 template < DGtal::Dimension dim, typename TInteger>
614 inline
615 TInteger
616 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
617 sTopology( const SCell & p )
618 {
619  Integer i = NumberTraits<Integer>::ZERO;
620  Integer j = NumberTraits<Integer>::ONE;
621  for ( DGtal::Dimension k = 0; k < DIM; ++k )
622  {
623  if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
624  i |= j;
625  j *= 2;
626  }
627  return i;
628 }
629 //-----------------------------------------------------------------------------
630 template < DGtal::Dimension dim, typename TInteger>
631 inline
632 DGtal::Dimension
633 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
634 uDim( const Cell & p )
635 {
636  Integer i = NumberTraits<Integer>::ZERO;
637  for ( DGtal::Dimension k = 0; k < DIM; ++k )
638  if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
639  ++i;
640  return i;
641 }
642 //-----------------------------------------------------------------------------
643 template < DGtal::Dimension dim, typename TInteger>
644 inline
645 DGtal::Dimension
646 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
647 sDim( const SCell & p )
648 {
649  Integer i = NumberTraits<Integer>::ZERO;
650  for ( DGtal::Dimension k = 0; k < DIM; ++k )
651  if ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) )
652  ++i;
653  return i;
654 }
655 //-----------------------------------------------------------------------------
656 template < DGtal::Dimension dim, typename TInteger>
657 inline
658 bool
659 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
660 uIsSurfel( const Cell & b )
661 {
662  return uDim( b ) == ( DIM - 1 );
663 }
664 //-----------------------------------------------------------------------------
665 template < DGtal::Dimension dim, typename TInteger>
666 inline
667 bool
668 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
669 sIsSurfel( const SCell & b )
670 {
671  return sDim( b ) == ( DIM - 1 );
672 }
673 //-----------------------------------------------------------------------------
674 template < DGtal::Dimension dim, typename TInteger>
675 inline
676 bool
677 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
678 uIsOpen( const Cell & p, DGtal::Dimension k )
679 {
680  return NumberTraits<Integer>::odd( p.coordinates[ k ] );
681 }
682 //-----------------------------------------------------------------------------
683 template < DGtal::Dimension dim, typename TInteger>
684 inline
685 bool
686 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
687 sIsOpen( const SCell & p, DGtal::Dimension k )
688 {
689  return NumberTraits<Integer>::odd( p.coordinates[ k ] );
690 }
691 
692 //-----------------------------------------------------------------------------
693 ///////////////////////////////////////////////////////////////////////////////
694 //-----------------------------------------------------------------------------
695 template < DGtal::Dimension dim, typename TInteger>
696 inline
697 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
698 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
699 uDirs( const Cell & p )
700 {
701  return DirIterator( p, true );
702 }
703 //-----------------------------------------------------------------------------
704 template < DGtal::Dimension dim, typename TInteger>
705 inline
706 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
707 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
708 sDirs( const SCell & p )
709 {
710  return DirIterator( p, true );
711 }
712 //-----------------------------------------------------------------------------
713 template < DGtal::Dimension dim, typename TInteger>
714 inline
715 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
716 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
717 uOrthDirs( const Cell & p )
718 {
719  return DirIterator( p, false );
720 }
721 //-----------------------------------------------------------------------------
722 template < DGtal::Dimension dim, typename TInteger>
723 inline
724 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::DirIterator
725 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
726 sOrthDirs( const SCell & p )
727 {
728  return DirIterator( p, false );
729 }
730 //-----------------------------------------------------------------------------
731 template < DGtal::Dimension dim, typename TInteger>
732 inline
733 DGtal::Dimension
734 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
735 uOrthDir( const Cell & s )
736 {
737  DirIterator it( s, false );
738  ASSERT( ! it.end() );
739  return *it;
740 }
741 //-----------------------------------------------------------------------------
742 template < DGtal::Dimension dim, typename TInteger>
743 inline
744 DGtal::Dimension
745 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
746 sOrthDir( const SCell & s )
747 {
748  DirIterator it( s, false );
749  ASSERT( ! it.end() );
750  return *it;
751 }
752 //-----------------------------------------------------------------------------
753 ///////////////////////////////////////////////////////////////////////////////
754 //-----------------------------------------------------------------------------
755 template < DGtal::Dimension dim, typename TInteger>
756 inline
757 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
758 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
759 uGetIncr( Cell p, DGtal::Dimension k )
760 {
761  ASSERT( k < DIM );
762  p.coordinates[ k ] += 2;
763  return p;
764 }
765 //-----------------------------------------------------------------------------
766 template < DGtal::Dimension dim, typename TInteger>
767 inline
768 bool
769 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
770 uIsMax( const Cell &, DGtal::Dimension )
771 {
772  return false;
773 }
774 //-----------------------------------------------------------------------------
775 template < DGtal::Dimension dim, typename TInteger>
776 inline
777 bool
778 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
779 uIsMin( const Cell &, DGtal::Dimension )
780 {
781  return false;
782 }
783 //-----------------------------------------------------------------------------
784 template < DGtal::Dimension dim, typename TInteger>
785 inline
786 bool
787 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
788 uIsInside( const Cell &, DGtal::Dimension )
789 {
790  return true;
791 }
792 //-----------------------------------------------------------------------------
793 template < DGtal::Dimension dim, typename TInteger>
794 inline
795 bool
796 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
797 uIsInside( const Cell & )
798 {
799  return true;
800 }
801 //-----------------------------------------------------------------------------
802 template < DGtal::Dimension dim, typename TInteger>
803 inline
804 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
805 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
806 uGetDecr( Cell p, DGtal::Dimension k )
807 {
808  p.coordinates[ k ] -= 2;
809  return p;
810 }
811 //-----------------------------------------------------------------------------
812 template < DGtal::Dimension dim, typename TInteger>
813 inline
814 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
815 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
816 uGetAdd( Cell p, DGtal::Dimension k, Integer x )
817 {
818  p.coordinates[ k ] += 2 * x;
819  return p;
820 }
821 //-----------------------------------------------------------------------------
822 template < DGtal::Dimension dim, typename TInteger>
823 inline
824 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
825 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
826 uGetSub( Cell p, DGtal::Dimension k, Integer x )
827 {
828  ASSERT( k < DIM );
829  p.coordinates[ k ] -= 2 * x;
830  return p;
831 }
832 //-----------------------------------------------------------------------------
833 template < DGtal::Dimension dim, typename TInteger>
834 inline
835 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
836 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
837 uTranslation( Cell p, const Vector & vec )
838 {
839  for ( DGtal::Dimension k = 0; k < DIM; ++k )
840  p.coordinates[ k ] += 2 * vec[ k ];
841 
842  return p;
843 }
844 //-----------------------------------------------------------------------------
845 template < DGtal::Dimension dim, typename TInteger>
846 inline
847 typename DGtal::KhalimskyPreSpaceND< dim, TInteger>::Cell
848 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
849 uProjection( Cell p, const Cell & bound, DGtal::Dimension k )
850 {
851  ASSERT( k < DIM );
852  ASSERT( uIsOpen(p, k) == uIsOpen(bound, k) );
853  p.coordinates[ k ] = bound.coordinates[ k ];
854  return p;
855 }
856 //-----------------------------------------------------------------------------
857 template < DGtal::Dimension dim, typename TInteger>
858 inline
859 void
860 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
861 uProject( Cell & p, const Cell & bound, DGtal::Dimension k )
862 {
863  ASSERT( k < DIM );
864  ASSERT( uIsOpen(p, k) == uIsOpen(bound, k) );
865  p.coordinates[ k ] = bound.coordinates[ k ];
866 }
867 //-----------------------------------------------------------------------------
868 template < DGtal::Dimension dim, typename TInteger>
869 inline
870 bool
871 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
872 uNext( Cell & p, const Cell & lower, const Cell & upper )
873 {
874  ASSERT( uTopology(p) == uTopology(lower)
875  && uTopology(p) == uTopology(upper) );
876 
877  DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
878  if ( uKCoord( p, k ) == uKCoord( upper, k ) )
879  {
880  if ( p == upper ) return false;
881  uProject( p, lower, k );
882  for ( k = 1; k < DIM; ++k )
883  {
884  if ( uKCoord( p, k ) == uKCoord( upper, k ) )
885  uProject( p, lower, k );
886  else
887  {
888  p.coordinates[ k ] += 2;
889  break;
890  }
891  }
892  return true;
893  }
894 
895  p.coordinates[ k ] += 2;
896  return true;
897 }
898 
899 //-----------------------------------------------------------------------------
900 ///////////////////////////////////////////////////////////////////////////////
901 //-----------------------------------------------------------------------------
902 template < DGtal::Dimension dim, typename TInteger>
903 inline
904 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
905 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
906 sGetIncr( SCell p, DGtal::Dimension k )
907 {
908  ASSERT( k < DIM );
909  p.coordinates[ k ] += 2;;
910  return p;
911 }
912 //-----------------------------------------------------------------------------
913 template < DGtal::Dimension dim, typename TInteger>
914 inline
915 bool
916 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
917 sIsMax( const SCell &, DGtal::Dimension )
918 {
919  return false;
920 }
921 //-----------------------------------------------------------------------------
922 template < DGtal::Dimension dim, typename TInteger>
923 inline
924 bool
925 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
926 sIsMin( const SCell &, DGtal::Dimension )
927 {
928  return false;
929 }
930 //-----------------------------------------------------------------------------
931 template < DGtal::Dimension dim, typename TInteger>
932 inline
933 bool
934 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
935 sIsInside( const SCell &, DGtal::Dimension )
936 {
937  return true;
938 }
939 //-----------------------------------------------------------------------------
940 template < DGtal::Dimension dim, typename TInteger>
941 inline
942 bool
943 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
944 sIsInside( const SCell & )
945 {
946  return true;
947 }
948 //-----------------------------------------------------------------------------
949 template < DGtal::Dimension dim, typename TInteger>
950 inline
951 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
952 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
953 sGetDecr( SCell p, DGtal::Dimension k )
954 {
955  ASSERT( k < DIM );
956  p.coordinates[ k ] -= 2;;
957  return p;
958 }
959 //-----------------------------------------------------------------------------
960 template < DGtal::Dimension dim, typename TInteger>
961 inline
962 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
963 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
964 sGetAdd( SCell p, DGtal::Dimension k, Integer x )
965 {
966  ASSERT( k < DIM );
967  p.coordinates[ k ] += 2 * x;;
968  return p;
969 }
970 //-----------------------------------------------------------------------------
971 template < DGtal::Dimension dim, typename TInteger>
972 inline
973 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
974 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
975 sGetSub( SCell p, DGtal::Dimension k, Integer x )
976 {
977  ASSERT( k < DIM );
978  p.coordinates[ k ] -= 2 * x;;
979  return p;
980 }
981 //-----------------------------------------------------------------------------
982 template < DGtal::Dimension dim, typename TInteger>
983 inline
984 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
985 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
986 sTranslation( SCell p, const Vector & vec )
987 {
988  for ( DGtal::Dimension k = 0; k < DIM; ++k )
989  p.coordinates[ k ] += 2 * vec[ k ];
990 
991  return p;
992 }
993 //-----------------------------------------------------------------------------
994 template < DGtal::Dimension dim, typename TInteger>
995 inline
996 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
997 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
998 sProjection( SCell p, const SCell & bound, DGtal::Dimension k )
999 {
1000  ASSERT( k < DIM );
1001  ASSERT( sIsOpen(p, k) == sIsOpen(bound, k) );
1002  p.coordinates[ k ] = bound.coordinates[ k ];
1003  return p;
1004 }
1005 //-----------------------------------------------------------------------------
1006 template < DGtal::Dimension dim, typename TInteger>
1007 inline
1008 void
1009 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1010 sProject( SCell & p, const SCell & bound, DGtal::Dimension k )
1011 {
1012  ASSERT( k < DIM );
1013  ASSERT( sIsOpen(p, k) == sIsOpen(bound, k) );
1014  p.coordinates[ k ] = bound.coordinates[ k ];
1015 }
1016 //-----------------------------------------------------------------------------
1017 template < DGtal::Dimension dim, typename TInteger>
1018 inline
1019 bool
1020 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1021 sNext( SCell & p, const SCell & lower, const SCell & upper )
1022 {
1023  ASSERT( sTopology(p) == sTopology(lower)
1024  && sTopology(p) == sTopology(upper) );
1025 
1026  DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1027  if ( sCoord( p, k ) == sCoord( upper, k ) )
1028  {
1029  if ( p == upper ) return false;
1030  sProject( p, lower, k );
1031  for ( k = 1; k < DIM; ++k )
1032  {
1033  if ( sCoord( p, k ) == sCoord( upper, k ) )
1034  sProject( p, lower, k );
1035  else
1036  {
1037  p.coordinates[ k ] += 2;;
1038  break;
1039  }
1040  }
1041  return true;
1042  }
1043 
1044  p.coordinates[ k ] += 2;
1045  return true;
1046 }
1047 
1048 //-----------------------------------------------------------------------------
1049 // ----------------------- Neighborhood services --------------------------
1050 //-----------------------------------------------------------------------------
1051 template < DGtal::Dimension dim, typename TInteger>
1052 inline
1053 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1054 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1055 uNeighborhood( const Cell & c )
1056 {
1057  Cells N;
1058  N.push_back( c );
1059  for ( DGtal::Dimension k = 0; k < DIM; ++k )
1060  {
1061  N.push_back( uGetDecr( c, k ) );
1062  N.push_back( uGetIncr( c, k ) );
1063  }
1064  return N;
1065 }
1066 //-----------------------------------------------------------------------------
1067 template < DGtal::Dimension dim, typename TInteger>
1068 inline
1069 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1070 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1071 sNeighborhood( const SCell & c )
1072 {
1073  SCells N;
1074  N.push_back( c );
1075  for ( DGtal::Dimension k = 0; k < DIM; ++k )
1076  {
1077  N.push_back( sGetDecr( c, k ) );
1078  N.push_back( sGetIncr( c, k ) );
1079  }
1080  return N;
1081 }
1082 //-----------------------------------------------------------------------------
1083 template < DGtal::Dimension dim, typename TInteger>
1084 inline
1085 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1086 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1087 uProperNeighborhood( const Cell & c )
1088 {
1089  Cells N;
1090  for ( DGtal::Dimension k = 0; k < DIM; ++k )
1091  {
1092  N.push_back( uGetDecr( c, k ) );
1093  N.push_back( uGetIncr( c, k ) );
1094  }
1095  return N;
1096 }
1097 //-----------------------------------------------------------------------------
1098 template < DGtal::Dimension dim, typename TInteger>
1099 inline
1100 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1101 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1102 sProperNeighborhood( const SCell & c )
1103 {
1104  SCells N;
1105  for ( DGtal::Dimension k = 0; k < DIM; ++k )
1106  {
1107  N.push_back( sGetDecr( c, k ) );
1108  N.push_back( sGetIncr( c, k ) );
1109  }
1110  return N;
1111 }
1112 //-----------------------------------------------------------------------------
1113 template < DGtal::Dimension dim, typename TInteger>
1114 inline
1115 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cell
1116 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1117 uAdjacent( const Cell & p, DGtal::Dimension k, bool up )
1118 {
1119  ASSERT( k < DIM );
1120  return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1121 }
1122 //-----------------------------------------------------------------------------
1123 template < DGtal::Dimension dim, typename TInteger>
1124 inline
1125 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1126 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1127 sAdjacent( const SCell & p, DGtal::Dimension k, bool up )
1128 {
1129  ASSERT( k < DIM );
1130  return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1131 }
1132 
1133 // ----------------------- Incidence services --------------------------
1134 //-----------------------------------------------------------------------------
1135 template < DGtal::Dimension dim, typename TInteger>
1136 inline
1137 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cell
1138 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1139 uIncident( Cell c, DGtal::Dimension k, bool up )
1140 {
1141  ASSERT( k < dim );
1142 
1143  if ( up ) ++c.coordinates[ k ];
1144  else --c.coordinates[ k ];
1145 
1146  return c;
1147 }
1148 //-----------------------------------------------------------------------------
1149 template < DGtal::Dimension dim, typename TInteger>
1150 inline
1151 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1152 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1153 sIncident( SCell c, DGtal::Dimension k, bool up )
1154 {
1155  ASSERT( k < dim );
1156 
1157  bool sign = up ? c.positive : ! c.positive;
1158  for ( DGtal::Dimension i = 0; i <= k; ++i )
1159  if ( sIsOpen( c, i ) )
1160  sign = ! sign;
1161  c.positive = sign;
1162 
1163  if ( up ) ++c.coordinates[ k ];
1164  else --c.coordinates[ k ];
1165 
1166  return c;
1167 }
1168 //-----------------------------------------------------------------------------
1169 template < DGtal::Dimension dim, typename TInteger>
1170 inline
1171 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1172 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1173 uLowerIncident( const Cell & c )
1174 {
1175  Cells N;
1176  for ( auto q = uDirs( c ); q != 0; ++q )
1177  {
1178  const DGtal::Dimension k = *q;
1179  N.push_back( uIncident( c, k, false ) );
1180  N.push_back( uIncident( c, k, true ) );
1181  }
1182  return N;
1183 }
1184 //-----------------------------------------------------------------------------
1185 template < DGtal::Dimension dim, typename TInteger>
1186 inline
1187 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1188 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1189 uUpperIncident( const Cell & c )
1190 {
1191  Cells N;
1192  for ( auto q = uOrthDirs( c ); q != 0; ++q )
1193  {
1194  const DGtal::Dimension k = *q;
1195  N.push_back( uIncident( c, k, false ) );
1196  N.push_back( uIncident( c, k, true ) );
1197  }
1198  return N;
1199 }
1200 //-----------------------------------------------------------------------------
1201 template < DGtal::Dimension dim, typename TInteger>
1202 inline
1203 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1204 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1205 sLowerIncident( const SCell & c )
1206 {
1207  SCells N;
1208  for ( auto q = sDirs( c ); q != 0; ++q )
1209  {
1210  const DGtal::Dimension k = *q;
1211  N.push_back( sIncident( c, k, false ) );
1212  N.push_back( sIncident( c, k, true ) );
1213  }
1214  return N;
1215 }
1216 //-----------------------------------------------------------------------------
1217 template < DGtal::Dimension dim, typename TInteger>
1218 inline
1219 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCells
1220 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1221 sUpperIncident( const SCell & c )
1222 {
1223  SCells N;
1224  for ( auto q = sOrthDirs( c ); q != 0; ++q )
1225  {
1226  const DGtal::Dimension k = *q;
1227  N.push_back( sIncident( c, k, false ) );
1228  N.push_back( sIncident( c, k, true ) );
1229  }
1230  return N;
1231 }
1232 //-----------------------------------------------------------------------------
1233 template < DGtal::Dimension dim, typename TInteger>
1234 inline
1235 void
1236 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1237 uAddFaces( Cells& faces, const Cell& c, Dimension axis )
1238 {
1239  const DGtal::Dimension dim_of_c = uDim( c );
1240  if ( axis >= dim_of_c ) return;
1241 
1242  DirIterator q = uDirs( c );
1243  for ( Dimension i = 0; i < axis; ++i ) ++q;
1244 
1245  const Integer x = uKCoord( c, *q );
1246 
1247  Cell f1 = uIncident( c, *q, false );
1248  Cell f2 = uIncident( c, *q, true );
1249 
1250  faces.push_back( f1 );
1251  faces.push_back( f2 );
1252 
1253  uAddFaces( faces, f1, axis );
1254  uAddFaces( faces, f2, axis );
1255 
1256  uAddFaces( faces, c, axis+1 );
1257 }
1258 //-----------------------------------------------------------------------------
1259 template < DGtal::Dimension dim, typename TInteger>
1260 inline
1261 void
1262 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1263 uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis )
1264 {
1265  const DGtal::Dimension dim_of_c = uDim( c );
1266  if ( axis >= dimension - dim_of_c ) return;
1267 
1268  DirIterator q = uOrthDirs( c );
1269  for ( Dimension i = 0; i < axis; ++i ) ++q;
1270 
1271  const Integer x = uKCoord( c, *q );
1272 
1273  Cell f1 = uIncident( c, *q, false );
1274  Cell f2 = uIncident( c, *q, true );
1275 
1276  cofaces.push_back( f1 );
1277  cofaces.push_back( f2 );
1278 
1279  uAddCoFaces( cofaces, f1, axis );
1280  uAddCoFaces( cofaces, f2, axis );
1281 
1282  uAddCoFaces( cofaces, c, axis+1 );
1283 }
1284 //-----------------------------------------------------------------------------
1285 template < DGtal::Dimension dim, typename TInteger>
1286 inline
1287 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1288 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1289 uFaces( const Cell & c )
1290 {
1291  Cells N;
1292  uAddFaces( N, c, 0 );
1293  return N;
1294 }
1295 //-----------------------------------------------------------------------------
1296 template < DGtal::Dimension dim, typename TInteger>
1297 inline
1298 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::Cells
1299 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1300 uCoFaces( const Cell & c )
1301 {
1302  Cells N;
1303  uAddCoFaces( N, c, 0 );
1304  return N;
1305 }
1306 //-----------------------------------------------------------------------------
1307 template < DGtal::Dimension dim, typename TInteger>
1308 inline
1309 bool
1310 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1311 sDirect( const SCell & p, DGtal::Dimension k )
1312 {
1313  ASSERT( k < dim );
1314 
1315  bool sign = p.positive;
1316  for ( DGtal::Dimension i = 0; i <= k; ++i )
1317  if ( sIsOpen( p, i ) )
1318  sign = ! sign;
1319  return sign;
1320 }
1321 //-----------------------------------------------------------------------------
1322 template < DGtal::Dimension dim, typename TInteger>
1323 inline
1324 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1325 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1326 sDirectIncident( SCell p, DGtal::Dimension k )
1327 {
1328  ASSERT( k < dim );
1329 
1330  bool sign = p.positive;
1331  for ( DGtal::Dimension i = 0; i <= k; ++i )
1332  if ( sIsOpen( p, i ) )
1333  sign = ! sign;
1334 
1335  bool up = sign;
1336  p.positive = POS;
1337 
1338  if ( up ) ++p.coordinates[ k ];
1339  else --p.coordinates[ k ];
1340 
1341  return p;
1342 }
1343 //-----------------------------------------------------------------------------
1344 template < DGtal::Dimension dim, typename TInteger>
1345 inline
1346 typename DGtal::KhalimskyPreSpaceND< dim, TInteger >::SCell
1347 DGtal::KhalimskyPreSpaceND< dim, TInteger >::
1348 sIndirectIncident( SCell p, DGtal::Dimension k )
1349 {
1350  ASSERT( k < dim );
1351 
1352  bool sign = p.positive;
1353  for ( DGtal::Dimension i = 0; i <= k; ++i )
1354  if ( sIsOpen( p, i ) )
1355  sign = ! sign;
1356 
1357  bool up = ! sign;
1358  p.positive = NEG;
1359 
1360  if ( up ) ++p.coordinates[ k ];
1361  else --p.coordinates[ k ];
1362 
1363  return p;
1364 }
1365 
1366 
1367 
1368 
1369 //-----------------------------------------------------------------------------
1370 template < DGtal::Dimension dim, typename TInteger>
1371 inline
1372 void
1373 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
1374 selfDisplay ( std::ostream & out )
1375 {
1376  out << "[KhalimskyPreSpaceND<" << dimension << ">]";
1377 }
1378 //-----------------------------------------------------------------------------
1379 template < DGtal::Dimension dim, typename TInteger>
1380 constexpr inline
1381 bool
1382 DGtal::KhalimskyPreSpaceND< dim, TInteger>::
1383 isValid()
1384 {
1385  return true;
1386 }
1387 
1388 
1389 
1390 ///////////////////////////////////////////////////////////////////////////////
1391 // Implementation of inline functions //
1392 template < DGtal::Dimension dim, typename TInteger>
1393 inline
1394 std::ostream&
1395 DGtal::operator<< ( std::ostream & out,
1396  const KhalimskyPreSpaceND< dim, TInteger> & object )
1397 {
1398  object.selfDisplay( out );
1399  return out;
1400 }
1401 
1402 // //
1403 ///////////////////////////////////////////////////////////////////////////////