GCC Code Coverage Report


Directory: ./
File: lib/geogram/delaunay/delaunay_nn.cpp
Date: 2026-09-07 02:36:43
Exec Total Coverage
Lines: 52 56 92.9%
Functions: 7 8 87.5%
Branches: 23 46 50.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 #include <geogram/delaunay/delaunay_nn.h>
41
42 namespace GEO {
43
44 66 Delaunay_NearestNeighbors::Delaunay_NearestNeighbors(
45 coord_index_t dimension
46 66 ) :
47 66 Delaunay(dimension) {
48
1/2
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
66 set_thread_safe(true);
49 66 set_default_nb_neighbors(20);
50
1/2
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
66 set_stores_neighbors(true);
51
2/4
✓ Branch 1 taken 66 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 66 times.
✗ Branch 5 not taken.
66 NN_ = NearestNeighborSearch::create(dimension);
52 66 }
53
54 264 Delaunay_NearestNeighbors::~Delaunay_NearestNeighbors() {
55 264 }
56
57 25797 void Delaunay_NearestNeighbors::enlarge_neighborhood(
58 index_t v, index_t nb
59 ) {
60 25797 neighbors_.lock_array(v);
61
2/2
✓ Branch 1 taken 25701 times.
✓ Branch 2 taken 96 times.
25797 if(nb > neighbors_.array_size(v)) {
62 // Allocated on the stack (more thread-friendly and no need
63 // to deallocate)
64 25701 index_t* neighbors = (index_t*) alloca(
65 sizeof(index_t) * nb
66 );
67 25701 nb = get_neighbors_internal(v, nb, neighbors);
68 25701 neighbors_.set_array(v, nb, neighbors, false);
69 }
70 25797 neighbors_.unlock_array(v);
71 25797 }
72
73 1315881 void Delaunay_NearestNeighbors::store_neighbors_CB(index_t v) {
74 // No need to lock/unlock array here, since we are
75 // sure that each array is accessed by a single thread.
76
1/2
✓ Branch 1 taken 1315881 times.
✗ Branch 2 not taken.
1315881 index_t nb = neighbors_.array_size(v);
77 1315881 nb = std::min(nb, nb_vertices() - 1);
78 // Allocated on the stack (more thread-friendly and no need
79 // to deallocate)
80 1315881 index_t* neighbors = (index_t*) alloca(
81 sizeof(index_t) * nb
82 );
83
1/2
✓ Branch 1 taken 1315881 times.
✗ Branch 2 not taken.
1315881 nb = get_neighbors_internal(v, nb, neighbors);
84
1/2
✓ Branch 1 taken 1315881 times.
✗ Branch 2 not taken.
1315881 neighbors_.set_array(v, nb, neighbors, false);
85
2/8
✓ Branch 1 taken 1315881 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 1315881 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
1315881 geo_debug_assert(neighbors_.array_size(v) == nb);
86 1315881 }
87
88 void Delaunay_NearestNeighbors::get_neighbors_internal(
89 index_t v, vector<index_t>& neighbors
90 ) const {
91 index_t nb = get_neighbors_internal(
92 v, neighbors.size(), neighbors.data()
93 );
94 neighbors.resize(nb);
95 }
96
97 461 void Delaunay_NearestNeighbors::set_vertices(
98 index_t nb_vertices, const double* vertices
99 ) {
100 461 Delaunay::set_vertices(nb_vertices, vertices);
101 461 NN_->set_points(nb_vertices, vertices);
102 461 update_neighbors();
103 461 }
104
105 1341582 index_t Delaunay_NearestNeighbors::get_neighbors_internal(
106 index_t i, index_t nb_neigh, index_t* neighbors
107 ) const {
108 1341582 nb_neigh++;
109 1341582 nb_neigh = std::min(nb_neigh, nb_vertices());
110
111 // Allocated on the stack (more multithread-friendly
112 // and no need to free)
113 1341582 index_t* closest_pt_ix = (index_t*) alloca(sizeof(index_t) * nb_neigh);
114 1341582 double* closest_pt_dist = (double*) alloca(sizeof(double) * nb_neigh);
115 1341582 NN_->get_nearest_neighbors(
116 nb_neigh, i, closest_pt_ix, closest_pt_dist
117 );
118
119 1341582 index_t nb_neigh_result = 0;
120
2/2
✓ Branch 0 taken 28853059 times.
✓ Branch 1 taken 86 times.
28853145 for(index_t j = 0; j < nb_neigh; j++) {
121
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 28853059 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
28853059 geo_debug_assert(signed_index_t(closest_pt_ix[j]) >= 0);
122
2/2
✓ Branch 0 taken 27511537 times.
✓ Branch 1 taken 1341522 times.
28853059 if(closest_pt_ix[j] != i) {
123 // Check for duplicated points
124
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 27511351 times.
27511537 if(closest_pt_dist[j] == 0.0) {
125 // If i is not the first one (in the
126 // duplicated points), then we 'disconnect' it
127 // (no neighbor !)
128
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 186 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
186 geo_debug_assert(signed_index_t(closest_pt_ix[j]) >= 0);
129
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 94 times.
186 if(closest_pt_ix[j] < i) {
130 92 return 0;
131 }
132 // Else, i is the first one, and we simply
133 // skip (do not store) the connection with
134 // closest_pt_ix[j].
135 } else {
136 27511351 neighbors[nb_neigh_result] = closest_pt_ix[j];
137 27511351 nb_neigh_result++;
138
2/2
✓ Branch 0 taken 1341404 times.
✓ Branch 1 taken 26169947 times.
27511351 if(nb_neigh_result == nb_neigh - 1) {
139 1341404 break;
140 }
141 }
142 }
143 }
144 1341490 return nb_neigh_result;
145 }
146
147 1820 index_t Delaunay_NearestNeighbors::nearest_vertex(const double* p) const {
148 1820 return NN_->get_nearest_neighbor(p);
149 }
150
151 /************************************************************************/
152 }
153