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//-----------------------------------------------------------------------------
44template <typename TKSpace>
46DGtal::SurfelNeighborhood<TKSpace>::
49//-----------------------------------------------------------------------------
50template <typename TKSpace>
52DGtal::SurfelNeighborhood<TKSpace>::
54 : mySpace( 0 ), mySurfelAdj( 0 )
56//-----------------------------------------------------------------------------
57template <typename TKSpace>
59DGtal::SurfelNeighborhood<TKSpace>::
60SurfelNeighborhood( const SurfelNeighborhood & other )
61 : mySpace( other.mySpace ), mySurfelAdj( other.mySurfelAdj ),
62 mySurfel( other.mySurfel ), myOrthDir( other.myOrthDir ),
63 myOrthDirect( other.myOrthDirect )
65//-----------------------------------------------------------------------------
66template <typename TKSpace>
68DGtal::SurfelNeighborhood<TKSpace> &
69DGtal::SurfelNeighborhood<TKSpace>::
70operator= ( const SurfelNeighborhood & other )
74 mySpace = other.mySpace;
75 mySurfelAdj = other.mySurfelAdj;
76 mySurfel = other.mySurfel;
77 myOrthDir = other.myOrthDir;
78 myOrthDirect = other.myOrthDirect;
82//-----------------------------------------------------------------------------
83template <typename TKSpace>
86DGtal::SurfelNeighborhood<TKSpace>::
87init( 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//-----------------------------------------------------------------------------
99template <typename TKSpace>
102DGtal::SurfelNeighborhood<TKSpace>::
103setSurfel( const SCell & aSurfel )
105 ASSERT( mySpace != 0 );
106 if ( mySurfel != aSurfel )
109 myOrthDir = mySpace->sOrthDir( aSurfel );
110 myOrthDirect = mySpace->sDirect( aSurfel, myOrthDir );
113//-----------------------------------------------------------------------------
114template <typename TKSpace>
116const typename DGtal::SurfelNeighborhood<TKSpace>::SCell &
117DGtal::SurfelNeighborhood<TKSpace>::
122//-----------------------------------------------------------------------------
123template <typename TKSpace>
126DGtal::SurfelNeighborhood<TKSpace>::
132//-----------------------------------------------------------------------------
133//----------------------- spel services -------------------------
134//-----------------------------------------------------------------------------
135template <typename TKSpace>
137typename DGtal::SurfelNeighborhood<TKSpace>::SCell
138DGtal::SurfelNeighborhood<TKSpace>::
141 ASSERT( mySpace != 0 );
142 return mySpace->sIncident( surfel(), orthDir(), myOrthDirect );
144//-----------------------------------------------------------------------------
145template <typename TKSpace>
147typename DGtal::SurfelNeighborhood<TKSpace>::SCell
148DGtal::SurfelNeighborhood<TKSpace>::
151 ASSERT( mySpace != 0 );
152 return mySpace->sIncident( surfel(), orthDir(), ! myOrthDirect );
154//-----------------------------------------------------------------------------
155template <typename TKSpace>
157typename DGtal::SurfelNeighborhood<TKSpace>::SCell
158DGtal::SurfelNeighborhood<TKSpace>::
159innerAdjacentSpel( DGtal::Dimension track_dir, bool pos ) const
161 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
162 return mySpace->sAdjacent( innerSpel(), track_dir, pos );
164//-----------------------------------------------------------------------------
165template <typename TKSpace>
167typename DGtal::SurfelNeighborhood<TKSpace>::SCell
168DGtal::SurfelNeighborhood<TKSpace>::
169outerAdjacentSpel( 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//-----------------------------------------------------------------------------
178template <typename TKSpace>
180typename DGtal::SurfelNeighborhood<TKSpace>::SCell
181DGtal::SurfelNeighborhood<TKSpace>::
182follower1( DGtal::Dimension track_dir, bool pos ) const
184 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
185 return mySpace->sIncident( innerSpel(), track_dir, pos );
187//-----------------------------------------------------------------------------
188template <typename TKSpace>
190typename DGtal::SurfelNeighborhood<TKSpace>::SCell
191DGtal::SurfelNeighborhood<TKSpace>::
192follower2( DGtal::Dimension track_dir, bool pos ) const
194 ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
195 return mySpace->sAdjacent( surfel(), track_dir, pos );
197//-----------------------------------------------------------------------------
198template <typename TKSpace>
200typename DGtal::SurfelNeighborhood<TKSpace>::SCell
201DGtal::SurfelNeighborhood<TKSpace>::
202follower3( 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//-----------------------------------------------------------------------------
211template <typename TKSpace>
212template <typename SpelSet>
215DGtal::SurfelNeighborhood<TKSpace>::
216getAdjacentOnSpelSet( 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//-----------------------------------------------------------------------------
276template <typename TKSpace>
277template <typename DigitalSet>
280DGtal::SurfelNeighborhood<TKSpace>::
281getAdjacentOnDigitalSet( 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//-----------------------------------------------------------------------------
344template <typename TKSpace>
345template <typename PointPredicate>
347DGtal::SurfelNeighborhood<TKSpace>::
348getAdjacentOnPointPredicate( 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//-----------------------------------------------------------------------------
408template <typename TKSpace>
409template <typename SurfelPredicate>
411DGtal::SurfelNeighborhood<TKSpace>::
412getAdjacentOnSurfelPredicate( 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//-----------------------------------------------------------------------------
470template <typename TKSpace>
473DGtal::SurfelNeighborhood<TKSpace>::selfDisplay ( std::ostream & out ) const
475 out << "[SurfelNeighborhood]";
477//-----------------------------------------------------------------------------
478template <typename TKSpace>
481DGtal::SurfelNeighborhood<TKSpace>::isValid() const
486///////////////////////////////////////////////////////////////////////////////
487// Implementation of inline functions //
489template <typename TKSpace>
492DGtal::operator<< ( std::ostream & out,
493 const SurfelNeighborhood<TKSpace> & object )
495 object.selfDisplay( out );
500///////////////////////////////////////////////////////////////////////////////