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