DGtal 2.1.0
Loading...
Searching...
No Matches
testDigitalSetByOctree.cpp
Go to the documentation of this file.
1
16
27
32
33#include "DGtal/helpers/StdDefs.h"
34#include "DGtal/kernel/sets/DigitalSetByOctree.h"
35#include "DGtalCatch.h"
36
37#include "DGtal/io/writers/VolWriter.h"
38#include "DGtal/io/readers/VolReader.h"
39#include "DGtal/io/writers/SVOWriter.h"
40#include "DGtal/io/readers/SVOReader.h"
41
42using namespace DGtal;
43using namespace std;
44
46{
47 inline static const Z3i::Domain domain {Z3i::Point(-1, -2, -1), Z3i::Point(14, 3, 9)};
48 inline static const Z3i::Domain expectedDomain{Z3i::Point(-1, -2, -1), Z3i::Point(14, 13, 14)};
49 // Some test cases
50 inline static const Z3i::Point testPoints[8] =
51 {
52 // Valid points inside the domain
53 Z3i::Point(0, 0, 0) , Z3i::Point(2, 1, 4), // Some points
54 Z3i::Point(-1, -1, -1), Z3i::Point(14, 13, 14), // On the edge
55 Z3i::Point(8, 7, 4), // Outside the original domain, but inside the expected one
56 // We pay for the bigger domain, we might accept those points as well
57 // Duplicates
58 Z3i::Point(0, 0, 0), Z3i::Point(8, 7, 4),
59 // Outside the domain
60 Z3i::Point(-5, 152, -123)
61 };
62 inline static const size_t testPointCount = sizeof(testPoints) / sizeof(Z3i::Point);
63 inline static const bool testPointsValid[8] =
64 {
65 true, true,
66 true, true,
67 true,
68 true, true,
69 false,
70 };
71 // Valid points of testPoints, in expected order
72 inline static const Z3i::Point validPoints[5] =
73 {
74 Z3i::Point(-1, -1, -1), Z3i::Point(0, 0, 0),
75 Z3i::Point(2, 1, 4) , Z3i::Point(8, 7, 4),
76 Z3i::Point(14, 13, 14)
77 };
78 inline static const size_t validPointCount = sizeof(validPoints) / sizeof(Z3i::Point);
79};
80
81TEST_CASE_METHOD(TestFixture, "Testing DigitalSetByOctree using Catch2", "[catch]")
82{
83 // This is checked at compile time !
84 using namespace DGtal;
87
88 SECTION("Test octree domain")
89 {
91 REQUIRE(octree.domain().lowerBound() == expectedDomain.lowerBound());
92 REQUIRE(octree.domain().upperBound() == expectedDomain.upperBound());
93 };
94
95 SECTION("Test octree insert")
96 {
98 for (int i = 0; i < testPointCount; ++i)
99 octree.insert(testPoints[i]);
100
101 REQUIRE(octree.size() == validPointCount);
102 };
103
104 SECTION("Testing if points exists")
105 {
107 for (int i = 0; i < testPointCount; ++i)
108 octree.insert(testPoints[i]);
109
110 for (int i = 0; i < sizeof(testPoints) / sizeof(Z3i::Point); ++i)
111 REQUIRE(testPointsValid[i] == octree(testPoints[i]));
112 };
113
114 SECTION("Testing iterating over octree")
115 {
117 for (int i = 0; i < testPointCount; ++i)
118 octree.insert(testPoints[i]);
119
120 size_t i = 0;
121 for (auto it = octree.begin(); it != octree.end(); ++it, ++i)
122 {
123 if (i >= validPointCount)
124 {
125 REQUIRE(false);
126 return;
127 }
128 REQUIRE(*it == validPoints[i]);
129 }
130 };
131
132 SECTION("Testing erasing points")
133 {
135 for (int i = 0; i < testPointCount; ++i)
136 octree.insert(testPoints[i]);
137
138 octree.erase(testPoints[0]);
139 octree.erase(octree.end()); // Invalid iterator, but we accept it anyway
140
141 for (auto it = octree.begin(); it != octree.end(); ++it)
142 REQUIRE(*it != testPoints[0]);
143
144 REQUIRE(octree.size() == validPointCount - 1);
145 };
146
147 SECTION("Test DAG on simple case")
148 {
149 const unsigned int lvl = 4;
150 const int size = (1 << lvl);
151
152 const size_t expectedMemory = lvl * sizeof(typename DigitalSetByOctree<Z3i::Space>::Node);
153 std::vector<size_t> expectedRslt(size, 3);
154 expectedRslt.front() = 2;
155 expectedRslt.back() = 2;
156
157 Z3i::Domain domainL(Z3i::Point{0, 0, 0}, Z3i::Point{size, size, size});
158
160
161 // One of best cases for dag: all points on the diagonal of the domain
162 // This is compressed as a single node per level.
163 for (size_t i = 0; i < size; ++i)
164 octree.insert(Z3i::Point{(int)i, (int)i, (int)i});
165
166 octree.convertToDAG();
167
168 auto lmbd = [](Z3i::Point, const std::vector<Z3i::Point>& neighborhood)
169 {
170 return neighborhood.size();
171 };
172 auto rslt = octree.computeFunction(octree.begin(), octree.end(), 1, lmbd);
173
174 REQUIRE(octree.memoryFootprint() == expectedMemory);
175 REQUIRE(rslt == expectedRslt);
176 };
177
178 SECTION("Test Vol I/O")
179 {
180 const unsigned int start = 5;
181 const unsigned int end = 10;
182 DigitalSetByOctree<Z3i::Space> octree1(Z3i::Domain(Z3i::Point{start, start, start}, {end, end, end}));
183 for (unsigned int i = 0; i < (end - start); ++i)
184 {
185 const int c = (int)start + (int)i;
186 octree1.insert(Z3i::Point{c, c, c});
187 }
188 octree1.convertToDAG();
189
190 SVOWriter<Z3i::Space>::exportSVO("tmp.svo", octree1, true);
191 auto octree2 = SVOReader<Z3i::Space>::importSVO("tmp.svo");
192
193 auto it1 = octree1.begin();
194 auto it2 = octree2.begin();
195
196 for (; it1 != octree1.end() && it2 != octree2.end(); ++it1, ++it2)
197 REQUIRE(*it1 == *it2);
198
199 REQUIRE(it1 == octree1.end());
200 REQUIRE(it2 == octree2.end());
201 };
202};
203
A DigitalSet that stores voxels as an octree, or a DAG.
void insert(const Point &p)
Inserts a new point in the octree.
size_t erase(const Iterator &it)
Remove a voxel from the octree.
size_t size() const
Returns the number of voxel in the set.
void convertToDAG()
Converts the octree to DAG.
Iterator end()
Returns an iterator to the end of the octree.
const Domain & domain() const
Returns the domain of the digital set.
Iterator begin() const
Returns an iterator to the begining of the octree.
const Point & lowerBound() const
const Point & upperBound() const
static Octree importSVO(const std::string &filename)
Imports an octree from a file.
static bool exportSVO(const std::string &filename, const DigitalSetByOctree< Space > &octree, const bool compressed=true)
Exports an octree to a file.
HyperRectDomain< Space > Domain
Definition StdDefs.h:172
Space::Point Point
Definition StdDefs.h:168
DGtal is the top-level namespace which contains all DGtal functions and types.
STL namespace.
Aim: Represents a set of points within the given domain. This set of points is modifiable by the user...
static const Z3i::Point validPoints[5]
static const Z3i::Domain expectedDomain
static const bool testPointsValid[8]
static const Z3i::Domain domain
static const size_t validPointCount
static const size_t testPointCount
static const Z3i::Point testPoints[8]
TEST_CASE_METHOD(TestFixture, "Testing DigitalSetByOctree using Catch2", "[catch]")
Domain domain
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))