GCC Code Coverage Report


Directory: ./
File: lib/geogram/mesh/mesh_io.h
Date: 2026-09-07 02:37:58
Exec Total Coverage
Lines: 22 28 78.6%
Functions: 9 11 81.8%
Branches: 4 8 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 #ifndef GEOGRAM_MESH_NEW_MESH_IO
41 #define GEOGRAM_MESH_NEW_MESH_IO
42
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/numeric.h>
45 #include <geogram/basic/factory.h>
46 #include <geogram/basic/attributes.h>
47 #include <geogram/mesh/mesh.h>
48 #include <string>
49
50 /**
51 * \file geogram/mesh/mesh_io.h
52 * \brief Functions to load and save meshes
53 */
54
55 namespace GEO {
56
57 class InputGeoFile;
58 class OutputGeoFile;
59
60 /**
61 * \brief Indicates the attributes stored in a mesh and attached
62 * to the mesh elements (vertices, facets or volumes).
63 * \details The set of attributes attached to a mesh is represented
64 * by a bitwise or combination of the constants.
65 */
66 enum MeshAttributesFlags {
67 MESH_NO_ATTRIBUTES = 0,
68 MESH_VERTEX_REGION = 1,
69 MESH_VERTEX_TEX_COORD = 2,
70 MESH_VERTEX_COLOR = 4,
71 MESH_FACET_REGION = 8,
72 MESH_CELL_REGION = 16,
73 MESH_EDGE_REGION = 32,
74 MESH_ALL_ATTRIBUTES = 255
75 };
76
77
78 /**
79 * \brief Mesh load/save flags
80 * \details Represents the optional attributes of a Mesh that can be
81 * loaded and stored in a file.
82 */
83 class GEOGRAM_API MeshIOFlags {
84 public:
85 /**
86 * \brief Constructs a new MeshIOFlags with default attributes.
87 */
88 MeshIOFlags();
89
90 /**
91 * \brief Gets the dimension of the mesh (number of coordinates of
92 * the vertices).
93 * \return the dimension of the mesh
94 * (i.e. number of coordinates of the verfices).
95 */
96 coord_index_t dimension() const {
97 return dimension_;
98 }
99
100 /**
101 * \brief Sets the dimension of the mesh (number of coordinates
102 * of the vertices).
103 * \param[in] x the dimension of the mesh
104 */
105 void set_dimension(coord_index_t x) {
106 dimension_ = x;
107 }
108
109 /**
110 * \brief Gets the attributes that should be loaded or saved.
111 * \return a set of MeshAttributesFlags combined with bitwise or
112 */
113 MeshAttributesFlags attributes() const {
114 return attributes_;
115 }
116
117 /**
118 * \brief Sets the attributes that should be loaded or stored.
119 * \param[in] x a set of MeshAttribute%s combined with bitwise or
120 */
121 30 void set_attributes(MeshAttributesFlags x) {
122 30 attributes_ = x;
123 30 }
124
125 /**
126 * \brief Sets a mesh attribute.
127 * \details Indicates that \p x should be loaded or stored.
128 * \param[in] x the attribute that should be set
129 */
130 72 void set_attribute(MeshAttributesFlags x) {
131 72 attributes_ = MeshAttributesFlags(attributes_ | x);
132 72 }
133
134 /**
135 * \brief Resets a mesh attribute..
136 * \details Indicates that \p x should not be loaded nor stored.
137 * \param[in] x the attribute that should be reset
138 */
139 void reset_attribute(MeshAttributesFlags& x) {
140 attributes_ = MeshAttributesFlags(attributes_ & ~x);
141 }
142
143 /**
144 * \brief Tests whether a mesh attribute is set.
145 * \details If set, this means that the mesh attribute \p x will
146 * be loaded or stored.
147 * \param[in] x the attribute to test
148 * \retval true if attribute \p x is se
149 * \retval false otherwise
150 */
151 1388 bool has_attribute(MeshAttributesFlags x) const {
152 1388 return (attributes_ & x) != 0;
153 }
154
155 /**
156 * \brief Gets the set of mesh elements that should be loaded or stored.
157 * \return a set of MeshElement%s combined with bitwise or
158 */
159 MeshElementsFlags elements() const {
160 return elements_;
161 }
162
163 /**
164 * \brief Sets the set of mesh elements that should be loaded or stored.
165 * \param[in] x a set of MeshElementsFlags combined with bitwise or
166 */
167 void set_elements(MeshElementsFlags x) {
168 elements_ = x;
169 }
170
171 /**
172 * \brief Sets a mesh element.
173 * \details Indicates that mesh elements \p x should be loaded or
174 * stored.
175 * \param[in] x the element to set
176 */
177 55 void set_element(MeshElementsFlags x) {
178 55 elements_ = MeshElementsFlags(elements_ | x);
179 55 }
180
181 /**
182 * \brief Resets a mesh element.
183 * \details Indicates that mesh elements \p x should not be
184 * loaded nor stored.
185 * \param[in] x the element to reset
186 */
187 18 void reset_element(MeshElementsFlags x) {
188 18 elements_ = MeshElementsFlags(elements_ & ~x);
189 18 }
190
191 /**
192 * \brief Tests whether a mesh element is set.
193 * \details If set, this means that the mesh elements \p x will
194 * be loaded or stored.
195 * \param[in] x the element to test
196 * \retval true if element \p x is set
197 * \retval false otherwise
198 */
199 460948 bool has_element(MeshElementsFlags x) const {
200 460948 return (elements_ & x) != 0;
201 }
202
203 /**
204 * \brief Sets the name of the texture image file
205 * associated with this mesh.
206 * \details Used by the OBJ file format. If present
207 * generates a material lib.
208 * \param[in] x the name of the file with the texture.
209 */
210 void set_texture_filename(const std::string& x) {
211 texture_filename_ = x;
212 }
213
214 /**
215 * \brief Gets the name of the texture image file.
216 * \return the name of the file.
217 * \see set_texture_filename()
218 */
219 59 const std::string& get_texture_filename() const {
220 59 return texture_filename_;
221 }
222
223 /**
224 * \brief Sets verbosity
225 * \details Error messages are always displayed, whatever the verbosity
226 * level.
227 * \param[in] x true if messages should be displayed, false otherwise.
228 * Default is true.
229 */
230 void set_verbose(bool x) {
231 verbose_ = x;
232 }
233
234 /**
235 * \brief Tests whether messages should be displayed.
236 * \details Error messages are always displayed, whatever the verbosity
237 * level.
238 * \retval true if messages are displayed
239 * \retval false otherwise
240 * \see set_verbose()
241 */
242 674 bool verbose() const {
243 674 return verbose_;
244 }
245
246 private:
247 coord_index_t dimension_;
248 MeshAttributesFlags attributes_;
249 MeshElementsFlags elements_;
250 std::string texture_filename_;
251 bool verbose_;
252 };
253
254
255 /**
256 * \brief Loads a mesh from a file.
257 * \details
258 * Loads the contents of the mesh file \p filename and stores the
259 * resulting mesh to \p M. The file format is determined by the \p
260 * filename's extension, which determines the appropriate
261 * MeshIOHandler to use to read the file.
262 * \param[in] filename name of the file to be loaded with optional path
263 * \param[out] M the loaded mesh
264 * \param[in] ioflags specifies which attributes and
265 * elements should be loaded
266 * \return true on success, false otherwise.
267 * \see MeshIOHandler
268 */
269 bool GEOGRAM_API mesh_load(
270 const std::string& filename, Mesh& M,
271 const MeshIOFlags& ioflags = MeshIOFlags()
272 );
273
274 /**
275 * \brief Loads a mesh from a GeoFile ('.geogram' file format).
276 * \details
277 * Loads the contents of the InputGeoFile \p geofile and stores the
278 * resulting mesh to \p M. This function can be used to load several
279 * meshes that are stored in the same GeoFile.
280 * \param[in] geofile a reference to the InputGeoFile
281 * \param[out] M the loaded mesh
282 * \param[in] ioflags specifies which attributes and
283 * elements should be loaded
284 * \return true on success, false otherwise.
285 */
286 bool GEOGRAM_API mesh_load(
287 InputGeoFile& geofile, Mesh& M,
288 const MeshIOFlags& ioflags = MeshIOFlags()
289 );
290
291
292 /**
293 * \brief Saves a mesh to a file.
294 * \details
295 * Saves mesh \p M to the file \p filename. The file format is determined
296 * by the \p filename's extension, which determines the appropriate
297 * MeshIOHandler to use to write the file.
298 * \param[in] M the mesh to save
299 * \param[in] filename name of the file
300 * \param[in] ioflags specifies which attributes and elements
301 * should be saved
302 * \return true on success, false otherwise.
303 * \see MeshIOHandler
304 */
305 bool GEOGRAM_API mesh_save(
306 const Mesh& M, const std::string& filename,
307 const MeshIOFlags& ioflags = MeshIOFlags()
308 );
309
310 /**
311 * \brief Saves a mesh to a GeoFile ('.geogram' file format)
312 * \details
313 * Saves mesh \p M to the GeoFile \p geofile. This function can be
314 * used to write several meshes into the same GeoFile.
315 * \param[in] M the mesh to save
316 * \param[in] geofile a reference to the OutputGeoFile
317 * \param[in] ioflags specifies which attributes and elements
318 * should be saved
319 * \return true on success, false otherwise.
320 */
321 bool GEOGRAM_API mesh_save(
322 const Mesh& M, OutputGeoFile& geofile,
323 const MeshIOFlags& ioflags = MeshIOFlags()
324 );
325
326
327 /*************************************************************************/
328
329 /**
330 * \brief Mesh loader and saver
331 * \details MeshIOHandler is responsible to load and save meshes in a
332 * specific file format. MeshIOHandler is used internally by mesh_load()
333 * and mesh_save(), so you don't normally need to use it directly, unless
334 * you need to implement a new file format.
335 *
336 * Vorpaline currently supports thr following file formats:
337 * - OBJ http://en.wikipedia.org/wiki/Wavefront_.obj_file
338 * - mesh, meshb (ASCII and binary)
339 * http://www-roc.inria.fr/gamma/gamma/Membres/CIPD/Loic.Marechal/Research/LM5.html
340 * - ply (ASCII and binary, single and double precision)
341 * http://en.wikipedia.org/wiki/PLY_(file_format)
342 * - OFF http://www.geomview.org/docs/html/OFF.html
343 * - STL (ASCII and binary)
344 * http://en.wikipedia.org/wiki/STL_(file_format)
345 *
346 * MeshIOHandler%s are created using method create() which uses the
347 * Factory service. Handlers for new file formats can be implemented and
348 * registered to the factory using geo_register_MeshIOHandler_creator().
349 * \see MeshIOHandlerFactory
350 * \see geo_register_MeshIOHandler_creator
351 */
352 class GEOGRAM_API MeshIOHandler : public Counted {
353 public:
354 /**
355 * \brief Creates a MeshIOHandler
356 * \param[in] format format of the file
357 * \retval nullptr if \p format is not a supported file format.
358 * \retval otherwise, a pointer to a IO handler. The returned pointer
359 * must be stored in an MeshIOHandler_var that does automatic
360 * destruction:
361 * \code
362 * MeshIOHandler_var handler = MeshIOHandler::create("mesh");
363 * \endcode
364 */
365 static MeshIOHandler* create(const std::string& format);
366
367 /**
368 * \brief Gets the MeshIOHandler for a file
369 * \details Determines the file format from the extension of file \p
370 * filename and creates a MeshIOHandler for this format.
371 * \param[in] filename a path to a mesh file
372 * \retval nullptr if \p format is not a supported file format.
373 * \retval a pointer to a IO handler if format is supported.
374 * \retval nullptr otherwise
375 * \see create()
376 */
377 static MeshIOHandler* get_handler(const std::string& filename);
378
379 /**
380 * \brief Loads a double precision mesh from a file.
381 * \param[in] filename name of the file
382 * \param[out] M the loaded mesh
383 * \param[in] ioflags specifies which attributes and elements
384 * should be loaded
385 */
386 virtual bool load(
387 const std::string& filename, Mesh& M,
388 const MeshIOFlags& ioflags = MeshIOFlags()
389 ) = 0;
390
391 /**
392 * \brief Saves a mesh to a file.
393 * \param[in] M the mesh to save
394 * \param[in] filename name of the file
395 * \param[in] ioflags specifies which attributes and elements
396 * should be saved
397 * \return true on success, false otherwise.
398 */
399 virtual bool save(
400 const Mesh& M, const std::string& filename,
401 const MeshIOFlags& ioflags = MeshIOFlags()
402 ) = 0;
403
404 protected:
405 /**
406 * \brief MeshIOHandler default constructor
407 */
408
4/8
✓ Branch 2 taken 421 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 421 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 421 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 421 times.
✗ Branch 12 not taken.
421 MeshIOHandler() {
409 421 }
410
411 /**
412 * \brief MeshIOHandler destructor
413 */
414 ~MeshIOHandler() override;
415
416 virtual void bind_attributes(
417 const Mesh& M, const MeshIOFlags& flags, bool create
418 );
419 virtual void unbind_attributes();
420
421 protected:
422 Attribute<index_t> vertex_region_;
423 Attribute<index_t> edge_region_;
424 Attribute<index_t> facet_region_;
425 Attribute<index_t> cell_region_;
426 };
427
428 /**
429 * \brief A smart pointer that contains a MeshIOHandler object.
430 * \relates MeshIOHandler
431 */
432 typedef SmartPointer<MeshIOHandler> MeshIOHandler_var;
433
434 /**
435 * \brief MeshIOHandler Factory
436 * \details
437 * This Factory is used to create MeshIOHandler objects.
438 * It can also be used to register new MeshIOHandler
439 * implementations.
440 * \see geo_register_MeshIOHandler_creator
441 * \see Factory
442 * \relates MeshIOHandler
443 */
444 typedef Factory0<MeshIOHandler> MeshIOHandlerFactory;
445
446 /**
447 * \brief Helper macro to register a MeshIOHandler implementation
448 * \see MeshIOHandlerFactory
449 * \relates MeshIOHandler
450 */
451 #define geo_register_MeshIOHandler_creator(type, name) \
452 geo_register_creator(GEO::MeshIOHandlerFactory, type, name)
453
454
455 void GEOGRAM_API mesh_io_initialize() ;
456 }
457
458 #endif
459