GCC Code Coverage Report


Directory: ./
File: lib/geogram/mesh/mesh_compare.cpp
Date: 2026-09-07 02:28:19
Exec Total Coverage
Lines: 21 55 38.2%
Functions: 1 2 50.0%
Branches: 27 94 28.7%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #include <geogram/mesh/mesh_compare.h>
41 #include <geogram/mesh/mesh.h>
42 #include <geogram/mesh/mesh_topology.h>
43 #include <geogram/mesh/mesh_geometry.h>
44 #include <geogram/basic/logger.h>
45
46 namespace {
47
48 using namespace GEO;
49
50 /**
51 * \brief Computes the number of facet borders
52 */
53 index_t mesh_nb_facet_borders(const Mesh& M) {
54 index_t nb_borders = 0;
55
4/4
✓ Branch 0 taken 420 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 420 times.
✓ Branch 3 taken 7 times.
854 for(index_t i: M.facet_corners) {
56
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 420 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 420 times.
840 if(M.facet_corners.adjacent_facet(i) == NO_FACET) {
57 nb_borders++;
58 }
59 }
60 return nb_borders;
61 }
62
63 /**
64 * \brief Computes the number of tet borders
65 */
66 index_t mesh_nb_cell_borders(const Mesh& M) {
67 index_t nb_borders = 0;
68 for(index_t c: M.cells) {
69 for(index_t lf = 0; lf < M.cells.nb_facets(c); ++lf) {
70 if(M.cells.adjacent(c, lf) == NO_CELL) {
71 nb_borders++;
72 }
73 }
74 }
75 return nb_borders;
76 }
77 }
78
79 namespace GEO {
80
81 7 MeshCompareFlags mesh_compare(
82 const Mesh& M1, const Mesh& M2,
83 MeshCompareFlags flags,
84 double tolerance,
85 bool verbose
86 ) {
87
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if(verbose) {
88
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 M1.show_stats("Mesh1");
89
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 M2.show_stats("Mesh2");
90 }
91
92
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 Logger::out("Compare")
93 << "Using floating point tolerance = " << tolerance
94 << std::endl;
95
96 int status = MESH_COMPARE_OK;
97
98 if(
99
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
14 (flags & MESH_COMPARE_DIMENSIONS) &&
100 M1.vertices.dimension() != M2.vertices.dimension()
101 ) {
102 if(verbose) {
103 Logger::err("Compare")
104 << "Dimensions differ"
105 << std::endl;
106 }
107 status |= MESH_COMPARE_DIMENSIONS;
108 }
109
110 if(
111
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 (flags & MESH_COMPARE_NB_VERTICES) &&
112 M1.vertices.nb() != M2.vertices.nb()
113 ) {
114 if(verbose) {
115 Logger::err("Compare")
116 << "Numbers of vertices differ"
117 << std::endl;
118 }
119 status |= MESH_COMPARE_NB_VERTICES;
120 }
121
122 if(
123
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 (flags & MESH_COMPARE_NB_FACETS) &&
124 M1.facets.nb() != M2.facets.nb()
125 ) {
126 if(verbose) {
127 Logger::err("Compare")
128 << "Numbers of facets differ"
129 << std::endl;
130 }
131 status |= MESH_COMPARE_NB_FACETS;
132 }
133
134 if(
135
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
14 (flags & MESH_COMPARE_NB_FACET_BORDERS) &&
136 mesh_nb_facet_borders(M1) != mesh_nb_facet_borders(M2)
137 ) {
138 if(verbose) {
139 Logger::err("Compare")
140 << "Numbers of facet borders differ"
141 << std::endl;
142 }
143 status |= MESH_COMPARE_NB_FACET_BORDERS;
144 }
145
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if(flags & MESH_COMPARE_AREAS) {
147 double M1_area = Geom::mesh_area(M1);
148 double M2_area = Geom::mesh_area(M2);
149
150
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if(verbose) {
151
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 Logger::out("Mesh1") << "area:" << M1_area << std::endl;
152
1/2
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 Logger::out("Mesh2") << "area:" << M2_area << std::endl;
153 }
154
155
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if(std::abs(M2_area - M1_area) > tolerance * M1_area) {
156 if(verbose) {
157 Logger::err("Compare")
158 << "Areas differ"
159 << std::endl;
160 }
161 status |= MESH_COMPARE_AREAS;
162 }
163 }
164
165 if(
166
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
14 (flags & MESH_COMPARE_TOPOLOGY) &&
167 7 !meshes_have_same_topology(M1, M2, verbose)
168 ) {
169 status |= MESH_COMPARE_TOPOLOGY;
170 }
171
172 if(
173
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
7 (flags & MESH_COMPARE_NB_TETS) &&
174 M1.cells.nb() != M2.cells.nb()
175 ) {
176 if(verbose) {
177 Logger::err("Compare")
178 << "Numbers of cells differ"
179 << std::endl;
180 }
181 status |= MESH_COMPARE_NB_TETS;
182 }
183
184
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if(flags & MESH_COMPARE_NB_TET_BORDERS) {
185 index_t M1_nb_tet_borders = mesh_nb_cell_borders(M1);
186 index_t M2_nb_tet_borders = mesh_nb_cell_borders(M2);
187
188 if(verbose) {
189 Logger::out("Mesh1")
190 << "nb_cell_borders:" << M1_nb_tet_borders
191 << std::endl;
192 Logger::out("Mesh2")
193 << "nb_cell_borders:" << M2_nb_tet_borders
194 << std::endl;
195 }
196
197 if(M1_nb_tet_borders != M2_nb_tet_borders) {
198 if(verbose) {
199 Logger::err("Compare")
200 << "Numbers of tet borders differ"
201 << std::endl;
202 }
203 status |= MESH_COMPARE_NB_TET_BORDERS;
204 }
205 }
206
207 7 return MeshCompareFlags(status);
208 }
209 }
210