DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
SurfelNeighborhood.ih
1 
30 
31 #include <cstdlib>
32 #include "DGtal/kernel/CPointPredicate.h"
33 #include "DGtal/topology/CSurfelPredicate.h"
35 
37 // IMPLEMENTATION of inline methods.
39 
41 // ----------------------- Standard services ------------------------------
42 
43 //-----------------------------------------------------------------------------
44 template <typename TKSpace>
45 inline
48 {}
49 //-----------------------------------------------------------------------------
50 template <typename TKSpace>
51 inline
54  : mySpace( 0 ), mySurfelAdj( 0 )
55 {}
56 //-----------------------------------------------------------------------------
57 template <typename TKSpace>
58 inline
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
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
87 init( const KSpace* space,
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
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
118 surfel() const
119 {
120  return mySurfel;
121 }
122 //-----------------------------------------------------------------------------
123 template <typename TKSpace>
124 inline
125 Dimension
127 orthDir() const
128 {
129  return myOrthDir;
130 }
131 
132 //-----------------------------------------------------------------------------
133 //----------------------- spel services -------------------------
134 //-----------------------------------------------------------------------------
135 template <typename TKSpace>
136 inline
139 innerSpel() const
140 {
141  ASSERT( mySpace != 0 );
142  return mySpace->sIncident( surfel(), orthDir(), myOrthDirect );
143 }
144 //-----------------------------------------------------------------------------
145 template <typename TKSpace>
146 inline
149 outerSpel() const
150 {
151  ASSERT( mySpace != 0 );
152  return mySpace->sIncident( surfel(), orthDir(), ! myOrthDirect );
153 }
154 //-----------------------------------------------------------------------------
155 template <typename TKSpace>
156 inline
159 innerAdjacentSpel( 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
169 outerAdjacentSpel( 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
182 follower1( 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
192 follower2( Dimension track_dir, bool pos ) const
193 {
194  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
195  return mySpace->sAdjacent( surfel(), track_dir, pos );
196  // return pos
197  // ? mySpace->sGetIncr( surfel(), track_dir )
198  // : mySpace->sGetDecr( surfel(), track_dir );
199 }
200 //-----------------------------------------------------------------------------
201 template <typename TKSpace>
202 inline
205 follower3( Dimension track_dir, bool pos ) const
206 {
207  ASSERT( ( mySpace != 0 ) && ( track_dir != myOrthDir ) );
208  return mySpace->sIncident( outerSpel(), track_dir, pos );
209 }
210 
211 //-----------------------------------------------------------------------------
212 // ----------------------- Surfel adjacency services --------------------
213 //-----------------------------------------------------------------------------
214 template <typename TKSpace>
215 template <typename SpelSet>
216 inline
217 unsigned int
220  const SpelSet & obj,
221  Dimension track_dir,
222  bool pos ) const
223 {
224  // Check that [m_surfel] is a bel.
225  ASSERT( mySpace != 0 );
226  ASSERT( mySurfelAdj != 0 );
227  Cell uinner_spel = mySpace->unsigns( innerSpel() );
228  ASSERT( obj.find( uinner_spel ) != obj.end() );
229  ASSERT( obj.find( mySpace->unsigns( outerSpel() ) ) == obj.end() );
230 
231  // Check if it goes outside the space.
232  if ( ( pos && mySpace->uisMax( uinner_spel, track_dir ) )
233  || ( ( ! pos ) && mySpace->uisMin( uinner_spel, track_dir ) ) )
234  return 0;
235  // Check type of surfel adjacency.
236  if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
237  { // interior to exterior
238  // Check first next bel.
239  if ( obj.find( mySpace->unsigns( innerAdjacentSpel( track_dir, pos ) ) )
240  == obj.end() )
241  {
242  adj_surfel = follower1( track_dir, pos );
243  return 1;
244  }
245  // Check second next bel.
246  if ( obj.find( mySpace->unsigns( outerAdjacentSpel( track_dir, pos ) ) )
247  == obj.end() )
248  {
249  adj_surfel = follower2( track_dir, pos );
250  return 2;
251  }
252  // The third one is then the right one.
253  adj_surfel = follower3( track_dir, pos );
254  return 3;
255  }
256  else // if ( mySurfelAdj->getAdjacency( m_orth_dir, track_dir ) )
257  { // exterior to interior
258  // Check first next bel.
259  if ( obj.find( mySpace->unsigns( outerAdjacentSpel( track_dir, pos ) ) )
260  != obj.end() )
261  {
262  adj_surfel = follower3( track_dir, pos );
263  return 3;
264  }
265  // Check second next bel.
266  if ( obj.find( mySpace->unsigns( innerAdjacentSpel( track_dir, pos ) ) )
267  != obj.end() )
268  {
269  adj_surfel = follower2( track_dir, pos );
270  return 2;
271  }
272  // The third one is then the right one.
273  adj_surfel = follower1( track_dir, pos );
274  return 1;
275  }
276 }
277 //-----------------------------------------------------------------------------
278 template <typename TKSpace>
279 template <typename DigitalSet>
280 inline
281 unsigned int
284  const DigitalSet & obj,
285  Dimension track_dir,
286  bool pos ) const
287 {
288  // Check that [m_surfel] is a bel.
289  ASSERT( mySpace != 0 );
290  ASSERT( mySurfelAdj != 0 );
291  Point inner_spel_pt = mySpace->sCoords( innerSpel() );
292  ASSERT( obj.find( inner_spel_pt ) != obj.end() );
293  ASSERT( obj.find( mySpace->sCoords( outerSpel() ) ) == obj.end() );
294 
295  // Check if it goes outside the space.
296  if ( ( pos && ( inner_spel_pt[ track_dir ] == mySpace->max( track_dir ) ) )
297  ||
298  ( (!pos) && ( inner_spel_pt[ track_dir ] == mySpace->min( track_dir ) ) )
299  )
300  return 0;
301  // Check type of surfel adjacency.
302  if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
303  { // interior to exterior
304  // Check first next bel.
305  if ( obj.find( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) )
306  == obj.end() )
307  {
308  adj_surfel = follower1( track_dir, pos );
309  return 1;
310  }
311  // Check second next bel.
312  if ( obj.find( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) )
313  == obj.end() )
314  {
315  adj_surfel = follower2( track_dir, pos );
316  return 2;
317  }
318  // The third one is then the right one.
319  adj_surfel = follower3( track_dir, pos );
320  return 3;
321  }
322  else // if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
323  { // exterior to interior
324  // Check first next bel.
325  if ( obj.find( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) )
326  != obj.end() )
327  {
328  adj_surfel = follower3( track_dir, pos );
329  return 3;
330  }
331  // Check second next bel.
332  if ( obj.find( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) )
333  != obj.end() )
334  {
335  adj_surfel = follower2( track_dir, pos );
336  return 2;
337  }
338  // The third one is then the right one.
339  adj_surfel = follower1( track_dir, pos );
340  return 1;
341  }
342 }
343 
344 
345 //-----------------------------------------------------------------------------
346 template <typename TKSpace>
347 template <typename PointPredicate>
348 unsigned int
351  const PointPredicate & pp,
352  Dimension track_dir,
353  bool pos ) const
354 {
355  BOOST_CONCEPT_ASSERT(( CPointPredicate<PointPredicate> ));
356 
357  // Check that [m_surfel] is a bel.
358  ASSERT( mySpace != 0 );
359  ASSERT( mySurfelAdj != 0 );
360  Point inner_spel_pt = mySpace->sCoords( innerSpel() );
361  ASSERT( pp( inner_spel_pt ) && "Should be inside." );
362  ASSERT( ! pp( mySpace->sCoords( outerSpel() ) ) && "Should be outside" );
363 
364  // Check if it goes outside the space.
365  if ( ( pos && ( inner_spel_pt[ track_dir ] == mySpace->max( track_dir ) ) )
366  ||
367  ( (!pos) && ( inner_spel_pt[ track_dir ] == mySpace->min( track_dir ) ) )
368  )
369  return 0;
370  // Check type of surfel adjacency.
371  if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
372  { // interior to exterior
373  // Check first next bel.
374  if ( ! pp( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) ) )
375  {
376  adj_surfel = follower1( track_dir, pos );
377  return 1;
378  }
379  // Check second next bel.
380  if ( ! pp( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) ) )
381  {
382  adj_surfel = follower2( track_dir, pos );
383  return 2;
384  }
385  // The third one is then the right one.
386  adj_surfel = follower3( track_dir, pos );
387  return 3;
388  }
389  else // if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
390  { // exterior to interior
391  // Check first next bel.
392  if ( pp( mySpace->sCoords( outerAdjacentSpel( track_dir, pos ) ) ) )
393  {
394  adj_surfel = follower3( track_dir, pos );
395  return 3;
396  }
397  // Check second next bel.
398  if ( pp( mySpace->sCoords( innerAdjacentSpel( track_dir, pos ) ) ) )
399  {
400  adj_surfel = follower2( track_dir, pos );
401  return 2;
402  }
403  // The third one is then the right one.
404  adj_surfel = follower1( track_dir, pos );
405  return 1;
406  }
407 }
408 
409 //-----------------------------------------------------------------------------
410 template <typename TKSpace>
411 template <typename SurfelPredicate>
412 unsigned int
415  const SurfelPredicate & sp,
416  Dimension track_dir,
417  bool pos ) const
418 {
419  BOOST_CONCEPT_ASSERT(( CSurfelPredicate<SurfelPredicate> ));
420  typedef typename KSpace::Integer Integer;
421 
422  // Check that [m_surfel] is a bel.
423  ASSERT( mySpace != 0 );
424  ASSERT( mySurfelAdj != 0 );
425  ASSERT( sp( mySurfel ) && "Current surfel should satisfy predicate." );
426 
427  // Check if it goes outside the space.
428  Integer x_track = mySpace->sCoord( surfel(), track_dir );
429  if ( ( pos && ( x_track == mySpace->max( track_dir ) ) )
430  ||
431  ( (!pos) && ( x_track == mySpace->min( track_dir ) ) )
432  )
433  return 0;
434  // Integer x_orth = mySpace->sCoord( surfel(), orthDir() );
435  SCell tmp_surfel = adj_surfel;
436 
437  // Check type of surfel adjacency.
438  if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
439  { // interior to exterior
440  // Check first next bel.
441  // if ( ( myOrthDirect && ( x_orth != mySpace->max( orthDir() ) ) )
442  // || ( ! myOrthDirect && ( x_orth != mySpace->min( orthDir() ) ) ) )
443  // {
444  adj_surfel = follower1( track_dir, pos );
445  if ( sp( adj_surfel ) ) return 1;
446  // }
447  // Check second next bel.
448  // if ( ( pos && ( x_track != mySpace->max( track_dir ) ) )
449  // || ( ! pos && ( x_track != mySpace->min( track_dir ) ) ) )
450  // {
451  adj_surfel = follower2( track_dir, pos );
452  if ( sp( adj_surfel ) ) return 2;
453  // }
454  // Check third one.
455  // if ( ( ! myOrthDirect && ( x_orth != mySpace->max( orthDir() ) ) )
456  // || ( myOrthDirect && ( x_orth != mySpace->min( orthDir() ) ) ) )
457  // {
458  adj_surfel = follower3( track_dir, pos );
459  if ( sp( adj_surfel ) ) return 3;
460  // }
461  }
462  else // if ( mySurfelAdj->getAdjacency( orthDir(), track_dir ) )
463  { // exterior to interior
464  // Check first next bel.
465  // if ( ( ! myOrthDirect && ( x_orth != mySpace->max( orthDir() ) ) )
466  // || ( myOrthDirect && ( x_orth != mySpace->min( orthDir() ) ) ) )
467  // {
468  adj_surfel = follower3( track_dir, pos );
469  if ( sp( adj_surfel ) ) return 3;
470  // }
471  // Check second next bel.
472  // if ( ( pos && ( x_track != mySpace->max( track_dir ) ) )
473  // || ( ! pos && ( x_track != mySpace->min( track_dir ) ) ) )
474  // {
475  adj_surfel = follower2( track_dir, pos );
476  if ( sp( adj_surfel ) ) return 2;
477  // }
478  // Check third one.
479  // if ( ( myOrthDirect && ( x_orth != mySpace->max( orthDir() ) ) )
480  // || ( ! myOrthDirect && ( x_orth != mySpace->min( orthDir() ) ) ) )
481  // {
482  adj_surfel = follower1( track_dir, pos );
483  if ( sp( adj_surfel ) ) return 1;
484  // }
485  }
486  adj_surfel = tmp_surfel;
487  return 0;
488 }
489 
490 
492 // Interface - public :
493 //-----------------------------------------------------------------------------
494 template <typename TKSpace>
495 inline
496 void
498 {
499  out << "[SurfelNeighborhood]";
500 }
501 //-----------------------------------------------------------------------------
502 template <typename TKSpace>
503 inline
504 bool
506 {
507  return true;
508 }
509 
511 // Implementation of inline functions //
512 
513 template <typename TKSpace>
514 inline
515 std::ostream&
516 DGtal::operator<< ( std::ostream & out,
517  const SurfelNeighborhood<TKSpace> & object )
518 {
519  object.selfDisplay( out );
520  return out;
521 }
522 
523 // //
525 
526