BRL-CAD
Loading...
Searching...
No Matches
trimesh.h
Go to the documentation of this file.
1/* T R I M E S H . H
2 * BRL-CAD
3 *
4 * Copyright (c) 2004-2026 United States Government as represented by
5 * the U.S. Army Research Laboratory.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * version 2.1 as published by the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this file; see the file named COPYING for more
18 * information.
19 */
20
21/*----------------------------------------------------------------------*/
22/* @file trimesh.h */
23/** @addtogroup bg_trimesh */
24/** @{ */
25
26/**
27 * @brief
28 * Algorithms related to 3D meshes built from triangles.
29 */
30
31#ifndef BG_TRIMESH_H
32#define BG_TRIMESH_H
33
34#include "common.h"
35#include "vmath.h"
36#include "bg/defines.h"
37#include "bu/vls.h"
38
39__BEGIN_DECLS
40
42 int va, vb;
44};
45
46/* every pair of contiguous elements is the start and end vertex index of an edge */
48 int count;
49 int *edges;
50};
51
53 int count;
54 int *faces;
55};
56
63
64#define BG_TRIMESH_EDGES_INIT_NULL {0, NULL}
65#define BG_TRIMESH_FACES_INIT_NULL {0, NULL}
66#define BG_TRIMESH_SOLID_ERRORS_INIT_NULL {BG_TRIMESH_FACES_INIT_NULL, BG_TRIMESH_EDGES_INIT_NULL, BG_TRIMESH_EDGES_INIT_NULL, BG_TRIMESH_EDGES_INIT_NULL}
67
68BG_EXPORT extern void bg_free_trimesh_edges(struct bg_trimesh_edges *edges);
69BG_EXPORT extern void bg_free_trimesh_faces(struct bg_trimesh_faces *faces);
70BG_EXPORT extern void bg_free_trimesh_solid_errors(struct bg_trimesh_solid_errors *errors);
71
72/**
73 * Check if a mesh is topologically closed and manifold. True if for
74 * every edge, there is exactly one other edge with the same two end
75 * vertices.
76 */
77BG_EXPORT extern int bg_trimesh_manifold_closed(int vcnt, int fcnt, fastf_t *v, int *f);
78
79/**
80 * Check if a mesh is consistently oriented. True if for every edge
81 * that has exactly one matching edge, the two edges have opposite
82 * orientations. Note that an open mesh can be oriented, but a
83 * non-manifold mesh cannot.
84 */
85BG_EXPORT extern int bg_trimesh_oriented(int vcnt, int fcnt, fastf_t *v, int *f);
86
87/**
88 * Check if a mesh is topologically solid. Returns 1 if the mesh is NOT SOLID
89 * and 0 if the mesh is SOLID. A SOLID (0) outcome indicates the mesh satisfies
90 * all three criteria: Closed, Manifold, Oriented
91 */
92BG_EXPORT extern int bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges);
93
94/* The below functions are for use as arguments to error tests. Given
95 * a face/edge, they return true if the caller should continue
96 * iterating through faces/edges, and false otherwise.
97 *
98 * The *_exit and *_continue functions just return false and true
99 * respectively. The *_gather functions expect the data argument to
100 * be a struct bg_trimesh_faces or struct bg_trimesh_edges with
101 * pre-allocated members of the correct size and count members set to
102 * 0, that they will populate.
103 */
104typedef int (*bg_face_error_func_t)(int face_idx, void *data);
105typedef int (*bg_edge_error_funct_t)(struct bg_trimesh_halfedge *edge, void *data);
106
107BG_EXPORT extern int bg_trimesh_face_exit(int face_idx, void *data);
108BG_EXPORT extern int bg_trimesh_face_continue(int face_idx, void *data);
109BG_EXPORT extern int bg_trimesh_face_gather(int face_idx, void *data);
110BG_EXPORT extern int bg_trimesh_edge_exit(struct bg_trimesh_halfedge *edge, void *data);
111BG_EXPORT extern int bg_trimesh_edge_continue(struct bg_trimesh_halfedge *edge, void *data);
112BG_EXPORT extern int bg_trimesh_edge_gather(struct bg_trimesh_halfedge *edge, void *data);
113
114/* These functions return 0 if no instances of the error are found.
115 * Otherwise, they return the number of instances of the error found
116 * before the error function argument returned false (at least 1).
117 */
118BG_EXPORT extern int bg_trimesh_degenerate_faces(int num_faces, int *fpoints, bg_face_error_func_t degenerate_func, void *data);
119BG_EXPORT extern int bg_trimesh_unmatched_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data);
120BG_EXPORT extern int bg_trimesh_misoriented_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data);
121BG_EXPORT extern int bg_trimesh_excess_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data);
122BG_EXPORT extern int bg_trimesh_solid2(int vcnt, int fcnt, fastf_t *v, int *f, struct bg_trimesh_solid_errors *errors);
123BG_EXPORT extern int bg_trimesh_hanging_nodes(int num_vertices, int num_faces, fastf_t *vertices, int *faces, struct bg_trimesh_solid_errors *errors);
124
125BG_EXPORT extern struct bg_trimesh_halfedge * bg_trimesh_generate_edge_list(int fcnt, int *f);
126
127/**
128 * @brief
129 * Calculate an axis aligned bounding box (RPP) for a triangle mesh.
130 *
131 * NOTE: This routine bounds only those points that are active in the triangle
132 * mesh, not all points present in the supplied points array.
133 *
134 * @param[out] min XYZ coordinate defining the minimum bbox point
135 * @param[out] max XYZ coordinate defining the maximum bbox point
136 * @param[in] faces array of trimesh faces
137 * @param[in] num_faces size of faces array
138 * @param[in] p array that holds the points defining the trimesh
139 * @param[in] num_pnts size of pnts array
140 */
141BG_EXPORT extern int
142bg_trimesh_aabb(point_t *min, point_t *max, const int *faces, size_t num_faces, const point_t *p, size_t num_pnts);
143
144/**
145 * @brief
146 * Calculate the surface area of a triangle mesh.
147 *
148 * @param[in] faces array of trimesh faces
149 * @param[in] num_faces size of faces array
150 * @param[in] p array that holds the points defining the trimesh
151 * @param[in] num_pnts size of pnts array
152 *
153 * @return -1 if error, else area of mesh in millimeters
154 */
155BG_EXPORT extern fastf_t
156bg_trimesh_area(const int *faces, size_t num_faces, const point_t *p, size_t num_pnts);
157
158
159/**
160 * Calculate the volume enclosed by a closed, consistently-oriented triangle
161 * mesh using the divergence theorem (signed-tetrahedra method).
162 *
163 * The mesh must be closed and consistently oriented (all face normals pointing
164 * outward or all inward). Consistent orientation is guaranteed for meshes
165 * that pass bg_trimesh_solid2() with zero unmatched edges. The function
166 * returns the absolute value of the signed result, so it works correctly
167 * regardless of whether normals point inward or outward.
168 *
169 * @param[in] faces flat array of triangle indices (3 ints per face)
170 * @param[in] num_faces number of triangles
171 * @param[in] p array of vertex positions
172 * @param[in] num_pnts number of vertices
173 *
174 * @return -1 if inputs are invalid, else volume in cubic millimeters
175 */
176BG_EXPORT extern fastf_t
177bg_trimesh_volume(const int *faces, size_t num_faces, const point_t *p, size_t num_pnts);
178
179/* Structure holding user-adjustable decimation settings */
181 int method; // Select decimation method to use
182 fastf_t feature_size; // Smallest feature size (mm) to leave undecimated
183 fastf_t max_runtime; // If the decimation takes more than max_runtime seconds, abort
184 size_t max_threads; // Don't use more than max_threads when processing.
185 struct bu_vls msgs; // Messages reported during decimation
186};
187#define BG_TRIMESH_DECIMATION_METHOD_DEFAULT 0
188#define BG_TRIMESH_DECIMATION_SETTINGS_INIT {BG_TRIMESH_DECIMATION_METHOD_DEFAULT, 0.0, 0.0, 0, BU_VLS_INIT_ZERO}
189
190/**
191 * @brief
192 * Decimate a mesh and return the decimated faces.
193 *
194 * @param[out] ofaces faces array for the new output mesh
195 * @param[out] n_ofaces length of ofaces array
196 * @param[in] ifaces array of input trimesh
197 * @param[in] n_ifaces size of input faces array
198 * @param[in] p array that holds the points defining the trimesh
199 * @param[in] n_p size of points array
200 * @param[in] s decimation settings
201 *
202 * NOTE: This routine will not produce a points array that includes only the
203 * points used in the decimated mesh - to generate that output, use the
204 * bg_trimesh_3d_gc routine with the ofaces set produced by this function.
205 *
206 * @return -1 if error, 0 if successful */
207DEPRECATED BG_EXPORT extern int bg_trimesh_decimate(int **ofaces, int *n_ofaces,
208 int *ifaces, int n_ifaces, point_t *p, int n_p, struct bg_trimesh_decimation_settings *s);
209
210/**
211 * Decimate a mesh, returning both its output faces and their input face
212 * provenance. The caller must free both output arrays with bu_free.
213 * face_sources[i] is the input face index associated with output face i;
214 * callers should use it to carry face-indexed application data through the
215 * operation.
216 *
217 * Like bg_trimesh_decimate, this routine retains the input point indices. Use
218 * bg_trimesh_3d_gc to produce a compact point array after handling any
219 * application data that uses those indices.
220 */
221BG_EXPORT extern int bg_trimesh_run_decimater(int **ofaces,
222 int **face_sources, int *n_ofaces, int *ifaces, int n_ifaces, point_t *p,
223 int n_p, struct bg_trimesh_decimation_settings *s);
224
225
226/* Make an attempt at a trimesh intersection calculator that returns the sets
227 * of faces intersecting and inside the other for each mesh. Doesn't attempt
228 * a boolean evaluation, just characterizes faces */
229BG_EXPORT extern int
231 int **faces_inside_1, int *num_faces_inside_1, int **faces_inside_2, int *num_faces_inside_2,
232 int **faces_isect_1, int *num_faces_isect_1, int **faces_isect_2, int *num_faces_isect_2,
233 int *faces_1, int num_faces_1, point_t *vertices_1, int num_vertices_1,
234 int *faces_2, int num_faces_2, point_t *vertices_2, int num_vertices_2);
235
236/**
237 * @brief
238 * Compute vertex normals for a mesh based on the connected faces.
239 *
240 * @param[out] onorms array of normals - will have the same length as the input points array
241 * @param[in] ifaces array of input trimesh
242 * @param[in] n_ifaces size of input faces array
243 * @param[in] p array that holds the points defining the trimesh
244 * @param[in] n_p size of points array
245 *
246 * NOTE: Any vertex point not used by the triangles in the trimesh will have a
247 * zero normal in the onorms array. This routine does not repack the data to
248 * eliminate unused vertices - for that use bg_trimesh_optimize
249 *
250 * @return -1 if error, 0 if successful */
251BG_EXPORT extern int bg_trimesh_normals(vect_t **onorms, int *ifaces, int n_ifaces, point_t *p, int n_p);
252
253
254/* Various additional mesh optimization steps that can be enabled
255 * NOTE: If we want to look at exposing the capabilities of something like
256 * https://github.com/zeux/meshoptimizer this would be the place to start... */
258 int collapse_degenerate; // Remove degenerate faces
259 fastf_t degenerate_edge_length; // If near zero and collapse_degenerate is set, only collapse triangles with two or more uses of the exact same vertex
260 fastf_t max_runtime; // If the optimization takes more than max_runtime seconds, abort
261 size_t max_threads; // Don't use more than max_threads when processing.
262};
263
264#define BG_TRIMESH_OPTIMIZATION_SETTINGS_INIT {0, 0.0, 0.0, 0}
265
266/**
267 * @brief
268 * Return trimesh information for a 3D mesh that contains just the date needed
269 * to represent in the mesh. Used to finalize intermediate processing meshes
270 * to generate a compact mesh for export or storage.
271 *
272 * @param[out] ofaces faces array for the new output mesh with new indices based on opnts array.
273 * @param[out] n_ofaces length of ofaces array
274 * @param[out] opnts compact points array for the new output mesh.
275 * @param[out] onorms (optional) compact normals array for the output mesh's points.
276 * @param[out] n_opnts length of opnts array.
277 * @param[in] ifaces array of input trimesh
278 * @param[in] n_ifaces size of input faces array
279 * @param[in] ipnts array that holds the points defining the original trimesh
280 * @param[in] inorms (optional) array that holds the normals for the mesh vertices
281 * @param[in] s (optional) settings to enable various additional processing steps
282 *
283 * @return -1 if error, number of faces in new trimesh if successful
284 */
285BG_EXPORT extern int bg_trimesh_optimize(
286 int **ofaces, int *n_ofaces,
287 point_t **opnts, vect_t **onorms, int *n_opnts,
288 const int *ifaces, int n_ifaces,
289 const point_t *ipnts, const vect_t *inorms,
291
292
293/**
294 * @brief
295 * Return trimesh information for a planar (2D) mesh that contains just the set
296 * of points active in the mesh.
297 *
298 * @param[out] ofaces faces array for the new output mesh
299 * @param[out] opnts points array for the new output mesh
300 * @param[out] n_opnts length of opnts array
301 * @param[in] ifaces array of input trimesh
302 * @param[in] n_ifaces size of input faces array
303 * @param[in] ipnts array that holds the points defining the original trimesh
304 *
305 * @return -1 if error, number of faces in new trimesh if successful (should
306 * match the original face count)
307 */
308BG_EXPORT extern int bg_trimesh_2d_gc(int **ofaces, point2d_t **opnts, int *n_opnts,
309 const int *ifaces, int n_ifaces, const point2d_t *ipnts);
310
311/**
312 * @brief
313 * Return trimesh information for a 3D mesh that contains just the set
314 * of points active in the mesh.
315 *
316 * @param[out] ofaces faces array for the new output mesh.
317 * @param[out] opnts points array for the new output mesh.
318 * @param[out] n_opnts length of opnts array.
319 * @param[in] faces array of input trimesh
320 * @param[in] num_faces size of input faces array
321 * @param[in] in_pts holds the points defining the original trimesh
322 *
323 * @return -1 if error, number of faces in new trimesh if successful (should
324 * match the original face count)
325 */
326BG_EXPORT extern int bg_trimesh_3d_gc(int **ofaces, point_t **opnts, int *n_opnts,
327 const int *faces, int num_faces, const point_t *in_pts);
328
329/**
330 * @brief
331 * Return a face set where all topologically connected faces are oriented
332 * consistently relative to their neighbors.
333 *
334 * @param[out] of faces array for the new output mesh (of==f is valid).
335 * @param[in] f input set of faces.
336 * @param[in] fcnt input face count
337 *
338 * @return -1 if error, otherwise return the number of times a face flipping
339 * operation was performed
340 */
341BG_EXPORT extern int
342bg_trimesh_sync(int *of, int *f, int fcnt);
343
344/**
345 * @brief
346 * Group edge-connected triangle components while retaining input face
347 * identity.
348 *
349 * The output uses a compact grouped-index representation. The original face
350 * indices for component i are stored in the half-open range
351 * [component_offsets[i], component_offsets[i+1]) of face_indices. Components
352 * and their faces are ordered by their first occurrence in the input.
353 *
354 * To build a self-contained face/point mesh for one component, copy the three
355 * entries from f for each returned face index into a temporary faces array,
356 * then pass that array and the original points to bg_trimesh_3d_gc.
357 *
358 * The caller must free both output arrays with bu_free.
359 *
360 * @param[out] face_indices input face indices grouped by component
361 * @param[out] component_offsets offsets into face_indices, with one terminal
362 * offset; length is the return value plus one
363 * @param[in] f input set of faces
364 * @param[in] fcnt input face count
365 *
366 * @return -1 on error, otherwise the number of connected components
367 */
368BG_EXPORT extern int
369bg_trimesh_separate(int **face_indices, int **component_offsets,
370 const int *f, int fcnt);
371
372/**
373 * @brief
374 * Return copied triangle arrays grouped into edge-connected components.
375 *
376 * This interface does not retain the original face indices, so callers cannot
377 * reliably associate face-indexed data with its output. New code should use
378 * bg_trimesh_separate.
379 *
380 * @param[out] ofs array of faces arrays containing the new output face sets.
381 * @param[out] ofc array of face counts for the new output face sets.
382 * @param[in] f input set of faces.
383 * @param[in] fcnt input face count
384 *
385 * @return -1 if error, otherwise return the number of face sets created
386 */
387DEPRECATED BG_EXPORT extern int
388bg_trimesh_split(int ***ofs, int **ofc, int *f, int fcnt);
389
390/**
391 * @brief
392 * Return a set of face sets where all topologically connected faces are
393 * grouped into common sets.
394 *
395 * @param[in] fname plot file name
396 * @param[in] faces face index array
397 * @param[in] num_faces number of faces
398 * @param[in] pnts points array
399 * @param[in] num_pnts number of points
400 *
401 * @return BRLCAD_ERROR if error, otherwise return BRLCAD_OK
402 */
403BG_EXPORT extern int
404bg_trimesh_2d_plot3(const char *fname, const int *faces, size_t num_faces, const point2d_t *pnts, size_t num_pnts);
405
406/**
407 * @brief
408 * Compare two trimeshes to determine if they (within tolerance) define the
409 * same mesh.
410 *
411 * This is a fairly focused function whose purpose is to spot meshes that have
412 * potentially gone through numerical or topological reordering but still
413 * define the same volume (for example, meshes that have been rotated or
414 * translated and then returned to an origin with PCA.) By design it does not
415 * analyze the differences to report on why two meshes differ - it simply
416 * returns a yes/no decision. Different vertex or face counts are grounds
417 * for immediate declaration the meshes differ - no effort is made to look for
418 * duplicate vertices or degenerate faces. Any such clean-ups must be performed
419 * before calling this function.
420 *
421 * The specification of a distance tolerance is used for vertex comparisons.
422 * Below the specified threshold, vertices that would otherwise be considered
423 * rejection criteria for being different will be considered the same.
424 * HOWEVER, that tolerance does NOT merge vertices - rather, when vertices are
425 * organized and sorted for comparison the candidate pairing vertices in the
426 * arrays are compared using the tolerance.
427 *
428 * Both vertex positions and face topology must be compatible - faces may use a
429 * different starting vertex (i.e. 0->1->2 and 1->2->0 are considered to be the
430 * same) but the ordering must be consistent (i.e. 0->2->1 would not be
431 * considered the same.)
432 *
433 * @param[in] f1 face index array referencing points in p1
434 * @param[in] num_f1 number of faces in f1
435 * @param[in] p1 first points array
436 * @param[in] num_p1 number of points in p1
437 * @param[in] f2 face index array referencing points in p2
438 * @param[in] num_f2 number of faces in f2
439 * @param[in] p2 second points array
440 * @param[in] num_p2 number of points in p2
441 * @param[in] dist_tol distance in mm below which points are considered the same
442 *
443 * @return 0 if same, otherwise return 1.
444 */
445BG_EXPORT extern int
447 const int *f1, size_t num_f1, const point_t *p1, size_t num_p1,
448 const int *f2, size_t num_f2, const point_t *p2, size_t num_p2,
449 fastf_t dist_tol
450 );
451
452/**
453 * @brief
454 * Generate a hash from the mesh data, using the tolerance parameter to
455 * clamp the numerical values. Both vertex positions and face topology
456 * are considered, in a style similar to bg_trimesh_diff.
457 *
458 * The clamping needed to generate a hash value will increase the chances of
459 * two similar meshes having the same hash, but the nature of numerical
460 * clamping results in some very close but not exact values clamping in
461 * opposite directions. Without global awareness of all vertex points at play
462 * in a database it is not possible to establish a binning that will work for
463 * all meshes in the same way (and there are no guarantees it is possible even
464 * with that knowledge, strictly speaking.) For a proper distance-based
465 * comparison of two meshes, bg_trimesh_diff should be used rather than
466 * comparing hash values. However, if mesh hash values DO match then the
467 * associated meshes should be quite close to being the same geometry per the
468 * specified tolerance - and in practice there are situations where we can get
469 * enough matching hashes to be useful - trial runs of PCA oriented BoT object
470 * grouping on a large database were able to identify matching hashes for
471 * about 80% of the cases were bg_trimesh_diff was able to geometrically
472 * identify fuzzy matches.
473 *
474 * Applications for this hash include looking up data associated with meshes
475 * via hash keys - if a large majority of duplicate meshes can be spotted in a
476 * .g database and indexed this way, it makes it possible to reduce the amount
477 * of duplicate data being stored. It is also possible to associated meshes
478 * with their hashes and then use a bg_trimesh_diff result to further map those
479 * hashes to unique data copies.
480 *
481 * TODO - look into whether some form of similarity hash might do better for
482 * our purposes here:
483 * https://github.com/seomoz/simhash-cpp
484 * https://github.com/FALCONN-LIB/FALCONN
485 * https://github.com/trendmicro/tlsh
486 *
487 * @param[in] f face index array referencing points in p
488 * @param[in] num_f number of faces in f
489 * @param[in] p points array
490 * @param[in] num_p number of points in p
491 * @param[in] dist_tol tolerance used when clamping points
492 *
493 * @return the bu_data_hash value of the mesh.
494 */
495BG_EXPORT extern unsigned long long
497 const int *f, size_t num_f, const point_t *p, size_t num_p,
498 fastf_t dist_tol
499 );
500
501
502
503
504/**
505 * Options governing triangle mesh repair operations.
506 *
507 * Repair attempts to produce a closed, consistently-oriented, manifold
508 * mesh from a defective input by colocating near-duplicate vertices,
509 * removing degenerate / duplicate faces, and filling boundary holes up
510 * to the caller-specified size limit.
511 */
513 fastf_t max_hole_area; /**< Largest hole area (mm^2) eligible for filling; 0 = use percentage */
514 fastf_t max_hole_area_percent; /**< Largest hole area as percentage of total mesh area; ignored when max_hole_area > 0 */
516
517/** Default repair options: fill holes up to 5% of the total mesh area. */
518#define BG_TRIMESH_REPAIR_OPTS_DEFAULT {0.0, 5.0}
520/**
521 * @brief
522 * Attempt to repair a non-manifold triangle mesh so that it becomes a
523 * closed, consistently-oriented solid.
524 *
525 * The function:
526 * 1. Colocates near-duplicate vertices (epsilon derived from bounding-box
527 * diagonal), removes degenerate and duplicate faces.
528 * 2. Removes small disconnected components (< 3% of total surface area).
529 * 3. Fills boundary holes whose area is at most the limit set in @p opts.
530 *
531 * @param[out] ofaces output face index array (caller must bu_free)
532 * @param[out] n_ofaces number of faces in @p ofaces
533 * @param[out] opnts output point array (caller must bu_free)
534 * @param[out] n_opnts number of points in @p opnts
535 * @param[in] ifaces input face index array (3 ints per face)
536 * @param[in] n_ifaces number of faces in @p ifaces
537 * @param[in] ipnts input point array
538 * @param[in] n_ipnts number of points in @p ipnts
539 * @param[in] opts repair options; NULL uses @c BG_TRIMESH_REPAIR_OPTS_DEFAULT
540 *
541 * @return 1 input mesh was already solid – @p ofaces / @p opnts are not set
542 * @return 0 repair succeeded – caller owns @p ofaces / @p opnts
543 * @return -1 error or repair failed to produce a valid result
544 */
545BG_EXPORT extern int
547 int **ofaces, int *n_ofaces,
548 point_t **opnts, int *n_opnts,
549 const int *ifaces, int n_ifaces,
550 const point_t *ipnts, int n_ipnts,
551 struct bg_trimesh_repair_opts *opts);
552
553
554/**
555 * Options governing triangle mesh remeshing operations.
556 *
557 * Remeshing regenerates the connectivity of a mesh so that its triangles
558 * are more uniform in size and shape while preserving the overall surface.
559 * The Geogram CVT (Centroidal Voronoi Tessellation) algorithm is used
560 * internally.
561 */
563 int target_count; /**< Desired vertex count in output; 0 = use count_multiplier */
564 fastf_t count_multiplier; /**< Multiply input vertex count by this to obtain target (default 10.0) */
565 fastf_t anisotropy; /**< Anisotropy weight for surface-normal direction; 0.0 = isotropic remesh (default 0.04) */
566 int lloyd_iters; /**< Number of Lloyd relaxation iterations (default 5) */
567 int newton_iters; /**< Number of Newton iterations for CVT optimization (default 30) */
569
570/** Default remesh options: 10× input vertex density, moderate anisotropy. */
571#define BG_TRIMESH_REMESH_OPTS_DEFAULT {0, 10.0, 0.04, 5, 30}
573/**
574 * @brief
575 * Remesh a triangle mesh to improve element quality and/or change density.
576 *
577 * A Geogram-based pre-repair pass is run on the input before remeshing so
578 * that degenerate or near-duplicate geometry does not confuse the CVT solver.
579 * The output mesh is a new triangulation of the same surface.
580 *
581 * @param[out] ofaces output face index array (caller must bu_free)
582 * @param[out] n_ofaces number of faces in @p ofaces
583 * @param[out] opnts output point array (caller must bu_free)
584 * @param[out] n_opnts number of points in @p opnts
585 * @param[in] ifaces input face index array (3 ints per face)
586 * @param[in] n_ifaces number of faces in @p ifaces
587 * @param[in] ipnts input point array
588 * @param[in] n_ipnts number of points in @p ipnts
589 * @param[in] opts remesh options; NULL uses @c BG_TRIMESH_REMESH_OPTS_DEFAULT
590 *
591 * @return 0 on success – caller owns @p ofaces / @p opnts
592 * @return -1 on error
593 */
594BG_EXPORT extern int
596 int **ofaces, int *n_ofaces,
597 point_t **opnts, int *n_opnts,
598 const int *ifaces, int n_ifaces,
599 const point_t *ipnts, int n_ipnts,
600 struct bg_trimesh_remesh_opts *opts);
601
602
603__END_DECLS
604
605#endif /* BG_TRIMESH_H */
606/** @} */
607/*
608 * Local Variables:
609 * mode: C
610 * tab-width: 8
611 * indent-tabs-mode: t
612 * c-file-style: "stroustrup"
613 * End:
614 * ex: shiftwidth=4 tabstop=8
615 */
Header file for the BRL-CAD common definitions.
int bg_trimesh_hanging_nodes(int num_vertices, int num_faces, fastf_t *vertices, int *faces, struct bg_trimesh_solid_errors *errors)
int bg_trimesh_misoriented_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data)
int bg_trimesh_aabb(point_t *min, point_t *max, const int *faces, size_t num_faces, const point_t *p, size_t num_pnts)
Calculate an axis aligned bounding box (RPP) for a triangle mesh.
int bg_trimesh_face_gather(int face_idx, void *data)
int bg_trimesh_sync(int *of, int *f, int fcnt)
Return a face set where all topologically connected faces are oriented consistently relative to their...
int bg_trimesh_diff(const int *f1, size_t num_f1, const point_t *p1, size_t num_p1, const int *f2, size_t num_f2, const point_t *p2, size_t num_p2, fastf_t dist_tol)
Compare two trimeshes to determine if they (within tolerance) define the same mesh.
int bg_trimesh_degenerate_faces(int num_faces, int *fpoints, bg_face_error_func_t degenerate_func, void *data)
int bg_trimesh_face_continue(int face_idx, void *data)
int bg_trimesh_edge_gather(struct bg_trimesh_halfedge *edge, void *data)
int bg_trimesh_run_decimater(int **ofaces, int **face_sources, int *n_ofaces, int *ifaces, int n_ifaces, point_t *p, int n_p, struct bg_trimesh_decimation_settings *s)
int bg_trimesh_excess_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data)
fastf_t bg_trimesh_area(const int *faces, size_t num_faces, const point_t *p, size_t num_pnts)
Calculate the surface area of a triangle mesh.
int bg_trimesh_edge_exit(struct bg_trimesh_halfedge *edge, void *data)
int bg_trimesh_oriented(int vcnt, int fcnt, fastf_t *v, int *f)
int bg_trimesh_manifold_closed(int vcnt, int fcnt, fastf_t *v, int *f)
int bg_trimesh_optimize(int **ofaces, int *n_ofaces, point_t **opnts, vect_t **onorms, int *n_opnts, const int *ifaces, int n_ifaces, const point_t *ipnts, const vect_t *inorms, struct bg_trimesh_optimization_settings *s)
Return trimesh information for a 3D mesh that contains just the date needed to represent in the mesh....
int bg_trimesh_edge_continue(struct bg_trimesh_halfedge *edge, void *data)
int bg_trimesh_separate(int **face_indices, int **component_offsets, const int *f, int fcnt)
Group edge-connected triangle components while retaining input face identity.
void bg_free_trimesh_edges(struct bg_trimesh_edges *edges)
DEPRECATED int bg_trimesh_split(int ***ofs, int **ofc, int *f, int fcnt)
Return copied triangle arrays grouped into edge-connected components.
int bg_trimesh_unmatched_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data)
int bg_trimesh_3d_gc(int **ofaces, point_t **opnts, int *n_opnts, const int *faces, int num_faces, const point_t *in_pts)
Return trimesh information for a 3D mesh that contains just the set of points active in the mesh.
int bg_trimesh_isect(int **faces_inside_1, int *num_faces_inside_1, int **faces_inside_2, int *num_faces_inside_2, int **faces_isect_1, int *num_faces_isect_1, int **faces_isect_2, int *num_faces_isect_2, int *faces_1, int num_faces_1, point_t *vertices_1, int num_vertices_1, int *faces_2, int num_faces_2, point_t *vertices_2, int num_vertices_2)
int bg_trimesh_2d_gc(int **ofaces, point2d_t **opnts, int *n_opnts, const int *ifaces, int n_ifaces, const point2d_t *ipnts)
Return trimesh information for a planar (2D) mesh that contains just the set of points active in the ...
int bg_trimesh_2d_plot3(const char *fname, const int *faces, size_t num_faces, const point2d_t *pnts, size_t num_pnts)
Return a set of face sets where all topologically connected faces are grouped into common sets.
int bg_trimesh_remesh(int **ofaces, int *n_ofaces, point_t **opnts, int *n_opnts, const int *ifaces, int n_ifaces, const point_t *ipnts, int n_ipnts, struct bg_trimesh_remesh_opts *opts)
Remesh a triangle mesh to improve element quality and/or change density.
int(* bg_face_error_func_t)(int face_idx, void *data)
Definition trimesh.h:104
fastf_t bg_trimesh_volume(const int *faces, size_t num_faces, const point_t *p, size_t num_pnts)
struct bg_trimesh_halfedge * bg_trimesh_generate_edge_list(int fcnt, int *f)
int bg_trimesh_solid2(int vcnt, int fcnt, fastf_t *v, int *f, struct bg_trimesh_solid_errors *errors)
int bg_trimesh_face_exit(int face_idx, void *data)
int bg_trimesh_normals(vect_t **onorms, int *ifaces, int n_ifaces, point_t *p, int n_p)
Compute vertex normals for a mesh based on the connected faces.
void bg_free_trimesh_solid_errors(struct bg_trimesh_solid_errors *errors)
int bg_trimesh_repair(int **ofaces, int *n_ofaces, point_t **opnts, int *n_opnts, const int *ifaces, int n_ifaces, const point_t *ipnts, int n_ipnts, struct bg_trimesh_repair_opts *opts)
Attempt to repair a non-manifold triangle mesh so that it becomes a closed, consistently-oriented sol...
int(* bg_edge_error_funct_t)(struct bg_trimesh_halfedge *edge, void *data)
Definition trimesh.h:105
DEPRECATED int bg_trimesh_decimate(int **ofaces, int *n_ofaces, int *ifaces, int n_ifaces, point_t *p, int n_p, struct bg_trimesh_decimation_settings *s)
Decimate a mesh and return the decimated faces.
void bg_free_trimesh_faces(struct bg_trimesh_faces *faces)
unsigned long long bg_trimesh_hash(const int *f, size_t num_f, const point_t *p, size_t num_p, fastf_t dist_tol)
Generate a hash from the mesh data, using the tolerance parameter to clamp the numerical values....
int bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges)
#define DEPRECATED
Definition common.h:439
fastf_t vect_t[ELEMENTS_PER_VECT]
3-tuple vector
Definition vmath.h:351
double fastf_t
fastest 64-bit (or larger) floating point type
Definition vmath.h:336
fastf_t point2d_t[ELEMENTS_PER_POINT2D]
2-tuple point
Definition vmath.h:345
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition vmath.h:357
Algorithms related to 3D meshes built from triangles.
Definition trimesh.h:41
fastf_t max_hole_area_percent
Definition trimesh.h:515
struct bg_trimesh_edges excess
Definition trimesh.h:60
struct bg_trimesh_edges misoriented
Definition trimesh.h:61
struct bg_trimesh_faces degenerate
Definition trimesh.h:58
struct bg_trimesh_edges unmatched
Definition trimesh.h:59
Definition vls.h:53
NMG topological edge.
Definition topology.h:144
fundamental vector, matrix, quaternion math macros