BRL-CAD
loop.h
Go to the documentation of this file.
1 /* L O O P . 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 /** @addtogroup nmg_loop */
23 /** @{ */
24 /** @file nmg/loop.h */
25 
26 #ifndef NMG_LOOP_H
27 #define NMG_LOOP_H
28 
29 #include "common.h"
30 
31 #include "vmath.h"
32 #include "bu/list.h"
33 #include "nmg/defines.h"
34 #include "nmg/topology.h"
35 
36 __BEGIN_DECLS
37 
38 #define NMG_CK_LOOP(_p) NMG_CKMAG(_p, NMG_LOOP_MAGIC, "loop")
39 #define NMG_CK_LOOP_A(_p) NMG_CKMAG(_p, NMG_LOOP_A_MAGIC, "loop_a")
40 #define NMG_CK_LOOPUSE(_p) NMG_CKMAG(_p, NMG_LOOPUSE_MAGIC, "loopuse")
41 
42 #define GET_LOOP(p, m) {NMG_GETSTRUCT(p, loop); NMG_INCR_INDEX(p, m);}
43 #define GET_LOOP_A(p, m) {NMG_GETSTRUCT(p, loop_a); NMG_INCR_INDEX(p, m);}
44 #define GET_LOOPUSE(p, m) {NMG_GETSTRUCT(p, loopuse); NMG_INCR_INDEX(p, m);}
45 #define GET_LOOPUSE_A(p, m) {NMG_GETSTRUCT(p, loopuse_a); NMG_INCR_INDEX(p, m);}
46 
47 #define FREE_LOOP(p) NMG_FREESTRUCT(p, loop)
48 #define FREE_LOOP_A(p) NMG_FREESTRUCT(p, loop_a)
49 #define FREE_LOOPUSE(p) NMG_FREESTRUCT(p, loopuse)
50 #define FREE_LOOPUSE_A(p) NMG_FREESTRUCT(p, loopuse_a)
51 
52 /**
53  * @brief Build the bounding box for a loop.
54  *
55  * The bounding box is guaranteed never to have zero thickness.
56  *
57  * XXX This really isn't loop geometry, this is a loop attribute. This routine
58  * really should be called nmg_loop_bb(), unless it gets something more to do.
59  */
60 NMG_EXPORT extern void nmg_loop_a(struct loop *l,
61  const struct bn_tol *tol);
62 
63 /**
64  * @brief Demote a loopuse of edgeuses to a bunch of wire edges in the shell.
65  *
66  * @retval 0 If all is well (edges moved to shell, loopuse deleted).
67  * @retval 1 If parent is empty, and is thus "illegal". Still successful.
68  */
69 NMG_EXPORT extern int nmg_demote_lu(struct loopuse *lu);
70 
71 /**
72  * @brief Make a new loop (with specified orientation) and vertex, in a shell
73  * or face.
74  * XXX - vertex or vertexuse? or both? ctj
75  *
76  * If the vertex 'v' is NULL, the shell's lone vertex is used, or a new vertex
77  * is created.
78  *
79  * "magic" must point to the magic number of a faceuse or shell.
80  *
81  * If the shell has a lone vertex in it, that lone vertex *will* be used. If a
82  * non-NULL 'v' is provided, the lone vertex and 'v' will be fused together.
83  * XXX Why is this good?
84  *
85  * If a convenient shell does not exist, use s=nmg_msv() to make the shell and
86  * vertex, then call lu=nmg_mlv(s, s->vu_p->v_p, OT_SAME), followed by
87  * nmg_kvu(s->vu_p).
88  *
89  * Implicit returns -
90  * The new vertexuse can be had by:
91  * BU_LIST_FIRST(vertexuse, &lu->down_hd);
92  *
93  * In case the returned loopuse isn't retained, the new loopuse was
94  * inserted at the +head+ of the appropriate list, e.g.:
95  * lu = BU_LIST_FIRST(loopuse, &fu->lu_hd);
96  * or
97  * lu = BU_LIST_FIRST(loopuse, &s->lu_hd);
98  *
99  * N.B. This function is made more complex than warranted by using the "hack"
100  * of stealing a vertexuse structure from the shell if at all possible. A
101  * future enhancement to this function would be to remove the vertexuse steal
102  * and have the caller pass in the vertex from the shell followed by a call to
103  * nmg_kvu(s->vu_p). The v==NULL convention is used only in nmg_mod.c.
104  */
105 NMG_EXPORT extern struct loopuse *nmg_mlv(uint32_t *magic,
106  struct vertex *v,
107  int orientation);
108 
109 /**
110  * @brief Kill loopuse, loopuse mate, and loop.
111  *
112  * if the loop contains any edgeuses or vertexuses they are killed
113  * before the loop is deleted.
114  *
115  * We support the concept of killing a loop with no children to
116  * support the routine "nmg_demote_lu"
117  *
118  * @retval 0 If all is well
119  * @retval 1 If parent is empty, and is thus "illegal"
120  */
121 NMG_EXPORT extern int nmg_klu(struct loopuse *lu1);
122 
123 /**
124  * @brief Join two loops together which share a common edge, such that both
125  * occurrences of the common edge are deleted.
126  *
127  * This routine always leaves "lu" intact, and kills the loop radial to "eu"
128  * (after stealing all its edges).
129  *
130  * Either both loops must be of the same orientation, or then first
131  * loop must be OT_SAME, and the second loop must be OT_OPPOSITE.
132  * Joining OT_SAME & OT_OPPOSITE always gives an OT_SAME result.
133  * Above statement is not true!!!! I have added nmg_lu_reorient() -JRA
134  * Since "lu" must survive, it must be the OT_SAME one.
135  */
136 NMG_EXPORT extern void nmg_jl(struct loopuse *lu,
137  struct edgeuse *eu);
138 
139 /**
140  * @brief Intended to join an interior and exterior loop together, by
141  * building a bridge between the two indicated vertices.
142  *
143  * This routine can be used to join two exterior loops which do not
144  * overlap, and it can also be used to join an exterior loop with a
145  * loop of opposite orientation that lies entirely within it. This
146  * restriction is important, but not checked for.
147  *
148  * If the two vertexuses reference distinct vertices, then two new
149  * edges are built to bridge the loops together. If the two
150  * vertexuses share the same vertex, then it is even easier.
151  *
152  * Returns the replacement for vu2.
153  */
154 NMG_EXPORT extern struct vertexuse *nmg_join_2loops(struct vertexuse *vu1,
155  struct vertexuse *vu2);
156 
157 /**
158  * @brief vu1 is in a regular loop, vu2 is in a loop of a single vertex A
159  * jaunt is taken from vu1 to vu2 and back to vu1, and the old loop at
160  * vu2 is destroyed.
161  *
162  * Return is the new vu that replaces vu2.
163  */
164 NMG_EXPORT extern struct vertexuse *nmg_join_singvu_loop(struct vertexuse *vu1,
165  struct vertexuse *vu2);
166 
167 /**
168  * @brief Both vertices are part of single vertex loops. Converts loop on
169  * vu1 into a real loop that connects them together, with a single
170  * edge (two edgeuses). Loop on vu2 is killed.
171  *
172  * Returns replacement vu for vu2.
173  * Does not change the orientation.
174  */
175 NMG_EXPORT extern struct vertexuse *nmg_join_2singvu_loops(struct vertexuse *vu1,
176  struct vertexuse *vu2);
177 
178 /**
179  * @brief Divide a loop of edges between two vertexuses.
180  *
181  * Make a new loop between the two vertexes, and split it and the loop of the
182  * vertexuses at the same time.
183  *
184  * @verbatim
185  BEFORE AFTER
186 
187 
188  Va eu1 vu1 Vb Va eu1 vu1 Vb
189  * <---------* <---------* * <--------* * <--------*
190  | | |
191  | ^ | ^ | ^
192  | Original | | Original | | New |
193  | Loopuse | | Loopuse | | Loopuse |
194  V | V | V / |
195  | | / |
196  *----------> *--------> * *--------> * *--------> *
197  Vd vu2 eu2 Vc Vd vu2 eu2 Vc
198  @endverbatim
199  *
200  * Returns the new loopuse pointer. The new loopuse will contain "vu2" and the
201  * edgeuse associated with "vu2" as the FIRST edgeuse on the list of edgeuses.
202  * The edgeuse for the new edge (connecting the vertices indicated by vu1 and
203  * vu2) will be the LAST edgeuse on the new loopuse's list of edgeuses.
204  *
205  * It is the caller's responsibility to re-bound the loops.
206  *
207  * Both old and new loopuse will have orientation OT_UNSPEC. It is the callers
208  * responsibility to determine what the orientations should be. This can be
209  * conveniently done with nmg_lu_reorient().
210  *
211  * Here is a simple example of how the new loopuse might have a different
212  * orientation than the original one:
213  *
214  * @verbatim
215  F<----------------E
216  | ^
217  | |
218  | C--------->D
219  | ^ .
220  | | .
221  | | .
222  | B<---------A
223  | ^
224  v |
225  G---------------->H
226  @endverbatim
227  *
228  * When nmg_cut_loop(A, D) is called, the new loop ABCD is clockwise, even
229  * though the original loop was counter-clockwise. There is no way to
230  * determine this without referring to the face normal and vertex geometry,
231  * which being a topology routine this routine shouldn't do.
232  *
233  * @retval NULL on error
234  * @retval lu on success, loopuse of new loop.
235  */
236 NMG_EXPORT extern struct loopuse *nmg_cut_loop(struct vertexuse *vu1,
237  struct vertexuse *vu2,
238  struct bu_list *vlfree);
239 
240 NMG_EXPORT extern struct loopuse *nmg_split_lu_at_vu(struct loopuse *lu,
241  struct vertexuse *vu);
242 NMG_EXPORT extern struct vertexuse *nmg_find_repeated_v_in_lu(struct vertexuse *vu);
243 NMG_EXPORT extern void nmg_split_touchingloops(struct loopuse *lu,
244  const struct bn_tol *tol);
245 NMG_EXPORT extern int nmg_join_touchingloops(struct loopuse *lu);
246 NMG_EXPORT extern int nmg_get_touching_jaunts(const struct loopuse *lu,
247  struct bu_ptbl *tbl,
248  int *need_init);
249 NMG_EXPORT extern void nmg_kill_accordions(struct loopuse *lu);
250 NMG_EXPORT extern int nmg_loop_split_at_touching_jaunt(struct loopuse *lu,
251  const struct bn_tol *tol);
252 NMG_EXPORT extern void nmg_simplify_loop(struct loopuse *lu, struct bu_list *vlfree);
253 NMG_EXPORT extern int nmg_kill_snakes(struct loopuse *lu, struct bu_list *vlfree);
254 NMG_EXPORT extern void nmg_mv_lu_between_shells(struct shell *dest,
255  struct shell *src,
256  struct loopuse *lu);
257 NMG_EXPORT extern void nmg_moveltof(struct faceuse *fu,
258  struct shell *s);
259 NMG_EXPORT extern struct loopuse *nmg_dup_loop(struct loopuse *lu,
260  uint32_t *parent,
261  long **trans_tbl);
262 NMG_EXPORT extern void nmg_set_lu_orientation(struct loopuse *lu,
263  int is_opposite);
264 NMG_EXPORT extern void nmg_lu_reorient(struct loopuse *lu);
265 /* EDGE Routines */
266 NMG_EXPORT extern struct edgeuse *nmg_eusplit(struct vertex *v,
267  struct edgeuse *oldeu,
268  int share_geom);
269 NMG_EXPORT extern struct edgeuse *nmg_esplit(struct vertex *v,
270  struct edgeuse *eu,
271  int share_geom);
272 NMG_EXPORT extern struct edgeuse *nmg_ebreak(struct vertex *v,
273  struct edgeuse *eu);
274 NMG_EXPORT extern struct edgeuse *nmg_ebreaker(struct vertex *v,
275  struct edgeuse *eu,
276  const struct bn_tol *tol);
277 NMG_EXPORT extern struct vertex *nmg_e2break(struct edgeuse *eu1,
278  struct edgeuse *eu2);
279 NMG_EXPORT extern int nmg_unbreak_edge(struct edgeuse *eu1_first);
280 NMG_EXPORT extern int nmg_unbreak_shell_edge_unsafe(struct edgeuse *eu1_first);
281 NMG_EXPORT extern struct edgeuse *nmg_eins(struct edgeuse *eu);
282 NMG_EXPORT extern void nmg_mv_eu_between_shells(struct shell *dest,
283  struct shell *src,
284  struct edgeuse *eu);
285 
286 NMG_EXPORT extern struct loopuse*nmg_find_lu_of_vu(const struct vertexuse *vu);
287 NMG_EXPORT extern int nmg_loop_is_a_crack(const struct loopuse *lu);
288 NMG_EXPORT extern int nmg_loop_is_ccw(const struct loopuse *lu,
289  const vect_t norm,
290  const struct bn_tol *tol);
291 NMG_EXPORT extern const struct vertexuse *nmg_loop_touches_self(const struct loopuse *lu);
292 NMG_EXPORT extern int nmg_2lu_identical(const struct edgeuse *eu1,
293  const struct edgeuse *eu2);
294 
295 NMG_EXPORT extern struct vertexuse *nmg_find_pnt_in_lu(const struct loopuse *lu,
296  const point_t pt,
297  const struct bn_tol *tol);
298 NMG_EXPORT extern int nmg_is_vertex_in_looplist(const struct vertex *v,
299  const struct bu_list *hd,
300  int singletons);
301 
302 NMG_EXPORT extern int nmg_is_edge_in_looplist(const struct edge *e,
303  const struct bu_list *hd);
304 
305 NMG_EXPORT extern struct vertexuse *nmg_find_vertex_in_lu(const struct vertex *v, const struct loopuse *lu);
306 NMG_EXPORT extern void nmg_fix_overlapping_loops(struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol);
307 NMG_EXPORT extern void nmg_break_crossed_loops(struct shell *is, const struct bn_tol *tol);
308 
309 NMG_EXPORT extern void nmg_loop_plane_newell(const struct loopuse *lu,
310  plane_t pl);
311 NMG_EXPORT extern fastf_t nmg_loop_plane_area(const struct loopuse *lu,
312  plane_t pl);
313 NMG_EXPORT extern fastf_t nmg_loop_plane_area2(const struct loopuse *lu,
314  plane_t pl,
315  const struct bn_tol *tol);
316 NMG_EXPORT extern fastf_t nmg_loop_plane_area(const struct loopuse *lu,
317  plane_t pl);
318 NMG_EXPORT extern int nmg_lu_is_convex(struct loopuse *lu,
319  struct bu_list *vlfree,
320  const struct bn_tol *tol);
321 NMG_EXPORT extern int nmg_classify_pnt_loop(const point_t pt,
322  const struct loopuse *lu,
323  struct bu_list *vlfree,
324  const struct bn_tol *tol);
325 
326 NMG_EXPORT extern int nmg_classify_lu_lu(const struct loopuse *lu1,
327  const struct loopuse *lu2,
328  struct bu_list *vlfree,
329  const struct bn_tol *tol);
330 NMG_EXPORT extern int nmg_class_pnt_lu_except(point_t pt,
331  const struct loopuse *lu,
332  const struct edge *e_p,
333  struct bu_list *vlfree,
334  const struct bn_tol *tol);
335 NMG_EXPORT extern void nmg_ck_lu_orientation(struct loopuse *lu,
336  const struct bn_tol *tolp);
337 
338 
339 __END_DECLS
340 
341 #endif /* NMG_LOOP_H */
342 /** @} */
343 /*
344  * Local Variables:
345  * mode: C
346  * tab-width: 8
347  * indent-tabs-mode: t
348  * c-file-style: "stroustrup"
349  * End:
350  * ex: shiftwidth=4 tabstop=8
351  */
Header file for the BRL-CAD common definitions.
struct vertexuse * nmg_join_singvu_loop(struct vertexuse *vu1, struct vertexuse *vu2)
vu1 is in a regular loop, vu2 is in a loop of a single vertex A jaunt is taken from vu1 to vu2 and ba...
void nmg_kill_accordions(struct loopuse *lu)
void nmg_lu_reorient(struct loopuse *lu)
struct edgeuse * nmg_eusplit(struct vertex *v, struct edgeuse *oldeu, int share_geom)
int nmg_loop_is_ccw(const struct loopuse *lu, const vect_t norm, const struct bn_tol *tol)
struct loopuse * nmg_dup_loop(struct loopuse *lu, uint32_t *parent, long **trans_tbl)
int nmg_unbreak_shell_edge_unsafe(struct edgeuse *eu1_first)
int nmg_is_vertex_in_looplist(const struct vertex *v, const struct bu_list *hd, int singletons)
fastf_t nmg_loop_plane_area2(const struct loopuse *lu, plane_t pl, const struct bn_tol *tol)
void nmg_break_crossed_loops(struct shell *is, const struct bn_tol *tol)
int nmg_lu_is_convex(struct loopuse *lu, struct bu_list *vlfree, const struct bn_tol *tol)
struct edgeuse * nmg_ebreaker(struct vertex *v, struct edgeuse *eu, const struct bn_tol *tol)
void nmg_jl(struct loopuse *lu, struct edgeuse *eu)
Join two loops together which share a common edge, such that both occurrences of the common edge are ...
struct vertexuse * nmg_find_pnt_in_lu(const struct loopuse *lu, const point_t pt, const struct bn_tol *tol)
int nmg_2lu_identical(const struct edgeuse *eu1, const struct edgeuse *eu2)
void nmg_loop_plane_newell(const struct loopuse *lu, plane_t pl)
int nmg_class_pnt_lu_except(point_t pt, const struct loopuse *lu, const struct edge *e_p, struct bu_list *vlfree, const struct bn_tol *tol)
struct loopuse * nmg_mlv(uint32_t *magic, struct vertex *v, int orientation)
Make a new loop (with specified orientation) and vertex, in a shell or face. XXX - vertex or vertexus...
struct vertexuse * nmg_join_2loops(struct vertexuse *vu1, struct vertexuse *vu2)
Intended to join an interior and exterior loop together, by building a bridge between the two indicat...
int nmg_is_edge_in_looplist(const struct edge *e, const struct bu_list *hd)
int nmg_join_touchingloops(struct loopuse *lu)
int nmg_unbreak_edge(struct edgeuse *eu1_first)
int nmg_kill_snakes(struct loopuse *lu, struct bu_list *vlfree)
struct edgeuse * nmg_esplit(struct vertex *v, struct edgeuse *eu, int share_geom)
const struct vertexuse * nmg_loop_touches_self(const struct loopuse *lu)
struct loopuse * nmg_find_lu_of_vu(const struct vertexuse *vu)
struct edgeuse * nmg_eins(struct edgeuse *eu)
void nmg_mv_lu_between_shells(struct shell *dest, struct shell *src, struct loopuse *lu)
int nmg_loop_is_a_crack(const struct loopuse *lu)
void nmg_simplify_loop(struct loopuse *lu, struct bu_list *vlfree)
struct edgeuse * nmg_ebreak(struct vertex *v, struct edgeuse *eu)
void nmg_set_lu_orientation(struct loopuse *lu, int is_opposite)
struct vertexuse * nmg_join_2singvu_loops(struct vertexuse *vu1, struct vertexuse *vu2)
Both vertices are part of single vertex loops. Converts loop on vu1 into a real loop that connects th...
void nmg_loop_a(struct loop *l, const struct bn_tol *tol)
Build the bounding box for a loop.
void nmg_moveltof(struct faceuse *fu, struct shell *s)
void nmg_mv_eu_between_shells(struct shell *dest, struct shell *src, struct edgeuse *eu)
struct vertexuse * nmg_find_repeated_v_in_lu(struct vertexuse *vu)
void nmg_fix_overlapping_loops(struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol)
struct vertexuse * nmg_find_vertex_in_lu(const struct vertex *v, const struct loopuse *lu)
int nmg_classify_lu_lu(const struct loopuse *lu1, const struct loopuse *lu2, struct bu_list *vlfree, const struct bn_tol *tol)
fastf_t nmg_loop_plane_area(const struct loopuse *lu, plane_t pl)
int nmg_klu(struct loopuse *lu1)
Kill loopuse, loopuse mate, and loop.
int nmg_classify_pnt_loop(const point_t pt, const struct loopuse *lu, struct bu_list *vlfree, const struct bn_tol *tol)
int nmg_get_touching_jaunts(const struct loopuse *lu, struct bu_ptbl *tbl, int *need_init)
struct loopuse * nmg_split_lu_at_vu(struct loopuse *lu, struct vertexuse *vu)
void nmg_ck_lu_orientation(struct loopuse *lu, const struct bn_tol *tolp)
int nmg_demote_lu(struct loopuse *lu)
Demote a loopuse of edgeuses to a bunch of wire edges in the shell.
struct loopuse * nmg_cut_loop(struct vertexuse *vu1, struct vertexuse *vu2, struct bu_list *vlfree)
Divide a loop of edges between two vertexuses.
struct vertex * nmg_e2break(struct edgeuse *eu1, struct edgeuse *eu2)
void nmg_split_touchingloops(struct loopuse *lu, const struct bn_tol *tol)
int nmg_loop_split_at_touching_jaunt(struct loopuse *lu, const struct bn_tol *tol)
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 plane_t[ELEMENTS_PER_PLANE]
Definition of a plane equation.
Definition: vmath.h:397
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition: vmath.h:355
Definition: tol.h:72
Definition: list.h:132
Definition: ptbl.h:53
NMG topological edge.
Definition: topology.h:144
NMG topological edge usage.
Definition: topology.h:155
NMG topological face usage.
Definition: topology.h:230
NMG topological loop.
Definition: topology.h:181
NMG topological loop usage.
Definition: topology.h:192
int orientation
OT_SAME=outside loop.
Definition: topology.h:200
NMG topological shell.
Definition: topology.h:261
NMG topological vertex - the simplest element of the topology system.
Definition: topology.h:98
NMG topological vertex usage.
Definition: topology.h:109
struct bu_list l
list of all vu's on a vertex
Definition: topology.h:110
fundamental vector, matrix, quaternion math macros