GCC Code Coverage Report


Directory: ./
File: lib/geogram/mesh/mesh_frame_field.h
Date: 2026-09-07 02:36:43
Exec Total Coverage
Lines: 0 16 0.0%
Functions: 0 5 0.0%
Branches: 0 14 0.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_MESH_MESH_FRAME_FIELD
41 #define GEOGRAM_MESH_MESH_FRAME_FIELD
42
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/geometry.h>
45 #include <geogram/points/nn_search.h>
46
47 /**
48 * \file mesh_frame_field.h
49 */
50
51 namespace GEO {
52
53 class Mesh;
54
55 /**
56 * \brief Represents a 3D frame field, i.e. a function that
57 * associates a 3d orthonormal basis to each point in 3D space.
58 */
59 class GEOGRAM_API FrameField {
60 public:
61 /**
62 * \brief Constructs a new uninitialized FrameField.
63 */
64 FrameField() : use_NN_(true) {
65 }
66
67 /**
68 * \brief Specifies whether a spatial search structure
69 * should be created.
70 * \details If a spatial search structure is created, then
71 * the field can be queried at any 3D location using
72 * get_nearest_frame() / get_nearest_frame_index(),
73 * this is the default mode. Otherwise, get_nearest_frame()
74 * and get_nearest_frame_index() cannot be used.
75 * \param[in] x true if spatial search should be used, false
76 * otherwise.
77 */
78 void set_use_spatial_search(bool x) {
79 use_NN_ = x;
80 }
81
82 /**
83 * \brief Loads a frame field from a file.
84 * \param[in] M a tetrahedral mesh
85 * \param[in] filename name of the file that contains the
86 * frame vectors
87 * \param[in] volumetric if true, the frames are attached
88 * to the tets of \p M, else they are attached to the facets
89 * \details The file is supposed to be ASCII, with one vector
90 * per line. Alternatively, the frames can be attached to
91 * specified points. In this case, \p volumetric is ignored, and
92 * the file has 12 scalars per line, that correspond to the
93 * coordinates of a point and the three vectors attached to the point.
94 * \retval true on success
95 * \retval false otherwise
96 */
97 bool load(
98 const Mesh& M, bool volumetric, const std::string& filename
99 );
100
101
102 /**
103 * \brief Creates a frame field that matches a given mesh.
104 * \details The frames are interpolated from the sharp features
105 * of the mesh.
106 * \param[in] M the input mesh
107 * \param[in] volumetric if true, the frame field is extrapolated
108 * to the tetrahedra of the mesh (using nearest neighbors for now)
109 * \param[in] sharp_angle_threshold angles smaller than this threshold
110 * (in degrees) are considered to be sharp features
111 */
112 void create_from_surface_mesh(
113 const Mesh& M, bool volumetric, double sharp_angle_threshold=45.0
114 );
115
116 /**
117 * \brief Gets the index of the frame nearest to a given point.
118 * \details Cannot be used if set_use_spatial_search(false) was
119 * called.
120 * \param[in] p the 3d coordinates of the point
121 * \return the index of the frame nearest to \p p
122 */
123 index_t get_nearest_frame_index(const double* p) const {
124 geo_assert(use_NN_);
125 return NN_->get_nearest_neighbor(p);
126 }
127
128 /**
129 * \brief Gets the frame nearest to a given point.
130 * \details Cannot be used if set_use_spatial_search(false) was
131 * called.
132 * \param[in] p the 3d coordinates of the point
133 * \param[out] f the 9 coordinates of the three
134 * vectors that compose the fram
135 */
136 void get_nearest_frame(const double* p, double* f) const {
137 geo_assert(use_NN_);
138 index_t fi = get_nearest_frame_index(p);
139 for(index_t c = 0; c < 9; ++c) {
140 f[c] = frames_[fi * 9 + c];
141 }
142 }
143
144 /**
145 * \brief Gets the vector that contains all the frames
146 * coordinates.
147 * \return a const reference to the vector of all the
148 * frame coordinates.
149 */
150 const vector<double>& frames() const {
151 return frames_;
152 }
153
154 /*
155 * \brief Scales one of the vectors of a frame.
156 * \details On exit, the norm of the vector nearest to \p N in
157 * \p frame has a norm equal to \p s.
158 * \param[in,out] frame the frame, as an array of 9 doubles
159 * \param[in] N the vector to be scaled (retrieved in the frame)
160 * \param[in] s scaling factor
161 */
162 static void scale_frame_vector(double* frame, const vec3& N, double s);
163
164 /**
165 * \brief Fixes a frame in such a way that it is orthogonal
166 * to a given vector.
167 * \details Makes one of the frame vectors aligned with \p N
168 * and the two other ones orthogonal to N.
169 * \param[in,out] frame the frame to fix
170 * \param[in] N the normal vector to be preserved
171 */
172 static void fix_frame(double* frame, const vec3& N);
173
174 private:
175 NearestNeighborSearch_var NN_;
176 vector<double> frames_;
177 vector<double> centers_;
178 bool use_NN_;
179 };
180
181
182 }
183
184 #endif
185