GCC Code Coverage Report


Directory: ./
File: lib/geogram/voronoi/generic_RVD_polygon.cpp
Date: 2026-09-07 02:36:43
Exec Total Coverage
Lines: 67 73 91.8%
Functions: 2 2 100.0%
Branches: 36 65 55.4%

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/voronoi/generic_RVD_polygon.h>
41 #include <geogram/numerics/predicates.h>
42 #include <algorithm>
43
44 namespace GEOGen {
45
46 433648 void Polygon::initialize_from_mesh_facet(
47 const Mesh* mesh, index_t facet, bool symbolic,
48 const GEO::Attribute<double>& vertex_weight
49 ) {
50 433648 clear();
51
2/2
✓ Branch 0 taken 121728 times.
✓ Branch 1 taken 311920 times.
433648 if(symbolic) {
52 // Copy facet
53 486912 for(index_t c = mesh->facets.corners_begin(facet);
54
2/2
✓ Branch 1 taken 365184 times.
✓ Branch 2 taken 121728 times.
486912 c < mesh->facets.corners_end(facet); c++
55 ) {
56 365184 index_t v = mesh->facet_corners.vertex(c);
57 365184 index_t adjacent_facet = mesh->facet_corners.adjacent_facet(c);
58
1/2
✓ Branch 1 taken 365184 times.
✗ Branch 2 not taken.
365184 Vertex* vx = add_vertex(
59 Vertex(
60 mesh->vertices.point_ptr(v),
61 vertex_weight.is_bound() ? vertex_weight[v] : 1.0,
62 signed_index_t(adjacent_facet)
63
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 365184 times.
✓ Branch 4 taken 365184 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 365184 times.
✗ Branch 8 not taken.
365184 )
64 );
65 365184 vx->sym().set_boundary_vertex(v);
66 }
67
68 // Initialize symbolic information
69
2/2
✓ Branch 1 taken 365184 times.
✓ Branch 2 taken 121728 times.
486912 for(index_t i1 = 0; i1 < nb_vertices(); i1++) {
70 365184 index_t i2 = next_vertex(i1);
71 365184 Vertex& v1 = vertex(i1);
72 365184 Vertex& v2 = vertex(i2);
73
74 // Note: Here we compute v2.sym()
75 // and we do not touch v1.sym()
76
77 365184 v2.sym().add_boundary_facet(facet);
78
2/2
✓ Branch 1 taken 362947 times.
✓ Branch 2 taken 2237 times.
365184 if(v1.adjacent_facet() >= 0) {
79 725894 v2.sym().add_boundary_facet(
80 362947 index_t(v1.adjacent_facet())
81 );
82 } else {
83 // "Virtual" boundary facet:
84 // indicates edge (i1,i2 = i1 \oplus 1)
85 // We no longer need them, except for
86 // indicating vertex sym. type.
87 4474 v2.sym().add_boundary_facet(
88 2237 mesh->facets.nb() + i1
89 );
90 }
91
92 // Note: we continue to compute v2.sym()
93 // and we do not touch v1.sym() (it looks
94 // like a copy-paste bug but it is correct !)
95
96
2/2
✓ Branch 1 taken 362947 times.
✓ Branch 2 taken 2237 times.
365184 if(v2.adjacent_facet() >= 0) {
97 725894 v2.sym().add_boundary_facet(
98 362947 index_t(v2.adjacent_facet())
99 );
100 } else {
101 // "Virtual" boundary facet:
102 // indicates edge (i1,i2 = i1 \oplus 1)
103 // We no longer need them, except for
104 // indicating vertex sym. type.
105 4474 v2.sym().add_boundary_facet(
106 2237 mesh->facets.nb() + i2
107 );
108 }
109 }
110 #ifdef GEO_DEBUG
111 // Sanity check: make sure that the facet is not
112 // adjacent to the same facet twice.
113 121728 index_t n = mesh->facets.nb_vertices(facet);
114 121728 signed_index_t* adj = (signed_index_t*) alloca(
115 sizeof(signed_index_t) * n
116 );
117 121728 GEO::Memory::clear(adj, sizeof(signed_index_t) * n);
118 121728 index_t i = 0;
119 121728 for(index_t c = mesh->facets.corners_begin(facet);
120
2/2
✓ Branch 1 taken 365184 times.
✓ Branch 2 taken 121728 times.
486912 c < mesh->facets.corners_end(facet); ++c
121 ) {
122 365184 adj[i] = signed_index_t(mesh->facet_corners.adjacent_facet(c));
123 365184 ++i;
124 }
125 121728 std::sort(adj, adj + n);
126
2/2
✓ Branch 0 taken 243456 times.
✓ Branch 1 taken 121728 times.
365184 for(i = 0; i < n - 1; ++i) {
127 // If this assertion fails, then the mesh probably has a degree2 vertex
128 // (use remove_degree2_vertices() in mesh_preprocessing.h)
129
3/8
✓ Branch 0 taken 241219 times.
✓ Branch 1 taken 2237 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 241219 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
243456 geo_debug_assert(
130 adj[i] == -1 || adj[i] != adj[i + 1]
131 );
132 }
133 #endif
134 } else {
135 // We are not in symbolic mode,
136 // we just gather the vertices, weights and adjacencies.
137 311920 for(index_t c = mesh->facets.corners_begin(facet);
138
2/2
✓ Branch 1 taken 935760 times.
✓ Branch 2 taken 311920 times.
1247680 c < mesh->facets.corners_end(facet); c++
139 ) {
140 935760 index_t v = mesh->facet_corners.vertex(c);
141 935760 index_t adjacent_facet = mesh->facet_corners.adjacent_facet(c);
142
1/2
✓ Branch 1 taken 935760 times.
✗ Branch 2 not taken.
935760 add_vertex(
143 935760 Vertex(
144 mesh->vertices.point_ptr(v),
145 vertex_weight.is_bound() ? vertex_weight[v] : 1.0,
146 signed_index_t(adjacent_facet)
147
3/6
✗ Branch 1 not taken.
✓ Branch 2 taken 935760 times.
✓ Branch 4 taken 935760 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 935760 times.
✗ Branch 8 not taken.
935760 )
148 );
149 }
150 }
151 433648 }
152
153 9590470 Sign Polygon::side_exact(
154 const Mesh* mesh, const Delaunay* delaunay,
155 const Vertex& q, const double* pi, const double* pj, coord_index_t dim
156 ) {
157
158
3/5
✗ Branch 2 not taken.
✓ Branch 3 taken 864336 times.
✓ Branch 4 taken 4906594 times.
✓ Branch 5 taken 3819540 times.
✗ Branch 6 not taken.
9590470 switch(q.sym().nb_boundary_facets()) {
159 case 0:
160 // All the points that we manipulate are supposed to
161 // belong to the restricted Voronoi diagram, therefore
162 // they belong to the surface, and are at least on one
163 // facet of the surface.
164 geo_assert_not_reached;
165
166 864336 case 1:
167 {
168 // The point q is the intersection between
169 // a facet (f0,f1,f2) of the surface and two
170 // bisectors [pi b0] and [pi b1].
171 864336 index_t b0 = q.sym().bisector(0);
172 864336 index_t b1 = q.sym().bisector(1);
173 864336 index_t f = q.sym().boundary_facet(0);
174
175 864336 index_t if0 = mesh->facets.vertex(f,0);
176 864336 index_t if1 = mesh->facets.vertex(f,1);
177 864336 index_t if2 = mesh->facets.vertex(f,2);
178 864336 const double* f0 = mesh->vertices.point_ptr(if0);
179 864336 const double* f1 = mesh->vertices.point_ptr(if1);
180 864336 const double* f2 = mesh->vertices.point_ptr(if2);
181 864336 return GEO::PCK::side3_SOS(
182 pi, delaunay->vertex_ptr(b0), delaunay->vertex_ptr(b1), pj,
183 f0, f1, f2, dim
184 864336 );
185 }
186
187 4906594 case 2:
188 {
189
190 // The point q is the intersection between
191 // two facets of the surface (i.e. an edge [e0 e1])
192 // and one bisector [pi b0].
193 // i.e. it's a vertex of the surface.
194
1/2
✓ Branch 2 taken 4906594 times.
✗ Branch 3 not taken.
4906594 index_t b0 = q.sym().bisector(0);
195 index_t e0, e1;
196
1/2
✓ Branch 2 taken 4906594 times.
✗ Branch 3 not taken.
4906594 q.sym().get_boundary_edge(e0, e1);
197
4/8
✓ Branch 1 taken 4906594 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4906594 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 4906594 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 4906594 times.
✗ Branch 11 not taken.
4906594 return GEO::PCK::side2_SOS(
198 pi, delaunay->vertex_ptr(b0), pj,
199 mesh->vertices.point_ptr(e0),
200 mesh->vertices.point_ptr(e1), dim
201 4906594 );
202 }
203
204 3819540 case 3:
205 {
206 // The point q is the intersection between
207 // three facets of the surface
208 // (i.e. a vertex v0 of the surface).
209 3819540 index_t v0 = q.sym().get_boundary_vertex();
210 3819540 return GEO::PCK::side1_SOS(
211 pi, pj, mesh->vertices.point_ptr(v0), dim
212 3819540 );
213 }
214 }
215 geo_assert_not_reached;
216 }
217 }
218