DGtal  1.5.beta
LightImplicitDigitalSurface.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 LightImplicitDigitalSurface.ih
19  * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20  * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
21  *
22  * @date 2011/09/01
23  *
24  * Implementation of inline methods defined in LightImplicitDigitalSurface.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 #include <iterator>
33 #include "DGtal/graph/CVertexPredicate.h"
34 #include "DGtal/topology/helpers/Surfaces.h"
35 //////////////////////////////////////////////////////////////////////////////
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 // IMPLEMENTATION of inline methods.
39 ///////////////////////////////////////////////////////////////////////////////
40 
41 //-----------------------------------------------------------------------------
42 template <typename TKSpace, typename TPointPredicate>
43 inline
44 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
45 ::~Tracker()
46 {}
47 //-----------------------------------------------------------------------------
48 template <typename TKSpace, typename TPointPredicate>
49 inline
50 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
51 ::Tracker( ConstAlias<DigitalSurfaceContainer> aSurface,
52  const Surfel & s )
53  : mySurface( aSurface ), myNeighborhood()
54 {
55  myNeighborhood.init( & surface().space(),
56  & surface().surfelAdjacency(),
57  s );
58 }
59 //-----------------------------------------------------------------------------
60 template <typename TKSpace, typename TPointPredicate>
61 inline
62 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
63 ::Tracker( const Tracker & other )
64  : mySurface( other.mySurface ), myNeighborhood( other.myNeighborhood )
65 {
66 }
67 //-----------------------------------------------------------------------------
68 template <typename TKSpace, typename TPointPredicate>
69 inline
70 const typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
71 ::DigitalSurfaceContainer &
72 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
73 ::surface() const
74 {
75  return mySurface;
76 }
77 //-----------------------------------------------------------------------------
78 template <typename TKSpace, typename TPointPredicate>
79 inline
80 const typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
81 ::Surfel &
82 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
83 ::current() const
84 {
85  return myNeighborhood.surfel();
86 }
87 //-----------------------------------------------------------------------------
88 template <typename TKSpace, typename TPointPredicate>
89 inline
90 DGtal::Dimension
91 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
92 ::orthDir() const
93 {
94  return myNeighborhood.orthDir();
95 }
96 //-----------------------------------------------------------------------------
97 template <typename TKSpace, typename TPointPredicate>
98 inline
99 void
100 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
101 ::move( const Surfel & s )
102 {
103  ASSERT( surface().isInside( s ) );
104  myNeighborhood.setSurfel( s );
105 }
106 //-----------------------------------------------------------------------------
107 template <typename TKSpace, typename TPointPredicate>
108 inline
109 DGtal::uint8_t
110 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
111 ::adjacent( Surfel & s, Dimension d, bool pos ) const
112 {
113  return static_cast<uint8_t>
114  ( myNeighborhood.getAdjacentOnPointPredicate( s, surface().pointPredicate(), d, pos ) );
115 }
116 
117 ///////////////////////////////////////////////////////////////////////////////
118 // ----------------------- Standard services ------------------------------
119 
120 //-----------------------------------------------------------------------------
121 template <typename TKSpace, typename TPointPredicate>
122 inline
123 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::~LightImplicitDigitalSurface()
124 {
125 }
126 //-----------------------------------------------------------------------------
127 template <typename TKSpace, typename TPointPredicate>
128 inline
129 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::LightImplicitDigitalSurface
130 ( const LightImplicitDigitalSurface & other )
131  : myKSpace( other.myKSpace ),
132  myPointPredicate( other.myPointPredicate ),
133  mySurfelAdjacency( other.mySurfelAdjacency ),
134  mySurfel( other.mySurfel ),
135  myTracker( *this, other.mySurfel )
136 {
137 }
138 //-----------------------------------------------------------------------------
139 template <typename TKSpace, typename TPointPredicate>
140 inline
141 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::LightImplicitDigitalSurface
142 ( ConstAlias<KSpace> aKSpace,
143  ConstAlias<PointPredicate> aPP,
144  const Adjacency & adj,
145  const Surfel & s )
146  : myKSpace( aKSpace ), myPointPredicate( aPP ), mySurfelAdjacency( adj ),
147  mySurfel( s ), myTracker( *this, s )
148 {
149 }
150 //-----------------------------------------------------------------------------
151 template <typename TKSpace, typename TPointPredicate>
152 inline
153 const
154 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Adjacency &
155 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::surfelAdjacency() const
156 {
157  return mySurfelAdjacency;
158 }
159 //-----------------------------------------------------------------------------
160 template <typename TKSpace, typename TPointPredicate>
161 inline
162 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Adjacency &
163 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::surfelAdjacency()
164 {
165  return mySurfelAdjacency;
166 }
167 //-----------------------------------------------------------------------------
168 template <typename TKSpace, typename TPointPredicate>
169 inline
170 const
171 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::PointPredicate &
172 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::pointPredicate() const
173 {
174  return myPointPredicate;
175 }
176 
177 //-----------------------------------------------------------------------------
178 // --------- CDigitalSurfaceContainer realization -------------------------
179 //-----------------------------------------------------------------------------
180 template <typename TKSpace, typename TPointPredicate>
181 inline
182 const typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::KSpace &
183 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::space() const
184 {
185  return myKSpace;
186 }
187 //-----------------------------------------------------------------------------
188 template <typename TKSpace, typename TPointPredicate>
189 inline
190 bool
191 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::isInside
192 ( const Surfel & s ) const
193 {
194  Dimension k = myKSpace.sOrthDir( s );
195  // checks if the surfel is on the space boundary.
196  if ( myKSpace.sIsMax( s, k ) || myKSpace.sIsMin( s, k ) )
197  return false;
198  // p1 must be in the set and p2 must not be in the set.
199  SCell spel1 = myKSpace.sDirectIncident( s, k );
200  Point p1 = myKSpace.sCoords( spel1 );
201  if ( myPointPredicate( p1 ) )
202  {
203  SCell spel2 = myKSpace.sIndirectIncident( s, k );
204  Point p2 = myKSpace.sCoords( spel2 );
205  return ! myPointPredicate( p2 );
206  }
207  return false;
208 }
209 //-----------------------------------------------------------------------------
210 template <typename TKSpace, typename TPointPredicate>
211 inline
212 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::SurfelConstIterator
213 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::begin() const
214 {
215  SelfVisitorRange range( new SelfVisitor( *this, mySurfel ) );
216  return range.begin();
217 }
218 //-----------------------------------------------------------------------------
219 template <typename TKSpace, typename TPointPredicate>
220 inline
221 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::SurfelConstIterator
222 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::end() const
223 {
224  return SurfelConstIterator();
225 }
226 //-----------------------------------------------------------------------------
227 template <typename TKSpace, typename TPointPredicate>
228 inline
229 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Size
230 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::nbSurfels() const
231 {
232  Size nb = 0;
233  for ( SurfelConstIterator it = begin(), it_end = end(); it != it_end; ++it )
234  ++nb;
235  return nb;
236 }
237 //-----------------------------------------------------------------------------
238 template <typename TKSpace, typename TPointPredicate>
239 inline
240 bool
241 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::empty() const
242 {
243  return false;
244 }
245 //-----------------------------------------------------------------------------
246 template <typename TKSpace, typename TPointPredicate>
247 inline
248 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::DigitalSurfaceTracker*
249 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::newTracker
250 ( const Surfel & s ) const
251 {
252  return new Tracker( *this, s );
253 }
254 //-----------------------------------------------------------------------------
255 template <typename TKSpace, typename TPointPredicate>
256 inline
257 DGtal::Connectedness
258 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::connectedness() const
259 {
260  return CONNECTED;
261 }
262 //-----------------------------------------------------------------------------
263 // ----------------- UndirectedSimplePreGraph realization --------------------
264 //-----------------------------------------------------------------------------
265 template <typename TKSpace, typename TPointPredicate>
266 inline
267 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Size
268 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>
269 ::degree( const Vertex & v ) const
270 {
271  Size d = 0;
272  Vertex s;
273  myTracker.move( v );
274  for ( typename KSpace::DirIterator q = space().sDirs( v );
275  q != 0; ++q )
276  {
277  if ( myTracker.adjacent( s, *q, true ) )
278  ++d;
279  if ( myTracker.adjacent( s, *q, false ) )
280  ++d;
281  }
282  return d;
283 }
284 //-----------------------------------------------------------------------------
285 template <typename TKSpace, typename TPointPredicate>
286 template <typename OutputIterator>
287 inline
288 void
289 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>
290 ::writeNeighbors( OutputIterator & it,
291  const Vertex & v ) const
292 {
293  Vertex s;
294  myTracker.move( v );
295  for ( typename KSpace::DirIterator q = space().sDirs( v );
296  q != 0; ++q )
297  {
298  if ( myTracker.adjacent( s, *q, true ) )
299  *it++ = s;
300  if ( myTracker.adjacent( s, *q, false ) )
301  *it++ = s;
302  }
303 }
304 //-----------------------------------------------------------------------------
305 template <typename TKSpace, typename TPointPredicate>
306 template <typename OutputIterator, typename VertexPredicate>
307 inline
308 void
309 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>
310 ::writeNeighbors( OutputIterator & it,
311  const Vertex & v,
312  const VertexPredicate & pred ) const
313 {
314  BOOST_CONCEPT_ASSERT(( concepts::CVertexPredicate< VertexPredicate > ));
315  Vertex s;
316  myTracker.move( v );
317  for ( typename KSpace::DirIterator q = space().sDirs( v );
318  q != 0; ++q )
319  {
320  if ( myTracker.adjacent( s, *q, true ) )
321  {
322  if ( pred( s ) ) *it++ = s;
323  }
324  if ( myTracker.adjacent( s, *q, false ) )
325  {
326  if ( pred( s ) ) *it++ = s;
327  }
328  }
329 }
330 //-----------------------------------------------------------------------------
331 template <typename TKSpace, typename TPointPredicate>
332 inline
333 typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Size
334 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>
335 ::bestCapacity() const
336 {
337  return KSpace::dimension * 2 - 2;
338 }
339 
340 
341 // ------------------------- Hidden services ------------------------------
342 
343 ///////////////////////////////////////////////////////////////////////////////
344 // Interface - public :
345 
346 /**
347  * Writes/Displays the object on an output stream.
348  * @param out the output stream where the object is written.
349  */
350 template <typename TKSpace, typename TPointPredicate>
351 inline
352 void
353 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::selfDisplay ( std::ostream & out ) const
354 {
355  out << "[LightImplicitDigitalSurface]";
356 }
357 
358 /**
359  * Checks the validity/consistency of the object.
360  * @return 'true' if the object is valid, 'false' otherwise.
361  */
362 template <typename TKSpace, typename TPointPredicate>
363 inline
364 bool
365 DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::isValid() const
366 {
367  return true;
368 }
369 
370 
371 
372 ///////////////////////////////////////////////////////////////////////////////
373 // Implementation of inline functions //
374 
375 template <typename TKSpace, typename TPointPredicate>
376 inline
377 std::ostream&
378 DGtal::operator<< ( std::ostream & out,
379  const LightImplicitDigitalSurface< TKSpace, TPointPredicate > & object )
380 {
381  object.selfDisplay( out );
382  return out;
383 }
384 
385 // //
386 ///////////////////////////////////////////////////////////////////////////////
387 
388