File: Clipping.cpp

package info (click to toggle)
libformfactor 0.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,288 kB
  • sloc: cpp: 17,289; python: 382; makefile: 15
file content (401 lines) | stat: -rw-r--r-- 17,283 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
//! Used to test the function ff::Polyhedron::clipped
#include "ff/Make.h"
#include "ff/Polyhedron.h"
#include "ff/Topology.h"
#include "test/3rdparty/catch.hpp"
#include "test/util/StreamOperators.h"
#include <iomanip>
#include <iostream>
namespace {
const ff::Topology topologyPyramid{{
                                       {{0, 1, 2, 3}, false},
                                       {{4, 1, 0}, false},
                                       {{4, 2, 1}, false},
                                       {{4, 3, 2}, false},
                                       {{4, 0, 3}, false},
                                   },
                                   false};
const std::vector<R3> verticesPyramid{
    {{-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}, {1, -1, -1}, {0, 0, 1}}};

const ff::Box* box = ff::make::Box(1, 1, 1);

auto cube = std::unique_ptr<ff::Polyhedron>(box->asPolyhedron());
auto pyramid = std::make_unique<ff::Polyhedron>(topologyPyramid, verticesPyramid);
auto octahedron = std::unique_ptr<ff::Polyhedron>(ff::make::Octahedron(1));
auto icosahedron = std::unique_ptr<ff::Polyhedron>(ff::make::Icosahedron(1));
auto dodecahedron = std::unique_ptr<ff::Polyhedron>(ff::make::Dodecahedron(1));

}; // namespace

//! Test the topology of the clipped polyhedra with zMin == -inf

TEST_CASE("Clipped:zMin:-inf", "[Polyhedron][clipped][topology]")
{
    std::vector<std::tuple<std::unique_ptr<ff::Polyhedron>&, ff::Topology>> polyhedra{
        {cube,
         {{{{0, 1, 2, 3}, false},
           {{0, 4, 5, 1}, false},
           {{1, 5, 6, 2}, false},
           {{0, 3, 7, 4}, false},
           {{2, 6, 7, 3}, false},
           {{7, 6, 5, 4}, false}},
          false}},
        {pyramid,
         {{{{0, 1, 2, 3}, false},
           {{0, 4, 5, 1}, false},
           {{1, 5, 6, 2}, false},
           {{2, 6, 7, 3}, false},
           {{0, 3, 7, 4}, false},
           {{7, 6, 5, 4}, false}},
          false}},
        {octahedron,
         {{{{0, 1, 2}, false},
           {{0, 3, 1}, false},
           {{0, 4, 3}, false},
           {{0, 2, 4}, false},
           {{3, 4, 2, 1}, false}},
          false}},
        {icosahedron,
         {{{{0, 1, 2}, false},
           {{0, 3, 1}, false},
           {{1, 4, 2}, false},
           {{0, 2, 5}, false},
           {{0, 12, 11, 3}, false},
           {{1, 3, 9, 6}, false},
           {{1, 6, 8, 4}, false},
           {{2, 4, 17, 16}, false},
           {{2, 16, 15, 5}, false},
           {{0, 5, 13, 12}, false},
           {{4, 8, 7}, false},
           {{3, 10, 9}, false},
           {{3, 11, 10}, false},
           {{5, 14, 13}, false},
           {{5, 15, 14}, false},
           {{4, 7, 17}, false},
           {{14, 15, 16, 17, 7, 8, 6, 9, 10, 11, 12, 13}, false}},
          false}},
        {dodecahedron,
         {{{{0, 1, 2, 3, 4}, false},
           {{0, 15, 10, 9, 16, 1}, false},
           {{1, 16, 8, 7, 17, 2}, false},
           {{2, 17, 6, 5, 18, 3}, false},
           {{3, 18, 14, 13, 19, 4}, false},
           {{0, 4, 19, 12, 11, 15}, false},
           {{6, 17, 7}, false},
           {{8, 16, 9}, false},
           {{10, 15, 11}, false},
           {{12, 19, 13}, false},
           {{5, 14, 18}, false},
           {{13, 14, 5, 6, 7, 8, 9, 10, 11, 12}, false}},
          false}}};
    for (auto& [polyhedron, topology] : polyhedra) {
        auto clipped = std::unique_ptr<ff::Polyhedron>(
            polyhedron->clipped(-INFINITY, polyhedron->location().z()));
        REQUIRE(topology == clipped->topology());
    }
}

//! Test the topology of the clipped polyhedra with zMax == inf

TEST_CASE("Clipped:zMax:inf", "[Polyhedron][clipped][topology]")
{
    std::vector<std::tuple<std::unique_ptr<ff::Polyhedron>&, ff::Topology>> polyhedra{
        {cube,
         {{{{4, 5, 6, 7}, false},
           {{0, 2, 4, 7}, false},
           {{0, 7, 6, 3}, false},
           {{1, 5, 4, 2}, false},
           {{1, 3, 6, 5}, false},
           {{1, 2, 0, 3}, false}},
          false}},
        {pyramid,
         {{{{0, 3, 4}, false},
           {{0, 4, 1}, false},
           {{1, 4, 2}, false},
           {{2, 4, 3}, false},
           {{2, 3, 0, 1}, false}},
          false}},
        {octahedron,
         {{{{0, 2, 4}, false},
           {{3, 0, 4}, false},
           {{3, 4, 1}, false},
           {{2, 1, 4}, false},
           {{1, 2, 0, 3}, false}},
          false}},
        {icosahedron,
         {{{{0, 1, 2}, false},
           {{3, 4, 5}, false},
           {{3, 6, 4}, false},
           {{7, 8, 9}, false},
           {{7, 10, 8}, false},
           {{0, 11, 1}, false},
           {{3, 12, 13, 6}, false},
           {{3, 5, 14, 15}, false},
           {{1, 15, 14, 2}, false},
           {{1, 11, 16, 17}, false},
           {{7, 17, 16, 10}, false},
           {{7, 9, 13, 12}, false},
           {{3, 15, 12}, false},
           {{1, 17, 15}, false},
           {{7, 12, 17}, false},
           {{12, 15, 17}, false},
           {{6, 13, 9, 8, 10, 16, 11, 0, 2, 14, 5, 4}, false}},
          false}},
        {dodecahedron,
         {{{{0, 1, 2}, false},
           {{3, 4, 5}, false},
           {{6, 7, 8}, false},
           {{9, 10, 11}, false},
           {{12, 13, 14}, false},
           {{3, 15, 16, 6, 8, 4}, false},
           {{1, 17, 15, 3, 5, 2}, false},
           {{0, 13, 12, 18, 17, 1}, false},
           {{9, 19, 18, 12, 14, 10}, false},
           {{6, 16, 19, 9, 11, 7}, false},
           {{15, 17, 18, 19, 16}, false},
           {{7, 11, 10, 14, 13, 0, 2, 5, 4, 8}, false}},
          false}}};
    for (auto& [polyhedron, topology] : polyhedra) {
        auto clipped = std::unique_ptr<ff::Polyhedron>(
            polyhedron->clipped(polyhedron->location().z(), INFINITY));
        REQUIRE(topology == clipped->topology());
    }
}

//! Test the topology of the clipped polyhedra with zMin == -inf && zMax == inf

TEST_CASE("Clipped:zMin-zMax:inf", "[Polyhedron][clipped][topology]")
{
    std::vector<std::tuple<std::unique_ptr<ff::Polyhedron>&, ff::Topology>> polyhedra{
        {cube,
         {{{{0, 1, 2, 3}, true},
           {{4, 5, 1, 0}, true},
           {{5, 6, 2, 1}, true},
           {{7, 4, 0, 3}, true},
           {{6, 7, 3, 2}, true},
           {{7, 6, 5, 4}, true}},
          true}},
        {pyramid,
         {{{{0, 1, 2, 3}, false},
           {{4, 1, 0}, false},
           {{4, 2, 1}, false},
           {{4, 3, 2}, false},
           {{4, 0, 3}, false}},
          false}},
        {octahedron,
         {{{{0, 2, 1}, false},
           {{0, 3, 2}, false},
           {{0, 4, 3}, false},
           {{0, 1, 4}, false},
           {{2, 3, 5}, false},
           {{1, 2, 5}, false},
           {{4, 1, 5}, false},
           {{3, 4, 5}, false}},
          true}},
        {icosahedron,
         {{{{0, 2, 1}, false},  {{0, 5, 2}, false},   {{2, 3, 1}, false},  {{1, 4, 0}, false},
           {{0, 6, 5}, false},  {{2, 5, 8}, false},   {{2, 8, 3}, false},  {{1, 3, 7}, false},
           {{1, 7, 4}, false},  {{0, 4, 6}, false},   {{3, 8, 9}, false},  {{5, 11, 8}, false},
           {{5, 6, 11}, false}, {{4, 10, 6}, false},  {{4, 7, 10}, false}, {{3, 9, 7}, false},
           {{8, 11, 9}, false}, {{6, 10, 11}, false}, {{7, 9, 10}, false}, {{9, 11, 10}, false}},
          true}},
        {dodecahedron,
         {{{{0, 4, 3, 2, 1}, false},
           {{0, 5, 12, 9, 4}, false},
           {{4, 9, 11, 8, 3}, false},
           {{3, 8, 10, 7, 2}, false},
           {{2, 7, 14, 6, 1}, false},
           {{1, 6, 13, 5, 0}, false},
           {{8, 11, 16, 15, 10}, false},
           {{9, 12, 17, 16, 11}, false},
           {{5, 13, 18, 17, 12}, false},
           {{6, 14, 19, 18, 13}, false},
           {{7, 10, 15, 19, 14}, false},
           {{15, 16, 17, 18, 19}, false}},
          true}},
    };
    for (const auto& [polyhedron, topology] : polyhedra) {
        auto clipped = std::unique_ptr<ff::Polyhedron>(polyhedron->clipped(-INFINITY, INFINITY));
        REQUIRE(topology == clipped->topology());
    }
}

//! Test the topology of the clipped polyhedra with zMin == ff::Polyhedron.location().z - 0.1 &&
//! zMax == ff::Polyhedron.location().z + 0.1

TEST_CASE("Clipped:zMin-zMax:0.1", "[Polyhedron][clipped][topology]")
{
    std::vector<std::tuple<std::unique_ptr<ff::Polyhedron>&, ff::Topology, std::vector<R3>>>
        polyhedra{
            {cube,
             {{{{4, 5, 6, 7}, false},
               {{0, 2, 4, 7}, false},
               {{1, 5, 4, 2}, false},
               {{0, 7, 6, 3}, false},
               {{1, 3, 6, 5}, false},
               {{1, 2, 0, 3}, false}},
              false},
             {{0.5, 0.5, 0.6},
              {-0.5, -0.5, 0.6},
              {0.5, -0.5, 0.6},
              {-0.5, 0.5, 0.6},
              {0.5, -0.5, 0.4},
              {-0.5, -0.5, 0.4},
              {-0.5, 0.5, 0.4},
              {0.5, 0.5, 0.4}}},
            {pyramid,
             {{{{4, 5, 6, 7}, false},
               {{4, 7, 0, 2}, false},
               {{4, 2, 1, 5}, false},
               {{5, 1, 3, 6}, false},
               {{6, 3, 0, 7}, false},
               {{1, 2, 0, 3}, false}},
              false},
             {
                 {-0.4500000000000000, -0.4500000000000000, 0.1000000000000000},
                 {0.4500000000000000, 0.4500000000000000, 0.1000000000000000},
                 {-0.4500000000000000, 0.4500000000000000, 0.1000000000000000},
                 {0.4500000000000000, -0.4500000000000000, 0.1000000000000000},
                 {-0.5500000000000000, 0.5500000000000000, -0.1000000000000000},
                 {0.5500000000000000, 0.5500000000000000, -0.1000000000000000},
                 {0.5500000000000000, -0.5500000000000000, -0.1000000000000000},
                 {-0.5500000000000000, -0.5500000000000000, -0.1000000000000000},
             }},
            {octahedron,
             {{{{0, 1, 2, 3}, false},
               {{2, 4, 5, 3}, false},
               {{4, 6, 7, 5}, false},
               {{0, 7, 6, 1}, false},
               {{1, 6, 4, 2}, false},
               {{3, 5, 8, 10}, false},
               {{0, 3, 10, 9}, false},
               {{0, 9, 11, 7}, false},
               {{5, 7, 11, 8}, false},
               {{9, 10, 8, 11}, false}},
              false},
             {
                 {0.5000000000000000, -0.5000000000000000, 0.7071067811865475},
                 {0.4292893218813453, -0.4292893218813453, 0.6071067811865475},
                 {0.4292893218813453, 0.4292893218813453, 0.6071067811865475},
                 {0.5000000000000000, 0.5000000000000000, 0.7071067811865475},
                 {-0.4292893218813453, 0.4292893218813453, 0.6071067811865475},
                 {-0.5000000000000000, 0.5000000000000000, 0.7071067811865475},
                 {-0.4292893218813453, -0.4292893218813453, 0.6071067811865475},
                 {-0.5000000000000000, -0.5000000000000000, 0.7071067811865475},
                 {-0.4292893218813453, 0.4292893218813453, 0.8071067811865474},
                 {0.4292893218813453, -0.4292893218813453, 0.8071067811865474},
                 {0.4292893218813453, 0.4292893218813453, 0.8071067811865474},
                 {-0.4292893218813453, -0.4292893218813453, 0.8071067811865474},
             }},
            {icosahedron,
             {{{{0, 1, 2, 3}, false},
               {{0, 3, 4, 5}, false},
               {{6, 7, 8, 9}, false},
               {{6, 9, 10, 11}, false},
               {{4, 12, 13, 5}, false},
               {{1, 14, 15, 2}, false},
               {{14, 16, 17, 15}, false},
               {{18, 19, 20, 21}, false},
               {{10, 20, 19, 11}, false},
               {{7, 13, 12, 8}, false},
               {{0, 5, 13, 7, 6, 11, 19, 18, 22, 16, 14, 1}, false},
               {{16, 22, 23, 17}, false},
               {{18, 21, 23, 22}, false},
               {{23, 21, 20, 10, 9, 8, 12, 4, 3, 2, 15, 17}, false}},
              false},
             {
                 {-0.4139144013297142, -0.7169207730875197, 0.6557613140761708},
                 {0.2618033988749896, -0.8090169943749472, 0.6557613140761708},
                 {-0.2618033988749896, -0.8090169943749473, 0.8557613140761707},
                 {-0.4521110024547247, -0.7830792269124804, 0.8557613140761707},
                 {-0.5697275697845422, -0.6312368914103249, 0.8557613140761707},
                 {-0.8315309686595316, -0.1777801029646224, 0.6557613140761708},
                 {-0.4139144013297142, 0.7169207730875197, 0.6557613140761708},
                 {-0.8315309686595316, 0.1777801029646224, 0.6557613140761708},
                 {-0.5697275697845422, 0.6312368914103249, 0.8557613140761707},
                 {-0.4521110024547247, 0.7830792269124804, 0.8557613140761707},
                 {-0.2618033988749896, 0.8090169943749473, 0.8557613140761707},
                 {0.2618033988749896, 0.8090169943749472, 0.6557613140761708},
                 {-0.8278288026594283, 0.0000000000000000, 0.8557613140761707},
                 {-0.9042220049094493, 0.0000000000000000, 0.6557613140761708},
                 {0.4521110024547247, -0.7830792269124803, 0.6557613140761708},
                 {0.4139144013297142, -0.7169207730875197, 0.8557613140761707},
                 {0.5697275697845421, -0.6312368914103248, 0.6557613140761708},
                 {0.8315309686595317, -0.1777801029646224, 0.8557613140761707},
                 {0.5697275697845421, 0.6312368914103248, 0.6557613140761708},
                 {0.4521110024547247, 0.7830792269124803, 0.6557613140761708},
                 {0.4139144013297142, 0.7169207730875197, 0.8557613140761707},
                 {0.8315309686595317, 0.1777801029646224, 0.8557613140761707},
                 {0.8278288026594283, 0.0000000000000000, 0.6557613140761708},
                 {0.9042220049094494, 0.0000000000000000, 0.8557613140761707},
             }},
            {dodecahedron,
             {{{{0, 1, 2, 3}, false},
               {{4, 5, 6, 7}, false},
               {{8, 9, 10, 11}, false},
               {{12, 13, 14, 15}, false},
               {{0, 3, 6, 5}, false},
               {{1, 16, 17, 2}, false},
               {{8, 11, 14, 13}, false},
               {{4, 7, 10, 9}, false},
               {{0, 5, 4, 9, 8, 13, 12, 18, 16, 1}, false},
               {{16, 18, 19, 17}, false},
               {{12, 15, 19, 18}, false},
               {{15, 14, 11, 10, 7, 6, 3, 2, 17, 19}, false}},
              false},
             {
                 {-0.9003225837313085, -0.9639113427454318, 1.0135163644116070},
                 {0.1618033988749897, -1.3090169943749470, 1.0135163644116070},
                 {-0.1618033988749896, -1.3090169943749470, 1.2135163644116072},
                 {-0.6385191848563186, -1.1541226460044625, 1.2135163644116072},
                 {-1.1949491424413905, 0.5583926740462365, 1.0135163644116070},
                 {-1.1949491424413905, -0.5583926740462365, 1.0135163644116070},
                 {-1.2949491424413906, -0.2506243203287109, 1.2135163644116072},
                 {-1.2949491424413906, 0.2506243203287109, 1.2135163644116072},
                 {0.1618033988749897, 1.3090169943749470, 1.0135163644116070},
                 {-0.9003225837313085, 0.9639113427454318, 1.0135163644116070},
                 {-0.6385191848563186, 1.1541226460044625, 1.2135163644116072},
                 {-0.1618033988749896, 1.3090169943749470, 1.2135163644116072},
                 {1.2949491424413906, 0.2506243203287108, 1.0135163644116070},
                 {0.6385191848563185, 1.1541226460044625, 1.0135163644116070},
                 {0.9003225837313084, 0.9639113427454318, 1.2135163644116072},
                 {1.1949491424413905, 0.5583926740462364, 1.2135163644116072},
                 {0.6385191848563185, -1.1541226460044625, 1.0135163644116070},
                 {0.9003225837313084, -0.9639113427454318, 1.2135163644116072},
                 {1.2949491424413906, -0.2506243203287108, 1.0135163644116070},
                 {1.1949491424413905, -0.5583926740462364, 1.2135163644116072},
             }},
        };
    for (const auto& [polyhedron, topology, vertices] : polyhedra) {
        auto clipped = std::unique_ptr<ff::Polyhedron>(polyhedron->clipped(
            polyhedron->location().z() - 0.1, polyhedron->location().z() + 0.1));
        REQUIRE(topology == clipped->topology());
        for (size_t i = 0; i < vertices.size(); ++i) {
            INFO(clipped->vertices())
            REQUIRE((vertices[i] - clipped->vertices()[i]).mag() < 1E-13);
        }
    }
}

//! Test that the function throws when zMin > zMax

TEST_CASE("Clipped:Throws:InvalidInput:Gt", "[Polyhedron][clipped][topology]")
{
    std::vector<std::tuple<std::unique_ptr<ff::Polyhedron>&>> polyhedra{
        {cube}, {pyramid}, {octahedron}, {icosahedron}, {dodecahedron}};
    for (auto& [polyhedron] : polyhedra) {
        CHECK_THROWS(polyhedron->clipped(1, 0));
    }
}

//! Test that the function throws when zMin == zMax

TEST_CASE("Clipped:Throws:InvalidInput:Eq", "[Polyhedron][clipped][topology]")
{
    std::vector<std::tuple<std::unique_ptr<ff::Polyhedron>&>> polyhedra{
        {cube}, {pyramid}, {octahedron}, {icosahedron}, {dodecahedron}};
    for (auto& [polyhedron] : polyhedra) {
        CHECK_THROWS(polyhedron->clipped(1, 1));
    }
}