DGtal  1.2.0
DigitalSetBoundary.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 DigitalSetBoundary.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 DigitalSetBoundary.h
25  *
26  * This file is part of the DGtal library.
27  */
28 
29 
30 //////////////////////////////////////////////////////////////////////////////
31 #include <cstdlib>
32 #include <iterator>
33 #include "DGtal/topology/helpers/Surfaces.h"
34 //////////////////////////////////////////////////////////////////////////////
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // IMPLEMENTATION of inline methods.
38 ///////////////////////////////////////////////////////////////////////////////
39 
40 //-----------------------------------------------------------------------------
41 template <typename TKSpace, typename TDigitalSet>
42 inline
43 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
44 ::~Tracker()
45 {}
46 //-----------------------------------------------------------------------------
47 template <typename TKSpace, typename TDigitalSet>
48 inline
49 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
50 ::Tracker( ConstAlias<DigitalSurfaceContainer> aSurface,
51  const Surfel & s )
52  : mySurface( aSurface ), myNeighborhood()
53 {
54  myNeighborhood.init( & surface().space(),
55  & surface().surfelAdjacency(),
56  s );
57 }
58 //-----------------------------------------------------------------------------
59 template <typename TKSpace, typename TDigitalSet>
60 inline
61 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
62 ::Tracker( const Tracker & other )
63  : mySurface( other.mySurface ), myNeighborhood( other.myNeighborhood )
64 {
65 }
66 //-----------------------------------------------------------------------------
67 template <typename TKSpace, typename TDigitalSet>
68 inline
69 const typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
70 ::DigitalSurfaceContainer &
71 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
72 ::surface() const
73 {
74  return mySurface;
75 }
76 //-----------------------------------------------------------------------------
77 template <typename TKSpace, typename TDigitalSet>
78 inline
79 const typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
80 ::Surfel &
81 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
82 ::current() const
83 {
84  return myNeighborhood.surfel();
85 }
86 //-----------------------------------------------------------------------------
87 template <typename TKSpace, typename TDigitalSet>
88 inline
89 DGtal::Dimension
90 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
91 ::orthDir() const
92 {
93  return myNeighborhood.orthDir();
94 }
95 //-----------------------------------------------------------------------------
96 template <typename TKSpace, typename TDigitalSet>
97 inline
98 void
99 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
100 ::move( const Surfel & s )
101 {
102  ASSERT( surface().isInside( s ) );
103  myNeighborhood.setSurfel( s );
104 }
105 //-----------------------------------------------------------------------------
106 template <typename TKSpace, typename TDigitalSet>
107 inline
108 DGtal::uint8_t
109 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Tracker
110 ::adjacent( Surfel & s, Dimension d, bool pos ) const
111 {
112  return static_cast<uint8_t>
113  ( myNeighborhood.getAdjacentOnPointPredicate( s, surface().digitalSet(), d, pos ) );
114 }
115 
116 ///////////////////////////////////////////////////////////////////////////////
117 // ----------------------- Standard services ------------------------------
118 
119 //-----------------------------------------------------------------------------
120 template <typename TKSpace, typename TDigitalSet>
121 inline
122 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::~DigitalSetBoundary()
123 {
124 }
125 //-----------------------------------------------------------------------------
126 template <typename TKSpace, typename TDigitalSet>
127 inline
128 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::DigitalSetBoundary
129 ( const DigitalSetBoundary & other )
130  : myKSpace( other.myKSpace ), myDigitalSet( other.myDigitalSet ),
131  mySurfelAdjacency( other.mySurfelAdjacency ),
132  mySurfels( other. mySurfels )
133 {
134 }
135 //-----------------------------------------------------------------------------
136 template <typename TKSpace, typename TDigitalSet>
137 inline
138 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::DigitalSetBoundary
139 ( ConstAlias<KSpace> aKSpace,
140  const DigitalSet & aSet,
141  const Adjacency & adj )
142  : myKSpace( aKSpace ), myDigitalSet( aSet ), mySurfelAdjacency( adj )
143 {
144  computeSurfels();
145 }
146 //-----------------------------------------------------------------------------
147 template <typename TKSpace, typename TDigitalSet>
148 inline
149 const
150 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Adjacency &
151 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::surfelAdjacency() const
152 {
153  return mySurfelAdjacency;
154 }
155 //-----------------------------------------------------------------------------
156 template <typename TKSpace, typename TDigitalSet>
157 inline
158 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Adjacency &
159 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::surfelAdjacency()
160 {
161  return mySurfelAdjacency;
162 }
163 //-----------------------------------------------------------------------------
164 template <typename TKSpace, typename TDigitalSet>
165 inline
166 const
167 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::DigitalSet &
168 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::digitalSet() const
169 {
170  return myDigitalSet;
171 }
172 
173 //-----------------------------------------------------------------------------
174 // --------- CDigitalSurfaceContainer realization -------------------------
175 //-----------------------------------------------------------------------------
176 template <typename TKSpace, typename TDigitalSet>
177 inline
178 const typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::KSpace &
179 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::space() const
180 {
181  return myKSpace;
182 }
183 //-----------------------------------------------------------------------------
184 template <typename TKSpace, typename TDigitalSet>
185 inline
186 bool
187 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::isInside
188 ( const Surfel & s ) const
189 {
190  Dimension k = myKSpace.sOrthDir( s );
191  // checks if the surfel is on the space boundary.
192  if ( myKSpace.sIsMax( s, k ) || myKSpace.sIsMin( s, k ) )
193  return false;
194  // p1 must be in the set and p2 must not be in the set.
195  SCell spel1 = myKSpace.sDirectIncident( s, k );
196  Point p1 = myKSpace.sCoords( spel1 );
197  if ( myDigitalSet.find( p1 ) != myDigitalSet.end() )
198  {
199  SCell spel2 = myKSpace.sIndirectIncident( s, k );
200  Point p2 = myKSpace.sCoords( spel2 );
201  return ! ( myDigitalSet.find( p2 ) != myDigitalSet.end() );
202  }
203  return false;
204 }
205 //-----------------------------------------------------------------------------
206 template <typename TKSpace, typename TDigitalSet>
207 inline
208 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::SurfelConstIterator
209 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::begin() const
210 {
211  return mySurfels.begin();
212 }
213 //-----------------------------------------------------------------------------
214 template <typename TKSpace, typename TDigitalSet>
215 inline
216 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::SurfelConstIterator
217 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::end() const
218 {
219  return mySurfels.end();
220 }
221 //-----------------------------------------------------------------------------
222 template <typename TKSpace, typename TDigitalSet>
223 inline
224 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::Size
225 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::nbSurfels() const
226 {
227  return (unsigned int)mySurfels.size();
228 }
229 //-----------------------------------------------------------------------------
230 template <typename TKSpace, typename TDigitalSet>
231 inline
232 bool
233 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::empty() const
234 {
235  return mySurfels.empty();
236 }
237 //-----------------------------------------------------------------------------
238 template <typename TKSpace, typename TDigitalSet>
239 inline
240 typename DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::DigitalSurfaceTracker*
241 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::newTracker
242 ( const Surfel & s ) const
243 {
244  return new Tracker( *this, s );
245 }
246 //-----------------------------------------------------------------------------
247 template <typename TKSpace, typename TDigitalSet>
248 inline
249 DGtal::Connectedness
250 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::connectedness() const
251 {
252  return UNKNOWN;
253 }
254 
255 // ------------------------- Hidden services ------------------------------
256 //-----------------------------------------------------------------------------
257 template <typename TKSpace, typename TDigitalSet>
258 inline
259 void
260 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::computeSurfels()
261 {
262  // Since 0.6, models of CDigitalSet are models of concepts::CPointPredicate.
263  // SetPredicate<DigitalSet> isInSet( myDigitalSet );
264  mySurfels.clear();
265  std::back_insert_iterator<SurfelStorage> output_it =
266  std::back_inserter( mySurfels );
267  Surfaces<KSpace>::sWriteBoundary( output_it,
268  myKSpace,
269  myDigitalSet,
270  myKSpace.lowerBound(),
271  myKSpace.upperBound() );
272 }
273 
274 ///////////////////////////////////////////////////////////////////////////////
275 // Interface - public :
276 
277 /**
278  * Writes/Displays the object on an output stream.
279  * @param out the output stream where the object is written.
280  */
281 template <typename TKSpace, typename TDigitalSet>
282 inline
283 void
284 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::selfDisplay ( std::ostream & out ) const
285 {
286  out << "[DigitalSetBoundary]";
287 }
288 
289 /**
290  * Checks the validity/consistency of the object.
291  * @return 'true' if the object is valid, 'false' otherwise.
292  */
293 template <typename TKSpace, typename TDigitalSet>
294 inline
295 bool
296 DGtal::DigitalSetBoundary<TKSpace,TDigitalSet>::isValid() const
297 {
298  return true;
299 }
300 
301 
302 
303 ///////////////////////////////////////////////////////////////////////////////
304 // Implementation of inline functions //
305 
306 template <typename TKSpace, typename TDigitalSet>
307 inline
308 std::ostream&
309 DGtal::operator<< ( std::ostream & out,
310  const DigitalSetBoundary<TKSpace,TDigitalSet> & object )
311 {
312  object.selfDisplay( out );
313  return out;
314 }
315 
316 // //
317 ///////////////////////////////////////////////////////////////////////////////
318 
319