DGtal 1.3.0
Loading...
Searching...
No Matches
KhalimskySpaceND.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 KhalimskySpaceND.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
21 *
22 * @date 2011/02/08
23 *
24 * Implementation of inline methods defined in KhalimskySpaceND.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <DGtal/io/Color.h>
32#include <DGtal/kernel/NumberTraits.h>
33//////////////////////////////////////////////////////////////////////////////
34
35///////////////////////////////////////////////////////////////////////////////
36// Namescape scope definition of static constants.
37///////////////////////////////////////////////////////////////////////////////
38
39template < DGtal::Dimension dim, typename TInteger >
40 const constexpr
41 DGtal::Dimension
42 DGtal::KhalimskySpaceND<dim, TInteger>::dimension;
43
44template < DGtal::Dimension dim, typename TInteger >
45 const constexpr
46 DGtal::Dimension
47 DGtal::KhalimskySpaceND<dim, TInteger>::DIM;
48
49template < DGtal::Dimension dim, typename TInteger >
50 const constexpr
51 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
52 DGtal::KhalimskySpaceND<dim, TInteger>::POS;
53
54template < DGtal::Dimension dim, typename TInteger >
55 const constexpr
56 typename DGtal::KhalimskySpaceND<dim, TInteger>::Sign
57 DGtal::KhalimskySpaceND<dim, TInteger>::NEG;
58
59///////////////////////////////////////////////////////////////////////////////
60// IMPLEMENTATION of inline methods.
61///////////////////////////////////////////////////////////////////////////////
62
63///////////////////////////////////////////////////////////////////////////////
64// KhalimskyCell
65///////////////////////////////////////////////////////////////////////////////
66//-----------------------------------------------------------------------------
67template < DGtal::Dimension dim, typename TInteger >
68inline
69DGtal::KhalimskyCell< dim, TInteger >::
70KhalimskyCell( Integer )
71 : myPreCell()
72{
73}
74//-----------------------------------------------------------------------------
75template < DGtal::Dimension dim, typename TInteger >
76inline
77DGtal::KhalimskyCell< dim, TInteger >::
78KhalimskyCell( const Point & p )
79 : myPreCell( p )
80{
81}
82//-----------------------------------------------------------------------------
83template < DGtal::Dimension dim, typename TInteger >
84inline
85DGtal::KhalimskyCell< dim, TInteger >::
86KhalimskyCell( const PreCell & aCell )
87 : myPreCell( aCell )
88{
89}
90//-----------------------------------------------------------------------------
91template < DGtal::Dimension dim, typename TInteger >
92inline
93DGtal::KhalimskyCell< dim, TInteger >::
94operator DGtal::KhalimskyPreCell< dim, TInteger > const& () const
95{
96 return myPreCell;
97}
98//-----------------------------------------------------------------------------
99template < DGtal::Dimension dim, typename TInteger >
100inline
101DGtal::KhalimskyPreCell< dim, TInteger > const &
102DGtal::KhalimskyCell< dim, TInteger >::
103preCell () const
104{
105 return myPreCell;
106}
107//-----------------------------------------------------------------------------
108template < DGtal::Dimension dim, typename TInteger >
109inline
110DGtal::KhalimskyCell< dim, TInteger >::
111operator DGtal::KhalimskyPreCell< dim, TInteger > & ()
112{
113 return myPreCell;
114}
115//-----------------------------------------------------------------------------
116template < DGtal::Dimension dim, typename TInteger >
117inline
118bool
119DGtal::KhalimskyCell< dim, TInteger >::
120operator==( const KhalimskyCell & other ) const
121{
122 return myPreCell == other.myPreCell;
123}
124//-----------------------------------------------------------------------------
125template < DGtal::Dimension dim, typename TInteger >
126inline
127bool
128DGtal::KhalimskyCell< dim, TInteger >::
129operator!=( const KhalimskyCell & other ) const
130{
131 return myPreCell != other.myPreCell;
132}
133//-----------------------------------------------------------------------------
134template < DGtal::Dimension dim, typename TInteger >
135inline
136bool
137DGtal::KhalimskyCell< dim, TInteger >::
138operator<( const KhalimskyCell & other ) const
139{
140 return myPreCell < other.myPreCell;
141}
142//-----------------------------------------------------------------------------
143template < DGtal::Dimension dim, typename TInteger >
144inline
145std::ostream &
146DGtal::operator<<( std::ostream & out,
147 const KhalimskyCell< dim, TInteger > & object )
148{
149 out << static_cast< const KhalimskyPreCell<dim, TInteger> & >(object);
150 return out;
151}
152
153//------------------------------------------------------------------------------
154template < DGtal::Dimension dim, typename TInteger >
155inline
156std::string
157DGtal::KhalimskyCell<dim, TInteger>::
158className() const
159{
160 return "KhalimskyCell";
161}
162
163///////////////////////////////////////////////////////////////////////////////
164// SignedKhalimskyCell
165///////////////////////////////////////////////////////////////////////////////
166//-----------------------------------------------------------------------------
167template < DGtal::Dimension dim, typename TInteger >
168inline
169DGtal::SignedKhalimskyCell< dim, TInteger >::
170SignedKhalimskyCell( Integer )
171 : mySPreCell()
172{
173}
174//-----------------------------------------------------------------------------
175template < DGtal::Dimension dim, typename TInteger >
176inline
177DGtal::SignedKhalimskyCell< dim, TInteger >::
178SignedKhalimskyCell( const Point & p, bool positive )
179 : mySPreCell( p, positive )
180{
181}
182//-----------------------------------------------------------------------------
183template < DGtal::Dimension dim, typename TInteger >
184inline
185DGtal::SignedKhalimskyCell< dim, TInteger >::
186SignedKhalimskyCell( const SPreCell & aCell )
187 : mySPreCell( aCell )
188{
189}
190//-----------------------------------------------------------------------------
191template < DGtal::Dimension dim, typename TInteger >
192inline
193DGtal::SignedKhalimskyCell< dim, TInteger >::
194operator DGtal::SignedKhalimskyPreCell< dim, TInteger > const& () const
195{
196 return mySPreCell;
197}
198//-----------------------------------------------------------------------------
199template < DGtal::Dimension dim, typename TInteger >
200inline
201DGtal::SignedKhalimskyPreCell< dim, TInteger > const &
202DGtal::SignedKhalimskyCell< dim, TInteger >::
203preCell() const
204{
205 return mySPreCell;
206}
207//-----------------------------------------------------------------------------
208template < DGtal::Dimension dim, typename TInteger >
209inline
210DGtal::SignedKhalimskyCell< dim, TInteger >::
211operator DGtal::SignedKhalimskyPreCell< dim, TInteger > & ()
212{
213 return mySPreCell;
214}
215//-----------------------------------------------------------------------------
216template < DGtal::Dimension dim, typename TInteger >
217inline
218bool
219DGtal::SignedKhalimskyCell< dim, TInteger >::
220operator==( const SignedKhalimskyCell & other ) const
221{
222 return mySPreCell == other.mySPreCell;
223}
224//-----------------------------------------------------------------------------
225template < DGtal::Dimension dim, typename TInteger >
226inline
227bool
228DGtal::SignedKhalimskyCell< dim, TInteger >::
229operator!=( const SignedKhalimskyCell & other ) const
230{
231 return mySPreCell != other.mySPreCell;
232}
233//-----------------------------------------------------------------------------
234template < DGtal::Dimension dim, typename TInteger >
235inline
236bool
237DGtal::SignedKhalimskyCell< dim, TInteger >::
238operator<( const SignedKhalimskyCell & other ) const
239{
240 return mySPreCell < other.mySPreCell;
241}
242//-----------------------------------------------------------------------------
243template < DGtal::Dimension dim,
244 typename TInteger >
245inline
246std::ostream &
247DGtal::operator<<( std::ostream & out,
248 const SignedKhalimskyCell< dim, TInteger > & object )
249{
250 out << static_cast< const SignedKhalimskyPreCell<dim, TInteger> & >(object);
251 return out;
252}
253
254//------------------------------------------------------------------------------
255template < DGtal::Dimension dim, typename TInteger >
256inline
257std::string
258DGtal::SignedKhalimskyCell<dim, TInteger>::
259className() const
260{
261 return "SignedKhalimskyCell";
262}
263
264///////////////////////////////////////////////////////////////////////////////
265// KhalimskySpaceNDHelper
266///////////////////////////////////////////////////////////////////////////////
267namespace DGtal
268{
269
270template <
271 DGtal::Dimension dim,
272 typename TInteger
273>
274class KhalimskySpaceNDHelper< KhalimskySpaceND< dim, TInteger > >
275{
276private:
277 // Private typedefs
278 using KhalimskySpace = KhalimskySpaceND< dim, TInteger >;
279 using Point = PointVector< dim, TInteger >;
280 using Cell = KhalimskyCell< dim, TInteger >;
281 using SCell = SignedKhalimskyCell< dim, TInteger >;
282
283 /// Returns derived mutable instance
284 KhalimskySpace& derived()
285 {
286 return *static_cast<KhalimskySpace*>(this);
287 }
288
289 /// Returns derived constant instance
290 KhalimskySpace const & derived() const
291 {
292 return *static_cast<KhalimskySpace const*>(this);
293 }
294
295
296public:
297 // Provided helpers
298
299 /// @return true is the specified dimension is periodic
300 inline
301 bool isDimensionPeriodicHelper( DGtal::Dimension d ) const
302 {
303 return derived().myClosure[ d ] == KhalimskySpace::PERIODIC;
304 }
305
306 /// @return true is there is at least one periodic dimension.
307 inline
308 bool isAnyDimensionPeriodicHelper() const
309 {
310 return myIsAnyDimensionPeriodic;
311 }
312
313 /** Modifies a khalimsky coordinate according to the dimension periodicity.
314 * @param[in,out] aKCoord the coordinate to modify.
315 * @param d the coordinate dimension.
316 */
317 inline
318 void updateKCoordHelper( typename Point::Coordinate & aKCoord, DGtal::Dimension d ) const
319 {
320 if ( isDimensionPeriodicHelper( d ) )
321 {
322 aKCoord = ( aKCoord - derived().myCellLower.myPreCell.coordinates[ d ] ) % myCellExtent[ d ];
323 aKCoord += ( ( aKCoord < 0 ) ?
324 derived().myCellUpper.myPreCell.coordinates[ d ] + 1
325 : derived().myCellLower.myPreCell.coordinates[ d ]
326 );
327 }
328 }
329
330 /** Returns a given khalimsky coordinate modified according to the dimension periodicity.
331 * @param[in] aKCoord the coordinate to modify.
332 * @param d the coordinate dimension.
333 * @returns the modified coordinate.
334 */
335 inline
336 typename Point::Coordinate returnKCoordHelper( typename Point::Coordinate aKCoord, DGtal::Dimension d ) const
337 {
338 updateKCoordHelper( aKCoord, d );
339 return aKCoord;
340 }
341
342 /** Modifies khalimsky coordinates of a point according to the dimension periodicity.
343 * @param[in,out] aKCoords the khalimksy coordinates.
344 */
345 inline
346 void updateKCoordsHelper( Point & aKCoords ) const
347 {
348 if ( isAnyDimensionPeriodicHelper() )
349 {
350 for ( DGtal::Dimension i = 0; i < dim; ++i )
351 updateKCoordHelper( aKCoords[ i ], i );
352 }
353 }
354
355 /** Returns given khalimsky coordinates of a point modified according to the dimension periodicity.
356 * @param[in] aKCoords the khalimksy coordinates.
357 */
358 inline
359 Point returnKCoordsHelper( Point aKCoords ) const
360 {
361 updateKCoordsHelper( aKCoords );
362 return aKCoords;
363 }
364
365 /** Modifies a cell's khalimsky coordinate according to the dimension periodicity.
366 * @param[in,out] aCell an unsigned cell.
367 * @param d the coordinate dimension.
368 */
369 inline
370 void updateCellHelper( Cell & aCell, DGtal::Dimension d ) const
371 {
372 updateKCoordHelper( aCell.myPreCell.coordinates[ d ], d );
373 }
374
375 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
376 * @param[in,out] aCell an unsigned cell.
377 */
378 inline
379 void updateCellHelper( Cell & aCell ) const
380 {
381 updateKCoordsHelper( aCell.myPreCell.coordinates );
382 }
383
384 /** Modifies a cell's khalimsky coordinate according to the dimension periodicity.
385 * @param[in,out] aCell a signed cell.
386 * @param d the coordinate dimension.
387 */
388 inline
389 void updateSCellHelper( SCell & aCell, DGtal::Dimension d ) const
390 {
391 updateKCoordHelper( aCell.mySPreCell.coordinates[ d ], d );
392 }
393
394 /** Modifies a cell's khalimsky coordinates according to the dimension periodicity.
395 * @param[in,out] aCell a signed cell.
396 */
397 inline
398 void updateSCellHelper( SCell & aCell ) const
399 {
400 updateKCoordsHelper( aCell.mySPreCell.coordinates );
401 }
402
403public:
404 /// Initialization
405 bool initHelper()
406 {
407 myIsAnyDimensionPeriodic = false;
408 for ( DGtal::Dimension i = 0; i < dim; ++i )
409 {
410 myIsAnyDimensionPeriodic |= isDimensionPeriodicHelper( i );
411 myCellExtent[ i ] = derived().myCellUpper.myPreCell.coordinates[ i ] - derived().myCellLower.myPreCell.coordinates[ i ] + 1;
412 }
413
414 return true;
415 }
416
417
418private:
419 // Optimization data
420 Point myCellExtent; ///< Extent between the extremal cells.
421 bool myIsAnyDimensionPeriodic; ///< true if there is at least one periodic dimension.
422};
423
424} // namespace DGtal
425
426///////////////////////////////////////////////////////////////////////////////
427// KhalimskySpaceND
428///////////////////////////////////////////////////////////////////////////////
429///////////////////////////////////////////////////////////////////////////////
430// ----------------------- Standard services ------------------------------
431//-----------------------------------------------------------------------------
432template < DGtal::Dimension dim, typename TInteger>
433inline
434DGtal::KhalimskySpaceND< dim, TInteger>::
435~KhalimskySpaceND()
436{
437}
438//-----------------------------------------------------------------------------
439template < DGtal::Dimension dim, typename TInteger>
440inline
441DGtal::KhalimskySpaceND< dim, TInteger>::
442KhalimskySpaceND()
443{
444 Point low, high;
445 for ( DGtal::Dimension i = 0; i < dimension; ++i )
446 {
447 low[ i ] = NumberTraits< Integer >::min() / 2 + 1;
448 high[ i ] = NumberTraits< Integer >::max() / 2 - 1;
449 }
450 init( low, high, true );
451}
452//-----------------------------------------------------------------------------
453template < DGtal::Dimension dim, typename TInteger>
454inline
455bool
456DGtal::KhalimskySpaceND< dim, TInteger>::
457init( const Point & lower,
458 const Point & upper,
459 bool isClosed )
460{
461 std::array<Closure, dimension> closure;
462 for ( DGtal::Dimension i = 0; i < dimension; ++i )
463 closure[ i ] = isClosed ? CLOSED : OPEN;
464
465 return init( lower, upper, closure );
466}
467//-----------------------------------------------------------------------------
468template < DGtal::Dimension dim, typename TInteger>
469inline
470bool
471DGtal::KhalimskySpaceND< dim, TInteger>::
472init( const Point & lower,
473 const Point & upper,
474 Closure closure )
475{
476 std::array<Closure, dimension> dimClosure;
477 dimClosure.fill( closure );
478
479 return init( lower, upper, dimClosure );
480}
481
482//-----------------------------------------------------------------------------
483template < DGtal::Dimension dim, typename TInteger>
484inline
485bool
486DGtal::KhalimskySpaceND< dim, TInteger>::
487init( const Point & lower,
488 const Point & upper,
489 const std::array<Closure, dim> & closure )
490{
491 myLower = lower;
492 myUpper = upper;
493 myClosure = closure;
494
495 if ( NumberTraits< Integer >::isBounded() == BOUNDED )
496 {
497 for ( DGtal::Dimension i = 0; i < dimension; ++i )
498 {
499 if ( ( lower[ i ] <= ( NumberTraits< Integer >::min() / 2 ) )
500 || ( upper[ i ] >= ( NumberTraits< Integer >::max() / 2 ) ) )
501 return false;
502 }
503 }
504
505 for ( DGtal::Dimension i = 0; i < dimension; ++i )
506 {
507 PreCellularGridSpace::uSetKCoord( myCellLower.myPreCell, i, ( lower[ i ] * 2 ) + ( closure[ i ] != OPEN ? 0 : 1 ) );
508 PreCellularGridSpace::uSetKCoord( myCellUpper.myPreCell, i, ( upper[ i ] * 2 ) + ( closure[ i ] == CLOSED ? 2 : 1 ) );
509
510 }
511
512 return this->initHelper();
513}
514//-----------------------------------------------------------------------------
515template < DGtal::Dimension dim, typename TInteger>
516inline
517typename DGtal::KhalimskySpaceND< dim, TInteger>::Size
518DGtal::KhalimskySpaceND< dim, TInteger>::
519size( DGtal::Dimension k ) const
520{
521 ASSERT( k < dimension );
522 return myUpper[ k ] + NumberTraits<Integer>::ONE - myLower[ k ];
523}
524//-----------------------------------------------------------------------------
525template < DGtal::Dimension dim, typename TInteger>
526inline
527TInteger
528DGtal::KhalimskySpaceND< dim, TInteger>::
529min( DGtal::Dimension k ) const
530{
531 return myLower[ k ];
532}
533//-----------------------------------------------------------------------------
534template < DGtal::Dimension dim, typename TInteger>
535inline
536TInteger
537DGtal::KhalimskySpaceND< dim, TInteger>::
538max( DGtal::Dimension k ) const
539{
540 return myUpper[ k ];
541}
542//-----------------------------------------------------------------------------
543template < DGtal::Dimension dim, typename TInteger>
544inline
545const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
546DGtal::KhalimskySpaceND< dim, TInteger>::
547lowerBound() const
548{
549 return myLower;
550}
551//-----------------------------------------------------------------------------
552template < DGtal::Dimension dim, typename TInteger>
553inline
554const typename DGtal::KhalimskySpaceND< dim, TInteger>::Point &
555DGtal::KhalimskySpaceND< dim, TInteger>::
556upperBound() const
557{
558 return myUpper;
559}
560//-----------------------------------------------------------------------------
561template < DGtal::Dimension dim, typename TInteger>
562inline
563const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
564DGtal::KhalimskySpaceND< dim, TInteger>::
565lowerCell() const
566{
567 return myCellLower;
568}
569//-----------------------------------------------------------------------------
570template < DGtal::Dimension dim, typename TInteger>
571inline
572const typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell &
573DGtal::KhalimskySpaceND< dim, TInteger>::
574upperCell() const
575{
576 return myCellUpper;
577}
578//-----------------------------------------------------------------------------
579template < DGtal::Dimension dim, typename TInteger>
580inline
581bool
582DGtal::KhalimskySpaceND< dim, TInteger>::
583uIsValid( const PreCell & p, Dimension k ) const
584{
585 return cIsValid( p.coordinates, k );
586}
587//-----------------------------------------------------------------------------
588template < DGtal::Dimension dim, typename TInteger>
589inline
590bool
591DGtal::KhalimskySpaceND< dim, TInteger>::
592uIsValid( const PreCell & p ) const
593{
594 return cIsValid( p.coordinates );
595}
596//-----------------------------------------------------------------------------
597template < DGtal::Dimension dim, typename TInteger>
598inline
599bool
600DGtal::KhalimskySpaceND< dim, TInteger>::
601cIsValid( const Point & p, Dimension k ) const
602{
603 return p[ k ] <= PreCellularGridSpace::uKCoord( myCellUpper, k )
604 && p[ k ] >= PreCellularGridSpace::uKCoord( myCellLower, k );
605}
606//-----------------------------------------------------------------------------
607template < DGtal::Dimension dim, typename TInteger>
608inline
609bool
610DGtal::KhalimskySpaceND< dim, TInteger>::
611cIsValid( const Point & p ) const
612{
613 for ( Dimension k = 0; k < DIM; ++ k )
614 if ( ! cIsValid( p, k ) )
615 return false;
616
617 return true;
618}
619//-----------------------------------------------------------------------------
620template < DGtal::Dimension dim, typename TInteger>
621inline
622bool
623DGtal::KhalimskySpaceND< dim, TInteger>::
624sIsValid( const SPreCell & p, Dimension k ) const
625{
626 return cIsValid( p.coordinates, k );
627}
628//-----------------------------------------------------------------------------
629template < DGtal::Dimension dim, typename TInteger>
630inline
631bool
632DGtal::KhalimskySpaceND< dim, TInteger>::
633sIsValid( const SPreCell & p ) const
634{
635 return cIsValid( p.coordinates );
636}
637//-----------------------------------------------------------------------------
638template < DGtal::Dimension dim, typename TInteger>
639inline
640bool
641DGtal::KhalimskySpaceND< dim, TInteger>::
642isSpaceClosed() const
643{
644 for ( Dimension i = 0; i < dimension; ++i )
645 if ( myClosure[ i ] == OPEN )
646 return false;
647
648 return true;
649}
650//-----------------------------------------------------------------------------
651template < DGtal::Dimension dim, typename TInteger>
652inline
653bool
654DGtal::KhalimskySpaceND< dim, TInteger>::
655isSpaceClosed( Dimension k ) const
656{
657 return myClosure[ k ] != OPEN;
658}
659//-----------------------------------------------------------------------------
660template < DGtal::Dimension dim, typename TInteger>
661inline
662bool
663DGtal::KhalimskySpaceND< dim, TInteger>::
664isSpacePeriodic() const
665{
666 for ( Dimension i = 0; i < dimension; ++i )
667 if ( myClosure[ i ] != PERIODIC )
668 return false;
669
670 return true;
671}
672//-----------------------------------------------------------------------------
673template < DGtal::Dimension dim, typename TInteger>
674inline
675bool
676DGtal::KhalimskySpaceND< dim, TInteger>::
677isSpacePeriodic( Dimension k ) const
678{
679 return myClosure[ k ] == PERIODIC;
680}
681//-----------------------------------------------------------------------------
682template < DGtal::Dimension dim, typename TInteger>
683inline
684bool
685DGtal::KhalimskySpaceND< dim, TInteger>::
686isAnyDimensionPeriodic() const
687{
688 return this->isAnyDimensionPeriodicHelper();
689}
690//-----------------------------------------------------------------------------
691template < DGtal::Dimension dim, typename TInteger>
692inline
693typename DGtal::KhalimskySpaceND< dim, TInteger>::Closure
694DGtal::KhalimskySpaceND< dim, TInteger>::
695getClosure(Dimension k) const
696{
697 return myClosure[k];
698}
699//-----------------------------------------------------------------------------
700template < DGtal::Dimension dim, typename TInteger>
701inline
702typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
703DGtal::KhalimskySpaceND< dim, TInteger>::
704uCell( const PreCell & c ) const
705{
706 return uCell( c.coordinates );
707}
708//-----------------------------------------------------------------------------
709template < DGtal::Dimension dim, typename TInteger>
710inline
711typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
712DGtal::KhalimskySpaceND< dim, TInteger>::
713uCell( const Point & kp ) const
714{
715 ASSERT( cIsInside( kp ) );
716 return Cell( this->returnKCoordsHelper( kp ) );
717}
718//-----------------------------------------------------------------------------
719template < DGtal::Dimension dim, typename TInteger>
720inline
721typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
722DGtal::KhalimskySpaceND< dim, TInteger>::
723uCell( Point p, const PreCell & c ) const
724{
725 return uCell( PreCellularGridSpace::uCell( p, c ) );
726}
727//-----------------------------------------------------------------------------
728template < DGtal::Dimension dim, typename TInteger>
729inline
730typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
731DGtal::KhalimskySpaceND< dim, TInteger>::
732sCell( const SPreCell & c ) const
733{
734 return sCell( c.coordinates, c.positive ? POS : NEG );
735}
736//-----------------------------------------------------------------------------
737template < DGtal::Dimension dim, typename TInteger>
738inline
739typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
740DGtal::KhalimskySpaceND< dim, TInteger>::
741sCell( const Point & kp, Sign sign ) const
742{
743 ASSERT( cIsInside( kp ) );
744 return SCell( this->returnKCoordsHelper( kp ), sign == POS );
745}
746//-----------------------------------------------------------------------------
747template < DGtal::Dimension dim, typename TInteger>
748inline
749typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
750DGtal::KhalimskySpaceND< dim, TInteger>::
751sCell( Point p, const SPreCell & c ) const
752{
753 return sCell( PreCellularGridSpace::sCell( p, c ) );
754}
755//-----------------------------------------------------------------------------
756template < DGtal::Dimension dim, typename TInteger>
757inline
758typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
759DGtal::KhalimskySpaceND< dim, TInteger>::
760uSpel( Point p ) const
761{
762 return uCell( PreCellularGridSpace::uSpel( p ) );
763}
764//-----------------------------------------------------------------------------
765template < DGtal::Dimension dim, typename TInteger>
766inline
767typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
768DGtal::KhalimskySpaceND< dim, TInteger>::
769sSpel( Point p, Sign sign ) const
770{
771 return sCell( PreCellularGridSpace::sSpel( p, sign ) );
772}
773//-----------------------------------------------------------------------------
774template < DGtal::Dimension dim, typename TInteger>
775inline
776typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
777DGtal::KhalimskySpaceND< dim, TInteger>::
778uPointel( Point p ) const
779{
780 return uCell( PreCellularGridSpace::uPointel( p ) );
781}
782//-----------------------------------------------------------------------------
783template < DGtal::Dimension dim, typename TInteger>
784inline
785typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
786DGtal::KhalimskySpaceND< dim, TInteger>::
787sPointel( Point p, Sign sign ) const
788{
789 return sCell( PreCellularGridSpace::sPointel( p, sign ) );
790}
791//-----------------------------------------------------------------------------
792///////////////////////////////////////////////////////////////////////////////
793//-----------------------------------------------------------------------------
794template < DGtal::Dimension dim, typename TInteger>
795inline
796typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
797DGtal::KhalimskySpaceND< dim, TInteger>::
798uKCoord( const Cell & c, DGtal::Dimension k ) const
799{
800 ASSERT( uIsValid(c) );
801 return PreCellularGridSpace::uKCoord( c, k );
802}
803//-----------------------------------------------------------------------------
804template < DGtal::Dimension dim, typename TInteger>
805inline
806typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
807DGtal::KhalimskySpaceND< dim, TInteger>::
808uCoord( const Cell & c, DGtal::Dimension k ) const
809{
810 ASSERT( uIsValid(c) );
811 return PreCellularGridSpace::uCoord( c, k );
812}
813//-----------------------------------------------------------------------------
814template < DGtal::Dimension dim, typename TInteger>
815inline
816typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
817DGtal::KhalimskySpaceND< dim, TInteger>::
818uKCoords( const Cell & c ) const
819{
820 ASSERT( uIsValid(c) );
821 return PreCellularGridSpace::uKCoords( c );
822}
823//-----------------------------------------------------------------------------
824template < DGtal::Dimension dim, typename TInteger>
825inline
826typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
827DGtal::KhalimskySpaceND< dim, TInteger>::
828uCoords( const Cell & c ) const
829{
830 ASSERT( uIsValid(c) );
831 return PreCellularGridSpace::uCoords( c );
832}
833//-----------------------------------------------------------------------------
834template < DGtal::Dimension dim, typename TInteger>
835inline
836typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
837DGtal::KhalimskySpaceND< dim, TInteger>::
838interiorVoxel( const SCell & sc ) const
839{
840 ASSERT( sIsValid(sc) );
841 return PreCellularGridSpace::interiorVoxel( sc );
842}
843//-----------------------------------------------------------------------------
844template < DGtal::Dimension dim, typename TInteger>
845inline
846typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
847DGtal::KhalimskySpaceND< dim, TInteger>::
848exteriorVoxel( const SCell & sc ) const
849{
850 ASSERT( sIsValid(sc) );
851 return PreCellularGridSpace::exteriorVoxel( sc );
852}
853//-----------------------------------------------------------------------------
854template < DGtal::Dimension dim, typename TInteger>
855inline
856typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
857DGtal::KhalimskySpaceND< dim, TInteger>::
858sKCoord( const SCell & c, DGtal::Dimension k ) const
859{
860 ASSERT( sIsValid(c) );
861 return PreCellularGridSpace::sKCoord( c, k );
862}
863//-----------------------------------------------------------------------------
864template < DGtal::Dimension dim, typename TInteger>
865inline
866typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
867DGtal::KhalimskySpaceND< dim, TInteger>::
868sCoord( const SCell & c, DGtal::Dimension k ) const
869{
870 ASSERT( sIsValid(c) );
871 return PreCellularGridSpace::sCoord( c, k );
872}
873//-----------------------------------------------------------------------------
874template < DGtal::Dimension dim, typename TInteger>
875inline
876typename DGtal::KhalimskySpaceND< dim, TInteger>::Point const &
877DGtal::KhalimskySpaceND< dim, TInteger>::
878sKCoords( const SCell & c ) const
879{
880 ASSERT( sIsValid(c) );
881 return PreCellularGridSpace::sKCoords( c );
882}
883//-----------------------------------------------------------------------------
884template < DGtal::Dimension dim, typename TInteger>
885inline
886typename DGtal::KhalimskySpaceND< dim, TInteger>::Point
887DGtal::KhalimskySpaceND< dim, TInteger>::
888sCoords( const SCell & c ) const
889{
890 ASSERT( sIsValid(c) );
891 return PreCellularGridSpace::sCoords( c );
892}
893//-----------------------------------------------------------------------------
894template < DGtal::Dimension dim, typename TInteger>
895inline
896typename DGtal::KhalimskySpaceND< dim, TInteger>::Sign
897DGtal::KhalimskySpaceND< dim, TInteger>::
898sSign( const SCell & c ) const
899{
900 ASSERT( sIsValid(c) );
901 return PreCellularGridSpace::sSign( c );
902}
903//-----------------------------------------------------------------------------
904template < DGtal::Dimension dim, typename TInteger>
905inline
906typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
907DGtal::KhalimskySpaceND< dim, TInteger>::
908signs( const Cell & p, Sign s ) const
909{
910 return sCell( PreCellularGridSpace::signs( p, s ) );
911}
912//-----------------------------------------------------------------------------
913template < DGtal::Dimension dim, typename TInteger>
914inline
915typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
916DGtal::KhalimskySpaceND< dim, TInteger>::
917unsigns( const SCell & p ) const
918{
919 return uCell( PreCellularGridSpace::unsigns( p ) );
920}
921//-----------------------------------------------------------------------------
922template < DGtal::Dimension dim, typename TInteger>
923inline
924typename DGtal::KhalimskySpaceND< dim, TInteger>::SCell
925DGtal::KhalimskySpaceND< dim, TInteger>::
926sOpp( const SCell & p ) const
927{
928 return sCell( PreCellularGridSpace::sOpp( p ) );
929}
930//-----------------------------------------------------------------------------
931template < DGtal::Dimension dim, typename TInteger>
932inline
933void
934DGtal::KhalimskySpaceND< dim, TInteger>::
935uSetKCoord( Cell & c, DGtal::Dimension k, Integer i ) const
936{
937 PreCellularGridSpace::uSetKCoord( c.myPreCell, k, i );
938 this->updateCellHelper( c, k );
939 ASSERT( uIsValid(c) );
940}
941//-----------------------------------------------------------------------------
942template < DGtal::Dimension dim, typename TInteger>
943inline
944void
945DGtal::KhalimskySpaceND< dim, TInteger>::
946sSetKCoord( SCell & c, DGtal::Dimension k, Integer i ) const
947{
948 PreCellularGridSpace::sSetKCoord( c.mySPreCell, k, i );
949 this->updateSCellHelper( c, k );
950 ASSERT( sIsValid(c) );
951}
952//-----------------------------------------------------------------------------
953template < DGtal::Dimension dim, typename TInteger>
954inline
955void
956DGtal::KhalimskySpaceND< dim, TInteger>::
957uSetCoord( Cell & c, DGtal::Dimension k, Integer i ) const
958{
959 PreCellularGridSpace::uSetCoord( c.myPreCell, k, i );
960 this->updateCellHelper( c, k );
961 ASSERT( uIsValid(c) );
962}
963//-----------------------------------------------------------------------------
964template < DGtal::Dimension dim, typename TInteger>
965inline
966void
967DGtal::KhalimskySpaceND< dim, TInteger>::
968sSetCoord( SCell & c, DGtal::Dimension k, Integer i ) const
969{
970 PreCellularGridSpace::sSetCoord( c.mySPreCell, k, i );
971 this->updateSCellHelper( c, k );
972 ASSERT( sIsValid(c) );
973}
974//-----------------------------------------------------------------------------
975template < DGtal::Dimension dim, typename TInteger>
976inline
977void
978DGtal::KhalimskySpaceND< dim, TInteger>::
979uSetKCoords( Cell & c, const Point & kp ) const
980{
981 PreCellularGridSpace::uSetKCoords( c.myPreCell, kp );
982 this->updateCellHelper( c );
983 ASSERT( uIsValid(c) );
984}
985//-----------------------------------------------------------------------------
986template < DGtal::Dimension dim, typename TInteger>
987inline
988void
989DGtal::KhalimskySpaceND< dim, TInteger>::
990sSetKCoords( SCell & c, const Point & kp ) const
991{
992 PreCellularGridSpace::sSetKCoords( c.mySPreCell, kp );
993 this->updateSCellHelper( c );
994 ASSERT( sIsValid(c) );
995}
996//-----------------------------------------------------------------------------
997template < DGtal::Dimension dim, typename TInteger>
998inline
999void
1000DGtal::KhalimskySpaceND< dim, TInteger>::
1001uSetCoords( Cell & c, const Point & p ) const
1002{
1003 PreCellularGridSpace::uSetCoords( c.myPreCell, p );
1004 this->updateCellHelper( c );
1005 ASSERT( uIsValid(c) );
1006}
1007//-----------------------------------------------------------------------------
1008template < DGtal::Dimension dim, typename TInteger>
1009inline
1010void
1011DGtal::KhalimskySpaceND< dim, TInteger>::
1012sSetCoords( SCell & c, const Point & p ) const
1013{
1014 PreCellularGridSpace::sSetCoords( c.mySPreCell, p );
1015 this->updateSCellHelper( c );
1016 ASSERT( sIsValid(c) );
1017}
1018//-----------------------------------------------------------------------------
1019template < DGtal::Dimension dim, typename TInteger>
1020inline
1021void
1022DGtal::KhalimskySpaceND< dim, TInteger>::
1023sSetSign( SCell & c, Sign s ) const
1024{
1025 PreCellularGridSpace::sSetSign( c.mySPreCell, s );
1026}
1027//-----------------------------------------------------------------------------
1028// ------------------------- Cell topology services -----------------------
1029//-----------------------------------------------------------------------------
1030template < DGtal::Dimension dim, typename TInteger>
1031inline
1032TInteger
1033DGtal::KhalimskySpaceND< dim, TInteger>::
1034uTopology( const Cell & p ) const
1035{
1036 return PreCellularGridSpace::uTopology( p );
1037}
1038//-----------------------------------------------------------------------------
1039template < DGtal::Dimension dim, typename TInteger>
1040inline
1041TInteger
1042DGtal::KhalimskySpaceND< dim, TInteger>::
1043sTopology( const SCell & p ) const
1044{
1045 return PreCellularGridSpace::sTopology( p );
1046}
1047//-----------------------------------------------------------------------------
1048template < DGtal::Dimension dim, typename TInteger>
1049inline
1050DGtal::Dimension
1051DGtal::KhalimskySpaceND< dim, TInteger>::
1052uDim( const Cell & p ) const
1053{
1054 return PreCellularGridSpace::uDim( p );
1055}
1056//-----------------------------------------------------------------------------
1057template < DGtal::Dimension dim, typename TInteger>
1058inline
1059DGtal::Dimension
1060DGtal::KhalimskySpaceND< dim, TInteger>::
1061sDim( const SCell & p ) const
1062{
1063 return PreCellularGridSpace::sDim( p );
1064}
1065//-----------------------------------------------------------------------------
1066template < DGtal::Dimension dim, typename TInteger>
1067inline
1068bool
1069DGtal::KhalimskySpaceND< dim, TInteger>::
1070uIsSurfel( const Cell & b ) const
1071{
1072 return PreCellularGridSpace::uIsSurfel( b );
1073}
1074//-----------------------------------------------------------------------------
1075template < DGtal::Dimension dim, typename TInteger>
1076inline
1077bool
1078DGtal::KhalimskySpaceND< dim, TInteger>::
1079sIsSurfel( const SCell & b ) const
1080{
1081 return PreCellularGridSpace::sIsSurfel( b );
1082}
1083//-----------------------------------------------------------------------------
1084template < DGtal::Dimension dim, typename TInteger>
1085inline
1086bool
1087DGtal::KhalimskySpaceND< dim, TInteger>::
1088uIsOpen( const Cell & p, DGtal::Dimension k ) const
1089{
1090 return PreCellularGridSpace::uIsOpen( p, k );
1091}
1092//-----------------------------------------------------------------------------
1093template < DGtal::Dimension dim, typename TInteger>
1094inline
1095bool
1096DGtal::KhalimskySpaceND< dim, TInteger>::
1097sIsOpen( const SCell & p, DGtal::Dimension k ) const
1098{
1099 return PreCellularGridSpace::sIsOpen( p, k );
1100}
1101
1102//-----------------------------------------------------------------------------
1103///////////////////////////////////////////////////////////////////////////////
1104//-----------------------------------------------------------------------------
1105template < DGtal::Dimension dim, typename TInteger>
1106inline
1107typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1108DGtal::KhalimskySpaceND< dim, TInteger>::
1109uDirs( const Cell & p ) const
1110{
1111 return PreCellularGridSpace::uDirs( p );
1112}
1113//-----------------------------------------------------------------------------
1114template < DGtal::Dimension dim, typename TInteger>
1115inline
1116typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1117DGtal::KhalimskySpaceND< dim, TInteger>::
1118sDirs( const SCell & p ) const
1119{
1120 return PreCellularGridSpace::sDirs( p );
1121}
1122//-----------------------------------------------------------------------------
1123template < DGtal::Dimension dim, typename TInteger>
1124inline
1125typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1126DGtal::KhalimskySpaceND< dim, TInteger>::
1127uOrthDirs( const Cell & p ) const
1128{
1129 return PreCellularGridSpace::uOrthDirs( p );
1130}
1131//-----------------------------------------------------------------------------
1132template < DGtal::Dimension dim, typename TInteger>
1133inline
1134typename DGtal::KhalimskySpaceND< dim, TInteger>::DirIterator
1135DGtal::KhalimskySpaceND< dim, TInteger>::
1136sOrthDirs( const SCell & p ) const
1137{
1138 return PreCellularGridSpace::sOrthDirs( p );
1139}
1140//-----------------------------------------------------------------------------
1141template < DGtal::Dimension dim, typename TInteger>
1142inline
1143DGtal::Dimension
1144DGtal::KhalimskySpaceND< dim, TInteger>::
1145uOrthDir( const Cell & s ) const
1146{
1147 return PreCellularGridSpace::uOrthDir( s );
1148}
1149//-----------------------------------------------------------------------------
1150template < DGtal::Dimension dim, typename TInteger>
1151inline
1152DGtal::Dimension
1153DGtal::KhalimskySpaceND< dim, TInteger>::
1154sOrthDir( const SCell & s ) const
1155{
1156 return PreCellularGridSpace::sOrthDir( s );
1157}
1158//-----------------------------------------------------------------------------
1159///////////////////////////////////////////////////////////////////////////////
1160//-----------------------------------------------------------------------------
1161//-----------------------------------------------------------------------------
1162template < DGtal::Dimension dim, typename TInteger>
1163inline
1164typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1165DGtal::KhalimskySpaceND< dim, TInteger>::
1166uFirst( const PreCell & p, DGtal::Dimension k ) const
1167{
1168 ASSERT( k < DIM );
1169
1170 return myClosure[ k ] == OPEN ?
1171 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1172 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1173}
1174//-----------------------------------------------------------------------------
1175template < DGtal::Dimension dim, typename TInteger>
1176inline
1177typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1178DGtal::KhalimskySpaceND< dim, TInteger>::
1179uFirst( const PreCell & p ) const
1180{
1181 Cell cell;
1182 for ( Dimension k = 0; k < dimension; ++k )
1183 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uFirst( p, k ) );
1184
1185 return cell;
1186}
1187//-----------------------------------------------------------------------------
1188template < DGtal::Dimension dim, typename TInteger>
1189inline
1190typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1191DGtal::KhalimskySpaceND< dim, TInteger>::
1192uLast( const PreCell & p, DGtal::Dimension k ) const
1193{
1194 ASSERT( k < DIM );
1195
1196 return myClosure[ k ] == CLOSED ?
1197 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1198 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1199}
1200//-----------------------------------------------------------------------------
1201template < DGtal::Dimension dim, typename TInteger>
1202inline
1203typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1204DGtal::KhalimskySpaceND< dim, TInteger>::
1205uLast( const PreCell & p ) const
1206{
1207 Cell cell;
1208 for ( Dimension k = 0; k < dimension; ++k )
1209 PreCellularGridSpace::uSetKCoord( cell.myPreCell, k, uLast( p, k ) );
1210
1211 return cell;
1212}
1213//-----------------------------------------------------------------------------
1214template < DGtal::Dimension dim, typename TInteger>
1215inline
1216typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1217DGtal::KhalimskySpaceND< dim, TInteger>::
1218uGetIncr( const Cell & p, DGtal::Dimension k ) const
1219{
1220 Cell cell( PreCellularGridSpace::uGetIncr( p, k ) );
1221 this->updateCellHelper( cell, k );
1222 ASSERT( uIsValid(cell) );
1223 return cell;
1224}
1225//-----------------------------------------------------------------------------
1226template < DGtal::Dimension dim, typename TInteger>
1227inline
1228bool
1229DGtal::KhalimskySpaceND< dim, TInteger>::
1230uIsMax( const Cell & p, DGtal::Dimension k ) const
1231{
1232 ASSERT( k < DIM );
1233 ASSERT( uIsInside(p) );
1234 return
1235 ! this->isDimensionPeriodicHelper( k )
1236 && PreCellularGridSpace::uKCoord( p, k ) >= uLast( p, k );
1237}
1238//-----------------------------------------------------------------------------
1239template < DGtal::Dimension dim, typename TInteger>
1240inline
1241bool
1242DGtal::KhalimskySpaceND< dim, TInteger>::
1243uIsInside( const PreCell & p, DGtal::Dimension k ) const
1244{
1245 return cIsInside( p.coordinates, k );
1246}
1247//-----------------------------------------------------------------------------
1248template < DGtal::Dimension dim, typename TInteger>
1249inline
1250bool
1251DGtal::KhalimskySpaceND< dim, TInteger>::
1252uIsInside( const PreCell & p ) const
1253{
1254 return cIsInside( p.coordinates );
1255}
1256//-----------------------------------------------------------------------------
1257template < DGtal::Dimension dim, typename TInteger>
1258inline
1259bool
1260DGtal::KhalimskySpaceND< dim, TInteger>::
1261cIsInside( const Point & p, DGtal::Dimension k ) const
1262{
1263 ASSERT( k < DIM );
1264 return this->isDimensionPeriodicHelper( k )
1265 || cIsValid( p, k );
1266}
1267//-----------------------------------------------------------------------------
1268template < DGtal::Dimension dim, typename TInteger>
1269inline
1270bool
1271DGtal::KhalimskySpaceND< dim, TInteger>::
1272cIsInside( const Point & p ) const
1273{
1274 for ( Dimension k = 0; k < DIM; ++k )
1275 if ( ! cIsInside( p, k ) )
1276 return false;
1277
1278 return true;
1279}
1280//-----------------------------------------------------------------------------
1281template < DGtal::Dimension dim, typename TInteger>
1282inline
1283typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1284DGtal::KhalimskySpaceND< dim, TInteger>::
1285uGetMax( Cell p, DGtal::Dimension k ) const
1286{
1287 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uLast( p, k ) );
1288 ASSERT( uIsValid( p ) );
1289 return p;
1290}
1291//-----------------------------------------------------------------------------
1292template < DGtal::Dimension dim, typename TInteger>
1293inline
1294typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1295DGtal::KhalimskySpaceND< dim, TInteger>::
1296uGetDecr( const Cell & p, DGtal::Dimension k ) const
1297{
1298 Cell cell( PreCellularGridSpace::uGetDecr( p, k ) );
1299 this->updateCellHelper( cell, k );
1300 ASSERT( uIsValid( cell ) );
1301 return cell;
1302}
1303//-----------------------------------------------------------------------------
1304template < DGtal::Dimension dim, typename TInteger>
1305inline
1306bool
1307DGtal::KhalimskySpaceND< dim, TInteger>::
1308uIsMin( const Cell & p, DGtal::Dimension k ) const
1309{
1310 ASSERT( uIsInside(p) );
1311 return
1312 ! this->isDimensionPeriodicHelper( k )
1313 && PreCellularGridSpace::uKCoord( p, k ) <= uFirst( p, k );
1314}
1315//-----------------------------------------------------------------------------
1316template < DGtal::Dimension dim, typename TInteger>
1317inline
1318typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1319DGtal::KhalimskySpaceND< dim, TInteger>::
1320uGetMin( Cell p, DGtal::Dimension k ) const
1321{
1322 PreCellularGridSpace::uSetKCoord( p.myPreCell, k, uFirst( p, k ) );
1323 ASSERT( uIsValid(p) );
1324 return p;
1325}
1326//-----------------------------------------------------------------------------
1327template < DGtal::Dimension dim, typename TInteger>
1328inline
1329typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1330DGtal::KhalimskySpaceND< dim, TInteger>::
1331uGetAdd( const Cell & p, DGtal::Dimension k, Integer x ) const
1332{
1333 Cell cell( PreCellularGridSpace::uGetAdd( p, k, x ) );
1334 this->updateCellHelper( cell, k );
1335 ASSERT( uIsValid( cell ) );
1336 return cell;
1337}
1338//-----------------------------------------------------------------------------
1339template < DGtal::Dimension dim, typename TInteger>
1340inline
1341typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1342DGtal::KhalimskySpaceND< dim, TInteger>::
1343uGetSub( const Cell & p, DGtal::Dimension k, Integer x ) const
1344{
1345 Cell cell( PreCellularGridSpace::uGetSub( p, k, x ) );
1346 this->updateCellHelper( cell, k );
1347 ASSERT( uIsValid( cell ) );
1348 return cell;
1349}
1350//-----------------------------------------------------------------------------
1351template < DGtal::Dimension dim, typename TInteger>
1352inline
1353TInteger
1354DGtal::KhalimskySpaceND< dim, TInteger>::
1355uDistanceToMax( const Cell & p, DGtal::Dimension k ) const
1356{
1357 using KPS = PreCellularGridSpace;
1358 ASSERT( k < DIM );
1359 ASSERT( uIsValid(p) );
1360 return ( KPS::uKCoord( myCellUpper, k ) - KPS::uKCoord( p, k ) ) >> 1;
1361}
1362//-----------------------------------------------------------------------------
1363template < DGtal::Dimension dim, typename TInteger>
1364inline
1365TInteger
1366DGtal::KhalimskySpaceND< dim, TInteger>::
1367uDistanceToMin( const Cell & p, DGtal::Dimension k ) const
1368{
1369 using KPS = PreCellularGridSpace;
1370 ASSERT( k < DIM );
1371 ASSERT( uIsValid(p) );
1372 return ( KPS::uKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1373}
1374//-----------------------------------------------------------------------------
1375template < DGtal::Dimension dim, typename TInteger>
1376inline
1377typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1378DGtal::KhalimskySpaceND< dim, TInteger>::
1379uTranslation( const Cell & p, const Vector & vec ) const
1380{
1381 Cell cell( PreCellularGridSpace::uTranslation( p, vec ) );
1382 this->updateCellHelper( cell );
1383 ASSERT( uIsValid( cell ) );
1384 return cell;
1385}
1386//-----------------------------------------------------------------------------
1387template < DGtal::Dimension dim, typename TInteger>
1388inline
1389typename DGtal::KhalimskySpaceND< dim, TInteger>::Cell
1390DGtal::KhalimskySpaceND< dim, TInteger>::
1391uProjection( const Cell & p, const Cell & bound, DGtal::Dimension k ) const
1392{
1393 Cell cell( PreCellularGridSpace::uProjection( p, bound, k ) );
1394 ASSERT( uIsValid( cell ) );
1395 return cell;
1396}
1397//-----------------------------------------------------------------------------
1398template < DGtal::Dimension dim, typename TInteger>
1399inline
1400void
1401DGtal::KhalimskySpaceND< dim, TInteger>::
1402uProject( Cell & p, const Cell & bound, DGtal::Dimension k ) const
1403{
1404 PreCellularGridSpace::uProject( p.myPreCell, bound, k );
1405 ASSERT( uIsValid( p ) );
1406}
1407//-----------------------------------------------------------------------------
1408template < DGtal::Dimension dim, typename TInteger>
1409inline
1410bool
1411DGtal::KhalimskySpaceND< dim, TInteger>::
1412uNext( Cell & p, const Cell & lower, const Cell & upper ) const
1413{
1414 ASSERT( uIsValid(p) );
1415 ASSERT( uIsValid(lower) );
1416 ASSERT( uIsValid(upper) );
1417 ASSERT( uTopology(p) == uTopology(lower)
1418 && uTopology(p) == uTopology(upper) );
1419
1420 using KPS = PreCellularGridSpace;
1421
1422 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1423 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1424 {
1425 if ( p == upper ) return false;
1426 KPS::uProject( p.myPreCell, lower, k );
1427
1428 for ( k = 1; k < DIM; ++k )
1429 {
1430 if ( KPS::uKCoord( p, k ) == KPS::uKCoord( upper, k ) )
1431 KPS::uProject( p.myPreCell, lower, k );
1432 else
1433 {
1434 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1435 break;
1436 }
1437 }
1438 return true;
1439 }
1440
1441 KPS::uSetKCoord( p.myPreCell, k, this->returnKCoordHelper( KPS::uKCoord( p, k ) + 2, k ) );
1442 return true;
1443}
1444
1445//-----------------------------------------------------------------------------
1446///////////////////////////////////////////////////////////////////////////////
1447//-----------------------------------------------------------------------------
1448//-----------------------------------------------------------------------------
1449template < DGtal::Dimension dim, typename TInteger>
1450inline
1451typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1452DGtal::KhalimskySpaceND< dim, TInteger>::
1453sFirst( const SPreCell & p, DGtal::Dimension k ) const
1454{
1455 ASSERT( k < DIM );
1456
1457 return myClosure[ k ] == OPEN ?
1458 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1459 : 2 * myLower[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1460}
1461//-----------------------------------------------------------------------------
1462template < DGtal::Dimension dim, typename TInteger>
1463inline
1464typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1465DGtal::KhalimskySpaceND< dim, TInteger >::
1466sFirst( const SPreCell & p ) const
1467{
1468 SCell cell;
1469 for ( Dimension k = 0; k < dimension; ++k )
1470 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sFirst( p, k ) );
1471
1472 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1473
1474 return cell;
1475}
1476//-----------------------------------------------------------------------------
1477template < DGtal::Dimension dim, typename TInteger>
1478inline
1479typename DGtal::KhalimskySpaceND< dim, TInteger>::Integer
1480DGtal::KhalimskySpaceND< dim, TInteger>::
1481sLast( const SPreCell & p, DGtal::Dimension k ) const
1482{
1483 ASSERT( k < DIM );
1484 return myClosure[ k ] == CLOSED ?
1485 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 2 )
1486 : 2 * myUpper[ k ] + ( NumberTraits<Integer>::odd( p.coordinates[ k ] ) ? 1 : 0 );
1487}
1488//-----------------------------------------------------------------------------
1489template < DGtal::Dimension dim, typename TInteger>
1490inline
1491typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1492DGtal::KhalimskySpaceND< dim, TInteger >::
1493sLast( const SPreCell & p ) const
1494{
1495 SCell cell;
1496 for ( Dimension k = 0; k < dimension; ++k )
1497 PreCellularGridSpace::sSetKCoord( cell.mySPreCell, k, sLast( p, k ) );
1498
1499 PreCellularGridSpace::sSetSign( cell.mySPreCell, PreCellularGridSpace::sSign( p ) );
1500
1501 return cell;
1502}
1503//-----------------------------------------------------------------------------
1504template < DGtal::Dimension dim, typename TInteger>
1505inline
1506typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1507DGtal::KhalimskySpaceND< dim, TInteger >::
1508sGetIncr( const SCell & p, DGtal::Dimension k ) const
1509{
1510 SCell cell( PreCellularGridSpace::sGetIncr( p, k ) );
1511 this->updateSCellHelper( cell, k );
1512 ASSERT( sIsValid( cell ) );
1513 return cell;
1514}
1515//-----------------------------------------------------------------------------
1516template < DGtal::Dimension dim, typename TInteger>
1517inline
1518bool
1519DGtal::KhalimskySpaceND< dim, TInteger >::
1520sIsMax( const SCell & p, DGtal::Dimension k ) const
1521{
1522 ASSERT( k < DIM );
1523 ASSERT( sIsInside(p) );
1524 return
1525 ! this->isDimensionPeriodicHelper( k )
1526 && PreCellularGridSpace::sKCoord( p, k ) >= sLast( p, k );
1527}
1528//-----------------------------------------------------------------------------
1529template < DGtal::Dimension dim, typename TInteger>
1530inline
1531bool
1532DGtal::KhalimskySpaceND< dim, TInteger>::
1533sIsInside( const SPreCell & p, DGtal::Dimension k ) const
1534{
1535 return cIsInside( p.coordinates, k );
1536}
1537//-----------------------------------------------------------------------------
1538template < DGtal::Dimension dim, typename TInteger>
1539inline
1540bool
1541DGtal::KhalimskySpaceND< dim, TInteger>::
1542sIsInside( const SPreCell & p ) const
1543{
1544 return cIsInside( p.coordinates );
1545}
1546//-----------------------------------------------------------------------------
1547template < DGtal::Dimension dim, typename TInteger>
1548inline
1549typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1550DGtal::KhalimskySpaceND< dim, TInteger >::
1551sGetMax( SCell p, DGtal::Dimension k ) const
1552{
1553 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sLast( p, k ) );
1554 ASSERT( sIsValid( p ) );
1555 return p;
1556}
1557//-----------------------------------------------------------------------------
1558template < DGtal::Dimension dim, typename TInteger>
1559inline
1560typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1561DGtal::KhalimskySpaceND< dim, TInteger >::
1562sGetDecr( const SCell & p, DGtal::Dimension k ) const
1563{
1564 SCell cell( PreCellularGridSpace::sGetDecr( p, k ) );
1565 this->updateSCellHelper( cell, k );
1566 ASSERT( sIsValid( cell ) );
1567 return cell;
1568}
1569//-----------------------------------------------------------------------------
1570template < DGtal::Dimension dim, typename TInteger>
1571inline
1572bool
1573DGtal::KhalimskySpaceND< dim, TInteger >::
1574sIsMin( const SCell & p, DGtal::Dimension k ) const
1575{
1576 ASSERT( k < DIM );
1577 ASSERT( sIsInside(p) );
1578 return
1579 ! this->isDimensionPeriodicHelper( k )
1580 && PreCellularGridSpace::sKCoord( p, k ) <= sFirst( p, k );
1581}
1582//-----------------------------------------------------------------------------
1583template < DGtal::Dimension dim, typename TInteger>
1584inline
1585typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1586DGtal::KhalimskySpaceND< dim, TInteger >::
1587sGetMin( SCell p, DGtal::Dimension k ) const
1588{
1589 PreCellularGridSpace::sSetKCoord( p.mySPreCell, k, sFirst( p, k ) );
1590 ASSERT( sIsValid( p ) );
1591 return p;
1592}
1593//-----------------------------------------------------------------------------
1594template < DGtal::Dimension dim, typename TInteger>
1595inline
1596typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1597DGtal::KhalimskySpaceND< dim, TInteger >::
1598sGetAdd( const SCell & p, DGtal::Dimension k, Integer x ) const
1599{
1600 SCell cell( PreCellularGridSpace::sGetAdd( p, k, x ) );
1601 this->updateSCellHelper( cell, k );
1602 ASSERT( sIsValid( cell ) );
1603 return cell;
1604}
1605//-----------------------------------------------------------------------------
1606template < DGtal::Dimension dim, typename TInteger>
1607inline
1608typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1609DGtal::KhalimskySpaceND< dim, TInteger >::
1610sGetSub( const SCell & p, DGtal::Dimension k, Integer x ) const
1611{
1612 SCell cell( PreCellularGridSpace::sGetSub( p, k, x ) );
1613 this->updateSCellHelper( cell, k );
1614 ASSERT( sIsValid( cell ) );
1615 return cell;
1616}
1617//-----------------------------------------------------------------------------
1618template < DGtal::Dimension dim, typename TInteger>
1619inline
1620TInteger
1621DGtal::KhalimskySpaceND< dim, TInteger >::
1622sDistanceToMax( const SCell & p, DGtal::Dimension k ) const
1623{
1624 using KPS = PreCellularGridSpace;
1625 ASSERT( k < DIM );
1626 ASSERT( sIsValid( p ) );
1627 return ( KPS::uKCoord( myCellUpper, k ) - KPS::sKCoord( p, k ) ) >> 1;
1628}
1629//-----------------------------------------------------------------------------
1630template < DGtal::Dimension dim, typename TInteger>
1631inline
1632TInteger
1633DGtal::KhalimskySpaceND< dim, TInteger >::
1634sDistanceToMin( const SCell & p, DGtal::Dimension k ) const
1635{
1636 using KPS = PreCellularGridSpace;
1637 ASSERT( k < DIM );
1638 ASSERT( sIsValid( p ) );
1639 return ( KPS::sKCoord( p, k ) - KPS::uKCoord( myCellLower, k ) ) >> 1;
1640}
1641//-----------------------------------------------------------------------------
1642template < DGtal::Dimension dim, typename TInteger>
1643inline
1644typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1645DGtal::KhalimskySpaceND< dim, TInteger >::
1646sTranslation( const SCell & p, const Vector & vec ) const
1647{
1648 SCell cell( PreCellularGridSpace::sTranslation( p, vec ) );
1649 this->updateSCellHelper( cell );
1650 ASSERT( sIsValid( cell ) );
1651 return cell;
1652}
1653//-----------------------------------------------------------------------------
1654template < DGtal::Dimension dim, typename TInteger>
1655inline
1656typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1657DGtal::KhalimskySpaceND< dim, TInteger >::
1658sProjection( const SCell & p, const SCell & bound, DGtal::Dimension k ) const
1659{
1660 SCell cell( PreCellularGridSpace::sProjection( p, bound, k ) );
1661 ASSERT( sIsValid( cell ) );
1662 return cell;
1663}
1664//-----------------------------------------------------------------------------
1665template < DGtal::Dimension dim, typename TInteger>
1666inline
1667void
1668DGtal::KhalimskySpaceND< dim, TInteger >::
1669sProject( SCell & p, const SCell & bound, DGtal::Dimension k ) const
1670{
1671 PreCellularGridSpace::sProject( p.mySPreCell, bound, k );
1672 ASSERT( sIsValid( p ) );
1673}
1674//-----------------------------------------------------------------------------
1675template < DGtal::Dimension dim, typename TInteger>
1676inline
1677bool
1678DGtal::KhalimskySpaceND< dim, TInteger >::
1679sNext( SCell & p, const SCell & lower, const SCell & upper ) const
1680{
1681 ASSERT( sIsValid(p) );
1682 ASSERT( sIsValid(lower) );
1683 ASSERT( sIsValid(upper) );
1684 ASSERT( sTopology(p) == sTopology(lower)
1685 && sTopology(p) == sTopology(upper) );
1686
1687 using KPS = PreCellularGridSpace;
1688
1689 DGtal::Dimension k = NumberTraits<Dimension>::ZERO;
1690 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1691 {
1692 if ( p == upper ) return false;
1693 KPS::sProject( p.mySPreCell, lower, k );
1694
1695 for ( k = 1; k < DIM; ++k )
1696 {
1697 if ( KPS::sKCoord( p, k ) == KPS::sKCoord( upper, k ) )
1698 KPS::sProject( p.mySPreCell, lower, k );
1699 else
1700 {
1701 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1702 break;
1703 }
1704 }
1705 return true;
1706 }
1707
1708 KPS::sSetKCoord( p.mySPreCell, k, this->returnKCoordHelper( KPS::sKCoord( p, k ) + 2, k ) );
1709 return true;
1710}
1711
1712//-----------------------------------------------------------------------------
1713// ----------------------- Neighborhood services --------------------------
1714//-----------------------------------------------------------------------------
1715template < DGtal::Dimension dim, typename TInteger>
1716inline
1717typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1718DGtal::KhalimskySpaceND< dim, TInteger >::
1719uNeighborhood( const Cell & c ) const
1720{
1721 ASSERT( uIsValid(c) );
1722
1723 Cells N;
1724 N.push_back( c );
1725 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1726 {
1727 if ( ! uIsMin( c, k ) )
1728 N.push_back( uGetDecr( c, k ) );
1729 if ( ! uIsMax( c, k ) )
1730 N.push_back( uGetIncr( c, k ) );
1731 }
1732 return N;
1733}
1734//-----------------------------------------------------------------------------
1735template < DGtal::Dimension dim, typename TInteger>
1736inline
1737typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1738DGtal::KhalimskySpaceND< dim, TInteger >::
1739sNeighborhood( const SCell & c ) const
1740{
1741 ASSERT( sIsValid(c) );
1742
1743 SCells N;
1744 N.push_back( c );
1745 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1746 {
1747 if ( ! sIsMin( c, k ) )
1748 N.push_back( sGetDecr( c, k ) );
1749 if ( ! sIsMax( c, k ) )
1750 N.push_back( sGetIncr( c, k ) );
1751 }
1752 return N;
1753}
1754//-----------------------------------------------------------------------------
1755template < DGtal::Dimension dim, typename TInteger>
1756inline
1757typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1758DGtal::KhalimskySpaceND< dim, TInteger >::
1759uProperNeighborhood( const Cell & c ) const
1760{
1761 ASSERT( uIsValid(c) );
1762
1763 Cells N;
1764 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1765 {
1766 if ( ! uIsMin( c, k ) )
1767 N.push_back( uGetDecr( c, k ) );
1768 if ( ! uIsMax( c, k ) )
1769 N.push_back( uGetIncr( c, k ) );
1770 }
1771 return N;
1772}
1773//-----------------------------------------------------------------------------
1774template < DGtal::Dimension dim, typename TInteger>
1775inline
1776typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1777DGtal::KhalimskySpaceND< dim, TInteger >::
1778sProperNeighborhood( const SCell & c ) const
1779{
1780 ASSERT( sIsValid(c) );
1781
1782 SCells N;
1783 for ( DGtal::Dimension k = 0; k < DIM; ++k )
1784 {
1785 if ( ! sIsMin( c, k ) )
1786 N.push_back( sGetDecr( c, k ) );
1787 if ( ! sIsMax( c, k ) )
1788 N.push_back( sGetIncr( c, k ) );
1789 }
1790 return N;
1791}
1792//-----------------------------------------------------------------------------
1793template < DGtal::Dimension dim, typename TInteger>
1794inline
1795typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1796DGtal::KhalimskySpaceND< dim, TInteger >::
1797uAdjacent( const Cell & p, DGtal::Dimension k, bool up ) const
1798{
1799 ASSERT( k < DIM );
1800 ASSERT( uIsValid(p) );
1801 ASSERT( ( up && !uIsMax(p, k) ) || ( !up && !uIsMin(p, k) ) );
1802 return up ? uGetIncr( p, k ) : uGetDecr( p, k );
1803}
1804//-----------------------------------------------------------------------------
1805template < DGtal::Dimension dim, typename TInteger>
1806inline
1807typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1808DGtal::KhalimskySpaceND< dim, TInteger >::
1809sAdjacent( const SCell & p, DGtal::Dimension k, bool up ) const
1810{
1811 ASSERT( k < DIM );
1812 ASSERT( sIsValid(p) );
1813 ASSERT( ( up && !sIsMax(p, k) ) || ( !up && !sIsMin(p, k) ) );
1814 return up ? sGetIncr( p, k ) : sGetDecr( p, k );
1815}
1816
1817// ----------------------- Incidence services --------------------------
1818//-----------------------------------------------------------------------------
1819template < DGtal::Dimension dim, typename TInteger>
1820inline
1821typename DGtal::KhalimskySpaceND< dim, TInteger >::Cell
1822DGtal::KhalimskySpaceND< dim, TInteger >::
1823uIncident( const Cell & c, DGtal::Dimension k, bool up ) const
1824{
1825 ASSERT( k < dim );
1826 ASSERT( uIsValid(c) );
1827 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( uKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1828 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < uKCoord( c, k ) ) );
1829
1830 Cell cell( PreCellularGridSpace::uIncident( c, k, up ) );
1831 this->updateCellHelper( cell, k );
1832
1833 return cell;
1834}
1835//-----------------------------------------------------------------------------
1836template < DGtal::Dimension dim, typename TInteger>
1837inline
1838typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
1839DGtal::KhalimskySpaceND< dim, TInteger >::
1840sIncident( const SCell & c, DGtal::Dimension k, bool up ) const
1841{
1842 ASSERT( k < dim );
1843 ASSERT( sIsValid(c) );
1844 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! up ) || ( sKCoord( c, k ) < uKCoord( myCellUpper, k ) ) );
1845 ASSERT( this->isDimensionPeriodicHelper( k ) || ( up ) || ( uKCoord( myCellLower, k ) < sKCoord( c, k ) ) );
1846
1847 SCell cell( PreCellularGridSpace::sIncident( c, k, up ) );
1848 this->updateSCellHelper( cell, k );
1849
1850 return cell;
1851}
1852//-----------------------------------------------------------------------------
1853template < DGtal::Dimension dim, typename TInteger>
1854inline
1855typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1856DGtal::KhalimskySpaceND< dim, TInteger >::
1857uLowerIncident( const Cell & c ) const
1858{
1859 ASSERT( uIsValid(c) );
1860
1861 Cells N;
1862 for ( DirIterator q = uDirs( c ); q != 0; ++q )
1863 {
1864 const DGtal::Dimension k = *q;
1865 if ( this->isDimensionPeriodicHelper( k ) )
1866 {
1867 N.push_back( uIncident( c, k, false ) );
1868 N.push_back( uIncident( c, k, true ) );
1869 }
1870 else
1871 {
1872 const Integer x = uKCoord( c, k );
1873 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1874 N.push_back( uIncident( c, k, false ) );
1875 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1876 N.push_back( uIncident( c, k, true ) );
1877 }
1878 }
1879 return N;
1880}
1881//-----------------------------------------------------------------------------
1882template < DGtal::Dimension dim, typename TInteger>
1883inline
1884typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
1885DGtal::KhalimskySpaceND< dim, TInteger >::
1886uUpperIncident( const Cell & c ) const
1887{
1888 ASSERT( uIsValid(c) );
1889
1890 Cells N;
1891 for ( DirIterator q = uOrthDirs( c ); q != 0; ++q )
1892 {
1893 const DGtal::Dimension k = *q;
1894 if ( this->isDimensionPeriodicHelper( k ) )
1895 {
1896 N.push_back( uIncident( c, k, false ) );
1897 N.push_back( uIncident( c, k, true ) );
1898 }
1899 else
1900 {
1901 const Integer x = uKCoord( c, k );
1902 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1903 N.push_back( uIncident( c, k, false ) );
1904 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1905 N.push_back( uIncident( c, k, true ) );
1906 }
1907 }
1908 return N;
1909}
1910//-----------------------------------------------------------------------------
1911template < DGtal::Dimension dim, typename TInteger>
1912inline
1913typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1914DGtal::KhalimskySpaceND< dim, TInteger >::
1915sLowerIncident( const SCell & c ) const
1916{
1917 ASSERT( sIsValid(c) );
1918
1919 SCells N;
1920 for ( DirIterator q = sDirs( c ); q != 0; ++q )
1921 {
1922 const DGtal::Dimension k = *q;
1923 if ( this->isDimensionPeriodicHelper( k ) )
1924 {
1925 N.push_back( sIncident( c, k, false ) );
1926 N.push_back( sIncident( c, k, true ) );
1927 }
1928 else
1929 {
1930 const Integer x = sKCoord( c, k );
1931 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1932 N.push_back( sIncident( c, k, false ) );
1933 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1934 N.push_back( sIncident( c, k, true ) );
1935 }
1936 }
1937 return N;
1938}
1939//-----------------------------------------------------------------------------
1940template < DGtal::Dimension dim, typename TInteger>
1941inline
1942typename DGtal::KhalimskySpaceND< dim, TInteger >::SCells
1943DGtal::KhalimskySpaceND< dim, TInteger >::
1944sUpperIncident( const SCell & c ) const
1945{
1946 ASSERT( sIsValid(c) );
1947
1948 SCells N;
1949 for ( DirIterator q = sOrthDirs( c ); q != 0; ++q )
1950 {
1951 const DGtal::Dimension k = *q;
1952 if ( this->isDimensionPeriodicHelper( k ) )
1953 {
1954 N.push_back( sIncident( c, k, false ) );
1955 N.push_back( sIncident( c, k, true ) );
1956 }
1957 else
1958 {
1959 const Integer x = sKCoord( c, k );
1960 if ( PreCellularGridSpace::uKCoord( myCellLower, k ) < x )
1961 N.push_back( sIncident( c, k, false ) );
1962 if ( x < PreCellularGridSpace::uKCoord( myCellUpper, k ) )
1963 N.push_back( sIncident( c, k, true ) );
1964 }
1965 }
1966 return N;
1967}
1968//-----------------------------------------------------------------------------
1969template < DGtal::Dimension dim, typename TInteger>
1970inline
1971void
1972DGtal::KhalimskySpaceND< dim, TInteger >::
1973uAddFaces( Cells& faces, const Cell& c, Dimension axis ) const
1974{
1975 using KPS = PreCellularGridSpace;
1976
1977 const DGtal::Dimension dim_of_c = uDim( c );
1978 if ( axis >= dim_of_c ) return;
1979
1980 DirIterator q = uDirs( c );
1981 for ( Dimension i = 0; i < axis; ++i ) ++q;
1982
1983 // We test incident cells existence within the current Khalimsky space.
1984 const Integer x = KPS::uKCoord( c, *q );
1985 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
1986 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
1987
1988 Cell f1, f2;
1989 if ( has_f1 ) f1 = uIncident( c, *q, false );
1990 if ( has_f2 ) f2 = uIncident( c, *q, true );
1991
1992 if ( has_f1 ) faces.push_back( f1 );
1993 if ( has_f2 ) faces.push_back( f2 );
1994
1995 if ( has_f1 ) uAddFaces( faces, f1, axis );
1996 if ( has_f2 ) uAddFaces( faces, f2, axis );
1997
1998 uAddFaces( faces, c, axis+1 );
1999}
2000//-----------------------------------------------------------------------------
2001template < DGtal::Dimension dim, typename TInteger>
2002inline
2003void
2004DGtal::KhalimskySpaceND< dim, TInteger >::
2005uAddCoFaces( Cells& cofaces, const Cell& c, Dimension axis ) const
2006{
2007 using KPS = PreCellularGridSpace;
2008
2009 const DGtal::Dimension dim_of_c = uDim( c );
2010 if ( axis >= dimension - dim_of_c ) return;
2011
2012 DirIterator q = uOrthDirs( c );
2013 for ( Dimension i = 0; i < axis; ++i ) ++q;
2014
2015 // We test incident cells existence within the current Khalimsky space.
2016 const Integer x = KPS::uKCoord( c, *q );
2017 bool has_f1 = this->isDimensionPeriodicHelper( *q ) || KPS::uKCoord( myCellLower, *q ) < x ;
2018 bool has_f2 = this->isDimensionPeriodicHelper( *q ) || x < KPS::uKCoord( myCellUpper, *q ) ;
2019
2020 Cell f1, f2;
2021 if ( has_f1 ) f1 = uIncident( c, *q, false );
2022 if ( has_f2 ) f2 = uIncident( c, *q, true );
2023
2024 if ( has_f1 ) cofaces.push_back( f1 );
2025 if ( has_f2 ) cofaces.push_back( f2 );
2026
2027 if ( has_f1 ) uAddCoFaces( cofaces, f1, axis );
2028 if ( has_f2 ) uAddCoFaces( cofaces, f2, axis );
2029
2030 uAddCoFaces( cofaces, c, axis+1 );
2031}
2032//-----------------------------------------------------------------------------
2033template < DGtal::Dimension dim, typename TInteger>
2034inline
2035typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2036DGtal::KhalimskySpaceND< dim, TInteger >::
2037uFaces( const Cell & c ) const
2038{
2039 ASSERT( uIsValid(c) );
2040
2041 Cells N;
2042 uAddFaces( N, c, 0 );
2043 return N;
2044}
2045//-----------------------------------------------------------------------------
2046template < DGtal::Dimension dim, typename TInteger>
2047inline
2048typename DGtal::KhalimskySpaceND< dim, TInteger >::Cells
2049DGtal::KhalimskySpaceND< dim, TInteger >::
2050uCoFaces( const Cell & c ) const
2051{
2052 ASSERT( uIsValid(c) );
2053
2054 Cells N;
2055 uAddCoFaces( N, c, 0 );
2056 return N;
2057}
2058//-----------------------------------------------------------------------------
2059template < DGtal::Dimension dim, typename TInteger>
2060inline
2061bool
2062DGtal::KhalimskySpaceND< dim, TInteger >::
2063sDirect( const SCell & p, DGtal::Dimension k ) const
2064{
2065 return PreCellularGridSpace::sDirect( p, k );
2066}
2067//-----------------------------------------------------------------------------
2068template < DGtal::Dimension dim, typename TInteger>
2069inline
2070typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2071DGtal::KhalimskySpaceND< dim, TInteger >::
2072sDirectIncident( const SCell & p, DGtal::Dimension k ) const
2073{
2074 using KPS = PreCellularGridSpace;
2075
2076 ASSERT( k < dim );
2077 ASSERT( sIsValid(p) );
2078 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2079 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2080
2081 SCell cell( KPS::sDirectIncident( p, k ) );
2082 this->updateSCellHelper( cell, k );
2083
2084 return cell;
2085}
2086//-----------------------------------------------------------------------------
2087template < DGtal::Dimension dim, typename TInteger>
2088inline
2089typename DGtal::KhalimskySpaceND< dim, TInteger >::SCell
2090DGtal::KhalimskySpaceND< dim, TInteger >::
2091sIndirectIncident( const SCell & p, DGtal::Dimension k ) const
2092{
2093 using KPS = PreCellularGridSpace;
2094
2095 ASSERT( k < dim );
2096 ASSERT( sIsValid(p) );
2097 ASSERT( this->isDimensionPeriodicHelper( k ) || ( KPS::sDirect( p, k ) ) || ( KPS::sKCoord( p, k ) < KPS::uKCoord( myCellUpper, k ) ) );
2098 ASSERT( this->isDimensionPeriodicHelper( k ) || ( ! KPS::sDirect( p, k ) ) || ( KPS::uKCoord( myCellLower, k ) < KPS::sKCoord( p, k ) ) );
2099
2100 SCell cell( KPS::sIndirectIncident( p, k ) );
2101 this->updateSCellHelper( cell, k );
2102
2103 return cell;
2104}
2105
2106
2107
2108
2109//-----------------------------------------------------------------------------
2110template < DGtal::Dimension dim, typename TInteger>
2111inline
2112void
2113DGtal::KhalimskySpaceND< dim, TInteger>::
2114selfDisplay ( std::ostream & out ) const
2115{
2116 out << "[KhalimskySpaceND<" << dimension << ">] { ";
2117 out << "{ ";
2118 for ( Dimension i = 0; i < dimension; ++i )
2119 out << ( myClosure[i] == OPEN ? "OPEN " : ( myClosure[i] == CLOSED ? "CLOSED " : "PERIODIC " ) );
2120 out << "}, ";
2121 out << "lower = " << myLower << ", ";
2122 out << "upper = " << myUpper;
2123 out << " }";
2124
2125}
2126//-----------------------------------------------------------------------------
2127template < DGtal::Dimension dim, typename TInteger>
2128inline
2129bool
2130DGtal::KhalimskySpaceND< dim, TInteger>::
2131isValid() const
2132{
2133 return true;
2134}
2135
2136
2137
2138///////////////////////////////////////////////////////////////////////////////
2139// Implementation of inline functions //
2140template < DGtal::Dimension dim, typename TInteger>
2141inline
2142std::ostream&
2143DGtal::operator<< ( std::ostream & out,
2144 const KhalimskySpaceND< dim, TInteger> & object )
2145{
2146 object.selfDisplay( out );
2147 return out;
2148}
2149
2150// //
2151///////////////////////////////////////////////////////////////////////////////