int _ged_rotate_tgc(struct ged *gedp, struct rt_tgc_internal *tgc, const char *attribute, matp_t rmat) { RT_TGC_CK_MAGIC(tgc); switch (attribute[0]) { case 'h': case 'H': switch (attribute[1]) { case '\0': MAT4X3VEC(tgc->h, rmat, tgc->h); break; case 'a': case 'A': if ((attribute[2] == 'b' || attribute[2] == 'B') && attribute[3] == '\0') { MAT4X3VEC(tgc->a, rmat, tgc->a); MAT4X3VEC(tgc->b, rmat, tgc->b); MAT4X3VEC(tgc->c, rmat, tgc->c); MAT4X3VEC(tgc->d, rmat, tgc->d); } else { bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } break; default: bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } break; default: bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } return GED_OK; }
/* * Default keypoint in model space is established in "pt". Returns * GED_ERROR if unable to determine a keypoint, otherwise returns * GED_OK. */ int _ged_get_solid_keypoint(struct ged *const gedp, fastf_t *const pt, const struct rt_db_internal *const ip, const fastf_t *const mat) { point_t mpt; RT_CK_DB_INTERNAL(ip); switch (ip->idb_type) { case ID_CLINE: { struct rt_cline_internal *cli = (struct rt_cline_internal *)ip->idb_ptr; RT_CLINE_CK_MAGIC(cli); VMOVE(mpt, cli->v); break; } case ID_PARTICLE: { struct rt_part_internal *part = (struct rt_part_internal *)ip->idb_ptr; RT_PART_CK_MAGIC(part); VMOVE(mpt, part->part_V); break; } case ID_PIPE: { struct rt_pipe_internal *pipeip; struct wdb_pipept *pipe_seg; pipeip = (struct rt_pipe_internal *)ip->idb_ptr; RT_PIPE_CK_MAGIC(pipeip); pipe_seg = BU_LIST_FIRST(wdb_pipept, &pipeip->pipe_segs_head); VMOVE(mpt, pipe_seg->pp_coord); break; } case ID_METABALL: { struct rt_metaball_internal *metaball = (struct rt_metaball_internal *)ip->idb_ptr; struct wdb_metaballpt *metaballpt; RT_METABALL_CK_MAGIC(metaball); VSETALL(mpt, 0.0); metaballpt = BU_LIST_FIRST(wdb_metaballpt, &metaball->metaball_ctrl_head); VMOVE(mpt, metaballpt->coord); break; } case ID_ARBN: { struct rt_arbn_internal *arbn = (struct rt_arbn_internal *)ip->idb_ptr; size_t i, j, k; int good_vert = 0; RT_ARBN_CK_MAGIC(arbn); for (i = 0; i < arbn->neqn; i++) { for (j = i + 1; j < arbn->neqn; j++) { for (k = j + 1; k < arbn->neqn; k++) { if (!bn_mkpoint_3planes(mpt, arbn->eqn[i], arbn->eqn[j], arbn->eqn[k])) { size_t l; good_vert = 1; for (l = 0; l < arbn->neqn; l++) { if (l == i || l == j || l == k) continue; if (DIST_PT_PLANE(mpt, arbn->eqn[l]) > gedp->ged_wdbp->wdb_tol.dist) { good_vert = 0; break; } } if (good_vert) break; } } if (good_vert) break; } if (good_vert) break; } break; } case ID_EBM: { struct rt_ebm_internal *ebm = (struct rt_ebm_internal *)ip->idb_ptr; point_t pnt; RT_EBM_CK_MAGIC(ebm); VSETALL(pnt, 0.0); MAT4X3PNT(mpt, ebm->mat, pnt); break; } case ID_BOT: { struct rt_bot_internal *bot = (struct rt_bot_internal *)ip->idb_ptr; VMOVE(mpt, bot->vertices); break; } case ID_DSP: { struct rt_dsp_internal *dsp = (struct rt_dsp_internal *)ip->idb_ptr; point_t pnt; RT_DSP_CK_MAGIC(dsp); VSETALL(pnt, 0.0); MAT4X3PNT(mpt, dsp->dsp_stom, pnt); break; } case ID_HF: { struct rt_hf_internal *hf = (struct rt_hf_internal *)ip->idb_ptr; RT_HF_CK_MAGIC(hf); VMOVE(mpt, hf->v); break; } case ID_VOL: { struct rt_vol_internal *vol = (struct rt_vol_internal *)ip->idb_ptr; point_t pnt; RT_VOL_CK_MAGIC(vol); VSETALL(pnt, 0.0); MAT4X3PNT(mpt, vol->mat, pnt); break; } case ID_HALF: { struct rt_half_internal *haf = (struct rt_half_internal *)ip->idb_ptr; RT_HALF_CK_MAGIC(haf); VSCALE(mpt, haf->eqn, haf->eqn[H]); break; } case ID_ARB8: { struct rt_arb_internal *arb = (struct rt_arb_internal *)ip->idb_ptr; RT_ARB_CK_MAGIC(arb); VMOVE(mpt, arb->pt[0]); break; } case ID_ELL: case ID_SPH: { struct rt_ell_internal *ell = (struct rt_ell_internal *)ip->idb_ptr; RT_ELL_CK_MAGIC(ell); VMOVE(mpt, ell->v); break; } case ID_SUPERELL: { struct rt_superell_internal *superell = (struct rt_superell_internal *)ip->idb_ptr; RT_SUPERELL_CK_MAGIC(superell); VMOVE(mpt, superell->v); break; } case ID_TOR: { struct rt_tor_internal *tor = (struct rt_tor_internal *)ip->idb_ptr; RT_TOR_CK_MAGIC(tor); VMOVE(mpt, tor->v); break; } case ID_TGC: case ID_REC: { struct rt_tgc_internal *tgc = (struct rt_tgc_internal *)ip->idb_ptr; RT_TGC_CK_MAGIC(tgc); VMOVE(mpt, tgc->v); break; } case ID_GRIP: { struct rt_grip_internal *gip = (struct rt_grip_internal *)ip->idb_ptr; RT_GRIP_CK_MAGIC(gip); VMOVE(mpt, gip->center); break; } case ID_ARS: { struct rt_ars_internal *ars = (struct rt_ars_internal *)ip->idb_ptr; RT_ARS_CK_MAGIC(ars); VMOVE(mpt, &ars->curves[0][0]); break; } case ID_RPC: { struct rt_rpc_internal *rpc = (struct rt_rpc_internal *)ip->idb_ptr; RT_RPC_CK_MAGIC(rpc); VMOVE(mpt, rpc->rpc_V); break; } case ID_RHC: { struct rt_rhc_internal *rhc = (struct rt_rhc_internal *)ip->idb_ptr; RT_RHC_CK_MAGIC(rhc); VMOVE(mpt, rhc->rhc_V); break; } case ID_EPA: { struct rt_epa_internal *epa = (struct rt_epa_internal *)ip->idb_ptr; RT_EPA_CK_MAGIC(epa); VMOVE(mpt, epa->epa_V); break; } case ID_EHY: { struct rt_ehy_internal *ehy = (struct rt_ehy_internal *)ip->idb_ptr; RT_EHY_CK_MAGIC(ehy); VMOVE(mpt, ehy->ehy_V); break; } case ID_HYP: { struct rt_hyp_internal *hyp = (struct rt_hyp_internal *)ip->idb_ptr; RT_HYP_CK_MAGIC(hyp); VMOVE(mpt, hyp->hyp_Vi); break; } case ID_ETO: { struct rt_eto_internal *eto = (struct rt_eto_internal *)ip->idb_ptr; RT_ETO_CK_MAGIC(eto); VMOVE(mpt, eto->eto_V); break; } case ID_POLY: { struct rt_pg_face_internal *_poly; struct rt_pg_internal *pg = (struct rt_pg_internal *)ip->idb_ptr; RT_PG_CK_MAGIC(pg); _poly = pg->poly; VMOVE(mpt, _poly->verts); break; } case ID_SKETCH: { struct rt_sketch_internal *skt = (struct rt_sketch_internal *)ip->idb_ptr; RT_SKETCH_CK_MAGIC(skt); VMOVE(mpt, skt->V); break; } case ID_EXTRUDE: { struct rt_extrude_internal *extr = (struct rt_extrude_internal *)ip->idb_ptr; RT_EXTRUDE_CK_MAGIC(extr); if (extr->skt && extr->skt->verts) { VJOIN2(mpt, extr->V, extr->skt->verts[0][0], extr->u_vec, extr->skt->verts[0][1], extr->v_vec); } else { VMOVE(mpt, extr->V); } break; } case ID_NMG: { struct vertex *v; struct vertexuse *vu; struct edgeuse *eu; struct loopuse *lu; struct faceuse *fu; struct shell *s; struct nmgregion *r; struct model *m = (struct model *) ip->idb_ptr; NMG_CK_MODEL(m); /* set default first */ VSETALL(mpt, 0.0); if (BU_LIST_IS_EMPTY(&m->r_hd)) break; r = BU_LIST_FIRST(nmgregion, &m->r_hd); if (!r) break; NMG_CK_REGION(r); if (BU_LIST_IS_EMPTY(&r->s_hd)) break; s = BU_LIST_FIRST(shell, &r->s_hd); if (!s) break; NMG_CK_SHELL(s); if (BU_LIST_IS_EMPTY(&s->fu_hd)) fu = (struct faceuse *)NULL; else fu = BU_LIST_FIRST(faceuse, &s->fu_hd); if (fu) { NMG_CK_FACEUSE(fu); lu = BU_LIST_FIRST(loopuse, &fu->lu_hd); NMG_CK_LOOPUSE(lu); if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) { eu = BU_LIST_FIRST(edgeuse, &lu->down_hd); NMG_CK_EDGEUSE(eu); NMG_CK_VERTEXUSE(eu->vu_p); v = eu->vu_p->v_p; } else { vu = BU_LIST_FIRST(vertexuse, &lu->down_hd); NMG_CK_VERTEXUSE(vu); v = vu->v_p; } NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } if (BU_LIST_IS_EMPTY(&s->lu_hd)) lu = (struct loopuse *)NULL; else lu = BU_LIST_FIRST(loopuse, &s->lu_hd); if (lu) { NMG_CK_LOOPUSE(lu); if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_EDGEUSE_MAGIC) { eu = BU_LIST_FIRST(edgeuse, &lu->down_hd); NMG_CK_EDGEUSE(eu); NMG_CK_VERTEXUSE(eu->vu_p); v = eu->vu_p->v_p; } else { vu = BU_LIST_FIRST(vertexuse, &lu->down_hd); NMG_CK_VERTEXUSE(vu); v = vu->v_p; } NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } if (BU_LIST_IS_EMPTY(&s->eu_hd)) eu = (struct edgeuse *)NULL; else eu = BU_LIST_FIRST(edgeuse, &s->eu_hd); if (eu) { NMG_CK_EDGEUSE(eu); NMG_CK_VERTEXUSE(eu->vu_p); v = eu->vu_p->v_p; NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } vu = s->vu_p; if (vu) { NMG_CK_VERTEXUSE(vu); v = vu->v_p; NMG_CK_VERTEX(v); if (!v->vg_p) break; VMOVE(mpt, v->vg_p->coord); break; } } default: VSETALL(mpt, 0.0); bu_vls_printf(gedp->ged_result_str, "get_solid_keypoint: unrecognized solid type"); return GED_ERROR; } MAT4X3PNT(pt, mat, mpt); return GED_OK; }
/** * R E C _ P R E P * * Given a pointer to a GED database record, and a transformation matrix, * determine if this is a valid REC, * and if so, precompute various terms of the formulas. * * Returns - * 0 REC is OK * !0 Error in description * * Implicit return - A struct rec_specific is created, and its * address is stored in stp->st_specific for use by rt_rec_shot(). If * the TGC is really an REC, stp->st_id is modified to ID_REC. */ int rt_rec_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip) { struct rt_tgc_internal *tip; struct rec_specific *rec; double magsq_h, magsq_a, magsq_b; double mag_h, mag_a, mag_b; mat_t R; mat_t Rinv; mat_t S; vect_t invsq; /* [ 1/(|A|**2), 1/(|B|**2), 1/(|Hv|**2) ] */ vect_t work; fastf_t f; if (!stp || !ip) return -1; RT_CK_SOLTAB(stp); RT_CK_DB_INTERNAL(ip); if (rtip) RT_CK_RTI(rtip); tip = (struct rt_tgc_internal *)ip->idb_ptr; RT_TGC_CK_MAGIC(tip); /* Validate that |H| > 0, compute |A| |B| |C| |D| */ mag_h = sqrt(magsq_h = MAGSQ(tip->h)); mag_a = sqrt(magsq_a = MAGSQ(tip->a)); mag_b = sqrt(magsq_b = MAGSQ(tip->b)); /* Check for |H| > 0, |A| > 0, |B| > 0 */ if (NEAR_ZERO(mag_h, RT_LEN_TOL) || NEAR_ZERO(mag_a, RT_LEN_TOL) || NEAR_ZERO(mag_b, RT_LEN_TOL)) { return 1; /* BAD, too small */ } /* Make sure that A == C, B == D */ VSUB2(work, tip->a, tip->c); f = MAGNITUDE(work); if (! NEAR_ZERO(f, RT_LEN_TOL)) { return 1; /* BAD, !cylinder */ } VSUB2(work, tip->b, tip->d); f = MAGNITUDE(work); if (! NEAR_ZERO(f, RT_LEN_TOL)) { return 1; /* BAD, !cylinder */ } /* Check for A.B == 0, H.A == 0 and H.B == 0 */ f = VDOT(tip->a, tip->b) / (mag_a * mag_b); if (! NEAR_ZERO(f, RT_DOT_TOL)) { return 1; /* BAD */ } f = VDOT(tip->h, tip->a) / (mag_h * mag_a); if (! NEAR_ZERO(f, RT_DOT_TOL)) { return 1; /* BAD */ } f = VDOT(tip->h, tip->b) / (mag_h * mag_b); if (! NEAR_ZERO(f, RT_DOT_TOL)) { return 1; /* BAD */ } /* * This TGC is really an REC */ stp->st_id = ID_REC; /* "fix" soltab ID */ stp->st_meth = &rt_functab[ID_REC]; BU_GET(rec, struct rec_specific); stp->st_specific = (genptr_t)rec; VMOVE(rec->rec_Hunit, tip->h); VUNITIZE(rec->rec_Hunit); VMOVE(rec->rec_V, tip->v); VMOVE(rec->rec_A, tip->a); VMOVE(rec->rec_B, tip->b); rec->rec_iAsq = 1.0/magsq_a; rec->rec_iBsq = 1.0/magsq_b; VSET(invsq, 1.0/magsq_a, 1.0/magsq_b, 1.0/magsq_h); /* Compute R and Rinv matrices */ MAT_IDN(R); f = 1.0/mag_a; VSCALE(&R[0], tip->a, f); f = 1.0/mag_b; VSCALE(&R[4], tip->b, f); f = 1.0/mag_h; VSCALE(&R[8], tip->h, f); bn_mat_trn(Rinv, R); /* inv of rot mat is trn */ /* Compute S */ MAT_IDN(S); S[ 0] = sqrt(invsq[0]); S[ 5] = sqrt(invsq[1]); S[10] = sqrt(invsq[2]); /* Compute SoR and invRoS */ bn_mat_mul(rec->rec_SoR, S, R); bn_mat_mul(rec->rec_invRoS, Rinv, S); /* Compute bounding sphere and RPP */ { fastf_t dx, dy, dz; /* For bounding sphere */ if (stp->st_meth->ft_bbox(ip, &(stp->st_min), &(stp->st_max), &(rtip->rti_tol))) return 1; VSET(stp->st_center, (stp->st_max[X] + stp->st_min[X])/2, (stp->st_max[Y] + stp->st_min[Y])/2, (stp->st_max[Z] + stp->st_min[Z])/2); dx = (stp->st_max[X] - stp->st_min[X])/2; f = dx; dy = (stp->st_max[Y] - stp->st_min[Y])/2; if (dy > f) f = dy; dz = (stp->st_max[Z] - stp->st_min[Z])/2; if (dz > f) f = dz; stp->st_aradius = f; stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz); } return 0; /* OK */ }
/** * R E C _ B B O X * * Calculate the RPP for an REC */ int rt_rec_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) { mat_t R; vect_t P, w1; fastf_t f, tmp, z; double magsq_h, magsq_a, magsq_b, magsq_c, magsq_d; double mag_h, mag_a, mag_b; struct rt_tgc_internal *tip; RT_CK_DB_INTERNAL(ip); tip = (struct rt_tgc_internal *)ip->idb_ptr; RT_TGC_CK_MAGIC(tip); mag_h = sqrt(magsq_h = MAGSQ(tip->h)); mag_a = sqrt(magsq_a = MAGSQ(tip->a)); mag_b = sqrt(magsq_b = MAGSQ(tip->b)); magsq_c = MAGSQ(tip->c); magsq_d = MAGSQ(tip->d); MAT_IDN(R); f = 1.0/mag_a; VSCALE(&R[0], tip->a, f); f = 1.0/mag_b; VSCALE(&R[4], tip->b, f); f = 1.0/mag_h; VSCALE(&R[8], tip->h, f); /* X */ VSET(P, 1.0, 0, 0); /* bounding plane normal */ MAT3X3VEC(w1, R, P); /* map plane into local coord syst */ /* 1st end ellipse (no Z part) */ tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; (*min)[X] = tip->v[X] - f; /* V.P +/- f */ (*max)[X] = tip->v[X] + f; /* 2nd end ellipse */ z = w1[Z] * mag_h; /* Z part */ tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; if (tip->v[X] - f + z < (*min)[X]) (*min)[X] = tip->v[X] - f + z; if (tip->v[X] + f + z > (*max)[X]) (*max)[X] = tip->v[X] + f + z; /* Y */ VSET(P, 0, 1.0, 0); /* bounding plane normal */ MAT3X3VEC(w1, R, P); /* map plane into local coord syst */ /* 1st end ellipse (no Z part) */ tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; (*min)[Y] = tip->v[Y] - f; /* V.P +/- f */ (*max)[Y] = tip->v[Y] + f; /* 2nd end ellipse */ z = w1[Z] * mag_h; /* Z part */ tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; if (tip->v[Y] - f + z < (*min)[Y]) (*min)[Y] = tip->v[Y] - f + z; if (tip->v[Y] + f + z > (*max)[Y]) (*max)[Y] = tip->v[Y] + f + z; /* Z */ VSET(P, 0, 0, 1.0); /* bounding plane normal */ MAT3X3VEC(w1, R, P); /* map plane into local coord syst */ /* 1st end ellipse (no Z part) */ tmp = magsq_a * w1[X] * w1[X] + magsq_b * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; (*min)[Z] = tip->v[Z] - f; /* V.P +/- f */ (*max)[Z] = tip->v[Z] + f; /* 2nd end ellipse */ z = w1[Z] * mag_h; /* Z part */ tmp = magsq_c * w1[X] * w1[X] + magsq_d * w1[Y] * w1[Y]; if (tmp > SMALL) f = sqrt(tmp); /* XY part */ else f = 0; if (tip->v[Z] - f + z < (*min)[Z]) (*min)[Z] = tip->v[Z] - f + z; if (tip->v[Z] + f + z > (*max)[Z]) (*max)[Z] = tip->v[Z] + f + z; return 0; }
/* * This routine is called (at prep time) * once for each region which uses this shader. * Any shader-specific initialization should be done here. * * Returns: * 1 success * 0 success, but delete region * -1 failure */ HIDDEN int bbd_setup(struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) { register struct bbd_specific *bbd_sp; struct rt_db_internal intern; struct rt_tgc_internal *tgc; int s; mat_t mat; struct bbd_img *bi; double angle; vect_t vtmp; int img_num; vect_t vv; /* check the arguments */ RT_CHECK_RTI(rtip); BU_CK_VLS(matparm); RT_CK_REGION(rp); if (rdebug&RDEBUG_SHADE) bu_log("bbd_setup(%s)\n", rp->reg_name); RT_CK_TREE(rp->reg_treetop); if (rp->reg_treetop->tr_a.tu_op != OP_SOLID) { bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name); bu_bomb("Shader should be used on region of single (rec/rcc) primitive\n"); } RT_CK_SOLTAB(rp->reg_treetop->tr_a.tu_stp); if (rp->reg_treetop->tr_a.tu_stp->st_id != ID_REC) { bu_log("--- Warning: Region %s shader %s", rp->reg_name, mfp->mf_name); bu_log("Shader should be used on region of single REC/RCC primitive %d\n", rp->reg_treetop->tr_a.tu_stp->st_id); bu_bomb("oops\n"); } /* Get memory for the shader parameters and shader-specific data */ BU_GET(bbd_sp, struct bbd_specific); *dpp = bbd_sp; /* initialize the default values for the shader */ memcpy(bbd_sp, &bbd_defaults, sizeof(struct bbd_specific)); bu_vls_init(&bbd_sp->img_filename); BU_LIST_INIT(&bbd_sp->imgs); bbd_sp->rtip = rtip; /* because new_image() needs this */ bbd_sp->img_count = 0; /* parse the user's arguments for this use of the shader. */ if (bu_struct_parse(matparm, bbd_parse_tab, (char *)bbd_sp, NULL) < 0) return -1; if (bbd_sp->img_count > MAX_IMAGES) { bu_log("too many images (%zu) in shader for %s sb < %d\n", bbd_sp->img_count, rp->reg_name, MAX_IMAGES); bu_bomb("excessive image count\n"); } MAT_IDN(mat); RT_DB_INTERNAL_INIT(&intern); s = rt_db_get_internal(&intern, rp->reg_treetop->tr_a.tu_stp->st_dp, rtip->rti_dbip, mat, &rt_uniresource); if (intern.idb_minor_type != ID_TGC && intern.idb_minor_type != ID_REC) { bu_log("What did I get? %d\n", intern.idb_minor_type); } if (s < 0) { bu_log("%s:%d didn't get internal", __FILE__, __LINE__); bu_bomb(""); } tgc = (struct rt_tgc_internal *)intern.idb_ptr; RT_TGC_CK_MAGIC(tgc); angle = M_PI / (double)bbd_sp->img_count; img_num = 0; VMOVE(vv, tgc->h); VUNITIZE(vv); for (BU_LIST_FOR(bi, bbd_img, &bbd_sp->imgs)) { static const point_t o = VINIT_ZERO; bn_mat_arb_rot(mat, o, vv, angle*img_num); /* compute plane equation */ MAT4X3VEC(bi->img_plane, mat, tgc->a); VUNITIZE(bi->img_plane); bi->img_plane[H] = VDOT(tgc->v, bi->img_plane); MAT4X3VEC(vtmp, mat, tgc->b); VADD2(bi->img_origin, tgc->v, vtmp); /* image origin in 3d space */ /* calculate image u vector */ VREVERSE(bi->img_x, vtmp); VUNITIZE(bi->img_x); bi->img_xlen = MAGNITUDE(vtmp) * 2; /* calculate image v vector */ VMOVE(bi->img_y, tgc->h); VUNITIZE(bi->img_y); bi->img_ylen = MAGNITUDE(tgc->h); if (rdebug&RDEBUG_SHADE) { HPRINT("\nimg_plane", bi->img_plane); VPRINT("vtmp", vtmp); VPRINT("img_origin", bi->img_origin); bu_log("img_xlen:%g ", bi->img_xlen); VPRINT("img_x", bi->img_x); bu_log("img_ylen:%g ", bi->img_ylen); VPRINT("img_y", bi->img_y); } img_num++; } rt_db_free_internal(&intern); if (rdebug&RDEBUG_SHADE) { bu_struct_print(" Parameters:", bbd_print_tab, (char *)bbd_sp); } return 1; }
int _ged_translate_tgc(struct ged *gedp, struct rt_tgc_internal *tgc, const char *attribute, vect_t tvec, int rflag) { fastf_t la, lb, lc, ld; vect_t hvec; RT_TGC_CK_MAGIC(tgc); VSCALE(tvec, tvec, gedp->ged_wdbp->dbip->dbi_local2base); switch (attribute[0]) { case 'h': case 'H': switch (attribute[1]) { case '\0': if (rflag) { VADD2(hvec, tgc->h, tvec); } else { VSUB2(hvec, tvec, tgc->v); } /* check for zero H vector */ if (MAGNITUDE(hvec) <= SQRT_SMALL_FASTF) { bu_vls_printf(gedp->ged_result_str, "Zero H vector not allowed."); return GED_ERROR; } VMOVE(tgc->h, hvec); break; case 'r': case 'R': if (attribute[2] != '\0') { bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } if (rflag) { VADD2(hvec, tgc->h, tvec); } else { VSUB2(hvec, tvec, tgc->v); } /* check for zero H vector */ if (MAGNITUDE(hvec) <= SQRT_SMALL_FASTF) { bu_vls_printf(gedp->ged_result_str, "Zero H vector not allowed."); return GED_ERROR; } VMOVE(tgc->h, hvec); /* have new height vector -- redefine rest of tgc */ la = MAGNITUDE(tgc->a); lb = MAGNITUDE(tgc->b); lc = MAGNITUDE(tgc->c); ld = MAGNITUDE(tgc->d); /* find 2 perpendicular vectors normal to H for new A, B */ VCROSS(tgc->b, tgc->h, tgc->a); VCROSS(tgc->a, tgc->b, tgc->h); VUNITIZE(tgc->a); VUNITIZE(tgc->b); /* Create new C, D from unit length A, B, with previous len */ VSCALE(tgc->c, tgc->a, lc); VSCALE(tgc->d, tgc->b, ld); /* Restore original vector lengths to A, B */ VSCALE(tgc->a, tgc->a, la); VSCALE(tgc->b, tgc->b, lb); break; default: bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } break; default: bu_vls_printf(gedp->ged_result_str, "bad tgc attribute - %s", attribute); return GED_ERROR; } return GED_OK; }