DGtal  0.9.3
testCubicalComplex.cpp
Go to the documentation of this file.
1 
30 #include <iostream>
32 #include <map>
33 #include <unordered_map>
34 #include "DGtal/base/Common.h"
35 #include "DGtal/kernel/domains/HyperRectDomain.h"
36 #include "DGtal/topology/KhalimskySpaceND.h"
37 #include "DGtal/topology/KhalimskyCellHashFunctions.h"
38 #include "DGtal/topology/CubicalComplex.h"
39 #include "DGtal/topology/CubicalComplexFunctions.h"
40 #include "DGtalCatch.h"
42 
43 using namespace std;
44 using namespace DGtal;
45 
46 
48 // Functions for testing class CubicalComplex.
50 
51 static const int NBCELLS = 1000;
52 
53 SCENARIO( "CubicalComplex< K3,std::unordered_map<> > unit tests (incidence,...)", "[cubical_complex][incidence]" )
54 {
55  typedef KhalimskySpaceND<3> KSpace;
56  typedef KSpace::Point Point;
57  typedef KSpace::Cell Cell;
58  typedef std::unordered_map<Cell, CubicalCellData> Map;
61 
62  srand( 0 );
63  KSpace K;
64  K.init( Point( 0,0,0 ), Point( 512,512,512 ), true );
65  std::vector<int> nbCoFaces( 4, 0 );
66  std::vector<int> nbFaces( 6, 0 );
67  std::vector<int> nbFaces2( 6, 0 );
68  std::vector<int> nbBdry( 10, 0 );
69  std::vector<int> nbBdry2( 10, 0 );
70 
71  GIVEN( "A cubical complex with random 3-cells" ) {
72  CC complex( K );
73  for ( int n = 0; n < NBCELLS; ++n )
74  {
75  Point p( (rand() % 512) | 0x1, (rand() % 512) | 0x1, (rand() % 512) | 0x1 );
76  Cell cell = K.uCell( p );
77  complex.insertCell( cell );
78  }
79  THEN( "It has only 3-cells and no other type of cells" ) {
80  REQUIRE( complex.nbCells( 0 ) == 0 );
81  REQUIRE( complex.nbCells( 1 ) == 0 );
82  REQUIRE( complex.nbCells( 2 ) == 0 );
83  REQUIRE( complex.nbCells( 3 ) > 0 );
84  }
85 
86  WHEN( "Computing proper faces of these 3-cells" ) {
87  std::vector<Cell> faces;
88  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
89  for ( CellMapConstIterator it = complex.begin( 3 ), itE = complex.end( 3 );
90  it != itE; ++it )
91  complex.faces( outIt, it->first );
92  THEN( "There are no proper faces within this complex" ) {
93  REQUIRE( faces.size() == 0 );
94  }
95  }
96 
97  WHEN( "Closing the cubical complex" ) {
98  complex.close();
99  THEN( "It has cells of all dimensions." ) {
100  REQUIRE( complex.nbCells( 0 ) > 0 );
101  REQUIRE( complex.nbCells( 1 ) > 0 );
102  REQUIRE( complex.nbCells( 2 ) > 0 );
103  }
104 
105  WHEN( "Computing the direct co-faces of 2-cells" ) {
106  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
107  it != itE; ++it )
108  {
109  std::vector<Cell> faces;
110  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
111  complex.directCoFaces( outIt, it->first );
112  int n = faces.size();
113  if ( n >= 3 ) n = 3; // should not happen
114  nbCoFaces[ n ]++;
115  }
116  THEN( "None of them are incident to zero 3-cells" ) {
117  REQUIRE( nbCoFaces[ 0 ] == 0 );
118  } AND_THEN ( "Most of them are incident to one 3-cells and some of them to two 3-cells" ) {
119  REQUIRE( nbCoFaces[ 1 ] > 10*nbCoFaces[ 2 ] );
120  } AND_THEN ("None of them are incident to three or more 3-cells" ) {
121  REQUIRE( nbCoFaces[ 3 ] == 0 );
122  }
123  }
124 
125  WHEN( "Computing direct faces of 2-cells" ) {
126  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
127  it != itE; ++it )
128  {
129  std::vector<Cell> faces;
130  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
131  complex.directFaces( outIt, it->first, true );
132  int n = faces.size();
133  if ( n < 4 ) n = 3; // should not happen
134  if ( n > 4 ) n = 5; // should not happen
135  nbFaces[ n ]++;
136  }
137  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
138  it != itE; ++it )
139  {
140  std::vector<Cell> faces;
141  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
142  complex.directFaces( outIt, it->first );
143  int n = faces.size();
144  if ( n < 4 ) n = 3; // should not happen
145  if ( n > 4 ) n = 5; // should not happen
146  nbFaces2[ n ]++;
147  }
148  THEN( "All of them have exactly 4 incident 1-cells when computed with hint closed" ) {
149  REQUIRE( nbFaces[ 3 ] == 0 );
150  REQUIRE( nbFaces[ 4 ] > 0 );
151  REQUIRE( nbFaces[ 5 ] == 0 );
152  } AND_THEN( "All of them have exactly 4 incident 1-cells when computed without hint" ) {
153  REQUIRE( nbFaces2[ 3 ] == 0 );
154  REQUIRE( nbFaces2[ 4 ] > 0 );
155  REQUIRE( nbFaces2[ 5 ] == 0 );
156  } AND_THEN( "It gives the same number of incident cells with or without hint" ) {
157  REQUIRE( nbFaces[ 4 ] == nbFaces2[ 4 ] );
158  }
159  }
160 
161  WHEN( "Computing boundaries of 2-cells" ) {
162  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
163  it != itE; ++it )
164  {
165  CC::Cells faces = complex.cellBoundary( it->first, true );
166  int n = faces.size();
167  if ( n < 8 ) n = 7; // should not happen
168  if ( n > 8 ) n = 9; // should not happen
169  nbBdry[ n ]++;
170  }
171  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
172  it != itE; ++it )
173  {
174  CC::Cells faces = complex.cellBoundary( it->first, false );
175  int n = faces.size();
176  if ( n < 8 ) n = 7; // should not happen
177  if ( n > 8 ) n = 9; // should not happen
178  nbBdry2[ n ]++;
179  }
180  THEN( "All of them contain exactly 8 cells when computed with hint closed" ) {
181  REQUIRE( nbBdry[ 7 ] == 0 );
182  REQUIRE( nbBdry[ 8 ] > 0 );
183  REQUIRE( nbBdry[ 9 ] == 0 );
184  } AND_THEN( "All of them contain exactly 8 cells when computed without hint" ) {
185  REQUIRE( nbBdry2[ 7 ] == 0 );
186  REQUIRE( nbBdry2[ 8 ] > 0 );
187  REQUIRE( nbBdry2[ 9 ] == 0 );
188  } AND_THEN( "It gives the same number of incident cells with or without hint" ) {
189  REQUIRE( nbBdry[ 8 ] == nbBdry2[ 8 ] );
190  }
191  }
192  } // WHEN( "Closing the cubical complex" ) {
193  }
194 }
195 
196 SCENARIO( "CubicalComplex< K3,std::unordered_map<> > collapse tests", "[cubical_complex][collapse]" )
197 {
198  typedef KhalimskySpaceND<3> KSpace;
199  typedef KSpace::Point Point;
200  typedef KSpace::Cell Cell;
201  typedef KSpace::Integer Integer;
202  typedef std::unordered_map<Cell, CubicalCellData> Map;
204  typedef CC::CellMapIterator CellMapIterator;
205 
206  srand( 0 );
207  KSpace K;
208  K.init( Point( 0,0,0 ), Point( 512,512,512 ), true );
209 
210  GIVEN( "A closed cubical complex made of 3x3x3 voxels with their incident cells" ) {
211  CC complex( K );
212  std::vector<Cell> S;
213  for ( Integer x = 0; x < 3; ++x )
214  for ( Integer y = 0; y < 3; ++y )
215  for ( Integer z = 0; z < 3; ++z )
216  {
217  S.push_back( K.uSpel( Point( x, y, z ) ) );
218  complex.insertCell( S.back() );
219  }
220  complex.close();
221  CAPTURE( complex.nbCells( 0 ) );
222  CAPTURE( complex.nbCells( 1 ) );
223  CAPTURE( complex.nbCells( 2 ) );
224  CAPTURE( complex.nbCells( 3 ) );
225 
226  THEN( "It has Euler characteristic 1" ) {
227  REQUIRE( complex.euler() == 1 );
228  }
229 
230  WHEN( "Fixing two vertices of this big cube and collapsing it" ) {
231  CellMapIterator it1 = complex.findCell( 0, K.uCell( Point( 0, 0, 0 ) ) );
232  CellMapIterator it2 = complex.findCell( 0, K.uCell( Point( 4, 4, 4 ) ) );
233  REQUIRE( it1 != complex.end( 0 ) );
234  REQUIRE( it2 != complex.end( 0 ) );
235  it1->second.data |= CC::FIXED;
236  it2->second.data |= CC::FIXED;
238  functions::collapse( complex, S.begin(), S.end(), P, false, true );
239  CAPTURE( complex.nbCells( 0 ) );
240  CAPTURE( complex.nbCells( 1 ) );
241  CAPTURE( complex.nbCells( 2 ) );
242  CAPTURE( complex.nbCells( 3 ) );
243 
244  THEN( "It keeps its topology so its euler characteristic is 1" ) {
245  REQUIRE( complex.euler() == 1 );
246  } AND_THEN( "It has no more 2-cells and 3-cells" ) {
247  REQUIRE( complex.nbCells( 2 ) == 0 );
248  REQUIRE( complex.nbCells( 3 ) == 0 );
249  } AND_THEN( "It has only 0-cells and 1-cells" ) {
250  REQUIRE( complex.nbCells( 0 ) > 0 );
251  REQUIRE( complex.nbCells( 1 ) > 0 );
252  }
253  }
254  }
255 }
256 
257 SCENARIO( "CubicalComplex< K3,std::unordered_map<> > link tests", "[cubical_complex][link]" )
258 {
259  typedef KhalimskySpaceND<3> KSpace;
260  typedef KSpace::Point Point;
261  typedef KSpace::Cell Cell;
262  typedef KSpace::Integer Integer;
263  typedef std::unordered_map<Cell, CubicalCellData> Map;
265 
266  srand( 0 );
267  KSpace K;
268  K.init( Point( 0,0,0 ), Point( 512,512,512 ), true );
269 
270  GIVEN( "A closed cubical complex made of 10x10x10 voxels with their incident cells" ) {
271  CC X( K );
272  CC S( K );
273  for ( Integer x = 0; x < 10; ++x )
274  for ( Integer y = 0; y < 10; ++y )
275  for ( Integer z = 0; z < 10; ++z )
276  {
277  Cell c = K.uSpel( Point( x, y, z ) );
278  if ( x*y*z != 0 )
279  S.insert( K.uPointel( Point( x, y, z ) ) );
280  X.insertCell( c );
281  }
282  X.close();
283  THEN( "It has Euler characteristic 1" ) {
284  REQUIRE( X.euler() == 1 );
285  }
286 
287  WHEN( "Computing the link of its inner pointels without hint" ) {
288  CC link_S_v1 = X.link( S );
289 
290  THEN( "This link is homeomorphic to a sphere and has euler characteristic 2" ) {
291  REQUIRE( link_S_v1.euler() == 2 );
292  }
293  }
294 
295  WHEN( "Computing the link of its inner pointels with full hints" ) {
296  CC link_S_v2 = X.link( S, true, true );
297 
298  THEN( "This link is again homeomorphic to a sphere and has euler characteristic 2" ) {
299  REQUIRE( link_S_v2.euler() == 2 );
300  }
301  }
302  }
303 }
304 
305 
308 // STD::MAP
311 
312 SCENARIO( "CubicalComplex< K3,std::map<> > unit tests (incidence,...)", "[cubical_complex][incidence]" )
313 {
314  typedef KhalimskySpaceND<3> KSpace;
315  typedef KSpace::Point Point;
316  typedef KSpace::Cell Cell;
317  typedef std::map<Cell, CubicalCellData> Map;
320 
321  srand( 0 );
322  KSpace K;
323  K.init( Point( 0,0,0 ), Point( 512,512,512 ), true );
324  std::vector<int> nbCoFaces( 4, 0 );
325  std::vector<int> nbFaces( 6, 0 );
326  std::vector<int> nbFaces2( 6, 0 );
327  std::vector<int> nbBdry( 10, 0 );
328  std::vector<int> nbBdry2( 10, 0 );
329 
330  GIVEN( "A cubical complex with random 3-cells" ) {
331  CC complex( K );
332  for ( int n = 0; n < NBCELLS; ++n )
333  {
334  Point p( (rand() % 512) | 0x1, (rand() % 512) | 0x1, (rand() % 512) | 0x1 );
335  Cell cell = K.uCell( p );
336  complex.insertCell( cell );
337  }
338  THEN( "It has only 3-cells and no other type of cells" ) {
339  REQUIRE( complex.nbCells( 0 ) == 0 );
340  REQUIRE( complex.nbCells( 1 ) == 0 );
341  REQUIRE( complex.nbCells( 2 ) == 0 );
342  REQUIRE( complex.nbCells( 3 ) > 0 );
343  }
344 
345  WHEN( "Computing proper faces of these 3-cells" ) {
346  std::vector<Cell> faces;
347  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
348  for ( CellMapConstIterator it = complex.begin( 3 ), itE = complex.end( 3 );
349  it != itE; ++it )
350  complex.faces( outIt, it->first );
351  THEN( "There are no proper faces within this complex" ) {
352  REQUIRE( faces.size() == 0 );
353  }
354  }
355 
356  WHEN( "Closing the cubical complex" ) {
357  complex.close();
358  THEN( "It has cells of all dimensions." ) {
359  REQUIRE( complex.nbCells( 0 ) > 0 );
360  REQUIRE( complex.nbCells( 1 ) > 0 );
361  REQUIRE( complex.nbCells( 2 ) > 0 );
362  }
363 
364  WHEN( "Computing the direct co-faces of 2-cells" ) {
365  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
366  it != itE; ++it )
367  {
368  std::vector<Cell> faces;
369  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
370  complex.directCoFaces( outIt, it->first );
371  int n = faces.size();
372  if ( n >= 3 ) n = 3; // should not happen
373  nbCoFaces[ n ]++;
374  }
375  THEN( "None of them are incident to zero 3-cells" ) {
376  REQUIRE( nbCoFaces[ 0 ] == 0 );
377  } AND_THEN ( "Most of them are incident to one 3-cells and some of them to two 3-cells" ) {
378  REQUIRE( nbCoFaces[ 1 ] > 10*nbCoFaces[ 2 ] );
379  } AND_THEN ("None of them are incident to three or more 3-cells" ) {
380  REQUIRE( nbCoFaces[ 3 ] == 0 );
381  }
382  }
383 
384  WHEN( "Computing direct faces of 2-cells" ) {
385  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
386  it != itE; ++it )
387  {
388  std::vector<Cell> faces;
389  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
390  complex.directFaces( outIt, it->first, true );
391  int n = faces.size();
392  if ( n < 4 ) n = 3; // should not happen
393  if ( n > 4 ) n = 5; // should not happen
394  nbFaces[ n ]++;
395  }
396  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
397  it != itE; ++it )
398  {
399  std::vector<Cell> faces;
400  std::back_insert_iterator< std::vector<Cell> > outIt( faces );
401  complex.directFaces( outIt, it->first );
402  int n = faces.size();
403  if ( n < 4 ) n = 3; // should not happen
404  if ( n > 4 ) n = 5; // should not happen
405  nbFaces2[ n ]++;
406  }
407  THEN( "All of them have exactly 4 incident 1-cells when computed with hint closed" ) {
408  REQUIRE( nbFaces[ 3 ] == 0 );
409  REQUIRE( nbFaces[ 4 ] > 0 );
410  REQUIRE( nbFaces[ 5 ] == 0 );
411  } AND_THEN( "All of them have exactly 4 incident 1-cells when computed without hint" ) {
412  REQUIRE( nbFaces2[ 3 ] == 0 );
413  REQUIRE( nbFaces2[ 4 ] > 0 );
414  REQUIRE( nbFaces2[ 5 ] == 0 );
415  } AND_THEN( "It gives the same number of incident cells with or without hint" ) {
416  REQUIRE( nbFaces[ 4 ] == nbFaces2[ 4 ] );
417  }
418  }
419 
420  WHEN( "Computing boundaries of 2-cells" ) {
421  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
422  it != itE; ++it )
423  {
424  CC::Cells faces = complex.cellBoundary( it->first, true );
425  int n = faces.size();
426  if ( n < 8 ) n = 7; // should not happen
427  if ( n > 8 ) n = 9; // should not happen
428  nbBdry[ n ]++;
429  }
430  for ( CellMapConstIterator it = complex.begin( 2 ), itE = complex.end( 2 );
431  it != itE; ++it )
432  {
433  CC::Cells faces = complex.cellBoundary( it->first, false );
434  int n = faces.size();
435  if ( n < 8 ) n = 7; // should not happen
436  if ( n > 8 ) n = 9; // should not happen
437  nbBdry2[ n ]++;
438  }
439  THEN( "All of them contain exactly 8 cells when computed with hint closed" ) {
440  REQUIRE( nbBdry[ 7 ] == 0 );
441  REQUIRE( nbBdry[ 8 ] > 0 );
442  REQUIRE( nbBdry[ 9 ] == 0 );
443  } AND_THEN( "All of them contain exactly 8 cells when computed without hint" ) {
444  REQUIRE( nbBdry2[ 7 ] == 0 );
445  REQUIRE( nbBdry2[ 8 ] > 0 );
446  REQUIRE( nbBdry2[ 9 ] == 0 );
447  } AND_THEN( "It gives the same number of incident cells with or without hint" ) {
448  REQUIRE( nbBdry[ 8 ] == nbBdry2[ 8 ] );
449  }
450  }
451  } // WHEN( "Closing the cubical complex" ) {
452  }
453 }
454 
455 SCENARIO( "CubicalComplex< K3,std::map<> > collapse tests", "[cubical_complex][collapse]" )
456 {
457  typedef KhalimskySpaceND<3> KSpace;
458  typedef KSpace::Point Point;
459  typedef KSpace::Cell Cell;
460  typedef KSpace::Integer Integer;
461  typedef std::map<Cell, CubicalCellData> Map;
463  typedef CC::CellMapIterator CellMapIterator;
464 
465  srand( 0 );
466  KSpace K;
467  K.init( Point( 0,0,0 ), Point( 512,512,512 ), true );
468 
469  GIVEN( "A closed cubical complex made of 3x3x3 voxels with their incident cells" ) {
470  CC complex( K );
471  std::vector<Cell> S;
472  for ( Integer x = 0; x < 3; ++x )
473  for ( Integer y = 0; y < 3; ++y )
474  for ( Integer z = 0; z < 3; ++z )
475  {
476  S.push_back( K.uSpel( Point( x, y, z ) ) );
477  complex.insertCell( S.back() );
478  }
479  complex.close();
480  CAPTURE( complex.nbCells( 0 ) );
481  CAPTURE( complex.nbCells( 1 ) );
482  CAPTURE( complex.nbCells( 2 ) );
483  CAPTURE( complex.nbCells( 3 ) );
484 
485  THEN( "It has Euler characteristic 1" ) {
486  REQUIRE( complex.euler() == 1 );
487  }
488 
489  WHEN( "Fixing two vertices of this big cube and collapsing it" ) {
490  CellMapIterator it1 = complex.findCell( 0, K.uCell( Point( 0, 0, 0 ) ) );
491  CellMapIterator it2 = complex.findCell( 0, K.uCell( Point( 4, 4, 4 ) ) );
492  REQUIRE( it1 != complex.end( 0 ) );
493  REQUIRE( it2 != complex.end( 0 ) );
494  it1->second.data |= CC::FIXED;
495  it2->second.data |= CC::FIXED;
497  functions::collapse( complex, S.begin(), S.end(), P, false, true );
498  CAPTURE( complex.nbCells( 0 ) );
499  CAPTURE( complex.nbCells( 1 ) );
500  CAPTURE( complex.nbCells( 2 ) );
501  CAPTURE( complex.nbCells( 3 ) );
502 
503  THEN( "It keeps its topology so its euler characteristic is 1" ) {
504  REQUIRE( complex.euler() == 1 );
505  } AND_THEN( "It has no more 2-cells and 3-cells" ) {
506  REQUIRE( complex.nbCells( 2 ) == 0 );
507  REQUIRE( complex.nbCells( 3 ) == 0 );
508  } AND_THEN( "It has only 0-cells and 1-cells" ) {
509  REQUIRE( complex.nbCells( 0 ) > 0 );
510  REQUIRE( complex.nbCells( 1 ) > 0 );
511  }
512  }
513  }
514 }
515 
516 SCENARIO( "CubicalComplex< K3,std::map<> > link tests", "[cubical_complex][link]" )
517 {
518  typedef KhalimskySpaceND<3> KSpace;
519  typedef KSpace::Point Point;
520  typedef KSpace::Cell Cell;
521  typedef KSpace::Integer Integer;
522  typedef std::map<Cell, CubicalCellData> Map;
524 
525  srand( 0 );
526  KSpace K;
527  K.init( Point( 0,0,0 ), Point( 512,512,512 ), true );
528 
529  GIVEN( "A closed cubical complex made of 10x10x10 voxels with their incident cells" ) {
530  CC X( K );
531  CC S( K );
532  for ( Integer x = 0; x < 10; ++x )
533  for ( Integer y = 0; y < 10; ++y )
534  for ( Integer z = 0; z < 10; ++z )
535  {
536  Cell c = K.uSpel( Point( x, y, z ) );
537  if ( x*y*z != 0 )
538  S.insert( K.uPointel( Point( x, y, z ) ) );
539  X.insertCell( c );
540  }
541  X.close();
542  THEN( "It has Euler characteristic 1" ) {
543  REQUIRE( X.euler() == 1 );
544  }
545 
546  WHEN( "Computing the link of its inner pointels without hint" ) {
547  CC link_S_v1 = X.link( S );
548 
549  THEN( "This link is homeomorphic to a sphere and has euler characteristic 2" ) {
550  REQUIRE( link_S_v1.euler() == 2 );
551  }
552  }
553 
554  WHEN( "Computing the link of its inner pointels with full hints" ) {
555  CC link_S_v2 = X.link( S, true, true );
556 
557  THEN( "This link is again homeomorphic to a sphere and has euler characteristic 2" ) {
558  REQUIRE( link_S_v2.euler() == 2 );
559  }
560  }
561  }
562 }
563 
564 SCENARIO( "CubicalComplex< K3,std::map<> > concept check tests", "[cubical_complex][concepts]" )
565 {
566  typedef KhalimskySpaceND<3> KSpace;
567  typedef KSpace::Cell Cell;
568  typedef std::map<Cell, CubicalCellData> Map;
570 
571  BOOST_CONCEPT_ASSERT(( boost::Container<CC> ));
572  BOOST_CONCEPT_ASSERT(( boost::ForwardIterator<CC::Iterator> ));
573  BOOST_CONCEPT_ASSERT(( boost::ForwardIterator<CC::ConstIterator> ));
574 }
575 
576 
577 SCENARIO( "CubicalComplex< K2,std::map<> > set operations and relations", "[cubical_complex][ccops]" )
578 {
579  typedef KhalimskySpaceND<2> KSpace;
580  typedef KSpace::Space Space;
582  typedef KSpace::Point Point;
583  typedef KSpace::Cell Cell;
584  typedef std::map<Cell, CubicalCellData> Map;
586 
587  using namespace DGtal::functions;
588 
589  KSpace K;
590  K.init( Point( 0,0 ), Point( 5,3 ), true );
591  Domain domain( Point( 0,0 ), Point( 5,3 ) );
592  CC X1( K );
593  X1.insertCell( K.uSpel( Point(1,1) ) );
594  X1.insertCell( K.uSpel( Point(2,1) ) );
595  X1.insertCell( K.uSpel( Point(3,1) ) );
596  X1.insertCell( K.uSpel( Point(2,2) ) );
597  CC X1c = ~ X1;
598 
599  CC X2( K );
600  X2.insertCell( K.uSpel( Point(2,2) ) );
601  X2.insertCell( K.uSpel( Point(3,2) ) );
602  X2.insertCell( K.uSpel( Point(4,2) ) );
603  X2.close();
604  CC X2c = ~ X2;
605  REQUIRE( ( X1 & X2 ).size() < X1.size() );
606  bool X1_and_X2_included_in_X1 = ( X1 & X2 ) <= X1;
607  bool X1c_and_X2c_included_in_X1c = ( X1c & X2c ) <= X1c;
608  CC A = ~( X1 & X2 );
609  CC B = ~( *(X1c & X2c) );
610  CAPTURE( A );
611  CAPTURE( B );
612  bool cl_X1_and_X2_equal_to_X1c_and_X2c = A == B;
613 
614  REQUIRE( X1_and_X2_included_in_X1 );
615  REQUIRE( X1c_and_X2c_included_in_X1c );
616  REQUIRE( cl_X1_and_X2_equal_to_X1c_and_X2c );
617 
618  CC X1bd = X1c - *X1c;
619  CAPTURE( X1bd );
620  CAPTURE( X1.boundary() );
621  bool X1bd_equal_X1boundary = X1bd == X1.boundary();
622  REQUIRE( X1bd_equal_X1boundary );
623 }
624 // //
Integer euler() const
CellMap::iterator CellMapIterator
Iterator for visiting type CellMap.
CAPTURE(thicknessHV)
std::unordered_map< Cell, CubicalCellData > Map
HyperRectDomain< Space > Domain
ConstIterator begin() const
const Domain domain(Point(1, 2), Point(6, 5))
srand(0)
Cells cellBoundary(const Cell &aCell, bool hintClosed=false) const
void faces(CellOutputIterator &outIt, const Cell &aCell, bool hintClosed=false) const
STL namespace.
std::vector< int > nbBdry(10, 0)
std::pair< Iterator, bool > insert(const Cell &aCell)
CellMap::const_iterator CellMapConstIterator
Const iterator for visiting type CellMap.
static const int NBCELLS
CubicalComplex link(const CubicalComplex &S, bool hintClosed=false, bool hintOpen=false) const
void insertCell(const Cell &aCell, const Data &data=Data())
std::vector< int > nbFaces2(6, 0)
REQUIRE(domain.isInside(aPoint))
SCENARIO("CubicalComplex< K3,std::unordered_map<> > collapse tests", "[cubical_complex][collapse]")
CC::CellMapConstIterator CellMapConstIterator
Go to http://www.sgi.com/tech/stl/ForwardIterator.html.
Definition: Boost.dox:40
Aim: This class represents an arbitrary cubical complex living in some Khalimsky space. Cubical complexes are sets of cells of different dimensions related together with incidence relations. Two cells in a cubical complex are incident if and only if they are incident in the surrounding Khalimsky space. In other words, cubical complexes are defined here as subsets of Khalimsky spaces.
void directCoFaces(CellOutputIterator &outIt, const Cell &aCell, bool hintOpen=false) const
DGtal is the top-level namespace which contains all DGtal functions and types.
CubicalComplex boundary(bool hintClosed=false) const
CubicalComplex< KSpace, Map > CC
ConstIterator end() const
Size nbCells(Dimension d) const
KSpace::Cells Cells
Type for a sequence of cells in the space.
CellMapConstIterator findCell(const Cell &aCell) const
functions namespace gathers all DGtal functionsxs.
Definition: SetFunctions.h:768
GIVEN("A cubical complex with random 3-cells")
KSpace::Point Point
KSpace K
void directFaces(CellOutputIterator &outIt, const Cell &aCell, bool hintClosed=false) const
KSpace::Cell Cell
std::vector< int > nbFaces(6, 0)
std::vector< int > nbCoFaces(4, 0)
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex...
std::vector< int > nbBdry2(10, 0)
Go to http://www.sgi.com/tech/stl/Container.html.
Definition: Boost.dox:104