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