BRL-CAD

Routines for working with NMG Edges and Edge Uses. More...

Collaboration diagram for Edge:

Files

file  edge.h
 

Macros

#define NMG_CK_EDGE(_p)   NMG_CKMAG(_p, NMG_EDGE_MAGIC, "edge")
 
#define NMG_CK_EDGE_G_LSEG(_p)   NMG_CKMAG(_p, NMG_EDGE_G_LSEG_MAGIC, "edge_g_lseg")
 
#define NMG_CK_EDGEUSE(_p)   NMG_CKMAG(_p, NMG_EDGEUSE_MAGIC, "edgeuse")
 
#define GET_EDGE(p, m)   {NMG_GETSTRUCT(p, edge); NMG_INCR_INDEX(p, m);}
 
#define GET_EDGE_G_LSEG(p, m)   {NMG_GETSTRUCT(p, edge_g_lseg); NMG_INCR_INDEX(p, m);}
 
#define GET_EDGE_G_CNURB(p, m)   {NMG_GETSTRUCT(p, edge_g_cnurb); NMG_INCR_INDEX(p, m);}
 
#define GET_EDGEUSE(p, m)   {NMG_GETSTRUCT(p, edgeuse); NMG_INCR_INDEX(p, m);}
 
#define FREE_EDGE(p)   NMG_FREESTRUCT(p, edge)
 
#define FREE_EDGE_G_LSEG(p)   NMG_FREESTRUCT(p, edge_g_lseg)
 
#define FREE_EDGE_G_CNURB(p)   NMG_FREESTRUCT(p, edge_g_cnurb)
 
#define FREE_EDGEUSE(p)   NMG_FREESTRUCT(p, edgeuse)
 
#define nmg_mev(_v, _u)   nmg_me((_v), (struct vertex *)NULL, (_u))
 
#define NMG_ARE_EUS_ADJACENT(_eu1, _eu2)
 
#define EDGESADJ(_e1, _e2)   NMG_ARE_EUS_ADJACENT(_e1, _e2)
 

Functions

void nmg_edge_g (struct edgeuse *eu)
 Compute the equation of the line formed by the endpoints of the edge. More...
 
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 pointer to the magic entry of an edge_g_lseg. More...
 
int nmg_demote_eu (struct edgeuse *eu)
 Demote a wire edge into a pair of self-loop vertices. More...
 
void nmg_je (struct edgeuse *eudst, struct edgeuse *eusrc)
 Move a pair of edgeuses onto a single edge (glue edgeuse). More...
 
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 "unglued" from the edge, and associated with a new edge structure. More...
 
void nmg_jeg (struct edge_g_lseg *dest_eg, struct edge_g_lseg *src_eg)
 Join two edge geometries. More...
 
struct edgeusenmg_me (struct vertex *v1, struct vertex *v2, struct shell *s)
 Make wire edge. More...
 
struct edgeusenmg_meonvu (struct vertexuse *vu)
 Make an edge on vertexuse. More...
 
int nmg_keu (struct edgeuse *eu)
 Delete an edgeuse & its mate from a shell or loop. More...
 
struct edgeusenmg_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 in s2. More...
 
struct edgeusenmg_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. More...
 
struct edgeusenmg_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. More...
 
struct edgeusenmg_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. More...
 
struct edgeusenmg_find_eu_of_vu (const struct vertexuse *vu)
 Return a pointer to the edgeuse which is the parent of this vertexuse. More...
 
struct edgeusenmg_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. More...
 
const struct edgeusenmg_faceradial (const struct edgeuse *eu)
 Looking radially around an edge, find another edge in the same face as the current edge. (this could be the mate to the current edge) More...
 
const struct edgeusenmg_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. More...
 
const struct edgeusenmg_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 common. If so, return an edgeuse in fu1 of that edge. More...
 
struct edgenmg_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 projected into 2D using the matrix 'mat'. Useful for finding the edge nearest a mouse click, for example. More...
 
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 to the edgeuse, such that they can be considered the +X and +Y axis, and the edgeuse is +Z. That is, X cross Y = Z. More...
 
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 into the interior of this loop, and lies in the plane of the face. The left vector is unitized. More...
 
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 into the interior of this loop, and lies in the plane of the face. The left vector is not unitized. More...
 
struct edgeusenmg_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 that is all there is. More...
 
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. More...
 
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. More...
 
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 structure pointed to by magic_p, where magic_p is a pointer to the magic entry of any NMG data structure in the model. More...
 
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 pointed to by magic_p, where magic_p is a pointer to the magic entry of any NMG data structure in the model. More...
 
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 structure pointed to by magic_p, where magic_p is a pointer to the magic entry of any NMG data structure in the model. More...
 
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". More...
 
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 from there on "down" in the model that has both vertices within tolerance of the given line. More...
 
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 the NMG entity indicated by magic_p. More...
 
int nmg_2edgeuse_g_coincident (const struct edgeuse *eu1, const struct edgeuse *eu2, const struct bn_tol *tol)
 
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. More...
 
struct edgeusenmg_pop_eu (struct bu_ptbl *stack)
 Convenience wrapper to retrieve and remove the last edgeuse element from the stack bu_ptbl. More...
 
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 edgeuse is not changed, so new edgeuse is parallel to the original. More...
 
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. More...
 
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 NMG element with the magic number pointed to by magic_p. More...
 
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. More...
 
int nmg_edge_g_fuse (const uint32_t *magic_p, struct bu_list *vlfree, const struct bn_tol *tol)
 Fuse edge_g structs. More...
 
struct edge_g_lsegnmg_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, select the proper edge geometry to associate with. More...
 
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. More...
 
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 proper angular orientation, so that the attached faces are correctly arranged radially around the edge. More...
 
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... More...
 
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, compare every edge in the model with every vertex in the model. More...
 
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. More...
 

Detailed Description

Routines for working with NMG Edges and Edge Uses.

Macro Definition Documentation

◆ NMG_CK_EDGE

#define NMG_CK_EDGE (   _p)    NMG_CKMAG(_p, NMG_EDGE_MAGIC, "edge")

Definition at line 38 of file edge.h.

◆ NMG_CK_EDGE_G_LSEG

#define NMG_CK_EDGE_G_LSEG (   _p)    NMG_CKMAG(_p, NMG_EDGE_G_LSEG_MAGIC, "edge_g_lseg")

Definition at line 39 of file edge.h.

◆ NMG_CK_EDGEUSE

#define NMG_CK_EDGEUSE (   _p)    NMG_CKMAG(_p, NMG_EDGEUSE_MAGIC, "edgeuse")

Definition at line 40 of file edge.h.

◆ GET_EDGE

#define GET_EDGE (   p,
 
)    {NMG_GETSTRUCT(p, edge); NMG_INCR_INDEX(p, m);}

Definition at line 42 of file edge.h.

◆ GET_EDGE_G_LSEG

#define GET_EDGE_G_LSEG (   p,
 
)    {NMG_GETSTRUCT(p, edge_g_lseg); NMG_INCR_INDEX(p, m);}

Definition at line 43 of file edge.h.

◆ GET_EDGE_G_CNURB

#define GET_EDGE_G_CNURB (   p,
 
)    {NMG_GETSTRUCT(p, edge_g_cnurb); NMG_INCR_INDEX(p, m);}

Definition at line 44 of file edge.h.

◆ GET_EDGEUSE

#define GET_EDGEUSE (   p,
 
)    {NMG_GETSTRUCT(p, edgeuse); NMG_INCR_INDEX(p, m);}

Definition at line 45 of file edge.h.

◆ FREE_EDGE

#define FREE_EDGE (   p)    NMG_FREESTRUCT(p, edge)

Definition at line 47 of file edge.h.

◆ FREE_EDGE_G_LSEG

#define FREE_EDGE_G_LSEG (   p)    NMG_FREESTRUCT(p, edge_g_lseg)

Definition at line 48 of file edge.h.

◆ FREE_EDGE_G_CNURB

#define FREE_EDGE_G_CNURB (   p)    NMG_FREESTRUCT(p, edge_g_cnurb)

Definition at line 49 of file edge.h.

◆ FREE_EDGEUSE

#define FREE_EDGEUSE (   p)    NMG_FREESTRUCT(p, edgeuse)

Definition at line 50 of file edge.h.

◆ nmg_mev

#define nmg_mev (   _v,
  _u 
)    nmg_me((_v), (struct vertex *)NULL, (_u))

Definition at line 155 of file edge.h.

◆ NMG_ARE_EUS_ADJACENT

#define NMG_ARE_EUS_ADJACENT (   _eu1,
  _eu2 
)
Value:
(\
((_eu1)->vu_p->v_p == (_eu2)->vu_p->v_p && \
(_eu1)->eumate_p->vu_p->v_p == (_eu2)->eumate_p->vu_p->v_p) || \
((_eu1)->vu_p->v_p == (_eu2)->eumate_p->vu_p->v_p && \
(_eu1)->eumate_p->vu_p->v_p == (_eu2)->vu_p->v_p))

Do two edgeuses share the same two vertices? If yes, eu's should be joined.

Definition at line 186 of file edge.h.

◆ EDGESADJ

#define EDGESADJ (   _e1,
  _e2 
)    NMG_ARE_EUS_ADJACENT(_e1, _e2)

Compat: Used in nmg_misc.c and nmg_mod.c

Definition at line 193 of file edge.h.

Function Documentation

◆ nmg_edge_g()

void nmg_edge_g ( struct edgeuse eu)

Compute the equation of the line formed by the endpoints of the edge.

◆ nmg_use_edge_g()

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 pointer to the magic entry of an edge_g_lseg.

Example magic_p keys: eu->g.magic_p &eg->l.magic

If the edgeuse is already associated with some geometry, that geometry is first released. Note that, to start with, the two edgeuses may be using different original geometries.

Also do the edgeuse mate.

Return values
0If the old edge geometry (eu->g.magic_p) has other uses.
1If the old edge geometry has been destroyed. Caller beware!

◆ nmg_demote_eu()

int nmg_demote_eu ( struct edgeuse eu)

Demote a wire edge into a pair of self-loop vertices.

Return values
0If all is well
1If shell is empty, and is thus "illegal".

◆ nmg_je()

void nmg_je ( struct edgeuse eudst,
struct edgeuse eusrc 
)

Move a pair of edgeuses onto a single edge (glue edgeuse).

The edgeuse eusrc and its mate are moved to the edge used by eudst. eusrc is made to be immediately radial to eudst. If eusrc does not share the same vertices as eudst, we bomb.

The edgeuse geometry pointers are not changed by this operation.

This routine was formerly called nmg_moveeu().

◆ nmg_unglueedge()

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 "unglued" from the edge, and associated with a new edge structure.

Primarily a support routine for nmg_eusplit()

If the original edge had edge geometry, that is not duplicated here, because it is not easy (or appropriate) for nmg_eusplit() to know whether the new vertex lies on the previous edge geometry or not. Hence having the nmg_ebreak() interface, which preserves the edge geometry across a split, and nmg_esplit() which does not.

◆ nmg_jeg()

void nmg_jeg ( struct edge_g_lseg dest_eg,
struct edge_g_lseg src_eg 
)

Join two edge geometries.

For all edges in the model which refer to 'src_eg', change them to refer to 'dest_eg'. The source is destroyed.

It is the responsibility of the caller to make certain that the 'dest_eg' is the best one for these edges. Outrageously wrong requests will cause this routine to abort.

This algorithm does not make sense if dest_eg is an edge_g_cnurb; those only make sense in the parameter space of their associated face.

◆ nmg_me()

struct edgeuse * nmg_me ( struct vertex v1,
struct vertex v2,
struct shell s 
)

Make wire edge.

Make a new edge between a pair of vertices in a shell.

A new vertex will be made for any NULL vertex pointer parameters. If we need to make a new vertex and the shell still has its vertexuse we re-use that vertex rather than freeing and re-allocating.

If both vertices were specified, and the shell also had a vertexuse pointer, the vertexuse in the shell is killed. XXX Why?

The explicit result is an edgeuse in shell "s" whose vertexuse refers to vertex v1. The edgeuse mate's vertexuse refers to vertex v2

Additional possible side effects:

  1. If the shell had a lone vertex in vu_p, it is destroyed, even if both vertices were specified.
  2. The returned edgeuse is the first item on the shell's eu_hd list, followed immediately by the mate.

◆ nmg_meonvu()

struct edgeuse * nmg_meonvu ( struct vertexuse vu)

Make an edge on vertexuse.

The new edge runs from and to that vertex.

If the vertexuse was the shell's sole vertexuse, then the new edge is a wire edge in the shell's eu_hd list.

If the vertexuse was part of a loop-of-a-single-vertex, either as a loop in a face or as a wire-loop in the shell, the loop becomes a regular loop with one edge that runs from and to the original vertex.

◆ nmg_keu()

int nmg_keu ( struct edgeuse eu)

Delete an edgeuse & its mate from a shell or loop.

Return values
0If all is well
1If the parent now has no edgeuses, and is thus "illegal" and in need of being deleted. (The lu / shell deletion can't be handled at this level, and must be done by the caller).

◆ nmg_find_matching_eu_in_s()

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 in s2.

This routine works properly regardless of whether eu1 is in s2 or not. A convenient wrapper for nmg_findeu().

◆ nmg_findeu()

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.

If a given shell "s" is specified, then only edgeuses in that shell will be considered, otherwise all edgeuses in the model are fair game.

If a particular edgeuse "eup" is specified, then that edgeuse and its mate will not be returned as a match.

If "dangling_only" is true, then an edgeuse will be matched only if there are no other edgeuses on the edge, i.e. the radial edgeuse is the same as the mate edgeuse.

Return values
edgeuse*Edgeuse which matches the criteria
NULLUnable to find matching edgeuse

◆ nmg_find_eu_in_face()

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.

◆ nmg_find_e()

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.

If a given shell "s" is specified, then only edges in that shell will be considered, otherwise all edges in the model are fair game.

If a particular edge "ep" is specified, then that edge will not be returned as a match.

Return values
edgeuse*Edgeuse of an edge which matches the criteria
NULLUnable to find matching edge

◆ nmg_find_eu_of_vu()

struct edgeuse * nmg_find_eu_of_vu ( const struct vertexuse vu)

Return a pointer to the edgeuse which is the parent of this vertexuse.

A simple helper routine, which replaces the amazingly bad sequence of: nmg_find_eu_with_vu_in_lu(nmg_find_lu_of_vu(vu), vu) that was being used in several places.

◆ nmg_find_eu_with_vu_in_lu()

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.

◆ nmg_faceradial()

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. (this could be the mate to the current edge)

◆ nmg_radial_face_edge_in_shell()

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.

◆ nmg_find_edge_between_2fu()

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 common. If so, return an edgeuse in fu1 of that edge.

If there are multiple edgeuses in common, ensure that they all refer to the same edge_g_lseg geometry structure. The intersection of two planes (non-coplanar) must be a single line.

Calling this routine when the two faces share face geometry and have more than one edge in common gives a NULL return, as there is no unique answer.

NULL is also returned if no common edge could be found.

◆ nmg_find_e_nearest_pt2()

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 projected into 2D using the matrix 'mat'. Useful for finding the edge nearest a mouse click, for example.

◆ nmg_eu_2vecs_perp()

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 to the edgeuse, such that they can be considered the +X and +Y axis, and the edgeuse is +Z. That is, X cross Y = Z.

Useful for erecting a coordinate system around an edge suitable for measuring the angles of other edges and faces with.

◆ nmg_find_eu_leftvec()

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 into the interior of this loop, and lies in the plane of the face. The left vector is unitized.

This routine depends on the vertex ordering in an OT_SAME loopuse being properly CCW for exterior loops, and CW for interior (hole) loops.

Return values
-1if edgeuse is not part of a faceuse.
0if left vector successfully computed into caller's array.

◆ nmg_find_eu_left_non_unit()

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 into the interior of this loop, and lies in the plane of the face. The left vector is not unitized.

This routine depends on the vertex ordering in an OT_SAME loopuse being properly CCW for exterior loops, and CW for interior (hole) loops.

Return values
-1if edgeuse is not part of a faceuse.
0if left vector successfully computed into caller's array.

◆ nmg_find_ot_same_eu_of_e()

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 that is all there is.

Useful for selecting a "good" edgeuse to pass to nmg_eu_2vecs_perp().

◆ nmg_is_vertex_in_edgelist()

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.

Return values
1If found
0If not found

◆ nmg_is_edge_in_edgelist()

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.

Return values
1If found
0If not found

◆ nmg_edgeuse_tabulate()

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 structure pointed to by magic_p, where magic_p is a pointer to the magic entry of any NMG data structure in the model.

For "raw" geometric struts, the magic entry will be the first entry in the struct - for example, a loop pointed to by l would have a magic_p key of &l->magic. For the use structures, the magic key is found within the leading bu_list - for example, a faceuse pointed to by *fu would have a magic_p key at &fu->l.magic

Each edgeuse pointer will be listed exactly once - i.e. uniqueness within the table may be assumed.

Parameters
[out]taba bu_ptbl holding struct edgeuse pointers.
magic_ppointer to an NMG data structure's magic entry.
vlfreelist of available vlist segments to be reused by debug drawing routines.

◆ nmg_edge_tabulate()

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 pointed to by magic_p, where magic_p is a pointer to the magic entry of any NMG data structure in the model.

For "raw" geometric struts, the magic entry will be the first entry in the struct - for example, a loop pointed to by l would have a magic_p key of &l->magic. For the use structures, the magic key is found within the leading bu_list - for example, a faceuse pointed to by *fu would have a magic_p key at &fu->l.magic

Each edge pointer will be listed exactly once - i.e. uniqueness within the table may be assumed.

Parameters
[out]taba bu_ptbl holding struct edge pointers.
magic_ppointer to an NMG data structure's magic entry.
vlfreelist of available vlist segments to be reused by debug drawing routines.

◆ nmg_edge_g_tabulate()

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 structure pointed to by magic_p, where magic_p is a pointer to the magic entry of any NMG data structure in the model.

For "raw" geometric struts, the magic entry will be the first entry in the struct - for example, a loop pointed to by l would have a magic_p key of &l->magic. For the use structures, the magic key is found within the leading bu_list - for example, a faceuse pointed to by *fu would have a magic_p key at &fu->l.magic

Parameters
[out]taba bu_ptbl holding edge geometry pointers.
magic_ppointer to an NMG data structure's magic entry.
vlfreelist of available vlist segments to be reused by debug drawing routines.

Each edge geometry pointer will be listed exactly once - i.e. uniqueness within the table may be assumed. However, the type of edge geometry stored is not necessarily unique - both edge_g_lseg and edge_g_cnurb structures will be stashed by this routine. It is the responsibility of the caller to check their magic numbers to sort out the type of each pointer:

struct bu_ptbl edge_g_tbl;
bu_ptbl_init(&edge_g_tbl, 64, "&edge_g_tbl");
nmg_edge_g_tabulate(&edge_g_tbl, &fu->l.magic, vlfree);
for (int i=0; i < BU_PTBL_LEN(&edge_g_tbl); i++) {
struct edge_g_lseg *elg;
struct edge_g_cnurb *ecg;
long *ep = BU_PTBL_GET(&edge_g_tbl, i);
switch (*ep) {
elg = (struct edge_g_lseg *)ep;
break;
ecg = (struct edge_g_cnurb *)ep;
break;
default
bu_log("Error - invalid edge geometry type\n");
}
}
int bu_log(const char *,...) _BU_ATTR_PRINTF12
#define NMG_EDGE_G_LSEG_MAGIC
Definition: magic.h:138
#define NMG_EDGE_G_CNURB_MAGIC
Definition: magic.h:137
void bu_ptbl_init(struct bu_ptbl *b, size_t len, const char *str)
#define BU_PTBL_LEN(ptbl)
Definition: ptbl.h:95
#define BU_PTBL_GET(ptbl, i)
Definition: ptbl.h:97
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...
#define NMG_CK_EDGE_G_LSEG(_p)
Definition: edge.h:39
#define NMG_CK_EDGE_G_CNURB(_p)
Definition: nurb.h:43
Definition: ptbl.h:53
Edge NURBS curve geometry.
Definition: topology.h:376
Line in 3D space.
Definition: topology.h:326

◆ nmg_edgeuse_with_eg_tabulate()

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".

The edge geometry has this information encoded within it, so this is largely a convenience routine to allow the caller to avoid bu_list based iteration which must understand the edge geometry containers and instead use the simpler bu_ptbl iteration.

◆ nmg_edgeuse_on_line_tabulate()

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 from there on "down" in the model that has both vertices within tolerance of the given line.

XXX This routine is a potential source of major trouble. XXX If there are "nearby" edges that "should" be on the list but XXX don't make it, then the intersection calculations might XXX miss important intersections. As an admittedly grubby workaround, use 10X the distance tol here, just to get more candidates onto the list. The caller will have to wrestle with the added fuzz.

◆ nmg_e_and_v_tabulate()

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 the NMG entity indicated by magic_p.

◆ nmg_2edgeuse_g_coincident()

int nmg_2edgeuse_g_coincident ( const struct edgeuse eu1,
const struct edgeuse eu2,
const struct bn_tol tol 
)

Given two edgeuses, determine if they share the same edge geometry, either topologically, or within tolerance.

Return values
0two edge geometries are not coincident
1edges geometries are everywhere coincident. (For linear edge_g_lseg, the 2 are the same line, within tol.)

◆ nmg_mark_edges_real()

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.

◆ nmg_pop_eu()

struct edgeuse * nmg_pop_eu ( struct bu_ptbl stack)

Convenience wrapper to retrieve and remove the last edgeuse element from the stack bu_ptbl.

◆ nmg_move_edge_thru_pnt()

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 edgeuse is not changed, so new edgeuse is parallel to the original.

Plane equations of all radial faces on this edge are changed and all vertices (except one anchor point) in radial loops are adjusted Note that the anchor point is chosen arbitrarily.

Return values
1failure
0success

◆ nmg_break_edge_at_verts()

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.

Returns the number of additional edges that were created.

◆ nmg_break_edges()

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 NMG element with the magic number pointed to by magic_p.

◆ nmg_edge_fuse()

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.

TODO - this needs MUCH better documentation...

If a bu_ptbl structure is passed into this function, the structure must contain edgeuse. Vertices will then be fused at the shell level. If an NMG structure is passed into this function, if the structure is an NMG region or model, vertices will be fused at the model level. If the NMG structure passed in is a shell or anything lower, vertices will be fused at the shell level.

◆ nmg_edge_g_fuse()

int nmg_edge_g_fuse ( const uint32_t *  magic_p,
struct bu_list vlfree,
const struct bn_tol tol 
)

Fuse edge_g structs.

TODO - this needs MUCH better documentation...

◆ nmg_pick_best_edge_g()

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, select the proper edge geometry to associate with.

Really, there are 3 geometries to be compared here: the vector between the two endpoints of this edge, and the two edge_g structures. Rather than always taking eu2 or eu1, select the one that best fits this one edge.

Consider fu1:

                      B
                      *
                     /|
                 eg2/ |
                   /  |
                 D/   |
                 *    |
                /     |
             A *-*----* C
                 E eg1

At the start of a face/face intersection, eg1 runs from A to C, and eg2 runs ADB. The line of intersection with the other face (fu2, not drawn) lies along eg1. Assume that edge AC needs to be broken at E, where E is just a little more than tol->dist away from A. Existing point D is found because it is within tol->dist of E, thanks to the cosine of angle BAC. So, edge AC is broken on vertex D, and the intersection list contains vertexuses A, E, and C.

Because D and E are the same point, fu1 has become a triangle with a little "spike" on the end. If this is handled simply by re-homing edge AE to eg2, it may cause trouble, because eg1 now runs EC, but the geometry for eg1 runs AC. If there are other vertices on edge eg1, the problem can not be resolved simply by recomputing the geometry of eg1. Since E (D) is within tolerance of eg1, it is not unreasonable just to leave eg1 alone.

The issue boils down to selecting whether the existing eg1 or eg2 best represents the direction of the little stub edge AD (shared with AE). In this case, eg2 is the correct choice, as AD (and AE) lie on line AB.

It would be disastrous to force all of eg1 to use the edge geometry of eg2, as the two lines are very different.

◆ nmg_eu_is_part_of_crack()

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.

◆ nmg_radial_join_eu()

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 proper angular orientation, so that the attached faces are correctly arranged radially around the edge.

This depends on both edges being part of face loops, with vertex and face geometry already associated.

The two edgeuses being joined might well be from separate shells, so the issue of preserving (simple) faceuse orientation parity (SAME, OPPOSITE, OPPOSITE, SAME, ...) can't be used here – that only applies to faceuses from the same shell.

Some of the edgeuses around both edges may be wires.

Call to nmg_check_radial at end has been deleted. Note that after two radial EU's have been joined a third cannot be joined to them without creating unclosed space that nmg_check_radial will find.

◆ nmg_break_all_es_on_v()

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...

◆ nmg_break_e_on_v()

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, compare every edge in the model with every vertex in the model.

If the vertex is within tolerance of the edge, break the edge, and enroll the new edge on a list of edges still to be processed.

A list of edges and a list of vertices are built, and then processed.

Space partitioning could improve the performance of this algorithm. For the moment, a brute-force approach is used.

Returns
Number of edges broken.

◆ nmg_wedge_class()

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.

0 degrees is to the rear (ON_REV), 90 degrees is to the RIGHT, 180 is ON_FORW, 270 is to the LEFT.

"halfway X" (ha, hb) have these properties:

< 0 (==> X < 180) RIGHT
> 0 (==> X > 180) LEFT
     ==0     (==> X == 180) ON_FORW

Possible return values are WEDGE_LEFT, WEDGE_CROSSING, WEDGE_RIGHT, and WEDGE_ON