DGtal 1.4.0
Loading...
Searching...
No Matches
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//-----------------------------------------------------------------------------
44template <typename TKSpace>
45inline
46DGtal::SurfelNeighborhood<TKSpace>::
47~SurfelNeighborhood()
48{}
49//-----------------------------------------------------------------------------
50template <typename TKSpace>
51inline
52DGtal::SurfelNeighborhood<TKSpace>::
53SurfelNeighborhood()
54 : mySpace( 0 ), mySurfelAdj( 0 )
55{}
56//-----------------------------------------------------------------------------
57template <typename TKSpace>
58inline
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 )
64{}
65//-----------------------------------------------------------------------------
66template <typename TKSpace>
67inline
68DGtal::SurfelNeighborhood<TKSpace> &
69DGtal::SurfelNeighborhood<TKSpace>::
70operator= ( 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//-----------------------------------------------------------------------------
83template <typename TKSpace>
84inline
85void
86DGtal::SurfelNeighborhood<TKSpace>::
87init( 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//-----------------------------------------------------------------------------
99template <typename TKSpace>
100inline
101void
102DGtal::SurfelNeighborhood<TKSpace>::
103setSurfel( 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//-----------------------------------------------------------------------------
114template <typename TKSpace>
115inline
116const typename DGtal::SurfelNeighborhood<TKSpace>::SCell &
117DGtal::SurfelNeighborhood<TKSpace>::
118surfel() const
119{
120 return mySurfel;
121}
122//-----------------------------------------------------------------------------
123template <typename TKSpace>
124inline
125DGtal::Dimension
126DGtal::SurfelNeighborhood<TKSpace>::
127orthDir() const
128{
129 return myOrthDir;
130}
131
132//-----------------------------------------------------------------------------
133//----------------------- spel services -------------------------
134//-----------------------------------------------------------------------------
135template <typename TKSpace>
136inline
137typename DGtal::SurfelNeighborhood<TKSpace>::SCell
138DGtal::SurfelNeighborhood<TKSpace>::
139innerSpel() const
140{
141 ASSERT( mySpace != 0 );
142 return mySpace->sIncident( surfel(), orthDir(), myOrthDirect );
143}
144//-----------------------------------------------------------------------------
145template <typename TKSpace>
146inline
147typename DGtal::SurfelNeighborhood<TKSpace>::SCell
148DGtal::SurfelNeighborhood<TKSpace>::
149outerSpel() const
150{
151 ASSERT( mySpace != 0 );
152 return mySpace->sIncident( surfel(), orthDir(), ! myOrthDirect );
153}
154//-----------------------------------------------------------------------------
155template <typename TKSpace>
156inline
157typename DGtal::SurfelNeighborhood<TKSpace>::SCell
158DGtal::SurfelNeighborhood<TKSpace>::
159innerAdjacentSpel( 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//-----------------------------------------------------------------------------
165template <typename TKSpace>
166inline
167typename DGtal::SurfelNeighborhood<TKSpace>::SCell
168DGtal::SurfelNeighborhood<TKSpace>::
169outerAdjacentSpel( 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//-----------------------------------------------------------------------------
178template <typename TKSpace>
179inline
180typename DGtal::SurfelNeighborhood<TKSpace>::SCell
181DGtal::SurfelNeighborhood<TKSpace>::
182follower1( 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//-----------------------------------------------------------------------------
188template <typename TKSpace>
189inline
190typename DGtal::SurfelNeighborhood<TKSpace>::SCell
191DGtal::SurfelNeighborhood<TKSpace>::
192follower2( 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//-----------------------------------------------------------------------------
198template <typename TKSpace>
199inline
200typename DGtal::SurfelNeighborhood<TKSpace>::SCell
201DGtal::SurfelNeighborhood<TKSpace>::
202follower3( 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//-----------------------------------------------------------------------------
211template <typename TKSpace>
212template <typename SpelSet>
213inline
214unsigned int
215DGtal::SurfelNeighborhood<TKSpace>::
216getAdjacentOnSpelSet( 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//-----------------------------------------------------------------------------
276template <typename TKSpace>
277template <typename DigitalSet>
278inline
279unsigned int
280DGtal::SurfelNeighborhood<TKSpace>::
281getAdjacentOnDigitalSet( 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//-----------------------------------------------------------------------------
344template <typename TKSpace>
345template <typename PointPredicate>
346unsigned int
347DGtal::SurfelNeighborhood<TKSpace>::
348getAdjacentOnPointPredicate( 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//-----------------------------------------------------------------------------
408template <typename TKSpace>
409template <typename SurfelPredicate>
410unsigned int
411DGtal::SurfelNeighborhood<TKSpace>::
412getAdjacentOnSurfelPredicate( 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//-----------------------------------------------------------------------------
470template <typename TKSpace>
471inline
472void
473DGtal::SurfelNeighborhood<TKSpace>::selfDisplay ( std::ostream & out ) const
474{
475 out << "[SurfelNeighborhood]";
476}
477//-----------------------------------------------------------------------------
478template <typename TKSpace>
479inline
480bool
481DGtal::SurfelNeighborhood<TKSpace>::isValid() const
482{
483 return true;
484}
485
486///////////////////////////////////////////////////////////////////////////////
487// Implementation of inline functions //
488
489template <typename TKSpace>
490inline
491std::ostream&
492DGtal::operator<< ( std::ostream & out,
493 const SurfelNeighborhood<TKSpace> & object )
494{
495 object.selfDisplay( out );
496 return out;
497}
498
499// //
500///////////////////////////////////////////////////////////////////////////////
501
502