BRL-CAD
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-2023 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
38__BEGIN_DECLS
39
41 int va, vb;
43};
44
45/* every pair of contiguous elements is the start and end vertex index of an edge */
47 int count;
48 int *edges;
49};
50
52 int count;
53 int *faces;
54};
55
61};
62
63#define BG_TRIMESH_EDGES_INIT_NULL {0, NULL}
64#define BG_TRIMESH_FACES_INIT_NULL {0, NULL}
65#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}
66
67BG_EXPORT extern void bg_free_trimesh_edges(struct bg_trimesh_edges *edges);
68BG_EXPORT extern void bg_free_trimesh_faces(struct bg_trimesh_faces *faces);
69BG_EXPORT extern void bg_free_trimesh_solid_errors(struct bg_trimesh_solid_errors *errors);
70
71/**
72 * Check if a mesh is topologically closed and manifold. True if for
73 * every edge, there is exactly one other edge with the same two end
74 * vertices.
75 */
76BG_EXPORT extern int bg_trimesh_manifold_closed(int vcnt, int fcnt, fastf_t *v, int *f);
77
78/**
79 * Check if a mesh is consistently oriented. True if for every edge
80 * that has exactly one matching edge, the two edges have opposite
81 * orientations. Note that an open mesh can be oriented, but a
82 * non-manifold mesh cannot.
83 */
84BG_EXPORT extern int bg_trimesh_oriented(int vcnt, int fcnt, fastf_t *v, int *f);
85
86/**
87 * Check if a mesh is topologically solid. True if the mesh is closed,
88 * manifold, and oriented.
89 */
90BG_EXPORT extern int bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges);
91
92/* The below functions are for use as arguments to error tests. Given
93 * a face/edge, they return true if the caller should continue
94 * iterating through faces/edges, and false otherwise.
95 *
96 * The *_exit and *_continue functions just return false and true
97 * respectively. The *_gather functions expect the data argument to
98 * be a struct bg_trimesh_faces or struct bg_trimesh_edges with
99 * pre-allocated members of the correct size and count members set to
100 * 0, that they will populate.
101 */
102typedef int (*bg_face_error_func_t)(int face_idx, void *data);
103typedef int (*bg_edge_error_funct_t)(struct bg_trimesh_halfedge *edge, void *data);
104
105BG_EXPORT extern int bg_trimesh_face_exit(int face_idx, void *data);
106BG_EXPORT extern int bg_trimesh_face_continue(int face_idx, void *data);
107BG_EXPORT extern int bg_trimesh_face_gather(int face_idx, void *data);
108BG_EXPORT extern int bg_trimesh_edge_exit(struct bg_trimesh_halfedge *edge, void *data);
109BG_EXPORT extern int bg_trimesh_edge_continue(struct bg_trimesh_halfedge *edge, void *data);
110BG_EXPORT extern int bg_trimesh_edge_gather(struct bg_trimesh_halfedge *edge, void *data);
111
112/* These functions return 0 if no instances of the error are found.
113 * Otherwise, they return the number of instances of the error found
114 * before the error function argument returned false (at least 1).
115 */
116BG_EXPORT extern int bg_trimesh_degenerate_faces(int num_faces, int *fpoints, bg_face_error_func_t degenerate_func, void *data);
117BG_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);
118BG_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);
119BG_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);
120BG_EXPORT extern int bg_trimesh_solid2(int vcnt, int fcnt, fastf_t *v, int *f, struct bg_trimesh_solid_errors *errors);
121BG_EXPORT extern int bg_trimesh_hanging_nodes(int num_vertices, int num_faces, fastf_t *vertices, int *faces, struct bg_trimesh_solid_errors *errors);
122
123BG_EXPORT extern struct bg_trimesh_halfedge * bg_trimesh_generate_edge_list(int fcnt, int *f);
124
125/**
126 * @brief
127 * Calculate an axis aligned bounding box (RPP) for a triangle mesh.
128 *
129 * NOTE: This routine bounds only those points that are active in the triangle
130 * mesh, not all points present in the supplied points array.
131 *
132 * @param[out] min XYZ coordinate defining the minimum bbox point
133 * @param[out] max XYZ coordinate defining the maximum bbox point
134 * @param[in] faces array of trimesh faces
135 * @param[in] num_faces size of faces array
136 * @param[in] p array that holds the points defining the trimesh
137 * @param[in] num_pnts size of pnts array
138 */
139BG_EXPORT extern int
140bg_trimesh_aabb(point_t *min, point_t *max, const int *faces, size_t num_faces, const point_t *p, size_t num_pnts);
141
142
143
144/* Structure holding user-adjustable decimation settings */
146 int method; // Select decimation method to use
147 fastf_t feature_size; // Smallest feature size (mm) to leave undecimated
148 fastf_t max_runtime; // If the decimation takes more than max_runtime seconds, abort
149 size_t max_threads; // Don't use more than max_threads when processing.
150};
151#define BG_TRIMESH_DECIMATION_METHOD_DEFAULT 0
152#define BG_TRIMESH_DECIMATION_SETTINGS_INIT {BG_TRIMESH_DECIMATION_METHOD_DEFAULT, 0.0, 0.0, 0}
153
154/**
155 * @brief
156 * Decimate a mesh and return the decimated faces.
157 *
158 * @param[out] ofaces faces array for the new output mesh
159 * @param[out] n_ofaces length of ofaces array
160 * @param[in] ifaces array of input trimesh
161 * @param[in] n_ifaces size of input faces array
162 * @param[in] p array that holds the points defining the trimesh
163 * @param[in] n_p size of points array
164 * @param[in] s decimation settings
165 *
166 * NOTE: This routine will not produce a points array that includes only the
167 * points used in the decimated mesh - to generate that output, use the
168 * bg_trimesh_3d_gc routine with the ofaces set produced by this function.
169 *
170 * @return -1 if error, 0 if successful */
171BG_EXPORT extern int bg_trimesh_decimate(int **ofaces, int *n_ofaces,
172 int *ifaces, int n_ifaces, point_t *p, int n_p, struct bg_trimesh_decimation_settings *s);
173
174
175/* Make an attempt at a trimesh intersection calculator that returns the sets
176 * of faces intersecting and inside the other for each mesh. Doesn't attempt
177 * a boolean evaluation, just characterizes faces */
178BG_EXPORT extern int
180 int **faces_inside_1, int *num_faces_inside_1, int **faces_inside_2, int *num_faces_inside_2,
181 int **faces_isect_1, int *num_faces_isect_1, int **faces_isect_2, int *num_faces_isect_2,
182 int *faces_1, int num_faces_1, point_t *vertices_1, int num_vertices_1,
183 int *faces_2, int num_faces_2, point_t *vertices_2, int num_vertices_2);
184
185/**
186 * @brief
187 * Compute vertex normals for a mesh based on the connected faces.
188 *
189 * @param[out] onorms array of normals - will have the same length as the input points array
190 * @param[in] ifaces array of input trimesh
191 * @param[in] n_ifaces size of input faces array
192 * @param[in] p array that holds the points defining the trimesh
193 * @param[in] n_p size of points array
194 *
195 * NOTE: Any vertex point not used by the triangles in the trimesh will have a
196 * zero normal in the onorms array. This routine does not repack the data to
197 * eliminate unused vertices - for that use bg_trimesh_optimize
198 *
199 * @return -1 if error, 0 if successful */
200BG_EXPORT extern int bg_trimesh_normals(vect_t **onorms, int *ifaces, int n_ifaces, point_t *p, int n_p);
201
202
203/* Various additional mesh optimization steps that can be enabled
204 * NOTE: If we want to look at exposing the capabilities of something like
205 * https://github.com/zeux/meshoptimizer this would be the place to start... */
207 int collapse_degenerate; // Remove degenerate faces
208 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
209 fastf_t max_runtime; // If the optimization takes more than max_runtime seconds, abort
210 size_t max_threads; // Don't use more than max_threads when processing.
211};
212
213#define BG_TRIMESH_OPTIMIZATION_SETTINGS_INIT {0, 0.0, 0.0, 0}
214
215/**
216 * @brief
217 * Return trimesh information for a 3D mesh that contains just the date needed
218 * to represent in the mesh. Used to finalize intermediate processing meshes
219 * to generate a compact mesh for export or storage.
220 *
221 * @param[out] ofaces faces array for the new output mesh with new indices based on opnts array.
222 * @param[out] n_ofaces length of ofaces array
223 * @param[out] opnts compact points array for the new output mesh.
224 * @param[out] onorms (optional) compact normals array for the output mesh's points.
225 * @param[out] n_opnts length of opnts array.
226 * @param[in] ifaces array of input trimesh
227 * @param[in] n_ifaces size of input faces array
228 * @param[in] ipnts array that holds the points defining the original trimesh
229 * @param[in] inorms (optional) array that holds the normals for the mesh vertices
230 * @param[in] s (optional) settings to enable various additional processing steps
231 *
232 * @return -1 if error, number of faces in new trimesh if successful
233 */
234BG_EXPORT extern int bg_trimesh_optimize(
235 int **ofaces, int *n_ofaces,
236 point_t **opnts, vect_t **onorms, int *n_opnts,
237 const int *ifaces, int n_ifaces,
238 const point_t *ipnts, const vect_t *inorms,
240
241
242/**
243 * @brief
244 * Return trimesh information for a planar (2D) mesh that contains just the set
245 * of points active in the mesh.
246 *
247 * @param[out] ofaces faces array for the new output mesh
248 * @param[out] n_ofaces length of ofaces array
249 * @param[out] opnts points array for the new output mesh
250 * @param[out] n_opnts length of opnts array
251 * @param[in] ifaces array of input trimesh
252 * @param[in] n_ifaces size of input faces array
253 * @param[in] ipnts array that holds the points defining the original trimesh
254 *
255 * @return -1 if error, number of faces in new trimesh if successful (should
256 * match the original face count)
257 */
258BG_EXPORT extern int bg_trimesh_2d_gc(int **ofaces, int *n_ofaces, point2d_t **opnts, int *n_opnts,
259 const int *ifaces, int n_ifaces, const point2d_t *ipnts);
260
261/**
262 * @brief
263 * Return trimesh information for a 3D mesh that contains just the set
264 * of points active in the mesh.
265 *
266 * @param[out] ofaces faces array for the new output mesh.
267 * @param[out] opnts points array for the new output mesh.
268 * @param[out] n_opnts length of opnts array.
269 * @param[in] faces array of input trimesh
270 * @param[in] num_faces size of input faces array
271 * @param[in] in_pts holds the points defining the original trimesh
272 *
273 * @return -1 if error, number of faces in new trimesh if successful (should
274 * match the original face count)
275 */
276BG_EXPORT extern int bg_trimesh_3d_gc(int **ofaces, point_t **opnts, int *n_opnts,
277 const int *faces, int num_faces, const point_t *in_pts);
278
279/**
280 * @brief
281 * Return a face set where all topologically connected faces are oriented
282 * consistently relative to their neighbors.
283 *
284 * @param[out] of faces array for the new output mesh (of==f is valid).
285 * @param[in] f input set of faces.
286 * @param[in] fcnt input face count
287 *
288 * @return -1 if error, otherwise return the number of times a face flipping
289 * operation was performed
290 */
291BG_EXPORT extern int
292bg_trimesh_sync(int *of, int *f, int fcnt);
293
294/**
295 * @brief
296 * Return a set of face sets where all topologically connected faces are
297 * grouped into common sets.
298 *
299 * @param[out] ofs array of faces arrays containing the new output face sets.
300 * @param[out] ofc array of face counts for the new output face sets.
301 * @param[in] f input set of faces.
302 * @param[in] fcnt input face count
303 *
304 * @return -1 if error, otherwise return the number of face sets created
305 */
306BG_EXPORT extern int
307bg_trimesh_split(int ***ofs, int **ofc, int *f, int fcnt);
308
309/**
310 * @brief
311 * Return a set of face sets where all topologically connected faces are
312 * grouped into common sets.
313 *
314 * @param[in] fname plot file name
315 * @param[in] faces face index array
316 * @param[in] num_faces number of faces
317 * @param[in] pnts points array
318 * @param[in] num_pnts number of points
319 *
320 * @return BRLCAD_ERROR if error, otherwise return BRLCAD_OK
321 */
322BG_EXPORT extern int
323bg_trimesh_2d_plot3(const char *fname, const int *faces, size_t num_faces, const point2d_t *pnts, size_t num_pnts);
324
325__END_DECLS
326
327#endif /* BG_TRIMESH_H */
328/** @} */
329/*
330 * Local Variables:
331 * mode: C
332 * tab-width: 8
333 * indent-tabs-mode: t
334 * c-file-style: "stroustrup"
335 * End:
336 * ex: shiftwidth=4 tabstop=8
337 */
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_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_excess_edges(int num_edges, struct bg_trimesh_halfedge *edge_list, bg_edge_error_funct_t error_edge_func, void *data)
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.
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_2d_gc(int **ofaces, int *n_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_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)
void bg_free_trimesh_edges(struct bg_trimesh_edges *edges)
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_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_split(int ***ofs, int **ofc, int *f, int fcnt)
Return a set of face sets where all topologically connected faces are grouped into common sets.
int(* bg_face_error_func_t)(int face_idx, void *data)
Definition: trimesh.h:102
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_edge_error_funct_t)(struct bg_trimesh_halfedge *edge, void *data)
Definition: trimesh.h:103
void bg_free_trimesh_faces(struct bg_trimesh_faces *faces)
int bg_trimesh_solid(int vcnt, int fcnt, fastf_t *v, int *f, int **bedges)
void int char int int double * min
Definition: tig.h:182
fastf_t vect_t[ELEMENTS_PER_VECT]
3-tuple vector
Definition: vmath.h:345
double fastf_t
fastest 64-bit (or larger) floating point type
Definition: vmath.h:330
fastf_t point2d_t[ELEMENTS_PER_POINT2D]
2-tuple point
Definition: vmath.h:339
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition: vmath.h:351
Algorithms related to 3D meshes built from triangles.
Definition: trimesh.h:40
struct bg_trimesh_edges excess
Definition: trimesh.h:59
struct bg_trimesh_edges misoriented
Definition: trimesh.h:60
struct bg_trimesh_faces degenerate
Definition: trimesh.h:57
struct bg_trimesh_edges unmatched
Definition: trimesh.h:58
NMG topological edge.
Definition: topology.h:144
fundamental vector, matrix, quaternion math macros