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