31 #include "DGtal/base/SetFunctions.h" 32 #include "DGtal/helpers/StdDefs.h" 33 #include "DGtal/topology/CubicalComplexFunctions.h" 34 #include "DGtal/topology/CubicalComplex.h" 35 #include "DGtal/topology/KhalimskyCellHashFunctions.h" 36 #include "DGtal/topology/VoxelComplex.h" 37 #include "DGtal/topology/VoxelComplexFunctions.h" 38 #include "DGtalCatch.h" 40 #include <unordered_map> 42 #include "DGtal/geometry/volumes/distance/DistanceTransformation.h" 43 #include "DGtal/geometry/volumes/distance/ExactPredicateLpSeparableMetric.h" 44 #include "DGtal/geometry/volumes/distance/VoronoiMap.h" 45 #include "DGtal/images/SimpleThresholdForegroundPredicate.h" 46 #include "DGtal/kernel/BasicPointPredicates.h" 47 #include "DGtal/topology/NeighborhoodConfigurations.h" 48 #include "DGtal/topology/tables/NeighborhoodTables.h" 53 using namespace DGtal;
58 struct Fixture_complex_diamond {
69 std::unordered_set<typename DGtal::Z3i::Domain::Point>>;
76 Fixture_complex_diamond() :
77 complex_fixture(ks_fixture) {
78 create_complex_from_set(create_set());
83 FixtureComplex complex_fixture;
90 FixtureDigitalSet create_set() {
91 using namespace DGtal;
94 Point p1(-10, -10, -10);
100 FixtureDigitalSet set_fixture(
domain);
102 if ((*it - c).norm1() <= 3)
103 set_fixture.insertNew(*it);
105 set_fixture.erase(c);
110 FixtureComplex &create_complex_from_set(
const FixtureDigitalSet &input_set) {
112 ks_fixture.
init(input_set.domain().lowerBound(),
113 input_set.domain().upperBound(),
true);
114 complex_fixture = FixtureComplex(ks_fixture);
115 complex_fixture.construct(input_set);
116 return complex_fixture;
121 auto &vc = complex_fixture;
122 auto &ks = vc.space();
123 auto s3 = vc.nbCells(3);
124 auto s2 = vc.nbCells(2);
125 auto s1 = vc.nbCells(1);
126 auto s0 = vc.nbCells(0);
127 SECTION(
"insertVoxel in border") {
130 vc_new.insertVoxelPoint(p);
131 auto sa3 = vc_new.nbCells(3);
132 auto sa2 = vc_new.nbCells(2);
133 auto sa1 = vc_new.nbCells(1);
134 auto sa0 = vc_new.nbCells(0);
144 SECTION(
"insertVoxel isolated") {
147 vc_new.insertVoxelCell(ks.uSpel(p));
148 auto sa3 = vc_new.nbCells(3);
149 auto sa2 = vc_new.nbCells(2);
150 auto sa1 = vc_new.nbCells(1);
151 auto sa0 = vc_new.nbCells(0);
161 SECTION(
"insertVoxel interior") {
164 vc_new.insertVoxelCell(ks.uSpel(p));
165 auto sa3 = vc_new.nbCells(3);
166 auto sa2 = vc_new.nbCells(2);
167 auto sa1 = vc_new.nbCells(1);
168 auto sa0 = vc_new.nbCells(0);
181 "[neighborhood][faces]") {
182 auto &vc = complex_fixture;
183 auto &ks = vc.space();
185 bool no_hint =
false;
186 auto not_found = vc.end(3);
188 SECTION(
"Voxel is in the interior of the complex.") {
190 auto cellMapIt = vc.findCell(3, ks.uSpel(p));
191 CHECK(cellMapIt != not_found);
192 auto cell = cellMapIt->first;
193 auto kfaces = ks.uFaces(cell);
196 CHECK(kfaces.size() == 26);
197 auto vcBoundary_closed = vc.cellBoundary(cell, closed);
198 CHECK(vcBoundary_closed.size() == 26);
199 auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
200 CHECK(vcBoundary_no_hint.size() == 26);
202 SECTION(
"Voxel is in the exterior") {
204 auto cellMapIt = vc.findCell(3, ks.uSpel(p));
205 CHECK(cellMapIt == not_found);
206 auto cell = ks.uSpel(p);
207 auto kfaces = ks.uFaces(cell);
210 CHECK(kfaces.size() == 26);
212 auto vcBoundary_closed = vc.cellBoundary(cell, closed);
213 CHECK(vcBoundary_closed.size() == 26);
215 auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
216 CHECK(vcBoundary_no_hint.size() == 0);
218 SECTION(
"Voxel is out, but surrounded by in voxels") {
220 auto cellMapIt = vc.findCell(3, ks.uSpel(p));
221 CHECK(cellMapIt == not_found);
222 auto cell = ks.uSpel(p);
223 auto kfaces = ks.uFaces(cell);
226 CHECK(kfaces.size() == 26);
227 auto vcBoundary_closed = vc.cellBoundary(cell, closed);
228 CHECK(vcBoundary_closed.size() == 26);
229 auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
230 CHECK(vcBoundary_no_hint.size() == 26);
232 SECTION(
"Voxel is in the border") {
234 auto cellMapIt = vc.findCell(3, ks.uSpel(p));
235 CHECK(cellMapIt != not_found);
236 auto cell = cellMapIt->first;
237 auto kfaces = ks.uFaces(cell);
240 CHECK(kfaces.size() == 26);
241 auto vcBoundary_closed = vc.cellBoundary(cell, closed);
242 CHECK(vcBoundary_closed.size() == 26);
243 auto vcBoundary_no_hint = vc.cellBoundary(cell, no_hint);
244 CHECK(vcBoundary_no_hint.size() == 26);
250 auto &vc = complex_fixture;
251 SECTION(
" get neighbors from Kspace") {
253 size_t dim_voxel = 3;
254 auto it = vc.begin(dim_voxel);
255 for (
auto &&n : std::vector<int>(10))
257 auto cell = it->first;
258 auto point_from_kspace_1 = cell.preCell().coordinates;
259 size_t expected_num_adjacent_voxels = 12;
261 SECTION(
"properNeighborhood from KSpace" 262 "does not output all adjacent voxels.") {
264 size_t expected_kspace_neighborhood = 7;
265 auto neigh_k = vc.space().uNeighborhood(cell);
266 CHECK(neigh_k.size() == expected_kspace_neighborhood);
268 auto propN_k = vc.space().uProperNeighborhood(cell);
269 CHECK(propN_k.size() == expected_kspace_neighborhood - 1);
272 SECTION(
"Getting associated pointels and voxels from input_cell") {
273 std::set<FixtureComplex::Cell> pointel_set;
274 vc.pointelsFromCell(pointel_set, cell);
275 std::set<FixtureComplex::Cell> voxel_set;
276 for (
auto &&p : pointel_set)
277 vc.spelsFromCell(voxel_set, p);
278 SECTION(
"Gets desired full adjancency for voxels") {
279 CHECK(voxel_set.size() == expected_num_adjacent_voxels);
281 auto clique = vc.Kneighborhood(cell);
282 CHECK(clique.nbCells(3) == expected_num_adjacent_voxels);
289 auto &vc = complex_fixture;
290 size_t dim_voxel = 3;
291 auto cit = vc.begin(dim_voxel);
292 for (
auto &&n : std::vector<int>(10))
294 auto cell = cit->first;
296 SECTION(
"querying voxel simplicity") {
298 std::vector<FixtureComplex::Cell> non_simple_cells;
299 for (
auto it = vc.begin(dim_voxel); it != vc.end(dim_voxel); ++it) {
300 if (vc.isSimple(it->first))
303 non_simple_cells.emplace_back(it->first);
308 size_t border_size = 44;
309 REQUIRE(nsimples == border_size);
315 auto &vc = complex_fixture;
317 vc.setSimplicityTable(functions::loadTable(simplicity::tableSimple26_6));
320 auto cit = vc.begin(dim_voxel);
321 for (
auto &&n : std::vector<int>(10))
323 auto cell = cit->first;
325 SECTION(
"querying voxel simplicity") {
327 std::vector<FixtureComplex::Cell> non_simple_cells;
328 for (
auto it = vc.begin(dim_voxel); it != vc.end(dim_voxel); ++it) {
329 if (vc.isSimple(it->first))
332 non_simple_cells.emplace_back(it->first);
336 size_t border_size = 44;
337 REQUIRE(nsimples == border_size);
342 auto &vc = complex_fixture;
343 auto itc = vc.begin(3);
344 for (
auto &&n : std::vector<int>(10))
346 auto cell = itc->first;
347 Point p_cell = vc.space().uCoords(cell);
348 auto neigh6 = vc.space().uProperNeighborhood(cell);
351 for(
auto & n : neigh6)
352 if(vc.belongs(n)) cells.push_back(n);
355 std::vector<std::pair<bool, FixtureComplex::Clique>> cliques_p;
357 for (
auto && cell_n : cells) {
358 auto cell_point = vc.space().uCoords(cell_n);
359 cliques_p.emplace_back(vc.K_2(p_cell, cell_point, verbose));
360 auto &is_critical = cliques_p.back().first;
361 auto &k2_clique = cliques_p.back().second;
362 CHECK(is_critical ==
true);
363 CHECK(k2_clique.nbCells(3) == 2);
366 SECTION(
" Check same results for different K_2 interfaces") {
367 for (
auto && cell_n : cells) {
368 auto co_face = vc.surfelBetweenAdjacentSpels(cell_n, cell);
370 auto cell_point = vc.space().uCoords(cell_n);
372 CHECK(
isEqual(vc.K_2(p_cell, cell_point,
false).second,
373 vc.K_2(cell, cell_n,
false).second) ==
true);
374 CHECK(
isEqual(vc.K_2(p_cell, cell_point,
false).second,
375 vc.K_2(co_face,
false).second) ==
true);
381 auto &vc = complex_fixture;
382 auto itc = vc.begin(3);
383 for (
auto &&n : std::vector<int>(10))
385 auto cell = itc->first;
386 Point p_cell = vc.space().uCoords(cell);
388 SECTION(
"K_1 mask from a linel") {
390 vc.space().uCell(cell.preCell().coordinates +
Point{0, 1, 1});
393 auto k1p = vc.K_1(linel,
true);
394 auto &is_critical = k1p.first;
395 CHECK(is_critical ==
true);
396 auto &k1_clique = k1p.second;
398 CHECK(k1_clique.nbCells(3) == 3);
403 auto &vc = complex_fixture;
404 auto itc = vc.begin(3);
405 for (
auto &&n : std::vector<int>(10))
407 auto cell = itc->first;
408 Point p_cell = vc.space().uCoords(cell);
410 SECTION(
"K_0 mask from a pointel") {
411 auto pointel = vc.space().uPointel(p_cell);
415 auto k0_mask = vc.K_0(pointel,
true);
417 auto &is_critical = k0_mask.first;
418 CHECK(is_critical ==
false);
419 auto &k0_clique = k0_mask.second;
421 CHECK(k0_clique.nbCells(3) == 1);
426 "[critical][clique]") {
427 auto &vc = complex_fixture;
429 SECTION(
" Get all criticalCliques() ") {
430 auto criticals = vc.criticalCliques();
431 CHECK(criticals.size() == 4);
433 CHECK(vc.nbCells(3) == 62);
434 CHECK(criticals[3].size() == 18);
435 CHECK(vc.nbCells(2) == 264);
436 CHECK(criticals[2].size() == 108);
437 CHECK(vc.nbCells(1) == 360);
438 CHECK(criticals[1].size() == 168);
439 CHECK(vc.nbCells(0) == 160);
440 CHECK(criticals[0].size() == 32);
448 struct Fixture_complex_fig4 {
458 std::unordered_set<typename DGtal::Z3i::Domain::Point>>;
459 using FixtureMap = std::unordered_map<KSpace::Cell, CubicalCellData>;
464 FixtureComplex complex_fixture;
471 Fixture_complex_fig4() : complex_fixture(ks_fixture) {
472 create_complex_from_set(create_set());
478 FixtureDigitalSet create_set() {
479 using namespace DGtal;
481 Point p1(-10, -10, -10);
482 Point p2(10, 10, 10);
486 FixtureDigitalSet fig4_set(
domain);
488 fig4_set.insertNew(a1);
490 fig4_set.insertNew(a2);
492 fig4_set.insertNew(a3);
494 fig4_set.insertNew(c1);
496 fig4_set.insertNew(c2);
498 fig4_set.insertNew(c3);
500 fig4_set.insertNew(c4);
502 fig4_set.insertNew(b1);
504 fig4_set.insertNew(b2);
506 fig4_set.insertNew(l1);
508 fig4_set.insertNew(l2);
510 fig4_set.insertNew(r1);
515 FixtureComplex &create_complex_from_set(
const FixtureDigitalSet &input_set) {
517 ks_fixture.
init(input_set.domain().lowerBound(),
518 input_set.domain().upperBound(),
true);
519 complex_fixture = FixtureComplex(ks_fixture);
520 complex_fixture.construct(input_set);
521 return complex_fixture;
525 "[critical][clique]") {
526 auto &vc = complex_fixture;
528 SECTION(
" Get all criticalCliques() ") {
529 auto criticals = vc.criticalCliques(
true);
530 CHECK(criticals.size() == 4);
532 CHECK(vc.nbCells(3) == 12);
533 CHECK(criticals[3].size() == 1);
534 CHECK(vc.nbCells(2) == 64);
535 CHECK(criticals[2].size() == 3);
536 CHECK(vc.nbCells(1) == 109);
537 CHECK(criticals[1].size() == 2);
538 CHECK(vc.nbCells(0) == 58);
539 CHECK(criticals[0].size() == 6);
545 "[isSurface][function]") {
546 auto &vc = complex_fixture;
551 vc.insertCell(3, vc.space().uSpel(c));
555 vc.insertCell(3, vc.space().uSpel(r));
559 vc.insertCell(3, vc.space().uSpel(l));
565 std::unordered_set<typename DGtal::Z3i::Domain::Point>>;
571 adjF, adjB, DGtal::DigitalTopologyProperties::JORDAN_DT);
573 SECTION(
"checking zero surfaces of original set") {
574 std::set<Point> zeroSurfacesCells;
575 DigitalSet voxel_set(
domain);
576 vc.dumpVoxels(voxel_set);
577 Object object(topo, voxel_set);
578 for (
const auto &p : voxel_set) {
579 auto small_obj =
object.properNeighborhood(p);
581 zeroSurfacesCells.insert(p);
583 CHECK(zeroSurfacesCells.size() == 1);
586 SECTION(
"checking one surfaces of original set") {
589 vc.insertCell(3, vc.space().uSpel(u));
593 vc.insertCell(3, vc.space().uSpel(d));
596 std::set<Point> oneSurfacesCells;
597 DigitalSet voxel_set(
domain);
598 vc.dumpVoxels(voxel_set);
599 Object object(topo, voxel_set);
601 for (
const auto &p : voxel_set) {
602 auto small_obj =
object.properNeighborhood(p);
604 oneSurfacesCells.insert(p);
606 CHECK(oneSurfacesCells.size() == 1);
613 struct Fixture_isthmus {
624 std::unordered_set<typename DGtal::Z3i::Domain::Point>>;
625 using FixtureMap = std::unordered_map<KSpace::Cell, CubicalCellData>;
630 FixtureComplex complex_fixture;
631 FixtureDigitalSet set_fixture;
638 Fixture_isthmus() : complex_fixture(ks_fixture), set_fixture(create_set()) {
639 create_complex_from_set(set_fixture);
645 FixtureDigitalSet create_set() {
646 using namespace DGtal;
648 Point p1(-10, -10, -10);
649 Point p2(10, 10, 10);
652 FixtureDigitalSet fig6_set(
domain);
655 fig6_set.insertNew(c00);
657 fig6_set.insertNew(c01);
659 fig6_set.insertNew(c02);
661 fig6_set.insertNew(c03);
664 fig6_set.insertNew(c10);
666 fig6_set.insertNew(y);
668 fig6_set.insertNew(c12);
670 fig6_set.insertNew(c13);
673 fig6_set.insertNew(c20);
675 fig6_set.insertNew(c21);
677 fig6_set.insertNew(c22);
678 Point c33(-1, 2, -1);
679 fig6_set.insertNew(c33);
682 fig6_set.insertNew(c30);
684 fig6_set.insertNew(c31);
687 fig6_set.insertNew(x);
690 fig6_set.insertNew(c50);
691 Point c51(-1, 5, -1);
692 fig6_set.insertNew(c51);
694 fig6_set.insertNew(c52);
697 fig6_set.insertNew(c60);
699 fig6_set.insertNew(c61);
700 Point c62(-2, 6, -1);
701 fig6_set.insertNew(c62);
706 FixtureComplex &create_complex_from_set(
const FixtureDigitalSet &input_set) {
708 ks_fixture.
init(input_set.domain().lowerBound(),
709 input_set.domain().upperBound(),
true);
710 complex_fixture = FixtureComplex(ks_fixture);
711 complex_fixture.construct(input_set);
712 return complex_fixture;
717 "[isthmus][thin][function]") {
719 auto &vc = complex_fixture;
720 auto &ks = vc.space();
722 set_fixture.erase(x);
726 vc.construct(set_fixture);
728 auto vc_new = asymetricThinningScheme<FixtureComplex>(
729 vc, selectFirst<FixtureComplex>, skelUltimate<FixtureComplex>);
730 CHECK(vc_new.nbCells(3) == 2);
736 auto &vc = complex_fixture;
738 auto &ks = vc.space();
742 SECTION(
"checking one isthmus") {
743 std::set<Point> isthmus;
744 for (
const auto &p : set_fixture) {
748 CHECK(isthmus.size() == 1);
749 auto xit = isthmus.find(x);
753 SECTION(
"checking 2 isthmus") {
754 std::set<Point> isthmus;
755 for (
const auto &p : set_fixture) {
759 CHECK(isthmus.size() == 1);
760 auto yit = isthmus.find(y);
764 SECTION(
"checking 1 and 2 isthmus") {
765 std::set<Point> isthmus;
766 for (
const auto &p : set_fixture) {
770 CHECK(isthmus.size() == 2);
771 auto xit = isthmus.find(x);
772 auto yit = isthmus.find(y);
773 CHECK(xit != isthmus.end());
774 CHECK(yit != isthmus.end());
779 auto &vc = complex_fixture;
780 auto &ks = vc.space();
782 auto vc_new = asymetricThinningScheme<FixtureComplex>(
783 vc, selectFirst<FixtureComplex>, skelUltimate<FixtureComplex>);
784 CHECK(vc_new.nbCells(3) == 1);
787 auto vc_new = asymetricThinningScheme<FixtureComplex>(
788 vc, selectFirst<FixtureComplex>, skelEnd<FixtureComplex>);
789 CHECK(vc_new.nbCells(3) == 5);
792 auto vc_new = asymetricThinningScheme<FixtureComplex>(
793 vc, selectRandom<FixtureComplex>, oneIsthmus<FixtureComplex>);
794 CHECK(vc_new.nbCells(3) == 3);
797 auto vc_new = asymetricThinningScheme<FixtureComplex>(
798 vc, selectRandom<FixtureComplex>, twoIsthmus<FixtureComplex>);
799 CHECK(vc_new.nbCells(3) == 1);
802 auto vc_new = asymetricThinningScheme<FixtureComplex>(
803 vc, selectRandom<FixtureComplex>, skelIsthmus<FixtureComplex>);
804 CHECK(vc_new.nbCells(3) == 3);
809 "[persistence][isthmus][thin][function]") {
811 auto &vc = complex_fixture;
812 auto &ks = vc.space();
814 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
815 vc, selectRandom<FixtureComplex>, skelUltimate<FixtureComplex>, 0);
816 CHECK(vc_new.nbCells(3) == 1);
819 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
820 vc, selectRandom<FixtureComplex>, skelEnd<FixtureComplex>, 0);
821 CHECK(vc_new.nbCells(3) == 5);
829 auto table = *functions::loadTable(isthmusicity::tableOneIsthmus);
830 auto pointToMaskMap =
831 *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
832 auto oneIsthmusTable =
833 [&table, &pointToMaskMap](
const FixtureComplex &fc,
837 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
838 vc, selectRandom<FixtureComplex>, oneIsthmusTable, 0);
839 CHECK(vc_new.nbCells(3) == 3);
847 auto table = *functions::loadTable(isthmusicity::tableTwoIsthmus);
848 auto pointToMaskMap =
849 *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
850 auto twoIsthmusTable =
851 [&table, &pointToMaskMap](
const FixtureComplex &fc,
855 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
856 vc, selectRandom<FixtureComplex>, twoIsthmusTable, 0);
857 CHECK(vc_new.nbCells(3) == 1);
865 auto table = *functions::loadTable(isthmusicity::tableIsthmus);
866 auto pointToMaskMap =
867 *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
868 auto isthmusTable = [&table,
869 &pointToMaskMap](
const FixtureComplex &fc,
873 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
874 vc, selectRandom<FixtureComplex>, isthmusTable, 0);
875 CHECK(vc_new.nbCells(3) == 3);
892 std::unordered_set<typename DGtal::Z3i::Domain::Point>>;
893 using FixtureMap = std::unordered_map<KSpace::Cell, CubicalCellData>;
898 FixtureComplex complex_fixture;
899 FixtureDigitalSet set_fixture;
906 Fixture_X() : complex_fixture(ks_fixture), set_fixture(create_set()) {
907 create_complex_from_set(set_fixture);
913 FixtureDigitalSet create_set() {
914 using namespace DGtal;
916 Point p1(-30, -30, -30);
917 Point p2(30, 30, 30);
920 FixtureDigitalSet a_set(
domain);
921 std::vector<Point> center_set;
922 center_set.reserve(9);
925 center_set.push_back(c00);
926 Point c01x(-1, 0, 0);
927 center_set.push_back(c01x);
929 center_set.push_back(c10x);
930 Point c02x(-2, 0, 0);
931 center_set.push_back(c02x);
933 center_set.push_back(c20x);
935 Point c01y(0, -1, 0);
936 center_set.push_back(c01y);
938 center_set.push_back(c10y);
939 Point c02y(0, -2, 0);
940 center_set.push_back(c02y);
942 center_set.push_back(c20y);
944 Point z_pos(0, 0, 1);
945 int branch_length(10);
946 std::vector<Point> diagonals;
947 diagonals.reserve(6);
948 for (
const auto &p : center_set) {
950 for (
int l = 0; l <= branch_length; ++l) {
951 diagonals.push_back({l, l, 0});
952 diagonals.push_back({l, -l, 0});
953 diagonals.push_back({-l, l, 0});
954 diagonals.push_back({-l, -l, 0});
955 for (
int z = -2; z <= 2; ++z)
956 for (
const auto &d : diagonals)
957 a_set.insert(p + d + (z * z_pos));
964 FixtureComplex &create_complex_from_set(FixtureDigitalSet &input_set) {
966 ks_fixture.
init(input_set.domain().lowerBound(),
967 input_set.domain().upperBound(),
true);
968 complex_fixture = FixtureComplex(ks_fixture);
969 complex_fixture.construct(input_set);
970 return complex_fixture;
975 "[x][persistence][isthmus][thin][function]") {
977 auto &vc = complex_fixture;
978 auto &ks = vc.space();
981 "persistence value of 1 is equivalent to the assymetric algorithm") {
982 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
983 vc, selectFirst<FixtureComplex>, skelEnd<FixtureComplex>, 1,
986 auto vc_assymetric = asymetricThinningScheme<FixtureComplex>(
987 vc, selectFirst<FixtureComplex>, skelEnd<FixtureComplex>,
true);
989 CHECK(vc_assymetric.nbCells(3) ==
990 Approx(vc_new.nbCells(3)).epsilon(0.1));
992 SECTION(
"persistence value: infinite is equivalent to ultimate skeleton") {
993 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
994 vc, selectRandom<FixtureComplex>, skelEnd<FixtureComplex>, 100,
996 REQUIRE(vc_new.nbCells(3) == 1);
1001 "[x][isthmus][thin][function][table]") {
1003 auto &vc = complex_fixture;
1004 auto &ks = vc.space();
1005 bool verbose =
true;
1015 SECTION(
"Compute with skelWithTable (isIsthmus)") {
1017 auto table = *functions::loadTable(isthmusicity::tableIsthmus);
1018 auto pointToMaskMap =
1019 *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
1020 auto skelWithTableIsthmus =
1021 [&table, &pointToMaskMap](
const FixtureComplex &fc,
1026 auto vc_new = asymetricThinningScheme<FixtureComplex>(
1027 vc, selectRandom<FixtureComplex>, skelWithTableIsthmus, verbose);
1032 SECTION(
"Compute with skelWithTable (isIsthmus) and empty Object") {
1033 trace.
beginBlock(
"Fixture_X skelIsthmus with table (empty objectSet)");
1034 vc.setSimplicityTable(
1035 functions::loadTable(simplicity::tableSimple26_6));
1037 auto table = *functions::loadTable(isthmusicity::tableIsthmus);
1038 auto pointToMaskMap =
1039 *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
1040 auto skelWithTableIsthmus =
1041 [&table, &pointToMaskMap](
const FixtureComplex &fc,
1046 auto vc_new = asymetricThinningScheme<FixtureComplex>(
1047 vc, selectRandom<FixtureComplex>, skelWithTableIsthmus, verbose);
1056 auto &vc = complex_fixture;
1057 auto &ks = vc.space();
1061 bool verbose =
true;
1062 SECTION(
"Fixture_X Distance Map") {
1065 DT dt(set_fixture.domain(), set_fixture, l3);
1067 auto selectDistMax = [&dt](
const FixtureComplex::Clique &clique) {
1068 return selectMaxValue<DT, FixtureComplex>(dt, clique);
1071 auto vc_new = asymetricThinningScheme<FixtureComplex>(
1072 vc, selectDistMax, skelEnd<FixtureComplex>, verbose);
1074 SECTION(
"persistenceThinning"){
1075 auto table = *functions::loadTable(isthmusicity::tableOneIsthmus);
1076 auto pointToMaskMap =
1077 *functions::mapZeroPointNeighborhoodToConfigurationMask<Point>();
1078 auto oneIsthmusTable =
1079 [&table, &pointToMaskMap](
const FixtureComplex &fc,
1083 int persistence = 3;
1084 auto vc_new = persistenceAsymetricThinningScheme<FixtureComplex>(
1085 vc, selectDistMax, oneIsthmusTable,
1086 persistence, verbose);
Aim: An object (or digital object) represents a set in some digital space associated with a digital t...
void beginBlock(const std::string &keyword="")
const ConstIterator & end() const
HyperRectDomain< Space > Domain
const Point & upperBound() const
Return the upper bound for digital points in this space.
TForegroundAdjacency ForegroundAdjacency
bool twoIsthmus(const TComplex &vc, const typename TComplex::Cell &cell)
bool oneIsthmus(const TComplex &vc, const typename TComplex::Cell &cell)
bool isOneSurface(const TObject &small_obj)
bool skelIsthmus(const TComplex &vc, const typename TComplex::Cell &cell)
Aim: implements separable l_p metrics with exact predicates.
REQUIRE(domain.isInside(aPoint))
TBackgroundAdjacency BackgroundAdjacency
Aim: Represents a digital topology as a couple of adjacency relations.
bool init(const Point &lower, const Point &upper, bool isClosed)
Specifies the upper and lower bounds for the maximal cells in this space.
bool isZeroSurface(const TObject &small_obj)
const ConstIterator & begin() const
DigitalTopology< Adj26, Adj6 > DT26_6
TEST_CASE_METHOD(Fixture_complex_diamond, "insertVoxel", "[insert][close]")
const Point & lowerBound() const
Return the lower bound for digital points in this space.
DGtal is the top-level namespace which contains all DGtal functions and types.
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
bool isEqual(Container1 &c1, Container2 &c2)
KhalimskySpaceND< 3, Integer > KSpace
functions namespace gathers all DGtal functionsxs.
bool skelWithTable(const boost::dynamic_bitset<> &table, const std::unordered_map< typename TComplex::Point, unsigned int > &pointToMaskMap, const TComplex &vc, const typename TComplex::Cell &cell)
SECTION("Testing constant forward iterators")
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
AnyCellCollection< Cell > Cells