33#include "DGtalCatch.h"
34#include "DGtal/helpers/StdDefs.h"
35#include "DGtal/shapes/Shapes.h"
36#include "DGtal/base/Common.h"
37#include "DGtal/topology/NeighborhoodConfigurations.h"
38#include "DGtal/topology/tables/NeighborhoodTables.h"
43template <
typename TObject>
45Object3D(
const typename TObject::DigitalTopology &dt)
47 using namespace DGtal;
49 Point p1( -10, -10, -10 );
50 Point p2( 10, 10, 10 );
57 if ( (*it - c ).norm1() <= 3 ) diamond_set.
insertNew( *it );
59 diamond_set.
erase( c );
64 return TObject(dt, diamond_set);
67TEST_CASE(
"Check that each neighborhood point in 3D (26 points) has associated a bit in an unsigned integer (NeighborhoodConfiguration).",
"[map][mask][3D]" )
70 using Map = unordered_map<Point, NeighborhoodConfiguration>;
72 mapZeroPointNeighborhoodToConfigurationMask< typename Object26_6::Point >();
74 truth3D[
Point{ -1, -1, -1 }] = 1;
75 truth3D[
Point{ 0, -1, -1 }] = 2;
76 truth3D[
Point{ 1, -1, -1 }] = 4;
77 truth3D[
Point{ -1, 0, -1 }] = 8;
78 truth3D[
Point{ 0, 0, -1 }] = 16;
79 truth3D[
Point{ 1, 0, -1 }] = 32;
80 truth3D[
Point{ -1, 1, -1 }] = 64;
81 truth3D[
Point{ 0, 1, -1 }] = 128;
82 truth3D[
Point{ 1, 1, -1 }] = 256;
83 truth3D[
Point{ -1, -1, 0 }] = 512;
84 truth3D[
Point{ 0, -1, 0 }] = 1024;
85 truth3D[
Point{ 1, -1, 0 }] = 2048;
86 truth3D[
Point{ -1, 0, 0 }] = 4096;
87 truth3D[
Point{ 1, 0, 0 }] = 8192;
88 truth3D[
Point{ -1, 1, 0 }] = 16384;
89 truth3D[
Point{ 0, 1, 0 }] = 32768;
90 truth3D[
Point{ 1, 1, 0 }] = 65536;
91 truth3D[
Point{ -1, -1, 1 }] = 131072;
92 truth3D[
Point{ 0, -1, 1 }] = 262144;
93 truth3D[
Point{ 1, -1, 1 }] = 524288;
94 truth3D[
Point{ -1, 0, 1 }] = 1048576;
95 truth3D[
Point{ 0, 0, 1 }] = 2097152;
96 truth3D[
Point{ 1, 0, 1 }] = 4194304;
97 truth3D[
Point{ -1, 1, 1 }] = 8388608;
98 truth3D[
Point{ 0, 1, 1 }] = 16777216;
99 truth3D[
Point{ 1, 1, 1 }] = 33554432;
100 CHECK(*pointToMask3D == truth3D);
103SCENARIO(
"Simplicity tables match on-the-fly calculations for all 3D topologies",
"[simple][object][diamond][3D]" )
105 auto mapZeroNeighborhoodToMask = mapZeroPointNeighborhoodToConfigurationMask<Z3i::Point>();
108 SECTION(
"26_6 topology using loadTable from string and default table size (2^26)"){
109 auto obj = Object3D<Object26_6>(dt26_6);
110 const auto & filename = simplicity::tableSimple26_6;
112 CHECK(ptable->size() == 67108864);
113 const auto & table = *ptable;
114 auto & objSet = obj.pointSet();
116 size_t nsimples_tables{0};
117 for(
const auto & p : objSet){
118 auto simple = obj.isSimple(p);
119 if( simple ) ++nsimples;
120 auto cfg = obj.getNeighborhoodConfigurationOccupancy(p, *mapZeroNeighborhoodToMask);
121 auto simple_from_table = table[cfg];
122 if( simple_from_table ) ++nsimples_tables;
123 INFO(
"Point: " << p <<
" cfg: " << cfg);
124 CHECK(simple == simple_from_table);
126 CHECK(nsimples == nsimples_tables);
127 auto border_size = obj.border().size();
128 CHECK(nsimples == border_size);
130 SECTION(
"18_6 topology using load table with explicit size (2^26)"){
131 auto obj = Object3D<Object18_6>(dt18_6);
132 const auto & filename = simplicity::tableSimple18_6;
134 auto ptable =
loadTable(filename, 67108864);
135 const auto & table = *ptable;
136 auto & objSet = obj.pointSet();
138 size_t nsimples_tables{0};
139 for(
const auto & p : objSet){
140 auto simple = obj.isSimple(p);
141 if( simple ) ++nsimples;
142 auto cfg = obj.getNeighborhoodConfigurationOccupancy(p, *mapZeroNeighborhoodToMask);
143 auto simple_from_table = table[cfg];
144 if( simple_from_table ) ++nsimples_tables;
145 INFO(
"Point: " << p <<
" cfg: " << cfg);
146 CHECK(simple == simple_from_table);
148 CHECK(nsimples == nsimples_tables);
149 auto border_size = obj.border().size();
150 CHECK(nsimples == border_size);
153 SECTION(
"6_26 topology using loadTable with template parameter N=3 (dimension)"){
154 auto obj = Object3D<Object6_26>(dt6_26);
155 const auto & filename = simplicity::tableSimple6_26;
156 auto ptable = loadTable<3>(filename);
157 const auto & table = *ptable;
158 auto & objSet = obj.pointSet();
160 size_t nsimples_tables{0};
161 for(
const auto & p : objSet){
162 auto simple = obj.isSimple(p);
163 if( simple ) ++nsimples;
164 auto cfg = obj.getNeighborhoodConfigurationOccupancy(p, *mapZeroNeighborhoodToMask);
165 auto simple_from_table = table[cfg];
166 if( simple_from_table ) ++nsimples_tables;
167 INFO(
"Point: " << p <<
" cfg: " << cfg);
168 CHECK(simple == simple_from_table);
170 CHECK(nsimples == nsimples_tables);
172 auto border_size = obj.border().size();
173 CHECK(nsimples != border_size);
177 auto obj = Object3D<Object6_18>(dt6_18);
178 const auto & filename = simplicity::tableSimple6_18;
180 const auto & table = *ptable;
181 auto & objSet = obj.pointSet();
183 size_t nsimples_tables{0};
184 for(
const auto & p : objSet){
185 auto simple = obj.isSimple(p);
186 if( simple ) ++nsimples;
187 auto cfg = obj.getNeighborhoodConfigurationOccupancy(p, *mapZeroNeighborhoodToMask);
188 auto simple_from_table = table[cfg];
189 if( simple_from_table ) ++nsimples_tables;
190 INFO(
"Point: " << p <<
" cfg: " << cfg);
191 CHECK(simple == simple_from_table);
193 CHECK(nsimples == nsimples_tables);
195 auto border_size = obj.border().size();
196 CHECK(nsimples != border_size);
209 using namespace DGtal;
211 Point p1( -17, -17 );
224 shape_set.erase(
Point( 5, 0 ) );
225 shape_set.erase(
Point( -1, -2 ) );
232TEST_CASE(
"Check that each neighborhood point in 2D (8 points) has associated a bit in an unsigned integer (NeighborhoodConfiguration).",
"[map][mask][2D]" )
235 using Map = unordered_map<Point, NeighborhoodConfiguration>;
237 mapZeroPointNeighborhoodToConfigurationMask< typename Object8_4::Point >();
239 truth2D[
Point{ -1, -1 }] = 1;
240 truth2D[
Point{ 0, -1 }] = 2;
241 truth2D[
Point{ 1, -1 }] = 4;
242 truth2D[
Point{ -1, 0 }] = 8;
243 truth2D[
Point{ 1, 0 }] = 16;
244 truth2D[
Point{ -1, 1 }] = 32;
245 truth2D[
Point{ 0, 1 }] = 64;
246 truth2D[
Point{ 1, 1 }] = 128;
248 CHECK(*pointToMask2D == truth2D);
251TEST_CASE_METHOD(Objects2D,
"Simplicity tables match on-the-fly calculations for all 2D topologies",
"[simple][object][balls][2D]" )
253 auto mapZeroNeighborhoodToMask = mapZeroPointNeighborhoodToConfigurationMask<Z2i::Point>();
255 SECTION(
"8_4 and 4_8 topologies using loadTable with specific table size (2^8) and with template parameter N=2 (dimension)"){
258 const auto & filename = simplicity::tableSimple8_4;
260 const auto & table = *ptable;
262 auto & objSet = obj.pointSet();
264 size_t nsimples_tables{0};
265 for(
const auto & p : objSet){
266 auto simple = obj.isSimple(p);
267 if( simple ) ++nsimples;
268 auto cfg = obj.getNeighborhoodConfigurationOccupancy(p, *mapZeroNeighborhoodToMask);
269 auto simple_from_table = table[cfg];
270 if( simple_from_table ) ++nsimples_tables;
271 INFO(
"Point: " << p <<
" cfg: " << cfg);
272 CHECK(simple == simple_from_table);
274 CHECK(nsimples == nsimples_tables);
279 const auto & filename = simplicity::tableSimple4_8;
280 auto ptable = loadTable<2>(filename);
281 CHECK(ptable->size() == 256);
282 const auto & table = *ptable;
284 auto & objSet = obj.pointSet();
286 size_t nsimples_tables{0};
287 for(
const auto & p : objSet){
288 auto simple = obj.isSimple(p);
289 if( simple ) ++nsimples;
290 auto cfg = obj.getNeighborhoodConfigurationOccupancy(p, *mapZeroNeighborhoodToMask);
291 auto simple_from_table = table[cfg];
292 if( simple_from_table ) ++nsimples_tables;
293 INFO(
"Point: " << p <<
" cfg: " << cfg);
294 CHECK(simple == simple_from_table);
296 CHECK(nsimples == nsimples_tables);
303 const auto & filename = isthmusicity::tableIsthmus;
305 const auto & table = *ptable;
306 boost::ignore_unused_variable_warning(table);
309 const auto & filename = isthmusicity::tableOneIsthmus;
311 const auto & table = *ptable;
312 boost::ignore_unused_variable_warning(table);
315 const auto & filename = isthmusicity::tableTwoIsthmus;
317 const auto & table = *ptable;
318 boost::ignore_unused_variable_warning(table);
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
void insertNew(const Point &p)
Size erase(const Point &p)
const ConstIterator & begin() const
const Point & lowerBound() const
const Point & upperBound() const
const ConstIterator & end() 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.
static void addNorm1Ball(TDigitalSet &aSet, const Point &aCenter, UnsignedInteger aRadius)
Object< DT8_4, DigitalSet > Object8_4
Object< DT4_8, DigitalSet > Object4_8
functions namespace gathers all DGtal functionsxs.
DGtal::CountedPtr< boost::dynamic_bitset<> > loadTable(const std::string &input_filename, const unsigned int known_size, const bool compressed=true)
DGtal is the top-level namespace which contains all DGtal functions and types.
std::unordered_map< Cell, CubicalCellData > Map
TEST_CASE("Check that each neighborhood point in 3D (26 points) has associated a bit in an unsigned integer (NeighborhoodConfiguration).", "[map][mask][3D]")
TEST_CASE_METHOD(Objects2D, "Simplicity tables match on-the-fly calculations for all 2D topologies", "[simple][object][balls][2D]")
TObject Object3D(const typename TObject::DigitalTopology &dt)
SECTION("Testing constant forward iterators")
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")