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