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"
57 using namespace DGtal;
60 #define INBLOCK_TEST(x) \
61 nbok += ( x ) ? 1 : 0; \
63 trace.info() << "(" << nbok << "/" << nb << ") " \
66 #define INBLOCK_TEST2(x,y) \
67 nbok += ( x ) ? 1 : 0; \
69 trace.info() << "(" << nbok << "/" << nb << ") " \
81 unsigned int nbok = 0;
88 Point p1( -449, -449 );
90 DomainType
domain( p1, p2 );
104 typedef ObjectType::SmallSet SmallSet;
117 double radius = (double) (r+1);
122 sstr <<
"Creating disk( r < " << radius <<
" ) ...";
128 if ( (*it - c ).norm() < radius )
130 disk.insertNew( *it );
134 trace.
beginBlock (
"Testing Object instanciation and smart copy ..." );
135 ObjectType disk_object( dt48, disk );
136 nbok += disk_object.size() == 7825 ? 1 : 0;
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;
144 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
145 <<
"Disk2 (r=450.0) " << disk_object2 << std::endl;
146 trace.
info() <<
" size=" << disk_object2.size() << std::endl;
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;
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;
160 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
161 <<
"Disk2 + c (r=450.0) " << disk_object2 << std::endl;
162 trace.
info() <<
" size=" << disk_object2.size() << std::endl;
167 nbok += neigh.
size() == 4 ? 1 : 0;
169 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
170 <<
"N_4(Disk, c).size() = " << neigh.
size()
171 <<
" == 4" << std::endl;
173 nbok += neigh.
size() == 3 ? 1 : 0;
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;
181 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
182 <<
"#N*_4(Disk, " << l <<
") = " << size
183 <<
" == 3" << std::endl;
186 nbok += neigh.
size() == 5 ? 1 : 0;
188 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
189 <<
"N_4(Disk2, c).size() = " << neigh.
size()
190 <<
" == 5" << std::endl;
195 ( neigh.
pointSet(), disk_object.pointSet() );
196 nbok += neigh.
size() == 7824 ? 1 : 0;
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;
206 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
207 <<
"neigh = N_4(Disk2, c), size() = " << neigh.
size()
208 <<
" == 5" << std::endl;
212 ObjectType bdisk = disk_object.border();
213 nbok += bdisk.size() == 400 ? 1 : 0;
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;
221 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
222 <<
"Border(Disk2, c), size() = " << bdisk2.size()
223 <<
" == 3364" << std::endl;
226 trace.
beginBlock (
"Testing expansion by layers on the boundary ..." );
228 ObjectExpander expander( bdisk, *(bdisk.pointSet().begin()) );
229 while ( ! expander.finished() )
231 nbok += expander.layer().size() <= 2 ? 1 : 0;
233 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
234 <<
"expander.layer.size() <= 2 "
235 << expander << std::endl;
236 expander.nextLayer();
240 trace.
beginBlock (
"Testing expansion by layers on the disk from center..." );
241 ObjectExpander expander2( disk_object2, c );
242 while ( ! expander2.finished() )
245 expander2.nextLayer();
247 nbok += expander2.distance() <= sqrt(2.0)*radius ? 1 : 0;
249 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
250 <<
"expander.distance() = " << expander2.distance()
251 <<
" <= " << sqrt(2.0)*radius << std::endl;
263 unsigned int nbok = 0;
278 Point p1( -50, -50, -50 );
279 Point p2( 50, 50, 50 );
284 trace.
beginBlock (
"Testing 3D Object instanciation and smart copy ..." );
285 trace.
info() <<
"Creating diamond (r=15)" << endl;
290 if ( (*it - c ).norm1() <= 15 ) diamond_set.
insertNew( *it );
292 ObjectType diamond( dt6_18, diamond_set );
293 trace.
info() <<
"Cloning diamond" << endl;
295 ObjectType diamond_clone( diamond );
297 trace.
info() <<
"Removing two points " << c <<
" and " << d << endl;
298 diamond_clone.pointSet().erase( c );
299 diamond_clone.pointSet().erase( d );
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;
307 for ( vector<ObjectType>::const_iterator it = objects.begin();
310 trace.
info() <<
"- objects[" << (it - objects.begin() ) <<
"]"
311 <<
" = " << *it << endl;
313 INBLOCK_TEST( objects[ 0 ].size() == ( objects[ 1 ].size() + 2 ) );
324 vector<ObjectType> objects2;
325 back_insert_iterator< vector< ObjectType > > inserter2( objects2 );
326 auto nbc0 = objects[ 0 ].border().writeComponents( inserter2 );
332 auto nbc1 = objects[ 1 ].border().writeComponents( inserter2 );
335 for ( vector<ObjectType>::const_iterator it = objects2.begin();
336 it != objects2.end();
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() );
357 unsigned int nbok = 0;
374 Point p1( -10, -10, -10 );
375 Point p2( 10, 10, 10 );
385 if ( (*it - c ).norm1() <= 3 ) diamond_set.
insertNew( *it );
387 diamond_set.
erase( c );
388 ObjectType diamond( dt6_18, diamond_set );
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;
404 it != diamond.pointSet().end();
407 <<
" " << ( diamond.isSimple( *it ) ?
"Simple" :
"Not simple" )
418 unsigned int nbok = 0;
427 Point p1( -10, -10 );
429 DomainType
domain( p1, p2 );
460 double radius = (double) (r+1);
465 sstr <<
"Creating disk( r < " << radius <<
" ) ...";
471 if ( (*it - c ).norm() < radius )
473 disk.insertNew( *it );
477 trace.
beginBlock (
"Testing Object instanciation and smart copy ..." );
478 ObjectType disk_object( dt48, disk );
479 ObjectType84 disk_object2( dt84, disk );
485 board.
setUnit(Board::UCentimeter);
488 board << disk_object;
490 board.
saveSVG(
"disk-object.svg");
493 board2.
setUnit(Board::UCentimeter);
496 board2 <<
SetMode( disk_object.className(),
"DrawAdjacencies" ) << disk_object;
498 board2.
saveSVG(
"disk-object-adj.svg");
501 board3.
setUnit(Board::UCentimeter);
504 board3 <<
SetMode( disk_object2.className(),
"DrawAdjacencies" ) << disk_object2;
506 board3.
saveSVG(
"disk-object-adj-bis.svg");
517 virtual void setStyle(
Board2D & aboard)
const
529 MyDrawStyleCustomFillColor(
const Color & c )
532 virtual void setStyle(
Board2D & aboard)
const
549 unsigned int nbok = 0;
554 Point p1( -17, -17 );
577 board.
setUnit(Board::UCentimeter);
581 board2.
setUnit(Board::UCentimeter);
592 std::queue<DigitalSet::Iterator> Q;
597 while ( ! Q.empty() )
604 new MyDrawStyleCustomFillColor
605 ( cmap_grad( layer ) ) )
612 }
while ( nb_simple != 0 );
621 std::queue<DigitalSet::Iterator> Q;
626 while ( ! Q.empty() )
633 new MyDrawStyleCustomFillColor
634 ( cmap_grad( layer ) ) )
641 }
while ( nb_simple != 0 );
646 board.
saveSVG(
"shape-thinning-4-8.svg");
651 board2.
saveSVG(
"shape-thinning-8-4.svg");
660 unsigned int nbok = 0;
663 using namespace DGtal;
670 Point p1( -10, -10, -10 );
671 Point p2( 10, 10, 10 );
680 if ( (*it - c ).norm1() <= 3 ) diamond_set.
insertNew( *it );
694 MyDigitalTopology::ForegroundAdjacency adjF;
695 MyDigitalTopology::BackgroundAdjacency adjB;
696 MyDigitalTopology topo(adjF, adjB, DGtal::DigitalTopologyProperties::JORDAN_DT);
697 MyObject obj(topo,diamond_set);
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);
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;
719 auto edges = obj.outEdges(*pit);
722 Point center( 0 , 0 , 0 );
723 auto cpit = obj.pointSet().find(center);
724 auto cedges = obj.outEdges(*cpit);
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])
743 unsigned int nbok = 0;
748 Point p1( -17, -17 );
766 auto table_smart_ptr = functions::loadTable<2>(simplicity::tableSimple4_8);
775 board.
setUnit(Board::UCentimeter);
779 board2.
setUnit(Board::UCentimeter);
789 std::queue<DigitalSet::Iterator> Q;
794 while ( ! Q.empty() )
801 new MyDrawStyleCustomFillColor
802 ( cmap_grad( layer ) ) )
809 }
while ( nb_simple != 0 );
818 int main(
int argc,
char** argv )
822 for (
int i = 0; i < argc; ++i )
833 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Structure representing an RGB triple with alpha component.
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
void insertNew(const Point &p)
ConstIterator end() const
Container::iterator Iterator
Iterator type of the container.
ConstIterator begin() const
Size erase(const Point &p)
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.
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 & end() const
const ConstIterator & begin() const
const Point & lowerBound() const
const Point & upperBound() const
std::string className() 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...
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.
Aim: A utility class for constructing different shapes (balls, diamonds, and others).
void beginBlock(const std::string &keyword="")
Board & setLineStyle(Shape::LineStyle style)
Board & setPenColorRGBi(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha=255)
void clear(const DGtal::Color &color=DGtal::Color::None)
Board & setFillColor(const DGtal::Color &color)
Board & setLineWidth(double width)
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
MyDigitalSurface::ConstIterator ConstIterator
Z2i this namespace gathers the standard of types for 2D imagery.
DGtal is the top-level namespace which contains all DGtal functions and types.
boost::uint64_t uint64_t
unsigned 64-bit integer.
Aim: Utility class to convert between types of sets.
Modifier class in a Board2D stream. Useful to choose your own mode for a given class....
Struct representing a 2D point.
HalfEdgeDataStructure::Size Size
int main(int argc, char **argv)
bool testSimplePoints3D()
#define INBLOCK_TEST2(x, y)
bool testSimplePoints2D()
HyperRectDomain< Space > Domain
Z2i::DigitalSet DigitalSet