BRL-CAD
edge.h
Go to the documentation of this file.
1/* E D G E . 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_edge */
23/** @{ */
24/** @file nmg/edge.h */
25
26#ifndef NMG_EDGE_H
27#define NMG_EDGE_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_EDGE(_p) NMG_CKMAG(_p, NMG_EDGE_MAGIC, "edge")
39#define NMG_CK_EDGE_G_LSEG(_p) NMG_CKMAG(_p, NMG_EDGE_G_LSEG_MAGIC, "edge_g_lseg")
40#define NMG_CK_EDGEUSE(_p) NMG_CKMAG(_p, NMG_EDGEUSE_MAGIC, "edgeuse")
41
42#define GET_EDGE(p, m) {NMG_GETSTRUCT(p, edge); NMG_INCR_INDEX(p, m);}
43#define GET_EDGE_G_LSEG(p, m) {NMG_GETSTRUCT(p, edge_g_lseg); NMG_INCR_INDEX(p, m);}
44#define GET_EDGE_G_CNURB(p, m) {NMG_GETSTRUCT(p, edge_g_cnurb); NMG_INCR_INDEX(p, m);}
45#define GET_EDGEUSE(p, m) {NMG_GETSTRUCT(p, edgeuse); NMG_INCR_INDEX(p, m);}
46
47#define FREE_EDGE(p) NMG_FREESTRUCT(p, edge)
48#define FREE_EDGE_G_LSEG(p) NMG_FREESTRUCT(p, edge_g_lseg)
49#define FREE_EDGE_G_CNURB(p) NMG_FREESTRUCT(p, edge_g_cnurb)
50#define FREE_EDGEUSE(p) NMG_FREESTRUCT(p, edgeuse)
51
52/**
53 * @brief Compute the equation of the line formed by the endpoints of the
54 * edge.
55 */
56NMG_EXPORT extern void nmg_edge_g(struct edgeuse *eu);
57
58/**
59 * @brief Associate edgeuse 'eu' with the edge geometry structure identified by
60 * 'magic_p', where magic_p is the pointer to the magic entry of an edge_g_lseg.
61 *
62 * Example magic_p keys: eu->g.magic_p &eg->l.magic
63 *
64 * If the edgeuse is already associated with some geometry, that geometry is
65 * first released. Note that, to start with, the two edgeuses may be using
66 * different original geometries.
67 *
68 * Also do the edgeuse mate.
69 *
70 * @retval 0 If the old edge geometry (eu->g.magic_p) has other uses.
71 * @retval 1 If the old edge geometry has been destroyed. Caller beware!
72 */
73NMG_EXPORT extern int nmg_use_edge_g(struct edgeuse *eu,
74 uint32_t *magic_p);
75
76/**
77 * @brief Demote a wire edge into a pair of self-loop vertices
78 *
79 * @retval 0 If all is well
80 * @retval 1 If shell is empty, and is thus "illegal".
81 */
82NMG_EXPORT extern int nmg_demote_eu(struct edgeuse *eu);
83
84/**
85 * @brief Move a pair of edgeuses onto a single edge (glue edgeuse).
86 *
87 * The edgeuse eusrc and its mate are moved to the edge used by eudst. eusrc
88 * is made to be immediately radial to eudst. If eusrc does not share the same
89 * vertices as eudst, we bomb.
90 *
91 * The edgeuse geometry pointers are not changed by this operation.
92 *
93 * This routine was formerly called nmg_moveeu().
94 */
95NMG_EXPORT extern void nmg_je(struct edgeuse *eudst,
96 struct edgeuse *eusrc);
97
98/**
99 * @brief If edgeuse is part of a shared edge (more than one pair of edgeuses
100 * on the edge), it and its mate are "unglued" from the edge, and associated
101 * with a new edge structure.
102 *
103 * Primarily a support routine for nmg_eusplit()
104 *
105 * If the original edge had edge geometry, that is *not* duplicated here,
106 * because it is not easy (or appropriate) for nmg_eusplit() to know whether
107 * the new vertex lies on the previous edge geometry or not. Hence having the
108 * nmg_ebreak() interface, which preserves the edge geometry across a split, and
109 * nmg_esplit() which does not.
110 */
111NMG_EXPORT extern void nmg_unglueedge(struct edgeuse *eu);
112
113/**
114 * @brief Join two edge geometries.
115 *
116 * For all edges in the model which refer to 'src_eg', change them to
117 * refer to 'dest_eg'. The source is destroyed.
118 *
119 * It is the responsibility of the caller to make certain that the
120 * 'dest_eg' is the best one for these edges. Outrageously wrong
121 * requests will cause this routine to abort.
122 *
123 * This algorithm does not make sense if dest_eg is an edge_g_cnurb;
124 * those only make sense in the parameter space of their associated
125 * face.
126 */
127NMG_EXPORT extern void nmg_jeg(struct edge_g_lseg *dest_eg,
128 struct edge_g_lseg *src_eg);
129
130/**
131 * @brief Make wire edge.
132 *
133 * Make a new edge between a pair of vertices in a shell.
134 *
135 * A new vertex will be made for any NULL vertex pointer parameters.
136 * If we need to make a new vertex and the shell still has its
137 * vertexuse we re-use that vertex rather than freeing and
138 * re-allocating.
139 *
140 * If both vertices were specified, and the shell also had a vertexuse
141 * pointer, the vertexuse in the shell is killed. XXX Why?
142 *
143 * The explicit result is an edgeuse in shell "s" whose vertexuse refers to
144 * vertex v1. The edgeuse mate's vertexuse refers to vertex v2
145 *
146 * Additional possible side effects:
147 * -# If the shell had a lone vertex in vu_p, it is destroyed, even if both
148 * vertices were specified.
149 * -# The returned edgeuse is the first item on the shell's eu_hd list,
150 * followed immediately by the mate.
151 */
152NMG_EXPORT extern struct edgeuse *nmg_me(struct vertex *v1,
153 struct vertex *v2,
154 struct shell *s);
155#define nmg_mev(_v, _u) nmg_me((_v), (struct vertex *)NULL, (_u))
156
157/**
158 * @brief Make an edge on vertexuse.
159 *
160 * The new edge runs from and to that vertex.
161 *
162 * If the vertexuse was the shell's sole vertexuse, then the new edge
163 * is a wire edge in the shell's eu_hd list.
164 *
165 * If the vertexuse was part of a loop-of-a-single-vertex, either as a
166 * loop in a face or as a wire-loop in the shell, the loop becomes a
167 * regular loop with one edge that runs from and to the original
168 * vertex.
169 */
170NMG_EXPORT extern struct edgeuse *nmg_meonvu(struct vertexuse *vu);
171
172/**
173 * @brief Delete an edgeuse & its mate from a shell or loop.
174 *
175 * @retval 0 If all is well
176 * @retval 1 If the parent now has no edgeuses, and is thus "illegal" and in
177 * need of being deleted. (The lu / shell deletion can't be handled at this
178 * level, and must be done by the caller).
179 */
180NMG_EXPORT extern int nmg_keu(struct edgeuse *eu);
181
182/**
183 * Do two edgeuses share the same two vertices? If yes, eu's should be
184 * joined.
185 */
186#define NMG_ARE_EUS_ADJACENT(_eu1, _eu2) (\
187 ((_eu1)->vu_p->v_p == (_eu2)->vu_p->v_p && \
188 (_eu1)->eumate_p->vu_p->v_p == (_eu2)->eumate_p->vu_p->v_p) || \
189 ((_eu1)->vu_p->v_p == (_eu2)->eumate_p->vu_p->v_p && \
190 (_eu1)->eumate_p->vu_p->v_p == (_eu2)->vu_p->v_p))
191
192/** Compat: Used in nmg_misc.c and nmg_mod.c */
193#define EDGESADJ(_e1, _e2) NMG_ARE_EUS_ADJACENT(_e1, _e2)
194
195/**
196 * @brief If shell s2 has an edge that connects the same vertices as eu1 connects,
197 * return the matching edgeuse in s2.
198 *
199 * This routine works properly regardless of whether eu1 is in s2 or not.
200 * A convenient wrapper for nmg_findeu().
201 */
202NMG_EXPORT extern struct edgeuse *nmg_find_matching_eu_in_s(const struct edgeuse *eu1,
203 const struct shell *s2);
204
205/**
206 * @brief Find an edgeuse in a shell between a given pair of vertex structs.
207 *
208 * If a given shell "s" is specified, then only edgeuses in that shell
209 * will be considered, otherwise all edgeuses in the model are fair game.
210 *
211 * If a particular edgeuse "eup" is specified, then that edgeuse
212 * and its mate will not be returned as a match.
213 *
214 * If "dangling_only" is true, then an edgeuse will be matched only if
215 * there are no other edgeuses on the edge, i.e. the radial edgeuse is
216 * the same as the mate edgeuse.
217 *
218 * @retval edgeuse* Edgeuse which matches the criteria
219 * @retval NULL Unable to find matching edgeuse
220 */
221NMG_EXPORT extern struct edgeuse *nmg_findeu(const struct vertex *v1,
222 const struct vertex *v2,
223 const struct shell *s,
224 const struct edgeuse *eup,
225 int dangling_only);
226
227/**
228 * @brief An analog to nmg_findeu(), only restricted to searching a faceuse,
229 * rather than to a whole shell.
230 */
231NMG_EXPORT extern struct edgeuse *nmg_find_eu_in_face(const struct vertex *v1,
232 const struct vertex *v2,
233 const struct faceuse *fu,
234 const struct edgeuse *eup,
235 int dangling_only);
236
237/**
238 * @brief Find an edge between a given pair of vertices.
239 *
240 * If a given shell "s" is specified, then only edges in that shell
241 * will be considered, otherwise all edges in the model are fair game.
242 *
243 * If a particular edge "ep" is specified, then that edge
244 * will not be returned as a match.
245 *
246 * @retval edgeuse* Edgeuse of an edge which matches the criteria
247 * @retval NULL Unable to find matching edge
248 */
249NMG_EXPORT extern struct edgeuse *nmg_find_e(const struct vertex *v1,
250 const struct vertex *v2,
251 const struct shell *s,
252 const struct edge *ep);
253
254/**
255 * @brief Return a pointer to the edgeuse which is the parent of this vertexuse.
256 *
257 * A simple helper routine, which replaces the amazingly bad sequence of:
258 * nmg_find_eu_with_vu_in_lu(nmg_find_lu_of_vu(vu), vu)
259 * that was being used in several places.
260 */
261NMG_EXPORT extern struct edgeuse *nmg_find_eu_of_vu(const struct vertexuse *vu);
262
263/**
264 * @brief Find an edgeuse starting at a given vertexuse within a loopuse.
265 */
266NMG_EXPORT extern struct edgeuse *nmg_find_eu_with_vu_in_lu(const struct loopuse *lu,
267 const struct vertexuse *vu);
268
269/**
270 * @brief Looking radially around an edge, find another edge in the same
271 * face as the current edge. (this could be the mate to the current edge)
272 */
273NMG_EXPORT extern const struct edgeuse *nmg_faceradial(const struct edgeuse *eu);
274
275/**
276 * @brief Looking radially around an edge, find another edge which is a part
277 * of a face in the same shell.
278 */
279NMG_EXPORT extern const struct edgeuse *nmg_radial_face_edge_in_shell(const struct edgeuse *eu);
280
281/**
282 * @brief Perform a topology search to determine if two faces (specified by
283 * their faceuses) share an edge in common. If so, return an edgeuse
284 * in fu1 of that edge.
285 *
286 * If there are multiple edgeuses in common, ensure that they all refer
287 * to the same edge_g_lseg geometry structure. The intersection of two planes
288 * (non-coplanar) must be a single line.
289 *
290 * Calling this routine when the two faces share face geometry
291 * and have more than one edge in common gives
292 * a NULL return, as there is no unique answer.
293 *
294 * NULL is also returned if no common edge could be found.
295 */
296NMG_EXPORT extern const struct edgeuse *nmg_find_edge_between_2fu(const struct faceuse *fu1,
297 const struct faceuse *fu2,
298 struct bu_list *vlfree,
299 const struct bn_tol *tol);
300
301/**
302 * @brief A geometric search routine to find the edge that is nearest to
303 * the given point, when all edges are projected into 2D using
304 * the matrix 'mat'.
305 * Useful for finding the edge nearest a mouse click, for example.
306 */
307NMG_EXPORT extern struct edge *nmg_find_e_nearest_pt2(uint32_t *magic_p,
308 const point_t pt2,
309 const mat_t mat,
310 struct bu_list *vlfree,
311 const struct bn_tol *tol);
312
313/**
314 * @brief Given an edgeuse, return two arbitrary unit-length vectors which
315 * are perpendicular to each other and to the edgeuse, such that
316 * they can be considered the +X and +Y axis, and the edgeuse is +Z.
317 * That is, X cross Y = Z.
318 *
319 * Useful for erecting a coordinate system around an edge suitable
320 * for measuring the angles of other edges and faces with.
321 */
322NMG_EXPORT extern void nmg_eu_2vecs_perp(vect_t xvec,
323 vect_t yvec,
324 vect_t zvec,
325 const struct edgeuse *eu,
326 const struct bn_tol *tol);
327
328/**
329 * @brief Given an edgeuse, if it is part of a faceuse, return the inward pointing
330 * "left" vector which points into the interior of this loop, and
331 * lies in the plane of the face. The left vector is unitized.
332 *
333 * This routine depends on the vertex ordering in an OT_SAME loopuse being
334 * properly CCW for exterior loops, and CW for interior (hole) loops.
335 *
336 * @retval -1 if edgeuse is not part of a faceuse.
337 * @retval 0 if left vector successfully computed into caller's array.
338 */
339NMG_EXPORT extern int nmg_find_eu_leftvec(vect_t left,
340 const struct edgeuse *eu);
341
342/**
343 * @brief Given an edgeuse, if it is part of a faceuse, return the inward
344 * pointing "left" vector which points into the interior of this loop, and
345 * lies in the plane of the face. The left vector is not unitized.
346 *
347 * This routine depends on the vertex ordering in an OT_SAME loopuse being
348 * properly CCW for exterior loops, and CW for interior (hole) loops.
349 *
350 * @retval -1 if edgeuse is not part of a faceuse.
351 * @retval 0 if left vector successfully computed into caller's array.
352 */
353NMG_EXPORT extern int nmg_find_eu_left_non_unit(vect_t left,
354 const struct edgeuse *eu);
355
356/**
357 * @brief If there is an edgeuse of an OT_SAME faceuse on this edge, return it.
358 * Only return a wire edgeuse if that is all there is.
359 *
360 * Useful for selecting a "good" edgeuse to pass to nmg_eu_2vecs_perp().
361 */
362NMG_EXPORT extern struct edgeuse *nmg_find_ot_same_eu_of_e(const struct edge *e);
363
364/**
365 * @brief Check if a vertex is in use within a list of edges
366 *
367 * @retval 1 If found
368 * @retval 0 If not found
369 */
370NMG_EXPORT extern int nmg_is_vertex_in_edgelist(const struct vertex *v,
371 const struct bu_list *hd);
372
373/**
374 * @brief Check if edge \b e is present within a list of edges
375 *
376 * @retval 1 If found
377 * @retval 0 If not found
378 */
379NMG_EXPORT extern int nmg_is_edge_in_edgelist(const struct edge *e,
380 const struct bu_list *hd);
381
382/**
383 * @brief Build the set of pointers to all edgeuse structures in an NMG model
384 * that are "below" the data structure pointed to by magic_p, where magic_p is
385 * a pointer to the magic entry of any NMG data structure in the model.
386 *
387 * For "raw" geometric struts, the magic entry will be the first entry in the
388 * struct - for example, a loop pointed to by l would have a magic_p key of
389 * &l->magic. For the use structures, the magic key is found within the leading
390 * bu_list - for example, a faceuse pointed to by *fu would have a magic_p key
391 * at &fu->l.magic
392 *
393 * Each edgeuse pointer will be listed exactly once - i.e. uniqueness within
394 * the table may be assumed.
395 *
396 * @param[out] tab a bu_ptbl holding struct edgeuse pointers.
397 *
398 * @param magic_p pointer to an NMG data structure's magic entry.
399 *
400 * @param vlfree list of available vlist segments to be reused by debug drawing routines.
401 */
402NMG_EXPORT extern void nmg_edgeuse_tabulate(struct bu_ptbl *tab,
403 const uint32_t *magic_p,
404 struct bu_list *vlfree);
405
406/**
407 * @brief Build the set of pointers to all edge structures in an NMG model
408 * that are "below" the data structure pointed to by magic_p, where magic_p is
409 * a pointer to the magic entry of any NMG data structure in the model.
410 *
411 * For "raw" geometric struts, the magic entry will be the first entry in the
412 * struct - for example, a loop pointed to by l would have a magic_p key of
413 * &l->magic. For the use structures, the magic key is found within the leading
414 * bu_list - for example, a faceuse pointed to by *fu would have a magic_p key
415 * at &fu->l.magic
416 *
417 * Each edge pointer will be listed exactly once - i.e. uniqueness within
418 * the table may be assumed.
419 *
420 * @param[out] tab a bu_ptbl holding struct edge pointers.
421 *
422 * @param magic_p pointer to an NMG data structure's magic entry.
423 *
424 * @param vlfree list of available vlist segments to be reused by debug drawing routines.
425 */
426NMG_EXPORT extern void nmg_edge_tabulate(struct bu_ptbl *tab,
427 const uint32_t *magic_p,
428 struct bu_list *vlfree);
429
430/**
431 * @brief Build the set of pointers to all edge geometry structures in an NMG
432 * model that are "below" the data structure pointed to by magic_p, where
433 * magic_p is a pointer to the magic entry of any NMG data structure in the
434 * model.
435 *
436 * For "raw" geometric struts, the magic entry will be the first entry in the
437 * struct - for example, a loop pointed to by l would have a magic_p key of
438 * &l->magic. For the use structures, the magic key is found within the leading
439 * bu_list - for example, a faceuse pointed to by *fu would have a magic_p key
440 * at &fu->l.magic
441 *
442 * @param[out] tab a bu_ptbl holding edge geometry pointers.
443 *
444 * @param magic_p pointer to an NMG data structure's magic entry.
445 *
446 * @param vlfree list of available vlist segments to be reused by debug drawing routines.
447 *
448 * Each edge geometry pointer will be listed exactly once - i.e. uniqueness
449 * within the table may be assumed. However, the type of edge geometry stored
450 * is *not* necessarily unique - both edge_g_lseg and edge_g_cnurb structures will
451 * be stashed by this routine. It is the responsibility of the caller to check
452 * their magic numbers to sort out the type of each pointer:
453 *
454 * @code
455 * struct bu_ptbl edge_g_tbl;
456 * bu_ptbl_init(&edge_g_tbl, 64, "&edge_g_tbl");
457 * nmg_edge_g_tabulate(&edge_g_tbl, &fu->l.magic, vlfree);
458 * for (int i=0; i < BU_PTBL_LEN(&edge_g_tbl); i++) {
459 * struct edge_g_lseg *elg;
460 * struct edge_g_cnurb *ecg;
461 * long *ep = BU_PTBL_GET(&edge_g_tbl, i);
462 * switch (*ep) {
463 * case NMG_EDGE_G_LSEG_MAGIC:
464 * elg = (struct edge_g_lseg *)ep;
465 * NMG_CK_EDGE_G_LSEG(elg);
466 * break;
467 * case NMG_EDGE_G_CNURB_MAGIC:
468 * ecg = (struct edge_g_cnurb *)ep;
469 * NMG_CK_EDGE_G_CNURB(ecg);
470 * break;
471 * default
472 * bu_log("Error - invalid edge geometry type\n");
473 * }
474 * }
475 * @endcode
476 */
477NMG_EXPORT extern void nmg_edge_g_tabulate(struct bu_ptbl *tab,
478 const uint32_t *magic_p,
479 struct bu_list *vlfree);
480/**
481 * @brief Build an bu_ptbl list which cites every edgeuse pointer that uses
482 * edge geometry "eg".
483 *
484 * The edge geometry has this information encoded within it, so this is largely
485 * a convenience routine to allow the caller to avoid bu_list based iteration
486 * which must understand the edge geometry containers and instead use the
487 * simpler bu_ptbl iteration.
488 */
489NMG_EXPORT extern void nmg_edgeuse_with_eg_tabulate(struct bu_ptbl *tab,
490 const struct edge_g_lseg *eg);
491/**
492 * @brief Given a pointer to any nmg data structure,
493 * build an bu_ptbl list which cites every edgeuse
494 * pointer from there on "down" in the model
495 * that has both vertices within tolerance of the given line.
496 *
497 * XXX This routine is a potential source of major trouble.
498 * XXX If there are "nearby" edges that "should" be on the list but
499 * XXX don't make it, then the intersection calculations might
500 * XXX miss important intersections.
501 * As an admittedly grubby workaround, use 10X the distance tol here,
502 * just to get more candidates onto the list.
503 * The caller will have to wrestle with the added fuzz.
504 */
505NMG_EXPORT extern void nmg_edgeuse_on_line_tabulate(struct bu_ptbl *tab,
506 const uint32_t *magic_p,
507 const point_t pt,
508 const vect_t dir,
509 struct bu_list *vlfree,
510 const struct bn_tol *tol);
511
512/**
513 * @brief Build lists of all edges (represented by one edgeuse on that edge)
514 * and all vertices found underneath the NMG entity indicated by magic_p.
515 */
516NMG_EXPORT extern void nmg_e_and_v_tabulate(struct bu_ptbl *eutab,
517 struct bu_ptbl *vtab,
518 const uint32_t *magic_p,
519 struct bu_list *vlfree);
520
521/**
522 * Given two edgeuses, determine if they share the same edge geometry,
523 * either topologically, or within tolerance.
524 *
525 * @retval 0 two edge geometries are not coincident
526 * @retval 1 edges geometries are everywhere coincident.
527 * (For linear edge_g_lseg, the 2 are the same line, within tol.)
528 */
529NMG_EXPORT extern int nmg_2edgeuse_g_coincident(const struct edgeuse *eu1,
530 const struct edgeuse *eu2,
531 const struct bn_tol *tol);
532
533/**
534 * @brief Sets the "is_real" flag on all edges at or below the pointer
535 * passed. Returns the number of flags set.
536 */
537NMG_EXPORT extern int nmg_mark_edges_real(const uint32_t *magic_p, struct bu_list *vlfree);
538
539/**
540 * @brief Convenience wrapper to retrieve and remove the last edgeuse element
541 * from the \b stack bu_ptbl.
542 */
543NMG_EXPORT extern struct edgeuse *nmg_pop_eu(struct bu_ptbl *stack);
544
545/**
546 * @brief Moves indicated edgeuse (mv_eu) so that it passes thru the given
547 * point (pt). The direction of the edgeuse is not changed, so new edgeuse is
548 * parallel to the original.
549 *
550 * Plane equations of all radial faces on this edge are changed and all
551 * vertices (except one anchor point) in radial loops are adjusted Note that
552 * the anchor point is chosen arbitrarily.
553 *
554 * @retval 1 failure
555 * @retval 0 success
556 */
557NMG_EXPORT extern int nmg_move_edge_thru_pnt(struct edgeuse *mv_eu,
558 const point_t pt,
559 const struct bn_tol *tol);
560
561/**
562 * @brief Split an edge into multiple edges at specified vertices if they
563 * are within tolerance distance.
564 *
565 * Returns the number of additional edges that were created.
566 */
567NMG_EXPORT extern int nmg_break_edge_at_verts(struct edge *e,
568 struct bu_ptbl *verts,
569 const struct bn_tol *tol);
570
571/**
572 * @brief Apply nmg_break_edge_at_verts() to all edge/vertex combinations present
573 * in the NMG model below the NMG element with the magic number pointed to by
574 * \b magic_p
575 */
576NMG_EXPORT extern int nmg_break_edges(uint32_t *magic_p, struct bu_list *vlfree,
577 const struct bn_tol *tol);
578
579/**
580 * @brief Fuse vertices and edges according to \b tol
581 *
582 * TODO - this needs MUCH better documentation...
583 *
584 * If a bu_ptbl structure is passed into this function, the structure must
585 * contain edgeuse. Vertices will then be fused at the shell level. If an NMG
586 * structure is passed into this function, if the structure is an NMG region or
587 * model, vertices will be fused at the model level. If the NMG structure
588 * passed in is a shell or anything lower, vertices will be fused at the shell
589 * level.
590 */
591NMG_EXPORT extern int nmg_edge_fuse(const uint32_t *magic_p,struct bu_list *vlfree,
592 const struct bn_tol *tol);
593
594/**
595 * @brief Fuse edge_g structs.
596 *
597 * TODO - this needs MUCH better documentation...
598 */
599NMG_EXPORT extern int nmg_edge_g_fuse(const uint32_t *magic_p,struct bu_list *vlfree,
600 const struct bn_tol *tol);
601
602/**
603 * @brief Given two edgeuses with different edge geometry but running between
604 * the same two vertices, select the proper edge geometry to associate with.
605 *
606 * Really, there are 3 geometries to be compared here: the vector between the
607 * two endpoints of this edge, and the two edge_g structures. Rather than
608 * always taking eu2 or eu1, select the one that best fits this one edge.
609 *
610 * Consider fu1:
611 * @verbatim
612 B
613 *
614 /|
615 eg2/ |
616 / |
617 D/ |
618 * |
619 / |
620 A *-*----* C
621 E eg1
622 @endverbatim
623 *
624 * At the start of a face/face intersection, eg1 runs from A to C,
625 * and eg2 runs ADB. The line of intersection with the other face
626 * (fu2, not drawn) lies along eg1.
627 * Assume that edge AC needs to be broken at E,
628 * where E is just a little more than tol->dist away from A.
629 * Existing point D is found because it *is* within tol->dist of E,
630 * thanks to the cosine of angle BAC.
631 * So, edge AC is broken on vertex D, and the intersection list
632 * contains vertexuses A, E, and C.
633 *
634 * Because D and E are the same point, fu1 has become a triangle with
635 * a little "spike" on the end. If this is handled simply by re-homing
636 * edge AE to eg2, it may cause trouble, because eg1 now runs EC,
637 * but the geometry for eg1 runs AC. If there are other vertices on
638 * edge eg1, the problem can not be resolved simply by recomputing the
639 * geometry of eg1.
640 * Since E (D) is within tolerance of eg1, it is not unreasonable
641 * just to leave eg1 alone.
642 *
643 * The issue boils down to selecting whether the existing eg1 or eg2
644 * best represents the direction of the little stub edge AD (shared with AE).
645 * In this case, eg2 is the correct choice, as AD (and AE) lie on line AB.
646 *
647 * It would be disastrous to force *all* of eg1 to use the edge geometry
648 * of eg2, as the two lines are very different.
649 */
650NMG_EXPORT extern struct edge_g_lseg *nmg_pick_best_edge_g(struct edgeuse *eu1,
651 struct edgeuse *eu2,
652 const struct bn_tol *tol);
653
654/**
655 * @brief Check if \b eu is part of a loop but is not correctly connected
656 * topologically to other edges in the loop.
657 */
658NMG_EXPORT extern int nmg_eu_is_part_of_crack(const struct edgeuse *eu);
659
660/**
661 * @brief Make all the edgeuses around eu2's edge to refer to eu1's edge,
662 * taking care to organize them into the proper angular orientation, so that
663 * the attached faces are correctly arranged radially around the edge.
664 *
665 * This depends on both edges being part of face loops, with vertex and face
666 * geometry already associated.
667 *
668 * The two edgeuses being joined might well be from separate shells, so the
669 * issue of preserving (simple) faceuse orientation parity (SAME, OPPOSITE,
670 * OPPOSITE, SAME, ...) can't be used here -- that only applies to faceuses
671 * from the same shell.
672 *
673 * Some of the edgeuses around both edges may be wires.
674 *
675 * Call to nmg_check_radial at end has been deleted. Note that after two
676 * radial EU's have been joined a third cannot be joined to them without
677 * creating unclosed space that nmg_check_radial will find.
678 */
679NMG_EXPORT extern void nmg_radial_join_eu(struct edgeuse *eu1,
680 struct edgeuse *eu2,
681 const struct bn_tol *tol);
682
683/**
684 * @brief TODO - document...
685 */
686NMG_EXPORT extern int nmg_break_all_es_on_v(uint32_t *magic_p,
687 struct vertex *v,struct bu_list *vlfree,
688 const struct bn_tol *tol);
689
690/**
691 * @brief As the first step in evaluating a boolean formula,
692 * before starting to do face/face intersections, compare every
693 * edge in the model with every vertex in the model.
694 *
695 * If the vertex is within tolerance of the edge, break the edge,
696 * and enroll the new edge on a list of edges still to be processed.
697 *
698 * A list of edges and a list of vertices are built, and then processed.
699 *
700 * Space partitioning could improve the performance of this algorithm.
701 * For the moment, a brute-force approach is used.
702 *
703 * @return
704 * Number of edges broken.
705 */
706NMG_EXPORT extern int nmg_break_e_on_v(const uint32_t *magic_p,struct bu_list *vlfree,
707 const struct bn_tol *tol);
708
709/**
710 * @brief Determine if the given wedge is entirely to the left or right of the
711 * ray, or if it crosses.
712 *
713 * 0 degrees is to the rear (ON_REV), 90 degrees is to the RIGHT, 180 is
714 * ON_FORW, 270 is to the LEFT.
715 *
716 * "halfway X" (ha, hb) have these properties:
717 * @verbatim
718 < 0 (==> X < 180) RIGHT
719 > 0 (==> X > 180) LEFT
720 ==0 (==> X == 180) ON_FORW
721 @endverbatim
722 *
723 * Possible return values are WEDGE_LEFT, WEDGE_CROSSING, WEDGE_RIGHT, and
724 * WEDGE_ON
725 */
726NMG_EXPORT extern int nmg_wedge_class(int ass, /* assessment of two edges forming wedge */
727 double a,
728 double b);
729
730__END_DECLS
731
732#endif /* NMG_EDGE_H */
733/** @} */
734/*
735 * Local Variables:
736 * mode: C
737 * tab-width: 8
738 * indent-tabs-mode: t
739 * c-file-style: "stroustrup"
740 * End:
741 * ex: shiftwidth=4 tabstop=8
742 */
Header file for the BRL-CAD common definitions.
struct edge_g_lseg * nmg_pick_best_edge_g(struct edgeuse *eu1, struct edgeuse *eu2, const struct bn_tol *tol)
Given two edgeuses with different edge geometry but running between the same two vertices,...
void nmg_edgeuse_on_line_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p, const point_t pt, const vect_t dir, struct bu_list *vlfree, const struct bn_tol *tol)
Given a pointer to any nmg data structure, build an bu_ptbl list which cites every edgeuse pointer fr...
void nmg_edge_g_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p, struct bu_list *vlfree)
Build the set of pointers to all edge geometry structures in an NMG model that are "below" the data s...
int nmg_find_eu_leftvec(vect_t left, const struct edgeuse *eu)
Given an edgeuse, if it is part of a faceuse, return the inward pointing "left" vector which points i...
const struct edgeuse * nmg_faceradial(const struct edgeuse *eu)
Looking radially around an edge, find another edge in the same face as the current edge....
void nmg_edge_g(struct edgeuse *eu)
Compute the equation of the line formed by the endpoints of the edge.
int nmg_edge_fuse(const uint32_t *magic_p, struct bu_list *vlfree, const struct bn_tol *tol)
Fuse vertices and edges according to tol.
struct edgeuse * nmg_find_e(const struct vertex *v1, const struct vertex *v2, const struct shell *s, const struct edge *ep)
Find an edge between a given pair of vertices.
struct edgeuse * nmg_find_eu_of_vu(const struct vertexuse *vu)
Return a pointer to the edgeuse which is the parent of this vertexuse.
int nmg_move_edge_thru_pnt(struct edgeuse *mv_eu, const point_t pt, const struct bn_tol *tol)
Moves indicated edgeuse (mv_eu) so that it passes thru the given point (pt). The direction of the edg...
int nmg_find_eu_left_non_unit(vect_t left, const struct edgeuse *eu)
Given an edgeuse, if it is part of a faceuse, return the inward pointing "left" vector which points i...
void nmg_edgeuse_with_eg_tabulate(struct bu_ptbl *tab, const struct edge_g_lseg *eg)
Build an bu_ptbl list which cites every edgeuse pointer that uses edge geometry "eg".
int nmg_keu(struct edgeuse *eu)
Delete an edgeuse & its mate from a shell or loop.
struct edge * nmg_find_e_nearest_pt2(uint32_t *magic_p, const point_t pt2, const mat_t mat, struct bu_list *vlfree, const struct bn_tol *tol)
A geometric search routine to find the edge that is nearest to the given point, when all edges are pr...
struct edgeuse * nmg_find_matching_eu_in_s(const struct edgeuse *eu1, const struct shell *s2)
If shell s2 has an edge that connects the same vertices as eu1 connects, return the matching edgeuse ...
struct edgeuse * nmg_me(struct vertex *v1, struct vertex *v2, struct shell *s)
Make wire edge.
struct edgeuse * nmg_pop_eu(struct bu_ptbl *stack)
Convenience wrapper to retrieve and remove the last edgeuse element from the stack bu_ptbl.
int nmg_edge_g_fuse(const uint32_t *magic_p, struct bu_list *vlfree, const struct bn_tol *tol)
Fuse edge_g structs.
void nmg_unglueedge(struct edgeuse *eu)
If edgeuse is part of a shared edge (more than one pair of edgeuses on the edge), it and its mate are...
struct edgeuse * nmg_findeu(const struct vertex *v1, const struct vertex *v2, const struct shell *s, const struct edgeuse *eup, int dangling_only)
Find an edgeuse in a shell between a given pair of vertex structs.
void nmg_eu_2vecs_perp(vect_t xvec, vect_t yvec, vect_t zvec, const struct edgeuse *eu, const struct bn_tol *tol)
Given an edgeuse, return two arbitrary unit-length vectors which are perpendicular to each other and ...
int nmg_break_edges(uint32_t *magic_p, struct bu_list *vlfree, const struct bn_tol *tol)
Apply nmg_break_edge_at_verts() to all edge/vertex combinations present in the NMG model below the NM...
int nmg_break_edge_at_verts(struct edge *e, struct bu_ptbl *verts, const struct bn_tol *tol)
Split an edge into multiple edges at specified vertices if they are within tolerance distance.
const struct edgeuse * nmg_radial_face_edge_in_shell(const struct edgeuse *eu)
Looking radially around an edge, find another edge which is a part of a face in the same shell.
struct edgeuse * nmg_find_eu_with_vu_in_lu(const struct loopuse *lu, const struct vertexuse *vu)
Find an edgeuse starting at a given vertexuse within a loopuse.
void nmg_je(struct edgeuse *eudst, struct edgeuse *eusrc)
Move a pair of edgeuses onto a single edge (glue edgeuse).
int nmg_wedge_class(int ass, double a, double b)
Determine if the given wedge is entirely to the left or right of the ray, or if it crosses.
int nmg_break_all_es_on_v(uint32_t *magic_p, struct vertex *v, struct bu_list *vlfree, const struct bn_tol *tol)
TODO - document...
const struct edgeuse * nmg_find_edge_between_2fu(const struct faceuse *fu1, const struct faceuse *fu2, struct bu_list *vlfree, const struct bn_tol *tol)
Perform a topology search to determine if two faces (specified by their faceuses) share an edge in co...
int nmg_mark_edges_real(const uint32_t *magic_p, struct bu_list *vlfree)
Sets the "is_real" flag on all edges at or below the pointer passed. Returns the number of flags set.
int nmg_use_edge_g(struct edgeuse *eu, uint32_t *magic_p)
Associate edgeuse 'eu' with the edge geometry structure identified by 'magic_p', where magic_p is the...
int nmg_demote_eu(struct edgeuse *eu)
Demote a wire edge into a pair of self-loop vertices.
int nmg_is_edge_in_edgelist(const struct edge *e, const struct bu_list *hd)
Check if edge e is present within a list of edges.
int nmg_is_vertex_in_edgelist(const struct vertex *v, const struct bu_list *hd)
Check if a vertex is in use within a list of edges.
int nmg_break_e_on_v(const uint32_t *magic_p, struct bu_list *vlfree, const struct bn_tol *tol)
As the first step in evaluating a boolean formula, before starting to do face/face intersections,...
void nmg_edgeuse_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p, struct bu_list *vlfree)
Build the set of pointers to all edgeuse structures in an NMG model that are "below" the data structu...
struct edgeuse * nmg_find_ot_same_eu_of_e(const struct edge *e)
If there is an edgeuse of an OT_SAME faceuse on this edge, return it. Only return a wire edgeuse if t...
void nmg_jeg(struct edge_g_lseg *dest_eg, struct edge_g_lseg *src_eg)
Join two edge geometries.
void nmg_e_and_v_tabulate(struct bu_ptbl *eutab, struct bu_ptbl *vtab, const uint32_t *magic_p, struct bu_list *vlfree)
Build lists of all edges (represented by one edgeuse on that edge) and all vertices found underneath ...
void nmg_radial_join_eu(struct edgeuse *eu1, struct edgeuse *eu2, const struct bn_tol *tol)
Make all the edgeuses around eu2's edge to refer to eu1's edge, taking care to organize them into the...
struct edgeuse * nmg_find_eu_in_face(const struct vertex *v1, const struct vertex *v2, const struct faceuse *fu, const struct edgeuse *eup, int dangling_only)
An analog to nmg_findeu(), only restricted to searching a faceuse, rather than to a whole shell.
struct edgeuse * nmg_meonvu(struct vertexuse *vu)
Make an edge on vertexuse.
int nmg_2edgeuse_g_coincident(const struct edgeuse *eu1, const struct edgeuse *eu2, const struct bn_tol *tol)
void nmg_edge_tabulate(struct bu_ptbl *tab, const uint32_t *magic_p, struct bu_list *vlfree)
Build the set of pointers to all edge structures in an NMG model that are "below" the data structure ...
int nmg_eu_is_part_of_crack(const struct edgeuse *eu)
Check if eu is part of a loop but is not correctly connected topologically to other edges in the loop...
fastf_t vect_t[ELEMENTS_PER_VECT]
3-tuple vector
Definition: vmath.h:345
fastf_t mat_t[ELEMENTS_PER_MAT]
4x4 matrix
Definition: vmath.h:366
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
Line in 3D space.
Definition: topology.h:326
NMG topological edge.
Definition: topology.h:144
NMG topological edge usage.
Definition: topology.h:155
uint32_t * magic_p
for those times when we're not sure
Definition: topology.h:161
NMG topological face usage.
Definition: topology.h:230
NMG topological loop usage.
Definition: topology.h:192
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
fundamental vector, matrix, quaternion math macros