DGtal  0.9.2
SurfelNeighborhood.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 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
21  *
22  * @date 2011/03/18
23  *
24  * Implementation of inline methods defined in SurfelNeighborhood.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 #include "DGtal/kernel/CPointPredicate.h"
33 #include "DGtal/topology/CSurfelPredicate.h"
34 //////////////////////////////////////////////////////////////////////////////
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // IMPLEMENTATION of inline methods.
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 ///////////////////////////////////////////////////////////////////////////////
41 // ----------------------- Standard services ------------------------------
42 
43 //-----------------------------------------------------------------------------
44 template <typename TKSpace>
45 inline
46 DGtal::SurfelNeighborhood<TKSpace>::
47 ~SurfelNeighborhood()
48 {}
49 //-----------------------------------------------------------------------------
50 template <typename TKSpace>
51 inline
52 DGtal::SurfelNeighborhood<TKSpace>::
53 SurfelNeighborhood()
54  : mySpace( 0 ), mySurfelAdj( 0 )
55 {}
56 //-----------------------------------------------------------------------------
57 template <typename TKSpace>
58 inline
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 )
64 {}
65 //-----------------------------------------------------------------------------
66 template <typename TKSpace>
67 inline
68 DGtal::SurfelNeighborhood<TKSpace> &
69 DGtal::SurfelNeighborhood<TKSpace>::
70 operator= ( const SurfelNeighborhood & other )
71 {
72  if ( this != &other )
73  {
74  mySpace = other.mySpace;
75  mySurfelAdj = other.mySurfelAdj;
76  mySurfel = other.mySurfel;
77  myOrthDir = other.myOrthDir;
78  myOrthDirect = other.myOrthDirect;
79  }
80  return *this;
81 }
82 //-----------------------------------------------------------------------------
83 template <typename TKSpace>
84 inline
85 void
86 DGtal::SurfelNeighborhood<TKSpace>::
87 init( const KSpace* space,
88  const SurfelAdjacency<KSpace::dimension>* adj,
89  const SCell & aSurfel )
90 {
91  mySpace = space;
92  mySurfelAdj = adj;
93  mySurfel = aSurfel;
94  myOrthDir = mySpace->sOrthDir( aSurfel );
95  myOrthDirect = mySpace->sDirect( aSurfel, myOrthDir );
96 
97 }
98 //-----------------------------------------------------------------------------
99 template <typename TKSpace>
100 inline
101 void
102 DGtal::SurfelNeighborhood<TKSpace>::
103 setSurfel( const SCell & aSurfel )
104 {
105  ASSERT( mySpace != 0 );
106  if ( mySurfel != aSurfel )
107  {
108  mySurfel = aSurfel;
109  myOrthDir = mySpace->sOrthDir( aSurfel );
110  myOrthDirect = mySpace->sDirect( aSurfel, myOrthDir );
111  }
112 }
113 //-----------------------------------------------------------------------------
114 template <typename TKSpace>
115 inline
116 const typename DGtal::SurfelNeighborhood<TKSpace>::SCell &
117 DGtal::SurfelNeighborhood<TKSpace>::
118 surfel() const
119 {
120  return mySurfel;
121 }
122 //-----------------------------------------------------------------------------
123 template <typename TKSpace>
124 inline
125 DGtal::Dimension
126 DGtal::SurfelNeighborhood<TKSpace>::
127 orthDir() const
128 {
129  return myOrthDir;
130 }
131 
132 //-----------------------------------------------------------------------------
133 //----------------------- spel services -------------------------
134 //-----------------------------------------------------------------------------
135 template <typename TKSpace>
136 inline
137 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
138 DGtal::SurfelNeighborhood<TKSpace>::
139 innerSpel() const
140 {
141  ASSERT( mySpace != 0 );
142  return mySpace->sIncident( surfel(), orthDir(), myOrthDirect );
143 }
144 //-----------------------------------------------------------------------------
145 template <typename TKSpace>
146 inline
147 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
148 DGtal::SurfelNeighborhood<TKSpace>::
149 outerSpel() const
150 {
151  ASSERT( mySpace != 0 );
152  return mySpace->sIncident( surfel(), orthDir(), ! myOrthDirect );
153 }
154 //-----------------------------------------------------------------------------
155 template <typename TKSpace>
156 inline
157 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
158 DGtal::SurfelNeighborhood<TKSpace>::
159 innerAdjacentSpel( DGtal::Dimension track_dir, bool pos ) const
160 {
161  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
162  return mySpace->sAdjacent( innerSpel(), track_dir, pos );
163 }
164 //-----------------------------------------------------------------------------
165 template <typename TKSpace>
166 inline
167 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
168 DGtal::SurfelNeighborhood<TKSpace>::
169 outerAdjacentSpel( DGtal::Dimension track_dir, bool pos ) const
170 {
171  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
172  return mySpace->sAdjacent( outerSpel(), track_dir, pos );
173 }
174 
175 //-----------------------------------------------------------------------------
176 //----------------------- follower services -------------------------
177 //-----------------------------------------------------------------------------
178 template <typename TKSpace>
179 inline
180 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
181 DGtal::SurfelNeighborhood<TKSpace>::
182 follower1( DGtal::Dimension track_dir, bool pos ) const
183 {
184  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
185  return mySpace->sIncident( innerSpel(), track_dir, pos );
186 }
187 //-----------------------------------------------------------------------------
188 template <typename TKSpace>
189 inline
190 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
191 DGtal::SurfelNeighborhood<TKSpace>::
192 follower2( DGtal::Dimension track_dir, bool pos ) const
193 {
194  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
195  return mySpace->sAdjacent( surfel(), track_dir, pos );
196 }
197 //-----------------------------------------------------------------------------
198 template <typename TKSpace>
199 inline
200 typename DGtal::SurfelNeighborhood<TKSpace>::SCell
201 DGtal::SurfelNeighborhood<TKSpace>::
202 follower3( DGtal::Dimension track_dir, bool pos ) const
203 {
204  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
205  return mySpace->sIncident( outerSpel(), track_dir, pos );
206 }
207 
208 //-----------------------------------------------------------------------------
209 // ----------------------- Surfel adjacency services --------------------
210 //-----------------------------------------------------------------------------
211 template <typename TKSpace>
212 template <typename SpelSet>
213 inline
214 unsigned int
215 DGtal::SurfelNeighborhood<TKSpace>::
216 getAdjacentOnSpelSet( SCell & adj_surfel,
217  const SpelSet & obj,
218  DGtal::Dimension track_dir,
219  bool pos ) const
220 {
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() );
227 
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 ) ) )
231  return 0;
232 
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 ) ) )
238  == obj.end() )
239  {
240  adj_surfel = follower1( track_dir, pos );
241  return 1;
242  }
243  // Check second next bel.
244  if ( obj.find( mySpace->unsigns( outerAdjacentSpel( track_dir, pos ) ) )
245  == obj.end() )
246  {
247  adj_surfel = follower2( track_dir, pos );
248  return 2;
249  }
250  // The third one is then the right one.
251  adj_surfel = follower3( track_dir, pos );
252  return 3;
253  }
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 ) ) )
258  != obj.end() )
259  {
260  adj_surfel = follower3( track_dir, pos );
261  return 3;
262  }
263  // Check second next bel.
264  if ( obj.find( mySpace->unsigns( innerAdjacentSpel( track_dir, pos ) ) )
265  != obj.end() )
266  {
267  adj_surfel = follower2( track_dir, pos );
268  return 2;
269  }
270  // The third one is then the right one.
271  adj_surfel = follower1( track_dir, pos );
272  return 1;
273  }
274 }
275 //-----------------------------------------------------------------------------
276 template <typename TKSpace>
277 template <typename DigitalSet>
278 inline
279 unsigned int
280 DGtal::SurfelNeighborhood<TKSpace>::
281 getAdjacentOnDigitalSet( SCell & adj_surfel,
282  const DigitalSet & obj,
283  DGtal::Dimension track_dir,
284  bool pos ) const
285 {
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() );
292 
293  // Check if it goes outside the space.
294  if ( ( pos && mySpace->sIsMax( innerSpel(), track_dir ) )
295  || ( !pos && mySpace->sIsMin( innerSpel(), track_dir ) )
296  )
297  return 0;
298 
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 ) ) )
304  == obj.end() )
305  {
306  adj_surfel = follower1( track_dir, pos );
307  return 1;
308  }
309  // Check second next bel.
310  if ( obj.find( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) )
311  == obj.end() )
312  {
313  adj_surfel = follower2( track_dir, pos );
314  return 2;
315  }
316  // The third one is then the right one.
317  adj_surfel = follower3( track_dir, pos );
318  return 3;
319  }
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 ) ) )
324  != obj.end() )
325  {
326  adj_surfel = follower3( track_dir, pos );
327  return 3;
328  }
329  // Check second next bel.
330  if ( obj.find( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) )
331  != obj.end() )
332  {
333  adj_surfel = follower2( track_dir, pos );
334  return 2;
335  }
336  // The third one is then the right one.
337  adj_surfel = follower1( track_dir, pos );
338  return 1;
339  }
340 }
341 
342 
343 //-----------------------------------------------------------------------------
344 template <typename TKSpace>
345 template <typename PointPredicate>
346 unsigned int
347 DGtal::SurfelNeighborhood<TKSpace>::
348 getAdjacentOnPointPredicate( SCell & adj_surfel,
349  const PointPredicate & pp,
350  DGtal::Dimension track_dir,
351  bool pos ) const
352 {
353  BOOST_CONCEPT_ASSERT(( concepts::CPointPredicate<PointPredicate> ));
354 
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" );
361 
362  // Check if it goes outside the space.
363  if ( ( pos && mySpace->sIsMax( innerSpel(), track_dir ) )
364  || ( !pos && mySpace->sIsMin( innerSpel(), track_dir ) )
365  )
366  return 0;
367 
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 ) ) ) )
373  {
374  adj_surfel = follower1( track_dir, pos );
375  return 1;
376  }
377  // Check second next bel.
378  if ( ! pp( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) ) )
379  {
380  adj_surfel = follower2( track_dir, pos );
381  return 2;
382  }
383  // The third one is then the right one.
384  adj_surfel = follower3( track_dir, pos );
385  return 3;
386  }
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 ) ) ) )
391  {
392  adj_surfel = follower3( track_dir, pos );
393  return 3;
394  }
395  // Check second next bel.
396  if ( pp( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) ) )
397  {
398  adj_surfel = follower2( track_dir, pos );
399  return 2;
400  }
401  // The third one is then the right one.
402  adj_surfel = follower1( track_dir, pos );
403  return 1;
404  }
405 }
406 
407 //-----------------------------------------------------------------------------
408 template <typename TKSpace>
409 template <typename SurfelPredicate>
410 unsigned int
411 DGtal::SurfelNeighborhood<TKSpace>::
412 getAdjacentOnSurfelPredicate( SCell & adj_surfel,
413  const SurfelPredicate & sp,
414  DGtal::Dimension track_dir,
415  bool pos ) const
416 {
417  BOOST_CONCEPT_ASSERT(( concepts::CSurfelPredicate<SurfelPredicate> ));
418 
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." );
423 
424  // Check if it goes outside the space.
425  if ( ( pos && mySpace->sIsMax( surfel(), track_dir ) )
426  || ( !pos && mySpace->sIsMin( surfel(), track_dir ) )
427  )
428  return 0;
429 
430  // Integer x_orth = mySpace->sCoord( surfel(), orthDir() );
431  SCell tmp_surfel = adj_surfel;
432 
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;
439 
440  // Check second next bel.
441  adj_surfel = follower2( track_dir, pos );
442  if ( sp( adj_surfel ) ) return 2;
443 
444  // Check third one.
445  adj_surfel = follower3( track_dir, pos );
446  if ( sp( adj_surfel ) ) return 3;
447  }
448  else
449  { // exterior to interior
450  // Check first next bel.
451  adj_surfel = follower3( track_dir, pos );
452  if ( sp( adj_surfel ) ) return 3;
453 
454  // Check second next bel.
455  adj_surfel = follower2( track_dir, pos );
456  if ( sp( adj_surfel ) ) return 2;
457 
458  // Check third one.
459  adj_surfel = follower1( track_dir, pos );
460  if ( sp( adj_surfel ) ) return 1;
461  }
462  adj_surfel = tmp_surfel;
463  return 0;
464 }
465 
466 
467 ///////////////////////////////////////////////////////////////////////////////
468 // Interface - public :
469 //-----------------------------------------------------------------------------
470 template <typename TKSpace>
471 inline
472 void
473 DGtal::SurfelNeighborhood<TKSpace>::selfDisplay ( std::ostream & out ) const
474 {
475  out << "[SurfelNeighborhood]";
476 }
477 //-----------------------------------------------------------------------------
478 template <typename TKSpace>
479 inline
480 bool
481 DGtal::SurfelNeighborhood<TKSpace>::isValid() const
482 {
483  return true;
484 }
485 
486 ///////////////////////////////////////////////////////////////////////////////
487 // Implementation of inline functions //
488 
489 template <typename TKSpace>
490 inline
491 std::ostream&
492 DGtal::operator<< ( std::ostream & out,
493  const SurfelNeighborhood<TKSpace> & object )
494 {
495  object.selfDisplay( out );
496  return out;
497 }
498 
499 // //
500 ///////////////////////////////////////////////////////////////////////////////
501 
502