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-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/** @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 */
60NMG_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 */
69NMG_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 */
105NMG_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 */
121NMG_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 */
136NMG_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 */
154NMG_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 */
164NMG_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 */
175NMG_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 */
236NMG_EXPORT extern struct loopuse *nmg_cut_loop(struct vertexuse *vu1,
237 struct vertexuse *vu2,
238 struct bu_list *vlfree);
239
240NMG_EXPORT extern struct loopuse *nmg_split_lu_at_vu(struct loopuse *lu,
241 struct vertexuse *vu);
242NMG_EXPORT extern struct vertexuse *nmg_find_repeated_v_in_lu(struct vertexuse *vu);
243NMG_EXPORT extern void nmg_split_touchingloops(struct loopuse *lu,
244 const struct bn_tol *tol);
245NMG_EXPORT extern int nmg_join_touchingloops(struct loopuse *lu);
246NMG_EXPORT extern int nmg_get_touching_jaunts(const struct loopuse *lu,
247 struct bu_ptbl *tbl,
248 int *need_init);
249NMG_EXPORT extern void nmg_kill_accordions(struct loopuse *lu);
250NMG_EXPORT extern int nmg_loop_split_at_touching_jaunt(struct loopuse *lu,
251 const struct bn_tol *tol);
252NMG_EXPORT extern void nmg_simplify_loop(struct loopuse *lu, struct bu_list *vlfree);
253NMG_EXPORT extern int nmg_kill_snakes(struct loopuse *lu, struct bu_list *vlfree);
254NMG_EXPORT extern void nmg_mv_lu_between_shells(struct shell *dest,
255 struct shell *src,
256 struct loopuse *lu);
257NMG_EXPORT extern void nmg_moveltof(struct faceuse *fu,
258 struct shell *s);
259NMG_EXPORT extern struct loopuse *nmg_dup_loop(struct loopuse *lu,
260 uint32_t *parent,
261 long **trans_tbl);
262NMG_EXPORT extern void nmg_set_lu_orientation(struct loopuse *lu,
263 int is_opposite);
264NMG_EXPORT extern void nmg_lu_reorient(struct loopuse *lu);
265/* EDGE Routines */
266NMG_EXPORT extern struct edgeuse *nmg_eusplit(struct vertex *v,
267 struct edgeuse *oldeu,
268 int share_geom);
269NMG_EXPORT extern struct edgeuse *nmg_esplit(struct vertex *v,
270 struct edgeuse *eu,
271 int share_geom);
272NMG_EXPORT extern struct edgeuse *nmg_ebreak(struct vertex *v,
273 struct edgeuse *eu);
274NMG_EXPORT extern struct edgeuse *nmg_ebreaker(struct vertex *v,
275 struct edgeuse *eu,
276 const struct bn_tol *tol);
277NMG_EXPORT extern struct vertex *nmg_e2break(struct edgeuse *eu1,
278 struct edgeuse *eu2);
279NMG_EXPORT extern int nmg_unbreak_edge(struct edgeuse *eu1_first);
280NMG_EXPORT extern int nmg_unbreak_shell_edge_unsafe(struct edgeuse *eu1_first);
281NMG_EXPORT extern struct edgeuse *nmg_eins(struct edgeuse *eu);
282NMG_EXPORT extern void nmg_mv_eu_between_shells(struct shell *dest,
283 struct shell *src,
284 struct edgeuse *eu);
285
286NMG_EXPORT extern struct loopuse*nmg_find_lu_of_vu(const struct vertexuse *vu);
287NMG_EXPORT extern int nmg_loop_is_a_crack(const struct loopuse *lu);
288NMG_EXPORT extern int nmg_loop_is_ccw(const struct loopuse *lu,
289 const vect_t norm,
290 const struct bn_tol *tol);
291NMG_EXPORT extern const struct vertexuse *nmg_loop_touches_self(const struct loopuse *lu);
292NMG_EXPORT extern int nmg_2lu_identical(const struct edgeuse *eu1,
293 const struct edgeuse *eu2);
294
295NMG_EXPORT extern struct vertexuse *nmg_find_pnt_in_lu(const struct loopuse *lu,
296 const point_t pt,
297 const struct bn_tol *tol);
298NMG_EXPORT extern int nmg_is_vertex_in_looplist(const struct vertex *v,
299 const struct bu_list *hd,
300 int singletons);
301
302NMG_EXPORT extern int nmg_is_edge_in_looplist(const struct edge *e,
303 const struct bu_list *hd);
304
305NMG_EXPORT extern struct vertexuse *nmg_find_vertex_in_lu(const struct vertex *v, const struct loopuse *lu);
306NMG_EXPORT extern void nmg_fix_overlapping_loops(struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol);
307NMG_EXPORT extern void nmg_break_crossed_loops(struct shell *is, const struct bn_tol *tol);
308
309NMG_EXPORT extern void nmg_loop_plane_newell(const struct loopuse *lu,
310 plane_t pl);
311NMG_EXPORT extern fastf_t nmg_loop_plane_area(const struct loopuse *lu,
312 plane_t pl);
313NMG_EXPORT extern fastf_t nmg_loop_plane_area2(const struct loopuse *lu,
314 plane_t pl,
315 const struct bn_tol *tol);
316NMG_EXPORT extern fastf_t nmg_loop_plane_area(const struct loopuse *lu,
317 plane_t pl);
318NMG_EXPORT extern int nmg_lu_is_convex(struct loopuse *lu,
319 struct bu_list *vlfree,
320 const struct bn_tol *tol);
321NMG_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
326NMG_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);
330NMG_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);
335NMG_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.
void nmg_kill_accordions(struct loopuse *lu)
struct edgeuse * nmg_eusplit(struct vertex *v, struct edgeuse *oldeu, int share_geom)
struct edgeuse * nmg_ebreak(struct vertex *v, struct edgeuse *eu)
struct edgeuse * nmg_eins(struct edgeuse *eu)
void nmg_lu_reorient(struct loopuse *lu)
int nmg_loop_is_ccw(const struct loopuse *lu, const vect_t norm, const struct bn_tol *tol)
struct vertexuse * nmg_find_repeated_v_in_lu(struct vertexuse *vu)
int nmg_unbreak_shell_edge_unsafe(struct edgeuse *eu1_first)
struct vertex * nmg_e2break(struct edgeuse *eu1, struct edgeuse *eu2)
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)
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 ...
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 edgeuse * nmg_esplit(struct vertex *v, struct edgeuse *eu, int share_geom)
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...
int nmg_is_edge_in_looplist(const struct edge *e, const struct bu_list *hd)
int nmg_join_touchingloops(struct loopuse *lu)
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...
int nmg_unbreak_edge(struct edgeuse *eu1_first)
int nmg_kill_snakes(struct loopuse *lu, struct bu_list *vlfree)
struct loopuse * nmg_split_lu_at_vu(struct loopuse *lu, struct vertexuse *vu)
const struct vertexuse * nmg_loop_touches_self(const struct loopuse *lu)
struct vertexuse * nmg_find_vertex_in_lu(const struct vertex *v, const struct loopuse *lu)
struct edgeuse * nmg_ebreaker(struct vertex *v, struct edgeuse *eu, const struct bn_tol *tol)
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)
void nmg_set_lu_orientation(struct loopuse *lu, int is_opposite)
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_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...
void nmg_fix_overlapping_loops(struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol)
struct vertexuse * nmg_find_pnt_in_lu(const struct loopuse *lu, const point_t pt, const struct bn_tol *tol)
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)
struct loopuse * nmg_dup_loop(struct loopuse *lu, uint32_t *parent, long **trans_tbl)
int nmg_get_touching_jaunts(const struct loopuse *lu, struct bu_ptbl *tbl, int *need_init)
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 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_split_touchingloops(struct loopuse *lu, const struct bn_tol *tol)
struct loopuse * nmg_find_lu_of_vu(const struct vertexuse *vu)
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:345
double fastf_t
fastest 64-bit (or larger) floating point type
Definition: vmath.h:330
fastf_t plane_t[ELEMENTS_PER_PLANE]
Definition of a plane equation.
Definition: vmath.h:393
fastf_t point_t[ELEMENTS_PER_POINT]
3-tuple point
Definition: vmath.h:351
Definition: tol.h:72
Definition: list.h:131
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