/** * Classify a point vs a vertex (touching/missed) */ static int nmg_class_pt_vu(struct fpi *fpi, struct vertexuse *vu) { vect_t delta; struct ve_dist *ved; NMG_CK_VERTEXUSE(vu); /* see if we've classified this vertex WRT the point already */ for (BU_LIST_FOR(ved, ve_dist, &fpi->ve_dh)) { NMG_CK_VED(ved); if (ved->magic_p == &vu->v_p->magic) { goto found; } } /* if we get here, we didn't find the vertex in the list of * previously classified geometry. Create an entry in the * face's list of processed geometry. */ VSUB2(delta, vu->v_p->vg_p->coord, fpi->pt); BU_ALLOC(ved, struct ve_dist); ved->magic_p = &vu->v_p->magic; ved->dist = MAGNITUDE(delta); if (ved->dist < fpi->tol->dist_sq) { ved->status = NMG_FPI_TOUCHED; if (fpi->hits == NMG_FPI_PERGEOM) { /* need to cast vu_func pointer for actual use as a function */ void (*cfp)(struct vertexuse *, point_t, const char*); cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func; cfp(vu, fpi->pt, fpi->priv); } } else ved->status = NMG_FPI_MISSED; ved->v1 = ved->v2 = vu->v_p; BU_LIST_MAGIC_SET(&ved->l, NMG_VE_DIST_MAGIC); BU_LIST_APPEND(&fpi->ve_dh, &ved->l); found: if (fpi->vu_func && ved->status == NMG_FPI_TOUCHED && fpi->hits == NMG_FPI_PERUSE) { /* need to cast vu_func pointer for actual use as a function */ void (*cfp)(struct vertexuse *, point_t, const char*); cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func; cfp(vu, fpi->pt, fpi->priv); } return ved->status; }
const struct ged_cmd * zoom_cmd(void) { static struct ged_cmd cmd = { BU_LIST_INIT_ZERO, "zoom", "zoom view by specified scale factor", "zoom", &zoom_load, &zoom_unload, &ged_zoom }; BU_LIST_MAGIC_SET(&(cmd.l), GED_CMD_MAGIC); return &cmd; }
/** * If there is no ve_dist structure for this edge, compute one and * add it to the list. * * Sort an edge_info structure into the loops list of edgeuse status */ static struct edge_info * nmg_class_pt_eu(struct fpi *fpi, struct edgeuse *eu, struct edge_info *edge_list, const int in_or_out_only) { struct bn_tol tmp_tol; struct edgeuse *next_eu; struct ve_dist *ved, *ed; struct edge_info *ei_p; struct edge_info *ei; pointp_t eu_pt; vect_t left; vect_t v_to_pt; int found_data = 0; NMG_CK_FPI(fpi); BN_CK_TOL(fpi->tol); if (RTG.NMG_debug & DEBUG_PT_FU) { bu_log("pt (%g %g %g) vs_edge (%g %g %g) (%g %g %g) (eu=%p)\n", V3ARGS(fpi->pt), V3ARGS(eu->vu_p->v_p->vg_p->coord), V3ARGS(eu->eumate_p->vu_p->v_p->vg_p->coord), (void *)eu); } /* we didn't find a ve_dist structure for this edge, so we'll * have to do the calculations. */ tmp_tol = (*fpi->tol); if (in_or_out_only) { tmp_tol.dist = 0.0; tmp_tol.dist_sq = 0.0; } BU_ALLOC(ved, struct ve_dist); ved->magic_p = &eu->e_p->magic; ved->status = bn_distsq_pt3_lseg3(&ved->dist, eu->vu_p->v_p->vg_p->coord, eu->eumate_p->vu_p->v_p->vg_p->coord, fpi->pt, &tmp_tol); ved->v1 = eu->vu_p->v_p; ved->v2 = eu->eumate_p->vu_p->v_p; BU_LIST_MAGIC_SET(&ved->l, NMG_VE_DIST_MAGIC); BU_LIST_APPEND(&fpi->ve_dh, &ved->l); eu_pt = ved->v1->vg_p->coord; if (RTG.NMG_debug & DEBUG_PT_FU) { bu_log("nmg_class_pt_eu: status for eu %p (%g %g %g)<->(%g %g %g) vs pt (%g %g %g) is %d\n", (void *)eu, V3ARGS(eu->vu_p->v_p->vg_p->coord), V3ARGS(eu->eumate_p->vu_p->v_p->vg_p->coord), V3ARGS(fpi->pt), ved->status); bu_log("\tdist = %g\n", ved->dist); } /* Add a struct for this edgeuse to the loop's list of dist-sorted * edgeuses. */ BU_ALLOC(ei, struct edge_info); ei->ved_p = ved; ei->eu_p = eu; BU_LIST_MAGIC_SET(&ei->l, NMG_EDGE_INFO_MAGIC); /* compute the status (ei->status) of the point WRT this edge */ switch (ved->status) { case 0: /* pt is on the edge(use) */ ei->nmg_class = NMG_CLASS_AonBshared; if (fpi->eu_func && (fpi->hits == NMG_FPI_PERUSE || (fpi->hits == NMG_FPI_PERGEOM && !found_data))) { /* need to cast eu_func pointer for actual use as a function */ void (*cfp)(struct edgeuse *, point_t, const char*); cfp = (void (*)(struct edgeuse *, point_t, const char *))fpi->eu_func; cfp(eu, fpi->pt, fpi->priv); } break; case 1: /* within tolerance of endpoint at ved->v1 */ ei->nmg_class = NMG_CLASS_AonBshared; /* add an entry for the vertex in the edge list so that * other uses of this vertex will claim the point is within * tolerance without re-computing */ BU_ALLOC(ed, struct ve_dist); ed->magic_p = &ved->v1->magic; ed->status = ved->status; ed->v1 = ed->v2 = ved->v1; BU_LIST_MAGIC_SET(&ed->l, NMG_VE_DIST_MAGIC); BU_LIST_APPEND(&fpi->ve_dh, &ed->l); if (fpi->vu_func && (fpi->hits == NMG_FPI_PERUSE || (fpi->hits == NMG_FPI_PERGEOM && !found_data))) { /* need to cast vu_func pointer for actual use as a function */ void (*cfp)(struct vertexuse *, point_t, const char*); cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func; cfp(eu->vu_p, fpi->pt, fpi->priv); } break; case 2: /* within tolerance of endpoint at ved->v2 */ ei->nmg_class = NMG_CLASS_AonBshared; /* add an entry for the vertex in the edge list so that * other uses of this vertex will claim the point is within * tolerance without re-computing */ BU_ALLOC(ed, struct ve_dist); ed->magic_p = &ved->v2->magic; ed->status = ved->status; ed->v1 = ed->v2 = ved->v2; BU_LIST_MAGIC_SET(&ed->l, NMG_VE_DIST_MAGIC); BU_LIST_APPEND(&fpi->ve_dh, &ed->l); if (fpi->vu_func && (fpi->hits == NMG_FPI_PERUSE || (fpi->hits == NMG_FPI_PERGEOM && !found_data))) { /* need to cast vu_func pointer for actual use as a function */ void (*cfp)(struct vertexuse *, point_t, const char*); cfp = (void (*)(struct vertexuse *, point_t, const char *))fpi->vu_func; cfp(eu->eumate_p->vu_p, fpi->pt, fpi->priv); } break; case 3: /* PCA of pt on line is within tolerance of ved->v1 of segment */ ei->nmg_class = nmg_class_pt_euvu(fpi->pt, eu, fpi->tol); if (ei->nmg_class == NMG_CLASS_Unknown) ei->ved_p->dist = MAX_FASTF; break; case 4: /* PCA of pt on line is within tolerance of ved->v2 of segment */ next_eu = BU_LIST_PNEXT_CIRC(edgeuse, &eu->l); ei->nmg_class = nmg_class_pt_euvu(fpi->pt, next_eu, fpi->tol); if (ei->nmg_class == NMG_CLASS_Unknown) ei->ved_p->dist = MAX_FASTF; break; case 5: /* PCA is along length of edge, but point is NOT on edge. */ if (nmg_find_eu_left_non_unit(left, eu)) bu_bomb("can't find left vector\n"); /* take dot product of v->pt vector with left to determine * if pt is inside/left of edge */ VSUB2(v_to_pt, fpi->pt, eu_pt); if (VDOT(v_to_pt, left) > -SMALL_FASTF) ei->nmg_class = NMG_CLASS_AinB; else ei->nmg_class = NMG_CLASS_AoutB; break; default: bu_log("%s:%d status = %d\n", __FILE__, __LINE__, ved->status); bu_bomb("Why did this happen?"); break; } if (RTG.NMG_debug & DEBUG_PT_FU) { bu_log("pt @ dist %g from edge classed %s vs edge\n", ei->ved_p->dist, nmg_class_name(ei->nmg_class)); /* pl_pt_e(fpi, ei); */ } /* now that it's complete, add ei to the edge list */ for (BU_LIST_FOR(ei_p, edge_info, &edge_list->l)) { /* if the distance to this edge is smaller, or * if the distance is the same & the edge is the same * Insert edge_info struct here in list */ if (ved->dist < ei_p->ved_p->dist || (ZERO(ved->dist - ei_p->ved_p->dist) && ei_p->ved_p->magic_p == ved->magic_p)) { break; } } BU_LIST_INSERT(&ei_p->l, &ei->l); return ei; }