BRL-CAD
|
Routines for working with NMG Edges and Edge Uses. More...
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 edgeuse * | nmg_me (struct vertex *v1, struct vertex *v2, struct shell *s) |
Make wire edge. More... | |
struct edgeuse * | nmg_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 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. More... | |
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. More... | |
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. More... | |
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. More... | |
struct edgeuse * | nmg_find_eu_of_vu (const struct vertexuse *vu) |
Return a pointer to the edgeuse which is the parent of this vertexuse. More... | |
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. More... | |
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) More... | |
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. More... | |
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. More... | |
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. 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 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. 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 edgeuse * | nmg_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_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. 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... | |
Routines for working with NMG Edges and Edge Uses.
#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_ARE_EUS_ADJACENT | ( | _eu1, | |
_eu2 | |||
) |
Do two edgeuses share the same two vertices? If yes, eu's should be joined.
#define EDGESADJ | ( | _e1, | |
_e2 | |||
) | NMG_ARE_EUS_ADJACENT(_e1, _e2) |
void nmg_edge_g | ( | struct edgeuse * | eu | ) |
Compute the equation of the line formed by the endpoints of the edge.
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.
0 | If the old edge geometry (eu->g.magic_p) has other uses. |
1 | If the old edge geometry has been destroyed. Caller beware! |
int nmg_demote_eu | ( | struct edgeuse * | eu | ) |
Demote a wire edge into a pair of self-loop vertices.
0 | If all is well |
1 | If shell is empty, and is thus "illegal". |
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().
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.
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.
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:
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.
int nmg_keu | ( | struct edgeuse * | eu | ) |
Delete an edgeuse & its mate from a shell or loop.
0 | If all is well |
1 | If 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). |
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().
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.
edgeuse* | Edgeuse which matches the criteria |
NULL | Unable to find matching edgeuse |
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_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.
edgeuse* | Edgeuse of an edge which matches the criteria |
NULL | Unable to find matching edge |
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.
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.
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)
Looking radially around an edge, find another edge which is a part of a face in the same shell.
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.
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.
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.
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.
-1 | if edgeuse is not part of a faceuse. |
0 | if left vector successfully computed into caller's array. |
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.
-1 | if edgeuse is not part of a faceuse. |
0 | if left vector successfully computed into caller's array. |
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().
Check if a vertex is in use within a list of edges.
1 | If found |
0 | If not found |
Check if edge e is present within a list of edges.
1 | If found |
0 | If not found |
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.
[out] | tab | a bu_ptbl holding struct edgeuse pointers. |
magic_p | pointer to an NMG data structure's magic entry. | |
vlfree | list of available vlist segments to be reused by debug drawing routines. |
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.
[out] | tab | a bu_ptbl holding struct edge pointers. |
magic_p | pointer to an NMG data structure's magic entry. | |
vlfree | list of available vlist segments to be reused by debug drawing routines. |
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
[out] | tab | a bu_ptbl holding edge geometry pointers. |
magic_p | pointer to an NMG data structure's magic entry. | |
vlfree | list 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:
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.
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.
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.
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.
0 | two edge geometries are not coincident |
1 | edges geometries are everywhere coincident. (For linear edge_g_lseg, the 2 are the same line, within 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.
Convenience wrapper to retrieve and remove the last edgeuse element from the stack bu_ptbl.
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.
1 | failure |
0 | success |
Split an edge into multiple edges at specified vertices if they are within tolerance distance.
Returns the number of additional edges that were created.
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.
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.
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...
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.
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.
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.
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...
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.
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