GCC Code Coverage Report


Directory: ./
File: lib/geogram/voronoi/RVD_mesh_builder.h
Date: 2026-09-07 02:28:19
Exec Total Coverage
Lines: 36 36 100.0%
Functions: 4 4 100.0%
Branches: 15 20 75.0%

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 #ifndef GEOGRAM_VORONOI_RVD_MESH_BUILDER
41 #define GEOGRAM_VORONOI_RVD_MESH_BUILDER
42
43 #include <geogram/basic/common.h>
44 #include <geogram/voronoi/generic_RVD.h>
45 #include <geogram/mesh/mesh.h>
46 #include <geogram/mesh/index.h>
47 #include <geogram/basic/attributes.h>
48 #include <geogram/basic/argused.h>
49
50 #include <vector>
51 #include <map>
52
53 /**
54 * \file geogram/voronoi/RVD_mesh_builder.h
55 * \brief Utilities to build meshes derived from restricted Voronoi diagrams.
56 * \note This file contains functions and classes used by the internal
57 * implementation of GEO::GenericVoronoiDiagram.
58 * They are not meant to be used directly by client code.
59 */
60
61 namespace GEO {
62
63 /**
64 * \brief RVDVertexMap maps symbolic vertices to unique ids.
65 * \details Symbolic vertices are manipulated by
66 * GEOGen::RestrictedVoronoiDiagram. This class is
67 * used for instance in the implementation of
68 * RVDMeshBuilder.
69 * \note This is an internal implementation class, not meant to
70 * be used directly, use GEO::RestrictedVoronoiDiagram instead.
71 */
72 class GEOGRAM_API RVDVertexMap {
73 public:
74 /**
75 * \brief Constructs an empty map
76 */
77 RVDVertexMap();
78
79 /**
80 * \brief Maps the symbolic information of a vertex
81 * into a unique identifier.
82 * \param[in] center_vertex_id the index of the current Voronoi
83 * seed (provided by action classes in
84 * GEOGen::RestrictedVoronoiDiagram)
85 * \param[in] sym the symbolic representation of the vertex
86 * (provided by action classes in
87 * GEOGen::RestrictedVoronoiDiagram)
88 * \return a unique identifier for this vertex
89 */
90 index_t find_or_create_vertex(
91 index_t center_vertex_id, const SymbolicVertex& sym
92 );
93
94 /**
95 * \brief Defines the index of the first created vertex.
96 * \param[in] i index of the first vertex that will be created
97 * (default is 0).
98 */
99 void set_first_vertex_index(index_t i) {
100 1261 nb_vertices_ = i;
101 }
102
103 protected:
104 /**
105 * \brief Allocates a new vertex.
106 */
107 index_t new_vertex() {
108 290770 index_t result = nb_vertices_;
109 290770 nb_vertices_++;
110 return result;
111 }
112
113 /**
114 * \brief Gets the number of bisectors represented
115 * in a symbolic vertex.
116 */
117 index_t nb_bisectors(const signed_trindex& sym) const {
118 index_t result = 0;
119 for(index_t i = 0; i < 3; i++) {
120 if(sym.indices[i] >= 0) {
121 result++;
122 }
123 }
124 return result;
125 }
126
127 private:
128 // Maps (+++)-center vertex id quadruples to unique vertex id
129 // +++ encodes a Voronoi vertex
130 std::map<quadindex, index_t> ppp_to_id_;
131
132 // Maps (++-)-center vertex id quadruples to unique vertex id
133 // ++- encodes the intersection between a Voronoi edge (++) and
134 // a facet of the boundary (-).
135 std::map<signed_quadindex, index_t> ppm_to_id_;
136
137 // Maps (+--)-center vertex id quadruples to unique vertex id
138 // +-- encodes the intersection between a Voronoi facet (+) and
139 // an edge of the boundary (--).
140 std::map<signed_quadindex, index_t> pmm_to_id_;
141
142 // Maps boundary vertex index to unique vertex id.
143 vector<signed_index_t> bv_to_id_;
144 index_t nb_vertices_;
145 };
146
147 /************************************************************************/
148
149 /**
150 * \brief Builds a Mesh using the symbolic information
151 * in the vertices computed by a RestrictedVoronoiDiagram.
152 * \details The vertices with the same symbolic information are
153 * merged.
154 * \note This is an internal implementation class, not meant to
155 * be used directly, use GEO::RestrictedVoronoiDiagram instead.
156 */
157 class RVDMeshBuilder {
158 public:
159 /**
160 * \brief Constructs a new RVDMeshBuilder
161 * \param[out] target where to build the mesh
162 * that represents the Restricted Voronoi Diagram
163 * \param[in] reference the input mesh
164 */
165 36 RVDMeshBuilder(
166 Mesh* target, Mesh* reference,
167 Delaunay*
168 36 ) :
169
1/2
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
36 target_(target),
170
2/4
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
36 nb_vertices_(0)
171 {
172 36 dim_ = coord_index_t(reference->vertices.dimension());
173 36 current_seed_ = max_index_t();
174 36 }
175
176 /**
177 * \brief Starts to build a new surface.
178 */
179 36 void begin_surface() {
180 36 target_->clear();
181 36 target_->vertices.set_dimension(dim_);
182
1/2
✓ Branch 2 taken 36 times.
✗ Branch 3 not taken.
36 facet_region_.bind(target_->facets.attributes(),"region");
183 36 }
184
185 /**
186 * \brief Starts a new reference facet.
187 * \details Does nothing in this implementation
188 * that does not use the reference facet index.
189 * \param[in] ref_facet index of the reference facet (unused)
190 */
191 void begin_reference_facet(index_t ref_facet) {
192 geo_argused(ref_facet);
193 60502 }
194
195 /**
196 * \brief Starts a new facet of the restricted
197 * Voronoi diagram.
198 * \param[in] seed the Voronoi seed that
199 * corresponds to the new facet.
200 */
201 void begin_facet(index_t seed) {
202 210409 current_seed_ = seed;
203 210409 facet_vertices_.resize(0);
204 }
205
206 /**
207 * \brief Adds a vertex to the current facet.
208 * \param[in] point coordinates of the vertex
209 * \param[in] sym symbolic representation of the vertex
210 */
211 841011 void add_vertex_to_facet(
212 const double* point, const SymbolicVertex& sym
213 ) {
214 841011 index_t id = vertex_map_.find_or_create_vertex(
215 current_seed_, sym
216 841011 );
217
2/2
✓ Branch 0 taken 213296 times.
✓ Branch 1 taken 627715 times.
841011 if(id >= nb_vertices_) {
218 213296 index_t v = target_->vertices.create_vertex();
219
2/2
✓ Branch 0 taken 639888 times.
✓ Branch 1 taken 213296 times.
853184 for(index_t c=0; c<dim_; ++c) {
220 639888 target_->vertices.point_ptr(v)[c] = point[c];
221 }
222 213296 nb_vertices_ = id + 1;
223 }
224
2/2
✓ Branch 0 taken 840868 times.
✓ Branch 1 taken 143 times.
841011 facet_vertices_.push_back(id);
225 841011 }
226
227 /**
228 * \brief Terminates the current facet.
229 * \note The reference facet information is
230 * not used by this implementation.
231 */
232 210409 void end_facet() {
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 210409 times.
210409 index_t f = target_->facets.create_polygon(facet_vertices_.size());
234
2/2
✓ Branch 0 taken 841011 times.
✓ Branch 1 taken 210409 times.
2102840 for(index_t lv=0; lv<facet_vertices_.size(); ++lv) {
235
2/2
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 840948 times.
841011 target_->facets.set_vertex(f,lv,facet_vertices_[lv]);
236 }
237 210409 facet_region_[f] = current_seed_;
238 210409 }
239
240 /**
241 * \brief Terminates the current reference facet.
242 * \details Does nothing in this implementation.
243 */
244 void end_reference_facet() {
245 }
246
247 /**
248 * \brief Terminates the current surface.
249 */
250 void end_surface() {
251 36 target_->facets.connect();
252 36 facet_region_.unbind();
253 }
254
255 /**
256 * \brief Specifies the dimension to be used.
257 * \details Not implemented yet, uses the dimension
258 * of the RestrictedVoronoiDiagram.
259 */
260 void set_dimension(coord_index_t x) {
261 geo_argused(x);
262 // TODO - Not implemented yet
263 }
264
265 private:
266 Mesh* target_;
267 Attribute<index_t> facet_region_;
268 RVDVertexMap vertex_map_;
269 coord_index_t dim_;
270 index_t current_seed_;
271 index_t nb_vertices_;
272 vector<index_t> facet_vertices_;
273 };
274
275 /************************************************************************/
276 }
277
278 #endif
279