File: test_surface_mesh.cpp

package info (click to toggle)
slic3r-prusa 2.9.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 196,524 kB
  • sloc: cpp: 534,736; ansic: 71,269; yacc: 1,311; makefile: 256; lex: 241; sh: 113
file content (122 lines) | stat: -rw-r--r-- 3,617 bytes parent folder | download | duplicates (2)
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
#include <catch2/catch_test_macros.hpp>
#include <test_utils.hpp>


#include <libslic3r/SurfaceMesh.hpp>

using namespace Slic3r;


// Generate a broken cube mesh. Face 8 is inverted, face 11 is missing.
indexed_triangle_set its_make_cube_broken(double xd, double yd, double zd)
{
    auto x = float(xd), y = float(yd), z = float(zd);
    return {
        { {0, 1, 2}, {0, 2, 3}, {4, 5, 6}, {4, 6, 7},
          {0, 4, 7}, {0, 7, 1}, {1, 7, 6}, {1, 6, 2},
          {2, 5, 6}, {2, 5, 3}, {4, 0, 3}  /*missing face*/ },
        { {x, y, 0}, {x, 0, 0}, {0, 0, 0}, {0, y, 0},
          {x, y, z}, {0, y, z}, {0, 0, z}, {x, 0, z} }
    };
}



TEST_CASE("SurfaceMesh on a cube", "[SurfaceMesh]") {
    indexed_triangle_set cube = its_make_cube(1., 1., 1.);
    SurfaceMesh sm(cube);
    const Halfedge_index hi_first = sm.halfedge(Face_index(0));
    Halfedge_index hi = hi_first;

    REQUIRE(! hi_first.is_invalid());
    
    SECTION("next / prev halfedge") {
        hi = sm.next(hi);
        REQUIRE(hi != hi_first);
        hi = sm.next(hi);
        hi = sm.next(hi);
        REQUIRE(hi == hi_first);
        hi = sm.prev(hi);
        REQUIRE(hi != hi_first);
        hi = sm.prev(hi);
        hi = sm.prev(hi);
        REQUIRE(hi == hi_first);
    }

    SECTION("next_around_target") {
        // Check that we get to the same halfedge after applying next_around_target
        // four times.
        const Vertex_index target_vert = sm.target(hi_first);
        for (int i=0; i<4;++i) {
            hi = sm.next_around_target(hi);
            REQUIRE((hi == hi_first) == (i == 3));
            REQUIRE(sm.is_same_vertex(sm.target(hi), target_vert));
            REQUIRE(! sm.is_border(hi));
        }
    }

    SECTION("iterate around target and source") {
        hi = sm.next_around_target(hi);
        hi = sm.prev_around_target(hi);
        hi = sm.prev_around_source(hi);
        hi = sm.next_around_source(hi);
        REQUIRE(hi == hi_first);
    }

    SECTION("opposite") {
        const Vertex_index target = sm.target(hi);
        const Vertex_index source = sm.source(hi);
        hi = sm.opposite(hi);
        REQUIRE(sm.is_same_vertex(target, sm.source(hi)));
        REQUIRE(sm.is_same_vertex(source, sm.target(hi)));
        hi = sm.opposite(hi);
        REQUIRE(hi == hi_first);
    }

    SECTION("halfedges walk") {
        for (int i=0; i<4; ++i) {
            hi = sm.next(hi);
            hi = sm.opposite(hi);
        }
        REQUIRE(hi == hi_first);
    }

    SECTION("point accessor") {
        Halfedge_index hi = sm.halfedge(Face_index(0));
        hi = sm.opposite(hi);
        hi = sm.prev(hi);
        hi = sm.opposite(hi);
        REQUIRE(hi.face() == Face_index(6));
        REQUIRE(sm.point(sm.target(hi)).isApprox(cube.vertices[7])); 
    }
}




TEST_CASE("SurfaceMesh on a broken cube", "[SurfaceMesh]") {
    indexed_triangle_set cube = its_make_cube_broken(1., 1., 1.);
    SurfaceMesh sm(cube);
    
    SECTION("Check inverted face") {
        Halfedge_index hi = sm.halfedge(Face_index(8));
        for (int i=0; i<3; ++i) {
            REQUIRE(! hi.is_invalid());
            REQUIRE(sm.is_border(hi));
        }
        REQUIRE(hi == sm.halfedge(Face_index(8)));
        hi = sm.opposite(hi);
        REQUIRE(hi.is_invalid());
    }

    SECTION("missing face") {
        Halfedge_index hi = sm.halfedge(Face_index(0));
        for (int i=0; i<3; ++i)
            hi = sm.next_around_source(hi);
        hi = sm.next(hi);
        REQUIRE(sm.is_border(hi));
        REQUIRE(! hi.is_invalid());
        hi = sm.opposite(hi);
        REQUIRE(hi.is_invalid());
    }
}