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 SurfelNeighborhood.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5807), University of Savoie, France
24 * Implementation of inline methods defined in SurfelNeighborhood.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 #include "DGtal/kernel/CPointPredicate.h"
33 #include "DGtal/topology/CSurfelPredicate.h"
34 //////////////////////////////////////////////////////////////////////////////
36 ///////////////////////////////////////////////////////////////////////////////
37 // IMPLEMENTATION of inline methods.
38 ///////////////////////////////////////////////////////////////////////////////
40 ///////////////////////////////////////////////////////////////////////////////
41 // ----------------------- Standard services ------------------------------
43 //-----------------------------------------------------------------------------
44 template <typename TKSpace>
46 DGtal::SurfelNeighborhood<TKSpace>::
49 //-----------------------------------------------------------------------------
50 template <typename TKSpace>
52 DGtal::SurfelNeighborhood<TKSpace>::
54 : mySpace( 0 ), mySurfelAdj( 0 )
56 //-----------------------------------------------------------------------------
57 template <typename TKSpace>
59 DGtal::SurfelNeighborhood<TKSpace>::
60 SurfelNeighborhood( const SurfelNeighborhood & other )
61 : mySpace( other.mySpace ), mySurfelAdj( other.mySurfelAdj ),
62 mySurfel( other.mySurfel ), myOrthDir( other.myOrthDir ),
63 myOrthDirect( other.myOrthDirect )
65 //-----------------------------------------------------------------------------
66 template <typename TKSpace>
68 DGtal::SurfelNeighborhood<TKSpace> &
69 DGtal::SurfelNeighborhood<TKSpace>::
70 operator= ( const SurfelNeighborhood & other )
74 mySpace = other.mySpace;
75 mySurfelAdj = other.mySurfelAdj;
76 mySurfel = other.mySurfel;
77 myOrthDir = other.myOrthDir;
78 myOrthDirect = other.myOrthDirect;
82 //-----------------------------------------------------------------------------
83 template <typename TKSpace>
86 DGtal::SurfelNeighborhood<TKSpace>::
87 init( const KSpace* space,
88 const SurfelAdjacency<KSpace::dimension>* adj,
89 const SCell & aSurfel )
94 myOrthDir = mySpace->sOrthDir( aSurfel );
95 myOrthDirect = mySpace->sDirect( aSurfel, myOrthDir );
98 //-----------------------------------------------------------------------------
99 template <typename TKSpace>
102 DGtal::SurfelNeighborhood<TKSpace>::
103 setSurfel( const SCell & aSurfel )
105 ASSERT( mySpace != 0 );
106 if ( mySurfel != aSurfel )
109 myOrthDir = mySpace->sOrthDir( aSurfel );
110 myOrthDirect = mySpace->sDirect( aSurfel, myOrthDir );
113 //-----------------------------------------------------------------------------
114 template <typename TKSpace>
116 const typename DGtal::SurfelNeighborhood<TKSpace>::SCell &
117 DGtal::SurfelNeighborhood<TKSpace>::
122 //-----------------------------------------------------------------------------
123 template <typename TKSpace>
126 DGtal::SurfelNeighborhood<TKSpace>::
132 //-----------------------------------------------------------------------------
133 //----------------------- spel services -------------------------
134 //-----------------------------------------------------------------------------
135 template <typename TKSpace>
137 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
138 DGtal::SurfelNeighborhood<TKSpace>::
141 ASSERT( mySpace != 0 );
142 return mySpace->sIncident( surfel(), orthDir(), myOrthDirect );
144 //-----------------------------------------------------------------------------
145 template <typename TKSpace>
147 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
148 DGtal::SurfelNeighborhood<TKSpace>::
151 ASSERT( mySpace != 0 );
152 return mySpace->sIncident( surfel(), orthDir(), ! myOrthDirect );
154 //-----------------------------------------------------------------------------
155 template <typename TKSpace>
157 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
158 DGtal::SurfelNeighborhood<TKSpace>::
159 innerAdjacentSpel( DGtal::Dimension track_dir, bool pos ) const
161 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
162 return mySpace->sAdjacent( innerSpel(), track_dir, pos );
164 //-----------------------------------------------------------------------------
165 template <typename TKSpace>
167 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
168 DGtal::SurfelNeighborhood<TKSpace>::
169 outerAdjacentSpel( DGtal::Dimension track_dir, bool pos ) const
171 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
172 return mySpace->sAdjacent( outerSpel(), track_dir, pos );
175 //-----------------------------------------------------------------------------
176 //----------------------- follower services -------------------------
177 //-----------------------------------------------------------------------------
178 template <typename TKSpace>
180 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
181 DGtal::SurfelNeighborhood<TKSpace>::
182 follower1( DGtal::Dimension track_dir, bool pos ) const
184 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
185 return mySpace->sIncident( innerSpel(), track_dir, pos );
187 //-----------------------------------------------------------------------------
188 template <typename TKSpace>
190 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
191 DGtal::SurfelNeighborhood<TKSpace>::
192 follower2( DGtal::Dimension track_dir, bool pos ) const
194 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
195 return mySpace->sAdjacent( surfel(), track_dir, pos );
197 //-----------------------------------------------------------------------------
198 template <typename TKSpace>
200 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
201 DGtal::SurfelNeighborhood<TKSpace>::
202 follower3( DGtal::Dimension track_dir, bool pos ) const
204 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
205 return mySpace->sIncident( outerSpel(), track_dir, pos );
208 //-----------------------------------------------------------------------------
209 // ----------------------- Surfel adjacency services --------------------
210 //-----------------------------------------------------------------------------
211 template <typename TKSpace>
212 template <typename SpelSet>
215 DGtal::SurfelNeighborhood<TKSpace>::
216 getAdjacentOnSpelSet( SCell & adj_surfel,
218 DGtal::Dimension track_dir,
221 // Check that [m_surfel] is a bel.
222 ASSERT( mySpace != 0 );
223 ASSERT( mySurfelAdj != 0 );
224 Cell uinner_spel = mySpace->unsigns( innerSpel() );
225 ASSERT( obj.find( uinner_spel ) != obj.end() );
226 ASSERT( obj.find( mySpace->unsigns( outerSpel() ) ) == obj.end() );
228 // Check if it goes outside the space.
229 if ( ( pos && mySpace->uisMax( uinner_spel, track_dir ) )
230 || ( ( ! pos ) && mySpace->uisMin( uinner_spel, track_dir ) ) )
233 // Check type of surfel adjacency.
234 if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
235 { // interior to exterior
236 // Check first next bel.
237 if ( obj.find( mySpace->unsigns( innerAdjacentSpel( track_dir, pos ) ) )
240 adj_surfel = follower1( track_dir, pos );
243 // Check second next bel.
244 if ( obj.find( mySpace->unsigns( outerAdjacentSpel( track_dir, pos ) ) )
247 adj_surfel = follower2( track_dir, pos );
250 // The third one is then the right one.
251 adj_surfel = follower3( track_dir, pos );
254 else // if ( mySurfelAdj->getAdjacency( m_orth_dir, track_dir ) )
255 { // exterior to interior
256 // Check first next bel.
257 if ( obj.find( mySpace->unsigns( outerAdjacentSpel( track_dir, pos ) ) )
260 adj_surfel = follower3( track_dir, pos );
263 // Check second next bel.
264 if ( obj.find( mySpace->unsigns( innerAdjacentSpel( track_dir, pos ) ) )
267 adj_surfel = follower2( track_dir, pos );
270 // The third one is then the right one.
271 adj_surfel = follower1( track_dir, pos );
275 //-----------------------------------------------------------------------------
276 template <typename TKSpace>
277 template <typename DigitalSet>
280 DGtal::SurfelNeighborhood<TKSpace>::
281 getAdjacentOnDigitalSet( SCell & adj_surfel,
282 const DigitalSet & obj,
283 DGtal::Dimension track_dir,
286 // Check that [m_surfel] is a bel.
287 ASSERT( mySpace != 0 );
288 ASSERT( mySurfelAdj != 0 );
289 Point inner_spel_pt = mySpace->sCoords( innerSpel() );
290 ASSERT( obj.find( inner_spel_pt ) != obj.end() );
291 ASSERT( obj.find( mySpace->sCoords( outerSpel() ) ) == obj.end() );
293 // Check if it goes outside the space.
294 if ( ( pos && mySpace->sIsMax( innerSpel(), track_dir ) )
295 || ( !pos && mySpace->sIsMin( innerSpel(), track_dir ) )
299 // Check type of surfel adjacency.
300 if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
301 { // interior to exterior
302 // Check first next bel.
303 if ( obj.find( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) )
306 adj_surfel = follower1( track_dir, pos );
309 // Check second next bel.
310 if ( obj.find( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) )
313 adj_surfel = follower2( track_dir, pos );
316 // The third one is then the right one.
317 adj_surfel = follower3( track_dir, pos );
320 else // if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
321 { // exterior to interior
322 // Check first next bel.
323 if ( obj.find( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) )
326 adj_surfel = follower3( track_dir, pos );
329 // Check second next bel.
330 if ( obj.find( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) )
333 adj_surfel = follower2( track_dir, pos );
336 // The third one is then the right one.
337 adj_surfel = follower1( track_dir, pos );
343 //-----------------------------------------------------------------------------
344 template <typename TKSpace>
345 template <typename PointPredicate>
347 DGtal::SurfelNeighborhood<TKSpace>::
348 getAdjacentOnPointPredicate( SCell & adj_surfel,
349 const PointPredicate & pp,
350 DGtal::Dimension track_dir,
353 BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<PointPredicate> ));
355 // Check that [m_surfel] is a bel.
356 ASSERT( mySpace != 0 );
357 ASSERT( mySurfelAdj != 0 );
358 Point inner_spel_pt = mySpace->sCoords( innerSpel() );
359 ASSERT( pp( inner_spel_pt ) && "Should be inside." );
360 ASSERT( ! pp( mySpace->sCoords( outerSpel() ) ) && "Should be outside" );
362 // Check if it goes outside the space.
363 if ( ( pos && mySpace->sIsMax( innerSpel(), track_dir ) )
364 || ( !pos && mySpace->sIsMin( innerSpel(), track_dir ) )
368 // Check type of surfel adjacency.
369 if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
370 { // interior to exterior
371 // Check first next bel.
372 if ( ! pp( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) ) )
374 adj_surfel = follower1( track_dir, pos );
377 // Check second next bel.
378 if ( ! pp( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) ) )
380 adj_surfel = follower2( track_dir, pos );
383 // The third one is then the right one.
384 adj_surfel = follower3( track_dir, pos );
387 else // if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
388 { // exterior to interior
389 // Check first next bel.
390 if ( pp( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) ) )
392 adj_surfel = follower3( track_dir, pos );
395 // Check second next bel.
396 if ( pp( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) ) )
398 adj_surfel = follower2( track_dir, pos );
401 // The third one is then the right one.
402 adj_surfel = follower1( track_dir, pos );
407 //-----------------------------------------------------------------------------
408 template <typename TKSpace>
409 template <typename SurfelPredicate>
411 DGtal::SurfelNeighborhood<TKSpace>::
412 getAdjacentOnSurfelPredicate( SCell & adj_surfel,
413 const SurfelPredicate & sp,
414 DGtal::Dimension track_dir,
417 BOOST_CONCEPT_ASSERT(( concepts::CSurfelPredicate<SurfelPredicate> ));
419 // Check that [m_surfel] is a bel.
420 ASSERT( mySpace != 0 );
421 ASSERT( mySurfelAdj != 0 );
422 ASSERT( sp( mySurfel ) && "Current surfel should satisfy predicate." );
424 // Check if it goes outside the space.
425 if ( ( pos && mySpace->sIsMax( surfel(), track_dir ) )
426 || ( !pos && mySpace->sIsMin( surfel(), track_dir ) )
430 // Integer x_orth = mySpace->sCoord( surfel(), orthDir() );
431 SCell tmp_surfel = adj_surfel;
433 // Check type of surfel adjacency.
434 if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
435 { // interior to exterior
436 // Check first next bel.
437 adj_surfel = follower1( track_dir, pos );
438 if ( sp( adj_surfel ) ) return 1;
440 // Check second next bel.
441 adj_surfel = follower2( track_dir, pos );
442 if ( sp( adj_surfel ) ) return 2;
445 adj_surfel = follower3( track_dir, pos );
446 if ( sp( adj_surfel ) ) return 3;
449 { // exterior to interior
450 // Check first next bel.
451 adj_surfel = follower3( track_dir, pos );
452 if ( sp( adj_surfel ) ) return 3;
454 // Check second next bel.
455 adj_surfel = follower2( track_dir, pos );
456 if ( sp( adj_surfel ) ) return 2;
459 adj_surfel = follower1( track_dir, pos );
460 if ( sp( adj_surfel ) ) return 1;
462 adj_surfel = tmp_surfel;
467 ///////////////////////////////////////////////////////////////////////////////
468 // Interface - public :
469 //-----------------------------------------------------------------------------
470 template <typename TKSpace>
473 DGtal::SurfelNeighborhood<TKSpace>::selfDisplay ( std::ostream & out ) const
475 out << "[SurfelNeighborhood]";
477 //-----------------------------------------------------------------------------
478 template <typename TKSpace>
481 DGtal::SurfelNeighborhood<TKSpace>::isValid() const
486 ///////////////////////////////////////////////////////////////////////////////
487 // Implementation of inline functions //
489 template <typename TKSpace>
492 DGtal::operator<< ( std::ostream & out,
493 const SurfelNeighborhood<TKSpace> & object )
495 object.selfDisplay( out );
500 ///////////////////////////////////////////////////////////////////////////////