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.
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.
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/>.
18 * @file CubicalComplex.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in CubicalComplex.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
33 #include "DGtal/base/SetFunctions.h"
34 #include "DGtal/topology/CubicalComplexFunctions.h"
35 //////////////////////////////////////////////////////////////////////////////
37 ///////////////////////////////////////////////////////////////////////////////
38 // IMPLEMENTATION of inline methods.
39 ///////////////////////////////////////////////////////////////////////////////
41 ///////////////////////////////////////////////////////////////////////////////
42 // ----------------------- Standard services ------------------------------
44 //-----------------------------------------------------------------------------
45 template <typename TKSpace, typename TCellContainer>
47 DGtal::CubicalComplex<TKSpace, TCellContainer>::
52 //-----------------------------------------------------------------------------
53 template <typename TKSpace, typename TCellContainer>
55 DGtal::CubicalComplex<TKSpace, TCellContainer>::
57 : myKSpace( 0 ), myCells( dimension+1 )
61 //-----------------------------------------------------------------------------
62 template <typename TKSpace, typename TCellContainer>
64 DGtal::CubicalComplex<TKSpace, TCellContainer>::
65 CubicalComplex( ConstAlias<KSpace> aK )
66 : myKSpace( &aK ), myCells( dimension+1 )
70 //-----------------------------------------------------------------------------
71 template <typename TKSpace, typename TCellContainer>
73 DGtal::CubicalComplex<TKSpace, TCellContainer>::
74 CubicalComplex( const CubicalComplex& other )
75 : myKSpace( other.myKSpace ), myCells( other.myCells )
79 //-----------------------------------------------------------------------------
80 template <typename TKSpace, typename TCellContainer>
81 template <typename TDigitalSet>
83 void DGtal::CubicalComplex<TKSpace, TCellContainer>::
84 construct( const TDigitalSet & set )
86 assert ( TDigitalSet::Domain::dimension == dimension );
87 for ( typename TDigitalSet::ConstIterator it = set.begin(); it != set.end(); ++it )
89 typedef typename TKSpace::Cells CellsCollection;
90 typename TKSpace::Cell cell = myKSpace->uSpel ( *it );
92 CellsCollection n = myKSpace->uFaces ( cell );
93 for ( typename CellsCollection::ConstIterator itt = n.begin() ; itt < n.end(); ++itt )
98 //-----------------------------------------------------------------------------
99 template <typename TKSpace, typename TCellContainer>
101 const typename DGtal::CubicalComplex<TKSpace, TCellContainer>::KSpace &
102 DGtal::CubicalComplex<TKSpace, TCellContainer>::
108 //-----------------------------------------------------------------------------
109 template <typename TKSpace, typename TCellContainer>
111 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::ConstIterator
112 DGtal::CubicalComplex<TKSpace, TCellContainer>::
115 return ConstIterator( *this, 0 );
118 //-----------------------------------------------------------------------------
119 template <typename TKSpace, typename TCellContainer>
121 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::ConstIterator
122 DGtal::CubicalComplex<TKSpace, TCellContainer>::
125 return ConstIterator( *this, dimension+1 );
128 //-----------------------------------------------------------------------------
129 template <typename TKSpace, typename TCellContainer>
131 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator
132 DGtal::CubicalComplex<TKSpace, TCellContainer>::
135 return Iterator( *this, 0 );
138 //-----------------------------------------------------------------------------
139 template <typename TKSpace, typename TCellContainer>
141 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator
142 DGtal::CubicalComplex<TKSpace, TCellContainer>::
145 return Iterator( *this, dimension+1 );
148 //-----------------------------------------------------------------------------
149 template <typename TKSpace, typename TCellContainer>
151 DGtal::CubicalComplex<TKSpace, TCellContainer>&
152 DGtal::CubicalComplex<TKSpace, TCellContainer>::
153 operator=( const CubicalComplex& other )
155 if ( this != &other )
157 myKSpace = other.myKSpace;
158 myCells = other.myCells;
163 //-----------------------------------------------------------------------------
164 template <typename TKSpace, typename TCellContainer>
167 DGtal::CubicalComplex<TKSpace, TCellContainer>::
170 for ( Dimension d = 0; d <= dimension; ++d )
174 //-----------------------------------------------------------------------------
175 template <typename TKSpace, typename TCellContainer>
177 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
178 DGtal::CubicalComplex<TKSpace, TCellContainer>::
179 count( const Cell& aCell ) const
181 return belongs( aCell ) ? 1 : 0;
184 //-----------------------------------------------------------------------------
185 template <typename TKSpace, typename TCellContainer>
188 DGtal::CubicalComplex<TKSpace, TCellContainer>::
191 myCells[ d ].clear();
193 //-----------------------------------------------------------------------------
194 template <typename TKSpace, typename TCellContainer>
197 DGtal::CubicalComplex<TKSpace, TCellContainer>::
198 fillData( Data data )
200 for ( Dimension d = 0; d <= dimension; ++d )
203 //-----------------------------------------------------------------------------
204 template <typename TKSpace, typename TCellContainer>
207 DGtal::CubicalComplex<TKSpace, TCellContainer>::
208 fillData( Dimension d, Data data )
210 ASSERT( d <= dimension );
211 for ( CellMapIterator it = begin( d ), itE = end( d ); it != itE; ++it )
217 //-----------------------------------------------------------------------------
218 template <typename TKSpace, typename TCellContainer>
221 DGtal::CubicalComplex<TKSpace, TCellContainer>::
224 Dimension d = static_cast<Dimension>((int)myCells.size()-1);
225 for ( typename std::vector<CellMap>::const_reverse_iterator it = myCells.rbegin(), itE = myCells.rend();
226 it != itE; ++it, --d )
227 if ( ! it->empty() ) return d;
230 //-----------------------------------------------------------------------------
231 template <typename TKSpace, typename TCellContainer>
234 DGtal::CubicalComplex<TKSpace, TCellContainer>::
235 dim( const Cell& c ) const
237 return myKSpace->uDim( c );
240 //-----------------------------------------------------------------------------
241 template <typename TKSpace, typename TCellContainer>
243 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
244 DGtal::CubicalComplex<TKSpace, TCellContainer>::
245 nbCells( Dimension d ) const
247 return static_cast<Size>(myCells[ d ].size());
250 //-----------------------------------------------------------------------------
251 template <typename TKSpace, typename TCellContainer>
253 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
254 DGtal::CubicalComplex<TKSpace, TCellContainer>::
258 for ( Dimension d = 0; d <= dimension; ++d )
259 n += myCells[ d ].size();
262 //-----------------------------------------------------------------------------
263 template <typename TKSpace, typename TCellContainer>
265 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
266 DGtal::CubicalComplex<TKSpace, TCellContainer>::
270 Point p = space().uKCoords( space().upperCell() )
271 - space().uKCoords( space().lowerCell() );
272 Size n = (Size) p.norm( Point::L_1 );
276 //-----------------------------------------------------------------------------
277 template <typename TKSpace, typename TCellContainer>
280 DGtal::CubicalComplex<TKSpace, TCellContainer>::
283 for ( Dimension d = 0; d <= dimension; ++d )
284 if ( ! myCells[ d ].empty() ) return false;
288 //-----------------------------------------------------------------------------
289 template <typename TKSpace, typename TCellContainer>
291 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Integer
292 DGtal::CubicalComplex<TKSpace, TCellContainer>::
297 for ( typename std::vector<CellMap>::const_iterator it = myCells.begin(), itE = myCells.end();
300 n += pos ? (Integer) it->size() : -(Integer) it->size();
306 //-----------------------------------------------------------------------------
307 template <typename TKSpace, typename TCellContainer>
309 std::pair< typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator,
310 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator >
311 DGtal::CubicalComplex<TKSpace, TCellContainer>::
312 equal_range( const Cell& aCell )
314 Dimension d = myKSpace->uDim( aCell );
315 std::pair< CellMapIterator, CellMapIterator > pIt
316 = myCells[ d ].equal_range( aCell );
317 return std::make_pair( Iterator( *this, d, pIt->first ),
318 Iterator( *this, d, pIt->second ) );
321 //-----------------------------------------------------------------------------
322 template <typename TKSpace, typename TCellContainer>
324 std::pair< typename DGtal::CubicalComplex<TKSpace, TCellContainer>::ConstIterator,
325 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::ConstIterator >
326 DGtal::CubicalComplex<TKSpace, TCellContainer>::
327 equal_range( const Cell& aCell ) const
329 Dimension d = myKSpace->uDim( aCell );
330 std::pair< CellMapConstIterator, CellMapConstIterator > pIt
331 = myCells[ d ].equal_range( aCell );
332 return std::make_pair( ConstIterator( *this, d, pIt->first ),
333 ConstIterator( *this, d, pIt->second ) );
336 //-----------------------------------------------------------------------------
337 template <typename TKSpace, typename TCellContainer>
340 DGtal::CubicalComplex<TKSpace, TCellContainer>::
343 eraseCell( it.myIt );
346 //-----------------------------------------------------------------------------
347 template <typename TKSpace, typename TCellContainer>
349 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
350 DGtal::CubicalComplex<TKSpace, TCellContainer>::
351 erase( const Cell& aCell )
353 return eraseCell( aCell );
356 //-----------------------------------------------------------------------------
357 template <typename TKSpace, typename TCellContainer>
360 DGtal::CubicalComplex<TKSpace, TCellContainer>::
361 erase( Iterator first, Iterator last )
363 while ( first != last )
365 Iterator tmp = first++;
370 //-----------------------------------------------------------------------------
371 template <typename TKSpace, typename TCellContainer>
373 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator
374 DGtal::CubicalComplex<TKSpace, TCellContainer>::
375 find( const Cell& aCell )
377 Dimension d = myKSpace->uDim( aCell );
378 CellMapIterator cmIt = findCell( d, aCell );
379 if ( cmIt == end( d ) ) return Iterator( *this, d+1 );
380 else return Iterator( *this, d, cmIt );
383 //-----------------------------------------------------------------------------
384 template <typename TKSpace, typename TCellContainer>
386 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::ConstIterator
387 DGtal::CubicalComplex<TKSpace, TCellContainer>::
388 find( const Cell& aCell ) const
390 Dimension d = myKSpace->uDim( aCell );
391 CellMapConstIterator cmIt = findCell( d, aCell );
392 if ( cmIt == end( d ) ) return ConstIterator( *this, d+1 );
393 else return ConstIterator( *this, d, cmIt );
396 //-----------------------------------------------------------------------------
397 template <typename TKSpace, typename TCellContainer>
399 std::pair< typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator,
401 DGtal::CubicalComplex<TKSpace, TCellContainer>::
402 insert( const Cell& aCell )
404 Dimension d = myKSpace->uDim( aCell );
405 std::pair< CellMapIterator,bool > pIt
406 = myCells[ d ].insert( std::make_pair( aCell, Data() ) );
407 return ( pIt.first == myCells[ d ].end() )
408 ? std::make_pair( Iterator( *this, dimension+1 ), false )
409 : std::make_pair( Iterator( *this, d, pIt.first ), pIt.second );
412 //-----------------------------------------------------------------------------
413 template <typename TKSpace, typename TCellContainer>
415 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Iterator
416 DGtal::CubicalComplex<TKSpace, TCellContainer>::
417 insert( Iterator position, const Cell& aCell )
419 Dimension d = myKSpace->uDim( aCell );
420 if ( position.dimension() == d )
421 return Iterator( *this, d,
422 myCells[ d ].insert( position.myIt,
423 std::make_pair( aCell, Data() ) ) );
425 return Iterator( *this, d,
426 myCells[ d ].insert( std::make_pair( aCell, Data() ) ).first );
428 //-----------------------------------------------------------------------------
429 template <typename TKSpace, typename TCellContainer>
430 template <class InputIterator>
433 DGtal::CubicalComplex<TKSpace, TCellContainer>::
434 insert( InputIterator first, InputIterator last )
436 for ( ; first != last; ++first )
440 //-----------------------------------------------------------------------------
441 template <typename TKSpace, typename TCellContainer>
444 DGtal::CubicalComplex<TKSpace, TCellContainer>::
445 swap( CubicalComplex& other )
447 if ( other != *this )
448 { // Swap space with special care of invalid complexes.
449 if ( myKSpace == 0 ) myKSpace = other.myKSpace;
450 else if ( other.myKSpace == 0 ) other.myKSpace = myKSpace;
451 else std::swap( myKSpace, other.myKSpace );
452 myCells.swap( other.myCells );
457 //-----------------------------------------------------------------------------
458 template <typename TKSpace, typename TCellContainer>
460 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Data&
461 DGtal::CubicalComplex<TKSpace, TCellContainer>::
462 operator[]( const Cell& aCell )
464 Dimension d = space().uDim( aCell );
465 return myCells[ d ][ aCell ];
468 //-----------------------------------------------------------------------------
469 template <typename TKSpace, typename TCellContainer>
472 DGtal::CubicalComplex<TKSpace, TCellContainer>::
473 operator()( const Cell& aCell ) const
475 Dimension d = space().uDim( aCell );
476 return findCell( d, aCell ) != end( d );
479 //-----------------------------------------------------------------------------
480 template <typename TKSpace, typename TCellContainer>
483 DGtal::CubicalComplex<TKSpace, TCellContainer>::
484 insertCell( const Cell& aCell, const Data& data )
486 insertCell( myKSpace->uDim( aCell ), aCell, data );
488 //-----------------------------------------------------------------------------
489 template <typename TKSpace, typename TCellContainer>
492 DGtal::CubicalComplex<TKSpace, TCellContainer>::
493 insertCell( Dimension d, const Cell& aCell, const Data& data )
495 myCells[ d ][ aCell ] = data;
498 //-----------------------------------------------------------------------------
499 template <typename TKSpace, typename TCellContainer>
500 template <typename CellConstIterator>
503 DGtal::CubicalComplex<TKSpace, TCellContainer>::
504 insertCells( CellConstIterator it, CellConstIterator itE, const Data& data )
506 for ( ; it != itE; ++it )
507 insertCell( *it, data );
510 //-----------------------------------------------------------------------------
511 template <typename TKSpace, typename TCellContainer>
512 template <typename CellConstIterator>
515 DGtal::CubicalComplex<TKSpace, TCellContainer>::
516 insertCells( Dimension d, CellConstIterator it, CellConstIterator itE, const Data& data )
518 for ( ; it != itE; ++it )
519 insertCell( d, *it, data );
522 //-----------------------------------------------------------------------------
523 template <typename TKSpace, typename TCellContainer>
525 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
526 DGtal::CubicalComplex<TKSpace, TCellContainer>::
527 eraseCell( const Cell& aCell )
529 return eraseCell( myKSpace->uDim( aCell ), aCell );
532 //-----------------------------------------------------------------------------
533 template <typename TKSpace, typename TCellContainer>
535 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
536 DGtal::CubicalComplex<TKSpace, TCellContainer>::
537 eraseCell( Dimension d, const Cell& aCell )
539 return (Size) myCells[ d ].erase( aCell );
542 //-----------------------------------------------------------------------------
543 template <typename TKSpace, typename TCellContainer>
546 DGtal::CubicalComplex<TKSpace, TCellContainer>::
547 eraseCell( CellMapIterator it )
549 Dimension d = myKSpace->uDim( it->first );
550 myCells[ d ].erase( it );
553 //-----------------------------------------------------------------------------
554 template <typename TKSpace, typename TCellContainer>
557 DGtal::CubicalComplex<TKSpace, TCellContainer>::
558 eraseCells( CellMapIterator it, CellMapIterator itE )
560 for ( ; it != itE; ++it )
564 //-----------------------------------------------------------------------------
565 template <typename TKSpace, typename TCellContainer>
566 template <typename CellConstIterator>
568 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
569 DGtal::CubicalComplex<TKSpace, TCellContainer>::
570 eraseCells( CellConstIterator it, CellConstIterator itE )
573 for ( ; it != itE; ++it )
574 nb += eraseCell( *it );
577 //-----------------------------------------------------------------------------
578 template <typename TKSpace, typename TCellContainer>
579 template <typename CellConstIterator>
581 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Size
582 DGtal::CubicalComplex<TKSpace, TCellContainer>::
583 eraseCells( Dimension d, CellConstIterator it, CellConstIterator itE )
586 for ( ; it != itE; ++it )
587 nb += eraseCell( d, *it );
590 //-----------------------------------------------------------------------------
591 template <typename TKSpace, typename TCellContainer>
594 DGtal::CubicalComplex<TKSpace, TCellContainer>::
595 belongs( const Cell& aCell ) const
597 return belongs( myKSpace->uDim( aCell ), aCell );
599 //-----------------------------------------------------------------------------
600 template <typename TKSpace, typename TCellContainer>
603 DGtal::CubicalComplex<TKSpace, TCellContainer>::
604 belongs( Dimension d, const Cell& aCell ) const
606 ASSERT( d <= dimension );
607 CellMapConstIterator it = myCells[ d ].find( aCell );
608 return it != myCells[ d ].end();
610 //-----------------------------------------------------------------------------
611 template <typename TKSpace, typename TCellContainer>
614 DGtal::CubicalComplex<TKSpace, TCellContainer>::
615 belongs( const PreCell& aCell ) const
617 return belongs( TKSpace::PreCellularGridSpace::uDim( aCell ), aCell );
619 //-----------------------------------------------------------------------------
620 template <typename TKSpace, typename TCellContainer>
623 DGtal::CubicalComplex<TKSpace, TCellContainer>::
624 belongs( Dimension d, const PreCell& aCell ) const
626 if (!myKSpace->uIsValid(aCell)) return false;
627 return belongs(d, myKSpace->uCell(aCell) );
629 //-----------------------------------------------------------------------------
630 template <typename TKSpace, typename TCellContainer>
631 template <typename CellOutputIterator>
634 DGtal::CubicalComplex<TKSpace, TCellContainer>::
635 faces( CellOutputIterator& outIt, const Cell& aCell, bool hintClosed ) const
637 Cells all_proper_faces = myKSpace->uFaces( aCell );
639 std::copy( all_proper_faces.begin(), all_proper_faces.end(), outIt );
641 for ( typename Cells::ConstIterator it = all_proper_faces.begin(),
642 itE = all_proper_faces.end(); it != itE; ++it )
643 if ( belongs( *it ) )
646 //-----------------------------------------------------------------------------
647 template <typename TKSpace, typename TCellContainer>
648 template <typename CellOutputIterator>
651 DGtal::CubicalComplex<TKSpace, TCellContainer>::
652 coFaces( CellOutputIterator& outIt, const Cell& aCell, bool hintOpen ) const
654 Cells all_proper_co_faces = myKSpace->uCoFaces( aCell );
656 std::copy( all_proper_co_faces.begin(), all_proper_co_faces.end(), outIt );
658 for ( typename Cells::ConstIterator it = all_proper_co_faces.begin(),
659 itE = all_proper_co_faces.end(); it != itE; ++it )
660 if ( belongs( *it ) )
663 //-----------------------------------------------------------------------------
664 template <typename TKSpace, typename TCellContainer>
665 template <typename CellOutputIterator>
668 DGtal::CubicalComplex<TKSpace, TCellContainer>::
669 directFaces( CellOutputIterator& outIt, const Cell& aCell, bool hintClosed ) const
671 Cells all_direct_faces = myKSpace->uLowerIncident( aCell );
673 std::copy( all_direct_faces.begin(), all_direct_faces.end(), outIt );
675 for ( typename Cells::ConstIterator it = all_direct_faces.begin(),
676 itE = all_direct_faces.end(); it != itE; ++it )
677 if ( belongs( *it ) )
680 //-----------------------------------------------------------------------------
681 template <typename TKSpace, typename TCellContainer>
682 template <typename CellMapIteratorOutputIterator>
685 DGtal::CubicalComplex<TKSpace, TCellContainer>::
686 directFacesIterators( CellMapIteratorOutputIterator& outIt, const Cell& aCell )
688 Cells all_direct_faces = myKSpace->uLowerIncident( aCell );
689 Dimension k = dim( aCell );
690 for ( typename Cells::ConstIterator it = all_direct_faces.begin(),
691 itE = all_direct_faces.end(); it != itE; ++it )
693 CellMapIterator map_it = findCell( *it );
694 if ( map_it != end( k-1 ) )
698 //-----------------------------------------------------------------------------
699 template <typename TKSpace, typename TCellContainer>
700 template <typename CellOutputIterator>
703 DGtal::CubicalComplex<TKSpace, TCellContainer>::
704 directCoFaces( CellOutputIterator& outIt, const Cell& aCell, bool hintOpen ) const
706 Cells all_direct_co_faces = myKSpace->uUpperIncident( aCell );
708 std::copy( all_direct_co_faces.begin(), all_direct_co_faces.end(), outIt );
710 for ( typename Cells::ConstIterator it = all_direct_co_faces.begin(),
711 itE = all_direct_co_faces.end(); it != itE; ++it )
712 if ( belongs( *it ) )
715 //-----------------------------------------------------------------------------
716 template <typename TKSpace, typename TCellContainer>
717 template <typename CellMapIteratorOutputIterator>
720 DGtal::CubicalComplex<TKSpace, TCellContainer>::
721 directCoFacesIterators( CellMapIteratorOutputIterator& outIt, const Cell& aCell )
723 Cells all_direct_faces = myKSpace->uUpperIncident( aCell );
724 Dimension k = dim( aCell );
725 for ( typename Cells::ConstIterator it = all_direct_faces.begin(),
726 itE = all_direct_faces.end(); it != itE; ++it )
728 CellMapIterator map_it = findCell( *it );
729 if ( map_it != end( k+1 ) )
734 //-----------------------------------------------------------------------------
735 template <typename TKSpace, typename TCellContainer>
736 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMap &
737 DGtal::CubicalComplex<TKSpace, TCellContainer>::getCells(const Dimension d)
742 template <typename TKSpace, typename TCellContainer>
743 const typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMap &
744 DGtal::CubicalComplex<TKSpace, TCellContainer>::getCells(const Dimension d) const
748 //-----------------------------------------------------------------------------
749 template <typename TKSpace, typename TCellContainer>
751 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapConstIterator
752 DGtal::CubicalComplex<TKSpace, TCellContainer>::
753 begin( Dimension d ) const
755 return myCells[ d ].begin();
758 //-----------------------------------------------------------------------------
759 template <typename TKSpace, typename TCellContainer>
761 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapConstIterator
762 DGtal::CubicalComplex<TKSpace, TCellContainer>::
763 end( Dimension d ) const
765 return myCells[ d ].end();
768 //-----------------------------------------------------------------------------
769 template <typename TKSpace, typename TCellContainer>
771 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapIterator
772 DGtal::CubicalComplex<TKSpace, TCellContainer>::
775 return myCells[ d ].begin();
778 //-----------------------------------------------------------------------------
779 template <typename TKSpace, typename TCellContainer>
781 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapIterator
782 DGtal::CubicalComplex<TKSpace, TCellContainer>::
785 return myCells[ d ].end();
788 //-----------------------------------------------------------------------------
789 template <typename TKSpace, typename TCellContainer>
792 DGtal::CubicalComplex<TKSpace, TCellContainer>::
798 //-----------------------------------------------------------------------------
799 template <typename TKSpace, typename TCellContainer>
802 DGtal::CubicalComplex<TKSpace, TCellContainer>::
805 if ( k <= 0 ) return;
807 for ( CellMapConstIterator it = begin( k ), itE = end( k );
810 Cells direct_faces = myKSpace->uLowerIncident( it->first );
811 for ( typename Cells::const_iterator cells_it = direct_faces.begin(),
812 cells_it_end = direct_faces.end(); cells_it != cells_it_end; ++cells_it )
813 insertCell( l, *cells_it );
818 //-----------------------------------------------------------------------------
819 template <typename TKSpace, typename TCellContainer>
822 DGtal::CubicalComplex<TKSpace, TCellContainer>::
828 //-----------------------------------------------------------------------------
829 template <typename TKSpace, typename TCellContainer>
832 DGtal::CubicalComplex<TKSpace, TCellContainer>::
838 for ( CellMapIterator it = begin( k ), itE = end( k ); it != itE; )
840 Cells direct_cofaces = myKSpace->uUpperIncident( it->first );
842 for ( typename Cells::const_iterator cells_it = direct_cofaces.begin(),
843 cells_it_end = direct_cofaces.end(); cells_it != cells_it_end; ++cells_it )
844 if ( ! belongs( l, *cells_it ) )
849 CellMapIterator itMem = it;
851 if ( ! is_open ) myCells[ k ].erase( itMem );
854 if ( k > 0 ) open( k - 1 );
857 //-----------------------------------------------------------------------------
858 template <typename TKSpace, typename TCellContainer>
860 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapConstIterator
861 DGtal::CubicalComplex<TKSpace, TCellContainer>::
862 findCell( const Cell& aCell ) const
864 return findCell( dim( aCell ), aCell );
867 //-----------------------------------------------------------------------------
868 template <typename TKSpace, typename TCellContainer>
870 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapConstIterator
871 DGtal::CubicalComplex<TKSpace, TCellContainer>::
872 findCell( Dimension d, const Cell& aCell ) const
874 return myCells[ d ].find( aCell );
877 //-----------------------------------------------------------------------------
878 template <typename TKSpace, typename TCellContainer>
880 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapIterator
881 DGtal::CubicalComplex<TKSpace, TCellContainer>::
882 findCell( const Cell& aCell )
884 return findCell( dim( aCell ), aCell );
887 //-----------------------------------------------------------------------------
888 template <typename TKSpace, typename TCellContainer>
890 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellMapIterator
891 DGtal::CubicalComplex<TKSpace, TCellContainer>::
892 findCell( Dimension d, const Cell& aCell )
894 return myCells[ d ].find( aCell );
899 //-----------------------------------------------------------------------------
900 template <typename TKSpace, typename TCellContainer>
902 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Cells
903 DGtal::CubicalComplex<TKSpace, TCellContainer>::
904 cellBoundary( const Cell& aCell, bool hintClosed ) const
906 if ( hintClosed ) return myKSpace->uFaces( aCell );
907 Cells proper_faces = myKSpace->uFaces( aCell );
908 // NB: (JOL) do not use std::remove_if since predicate is passed by value.
909 typename Cells::iterator first = proper_faces.begin();
910 typename Cells::iterator last = proper_faces.end();
911 typename Cells::iterator result = first;
912 for ( ; first != last; ++first )
914 if ( belongs( *first ) )
916 *result = std::move( *first );
920 proper_faces.resize( result - proper_faces.begin() );
923 //-----------------------------------------------------------------------------
924 template <typename TKSpace, typename TCellContainer>
926 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::Cells
927 DGtal::CubicalComplex<TKSpace, TCellContainer>::
928 cellCoBoundary( const Cell& aCell, bool hintOpen ) const
930 if ( hintOpen ) return myKSpace->uCoFaces( aCell );
931 Cells proper_cofaces = myKSpace->uCoFaces( aCell );
932 // NB: (JOL) do not use std::remove_if since predicate is passed by value.
933 typename Cells::iterator first = proper_cofaces.begin();
934 typename Cells::iterator last = proper_cofaces.end();
935 typename Cells::iterator result = first;
936 for ( ; first != last; ++first )
938 if ( belongs( *first ) )
940 *result = std::move( *first );
944 proper_cofaces.resize( result - proper_cofaces.begin() );
945 return proper_cofaces;
948 //-----------------------------------------------------------------------------
949 template <typename TKSpace, typename TCellContainer>
952 DGtal::CubicalComplex<TKSpace, TCellContainer>::
953 isCellInterior( const Cell& aCell ) const
955 Cells proper_cofaces = myKSpace->uCoFaces( aCell );
956 typename Cells::iterator first = proper_cofaces.begin();
957 typename Cells::iterator last = proper_cofaces.end();
958 for ( ; first != last; ++first )
960 if ( ! belongs( *first ) ) return false;
965 //-----------------------------------------------------------------------------
966 template <typename TKSpace, typename TCellContainer>
969 DGtal::CubicalComplex<TKSpace, TCellContainer>::
970 isCellBoundary( const Cell& aCell ) const
972 return ! isCellInterior( aCell );
975 //-----------------------------------------------------------------------------
976 template <typename TKSpace, typename TCellContainer>
978 DGtal::CubicalComplex<TKSpace, TCellContainer>
979 DGtal::CubicalComplex<TKSpace, TCellContainer>::
982 CubicalComplex I( space() );
983 for ( Dimension d = 0; d <= dimension; ++d )
985 for ( CellMapConstIterator it = begin( d ), itE = end( d ); it != itE; ++it )
987 if ( isCellInterior( it->first ) )
988 I.insertCell( d, it->first, it->second );
994 //-----------------------------------------------------------------------------
995 template <typename TKSpace, typename TCellContainer>
997 DGtal::CubicalComplex<TKSpace, TCellContainer>
998 DGtal::CubicalComplex<TKSpace, TCellContainer>::
999 boundary( bool hintClosed ) const
1001 CubicalComplex B( *this );
1002 if ( ! hintClosed ) B.close();
1003 for ( Dimension d = 0; d <= dimension; ++d )
1005 CellMapIterator itNext;
1006 for ( CellMapIterator it = B.begin( d ), itE = B.end( d ); it != itE; )
1008 itNext = it; ++itNext;
1009 if ( B.isCellInterior( it->first ) )
1017 //-----------------------------------------------------------------------------
1018 template <typename TKSpace, typename TCellContainer>
1021 DGtal::CubicalComplex<TKSpace, TCellContainer>::
1022 getInteriorAndBoundary( CubicalComplex& intcc, CubicalComplex& bdcc,
1023 bool hintClosed ) const
1026 bdcc = CubicalComplex( this->space() );
1027 if ( ! hintClosed ) intcc.close();
1028 for ( Dimension d = 0; d <= dimension; ++d )
1030 CellMapIterator itNext;
1031 for ( CellMapIterator it = intcc.begin( d ), itE = intcc.end( d ); it != itE; )
1033 itNext = it; ++itNext;
1034 if ( ! intcc.isCellInterior( it->first ) )
1036 intcc.eraseCell( it );
1037 bdcc.insertCell( d, it->first, it->second );
1044 //-----------------------------------------------------------------------------
1045 template <typename TKSpace, typename TCellContainer>
1047 typename DGtal::CubicalComplex<TKSpace, TCellContainer>
1048 DGtal::CubicalComplex<TKSpace, TCellContainer>::
1049 closure( const CubicalComplex& S, bool hintClosed ) const
1051 CubicalComplex cl_S = S;
1052 for ( ConstIterator it = S.begin(), itE = S.end(); it != itE; ++it )
1054 Cells cell_faces = cellBoundary( *it, hintClosed );
1055 cl_S.insert( cell_faces.begin(), cell_faces.end() );
1059 //-----------------------------------------------------------------------------
1060 template <typename TKSpace, typename TCellContainer>
1062 typename DGtal::CubicalComplex<TKSpace, TCellContainer>
1063 DGtal::CubicalComplex<TKSpace, TCellContainer>::
1064 star( const CubicalComplex& S, bool hintOpen ) const
1066 CubicalComplex star_S = S;
1067 for ( ConstIterator it = S.begin(), itE = S.end(); it != itE; ++it )
1069 Cells cell_cofaces = cellCoBoundary( *it, hintOpen );
1070 star_S.insert( cell_cofaces.begin(), cell_cofaces.end() );
1074 //-----------------------------------------------------------------------------
1075 template <typename TKSpace, typename TCellContainer>
1077 typename DGtal::CubicalComplex<TKSpace, TCellContainer>
1078 DGtal::CubicalComplex<TKSpace, TCellContainer>::
1079 link( const CubicalComplex& S, bool hintClosed, bool hintOpen ) const
1081 CubicalComplex cl_star_S = closure( star ( S, hintOpen ), hintClosed );
1082 CubicalComplex star_cl_S = star ( closure( S, hintClosed ), hintOpen );
1084 // Calls a specializable difference of sets operation.
1085 return cl_star_S - star_cl_S;
1088 //-----------------------------------------------------------------------------
1089 template <typename TKSpace, typename TCellContainer>
1091 typename DGtal::CubicalComplex<TKSpace, TCellContainer>::CellType
1092 DGtal::CubicalComplex<TKSpace, TCellContainer>::
1093 computeCellType( const Cell& c, CellMapIterator& it_cell_up, Dimension n )
1095 // Check if it is a maximal cell
1096 Dimension k = dim( c );
1097 if ( k == n ) return Maximal;
1099 std::vector< CellMapIterator > Q_up;
1100 std::back_insert_iterator< std::vector< CellMapIterator > > back_it( Q_up );
1101 this->directCoFacesIterators( back_it, c );
1103 // Filtering unwanted up-incident cells.
1105 for ( typename std::vector< CellMapIterator >::const_iterator it = Q_up.begin(), itE = Q_up.end();
1108 uint32_t& data = (*it)->second.data;
1109 if ( ! ( data & COLLAPSIBLE ) ) return Any;
1110 if ( ! ( data & REMOVED ) )
1113 if ( nb > 1 ) return Any;
1117 return ( nb != 0 ) ? Free : Maximal ;
1122 ///////////////////////////////////////////////////////////////////////////////
1123 // Interface - public :
1126 * Writes/Displays the object on an output stream.
1127 * @param out the output stream where the object is written.
1129 template <typename TKSpace, typename TCellContainer>
1132 DGtal::CubicalComplex<TKSpace, TCellContainer>::selfDisplay ( std::ostream & out ) const
1134 out << "[CubicalComplex dim=" << dim() << " chi=" << euler();
1135 for ( Dimension i = 0; i < myCells.size(); ++i )
1136 out << " #" << i << "=" << myCells[ i ].size();
1141 * Checks the validity/consistency of the object.
1142 * @return 'true' if the object is valid, 'false' otherwise.
1144 template <typename TKSpace, typename TCellContainer>
1147 DGtal::CubicalComplex<TKSpace, TCellContainer>::isValid() const
1152 //-----------------------------------------------------------------------------
1153 template <typename TKSpace, typename TCellContainer>
1156 DGtal::CubicalComplex<TKSpace, TCellContainer>::className() const
1158 return "CubicalComplex";
1163 ///////////////////////////////////////////////////////////////////////////////
1164 // Implementation of inline functions //
1166 template <typename TKSpace, typename TCellContainer>
1169 DGtal::operator<< ( std::ostream & out,
1170 const CubicalComplex<TKSpace, TCellContainer> & object )
1172 object.selfDisplay( out );
1177 ///////////////////////////////////////////////////////////////////////////////