32 #include "DGtal/base/Common.h"
33 #include "DGtal/kernel/SpaceND.h"
34 #include "DGtal/kernel/domains/HyperRectDomain.h"
35 #include "DGtal/kernel/sets/DigitalSetSelector.h"
36 #include "DGtal/topology/CCellularGridSpaceND.h"
37 #include "DGtal/topology/KhalimskySpaceND.h"
38 #include "DGtal/topology/SurfelAdjacency.h"
39 #include "DGtal/topology/SurfelNeighborhood.h"
40 #include "DGtal/shapes/Shapes.h"
41 #include "DGtal/topology/helpers/Surfaces.h"
42 #include "DGtal/io/boards/Board2D.h"
43 #include "DGtal/io/Color.h"
47 using namespace DGtal;
56 template <
typename KSpace>
57 bool testCellularGridSpaceND()
59 typedef typename KSpace::Cell
Cell;
60 typedef typename KSpace::SCell
SCell;
61 typedef typename KSpace::Point
Point;
62 typedef typename KSpace::DirIterator DirIterator;
63 typedef typename KSpace::Cells
Cells;
64 typedef typename KSpace::SCells
SCells;
65 unsigned int nbok = 0;
70 int xlow[ 4 ] = { -3, -2, -2, -1 };
71 int xhigh[ 4 ] = { 5, 3, 2, 3 };
74 bool space_ok = K.init( low, high,
true );
75 nbok += space_ok ? 1 : 0;
77 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
78 <<
"K.init( low, high )" << std::endl;
79 trace.
info() <<
"K.dim()=" << K.dimension << endl;
80 int spel[ 4 ] = { 1, 1, 1, 1 };
82 Cell center = K.uCell( kp );
83 Cell c1 = K.uCell( kp );
84 Cell clow = K.uCell( low, kp );
85 Cell chigh = K.uCell( high, kp );
87 <<
" topo(c1)=" << K.uTopology( c1 ) <<
" dirs=";
88 for ( DirIterator q = K.uDirs( clow ); q != 0; ++q )
91 Cell f = K.uFirst( c1 );
92 Cell l = K.uLast( c1 );
93 trace.
info() <<
"Loop in " << clow << chigh << endl;
95 unsigned int nbelems = 0;
99 }
while ( K.uNext( c1, f, l ) );
100 trace.
info() <<
" -> " << nbelems <<
" elements." << endl;
101 unsigned int exp_nbelems = 1;
102 for (
Dimension i = 0; i < K.dimension; ++i )
103 exp_nbelems *= K.size( i );
104 nbok += nbelems == exp_nbelems ? 1 : 0;
106 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
107 << nbelems <<
" scanned elements == "
108 << exp_nbelems <<
" space size."
112 Cells N = K.uNeighborhood( center );
113 nbok += N.size() == ( K.dimension*2 + 1 ) ? 1 : 0;
115 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
116 << N.size() <<
"(neighborhood size) == "
117 << ( K.dimension*2 + 1 ) <<
"(2*dim()+1)" << endl;
118 Cells Np = K.uProperNeighborhood( center );
119 nbok += Np.size() == ( K.dimension*2 ) ? 1 : 0;
121 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
122 << Np.size() <<
"(proper neighborhood size) == "
123 << ( K.dimension*2 ) <<
"(2*dim())" << endl;
127 Cells Nf = K.uFaces( center );
128 nbok += Nf.size() == ceil( std::pow( 3.0 ,(
int) K.dimension ) - 1 ) ? 1 : 0;
130 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
131 << Nf.size() <<
"(faces size) == "
132 << floor( std::pow( 3.0, (
int)K.dimension ) - 1 ) <<
"(3^dim()-1)" << endl;
136 SCell sspel = K.sCell( kp, K.POS );
137 for ( DirIterator q1 = K.sDirs( sspel ); q1 != 0; ++q1 )
138 for ( DirIterator q2 = K.sDirs( sspel ); q2 != 0; ++q2 )
142 SCell s0 = K.sIncident( sspel, *q1,
true );
143 SCell s1 = K.sIncident( sspel, *q2,
true );
144 SCell l10 = K.sIncident( s0, *q2,
true );
145 SCell l01 = K.sIncident( s1, *q1,
true );
146 trace.
info() <<
"D+_" << *q2 <<
"(D+_" << *q1 <<
"(V))=" << l10
147 <<
" D+_" << *q1 <<
"(D+_" << *q2 <<
"(V))=" << l01
149 nbok += l10 == K.sOpp( l01 ) ? 1 : 0;
153 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
154 <<
"anti-commutativity of incidence operators." << std::endl;
158 for ( DirIterator q1 = K.sDirs( sspel ); q1 != 0; ++q1 )
159 for ( DirIterator q2 = K.sDirs( sspel ); q2 != 0; ++q2 )
163 SCell s0 = K.sDirectIncident( sspel, *q1 );
164 SCell l10 = K.sDirectIncident( s0, *q2 );
165 SCell s1 = K.sDirectIncident( sspel, *q2 );
166 SCell l01 = K.sDirectIncident( s1, *q1 );
167 trace.
info() <<
"Dd_" << *q2 <<
"(Dd_" << *q1 <<
"(V))=" << l10
168 <<
" Dd_" << *q1 <<
"(Dd_" << *q2 <<
"(V))=" << l01
170 nbok += l10 != l01 ? 1 : 0;
171 nbok += K.sSign( s0 ) == K.POS ? 1 : 0;
172 nbok += K.sSign( s1 ) == K.POS ? 1 : 0;
173 nbok += K.sSign( l10 ) == K.POS ? 1 : 0;
174 nbok += K.sSign( l01 ) == K.POS ? 1 : 0;
175 nbok += s0 == K.sIncident( sspel, *q1, K.sDirect( sspel, *q1 ) )
177 nbok += s1 == K.sIncident( sspel, *q2, K.sDirect( sspel, *q2 ) )
179 nbok += l10 == K.sIncident( s0, *q2, K.sDirect( s0, *q2 ) )
181 nbok += l01 == K.sIncident( s1, *q1, K.sDirect( s1, *q1 ) )
186 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
187 <<
"correctness of direct and indirect orientations." << std::endl;
196 template <
typename KSpace>
197 bool testSurfelAdjacency()
199 typedef typename KSpace::Integer
Integer;
200 typedef typename KSpace::Cell Cell;
201 typedef typename KSpace::SCell SCell;
202 typedef typename KSpace::Point Point;
203 typedef typename KSpace::DirIterator DirIterator;
204 typedef typename KSpace::Cells Cells;
205 typedef typename KSpace::SCells SCells;
206 unsigned int nbok = 0;
209 trace.
beginBlock (
"Testing block KSpace instantiation and scan ..." );
211 int xlow[ 4 ] = { -3, -3, -3, -3 };
212 int xhigh[ 4 ] = { 5, 3, 3, 3 };
215 bool space_ok = K.init( low, high,
true );
216 nbok += space_ok ? 1 : 0;
218 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
219 <<
"K.init( low, high )" << std::endl;
220 trace.
info() <<
"K.dim()=" << K.dimension << endl;
224 for (
Dimension i = 0; i < K.dimension; ++i )
225 for (
Dimension j = 0; j < K.dimension; ++j )
227 trace.
info() <<
"(" << i <<
"," << j <<
")="
228 << ( SAdj.getAdjacency( i, j ) ?
"i2e" :
"e2i" );
232 int spel[ 4 ] = { 1, 1, 1, 1 };
234 SCell sspel = K.sCell( kp, K.POS );
236 for (
Dimension k = 0; k < K.dimension; ++k )
238 SCell surfel = K.sIncident( sspel, k,
true );
239 SCell innerspel = K.sDirectIncident( surfel, K.sOrthDir( surfel ) );
240 trace.
info() <<
"spel=" << sspel <<
" surfel=" << surfel
241 <<
" innerspel=" << innerspel << endl;
242 nbok += sspel == innerspel ? 1 : 0;
244 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
245 <<
"spel == innerspel" << std::endl;
246 surfel = K.sIncident( sspel, k,
false );
247 innerspel = K.sDirectIncident( surfel, K.sOrthDir( surfel ) );
248 trace.
info() <<
"spel=" << sspel <<
" surfel=" << surfel
249 <<
" innerspel=" << innerspel << endl;
250 nbok += sspel == innerspel ? 1 : 0;
252 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
253 <<
"spel == innerspel" << std::endl;
259 SCell surfel = K.sIncident( sspel, 0,
false );
260 SN.
init( &K, &SAdj, surfel );
261 trace.
info() <<
"surfel =" << surfel << endl;
274 Domain domain( low, high );
275 DigitalSet shape_set( domain );
277 int center[ 4 ] = { 1, 0, 0, 0 };
278 Point pcenter( center );
280 trace.
info() <<
"surfel = " << surfel << endl;
281 SCell other1, other2;
284 trace.
info() <<
"directNext = " << other1 << endl;
285 trace.
info() <<
"indirectNext= " << other2 << endl;
286 std::set<SCell> bdry;
291 K, SAdj, shape_set_predicate, surfel );
292 trace.
info() <<
"tracking finished, size=" << bdry.size()
293 <<
", should be " << 2*K.dimension*(2*K.dimension-1) << endl;
294 nbok += bdry.size() == ( 2*K.dimension*(2*K.dimension-1) ) ? 1 : 0;
296 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
297 <<
"bdry.size() == ( 2*K.dimension*(2*K.dimension-1) )"
299 std::set<SCell> bdry_direct;
301 K, SAdj, shape_set_predicate, surfel );
302 trace.
info() <<
"fast direct tracking finished, size=" << bdry_direct.size()
303 <<
", should be " << 2*K.dimension*(2*K.dimension-1) << endl;
304 nbok += bdry_direct.size() == ( 2*K.dimension*(2*K.dimension-1) ) ? 1 : 0;
306 trace.
info() <<
"(" << nbok <<
"/" << nb <<
") "
307 <<
"bdry_direct.size() == ( 2*K.dimension*(2*K.dimension-1) )"
311 if ( K.dimension == 2 )
315 board <<
SetMode( domain.className(),
"Paving" )
317 for (
typename std::set<SCell>::const_iterator it = bdry_direct.begin(),
318 it_end = bdry_direct.end(); it != it_end; ++it )
320 board.
saveEPS(
"cells-2.eps" );
321 board.
saveSVG(
"cells-2.svg" );
326 template <
typename KSpace>
327 bool testCellDrawOnBoard()
329 typedef typename KSpace::Integer Integer;
330 typedef typename KSpace::Cell Cell;
331 typedef typename KSpace::SCell SCell;
332 typedef typename KSpace::Point Point;
333 typedef typename KSpace::DirIterator DirIterator;
334 typedef typename KSpace::Cells Cells;
335 typedef typename KSpace::SCells SCells;
338 unsigned int nbok = 0;
342 int xlow[ 4 ] = { -3, -3 };
343 int xhigh[ 4 ] = { 5, 3 };
346 bool space_ok = K.init( low, high,
true );
347 Domain domain( low, high );
350 board <<
SetMode( domain.className(),
"Paving" )
352 int spel[ 2 ] = { 1, 1 };
354 Cell uspel = K.uCell( kp );
357 << K.uIncident( uspel, 0,
false )
358 << K.uIncident( uspel, 1,
false );
359 int spel2[ 2 ] = { 5, 1 };
361 SCell sspel2 = K.sCell( kp2, K.POS );
364 Color( 255, 100, 100 ),
366 Board2D::Shape::SolidStyle ) )
368 << K.sIncident( sspel2, 0, K.sDirect( sspel2, 0 ) )
369 << K.sIncident( sspel2, 1, K.sDirect( sspel2, 0 ) );
370 board.
saveEPS(
"cells-1.eps" );
371 board.
saveSVG(
"cells-1.svg" );
375 SCell slinel0 = K.sIncident( sspel2, 0, K.sDirect( sspel2, 0 ) );
376 SCell spointel01 = K.sIncident( slinel0, 1, K.sDirect( slinel0, 1 ) );
379 Color( 255, 100, 100 ) ) )
383 Color( 100, 255, 100 ) ) )
387 Color( 100, 100, 255 ) ) )
389 board.
saveEPS(
"cells-3.eps" );
390 board.
saveSVG(
"cells-3.svg" );
392 return ((space_ok) && (nbok == nb));
395 template <
typename KSpace>
398 typedef typename KSpace::Point Point;
402 typedef typename KSpace::SCell SCell;
406 Point low(-3,-3,-3), high(3,3,3);
407 Domain domain( low, high );
408 DigitalSet shape_set( domain );
409 PointPredicate pp( shape_set );
411 K.init( low, high,
true );
413 Point p000(0,0,0), p001(0,0,1), p010(0,1,0), p011(0,1,1),
414 p100(1,0,0), p101(1,0,1), p110(1,1,0), p111(1,1,1);
416 shape_set.insert( p000 );
417 shape_set.insert( p100 );
427 return ( (s010 == SCell( Point(1,2,1),
true ) ) &&
428 (s001 == SCell( Point(1,1,2),
false ) ) );
434 int main(
int argc,
char** argv )
438 for (
int i = 0; i < argc; ++i )
449 bool res = testCellularGridSpaceND<K2>()
450 && testCellularGridSpaceND<K3>()
451 && testCellularGridSpaceND<K4>()
452 && testSurfelAdjacency<K2>()
453 && testSurfelAdjacency<K3>()
454 && testSurfelAdjacency<K4>()
455 && testCellDrawOnBoard<K2>()
456 && testFindABel<K3>();
457 trace.
emphase() << ( res ?
"Passed." :
"Error." ) << endl;