File failed to load: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/config/TeX-MML-AM_CHTML/MathJax.js
DGtal 2.0.0
testObject.cpp
Go to the documentation of this file.
1
16
29
31#include <cmath>
32#include <iostream>
33#include <sstream>
34#include <queue>
35#include "DGtal/base/Common.h"
36#include "DGtal/kernel/SpaceND.h"
37#include "DGtal/kernel/domains/DomainPredicate.h"
38#include "DGtal/kernel/domains/HyperRectDomain.h"
39#include "DGtal/kernel/sets/DigitalSetSelector.h"
40#include "DGtal/kernel/sets/DigitalSetConverter.h"
41#include "DGtal/topology/MetricAdjacency.h"
42#include "DGtal/topology/DomainAdjacency.h"
43#include "DGtal/topology/DigitalTopology.h"
44#include "DGtal/topology/Object.h"
45#include "DGtal/graph/Expander.h"
46#include "DGtal/io/boards/Board2D.h"
47#include "DGtal/io/Color.h"
48#include "DGtal/io/colormaps/GradientColorMap.h"
49#include "DGtal/shapes/Shapes.h"
50#include "DGtal/helpers/StdDefs.h"
51#include "DGtal/topology/NeighborhoodConfigurations.h"
52#include "DGtal/topology/tables/NeighborhoodTables.h"
54
55using namespace std;
56using namespace DGtal;
57using namespace LibBoard;
58
59#define INBLOCK_TEST(x) \
60 nbok += ( x ) ? 1 : 0; \
61 nb++; \
62 trace.info() << "(" << nbok << "/" << nb << ") " \
63 << #x << std::endl;
64
65#define INBLOCK_TEST2(x,y) \
66 nbok += ( x ) ? 1 : 0; \
67 nb++; \
68 trace.info() << "(" << nbok << "/" << nb << ") " \
69 << y << std::endl;
70
72// Functions for testing class Object.
74
79{
80 unsigned int nbok = 0;
81 unsigned int nb = 0;
82
83 typedef SpaceND< 2 > Z2;
84 typedef Z2::Point Point;
86 typedef HyperRectDomain< Z2 > DomainType;
87 Point p1( -449, -449 );
88 Point p2( 449, 449 );
89 DomainType domain( p1, p2 );
90
91 // typedef DomainMetricAdjacency< DomainType, 1 > Adj4;
92 // typedef DomainMetricAdjacency< DomainType, 2 > Adj8;
93 typedef MetricAdjacency< Z2, 1 > MetricAdj4;
94 typedef MetricAdjacency< Z2, 2 > MetricAdj8;
99 MediumSet;
100// typedef DigitalSetSelector< DomainType, SMALL_DS >::Type
101// MediumSet;
102 typedef Object<DT48, MediumSet> ObjectType;
103 typedef ObjectType::SmallSet SmallSet;
104 typedef Object<DT48, SmallSet> SmallObjectType;
105 typedef ObjectType::Size Size;
106
107 // Adj4 adj4( domain );
108 // Adj8 adj8( domain );
109 MetricAdj4 madj4;
110 MetricAdj8 madj8;
111 Adj4 adj4( domain, madj4 );
112 Adj8 adj8( domain, madj8 );
113 DT48 dt48( adj4, adj8, JORDAN_DT );
114
115 Coordinate r = 49;
116 double radius = (double) (r+1);
117 Point c( 0, 0 );
118 Point l( r, 0 );
119 MediumSet disk( domain );
120 ostringstream sstr;
121 sstr << "Creating disk( r < " << radius << " ) ...";
122 trace.beginBlock ( sstr.str() );
123 for ( DomainType::ConstIterator it = domain.begin();
124 it != domain.end();
125 ++it )
126 {
127 if ( (*it - c ).norm() < radius ) // 450.0
128 // insertNew is very important for vector container.
129 disk.insertNew( *it );
130 }
131 trace.endBlock();
132
133 trace.beginBlock ( "Testing Object instanciation and smart copy ..." );
134 ObjectType disk_object( dt48, disk );
135 nbok += disk_object.size() == 7825 ? 1 : 0;
136 nb++;
137 trace.info() << "(" << nbok << "/" << nb << ") "
138 << "Disk (r=450.0) " << disk_object << std::endl;
139 trace.info() << " size=" << disk_object.size() << std::endl;
140 ObjectType disk_object2( disk_object );
141 nbok += disk_object2.size() == 7825 ? 1 : 0;
142 nb++;
143 trace.info() << "(" << nbok << "/" << nb << ") "
144 << "Disk2 (r=450.0) " << disk_object2 << std::endl;
145 trace.info() << " size=" << disk_object2.size() << std::endl;
146 trace.endBlock();
147
148 trace.beginBlock ( "Testing copy on write system ..." );
149 trace.info() << "Removing center point in Disk." << std::endl;
150 disk_object.pointSet().erase( c );
151 disk_object2.pointSet().insert( c );
152 nbok += disk_object.size() == 7824 ? 1 : 0;
153 nb++;
154 trace.info() << "(" << nbok << "/" << nb << ") "
155 << "Disk - c (r=450.0) " << disk_object << std::endl;
156 trace.info() << " size=" << disk_object.size() << std::endl;
157 nbok += disk_object2.size() == 7825 ? 1 : 0;
158 nb++;
159 trace.info() << "(" << nbok << "/" << nb << ") "
160 << "Disk2 + c (r=450.0) " << disk_object2 << std::endl;
161 trace.info() << " size=" << disk_object2.size() << std::endl;
162 trace.endBlock();
163
164 trace.beginBlock ( "Testing neighborhoods ..." );
165 Object<DT48, SmallSet> neigh = disk_object.neighborhood( c );
166 nbok += neigh.size() == 4 ? 1 : 0;
167 nb++;
168 trace.info() << "(" << nbok << "/" << nb << ") "
169 << "N_4(Disk, c).size() = " << neigh.size()
170 << " == 4" << std::endl;
171 neigh = disk_object.properNeighborhood( l );
172 nbok += neigh.size() == 3 ? 1 : 0;
173 nb++;
174 trace.info() << "(" << nbok << "/" << nb << ") "
175 << "N*_4(Disk, " << l << ").size() = " << neigh.size()
176 << " == 3" << std::endl;
177 Size size = disk_object.properNeighborhoodSize( l );
178 nbok += size == 3 ? 1 : 0;
179 nb++;
180 trace.info() << "(" << nbok << "/" << nb << ") "
181 << "#N*_4(Disk, " << l << ") = " << size
182 << " == 3" << std::endl;
183
184 neigh = disk_object2.neighborhood( c );
185 nbok += neigh.size() == 5 ? 1 : 0;
186 nb++;
187 trace.info() << "(" << nbok << "/" << nb << ") "
188 << "N_4(Disk2, c).size() = " << neigh.size()
189 << " == 5" << std::endl;
190 trace.endBlock();
191
192 trace.beginBlock ( "Testing set converters ..." );
194 ( neigh.pointSet(), disk_object.pointSet() );
195 nbok += neigh.size() == 7824 ? 1 : 0;
196 nb++;
197 trace.info() << "(" << nbok << "/" << nb << ") "
198 << "neigh = disk_object, size() = " << neigh.size()
199 << " == 636100" << std::endl;
200 SmallObjectType neigh2 = disk_object2.neighborhood( c );
202 ( neigh.pointSet(), neigh2.pointSet() );
203 nbok += neigh.size() == 5 ? 1 : 0;
204 nb++;
205 trace.info() << "(" << nbok << "/" << nb << ") "
206 << "neigh = N_4(Disk2, c), size() = " << neigh.size()
207 << " == 5" << std::endl;
208 trace.endBlock();
209
210 trace.beginBlock ( "Testing border extraction ..." );
211 ObjectType bdisk = disk_object.border();
212 nbok += bdisk.size() == 400 ? 1 : 0;
213 nb++;
214 trace.info() << "(" << nbok << "/" << nb << ") "
215 << "Border(Disk, c), size() = " << bdisk.size()
216 << " == 3372" << std::endl;
217 ObjectType bdisk2 = disk_object2.border();
218 nbok += bdisk2.size() == 392 ? 1 : 0;
219 nb++;
220 trace.info() << "(" << nbok << "/" << nb << ") "
221 << "Border(Disk2, c), size() = " << bdisk2.size()
222 << " == 3364" << std::endl;
223 trace.endBlock();
224
225 trace.beginBlock ( "Testing expansion by layers on the boundary ..." );
226 typedef Expander< ObjectType > ObjectExpander;
227 ObjectExpander expander( bdisk, *(bdisk.pointSet().begin()) );
228 while ( ! expander.finished() )
229 {
230 nbok += expander.layer().size() <= 2 ? 1 : 0;
231 nb++;
232 trace.info() << "(" << nbok << "/" << nb << ") "
233 << "expander.layer.size() <= 2 "
234 << expander << std::endl;
235 expander.nextLayer();
236 }
237 trace.endBlock();
238
239 trace.beginBlock ( "Testing expansion by layers on the disk from center..." );
240 ObjectExpander expander2( disk_object2, c );
241 while ( ! expander2.finished() )
242 {
243 trace.info() << expander2 << std::endl;
244 expander2.nextLayer();
245 }
246 nbok += expander2.distance() <= sqrt(2.0)*radius ? 1 : 0;
247 nb++;
248 trace.info() << "(" << nbok << "/" << nb << ") "
249 << "expander.distance() = " << expander2.distance()
250 << " <= " << sqrt(2.0)*radius << std::endl;
251 trace.endBlock();
252
253 return nbok == nb;
254}
255
261{
262 unsigned int nbok = 0;
263 unsigned int nb = 0;
264 typedef SpaceND< 3 > Z3;
265 typedef MetricAdjacency< Z3, 1 > Adj6;
266 typedef MetricAdjacency< Z3, 2 > Adj18;
267 typedef DigitalTopology< Adj6, Adj18 > DT6_18;
268 typedef Z3::Point Point;
270 typedef Domain::ConstIterator DomainConstIterator;
272 typedef Object<DT6_18, DigitalSet> ObjectType;
273 Adj6 adj6;
274 Adj18 adj18;
275 DT6_18 dt6_18( adj6, adj18, JORDAN_DT );
276
277 Point p1( -50, -50, -50 );
278 Point p2( 50, 50, 50 );
279 Domain domain( p1, p2 );
280 Point c( 0, 0, 0 );
281 Point d( 5, 2, 0 );
282
283 trace.beginBlock ( "Testing 3D Object instanciation and smart copy ..." );
284 trace.info() << "Creating diamond (r=15)" << endl;
285 // diamond of radius 30
286 DigitalSet diamond_set( domain );
287 for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it )
288 {
289 if ( (*it - c ).norm1() <= 15 ) diamond_set.insertNew( *it );
290 }
291 ObjectType diamond( dt6_18, diamond_set );
292 trace.info() << "Cloning diamond" << endl;
293 // The following line takes almost no time.
294 ObjectType diamond_clone( diamond );
295 // Since one of the objects is modified, the set is duplicated at the following line
296 trace.info() << "Removing two points " << c << " and " << d << endl;
297 diamond_clone.pointSet().erase( c );
298 diamond_clone.pointSet().erase( d );
299
300 trace.info() << "Inserting into vector<Object>" << endl;
301 vector<ObjectType> objects;
302 back_insert_iterator< vector< ObjectType > > inserter( objects );
303 *inserter++ = diamond;
304 *inserter++ = diamond_clone;
305
306 for ( vector<ObjectType>::const_iterator it = objects.begin();
307 it != objects.end();
308 ++it )
309 trace.info() << "- objects[" << (it - objects.begin() ) << "]"
310 << " = " << *it << endl;
311
312 INBLOCK_TEST( objects[ 0 ].size() == ( objects[ 1 ].size() + 2 ) );
313 INBLOCK_TEST( objects[ 0 ].size() == 4991 );
314 trace.endBlock();
315
316 trace.beginBlock ( "Testing connected component extraction ..." );
317 // JOL: do like this for output iterators pointing on the same
318 // container as 'this'. Works fine and nearly as fast.
319 //
320 // ObjectType( objects[ 0 ] ).writeComponents( inserter );
321
322 trace.beginBlock ( "Components of diamond.border() ..." );
323 vector<ObjectType> objects2;
324 back_insert_iterator< vector< ObjectType > > inserter2( objects2 );
325 auto nbc0 = objects[ 0 ].border().writeComponents( inserter2 );
326 INBLOCK_TEST( nbc0 == 1 );
327 INBLOCK_TEST( objects[ 0 ].computeConnectedness() == CONNECTED );
328 trace.endBlock();
329
330 trace.beginBlock ( "Components of diamond_clone.border() ..." );
331 auto nbc1 = objects[ 1 ].border().writeComponents( inserter2 );
332 INBLOCK_TEST( nbc1 == 3 );
333 trace.endBlock();
334 for ( vector<ObjectType>::const_iterator it = objects2.begin();
335 it != objects2.end();
336 ++it )
337 trace.info() << "- objects2[" << (it - objects2.begin() ) << "]"
338 << " = " << *it << endl;
339 INBLOCK_TEST( objects2[ 0 ].size() == objects2[ 1 ].size() );
340 INBLOCK_TEST( objects2[ 2 ].size() == objects2[ 3 ].size() );
341 INBLOCK_TEST( objects2[ 0 ].size() == 1688 );
342 INBLOCK_TEST( objects2[ 2 ].size() == 18 );
343
344 trace.endBlock();
345
346 return nbok == nb;
347
348}
349
355{
356 unsigned int nbok = 0;
357 unsigned int nb = 0;
358 typedef SpaceND< 3 > Z3;
359 typedef MetricAdjacency< Z3, 1 > Adj6;
360 typedef MetricAdjacency< Z3, 2 > Adj18;
361 typedef DigitalTopology< Adj6, Adj18 > DT6_18;
362 typedef Z3::Point Point;
364 typedef Domain::ConstIterator DomainConstIterator;
366 typedef Object<DT6_18, DigitalSet> ObjectType;
367 typedef Object<DT6_18, DigitalSet>::SmallObject SmallObjectType;
368 typedef Object<DT6_18, DigitalSet>::SmallComplementObject SmallComplementObjectType;
369 Adj6 adj6;
370 Adj18 adj18;
371 DT6_18 dt6_18( adj6, adj18, JORDAN_DT );
372
373 Point p1( -10, -10, -10 );
374 Point p2( 10, 10, 10 );
375 Domain domain( p1, p2 );
376 Point c( 0, 0, 0 );
377 Point r( 3, 0, 0 );
378
379 trace.beginBlock ( "Creating Diamond (r=4)" );
380 // diamond of radius 4
381 DigitalSet diamond_set( domain );
382 for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it )
383 {
384 if ( (*it - c ).norm1() <= 3 ) diamond_set.insertNew( *it );
385 }
386 diamond_set.erase( c );
387 ObjectType diamond( dt6_18, diamond_set );
388 trace.endBlock();
389
390 trace.beginBlock ( "Geodesic neighborhoods ..." );
391 SmallObjectType geoN6_3 = diamond.geodesicNeighborhood( adj6, r, 3 );
392 SmallObjectType geoN18_2 = diamond.geodesicNeighborhood( adj18, r, 2 );
393 trace.info() << "geoN6_3 = " << geoN6_3 << endl;
394 trace.info() << "geoN18_2 = " << geoN18_2 << endl;
395 SmallComplementObjectType cgeoN6_3 = diamond.geodesicNeighborhoodInComplement( adj6, r, 3 );
396 SmallComplementObjectType cgeoN18_2 = diamond.geodesicNeighborhoodInComplement( adj18, r, 2 );
397 trace.info() << "cgeoN6_3 = " << cgeoN6_3 << endl;
398 trace.info() << "cgeoN18_2 = " << cgeoN18_2 << endl;
399 trace.endBlock();
400
401 trace.beginBlock ( "Simple points ..." );
402 for ( DigitalSet::ConstIterator it = diamond.pointSet().begin();
403 it != diamond.pointSet().end();
404 ++it )
405 trace.info() << "- " << *it
406 << " " << ( diamond.isSimple( *it ) ? "Simple" : "Not simple" )
407 << endl;
408 trace.endBlock();
409
410
411 return nbok == nb;
412}
413
414
416{
417 unsigned int nbok = 0;
418 unsigned int nb = 0;
419
420 trace.beginBlock ( "testDraw(): testing drawing commands." );
421
422 typedef SpaceND< 2 > Z2;
423 typedef Z2::Point Point;
425 typedef HyperRectDomain< Z2 > DomainType;
426 Point p1( -10, -10 );
427 Point p2( 10, 10 );
428 DomainType domain( p1, p2 );
429
430 // typedef DomainMetricAdjacency< DomainType, 1 > Adj4;
431 // typedef DomainMetricAdjacency< DomainType, 2 > Adj8;
432 typedef MetricAdjacency< Z2, 1 > MetricAdj4;
433 typedef MetricAdjacency< Z2, 2 > MetricAdj8;
439 MediumSet;
440// typedef DigitalSetSelector< DomainType, SMALL_DS >::Type
441// MediumSet;
442 typedef Object<DT48, MediumSet> ObjectType;
443 typedef Object<DT84, MediumSet> ObjectType84;
444
445 //typedef ObjectType::SmallSet SmallSet;
446 //typedef Object<DT48, SmallSet> SmallObjectType;
447 //typedef ObjectType::Size Size;
448
449 // Adj4 adj4( domain );
450 // Adj8 adj8( domain );
451 MetricAdj4 madj4;
452 MetricAdj8 madj8;
453 Adj4 adj4( domain, madj4 );
454 Adj8 adj8( domain, madj8 );
455 DT48 dt48( adj4, adj8, JORDAN_DT );
456 DT84 dt84( adj8, adj4, JORDAN_DT );
457
458 Coordinate r = 5;
459 double radius = (double) (r+1);
460 Point c( 0, 0 );
461 Point l( r, 0 );
462 MediumSet disk( domain );
463 ostringstream sstr;
464 sstr << "Creating disk( r < " << radius << " ) ...";
465 trace.beginBlock ( sstr.str() );
466 for ( DomainType::ConstIterator it = domain.begin();
467 it != domain.end();
468 ++it )
469 {
470 if ( (*it - c ).norm() < radius ) // 450.0
471 // insertNew is very important for vector container.
472 disk.insertNew( *it );
473 }
474 trace.endBlock();
475
476 trace.beginBlock ( "Testing Object instanciation and smart copy ..." );
477 ObjectType disk_object( dt48, disk );
478 ObjectType84 disk_object2( dt84, disk );
479 trace.endBlock();
480
481 trace.beginBlock ( "Testing export as SVG with libboard." );
482
483 Board2D board;
485
486 board << SetMode( domain.className(), "Grid" ) << domain;
487 board << disk_object;
488
489 board.saveSVG("disk-object.svg");
490
491 Board2D board2;
493
494 board2 << SetMode( domain.className(), "Grid" ) << domain;
495 board2 << SetMode( disk_object.className(), "DrawAdjacencies" ) << disk_object;
496
497 board2.saveSVG("disk-object-adj.svg");
498
499 Board2D board3;
501
502 board3 << SetMode( domain.className(), "Grid" ) << domain;
503 board3 << SetMode( disk_object2.className(), "DrawAdjacencies" ) << disk_object2;
504
505 board3.saveSVG("disk-object-adj-bis.svg");
506 trace.endBlock();
507
508 trace.endBlock();
509
510 return nbok == nb;
511
512}
513
515{
516 virtual void setStyle(Board2D & aboard) const
517 {
518 aboard.setFillColor( Color::Red);
519 aboard.setPenColorRGBi(200,0,0);
520 aboard.setLineStyle(LibBoard::Shape::SolidStyle);
521 aboard.setLineWidth( 2 );
522 }
523};
524
526{
529 : myColor( c )
530 {}
531 virtual void setStyle(Board2D & aboard) const
532 {
533 aboard.setFillColor( myColor );
534 aboard.setPenColorRGBi( 0, 0, 0 );
535 aboard.setLineStyle( LibBoard::Shape::SolidStyle );
536 aboard.setLineWidth( 1.0 );
537 }
538};
539
540using namespace DGtal::Z2i;
541
547{
548 unsigned int nbok = 0;
549 unsigned int nb = 0;
550 typedef DGtal::Z2i::Point Point;
551 //typedef Domain::ConstIterator DomainConstIterator;
552
553 Point p1( -17, -17 );
554 Point p2( 17, 17 );
555 Domain domain( p1, p2 );
556 DigitalSet shape_set( domain );
557 Shapes<Domain>::addNorm1Ball( shape_set, Point( -10, -8 ), 7 );
558 Shapes<Domain>::addNorm1Ball( shape_set, Point( 10, 8 ), 7 );
559 Shapes<Domain>::addNorm1Ball( shape_set, Point( 3, 0 ), 6 );
560 Shapes<Domain>::addNorm1Ball( shape_set, Point( 0, -3 ), 7 );
561 Shapes<Domain>::addNorm1Ball( shape_set, Point( -10, 0 ), 6 );
562 Shapes<Domain>::addNorm1Ball( shape_set, Point( -8, 8 ), 6 );
563 Shapes<Domain>::addNorm1Ball( shape_set, Point( 0, 9 ), 6 );
564 Shapes<Domain>::addNorm1Ball( shape_set, Point( 15, -2 ), 6 );
565 Shapes<Domain>::addNorm1Ball( shape_set, Point( 12, -10 ), 4 );
566 shape_set.erase( Point( 5, 0 ) );
567 shape_set.erase( Point( -1, -2 ) );
568 Object4_8 shape( dt4_8, shape_set );
569 Object8_4 shape2( dt8_4, shape_set );
570
571 GradientColorMap<int> cmap_grad( 0, 6 );
572 cmap_grad.addColor( Color( 128, 128, 255 ) );
573 cmap_grad.addColor( Color( 255, 255, 128 ) );
574 //cmap_grad.addColor( Color( 220, 130, 25 ) );
575 Board2D board;
577 board << SetMode( domain.className(), "Paving" )
578 << domain;
579 Board2D board2;
581 board2 << SetMode( domain.className(), "Grid" )
582 << domain;
583
584 // Greedy thinning.
585 DGtal::uint64_t nb_simple;
586 trace.beginBlock ( "Greedy homotopic thinning ..." );
587 int layer = 0;
588 do
589 {
590 DigitalSet & S = shape.pointSet();
591 std::queue<DigitalSet::Iterator> Q;
592 for ( DigitalSet::Iterator it = S.begin(); it != S.end(); ++it )
593 if ( shape.isSimple( *it ) )
594 Q.push( it );
595 nb_simple = 0;
596 while ( ! Q.empty() )
597 {
598 DigitalSet::Iterator it = Q.front();
599 Q.pop();
600 if ( shape.isSimple( *it ) )
601 {
602 board << CustomStyle( it->className(),
604 ( cmap_grad( layer ) ) )
605 << *it;
606 S.erase( *it );
607 ++nb_simple;
608 }
609 }
610 ++layer;
611 } while ( nb_simple != 0 );
612 trace.endBlock();
613
614 // Greedy thinning.
615 trace.beginBlock ( "Greedy homotopic thinning ..." );
616 layer = 0;
617 do
618 {
619 DigitalSet & S = shape2.pointSet();
620 std::queue<DigitalSet::Iterator> Q;
621 for ( DigitalSet::Iterator it = S.begin(); it != S.end(); ++it )
622 if ( shape2.isSimple( *it ) )
623 Q.push( it );
624 nb_simple = 0;
625 while ( ! Q.empty() )
626 {
627 DigitalSet::Iterator it = Q.front();
628 Q.pop();
629 if ( shape2.isSimple( *it ) )
630 {
631 board2 << CustomStyle( it->className(),
633 ( cmap_grad( layer ) ) )
634 << *it;
635 S.erase( *it );
636 ++nb_simple;
637 }
638 }
639 ++layer;
640 } while ( nb_simple != 0 );
641 trace.endBlock();
642
643 board << CustomStyle( shape.className(), new MyDrawStyleCustomRed )
644 << shape;
645 board.saveSVG( "shape-thinning-4-8.svg");
646 board.clear();
647
648 board2 << CustomStyle( shape2.className(), new MyDrawStyleCustomRed )
649 << shape2;
650 board2.saveSVG( "shape-thinning-8-4.svg");
651 board2.clear();
652
653 return nbok == nb;
654}
655
657{
658
659 unsigned int nbok = 0;
660 unsigned int nb = 0;
661
662 using namespace DGtal;
663 using namespace Z3i;
664 using Point = Z3i::Point ;
665 using Domain = Z3i::Domain ;
667 using KSpace = Z3i::KSpace ;
668 trace.beginBlock ( "Create Diamond Object" );
669 Point p1( -10, -10, -10 );
670 Point p2( 10, 10, 10 );
671 Domain domain( p1, p2 );
672 Point c( 0, 0, 0 );
673 Point r( 3, 0, 0 );
674
675 // diamond of radius 4
676 DigitalSet diamond_set( domain );
677 for ( auto it = domain.begin(); it != domain.end(); ++it )
678 {
679 if ( (*it - c ).norm1() <= 3 ) diamond_set.insertNew( *it );
680 }
681 // diamond_set.erase( c );
682
683 KSpace K;
684 bool space_ok = K.init( domain.lowerBound(),
685 domain.upperBound(), true // necessary
686 );
687 INBLOCK_TEST( space_ok == true ) ;
688
689 using MyDigitalTopology = Z3i::DT26_6;
690 // using MyDigitalSet = Z3i::DigitalSet ;
693 MyDigitalTopology::ForegroundAdjacency adjF;
694 MyDigitalTopology::BackgroundAdjacency adjB;
695 MyDigitalTopology topo(adjF, adjB, DGtal::DigitalTopologyProperties::JORDAN_DT);
696 MyObject obj(topo,diamond_set);
697
698 INBLOCK_TEST( obj.size() == diamond_set.size() );
699 trace.endBlock();
700 trace.beginBlock( "Check edges" );
701
702 std::set<Point> corner_points;
703 Point north( 0 , 0 , 3 );
704 corner_points.insert(north);
705 Point south( 0 , 0 , -3 );
706 corner_points.insert(south);
707 Point east( 3 , 0 , 0 );
708 corner_points.insert(east);
709 Point west( -3 , 0 , 0 );
710 corner_points.insert(west);
711
712 for(auto && p : corner_points){
713 auto pit = obj.pointSet().find(p);
714 if(pit == obj.pointSet().end()){
715 trace.info() << "point not found" << std::endl;
716 return false;
717 }
718 auto edges = obj.outEdges(*pit);
719 INBLOCK_TEST2( edges.size() == 5, edges.size() );
720 }
721 Point center( 0 , 0 , 0 );
722 auto cpit = obj.pointSet().find(center);
723 auto cedges = obj.outEdges(*cpit);
724 INBLOCK_TEST2( cedges.size() == 26, cedges.size() );
725
726 // opposites edge
727 for(auto && e : cedges){
728 auto rev_e = obj.opposite(e);
730 (e.vertices[0] == rev_e.vertices[1]) &&
731 (e.vertices[1] == rev_e.vertices[0])
732 )
733 }
734 trace.endBlock();
735
736 return nbok == nb;
737
738}
739
741{
742 unsigned int nbok = 0;
743 unsigned int nb = 0;
744 typedef DGtal::Z2i::Point Point;
745 //typedef Domain::ConstIterator DomainConstIterator;
746
747 Point p1( -17, -17 );
748 Point p2( 17, 17 );
749 Domain domain( p1, p2 );
750 DigitalSet shape_set( domain );
751 Shapes<Domain>::addNorm1Ball( shape_set, Point( -10, -8 ), 7 );
752 Shapes<Domain>::addNorm1Ball( shape_set, Point( 10, 8 ), 7 );
753 Shapes<Domain>::addNorm1Ball( shape_set, Point( 3, 0 ), 6 );
754 Shapes<Domain>::addNorm1Ball( shape_set, Point( 0, -3 ), 7 );
755 Shapes<Domain>::addNorm1Ball( shape_set, Point( -10, 0 ), 6 );
756 Shapes<Domain>::addNorm1Ball( shape_set, Point( -8, 8 ), 6 );
757 Shapes<Domain>::addNorm1Ball( shape_set, Point( 0, 9 ), 6 );
758 Shapes<Domain>::addNorm1Ball( shape_set, Point( 15, -2 ), 6 );
759 Shapes<Domain>::addNorm1Ball( shape_set, Point( 12, -10 ), 4 );
760 shape_set.erase( Point( 5, 0 ) );
761 shape_set.erase( Point( -1, -2 ) );
762 Object4_8 shape( dt4_8, shape_set );
763 // shape.setTable(functions::loadTable<2>(simplicity::tableSimple4_8));
764 {
765 auto table_smart_ptr = functions::loadTable<2>(simplicity::tableSimple4_8);
766 shape.setTable(table_smart_ptr); // table must survive (smart_ptr)
767 }
768
769 GradientColorMap<int> cmap_grad( 0, 6 );
770 cmap_grad.addColor( Color( 128, 128, 255 ) );
771 cmap_grad.addColor( Color( 255, 255, 128 ) );
772 //cmap_grad.addColor( Color( 220, 130, 25 ) );
773 Board2D board;
775 board << SetMode( domain.className(), "Paving" )
776 << domain;
777 Board2D board2;
779 board2 << SetMode( domain.className(), "Grid" )
780 << domain;
781
782 // Greedy thinning.
783 DGtal::uint64_t nb_simple;
784 trace.beginBlock ( "Greedy homotopic thinning with table..." );
785 int layer = 0;
786 do {
787 DigitalSet & S = shape.pointSet();
788 std::queue<DigitalSet::Iterator> Q;
789 for ( DigitalSet::Iterator it = S.begin(); it != S.end(); ++it )
790 if ( shape.isSimple( *it ) )
791 Q.push( it );
792 nb_simple = 0;
793 while ( ! Q.empty() )
794 {
795 DigitalSet::Iterator it = Q.front();
796 Q.pop();
797 if ( shape.isSimple( *it ) )
798 {
799 board << CustomStyle( it->className(),
801 ( cmap_grad( layer ) ) )
802 << *it;
803 S.erase( *it );
804 ++nb_simple;
805 }
806 }
807 ++layer;
808 } while ( nb_simple != 0 );
809 trace.endBlock();
810
811 return nbok == nb;
812
813}
814
815// Standard services - public :
816
817int main( int argc, char** argv )
818{
819 trace.beginBlock ( "Testing class Object" );
820 trace.info() << "Args:";
821 for ( int i = 0; i < argc; ++i )
822 trace.info() << " " << argv[ i ];
823 trace.info() << endl;
824
825 bool res = testObject() &&
829 && testObjectGraph()
830 && testSetTable();
831
832 trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
833 trace.endBlock();
834 return res ? 0 : 1;
835}
836// //
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Definition Board2D.h:71
Structure representing an RGB triple with alpha component.
Definition Color.h:77
static const Color Red
Definition Color.h:425
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: Given a domain and an adjacency, limits the given adjacency to the specified domain for all adja...
Aim: This class is useful to visit an object by adjacencies, layer by layer.
Definition Expander.h:98
Aim: This class template may be used to (linearly) convert scalar values in a given range into a colo...
void addColor(const Color &color)
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
Aim: Describes digital adjacencies in digital spaces that are defined with the 1-norm and the infinit...
Aim: An object (or digital object) represents a set in some digital space associated with a digital t...
Definition Object.h:120
Size size() const
Object< ReverseTopology, SmallSet > SmallComplementObject
Definition Object.h:154
const DigitalSet & pointSet() const
std::string className() const
SmallObject properNeighborhood(const Point &p) const
SmallObject neighborhood(const Point &p) const
Object< DigitalTopology, SmallSet > SmallObject
Definition Object.h:153
void setTable(Alias< boost::dynamic_bitset<> >inputTable)
bool isSimple(const Point &v) const
static void addNorm1Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)
PointVector< dim, Integer > Point
Definition SpaceND.h:110
Board & setPenColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
Definition Board.cpp:277
void clear(const DGtal::Color &color=DGtal::Color::None)
Definition Board.cpp:151
Board & setFillColor(const DGtal::Color &color)
Definition Board.cpp:321
Board & setLineWidth(double width)
Definition Board.cpp:328
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition Board.cpp:1011
void setUnit(Unit unit)
Definition Board.cpp:239
Board & setLineStyle(Shape::LineStyle style)
Z2i this namespace gathers the standard of types for 2D imagery.
static const DT8_4 dt8_4
Definition StdDefs.h:114
Object< DT8_4, DigitalSet > Object8_4
Definition StdDefs.h:105
MetricAdjacency< Space, 1 > Adj4
Definition StdDefs.h:90
KhalimskySpaceND< 2, Integer > KSpace
Definition StdDefs.h:77
static const DT4_8 dt4_8
Definition StdDefs.h:113
Object< DT4_8, DigitalSet > Object4_8
Definition StdDefs.h:101
static const Adj4 adj4
Definition StdDefs.h:111
MetricAdjacency< Space, 2 > Adj8
Definition StdDefs.h:92
Space::Point Point
Definition StdDefs.h:95
static const Adj8 adj8
Definition StdDefs.h:112
DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet
Definition StdDefs.h:100
Space Z2
Definition StdDefs.h:76
Z3i this namespace gathers the standard of types for 3D imagery.
HyperRectDomain< Space > Domain
Definition StdDefs.h:172
KhalimskySpaceND< 3, Integer > KSpace
Definition StdDefs.h:146
Space::Point Point
Definition StdDefs.h:168
DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet
Definition StdDefs.h:173
DigitalTopology< Adj26, Adj6 > DT26_6
Definition StdDefs.h:167
DGtal::CountedPtr< boost::dynamic_bitset<> > loadTable(const std::string &input_filename, const unsigned int known_size, const bool compressed=true)
DGtal is the top-level namespace which contains all DGtal functions and types.
std::uint64_t uint64_t
unsigned 64-bit integer.
Definition BasicTypes.h:64
@ CONNECTED
Definition Topology.h:52
Trace trace
STL namespace.
static void assign(OutputDigitalSet &output, const InputDigitalSet &input)
DigitalSetByAssociativeContainer< Domain, std::unordered_set< typename Domain::Point > > Type
Modifier class in a Board2D stream. Useful to choose your own mode for a given class....
Definition Board2D.h:247
Struct representing a 2D point.
Definition Point.h:27
virtual void setStyle(Board2D &aboard) const
MyDrawStyleCustomFillColor(const Color &c)
virtual void setStyle(Board2D &aboard) const
int main()
Definition testBits.cpp:56
KSpace K
HalfEdgeDataStructure::Size Size
bool testObject3D()
bool testSetTable()
bool testSimplePoints3D()
bool testObject()
bool testObjectGraph()
bool testDraw()
#define INBLOCK_TEST2(x, y)
bool testSimplePoints2D()
#define INBLOCK_TEST(x)
Domain domain