BRL-CAD

Routines for working with NMG Loops and Loop Uses. More...

Collaboration diagram for Loop:

Files

file  loop.h
 

Macros

#define NMG_CK_LOOP(_p)   NMG_CKMAG(_p, NMG_LOOP_MAGIC, "loop")
 
#define NMG_CK_LOOP_A(_p)   NMG_CKMAG(_p, NMG_LOOP_A_MAGIC, "loop_a")
 
#define NMG_CK_LOOPUSE(_p)   NMG_CKMAG(_p, NMG_LOOPUSE_MAGIC, "loopuse")
 
#define GET_LOOP(p, m)   {NMG_GETSTRUCT(p, loop); NMG_INCR_INDEX(p, m);}
 
#define GET_LOOP_A(p, m)   {NMG_GETSTRUCT(p, loop_a); NMG_INCR_INDEX(p, m);}
 
#define GET_LOOPUSE(p, m)   {NMG_GETSTRUCT(p, loopuse); NMG_INCR_INDEX(p, m);}
 
#define GET_LOOPUSE_A(p, m)   {NMG_GETSTRUCT(p, loopuse_a); NMG_INCR_INDEX(p, m);}
 
#define FREE_LOOP(p)   NMG_FREESTRUCT(p, loop)
 
#define FREE_LOOP_A(p)   NMG_FREESTRUCT(p, loop_a)
 
#define FREE_LOOPUSE(p)   NMG_FREESTRUCT(p, loopuse)
 
#define FREE_LOOPUSE_A(p)   NMG_FREESTRUCT(p, loopuse_a)
 

Functions

void nmg_loop_a (struct loop *l, const struct bn_tol *tol)
 Build the bounding box for a loop. More...
 
int nmg_demote_lu (struct loopuse *lu)
 Demote a loopuse of edgeuses to a bunch of wire edges in the shell. More...
 
struct loopusenmg_mlv (uint32_t *magic, struct vertex *v, int orientation)
 Make a new loop (with specified orientation) and vertex, in a shell or face. XXX - vertex or vertexuse? or both? ctj. More...
 
int nmg_klu (struct loopuse *lu1)
 Kill loopuse, loopuse mate, and loop. More...
 
void nmg_jl (struct loopuse *lu, struct edgeuse *eu)
 Join two loops together which share a common edge, such that both occurrences of the common edge are deleted. More...
 
struct vertexusenmg_join_2loops (struct vertexuse *vu1, struct vertexuse *vu2)
 Intended to join an interior and exterior loop together, by building a bridge between the two indicated vertices. More...
 
struct vertexusenmg_join_singvu_loop (struct vertexuse *vu1, struct vertexuse *vu2)
 vu1 is in a regular loop, vu2 is in a loop of a single vertex A jaunt is taken from vu1 to vu2 and back to vu1, and the old loop at vu2 is destroyed. More...
 
struct vertexusenmg_join_2singvu_loops (struct vertexuse *vu1, struct vertexuse *vu2)
 Both vertices are part of single vertex loops. Converts loop on vu1 into a real loop that connects them together, with a single edge (two edgeuses). Loop on vu2 is killed. More...
 
struct loopusenmg_cut_loop (struct vertexuse *vu1, struct vertexuse *vu2, struct bu_list *vlfree)
 Divide a loop of edges between two vertexuses. More...
 
struct loopusenmg_split_lu_at_vu (struct loopuse *lu, struct vertexuse *vu)
 
struct vertexusenmg_find_repeated_v_in_lu (struct vertexuse *vu)
 
void nmg_split_touchingloops (struct loopuse *lu, const struct bn_tol *tol)
 
int nmg_join_touchingloops (struct loopuse *lu)
 
int nmg_get_touching_jaunts (const struct loopuse *lu, struct bu_ptbl *tbl, int *need_init)
 
void nmg_kill_accordions (struct loopuse *lu)
 
int nmg_loop_split_at_touching_jaunt (struct loopuse *lu, const struct bn_tol *tol)
 
void nmg_simplify_loop (struct loopuse *lu, struct bu_list *vlfree)
 
int nmg_kill_snakes (struct loopuse *lu, struct bu_list *vlfree)
 
void nmg_mv_lu_between_shells (struct shell *dest, struct shell *src, struct loopuse *lu)
 
void nmg_moveltof (struct faceuse *fu, struct shell *s)
 
struct loopusenmg_dup_loop (struct loopuse *lu, uint32_t *parent, long **trans_tbl)
 
void nmg_set_lu_orientation (struct loopuse *lu, int is_opposite)
 
void nmg_lu_reorient (struct loopuse *lu)
 
struct edgeusenmg_eusplit (struct vertex *v, struct edgeuse *oldeu, int share_geom)
 
struct edgeusenmg_esplit (struct vertex *v, struct edgeuse *eu, int share_geom)
 
struct edgeusenmg_ebreak (struct vertex *v, struct edgeuse *eu)
 
struct edgeusenmg_ebreaker (struct vertex *v, struct edgeuse *eu, const struct bn_tol *tol)
 
struct vertexnmg_e2break (struct edgeuse *eu1, struct edgeuse *eu2)
 
int nmg_unbreak_edge (struct edgeuse *eu1_first)
 
int nmg_unbreak_shell_edge_unsafe (struct edgeuse *eu1_first)
 
struct edgeusenmg_eins (struct edgeuse *eu)
 
void nmg_mv_eu_between_shells (struct shell *dest, struct shell *src, struct edgeuse *eu)
 
struct loopusenmg_find_lu_of_vu (const struct vertexuse *vu)
 
int nmg_loop_is_a_crack (const struct loopuse *lu)
 
int nmg_loop_is_ccw (const struct loopuse *lu, const vect_t norm, const struct bn_tol *tol)
 
const struct vertexusenmg_loop_touches_self (const struct loopuse *lu)
 
int nmg_2lu_identical (const struct edgeuse *eu1, const struct edgeuse *eu2)
 
struct vertexusenmg_find_pnt_in_lu (const struct loopuse *lu, const point_t pt, const struct bn_tol *tol)
 
int nmg_is_vertex_in_looplist (const struct vertex *v, const struct bu_list *hd, int singletons)
 
int nmg_is_edge_in_looplist (const struct edge *e, const struct bu_list *hd)
 
struct vertexusenmg_find_vertex_in_lu (const struct vertex *v, const struct loopuse *lu)
 
void nmg_fix_overlapping_loops (struct shell *s, struct bu_list *vlfree, const struct bn_tol *tol)
 
void nmg_break_crossed_loops (struct shell *is, const struct bn_tol *tol)
 
void nmg_loop_plane_newell (const struct loopuse *lu, plane_t pl)
 
fastf_t nmg_loop_plane_area (const struct loopuse *lu, plane_t pl)
 
fastf_t nmg_loop_plane_area2 (const struct loopuse *lu, plane_t pl, const struct bn_tol *tol)
 
int nmg_lu_is_convex (struct loopuse *lu, struct bu_list *vlfree, const struct bn_tol *tol)
 
int nmg_classify_pnt_loop (const point_t pt, const struct loopuse *lu, struct bu_list *vlfree, const struct bn_tol *tol)
 
int nmg_classify_lu_lu (const struct loopuse *lu1, const struct loopuse *lu2, struct bu_list *vlfree, const struct bn_tol *tol)
 
int nmg_class_pnt_lu_except (point_t pt, const struct loopuse *lu, const struct edge *e_p, struct bu_list *vlfree, const struct bn_tol *tol)
 
void nmg_ck_lu_orientation (struct loopuse *lu, const struct bn_tol *tolp)
 

Detailed Description

Routines for working with NMG Loops and Loop Uses.

Macro Definition Documentation

◆ NMG_CK_LOOP

#define NMG_CK_LOOP (   _p)    NMG_CKMAG(_p, NMG_LOOP_MAGIC, "loop")

Definition at line 38 of file loop.h.

◆ NMG_CK_LOOP_A

#define NMG_CK_LOOP_A (   _p)    NMG_CKMAG(_p, NMG_LOOP_A_MAGIC, "loop_a")

Definition at line 39 of file loop.h.

◆ NMG_CK_LOOPUSE

#define NMG_CK_LOOPUSE (   _p)    NMG_CKMAG(_p, NMG_LOOPUSE_MAGIC, "loopuse")

Definition at line 40 of file loop.h.

◆ GET_LOOP

#define GET_LOOP (   p,
 
)    {NMG_GETSTRUCT(p, loop); NMG_INCR_INDEX(p, m);}

Definition at line 42 of file loop.h.

◆ GET_LOOP_A

#define GET_LOOP_A (   p,
 
)    {NMG_GETSTRUCT(p, loop_a); NMG_INCR_INDEX(p, m);}

Definition at line 43 of file loop.h.

◆ GET_LOOPUSE

#define GET_LOOPUSE (   p,
 
)    {NMG_GETSTRUCT(p, loopuse); NMG_INCR_INDEX(p, m);}

Definition at line 44 of file loop.h.

◆ GET_LOOPUSE_A

#define GET_LOOPUSE_A (   p,
 
)    {NMG_GETSTRUCT(p, loopuse_a); NMG_INCR_INDEX(p, m);}

Definition at line 45 of file loop.h.

◆ FREE_LOOP

#define FREE_LOOP (   p)    NMG_FREESTRUCT(p, loop)

Definition at line 47 of file loop.h.

◆ FREE_LOOP_A

#define FREE_LOOP_A (   p)    NMG_FREESTRUCT(p, loop_a)

Definition at line 48 of file loop.h.

◆ FREE_LOOPUSE

#define FREE_LOOPUSE (   p)    NMG_FREESTRUCT(p, loopuse)

Definition at line 49 of file loop.h.

◆ FREE_LOOPUSE_A

#define FREE_LOOPUSE_A (   p)    NMG_FREESTRUCT(p, loopuse_a)

Definition at line 50 of file loop.h.

Function Documentation

◆ nmg_loop_a()

void nmg_loop_a ( struct loop l,
const struct bn_tol tol 
)

Build the bounding box for a loop.

The bounding box is guaranteed never to have zero thickness.

XXX This really isn't loop geometry, this is a loop attribute. This routine really should be called nmg_loop_bb(), unless it gets something more to do.

◆ nmg_demote_lu()

int nmg_demote_lu ( struct loopuse lu)

Demote a loopuse of edgeuses to a bunch of wire edges in the shell.

Return values
0If all is well (edges moved to shell, loopuse deleted).
1If parent is empty, and is thus "illegal". Still successful.

◆ nmg_mlv()

struct loopuse * nmg_mlv ( uint32_t *  magic,
struct vertex v,
int  orientation 
)

Make a new loop (with specified orientation) and vertex, in a shell or face. XXX - vertex or vertexuse? or both? ctj.

If the vertex 'v' is NULL, the shell's lone vertex is used, or a new vertex is created.

"magic" must point to the magic number of a faceuse or shell.

If the shell has a lone vertex in it, that lone vertex will be used. If a non-NULL 'v' is provided, the lone vertex and 'v' will be fused together. XXX Why is this good?

If a convenient shell does not exist, use s=nmg_msv() to make the shell and vertex, then call lu=nmg_mlv(s, s->vu_p->v_p, OT_SAME), followed by nmg_kvu(s->vu_p).

Implicit returns - The new vertexuse can be had by: BU_LIST_FIRST(vertexuse, &lu->down_hd);

In case the returned loopuse isn't retained, the new loopuse was inserted at the +head+ of the appropriate list, e.g.: lu = BU_LIST_FIRST(loopuse, &fu->lu_hd); or lu = BU_LIST_FIRST(loopuse, &s->lu_hd);

N.B. This function is made more complex than warranted by using the "hack" of stealing a vertexuse structure from the shell if at all possible. A future enhancement to this function would be to remove the vertexuse steal and have the caller pass in the vertex from the shell followed by a call to nmg_kvu(s->vu_p). The v==NULL convention is used only in nmg_mod.c.

◆ nmg_klu()

int nmg_klu ( struct loopuse lu1)

Kill loopuse, loopuse mate, and loop.

if the loop contains any edgeuses or vertexuses they are killed before the loop is deleted.

We support the concept of killing a loop with no children to support the routine "nmg_demote_lu"

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

◆ nmg_jl()

void nmg_jl ( struct loopuse lu,
struct edgeuse eu 
)

Join two loops together which share a common edge, such that both occurrences of the common edge are deleted.

This routine always leaves "lu" intact, and kills the loop radial to "eu" (after stealing all its edges).

Either both loops must be of the same orientation, or then first loop must be OT_SAME, and the second loop must be OT_OPPOSITE. Joining OT_SAME & OT_OPPOSITE always gives an OT_SAME result. Above statement is not true!!!! I have added nmg_lu_reorient() -JRA Since "lu" must survive, it must be the OT_SAME one.

◆ nmg_join_2loops()

struct vertexuse * nmg_join_2loops ( struct vertexuse vu1,
struct vertexuse vu2 
)

Intended to join an interior and exterior loop together, by building a bridge between the two indicated vertices.

This routine can be used to join two exterior loops which do not overlap, and it can also be used to join an exterior loop with a loop of opposite orientation that lies entirely within it. This restriction is important, but not checked for.

If the two vertexuses reference distinct vertices, then two new edges are built to bridge the loops together. If the two vertexuses share the same vertex, then it is even easier.

Returns the replacement for vu2.

◆ nmg_join_singvu_loop()

struct vertexuse * nmg_join_singvu_loop ( struct vertexuse vu1,
struct vertexuse vu2 
)

vu1 is in a regular loop, vu2 is in a loop of a single vertex A jaunt is taken from vu1 to vu2 and back to vu1, and the old loop at vu2 is destroyed.

Return is the new vu that replaces vu2.

◆ nmg_join_2singvu_loops()

struct vertexuse * nmg_join_2singvu_loops ( struct vertexuse vu1,
struct vertexuse vu2 
)

Both vertices are part of single vertex loops. Converts loop on vu1 into a real loop that connects them together, with a single edge (two edgeuses). Loop on vu2 is killed.

Returns replacement vu for vu2. Does not change the orientation.

◆ nmg_cut_loop()

struct loopuse * nmg_cut_loop ( struct vertexuse vu1,
struct vertexuse vu2,
struct bu_list vlfree 
)

Divide a loop of edges between two vertexuses.

Make a new loop between the two vertexes, and split it and the loop of the vertexuses at the same time.

             BEFORE                                  AFTER


    Va    eu1  vu1           Vb             Va   eu1  vu1             Vb
     * <---------* <---------*               * <--------*  * <--------*
     |                                       |             |
     |                       ^               |          ^  |          ^
     |        Original       |               | Original |  |    New   |
     |          Loopuse      |               | Loopuse  |  |  Loopuse |
     V                       |               V          |  V /        |
                             |                          |   /         |
     *----------> *--------> *               *--------> *  *--------> *
    Vd            vu2 eu2    Vc             Vd             vu2  eu2   Vc

Returns the new loopuse pointer. The new loopuse will contain "vu2" and the edgeuse associated with "vu2" as the FIRST edgeuse on the list of edgeuses. The edgeuse for the new edge (connecting the vertices indicated by vu1 and vu2) will be the LAST edgeuse on the new loopuse's list of edgeuses.

It is the caller's responsibility to re-bound the loops.

Both old and new loopuse will have orientation OT_UNSPEC. It is the callers responsibility to determine what the orientations should be. This can be conveniently done with nmg_lu_reorient().

Here is a simple example of how the new loopuse might have a different orientation than the original one:

             F<----------------E
             |                 ^
             |                 |
             |      C--------->D
             |      ^          .
             |      |          .
             |      |          .
             |      B<---------A
             |                 ^
             v                 |
             G---------------->H

When nmg_cut_loop(A, D) is called, the new loop ABCD is clockwise, even though the original loop was counter-clockwise. There is no way to determine this without referring to the face normal and vertex geometry, which being a topology routine this routine shouldn't do.

Return values
NULLon error
luon success, loopuse of new loop.

◆ nmg_split_lu_at_vu()

struct loopuse * nmg_split_lu_at_vu ( struct loopuse lu,
struct vertexuse vu 
)

◆ nmg_find_repeated_v_in_lu()

struct vertexuse * nmg_find_repeated_v_in_lu ( struct vertexuse vu)

◆ nmg_split_touchingloops()

void nmg_split_touchingloops ( struct loopuse lu,
const struct bn_tol tol 
)

◆ nmg_join_touchingloops()

int nmg_join_touchingloops ( struct loopuse lu)

◆ nmg_get_touching_jaunts()

int nmg_get_touching_jaunts ( const struct loopuse lu,
struct bu_ptbl tbl,
int *  need_init 
)

◆ nmg_kill_accordions()

void nmg_kill_accordions ( struct loopuse lu)

◆ nmg_loop_split_at_touching_jaunt()

int nmg_loop_split_at_touching_jaunt ( struct loopuse lu,
const struct bn_tol tol 
)

◆ nmg_simplify_loop()

void nmg_simplify_loop ( struct loopuse lu,
struct bu_list vlfree 
)

◆ nmg_kill_snakes()

int nmg_kill_snakes ( struct loopuse lu,
struct bu_list vlfree 
)

◆ nmg_mv_lu_between_shells()

void nmg_mv_lu_between_shells ( struct shell dest,
struct shell src,
struct loopuse lu 
)

◆ nmg_moveltof()

void nmg_moveltof ( struct faceuse fu,
struct shell s 
)

◆ nmg_dup_loop()

struct loopuse * nmg_dup_loop ( struct loopuse lu,
uint32_t *  parent,
long **  trans_tbl 
)

◆ nmg_set_lu_orientation()

void nmg_set_lu_orientation ( struct loopuse lu,
int  is_opposite 
)

◆ nmg_lu_reorient()

void nmg_lu_reorient ( struct loopuse lu)

◆ nmg_eusplit()

struct edgeuse * nmg_eusplit ( struct vertex v,
struct edgeuse oldeu,
int  share_geom 
)

◆ nmg_esplit()

struct edgeuse * nmg_esplit ( struct vertex v,
struct edgeuse eu,
int  share_geom 
)

◆ nmg_ebreak()

struct edgeuse * nmg_ebreak ( struct vertex v,
struct edgeuse eu 
)

◆ nmg_ebreaker()

struct edgeuse * nmg_ebreaker ( struct vertex v,
struct edgeuse eu,
const struct bn_tol tol 
)

◆ nmg_e2break()

struct vertex * nmg_e2break ( struct edgeuse eu1,
struct edgeuse eu2 
)

◆ nmg_unbreak_edge()

int nmg_unbreak_edge ( struct edgeuse eu1_first)

◆ nmg_unbreak_shell_edge_unsafe()

int nmg_unbreak_shell_edge_unsafe ( struct edgeuse eu1_first)

◆ nmg_eins()

struct edgeuse * nmg_eins ( struct edgeuse eu)

◆ nmg_mv_eu_between_shells()

void nmg_mv_eu_between_shells ( struct shell dest,
struct shell src,
struct edgeuse eu 
)

◆ nmg_find_lu_of_vu()

struct loopuse * nmg_find_lu_of_vu ( const struct vertexuse vu)

◆ nmg_loop_is_a_crack()

int nmg_loop_is_a_crack ( const struct loopuse lu)

◆ nmg_loop_is_ccw()

int nmg_loop_is_ccw ( const struct loopuse lu,
const vect_t  norm,
const struct bn_tol tol 
)

◆ nmg_loop_touches_self()

const struct vertexuse * nmg_loop_touches_self ( const struct loopuse lu)

◆ nmg_2lu_identical()

int nmg_2lu_identical ( const struct edgeuse eu1,
const struct edgeuse eu2 
)

◆ nmg_find_pnt_in_lu()

struct vertexuse * nmg_find_pnt_in_lu ( const struct loopuse lu,
const point_t  pt,
const struct bn_tol tol 
)

◆ nmg_is_vertex_in_looplist()

int nmg_is_vertex_in_looplist ( const struct vertex v,
const struct bu_list hd,
int  singletons 
)

◆ nmg_is_edge_in_looplist()

int nmg_is_edge_in_looplist ( const struct edge e,
const struct bu_list hd 
)

◆ nmg_find_vertex_in_lu()

struct vertexuse * nmg_find_vertex_in_lu ( const struct vertex v,
const struct loopuse lu 
)

◆ nmg_fix_overlapping_loops()

void nmg_fix_overlapping_loops ( struct shell s,
struct bu_list vlfree,
const struct bn_tol tol 
)

◆ nmg_break_crossed_loops()

void nmg_break_crossed_loops ( struct shell is,
const struct bn_tol tol 
)

◆ nmg_loop_plane_newell()

void nmg_loop_plane_newell ( const struct loopuse lu,
plane_t  pl 
)

◆ nmg_loop_plane_area()

fastf_t nmg_loop_plane_area ( const struct loopuse lu,
plane_t  pl 
)

◆ nmg_loop_plane_area2()

fastf_t nmg_loop_plane_area2 ( const struct loopuse lu,
plane_t  pl,
const struct bn_tol tol 
)

◆ nmg_lu_is_convex()

int nmg_lu_is_convex ( struct loopuse lu,
struct bu_list vlfree,
const struct bn_tol tol 
)

◆ nmg_classify_pnt_loop()

int nmg_classify_pnt_loop ( const point_t  pt,
const struct loopuse lu,
struct bu_list vlfree,
const struct bn_tol tol 
)

◆ nmg_classify_lu_lu()

int nmg_classify_lu_lu ( const struct loopuse lu1,
const struct loopuse lu2,
struct bu_list vlfree,
const struct bn_tol tol 
)

◆ nmg_class_pnt_lu_except()

int nmg_class_pnt_lu_except ( point_t  pt,
const struct loopuse lu,
const struct edge e_p,
struct bu_list vlfree,
const struct bn_tol tol 
)

◆ nmg_ck_lu_orientation()

void nmg_ck_lu_orientation ( struct loopuse lu,
const struct bn_tol tolp 
)