DGtal 1.4.0
Loading...
Searching...
No Matches
testDigitalSurface.cpp
Go to the documentation of this file.
1
31#include <iostream>
32#include "DGtal/base/Common.h"
33#include "DGtal/base/CConstSinglePassRange.h"
34#include "DGtal/topology/DigitalSurface.h"
35#include "DGtal/topology/DigitalSetBoundary.h"
36#include "DGtal/topology/ImplicitDigitalSurface.h"
37#include "DGtal/topology/LightImplicitDigitalSurface.h"
38#include "DGtal/topology/ExplicitDigitalSurface.h"
39#include "DGtal/topology/LightExplicitDigitalSurface.h"
40#include "DGtal/graph/BreadthFirstVisitor.h"
41#include "DGtal/topology/helpers/FrontierPredicate.h"
42#include "DGtal/topology/helpers/BoundaryPredicate.h"
43#include "DGtal/graph/CUndirectedSimpleLocalGraph.h"
44#include "DGtal/graph/CUndirectedSimpleGraph.h"
45#include "DGtal/images/ImageContainerBySTLVector.h"
46#include "DGtal/shapes/Shapes.h"
48
49using namespace std;
50using namespace DGtal;
51using namespace DGtal::concepts;
52using namespace DGtal::functors;
53
55// Functions for testing class DigitalSurface.
57
62{
63 unsigned int nbok = 0;
64 unsigned int nb = 0;
65
66 trace.beginBlock ( "Testing block ... DigitalSetBoundary" );
67 using namespace Z2i;
69 typedef Boundary::SurfelConstIterator ConstIterator;
70 typedef Boundary::Tracker Tracker;
71 typedef Boundary::Surfel Surfel;
72 Point p1( -10, -10 );
73 Point p2( 10, 10 );
74 Domain domain( p1, p2 );
75 DigitalSet dig_set( domain );
76 Shapes<Domain>::addNorm2Ball( dig_set, Point( 0, 0 ), 5 );
77 Shapes<Domain>::removeNorm2Ball( dig_set, Point( 0, 0 ), 1 );
78 KSpace K;
79 nbok += K.init( domain.lowerBound(), domain.upperBound(), true ) ? 1 : 0;
80 nb++;
81 trace.info() << "(" << nbok << "/" << nb << ") "
82 << "K.init() is ok" << std::endl;
83 Boundary boundary( K, dig_set );
84 unsigned int nbsurfels = 0;
85 for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
86 it != it_end; ++it )
87 {
88 ++nbsurfels;
89 }
90 trace.info() << nbsurfels << " surfels found." << std::endl;
91 ++nb; nbok += nbsurfels == ( 12 + 44 ) ? 1 : 0;
92 trace.info() << "(" << nbok << "/" << nb << ") "
93 << "nbsurfels == (12 + 44 )" << std::endl;
94 for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
95 it != it_end; ++it )
96 {
97 Tracker* ptrTracker = boundary.newTracker( *it );
98 Surfel s = ptrTracker->current();
99 Dimension trackDir = * K.sDirs( s );
100 Surfel s1, s2;
101 unsigned int m1 = ptrTracker->adjacent( s1, trackDir, true );
102 unsigned int m2 = ptrTracker->adjacent( s2, trackDir, false );
103 trace.info() << "s = " << s << std::endl;
104 trace.info() << "s1 = " << s1 << " m1 = " << m1 << std::endl;
105 trace.info() << "s2 = " << s2 << " m2 = " << m2 << std::endl;
106 ++nb; nbok += boundary.isInside( s1 ) ? 1 : 0;
107 trace.info() << "(" << nbok << "/" << nb << ") "
108 << "boundary.isInside( s1 )" << std::endl;
109 ++nb; nbok += boundary.isInside( s2 ) ? 1 : 0;
110 trace.info() << "(" << nbok << "/" << nb << ") "
111 << "boundary.isInside( s2 )" << std::endl;
112 delete ptrTracker;
113 }
114 trace.endBlock();
115 return nbok == nb;
116}
117
118template <typename TPoint3>
119struct ImplicitDigitalEllipse3 {
120 typedef TPoint3 Point;
121 inline
122 ImplicitDigitalEllipse3( double a, double b, double c )
123 : myA( a ), myB( b ), myC( c )
124 {}
125 inline
126 bool operator()( const TPoint3 & p ) const
127 {
128 double x = ( (double) p[ 0 ] / myA );
129 double y = ( (double) p[ 1 ] / myB );
130 double z = ( (double) p[ 2 ] / myC );
131 return ( x*x + y*y + z*z ) <= 1.0;
132 }
133 double myA, myB, myC;
134};
135
137{
138 unsigned int nbok = 0;
139 unsigned int nb = 0;
140
141 trace.beginBlock ( "Testing block ... ImplicitDigitalSurface" );
142 using namespace Z3i;
143 typedef ImplicitDigitalEllipse3<Point> ImplicitDigitalEllipse;
145 typedef Boundary::SurfelConstIterator ConstIterator;
146 typedef Boundary::Tracker Tracker;
147 typedef Boundary::Surfel Surfel;
148 Point p1( -10, -10, -10 );
149 Point p2( 10, 10, 10 );
150 KSpace K;
151 nbok += K.init( p1, p2, true ) ? 1 : 0;
152 nb++;
153 trace.info() << "(" << nbok << "/" << nb << ") "
154 << "K.init() is ok" << std::endl;
155 ImplicitDigitalEllipse ellipse( 6.0, 4.5, 3.4 );
156 Surfel bel = Surfaces<KSpace>::findABel( K, ellipse, 10000 );
157 Boundary boundary( K, ellipse,
159 unsigned int nbsurfels = 0;
160 for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
161 it != it_end; ++it )
162 {
163 ++nbsurfels;
164 }
165 trace.info() << nbsurfels << " surfels found." << std::endl;
166 // ++nb; nbok += nbsurfels == ( 12 + 44 ) ? 1 : 0;
167 // trace.info() << "(" << nbok << "/" << nb << ") "
168 // << "nbsurfels == (12 + 44 )" << std::endl;
169 for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
170 it != it_end; ++it )
171 {
172 Tracker* ptrTracker = boundary.newTracker( *it );
173 Surfel s = ptrTracker->current();
174 Dimension trackDir = * K.sDirs( s );
175 Surfel s1, s2;
176 unsigned int m1 = ptrTracker->adjacent( s1, trackDir, true );
177 unsigned int m2 = ptrTracker->adjacent( s2, trackDir, false );
178 trace.info() << "s = " << s << std::endl;
179 trace.info() << "s1 = " << s1 << " m1 = " << m1 << std::endl;
180 trace.info() << "s2 = " << s2 << " m2 = " << m2 << std::endl;
181 ++nb; nbok += boundary.isInside( s1 ) ? 1 : 0;
182 trace.info() << "(" << nbok << "/" << nb << ") "
183 << "boundary.isInside( s1 )" << std::endl;
184 ++nb; nbok += boundary.isInside( s2 ) ? 1 : 0;
185 trace.info() << "(" << nbok << "/" << nb << ") "
186 << "boundary.isInside( s2 )" << std::endl;
187 delete ptrTracker;
188 }
189 trace.endBlock();
190 return nbok == nb;
191}
192
193//-----------------------------------------------------------------------------
194// Testing LightImplicitDigitalSurface
195//-----------------------------------------------------------------------------
197{
198 using namespace Z3i;
199 typedef ImplicitDigitalEllipse3<Point> ImplicitDigitalEllipse;
201 typedef Boundary::SurfelConstIterator ConstIterator;
202 typedef Boundary::Tracker Tracker;
203 typedef Boundary::Surfel Surfel;
204
205 unsigned int nbok = 0;
206 unsigned int nb = 0;
207 trace.beginBlock ( "Testing block ... LightImplicitDigitalSurface" );
208 Point p1( -10, -10, -10 );
209 Point p2( 10, 10, 10 );
210 KSpace K;
211 nbok += K.init( p1, p2, true ) ? 1 : 0;
212 nb++;
213 trace.info() << "(" << nbok << "/" << nb << ") "
214 << "K.init() is ok" << std::endl;
215 ImplicitDigitalEllipse ellipse( 6.0, 4.5, 3.4 );
216 Surfel bel = Surfaces<KSpace>::findABel( K, ellipse, 10000 );
217 Boundary boundary( K, ellipse,
219 unsigned int nbsurfels = 0;
220 for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
221 it != it_end; ++it )
222 {
223 ++nbsurfels;
224 }
225 trace.info() << nbsurfels << " surfels found." << std::endl;
226 trace.beginBlock ( "Checks if adjacent surfels are part of the surface." );
227
228 for ( ConstIterator it = boundary.begin(), it_end = boundary.end();
229 it != it_end; ++it )
230 {
231 Tracker* ptrTracker = boundary.newTracker( *it );
232 Surfel s = ptrTracker->current();
233 Dimension trackDir = * K.sDirs( s );
234 Surfel s1, s2;
235 // unsigned int m1 =
236 ptrTracker->adjacent( s1, trackDir, true );
237 // unsigned int m2 =
238 ptrTracker->adjacent( s2, trackDir, false );
239 // trace.info() << "s = " << s << std::endl;
240 // trace.info() << "s1 = " << s1 << " m1 = " << m1 << std::endl;
241 // trace.info() << "s2 = " << s2 << " m2 = " << m2 << std::endl;
242 ++nb; nbok += boundary.isInside( s1 ) ? 1 : 0;
243 // trace.info() << "(" << nbok << "/" << nb << ") "
244 // << "boundary.isInside( s1 )" << std::endl;
245 ++nb; nbok += boundary.isInside( s2 ) ? 1 : 0;
246 // trace.info() << "(" << nbok << "/" << nb << ") "
247 // << "boundary.isInside( s2 )" << std::endl;
248 delete ptrTracker;
249 }
250 trace.info() << "(" << nbok << "/" << nb << ") isInside tests." << std::endl;
251 trace.endBlock();
252 trace.endBlock();
253 return nbok == nb;
254}
255
256template <typename Image3D>
257void fillImage3D( Image3D & img,
258 typename Image3D::Point low,
259 typename Image3D::Point up,
260 typename Image3D::Value value )
261{
262 typedef typename Image3D::Point Point;
263 typedef typename Image3D::Integer Integer;
264 for ( Integer z = low[ 2 ]; z <= up[ 2 ]; ++z )
265 for ( Integer y = low[ 1 ]; y <= up[ 1 ]; ++y )
266 for ( Integer x = low[ 0 ]; x <= up[ 0 ]; ++x )
267 img.setValue( Point( x, y, z ), value );
268}
269
270//-----------------------------------------------------------------------------
271// Testing ExplicitDigitalSurface
272//-----------------------------------------------------------------------------
274{
275 using namespace Z3i;
277 typedef FrontierPredicate<KSpace, Image> SurfelPredicate;
279 typedef Frontier::SurfelConstIterator ConstIterator;
280
281 unsigned int nbok = 0;
282 unsigned int nb = 0;
283 trace.beginBlock ( "Testing block ... ExplicitDigitalSurface" );
284 Point p1( -5, -5, -5 );
285 Point p2( 5, 5, 5 );
286 KSpace K;
287 nbok += K.init( p1, p2, true ) ? 1 : 0;
288 nb++;
289 trace.info() << "(" << nbok << "/" << nb << ") "
290 << "K.init() is ok" << std::endl;
291 Image image( Domain(p1, p2) );
292 fillImage3D( image, p1, p2, 0 );
293 fillImage3D( image, Point(-2,-2,-2 ), Point( 2, 2, 2 ), 1 );
294 fillImage3D( image, Point( 0, 0,-2 ), Point( 0, 0, 2 ), 2 );
295 fillImage3D( image, Point(-1,-1, 2 ), Point( 1, 1, 2 ), 2 );
296 {
297 SCell vox2 = K.sSpel( Point( 0, 0, 2 ), K.POS );
298 SCell bel20 = K.sIncident( vox2, 2, true );
299 SurfelPredicate surfPredicate( K, image, 2, 0 );
300 Frontier frontier20( K, surfPredicate,
302 bel20 );
303 unsigned int nbsurfels = 0;
304 for ( ConstIterator it = frontier20.begin(), it_end = frontier20.end();
305 it != it_end; ++it )
306 {
307 ++nbsurfels;
308 }
309 trace.info() << nbsurfels << " surfels found." << std::endl;
310 ++nb; nbok += nbsurfels == 9 ? 1 : 0;
311 trace.info() << "(" << nbok << "/" << nb << ") "
312 << "frontier20: nbsurfels == 9" << std::endl;
313 }
314 {
315 SCell vox1 = K.sSpel( Point( 2, 0, 0 ), K.POS );
316 SCell bel10 = K.sIncident( vox1, 0, true );
317 SurfelPredicate surfPredicate( K, image, 1, 0 );
318 Frontier frontier10( K, surfPredicate,
320 bel10 );
321 unsigned int nbsurfels = 0;
322 for ( ConstIterator it = frontier10.begin(), it_end = frontier10.end();
323 it != it_end; ++it )
324 {
325 ++nbsurfels;
326 }
327 trace.info() << nbsurfels << " surfels found." << std::endl;
328 ++nb; nbok += nbsurfels == 140 ? 1 : 0; // 4*25(sides) + 16(top) + 24(bot)
329 trace.info() << "(" << nbok << "/" << nb << ") "
330 << "frontier10: nbsurfels == 140" << std::endl;
331 }
332 {
333 SCell vox1 = K.sSpel( Point( 1, 0, 0 ), K.POS );
334 SCell bel12 = K.sIncident( vox1, 0, false );
335 SurfelPredicate surfPredicate( K, image, 1, 2 );
336 Frontier frontier12( K, surfPredicate,
338 bel12 );
339 unsigned int nbsurfels = 0;
340 for ( ConstIterator it = frontier12.begin(), it_end = frontier12.end();
341 it != it_end; ++it )
342 {
343 ++nbsurfels;
344 }
345 trace.info() << nbsurfels << " surfels found." << std::endl;
346 ++nb; nbok += nbsurfels == 36 ? 1 : 0; // 8+12(top) + 16(axis)
347 trace.info() << "(" << nbok << "/" << nb << ") "
348 << "frontier12: nbsurfels == 36" << std::endl;
349 }
350 {
351 typedef BoundaryPredicate<KSpace, Image> SecondSurfelPredicate;
353 typedef Boundary::SurfelConstIterator EConstIterator;
354 // typedef Boundary::Tracker Tracker;
355 // typedef Boundary::SCell SCell;
356 // typedef Boundary::Surfel Surfel;
357 SCell vox1 = K.sSpel( Point( 1, 0, 0 ), K.POS );
358 SCell bel1x = K.sIncident( vox1, 0, false );
359 SecondSurfelPredicate surfPredicate( K, image, 1 );
360 Boundary boundary1x( K, surfPredicate,
362 bel1x );
363 unsigned int nbsurfels = 0;
364 for ( EConstIterator it = boundary1x.begin(), it_end = boundary1x.end();
365 it != it_end; ++it )
366 {
367 ++nbsurfels;
368 }
369 trace.info() << nbsurfels << " surfels found." << std::endl;
370 ++nb; nbok += nbsurfels == 176 ? 1 : 0;
371 trace.info() << "(" << nbok << "/" << nb << ") "
372 << "boundary1x: nbsurfels == 176" << std::endl;
373 }
374 trace.endBlock();
375 return nbok == nb;
376}
377
378//-----------------------------------------------------------------------------
379// Testing LightExplicitDigitalSurface
380//-----------------------------------------------------------------------------
382{
383 using namespace Z3i;
385 typedef FrontierPredicate<KSpace, Image> SurfelPredicate;
387 typedef Frontier::SurfelConstIterator ConstIterator;
388
389 unsigned int nbok = 0;
390 unsigned int nb = 0;
391 trace.beginBlock ( "Testing block ... LightExplicitDigitalSurface" );
392 Point p1( -5, -5, -5 );
393 Point p2( 5, 5, 5 );
394 KSpace K;
395 nbok += K.init( p1, p2, true ) ? 1 : 0;
396 nb++;
397 trace.info() << "(" << nbok << "/" << nb << ") "
398 << "K.init() is ok" << std::endl;
399 Image image( Domain(p1, p2) );
400 fillImage3D( image, p1, p2, 0 );
401 fillImage3D( image, Point(-2,-2,-2 ), Point( 2, 2, 2 ), 1 );
402 fillImage3D( image, Point( 0, 0,-2 ), Point( 0, 0, 2 ), 2 );
403 fillImage3D( image, Point(-1,-1, 2 ), Point( 1, 1, 2 ), 2 );
404 {
405 SCell vox2 = K.sSpel( Point( 0, 0, 2 ), K.POS );
406 SCell bel20 = K.sIncident( vox2, 2, true );
407 SurfelPredicate surfPredicate( K, image, 2, 0 );
408 Frontier frontier20( K, surfPredicate,
410 bel20 );
411 unsigned int nbsurfels = 0;
412 for ( ConstIterator it = frontier20.begin(), it_end = frontier20.end();
413 it != it_end; ++it )
414 {
415 ++nbsurfels;
416 }
417 trace.info() << nbsurfels << " surfels found." << std::endl;
418 ++nb; nbok += nbsurfels == 9 ? 1 : 0;
419 trace.info() << "(" << nbok << "/" << nb << ") "
420 << "frontier20: nbsurfels == 9" << std::endl;
421 }
422 {
423 SCell vox1 = K.sSpel( Point( 2, 0, 0 ), K.POS );
424 SCell bel10 = K.sIncident( vox1, 0, true );
425 SurfelPredicate surfPredicate( K, image, 1, 0 );
426 Frontier frontier10( K, surfPredicate,
428 bel10 );
429 unsigned int nbsurfels = 0;
430 for ( ConstIterator it = frontier10.begin(), it_end = frontier10.end();
431 it != it_end; ++it )
432 {
433 ++nbsurfels;
434 }
435 trace.info() << nbsurfels << " surfels found." << std::endl;
436 ++nb; nbok += nbsurfels == 140 ? 1 : 0; // 4*25(sides) + 16(top) + 24(bot)
437 trace.info() << "(" << nbok << "/" << nb << ") "
438 << "frontier10: nbsurfels == 140" << std::endl;
439 }
440 {
441 SCell vox1 = K.sSpel( Point( 1, 0, 0 ), K.POS );
442 SCell bel12 = K.sIncident( vox1, 0, false );
443 SurfelPredicate surfPredicate( K, image, 1, 2 );
444 Frontier frontier12( K, surfPredicate,
446 bel12 );
447 unsigned int nbsurfels = 0;
448 for ( ConstIterator it = frontier12.begin(), it_end = frontier12.end();
449 it != it_end; ++it )
450 {
451 ++nbsurfels;
452 }
453 trace.info() << nbsurfels << " surfels found." << std::endl;
454 ++nb; nbok += nbsurfels == 36 ? 1 : 0; // 8+12(top) + 16(axis)
455 trace.info() << "(" << nbok << "/" << nb << ") "
456 << "frontier12: nbsurfels == 36" << std::endl;
457 }
458 {
459 typedef BoundaryPredicate<KSpace, Image> SecondSurfelPredicate;
461 typedef Boundary::SurfelConstIterator LEConstIterator;
462 //typedef Boundary::Tracker Tracker;
463 //typedef Boundary::SCell SCell;
464 //typedef Boundary::Surfel Surfel;
465 SCell vox1 = K.sSpel( Point( 1, 0, 0 ), K.POS );
466 SCell bel1x = K.sIncident( vox1, 0, false );
467 SecondSurfelPredicate surfPredicate( K, image, 1 );
468 Boundary boundary1x( K, surfPredicate,
470 bel1x );
471 unsigned int nbsurfels = 0;
472 for ( LEConstIterator it = boundary1x.begin(), it_end = boundary1x.end();
473 it != it_end; ++it )
474 {
475 ++nbsurfels;
476 }
477 trace.info() << nbsurfels << " surfels found." << std::endl;
478 ++nb; nbok += nbsurfels == 176 ? 1 : 0;
479 trace.info() << "(" << nbok << "/" << nb << ") "
480 << "boundary1x: nbsurfels == 176" << std::endl;
481 }
482 trace.endBlock();
483 return nbok == nb;
484}
485
486
487
488template <typename KSpace>
490{
491 unsigned int nbok = 0;
492 unsigned int nb = 0;
493 std::string msg( "Testing block ... DigitalSurface in K" );
494 msg += '0' + KSpace::dimension;
495 trace.beginBlock ( msg );
496 //"Testing block ... DigitalSurface " + std::string( KSpace.dimension ) );
497 typedef typename KSpace::Space Space;
498 typedef typename KSpace::Size Size;
499 typedef typename Space::Point Point;
502
503 trace.beginBlock ( "Creating object and DigitalSurfaceContainer" );
504 Point p0 = Point::diagonal( 0 );
505 Point p1 = Point::diagonal( -6 );
506 Point p2 = Point::diagonal( 6 );
507 Domain domain( p1, p2 );
508 DigitalSet dig_set( domain );
509 Shapes<Domain>::addNorm2Ball( dig_set, p0, 3 );
510 Shapes<Domain>::removeNorm2Ball( dig_set, p0, 1 );
511 KSpace K;
512 nbok += K.init( domain.lowerBound(), domain.upperBound(), true ) ? 1 : 0;
513 nb++;
514 trace.info() << "(" << nbok << "/" << nb << ") "
515 << "K.init() is ok" << std::endl;
516 trace.endBlock();
517
518 trace.beginBlock ( "Testing DigitalSurface" );
519 typedef DigitalSetBoundary<KSpace,DigitalSet> DSContainer;
520 typedef DigitalSurface<DSContainer> MyDS;
521
522 //Checking the type as a model of CSinglePassConstRange
523 BOOST_CONCEPT_ASSERT(( CConstSinglePassRange < MyDS> ));
524 BOOST_CONCEPT_ASSERT(( CUndirectedSimpleLocalGraph < MyDS> ));
525 BOOST_CONCEPT_ASSERT(( CUndirectedSimpleGraph < MyDS> ));
526
527
528 typedef typename MyDS::Surfel Surfel;
529 DSContainer* ptrBdry = new DSContainer( K, dig_set );
530 MyDS digsurf( ptrBdry ); // acquired
531 Size nbsurfels =
532 ( K.dimension == 2 ) ? 12+28 :
533 ( K.dimension == 3 ) ? 30+174 :
534 ( K.dimension == 4 ) ? 56+984 :
535 ( K.dimension == 5 ) ? 4340 : 0;
536 ++nb; nbok += digsurf.size() == nbsurfels ? 1 : 0;
537 trace.info() << "(" << nbok << "/" << nb << ") "
538 << "digsurf.size() = " << digsurf.size()
539 << " == " << nbsurfels << std::endl;
540 for ( typename MyDS::ConstIterator it = digsurf.begin(),
541 it_end = digsurf.end();
542 it != it_end;
543 ++it )
544 {
545 Surfel s = *it;
546 ++nb; nbok += digsurf.degree( s ) == 2*(K.dimension-1) ? 1 : 0;
547 }
548 trace.info() << "(" << nbok << "/" << nb << ") "
549 << "digsurf.degree( s ) == "
550 << 2*(K.dimension-1) << std::endl;
551 trace.endBlock();
552 trace.beginBlock ( "Testing BreadthFirstVisitor on DigitalSurface" );
553 BreadthFirstVisitor< MyDS > visitor( digsurf, *digsurf.begin() );
554 typedef typename BreadthFirstVisitor< MyDS >::Node BFVNode;
555 typedef typename BreadthFirstVisitor< MyDS >::MarkSet BFVMarkSet;
556 unsigned int nb_dist_1 = 0;
557 BFVNode node;
558 while ( ! visitor.finished() )
559 {
560 node = visitor.current();
561 if ( node.second == 1 ) ++nb_dist_1;
562 visitor.expand();
563 }
564 trace.info() << "last node v=" << node.first << " d=" << node.second << std::endl;
565 ++nb; nbok += nb_dist_1 == 2*(K.dimension-1) ? 1 : 0;
566 trace.info() << "(" << nbok << "/" << nb << ") "
567 << "nb surfels at distance 1 == "
568 << 2*(K.dimension-1) << std::endl;
569 const BFVMarkSet & visitedVtx = visitor.markedVertices();
570 Size nbsurfelsComp1 =
571 ( K.dimension == 2 ) ? 28 :
572 ( K.dimension == 3 ) ? 174 :
573 ( K.dimension == 4 ) ? 984 : 0;
574 ++nb; nbok += visitedVtx.size() == nbsurfelsComp1 ? 1 : 0;
575 trace.info() << "(" << nbok << "/" << nb << ") "
576 << "nb visited = " << visitedVtx.size() << " == "
577 << nbsurfelsComp1 << std::endl;
578
579 trace.endBlock();
580
581
582 trace.endBlock();
583 return nbok == nb;
584}
585
587{
589 typedef typename KSpace::Space Space;
590 typedef typename Space::Point Point;
594 typedef DigitalSetBoundary<KSpace,DigitalSet> DSContainer;
595 typedef DigitalSurface<DSContainer> MyDS;
596 typedef typename MyDS::Vertex Vertex;
597 typedef typename MyDS::SCell SCell;
598
599 unsigned int nbok = 0;
600 unsigned int nb = 0;
601 trace.beginBlock ( "Creating surface around one voxel" );
602 Point pt0;
603 Point pt1 = Point::diagonal( -1 );
604 Point pt2 = Point::diagonal( 1 );
605 Domain domain( pt1, pt2 );
606 DigitalSet dig_set( domain );
607 dig_set.insert( pt0 );
608 KSpace K;
609 nbok += K.init( domain.lowerBound(), domain.upperBound(), true ) ? 1 : 0;
610 nb++;
611 trace.info() << "(" << nbok << "/" << nb << ") "
612 << "K.init() is ok" << std::endl;
613 DSContainer* ptrBdry = new DSContainer( K, dig_set );
614 MyDS digsurf( ptrBdry ); // acquired
615 ++nb; nbok += digsurf.size() == 6 ? 1 : 0;
616 trace.info() << "(" << nbok << "/" << nb << ") "
617 << "digsurf.size() = " << digsurf.size()
618 << " == " << 6 << std::endl;
619 trace.endBlock();
620 trace.beginBlock ( "Check ordering" );
621 std::map< std::pair< SCell, SCell >, unsigned int > nb_arcs;
622 for ( Vertex v : digsurf )
623 {
624 auto faces = digsurf.facesAroundVertex( v, true );
625 for ( unsigned int i = 0; i < faces.size(); ++i )
626 {
627 auto p = std::make_pair( digsurf.pivot( faces[ i ] ),
628 digsurf.pivot( faces[ (i+1)%4 ] ) );
629 trace.info() << "Arc " << p.first << " --- " << p.second << std::endl;
630 if ( nb_arcs.find( p ) == nb_arcs.end() )
631 nb_arcs[ p ] = 1;
632 else
633 nb_arcs[ p ] += 1;
634 }
635 }
636 ++nb; nbok += nb_arcs.size() == 24 ? 1 : 0;
637 trace.info() << "(" << nbok << "/" << nb << ") "
638 << "nb_arcs.size() = " << nb_arcs.size()
639 << " == " << 24 << " (cube has 24 arcs)" << std::endl;
640 for ( auto arc : nb_arcs )
641 {
642 SCell p1 = arc.first.first;
643 SCell p2 = arc.first.second;
644 ++nb; nbok += (K.sCoords( p1 ) - K.sCoords( p2 )).norm1() == 1 ? 1 : 0;
645 }
646 trace.info() << "(" << nbok << "/" << nb << ") "
647 << "arcs have all norm 1." << std::endl;
648 for ( auto arc : nb_arcs )
649 {
650 SCell p1 = arc.first.first;
651 SCell p2 = arc.first.second;
652 auto it = nb_arcs.find( std::make_pair( p2, p1 ) );
653 ++nb; nbok += arc.second == 1 ? 1 : 0;
654 ++nb; nbok += ( it != nb_arcs.end() ) && it->second == 1 ? 1 : 0;
655 }
656 trace.info() << "(" << nbok << "/" << nb << ") "
657 << "arcs are unique and their inverse are unique." << std::endl;
658 trace.endBlock();
659 return nb == nbok;
660}
661
663// Standard services - public :
664
665int main( int argc, char** argv )
666{
667 trace.beginBlock ( "Testing class DigitalSurface" );
668 trace.info() << "Args:";
669 for ( int i = 0; i < argc; ++i )
670 trace.info() << " " << argv[ i ];
671 trace.info() << endl;
672
673 bool res = testDigitalSetBoundary()
682 trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
683 trace.endBlock();
684 return res ? 0 : 1;
685}
686// //
Aim: This class is useful to perform a breadth-first exploration of a graph given a starting point or...
const Node & current() const
const MarkSet & markedVertices() const
std::pair< Vertex, Data > Node
FIXME.
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as the boundary of a given...
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: Represents a set of n-1-cells in a nD space, together with adjacency relation between these cell...
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as connected surfels....
const Point & lowerBound() const
const Point & upperBound() const
Aim: implements association bewteen points lying in a digital domain and values.
Definition Image.h:70
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as the boundary of an impl...
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
bool init(const Point &lower, const Point &upper, bool isClosed)
Specifies the upper and lower bounds for the maximal cells in this space.
DirIterator sDirs(const SCell &p) const
Given a signed cell [p], returns an iterator to iterate over each coordinate the cell spans.
Point sCoords(const SCell &c) const
Return its digital coordinates.
SCell sSpel(Point p, Sign sign=POS) const
From the digital coordinates of a point in Zn, builds the corresponding spel (cell of maximal dimensi...
static const constexpr Sign POS
NumberTraits< Integer >::UnsignedVersion Size
Type used to represent sizes in the digital space.
SCell sIncident(const SCell &c, Dimension k, bool up) const
Return the forward or backward signed cell incident to [c] along axis [k], depending on [up].
static const constexpr Dimension dimension
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as connected surfels....
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as the boundary of an impl...
static void addNorm2Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)
static void removeNorm2Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)
static SCell findABel(const KSpace &K, const PointPredicate &pp, unsigned int nbtries=1000)
Aim: Represent adjacencies between surfel elements, telling if it follows an interior to exterior ord...
void beginBlock(const std::string &keyword="")
std::ostream & emphase()
std::ostream & info()
double endBlock()
Aim: The predicate on surfels that represents the frontier between a region and its complementary in ...
Aim: The predicate on surfels that represents the frontier between two regions in an image....
Z3i::SCell SCell
MyDigitalSurface::ConstIterator ConstIterator
Aim: Gathers several functions useful for concept checks.
functors namespace gathers all DGtal functors.
DGtal is the top-level namespace which contains all DGtal functions and types.
DGtal::uint32_t Dimension
Definition Common.h:136
Trace trace
Definition Common.h:153
STL namespace.
DigitalSetByAssociativeContainer< Domain, std::unordered_set< typename Domain::Point > > Type
Represents a signed cell in a cellular grid space by its Khalimsky coordinates and a boolean value.
int main()
Definition testBits.cpp:56
MyPointD Point
KSpace K
bool testDigitalSurface()
bool testLightImplicitDigitalSurface()
void fillImage3D(Image3D &img, typename Image3D::Point low, typename Image3D::Point up, typename Image3D::Value value)
bool testDigitalSetBoundary()
bool testExplicitDigitalSurface()
bool testLightExplicitDigitalSurface()
bool testOrderingDigitalSurfaceFacesAroundVertex()
bool testImplicitDigitalSurface()
HalfEdgeDataStructure::Size Size
Domain domain
ImageContainerBySTLVector< Domain, Value > Image
HyperRectDomain< Space > Domain
TriMesh::Vertex Vertex
Z2i::DigitalSet DigitalSet