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"
52SCENARIO(
"CubicalComplex< K3,std::unordered_map<> > unit tests (incidence,...)",
"[cubical_complex][incidence]" )
57 typedef std::unordered_map<Cell, CubicalCellData>
Map;
70 GIVEN(
"A cubical complex with random 3-cells" ) {
72 for (
int n = 0; n <
NBCELLS; ++n )
74 Point p( (rand() % 512) | 0x1, (rand() % 512) | 0x1, (rand() % 512) | 0x1 );
76 complex.insertCell( cell );
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 );
85 WHEN(
"Computing proper faces of these 3-cells" ) {
86 std::vector<Cell> faces;
87 std::back_insert_iterator< std::vector<Cell> > outIt( faces );
90 complex.faces( outIt, it->first );
91 THEN(
"There are no proper faces within this complex" ) {
96 WHEN(
"Closing the cubical complex" ) {
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 );
104 WHEN(
"Computing the direct co-faces of 2-cells" ) {
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());
115 THEN(
"None of them are incident to zero 3-cells" ) {
117 } AND_THEN (
"Most of them are incident to one 3-cells and some of them to two 3-cells" ) {
119 } AND_THEN (
"None of them are incident to three or more 3-cells" ) {
124 WHEN(
"Computing direct faces of 2-cells" ) {
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();
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();
147 THEN(
"All of them have exactly 4 incident 1-cells when computed with hint closed" ) {
151 } AND_THEN(
"All of them have exactly 4 incident 1-cells when computed without hint" ) {
155 } AND_THEN(
"It gives the same number of incident cells with or without hint" ) {
160 WHEN(
"Computing boundaries of 2-cells" ) {
164 CC::Cells faces = complex.cellBoundary( it->first,
true );
165 size_t n = faces.size();
173 CC::Cells faces = complex.cellBoundary( it->first,
false );
174 size_t n = faces.size();
179 THEN(
"All of them contain exactly 8 cells when computed with hint closed" ) {
183 } AND_THEN(
"All of them contain exactly 8 cells when computed without hint" ) {
187 } AND_THEN(
"It gives the same number of incident cells with or without hint" ) {
195SCENARIO(
"CubicalComplex< K3,std::unordered_map<> > collapse tests",
"[cubical_complex][collapse]" )
201 typedef std::unordered_map<Cell, CubicalCellData>
Map;
209 GIVEN(
"A closed cubical complex made of 3x3x3 voxels with their incident cells" ) {
212 for (
Integer x = 0; x < 3; ++x )
213 for (
Integer y = 0; y < 3; ++y )
214 for (
Integer z = 0; z < 3; ++z )
217 complex.insertCell( S.back() );
220 CAPTURE( complex.nbCells( 0 ) );
221 CAPTURE( complex.nbCells( 1 ) );
222 CAPTURE( complex.nbCells( 2 ) );
223 CAPTURE( complex.nbCells( 3 ) );
225 THEN(
"It has Euler characteristic 1" ) {
226 REQUIRE( complex.euler() == 1 );
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;
238 CAPTURE( complex.nbCells( 0 ) );
239 CAPTURE( complex.nbCells( 1 ) );
240 CAPTURE( complex.nbCells( 2 ) );
241 CAPTURE( complex.nbCells( 3 ) );
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 );
256SCENARIO(
"CubicalComplex< K3,std::unordered_map<> > link tests",
"[cubical_complex][link]" )
262 typedef std::unordered_map<Cell, CubicalCellData>
Map;
269 GIVEN(
"A closed cubical complex made of 10x10x10 voxels with their incident cells" ) {
272 for (
Integer x = 0; x < 10; ++x )
273 for (
Integer y = 0; y < 10; ++y )
274 for (
Integer z = 0; z < 10; ++z )
282 THEN(
"It has Euler characteristic 1" ) {
286 WHEN(
"Computing the link of its inner pointels without hint" ) {
287 CC link_S_v1 = X.
link( S );
289 THEN(
"This link is homeomorphic to a sphere and has euler characteristic 2" ) {
294 WHEN(
"Computing the link of its inner pointels with full hints" ) {
295 CC link_S_v2 = X.
link( S,
true,
true );
297 THEN(
"This link is again homeomorphic to a sphere and has euler characteristic 2" ) {
311SCENARIO(
"CubicalComplex< K3,std::map<> > unit tests (incidence,...)",
"[cubical_complex][incidence]" )
316 typedef std::map<Cell, CubicalCellData>
Map;
324 std::vector<int>
nbFaces( 6, 0 );
326 std::vector<int>
nbBdry( 10, 0 );
327 std::vector<int>
nbBdry2( 10, 0 );
329 GIVEN(
"A cubical complex with random 3-cells" ) {
331 for (
int n = 0; n <
NBCELLS; ++n )
333 Point p( (rand() % 512) | 0x1, (rand() % 512) | 0x1, (rand() % 512) | 0x1 );
335 complex.insertCell( cell );
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 );
344 WHEN(
"Computing proper faces of these 3-cells" ) {
345 std::vector<Cell> faces;
346 std::back_insert_iterator< std::vector<Cell> > outIt( faces );
349 complex.faces( outIt, it->first );
350 THEN(
"There are no proper faces within this complex" ) {
355 WHEN(
"Closing the cubical complex" ) {
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 );
363 WHEN(
"Computing the direct co-faces of 2-cells" ) {
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();
374 THEN(
"None of them are incident to zero 3-cells" ) {
376 } AND_THEN (
"Most of them are incident to one 3-cells and some of them to two 3-cells" ) {
378 } AND_THEN (
"None of them are incident to three or more 3-cells" ) {
383 WHEN(
"Computing direct faces of 2-cells" ) {
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();
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();
406 THEN(
"All of them have exactly 4 incident 1-cells when computed with hint closed" ) {
410 } AND_THEN(
"All of them have exactly 4 incident 1-cells when computed without hint" ) {
414 } AND_THEN(
"It gives the same number of incident cells with or without hint" ) {
419 WHEN(
"Computing boundaries of 2-cells" ) {
423 CC::Cells faces = complex.cellBoundary( it->first,
true );
424 auto n = faces.size();
432 CC::Cells faces = complex.cellBoundary( it->first,
false );
433 auto n = faces.size();
438 THEN(
"All of them contain exactly 8 cells when computed with hint closed" ) {
442 } AND_THEN(
"All of them contain exactly 8 cells when computed without hint" ) {
446 } AND_THEN(
"It gives the same number of incident cells with or without hint" ) {
454SCENARIO(
"CubicalComplex< K3,std::map<> > collapse tests",
"[cubical_complex][collapse]" )
460 typedef std::map<Cell, CubicalCellData>
Map;
468 GIVEN(
"A closed cubical complex made of 3x3x3 voxels with their incident cells" ) {
471 for (
Integer x = 0; x < 3; ++x )
472 for (
Integer y = 0; y < 3; ++y )
473 for (
Integer z = 0; z < 3; ++z )
476 complex.insertCell( S.back() );
479 CAPTURE( complex.nbCells( 0 ) );
480 CAPTURE( complex.nbCells( 1 ) );
481 CAPTURE( complex.nbCells( 2 ) );
482 CAPTURE( complex.nbCells( 3 ) );
484 THEN(
"It has Euler characteristic 1" ) {
485 REQUIRE( complex.euler() == 1 );
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;
497 CAPTURE( complex.nbCells( 0 ) );
498 CAPTURE( complex.nbCells( 1 ) );
499 CAPTURE( complex.nbCells( 2 ) );
500 CAPTURE( complex.nbCells( 3 ) );
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 );
515SCENARIO(
"CubicalComplex< K3,std::map<> > link tests",
"[cubical_complex][link]" )
521 typedef std::map<Cell, CubicalCellData>
Map;
528 GIVEN(
"A closed cubical complex made of 10x10x10 voxels with their incident cells" ) {
531 for (
Integer x = 0; x < 10; ++x )
532 for (
Integer y = 0; y < 10; ++y )
533 for (
Integer z = 0; z < 10; ++z )
541 THEN(
"It has Euler characteristic 1" ) {
545 WHEN(
"Computing the link of its inner pointels without hint" ) {
546 CC link_S_v1 = X.
link( S );
548 THEN(
"This link is homeomorphic to a sphere and has euler characteristic 2" ) {
553 WHEN(
"Computing the link of its inner pointels with full hints" ) {
554 CC link_S_v2 = X.
link( S,
true,
true );
556 THEN(
"This link is again homeomorphic to a sphere and has euler characteristic 2" ) {
563SCENARIO(
"CubicalComplex< K3,std::map<> > concept check tests",
"[cubical_complex][concepts]" )
567 typedef std::map<Cell, CubicalCellData>
Map;
576SCENARIO(
"CubicalComplex< K2,std::map<> > set operations and relations",
"[cubical_complex][ccops]" )
583 typedef std::map<Cell, CubicalCellData>
Map;
603 bool X1_and_X2_included_in_X1 = ( X1 & X2 ) <= X1;
604 bool X1c_and_X2c_included_in_X1c = ( X1c & X2c ) <= X1c;
606 CC B = ~( *(X1c & X2c) );
609 bool cl_X1_and_X2_equal_to_X1c_and_X2c = A == B;
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 );
615 CC X1bd = X1c - *X1c;
618 bool X1bd_equal_X1boundary = X1bd == X1.
boundary();
619 REQUIRE( X1bd_equal_X1boundary );
Aim: This class represents an arbitrary cubical complex living in some Khalimsky space....
CubicalComplex boundary(bool hintClosed=false) const
CubicalComplex link(const CubicalComplex &S, bool hintClosed=false, bool hintOpen=false) 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.
std::pair< Iterator, bool > insert(const Cell &aCell)
CellMap::const_iterator CellMapConstIterator
Const iterator for visiting type CellMap.
Aim: Parallelepidec region of a digital space, model of a 'CDomain'.
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.
Point::Coordinate Integer
uint64_t collapse(CubicalComplex< TKSpace, TCellContainer > &K, CellConstIterator S_itB, CellConstIterator S_itE, const CellMapIteratorPriority &priority, bool hintIsSClosed=false, bool hintIsKClosed=false, bool verbose=false)
DGtal is the top-level namespace which contains all DGtal functions and types.
Go to http://www.sgi.com/tech/stl/Container.html.
Go to http://www.sgi.com/tech/stl/ForwardIterator.html.
std::unordered_map< Cell, CubicalCellData > Map
std::vector< int > nbFaces(6, 0)
std::vector< int > nbBdry2(10, 0)
CubicalComplex< KSpace, Map > CC
std::vector< int > nbCoFaces(4, 0)
GIVEN("A cubical complex with random 3-cells")
std::vector< int > nbBdry(10, 0)
CC::CellMapConstIterator CellMapConstIterator
std::vector< int > nbFaces2(6, 0)
HyperRectDomain< Space > Domain
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")