void bu_delete_hook(struct bu_hook_list *hlp, bu_hook_t func, genptr_t clientdata) { struct bu_hook_list *cur = hlp; for (BU_LIST_FOR(cur, bu_hook_list, &hlp->l)) { if (cur->hookfunc == func && cur->clientdata == clientdata) { struct bu_hook_list *old = BU_LIST_PLAST(bu_hook_list, cur); BU_LIST_DEQUEUE(&(cur->l)); bu_free((genptr_t)cur, "bu_delete_hook"); cur = old; } } }
int bu_cmdhist_prev(void *clientData, int argc, const char **UNUSED(argv)) { struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData; struct bu_cmdhist *hp; if (argc != 2) { bu_log("ERROR: expecting only two arguments\n"); return BRLCAD_ERROR; } hp = BU_LIST_PLAST(bu_cmdhist, chop->cho_curr); if (BU_LIST_NOT_HEAD(hp, &chop->cho_head.l)) chop->cho_curr = hp; /* result is in chop->cho_curr */ return BRLCAD_OK; }
/** * B U _ L O G _ D E L E T E _ H O O K * * Removes the hook matching the function and clientdata parameters from * the hook list. Note that it is not necessarily the active (top) hook. */ void bu_log_delete_hook(bu_hook_t func, genptr_t clientdata) { #if 0 struct bu_hook_list *cur = &bu_log_hook_list; for ( BU_LIST_FOR( cur, bu_hook_list, &(bu_log_hook_list.l) ) ) { if ( cur->hookfunc == func && cur->clientdata == clientdata) { struct bu_hook_list *old = BU_LIST_PLAST(bu_hook_list, cur); BU_LIST_DEQUEUE( &(cur->l) ); bu_free((genptr_t)cur, "bu_log hook"); cur = old; } } #else bu_delete_hook(&bu_log_hook_list, func, clientdata); #endif }
/** * Read a polygon file and convert it to an NMG shell * * A polygon file consists of the following: * * The first line consists of two integer numbers: the number of * points (vertices) in the file, followed by the number of polygons * in the file. This line is followed by lines for each of the * vertices. Each vertex is listed on its own line, as the 3tuple "X * Y Z". After the list of vertices comes the list of polygons. * each polygon is represented by a line containing 1) the number of * vertices in the polygon, followed by 2) the indices of the * vertices that make up the polygon. * * Implicitly returns r->s_p which is a new shell containing all the * faces from the polygon file. * * XXX This is a horrible way to do this. Lee violates his own rules * about not creating fundamental structures on his own... :-) * Retired in favor of more modern tessellation strategies. */ struct shell * nmg_polytonmg(FILE *fp, struct nmgregion *r, const struct bn_tol *tol) { int i, j, num_pts, num_facets, pts_this_face, facet; int vl_len; struct vertex **v; /* list of all vertices */ struct vertex **vl; /* list of vertices for this polygon*/ point_t p; struct shell *s; struct faceuse *fu; struct loopuse *lu; struct edgeuse *eu; plane_t plane; struct model *m; s = nmg_msv(r); m = s->r_p->m_p; nmg_kvu(s->vu_p); /* get number of points & number of facets in file */ if (fscanf(fp, "%d %d", &num_pts, &num_facets) != 2) bu_bomb("polytonmg() Error in first line of poly file\n"); else if (RTG.NMG_debug & DEBUG_POLYTO) bu_log("points: %d facets: %d\n", num_pts, num_facets); v = (struct vertex **) bu_calloc(num_pts, sizeof (struct vertex *), "vertices"); /* build the vertices */ for (i = 0; i < num_pts; ++i) { GET_VERTEX(v[i], m); v[i]->magic = NMG_VERTEX_MAGIC; } /* read in the coordinates of the vertices */ for (i=0; i < num_pts; ++i) { if (fscanf(fp, "%lg %lg %lg", &p[0], &p[1], &p[2]) != 3) bu_bomb("polytonmg() Error reading point"); else if (RTG.NMG_debug & DEBUG_POLYTO) bu_log("read vertex #%d (%g %g %g)\n", i, p[0], p[1], p[2]); nmg_vertex_gv(v[i], p); } vl = (struct vertex **)bu_calloc(vl_len=8, sizeof (struct vertex *), "vertex parameter list"); for (facet = 0; facet < num_facets; ++facet) { if (fscanf(fp, "%d", &pts_this_face) != 1) bu_bomb("polytonmg() error getting pt count for this face"); if (RTG.NMG_debug & DEBUG_POLYTO) bu_log("facet %d pts in face %d\n", facet, pts_this_face); if (pts_this_face > vl_len) { while (vl_len < pts_this_face) vl_len *= 2; vl = (struct vertex **)bu_realloc((char *)vl, vl_len*sizeof(struct vertex *), "vertex parameter list (realloc)"); } for (i=0; i < pts_this_face; ++i) { if (fscanf(fp, "%d", &j) != 1) bu_bomb("polytonmg() error getting point index for v in f"); vl[i] = v[j-1]; } fu = nmg_cface(s, vl, pts_this_face); lu = BU_LIST_FIRST(loopuse, &fu->lu_hd); /* XXX should check for vertex-loop */ eu = BU_LIST_FIRST(edgeuse, &lu->down_hd); NMG_CK_EDGEUSE(eu); if (bn_mk_plane_3pts(plane, eu->vu_p->v_p->vg_p->coord, BU_LIST_PNEXT(edgeuse, eu)->vu_p->v_p->vg_p->coord, BU_LIST_PLAST(edgeuse, eu)->vu_p->v_p->vg_p->coord, tol)) { bu_log("At %d in %s\n", __LINE__, __FILE__); bu_bomb("polytonmg() cannot make plane equation\n"); } else nmg_face_g(fu, plane); } for (i=0; i < num_pts; ++i) { if (BU_LIST_IS_EMPTY(&v[i]->vu_hd)) continue; FREE_VERTEX(v[i]); } bu_free((char *)v, "vertex array"); return s; }
/** * Make a list of all edgeuses which are at the same distance as the * first element on the list. Toss out opposing pairs of edgeuses of the * same edge. * */ HIDDEN void make_near_list(struct edge_info *edge_list, struct bu_list *near1, const struct bn_tol *tol) { struct edge_info *ei; struct edge_info *ei_p; struct edge_info *tmp; fastf_t dist; BU_CK_LIST_HEAD(&edge_list->l); BU_CK_LIST_HEAD(near1); /* toss opposing pairs of uses of the same edge from the list */ ei = BU_LIST_FIRST(edge_info, &edge_list->l); while (BU_LIST_NOT_HEAD(&ei->l, &edge_list->l)) { NMG_CK_EI(ei); ei_p = BU_LIST_FIRST(edge_info, &edge_list->l); while (BU_LIST_NOT_HEAD(&ei_p->l, &edge_list->l)) { NMG_CK_EI(ei_p); NMG_CK_VED(ei_p->ved_p); /* if we've found an opposing use of the same * edge toss the pair of them */ if (ei_p->ved_p->magic_p == ei->ved_p->magic_p && ei_p->eu_p->eumate_p->vu_p->v_p == ei->eu_p->vu_p->v_p && ei_p->eu_p->vu_p->v_p == ei->eu_p->eumate_p->vu_p->v_p) { if (UNLIKELY(RTG.NMG_debug & DEBUG_PT_FU)) { bu_log("tossing edgeuse pair:\n"); bu_log("(%g %g %g) -> (%g %g %g)\n", V3ARGS(ei->eu_p->vu_p->v_p->vg_p->coord), V3ARGS(ei->eu_p->eumate_p->vu_p->v_p->vg_p->coord)); bu_log("(%g %g %g) -> (%g %g %g)\n", V3ARGS(ei_p->eu_p->vu_p->v_p->vg_p->coord), V3ARGS(ei_p->eu_p->eumate_p->vu_p->v_p->vg_p->coord)); } tmp = ei_p; ei_p = BU_LIST_PLAST(edge_info, &ei_p->l); BU_LIST_DEQUEUE(&tmp->l); bu_free((char *)tmp, "edge info struct"); tmp = ei; ei = BU_LIST_PLAST(edge_info, &ei->l); BU_LIST_DEQUEUE(&tmp->l); bu_free((char *)tmp, "edge info struct"); break; } ei_p = BU_LIST_PNEXT(edge_info, &ei_p->l); } ei = BU_LIST_PNEXT(edge_info, &ei->l); } if (BU_LIST_IS_EMPTY(&edge_list->l)) return; ei = BU_LIST_FIRST(edge_info, &edge_list->l); NMG_CK_EI(ei); NMG_CK_VED(ei->ved_p); dist = ei->ved_p->dist; /* create "near" list with all ei's at this dist */ for (BU_LIST_FOR(ei, edge_info, &edge_list->l)) { NMG_CK_EI(ei); NMG_CK_VED(ei->ved_p); if (NEAR_EQUAL(ei->ved_p->dist, dist, tol->dist_sq)) { ei_p = BU_LIST_PLAST(edge_info, &ei->l); BU_LIST_DEQUEUE(&ei->l); BU_LIST_APPEND(near1, &ei->l); ei = ei_p; } } if (UNLIKELY(RTG.NMG_debug & DEBUG_PT_FU)) { bu_log("dist %g near list\n", dist); for (BU_LIST_FOR(ei, edge_info, near1)) { bu_log("\t(%g %g %g) -> (%g %g %g)\n", V3ARGS(ei->eu_p->vu_p->v_p->vg_p->coord), V3ARGS(ei->eu_p->eumate_p->vu_p->v_p->vg_p->coord)); bu_log("\tdist:%g class:%s status:%d\n\t\tv1(%g %g %g) v2(%g %g %g)\n", ei->ved_p->dist, nmg_class_name(ei->nmg_class), ei->ved_p->status, V3ARGS(ei->ved_p->v1->vg_p->coord), V3ARGS(ei->ved_p->v2->vg_p->coord)); bu_log("\tei->ved_p->magic_p=%p, ei->eu_p->vu_p=%p, ei->eu_p->eumate_p->vu_p=%p\n", (void *)ei->ved_p->magic_p, (void *)ei->eu_p->vu_p, (void *)ei->eu_p->eumate_p->vu_p); } }