DGtal 1.3.0
Loading...
Searching...
No Matches
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//-----------------------------------------------------------------------------
42template <typename TKSpace, typename TPointPredicate>
43inline
44DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
45::~Tracker()
46{}
47//-----------------------------------------------------------------------------
48template <typename TKSpace, typename TPointPredicate>
49inline
50DGtal::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//-----------------------------------------------------------------------------
60template <typename TKSpace, typename TPointPredicate>
61inline
62DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
63::Tracker( const Tracker & other )
64 : mySurface( other.mySurface ), myNeighborhood( other.myNeighborhood )
65{
66}
67//-----------------------------------------------------------------------------
68template <typename TKSpace, typename TPointPredicate>
69inline
70const typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
71::DigitalSurfaceContainer &
72DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
73::surface() const
74{
75 return mySurface;
76}
77//-----------------------------------------------------------------------------
78template <typename TKSpace, typename TPointPredicate>
79inline
80const typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
81::Surfel &
82DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
83::current() const
84{
85 return myNeighborhood.surfel();
86}
87//-----------------------------------------------------------------------------
88template <typename TKSpace, typename TPointPredicate>
89inline
90DGtal::Dimension
91DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
92::orthDir() const
93{
94 return myNeighborhood.orthDir();
95}
96//-----------------------------------------------------------------------------
97template <typename TKSpace, typename TPointPredicate>
98inline
99void
100DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Tracker
101::move( const Surfel & s )
102{
103 ASSERT( surface().isInside( s ) );
104 myNeighborhood.setSurfel( s );
105}
106//-----------------------------------------------------------------------------
107template <typename TKSpace, typename TPointPredicate>
108inline
109DGtal::uint8_t
110DGtal::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//-----------------------------------------------------------------------------
121template <typename TKSpace, typename TPointPredicate>
122inline
123DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::~LightImplicitDigitalSurface()
124{
125}
126//-----------------------------------------------------------------------------
127template <typename TKSpace, typename TPointPredicate>
128inline
129DGtal::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//-----------------------------------------------------------------------------
139template <typename TKSpace, typename TPointPredicate>
140inline
141DGtal::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//-----------------------------------------------------------------------------
151template <typename TKSpace, typename TPointPredicate>
152inline
153const
154typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Adjacency &
155DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::surfelAdjacency() const
156{
157 return mySurfelAdjacency;
158}
159//-----------------------------------------------------------------------------
160template <typename TKSpace, typename TPointPredicate>
161inline
162typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Adjacency &
163DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::surfelAdjacency()
164{
165 return mySurfelAdjacency;
166}
167//-----------------------------------------------------------------------------
168template <typename TKSpace, typename TPointPredicate>
169inline
170const
171typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::PointPredicate &
172DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::pointPredicate() const
173{
174 return myPointPredicate;
175}
176
177//-----------------------------------------------------------------------------
178// --------- CDigitalSurfaceContainer realization -------------------------
179//-----------------------------------------------------------------------------
180template <typename TKSpace, typename TPointPredicate>
181inline
182const typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::KSpace &
183DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::space() const
184{
185 return myKSpace;
186}
187//-----------------------------------------------------------------------------
188template <typename TKSpace, typename TPointPredicate>
189inline
190bool
191DGtal::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//-----------------------------------------------------------------------------
210template <typename TKSpace, typename TPointPredicate>
211inline
212typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::SurfelConstIterator
213DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::begin() const
214{
215 SelfVisitorRange range( new SelfVisitor( *this, mySurfel ) );
216 return range.begin();
217}
218//-----------------------------------------------------------------------------
219template <typename TKSpace, typename TPointPredicate>
220inline
221typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::SurfelConstIterator
222DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::end() const
223{
224 return SurfelConstIterator();
225}
226//-----------------------------------------------------------------------------
227template <typename TKSpace, typename TPointPredicate>
228inline
229typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Size
230DGtal::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//-----------------------------------------------------------------------------
238template <typename TKSpace, typename TPointPredicate>
239inline
240bool
241DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::empty() const
242{
243 return false;
244}
245//-----------------------------------------------------------------------------
246template <typename TKSpace, typename TPointPredicate>
247inline
248typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::DigitalSurfaceTracker*
249DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::newTracker
250( const Surfel & s ) const
251{
252 return new Tracker( *this, s );
253}
254//-----------------------------------------------------------------------------
255template <typename TKSpace, typename TPointPredicate>
256inline
257DGtal::Connectedness
258DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::connectedness() const
259{
260 return CONNECTED;
261}
262//-----------------------------------------------------------------------------
263// ----------------- UndirectedSimplePreGraph realization --------------------
264//-----------------------------------------------------------------------------
265template <typename TKSpace, typename TPointPredicate>
266inline
267typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Size
268DGtal::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//-----------------------------------------------------------------------------
285template <typename TKSpace, typename TPointPredicate>
286template <typename OutputIterator>
287inline
288void
289DGtal::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//-----------------------------------------------------------------------------
305template <typename TKSpace, typename TPointPredicate>
306template <typename OutputIterator, typename VertexPredicate>
307inline
308void
309DGtal::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//-----------------------------------------------------------------------------
331template <typename TKSpace, typename TPointPredicate>
332inline
333typename DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::Size
334DGtal::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 */
350template <typename TKSpace, typename TPointPredicate>
351inline
352void
353DGtal::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 */
362template <typename TKSpace, typename TPointPredicate>
363inline
364bool
365DGtal::LightImplicitDigitalSurface<TKSpace,TPointPredicate>::isValid() const
366{
367 return true;
368}
369
370
371
372///////////////////////////////////////////////////////////////////////////////
373// Implementation of inline functions //
374
375template <typename TKSpace, typename TPointPredicate>
376inline
377std::ostream&
378DGtal::operator<< ( std::ostream & out,
379 const LightImplicitDigitalSurface< TKSpace, TPointPredicate > & object )
380{
381 object.selfDisplay( out );
382 return out;
383}
384
385// //
386///////////////////////////////////////////////////////////////////////////////
387
388