/** * Compute a perspective matrix for a right-handed coordinate system. * Reference: SGI Graphics Reference Appendix C * * (Note: SGI is left-handed, but the fix is done in the Display * Manager). */ void ged_persp_mat(mat_t m, fastf_t fovy, fastf_t aspect, fastf_t near1, fastf_t far1, fastf_t backoff) { mat_t m2, tran; fovy *= DEG2RAD; MAT_IDN(m2); m2[5] = cos(fovy/2.0) / sin(fovy/2.0); m2[0] = m2[5]/aspect; m2[10] = (far1+near1) / (far1-near1); m2[11] = 2*far1*near1 / (far1-near1); /* This should be negative */ m2[14] = -1; /* XXX This should be positive */ m2[15] = 0; /* Move eye to origin, then apply perspective */ MAT_IDN(tran); tran[11] = -backoff; bn_mat_mul(m, m2, tran); }
void bn_wrt_point_direc(mat_t out, const mat_t change, const mat_t in, const point_t point, const vect_t direc, const struct bn_tol *tol) { static mat_t t1; static mat_t pt_to_origin, origin_to_pt; static mat_t d_to_zaxis, zaxis_to_d; static vect_t zaxis; /* build "point to origin" matrix */ MAT_IDN(pt_to_origin); MAT_DELTAS_VEC_NEG(pt_to_origin, point); /* build "origin to point" matrix */ MAT_IDN(origin_to_pt); MAT_DELTAS_VEC_NEG(origin_to_pt, point); /* build "direc to zaxis" matrix */ VSET(zaxis, 0.0, 0.0, 1.0); bn_mat_fromto(d_to_zaxis, direc, zaxis, tol); /* build "zaxis to direc" matrix */ bn_mat_inv(zaxis_to_d, d_to_zaxis); /* apply change matrix... * t1 = change * d_to_zaxis * pt_to_origin * in */ bn_mat_mul4(t1, change, d_to_zaxis, pt_to_origin, in); /* apply origin_to_pt matrix: * out = origin_to_pt * zaxis_to_d * * change * d_to_zaxis * pt_to_origin * in */ bn_mat_mul3(out, origin_to_pt, zaxis_to_d, t1); }
void bn_mat_arb_rot( mat_t m, const point_t pt, const vect_t dir, const fastf_t ang) { mat_t tran1, tran2, rot; double cos_ang, sin_ang, one_m_cosang; double n1_sq, n2_sq, n3_sq; double n1_n2, n1_n3, n2_n3; if (ZERO(ang)) { MAT_IDN(m); return; } MAT_IDN(tran1); MAT_IDN(tran2); /* construct translation matrix to pt */ tran1[MDX] = (-pt[X]); tran1[MDY] = (-pt[Y]); tran1[MDZ] = (-pt[Z]); /* construct translation back from pt */ tran2[MDX] = pt[X]; tran2[MDY] = pt[Y]; tran2[MDZ] = pt[Z]; /* construct rotation matrix */ cos_ang = cos(ang); sin_ang = sin(ang); one_m_cosang = 1.0 - cos_ang; n1_sq = dir[X] * dir[X]; n2_sq = dir[Y] * dir[Y]; n3_sq = dir[Z] * dir[Z]; n1_n2 = dir[X] * dir[Y]; n1_n3 = dir[X] * dir[Z]; n2_n3 = dir[Y] * dir[Z]; MAT_IDN(rot); rot[0] = n1_sq + (1.0 - n1_sq) * cos_ang; rot[1] = n1_n2 * one_m_cosang - dir[Z] * sin_ang; rot[2] = n1_n3 * one_m_cosang + dir[Y] * sin_ang; rot[4] = n1_n2 * one_m_cosang + dir[Z] * sin_ang; rot[5] = n2_sq + (1.0 - n2_sq) * cos_ang; rot[6] = n2_n3 * one_m_cosang - dir[X] * sin_ang; rot[8] = n1_n3 * one_m_cosang - dir[Y] * sin_ang; rot[9] = n2_n3 * one_m_cosang + dir[X] * sin_ang; rot[10] = n3_sq + (1.0 - n3_sq) * cos_ang; bn_mat_mul(m, rot, tran1); bn_mat_mul2(tran2, m); }
/** * Create a perspective matrix that transforms the +/1 viewing cube, * with the actual eye position (not at Z=+1) specified in viewing * coords, into a related space where the eye has been sheared onto * the Z axis and repositioned at Z=(0, 0, 1), with the same * perspective field of view as before. * * The Zbuffer clips off stuff with negative Z values. * * pmat = persp * xlate * shear */ void ged_mike_persp_mat(mat_t pmat, const point_t eye) { mat_t shear; mat_t persp; mat_t xlate; mat_t t1, t2; point_t sheared_eye; if (eye[Z] <= SMALL) { VPRINT("mike_persp_mat(): ERROR, z<0, eye", eye); return; } /* Shear "eye" to +Z axis */ MAT_IDN(shear); shear[2] = -eye[X]/eye[Z]; shear[6] = -eye[Y]/eye[Z]; MAT4X3VEC(sheared_eye, shear, eye); if (!NEAR_ZERO(sheared_eye[X], .01) || !NEAR_ZERO(sheared_eye[Y], .01)) { VPRINT("ERROR sheared_eye", sheared_eye); return; } /* Translate along +Z axis to put sheared_eye at (0, 0, 1). */ MAT_IDN(xlate); /* XXX should I use MAT_DELTAS_VEC_NEG()? X and Y should be 0 now */ MAT_DELTAS(xlate, 0, 0, 1-sheared_eye[Z]); /* Build perspective matrix inline, substituting fov=2*atan(1, Z) */ MAT_IDN(persp); /* From page 492 of Graphics Gems */ persp[0] = sheared_eye[Z]; /* scaling: fov aspect term */ persp[5] = sheared_eye[Z]; /* scaling: determines fov */ /* From page 158 of Rogers Mathematical Elements */ /* Z center of projection at Z=+1, r=-1/1 */ persp[14] = -1; bn_mat_mul(t1, xlate, shear); bn_mat_mul(t2, persp, t1); /* Now, move eye from Z=1 to Z=0, for clipping purposes */ MAT_DELTAS(xlate, 0, 0, -1); bn_mat_mul(pmat, xlate, t2); }
int BrepHandler::extractCircularArc(const DirectoryEntry* de, const ParameterData& params) { point_t center, start, end; double offset_z = params.getReal(1); center[X] = params.getReal(2); center[Y] = params.getReal(3); center[Z] = offset_z; start[X] = params.getReal(4); start[Y] = params.getReal(5); start[Z] = offset_z; end[X] = params.getReal(6); end[Y] = params.getReal(7); end[Z] = offset_z; mat_t xform; MAT_IDN(xform); _iges->getTransformation(de->xform(), xform); // choose the circle/interval representation // so, calculate the circle params, and then the angle the arc subtends double dx = start[X] - center[X]; double dy = start[Y] - center[Y]; double radius = sqrt(dx*dx + dy*dy); point_t tcenter, tstart, tend; MAT4X3PNT(tcenter, xform, center); MAT4X3PNT(tstart, xform, start); MAT4X3PNT(tend, xform, end); vect_t normal = {0,0,1}; vect_t tnormal; MAT4X3VEC(tnormal, xform, normal); return handleCircularArc(radius, tcenter, tnormal, tstart, tend); }
/** * B N _ M A T _ A N G L E S * * This routine builds a Homogeneous rotation matrix, given * alpha, beta, and gamma as angles of rotation, in degrees. * * Alpha is angle of rotation about the X axis, and is done third. * Beta is angle of rotation about the Y axis, and is done second. * Gamma is angle of rotation about Z axis, and is done first. */ void bn_mat_angles(register fastf_t *mat, double alpha_in, double beta_in, double ggamma_in) { double alpha, beta, ggamma; double calpha, cbeta, cgamma; double salpha, sbeta, sgamma; if ( alpha_in == 0.0 && beta_in == 0.0 && ggamma_in == 0.0 ) { MAT_IDN( mat ); return; } alpha = alpha_in * bn_degtorad; beta = beta_in * bn_degtorad; ggamma = ggamma_in * bn_degtorad; calpha = cos( alpha ); cbeta = cos( beta ); cgamma = cos( ggamma ); /* sine of "180*bn_degtorad" will not be exactly zero * and will result in errors when some codes try to * convert this back to azimuth and elevation. * do_frame() uses this technique!!! */ if ( alpha_in == 180.0 ) salpha = 0.0; else salpha = sin( alpha ); if ( beta_in == 180.0 ) sbeta = 0.0; else sbeta = sin( beta ); if ( ggamma_in == 180.0 ) sgamma = 0.0; else sgamma = sin( ggamma ); mat[0] = cbeta * cgamma; mat[1] = -cbeta * sgamma; mat[2] = sbeta; mat[3] = 0.0; mat[4] = salpha * sbeta * cgamma + calpha * sgamma; mat[5] = -salpha * sbeta * sgamma + calpha * cgamma; mat[6] = -salpha * cbeta; mat[7] = 0.0; mat[8] = salpha * sgamma - calpha * sbeta * cgamma; mat[9] = salpha * cgamma + calpha * sbeta * sgamma; mat[10] = calpha * cbeta; mat[11] = 0.0; mat[12] = mat[13] = mat[14] = 0.0; mat[15] = 1.0; }
void bn_mat_lookat(mat_t rot, const vect_t dir, int yflip) { mat_t first; mat_t second; mat_t prod12; mat_t third; vect_t x; vect_t z; vect_t t1; fastf_t hypot_xy; vect_t xproj; vect_t zproj; /* First, rotate D around Z axis to match +X axis (azimuth) */ hypot_xy = hypot(dir[X], dir[Y]); bn_mat_zrot(first, -dir[Y] / hypot_xy, dir[X] / hypot_xy); /* Next, rotate D around Y axis to match -Z axis (elevation) */ bn_mat_yrot(second, -hypot_xy, -dir[Z]); bn_mat_mul(prod12, second, first); /* Produce twist correction, by re-orienting projection of X axis */ VSET(x, 1, 0, 0); MAT4X3VEC(xproj, prod12, x); hypot_xy = hypot(xproj[X], xproj[Y]); if (hypot_xy < 1.0e-10) { bu_log("Warning: bn_mat_lookat: unable to twist correct, hypot=%g\n", hypot_xy); VPRINT("xproj", xproj); MAT_COPY(rot, prod12); return; } bn_mat_zrot(third, -xproj[Y] / hypot_xy, xproj[X] / hypot_xy); bn_mat_mul(rot, third, prod12); if (yflip) { VSET(z, 0, 0, 1); MAT4X3VEC(zproj, rot, z); /* If original Z inverts sign, flip sign on resulting Y */ if (zproj[Y] < 0.0) { MAT_COPY(prod12, rot); MAT_IDN(third); third[5] = -1; bn_mat_mul(rot, third, prod12); } } /* Check the final results */ MAT4X3VEC(t1, rot, dir); if (t1[Z] > -0.98) { bu_log("Error: bn_mat_lookat final= (%g, %g, %g)\n", V3ARGS(t1)); } }
/** * R T _ D S P _ M I R R O R * * Given a pointer to an internal GED database object, mirror the * object's values about the given transformation matrix. */ int rt_dsp_mirror(struct rt_db_internal *ip, register const plane_t plane) { struct rt_dsp_internal *dsp; mat_t mirmat; mat_t rmat; mat_t temp; vect_t nvec; vect_t xvec; vect_t mirror_dir; point_t mirror_pt; fastf_t ang; static point_t origin = {0.0, 0.0, 0.0}; RT_CK_DB_INTERNAL(ip); dsp = (struct rt_dsp_internal *)ip->idb_ptr; RT_EBM_CK_MAGIC(dsp); MAT_IDN(mirmat); VMOVE(mirror_dir, plane); VSCALE(mirror_pt, plane, plane[W]); /* Build mirror transform matrix, for those who need it. */ /* First, perform a mirror down the X axis */ mirmat[0] = -1.0; /* Create the rotation matrix */ VSET(xvec, 1, 0, 0); VCROSS(nvec, xvec, mirror_dir); VUNITIZE(nvec); ang = -acos(VDOT(xvec, mirror_dir)); bn_mat_arb_rot(rmat, origin, nvec, ang*2.0); /* Add the rotation to mirmat */ MAT_COPY(temp, mirmat); bn_mat_mul(mirmat, temp, rmat); /* Add the translation to mirmat */ mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X]; mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y]; mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z]; bn_mat_mul(temp, mirmat, dsp->dsp_mtos); MAT_COPY(dsp->dsp_mtos, temp); return 0; }
int bn_decode_mat(fastf_t *m, const char *str) { if ( strcmp( str, "I" ) == 0 ) { MAT_IDN( m ); return 16; } if ( *str == '{' ) str++; return sscanf(str, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &m[0], &m[1], &m[2], &m[3], &m[4], &m[5], &m[6], &m[7], &m[8], &m[9], &m[10], &m[11], &m[12], &m[13], &m[14], &m[15]); }
void bn_mat_xform_about_pt(mat_t mat, const mat_t xform, const point_t pt) { mat_t xlate; mat_t tmp; MAT_IDN(xlate); MAT_DELTAS_VEC_NEG(xlate, pt); bn_mat_mul(tmp, xform, xlate); MAT_DELTAS_VEC(xlate, pt); bn_mat_mul(mat, xlate, tmp); }
int bn_mat_scale_about_pt(mat_t mat, const point_t pt, const double scale) { mat_t xlate; mat_t s; mat_t tmp; MAT_IDN(xlate); MAT_DELTAS_VEC_NEG(xlate, pt); MAT_IDN(s); if (ZERO(scale)) { MAT_ZERO(mat); return -1; /* ERROR */ } s[15] = 1 / scale; bn_mat_mul(tmp, s, xlate); MAT_DELTAS_VEC(xlate, pt); bn_mat_mul(mat, xlate, tmp); return 0; /* OK */ }
void do_tree(char *name, char *lname, int level) { int i; char nm[64]; char *leafp; int scale; struct wmember head; struct wmember *wp; BU_LIST_INIT(&head.l); if (level <= 1) leafp = lname; else leafp = nm; scale = 100; for (i=1; i<level; i++) scale *= 2; snprintf(nm, 64, "%sL", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_IDN(wp->wm_mat); snprintf(nm, 64, "%sR", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_DELTAS(wp->wm_mat, 1*scale, 0, 0); snprintf(nm, 64, "%sB", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_DELTAS(wp->wm_mat, 0.5*scale, sin60*scale, 0); snprintf(nm, 64, "%sT", name); wp = mk_addmember(leafp, &head.l, NULL, WMOP_UNION); MAT_DELTAS(wp->wm_mat, 0.5*scale, sin60/3*scale, sin60*scale); /* Set region flag on lowest level */ mk_lcomb(outfp, name, &head, level<=1, NULL, NULL, NULL, 0); /* Loop for children if level > 1 */ if (level <= 1) return; for (i=0; i<4; i++) { snprintf(nm, 64, "%s%c", name, "LRBTx"[i]); do_tree(nm, lname, level-1); } }
int main(int argc, char** argv) { struct rt_wdb* outfp; ON_Brep* brep; ON_TextLog error_log; const char* id_name = "B-Rep Example"; const char* geom_name = "cube.s"; ON::Begin(); if (argc > 1) { printf("Writing a twisted cube b-rep...\n"); outfp = wdb_fopen("brep_cube1.g"); mk_id(outfp, id_name); brep = MakeTwistedCube(error_log); mk_brep(outfp, geom_name, brep); //mk_comb1(outfp, "cube.r", geom_name, 1); unsigned char rgb[] = {255,255,255}; mk_region1(outfp, "cube.r", geom_name, "plastic", "", rgb); wdb_close(outfp); delete brep; } printf("Reading a twisted cube b-rep...\n"); struct db_i* dbip = db_open("brep_cube1.g", "r"); db_dirbuild(dbip); struct directory* dirp; if ((dirp = db_lookup(dbip, "cube.s", 0)) != DIR_NULL) { printf("\tfound cube.s\n"); struct rt_db_internal ip; mat_t mat; MAT_IDN(mat); if (rt_db_get_internal(&ip, dirp, dbip, mat, &rt_uniresource) >= 0) { printPoints((struct rt_brep_internal*)ip.idb_ptr); } else { fprintf(stderr, "problem getting internal object rep\n"); } } db_close(dbip); ON::End(); return 0; }
void do_light(char *name, fastf_t *pos, fastf_t *dir_at, int da_flag, double r, unsigned char *rgb, struct wmember *headp) /* direction or aim point */ /* 0 = direction, !0 = aim point */ /* radius of light */ { char nbuf[64]; vect_t center; mat_t rot; mat_t xlate; mat_t both; vect_t from; vect_t dir; if ( da_flag ) { VSUB2( dir, dir_at, pos ); VUNITIZE( dir ); } else { VMOVE( dir, dir_at ); } snprintf( nbuf, 64, "%s.s", name ); VSETALL( center, 0 ); mk_sph( outfp, nbuf, center, r ); /* * Need to rotate from 0, 0, -1 to vect "dir", * then xlate to final position. */ VSET( from, 0, 0, -1 ); bn_mat_fromto( rot, from, dir ); MAT_IDN( xlate ); MAT_DELTAS_VEC( xlate, pos); bn_mat_mul( both, xlate, rot ); mk_region1( outfp, name, nbuf, "light", "shadows=1", rgb ); (void)mk_addmember( name, &(headp->l), NULL, WMOP_UNION ); }
void bn_mat_angles_rad( register mat_t mat, double alpha, double beta, double ggamma) { double calpha, cbeta, cgamma; double salpha, sbeta, sgamma; if (ZERO(alpha) && ZERO(beta) && ZERO(ggamma)) { MAT_IDN(mat); return; } calpha = cos(alpha); cbeta = cos(beta); cgamma = cos(ggamma); salpha = sin(alpha); sbeta = sin(beta); sgamma = sin(ggamma); mat[0] = cbeta * cgamma; mat[1] = -cbeta * sgamma; mat[2] = sbeta; mat[3] = 0.0; mat[4] = salpha * sbeta * cgamma + calpha * sgamma; mat[5] = -salpha * sbeta * sgamma + calpha * cgamma; mat[6] = -salpha * cbeta; mat[7] = 0.0; mat[8] = salpha * sgamma - calpha * sbeta * cgamma; mat[9] = salpha * cgamma + calpha * sbeta * sgamma; mat[10] = calpha * cbeta; mat[11] = 0.0; mat[12] = mat[13] = mat[14] = 0.0; mat[15] = 1.0; }
HIDDEN int scloud_setup(register struct region *rp, struct bu_vls *matparm, void **dpp, const struct mfuncs *mfp, struct rt_i *rtip) /* pointer to reg_udata in *rp */ { register struct scloud_specific *scloud; struct db_full_path full_path; mat_t region_to_model; mat_t model_to_region; mat_t tmp; BU_CK_VLS(matparm); BU_GET(scloud, struct scloud_specific); *dpp = scloud; if (rp->reg_aircode == 0) { bu_log("WARNING(%s): air shader '%s' applied to non-air region.\n%s\n", rp->reg_name, mfp->mf_name, " Set air flag with \"edcodes\" in mged"); bu_bomb(""); } memcpy(scloud, &scloud_defaults, sizeof(struct scloud_specific)); if (rdebug&RDEBUG_SHADE) bu_log("scloud_setup\n"); if (bu_struct_parse(matparm, scloud_parse, (char *)scloud) < 0) return -1; if (rdebug&RDEBUG_SHADE) (void)bu_struct_print(rp->reg_name, scloud_parse, (char *)scloud); /* get transformation between world and "region" coordinates */ if (db_string_to_path(&full_path, rtip->rti_dbip, rp->reg_name)) { /* bad thing */ bu_bomb("db_string_to_path() error"); } if (! db_path_to_mat(rtip->rti_dbip, &full_path, region_to_model, 0, &rt_uniresource)) { /* bad thing */ bu_bomb("db_path_to_mat() error"); } /* get matrix to map points from model space to "region" space */ bn_mat_inv(model_to_region, region_to_model); /* add the noise-space scaling */ MAT_IDN(tmp); if (!EQUAL(scloud->scale, 1.0)) { tmp[0] = tmp[5] = tmp[10] = 1.0 / scloud->scale; } else { tmp[0] = 1.0 / (scloud->vscale[0]); tmp[5] = 1.0 / (scloud->vscale[1]); tmp[10] = 1.0 / (scloud->vscale[2]); } bn_mat_mul(scloud->mtos, tmp, model_to_region); /* add the translation within noise space */ MAT_IDN(tmp); tmp[MDX] = scloud->delta[0]; tmp[MDY] = scloud->delta[1]; tmp[MDZ] = scloud->delta[2]; bn_mat_mul2(tmp, scloud->mtos); bn_mat_inv(scloud->stom, scloud->mtos); return 1; }
/* * T P _ 3 S Y M B O L */ void tp_3symbol(FILE *fp, char *string, fastf_t *origin, fastf_t *rot, double scale) /* string of chars to be plotted */ /* lower left corner of 1st char */ /* Transform matrix (WARNING: may xlate) */ /* scale factor to change 1x1 char sz */ { register unsigned char *cp; double offset; /* offset of char from given x, y */ int ysign; /* sign of y motion, either +1 or -1 */ vect_t temp; vect_t loc; mat_t xlate_to_origin; mat_t mat; if ( string == NULL || *string == '\0' ) return; /* done before begun! */ /* * The point "origin" will be the center of the axis rotation. * The text is located in a local coordinate system with the * lower left corner of the first character at (0, 0, 0), with * the text proceeding onward towards +X. * We need to rotate the text around its local (0, 0, 0), * and then translate to the user's designated "origin". * If the user provided translation or * scaling in his matrix, it will *also* be applied. */ MAT_IDN( xlate_to_origin ); MAT_DELTAS_VEC( xlate_to_origin, origin ); bn_mat_mul( mat, xlate_to_origin, rot ); /* Check to see if initialization is needed */ if ( tp_cindex[040] == 0 ) tp_setup(); /* Draw each character in the input string */ offset = 0; for ( cp = (unsigned char *)string; *cp; cp++, offset += scale ) { register int *p; /* pointer to stroke table */ register int stroke; VSET( temp, offset, 0, 0 ); MAT4X3PNT( loc, mat, temp ); pdv_3move( fp, loc ); for ( p = tp_cindex[*cp]; (stroke= *p) != LAST; p++ ) { int draw; if ( stroke==NEGY ) { ysign = (-1); stroke = *++p; } else ysign = 1; /* Detect & process pen control */ if ( stroke < 0 ) { stroke = -stroke; draw = 0; } else draw = 1; /* stroke co-ordinates in string coord system */ VSET( temp, (stroke/11) * 0.1 * scale + offset, (ysign * (stroke%11)) * 0.1 * scale, 0 ); MAT4X3PNT( loc, mat, temp ); if ( draw ) pdv_3cont( fp, loc ); else pdv_3move( fp, loc ); } } }
int ged_copyeval(struct ged *gedp, int argc, const char *argv[]) { static const char *usage = "path_to_old_prim new_prim"; struct _ged_trace_data gtd; struct directory *dp; struct rt_db_internal *ip; struct rt_db_internal internal, new_int; char *tok; int endpos = 0; int i; mat_t start_mat; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } /* initialize gtd */ gtd.gtd_gedp = gedp; gtd.gtd_flag = _GED_CPEVAL; gtd.gtd_prflag = 0; /* check if new solid name already exists in description */ GED_CHECK_EXISTS(gedp, argv[2], LOOKUP_QUIET, GED_ERROR); MAT_IDN(start_mat); /* build directory pointer array for desired path */ if (strchr(argv[1], '/')) { tok = strtok((char *)argv[1], "/"); while (tok) { GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], tok, LOOKUP_NOISY, GED_ERROR & GED_QUIET); endpos++; tok = strtok((char *)NULL, "/"); } } else { GED_DB_LOOKUP(gedp, gtd.gtd_obj[endpos], argv[1], LOOKUP_NOISY, GED_ERROR & GED_QUIET); endpos++; } if (endpos < 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } gtd.gtd_objpos = endpos - 1; GED_DB_GET_INTERNAL(gedp, &internal, gtd.gtd_obj[endpos - 1], bn_mat_identity, &rt_uniresource, GED_ERROR); if (endpos > 1) { /* Make sure that final component in path is a solid */ if (internal.idb_type == ID_COMBINATION) { rt_db_free_internal(&internal); bu_vls_printf(gedp->ged_result_str, "final component on path must be a primitive!\n"); return GED_ERROR; } /* Accumulate the matrices */ ged_trace(gtd.gtd_obj[0], 0, start_mat, >d, 1); if (gtd.gtd_prflag == 0) { bu_vls_printf(gedp->ged_result_str, "PATH: "); for (i = 0; i < gtd.gtd_objpos; i++) bu_vls_printf(gedp->ged_result_str, "/%s", gtd.gtd_obj[i]->d_namep); bu_vls_printf(gedp->ged_result_str, " NOT FOUND\n"); rt_db_free_internal(&internal); return GED_ERROR; } /* Have found the desired path - wdb_xform is the transformation matrix */ /* wdb_xform matrix calculated in wdb_trace() */ /* create the new solid */ RT_DB_INTERNAL_INIT(&new_int); if (rt_generic_xform(&new_int, gtd.gtd_xform, &internal, 0, gedp->ged_wdbp->dbip, &rt_uniresource)) { rt_db_free_internal(&internal); bu_vls_printf(gedp->ged_result_str, "ged_copyeval: rt_generic_xform failed\n"); return GED_ERROR; } ip = &new_int; } else ip = &internal; /* should call GED_DB_DIRADD() but need to deal with freeing the * internals on failure. */ dp=db_diradd(gedp->ged_wdbp->dbip, argv[2], RT_DIR_PHONY_ADDR, 0, gtd.gtd_obj[endpos-1]->d_flags, (void *)&ip->idb_type); if (dp == RT_DIR_NULL) { rt_db_free_internal(&internal); if (ip == &new_int) rt_db_free_internal(&new_int); bu_vls_printf(gedp->ged_result_str, "An error has occurred while adding a new object to the database."); return GED_ERROR; } /* should call GED_DB_DIRADD() but need to deal with freeing the * internals on failure. */ if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, &rt_uniresource) < 0) { /* if (ip == &new_int) then new_int gets freed by the rt_db_put_internal above * regardless of whether it succeeds or not. At this point only internal needs * to be freed. On the other hand if (ip == &internal), the internal gets freed * freed by the rt_db_put_internal above. In this case memory for new_int has * not been allocated. */ if (ip == &new_int) rt_db_free_internal(&internal); bu_vls_printf(gedp->ged_result_str, "Database write error, aborting"); return GED_ERROR; } /* see previous comment */ if (ip == &new_int) rt_db_free_internal(&internal); return GED_OK; }
/* * P L O T _ O P E N * * Fire up the display manager, and the display processor. * */ struct dm * plot_open(Tcl_Interp *interp, int argc, const char *argv[]) { static int count = 0; struct dm *dmp; Tcl_Obj *obj; BU_ALLOC(dmp, struct dm); *dmp = dm_plot; /* struct copy */ dmp->dm_interp = interp; BU_ALLOC(dmp->dm_vars.priv_vars, struct plot_vars); obj = Tcl_GetObjResult(interp); if (Tcl_IsShared(obj)) obj = Tcl_DuplicateObj(obj); bu_vls_init(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls); bu_vls_init(&dmp->dm_pathName); bu_vls_init(&dmp->dm_tkName); bu_vls_printf(&dmp->dm_pathName, ".dm_plot%d", count++); bu_vls_printf(&dmp->dm_tkName, "dm_plot%d", count++); /* skip first argument */ --argc; ++argv; /* Process any options */ ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D = 1; /* 3-D w/color, by default */ while (argv[0] != (char *)0 && argv[0][0] == '-') { switch (argv[0][1]) { case '3': break; case '2': ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D = 0; /* 2-D, for portability */ break; case 'g': ((struct plot_vars *)dmp->dm_vars.priv_vars)->grid = 1; break; case 'f': ((struct plot_vars *)dmp->dm_vars.priv_vars)->floating = 1; break; case 'z': case 'Z': /* Enable Z clipping */ Tcl_AppendStringsToObj(obj, "Clipped in Z to viewing cube\n", (char *)NULL); dmp->dm_zclip = 1; break; default: Tcl_AppendStringsToObj(obj, "bad PLOT option ", argv[0], "\n", (char *)NULL); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } argv++; } if (argv[0] == (char *)0) { Tcl_AppendStringsToObj(obj, "no filename or filter specified\n", (char *)NULL); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } if (argv[0][0] == '|') { bu_vls_strcpy(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, &argv[0][1]); while ((++argv)[0] != (char *)0) { bu_vls_strcat(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, " "); bu_vls_strcat(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, argv[0]); } ((struct plot_vars *)dmp->dm_vars.priv_vars)->is_pipe = 1; } else { bu_vls_strcpy(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls, argv[0]); } if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_pipe) { if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp = popen(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "w")) == NULL) { perror(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls)); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } Tcl_AppendStringsToObj(obj, "piped to ", bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "\n", (char *)NULL); } else { if ((((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp = fopen(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "wb")) == NULL) { perror(bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls)); (void)plot_close(dmp); Tcl_SetObjResult(interp, obj); return DM_NULL; } Tcl_AppendStringsToObj(obj, "plot stored in ", bu_vls_addr(&((struct plot_vars *)dmp->dm_vars.priv_vars)->vls), "\n", (char *)NULL); } setbuf(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, ((struct plot_vars *)dmp->dm_vars.priv_vars)->ttybuf); if (((struct plot_vars *)dmp->dm_vars.priv_vars)->is_3D) pl_3space(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, -2048, -2048, -2048, 2048, 2048, 2048); else pl_space(((struct plot_vars *)dmp->dm_vars.priv_vars)->up_fp, -2048, -2048, 2048, 2048); MAT_IDN(plotmat); Tcl_SetObjResult(interp, obj); return dmp; }
int main(int argc, char **argv) { void anim_dir2mat(fastf_t *, const fastf_t *, const fastf_t *), anim_y_p_r2mat(fastf_t *, double, double, double), anim_add_trans(fastf_t *, const fastf_t *, const fastf_t *), anim_mat_print(FILE *, const fastf_t *, int); int get_args(int argc, char **argv), track_prep(void), val, frame, go, i, count; fastf_t y_rot, distance, yaw, pitch, roll; vect_t p1, p2, p3, dir, dir2, wheel_now, wheel_prev; vect_t zero, position, vdelta, temp, to_track, to_front; mat_t mat_v, wmat, mat_x; FILE *stream; int last_frame; VSETALL(zero, 0.0); VSETALL(to_track, 0.0); VSETALL(centroid, 0.0); VSETALL(rcentroid, 0.0); init_dist = y_rot = radius= 0.0; first_frame = num_wheels = steer = axes = cent = links_placed=0; num_wheels = num_links = last_frame = 0; MAT_IDN(mat_v); MAT_IDN(mat_x); MAT_IDN(wmat); MAT_IDN(m_axes); MAT_IDN(m_rev_axes); if (!get_args(argc, argv)) { fprintf(stderr, "anim_hardtrack: argument error."); return(-1); } if (axes || cent ) { /* vehicle has own reference frame */ anim_add_trans(m_axes, centroid, zero); anim_add_trans(m_rev_axes, zero, rcentroid); } /* get track information from specified file */ if (!(stream = fopen(*(argv+bu_optind), "rb"))) { fprintf(stderr, "Anim_hardtrack: Could not open file %s.\n", *(argv+bu_optind)); return(0); } num_wheels = -1; if (radius) { while (!feof(stream)) { fscanf(stream, "%*f %*f %*f"); num_wheels++; } } else { while (!feof(stream)) { fscanf(stream, "%*f %*f %*f %*f"); num_wheels++; } } rewind(stream); /*allocate memory for track information*/ x = (struct all *) bu_calloc(num_wheels, sizeof(struct all), "struct all"); /*read rest of track info */ for (i=0;i<NW;i++) { fscanf(stream, "%lf %lf %lf", temp, temp+1, temp+2); if (radius) x[i].w.rad = radius; else fscanf(stream, "%lf", & x[i].w.rad); MAT4X3PNT(x[i].w.pos, m_rev_axes, temp); if (i==0) track_y = x[0].w.pos[1]; else x[i].w.pos[1] = track_y; } (void) fclose(stream); (void) track_prep(); if (get_circumf) { printf("%.10g\n", tracklen); return(0); } /* initialize to_track */ VSET(to_track, 0.0, track_y, 0.0); VSET(to_front, 1.0, 0.0, 0.0); if ((!print_link)&&(!print_wheel)) { fprintf(stderr, "anim_hardtrack: no ouput requested. Use -l or -w.\n"); bu_exit(0, NULL); } /* main loop */ distance = 0.0; if (!steer) frame = first_frame; else frame = first_frame-1; for (val = 3; val > 2; frame++) { go = 1; /*p2 is current position. p3 is next;p1 is previous*/ VMOVE(p1, p2); VMOVE(p2, p3); scanf("%*f");/*time stamp*/ val = scanf("%lf %lf %lf", p3, p3+1, p3 + 2); if (!steer) { scanf("%lf %lf %lf", &yaw, &pitch, &roll); anim_dy_p_r2mat(mat_v, yaw, pitch, roll); anim_add_trans(mat_v, p3, rcentroid); } else { /* analyze positions for steering */ /*get useful direction unit vectors*/ if (frame == first_frame) { /* first frame*/ VSUBUNIT(dir, p3, p2); VMOVE(dir2, dir); } else if (val < 3) { /*last frame*/ VSUBUNIT(dir, p2, p1); VMOVE(dir2, dir); } else if (frame > first_frame) { /*normal*/ VSUBUNIT(dir, p3, p1); VSUBUNIT(dir2, p2, p1);/*needed for vertical case*/ } else go = 0;/*first time through loop;no p2*/ /*create matrix which would move vehicle*/ anim_dir2mat(mat_v, dir, dir2); anim_add_trans(mat_v, p2, rcentroid); } /*determine distance traveled*/ VMOVE(wheel_prev, wheel_now); MAT4X3PNT(wheel_now, mat_v, to_track); if (frame > first_frame) { /* increment distance by distance moved */ VSUB2(vdelta, wheel_now, wheel_prev); MAT3X3VEC(temp, mat_v, to_front);/*new front of vehicle*/ distance += VDOT(temp, vdelta);/*portion of vdelta in line with track*/ } if (go) { if (print_mode==TRACK_ANIM) { printf("start %d;\nclean;\n", frame); } else if (print_mode==TRACK_ARCED) { if (frame != arced_frame) continue; last_frame = 1; } if (print_link) { for (count=0;count<num_links;count++) { (void) get_link(position, &y_rot, distance+tracklen*count/num_links+init_dist); anim_y_p_r2mat(wmat, 0.0, y_rot+r[count].ang, 0.0); anim_add_trans(wmat, position, r[count].pos); if ((axes || cent) && links_placed) { /* link moved from vehicle coords */ bn_mat_mul(mat_x, wmat, m_rev_axes); bn_mat_mul(wmat, m_axes, mat_x); } else if (axes || cent) { /* link moved to vehicle coords */ MAT_MOVE(mat_x, wmat); bn_mat_mul(wmat, m_axes, mat_x); } if (print_mode==TRACK_ANIM) { printf("anim %s.%d matrix %s\n", *(argv+link_nindex), count, link_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "\n", ";\n"); } else if (print_mode==TRACK_ARCED) { printf("arced %s.%d matrix %s ", *(argv+link_nindex), count, link_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "", "\n"); } } } if (print_wheel) { for (count = 0;count<num_wheels;count++) { anim_y_p_r2mat(wmat, 0.0, -distance/x[count].w.rad, 0.0); VREVERSE(temp, x[count].w.pos); anim_add_trans(wmat, x[count].w.pos, temp); if (axes || cent) { bn_mat_mul(mat_x, wmat, m_rev_axes); bn_mat_mul(wmat, m_axes, mat_x); } if (print_mode==TRACK_ANIM) { printf("anim %s.%d matrix %s\n", *(argv+wheel_nindex), count, wheel_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "\n", ";\n"); } else if (print_mode==TRACK_ARCED) { printf("arced %s.%d matrix %s ", *(argv+wheel_nindex), count, wheel_cmd); anim_mat_printf(stdout, wmat, "%.10g ", "", "\n"); } } } if (print_mode==TRACK_ANIM) printf("end;\n"); } if (last_frame) break; } if (x) { bu_free(x, "struct all"); } if (r) { bu_free(r, "struct rlink"); } return( 0 ); }
/** * Given a pointer to an internal GED database object, mirror the * object's values about the given transformation matrix. */ int rt_ell_mirror(struct rt_db_internal *ip, register const plane_t plane) { struct rt_ell_internal *ell; mat_t mirmat; mat_t rmat; mat_t temp; vect_t nvec; vect_t xvec; vect_t mirror_dir; point_t mirror_pt; fastf_t ang; mat_t mat; point_t pt; vect_t a, b, c; vect_t n; static point_t origin = {0.0, 0.0, 0.0}; RT_CK_DB_INTERNAL(ip); ell = (struct rt_ell_internal *)ip->idb_ptr; RT_ELL_CK_MAGIC(ell); MAT_IDN(mirmat); VMOVE(mirror_dir, plane); VSCALE(mirror_pt, plane, plane[W]); /* Build mirror transform matrix, for those who need it. */ /* First, perform a mirror down the X axis */ mirmat[0] = -1.0; /* Create the rotation matrix */ VSET(xvec, 1, 0, 0); VCROSS(nvec, xvec, mirror_dir); VUNITIZE(nvec); ang = -acos(VDOT(xvec, mirror_dir)); bn_mat_arb_rot(rmat, origin, nvec, ang*2.0); /* Add the rotation to mirmat */ MAT_COPY(temp, mirmat); bn_mat_mul(mirmat, temp, rmat); /* Add the translation to mirmat */ mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X]; mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y]; mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z]; VMOVE(pt, ell->v); MAT4X3PNT(ell->v, mirmat, pt); VMOVE(a, ell->a); VUNITIZE(a); VCROSS(n, mirror_dir, ell->a); VUNITIZE(n); ang = M_PI_2 - acos(VDOT(a, mirror_dir)); bn_mat_arb_rot(mat, origin, n, ang*2); VMOVE(a, ell->a); MAT4X3VEC(ell->a, mat, a); VMOVE(b, ell->b); VUNITIZE(b); VCROSS(n, mirror_dir, ell->b); VUNITIZE(n); ang = M_PI_2 - acos(VDOT(b, mirror_dir)); bn_mat_arb_rot(mat, origin, n, ang*2); VMOVE(b, ell->b); MAT4X3VEC(ell->b, mat, b); VMOVE(c, ell->c); VUNITIZE(c); VCROSS(n, mirror_dir, ell->c); VUNITIZE(n); ang = M_PI_2 - acos(VDOT(c, mirror_dir)); bn_mat_arb_rot(mat, origin, n, ang*2); VMOVE(c, ell->c); MAT4X3VEC(ell->c, mat, c); return 0; }
int main(int argc, char **argv) { vect_t norm; unsigned char rgb[3]; int ix; double x; double size; int quant; struct wmember head; vect_t bmin, bmax, bthick; vect_t r1min, r1max, r1thick; vect_t lwh; /* length, width, height */ vect_t pbase; BU_LIST_INIT( &head.l ); MAT_IDN( identity ); sin60 = sin(60.0 * 3.14159265358979323846264 / 180.0); outfp = wdb_fopen("room.g"); mk_id( outfp, "Procedural Rooms" ); /* Create the building */ VSET( bmin, 0, 0, 0 ); VSET( bmax, 80000, 60000, HEIGHT ); VSET( bthick, 100, 100, 100 ); make_room( "bldg", bmin, bmax, bthick, &head ); /* Create the first room */ VSET( r1thick, 100, 100, 0 ); VMOVE( r1min, bmin ); VSET( r1max, 40000, 10000, HEIGHT ); VADD2( r1max, r1min, r1max ); make_walls( "rm1", r1min, r1max, r1thick, NORTH|EAST, &head ); make_carpet( "rm1carpet", r1min, r1max, "carpet.pix", &head ); /* Create the golden earth */ VSET( norm, 0, 0, 1 ); mk_half( outfp, "plane", norm, -bthick[Z]-10.0 ); rgb[0] = 240; /* gold/brown */ rgb[1] = 180; rgb[2] = 64; mk_region1( outfp, "plane.r", "plane", NULL, NULL, rgb ); (void)mk_addmember( "plane.r", &head.l, NULL, WMOP_UNION ); /* Create the display pillars */ size = 4000; /* separation between centers */ quant = 5; /* pairs */ VSET( lwh, 400, 400, 1000 ); for ( ix=quant-1; ix>=0; ix-- ) { x = 10000 + ix*size; VSET( pbase, x, 10000*.25, r1min[Z] ); make_pillar( "Pil", ix, 0, pbase, lwh, &head ); VSET( pbase, x, 10000*.75, r1min[Z] ); make_pillar( "Pil", ix, 1, pbase, lwh, &head ); } #ifdef never /* Create some light */ white[0] = white[1] = white[2] = 255; base = size*(quant/2+1); VSET( aim, 0, 0, 0 ); VSET( pos, base, base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l1", pos, aim, 1, 100.0, white, &head ); VSET( pos, -base, base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l2", pos, aim, 1, 100.0, white, &head ); VSET( pos, -base, -base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l3", pos, aim, 1, 100.0, white, &head ); VSET( pos, base, -base, minheight+maxheight*bn_rand0to1(randp) ); do_light( "l4", pos, aim, 1, 100.0, white, &head ); #endif /* Build the overall combination */ mk_lfcomb( outfp, "room", &head, 0 ); return 0; }
int rt_process_uplot_value(register struct bu_list **vhead, struct bn_vlblock *vbp, FILE *fp, register int c, double char_size, int mode) { mat_t mat; const struct uplot *up; #define CARG_LEN 256 #define ARG_LEN 6 char carg[CARG_LEN]; fastf_t arg[ARG_LEN]; vect_t a, b; point_t last_pos; static point_t lpnt; /* last point of a move/draw series */ static int moved = 0; /* moved since color change */ memset(carg, 0, sizeof(char)*CARG_LEN); memset(arg, 0, sizeof(fastf_t)*ARG_LEN); #undef ARG_LEN #undef CARG_LEN /* look it up */ if (c < 'A' || c > 'z') { up = &rt_uplot_error; } else { up = &rt_uplot_letters[ c - 'A' ]; } if (up->targ == TBAD) { fprintf(stderr, "Lee : Bad command '%c' (0x%02x)\n", c, c); return -1; } if (up->narg > 0) { if (mode == PL_OUTPUT_MODE_BINARY) rt_uplot_get_args(fp, up, carg, arg); else rt_uplot_get_text_args(fp, up, carg, arg); } switch (c) { case 's': case 'w': case 'S': case 'W': /* Space commands, do nothing. */ break; case 'm': case 'o': /* 2-D move */ arg[Z] = 0; BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE); VMOVE(lpnt, arg); moved = 1; break; case 'M': case 'O': /* 3-D move */ BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE); VMOVE(lpnt, arg); moved = 1; break; case 'n': case 'q': /* * If no move command was issued since the last color * change, insert one now using the last point from a * move/draw. */ if (!moved) { BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, lpnt, BN_VLIST_LINE_MOVE); moved = 1; } /* 2-D draw */ arg[Z] = 0; BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW); VMOVE(lpnt, arg); break; case 'N': case 'Q': /* * If no move command was issued since the last color * change, insert one now using the last point from a * move/draw. */ if (!moved) { BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, lpnt, BN_VLIST_LINE_MOVE); moved = 1; } /* 3-D draw */ BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW); VMOVE(lpnt, arg); break; case 'l': case 'v': /* 2-D line */ VSET(a, arg[0], arg[1], 0.0); VSET(b, arg[2], arg[3], 0.0); BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, a, BN_VLIST_LINE_MOVE); BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, b, BN_VLIST_LINE_DRAW); break; case 'L': case 'V': /* 3-D line */ VSET(a, arg[0], arg[1], arg[2]); VSET(b, arg[3], arg[4], arg[5]); BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, a, BN_VLIST_LINE_MOVE); BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, b, BN_VLIST_LINE_DRAW); break; case 'p': case 'x': /* 2-D point */ arg[Z] = 0; BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE); BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW); break; case 'P': case 'X': /* 3-D point */ BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_MOVE); BN_ADD_VLIST(vbp->free_vlist_hd, *vhead, arg, BN_VLIST_LINE_DRAW); break; case 'C': /* Color */ *vhead = rt_vlblock_find(vbp, carg[0], carg[1], carg[2]); moved = 0; break; case 't': /* Text string */ MAT_IDN(mat); if (BU_LIST_NON_EMPTY(*vhead)) { struct bn_vlist *vlp; /* Use coordinates of last op */ vlp = BU_LIST_LAST(bn_vlist, *vhead); VMOVE(last_pos, vlp->pt[vlp->nused-1]); } else { VSETALL(last_pos, 0); } bn_vlist_3string(*vhead, vbp->free_vlist_hd, carg, last_pos, mat, char_size); break; } return 0; }
int ged_otranslate(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct _ged_trace_data gtd; struct rt_db_internal intern; vect_t delta; double scan[3]; mat_t dmat; mat_t emat; mat_t tmpMat; mat_t invXform; point_t rpp_min; point_t rpp_max; static const char *usage = "obj dx dy dz"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_READ_ONLY(gedp, GED_ERROR); GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); /* initialize result */ bu_vls_trunc(gedp->ged_result_str, 0); /* must be wanting help */ if (argc == 1) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_HELP; } if (argc != 5) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (_ged_get_obj_bounds2(gedp, 1, argv+1, >d, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; dp = gtd.gtd_obj[gtd.gtd_objpos-1]; if (!(dp->d_flags & RT_DIR_SOLID)) { if (_ged_get_obj_bounds(gedp, 1, argv+1, 1, rpp_min, rpp_max) == GED_ERROR) return GED_ERROR; } if (sscanf(argv[2], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad x value - %s", argv[0], argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad y value - %s", argv[0], argv[3]); return GED_ERROR; } if (sscanf(argv[4], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad z value - %s", argv[0], argv[4]); return GED_ERROR; } MAT_IDN(dmat); VSCALE(delta, scan, gedp->ged_wdbp->dbip->dbi_local2base); MAT_DELTAS_VEC(dmat, delta); bn_mat_inv(invXform, gtd.gtd_xform); bn_mat_mul(tmpMat, invXform, dmat); bn_mat_mul(emat, tmpMat, gtd.gtd_xform); GED_DB_GET_INTERNAL(gedp, &intern, dp, emat, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); return GED_OK; }
/** * Given a pointer to an internal GED database object, mirror the * object's values about the given transformation matrix. */ int rt_half_mirror(struct rt_db_internal *ip, register const plane_t plane) { struct rt_half_internal *half; mat_t mirmat; mat_t rmat; mat_t temp; vect_t nvec; vect_t xvec; vect_t mirror_dir; point_t mirror_pt; fastf_t ang; vect_t n1; vect_t n2; static fastf_t tol_dist_sq = 0.0005 * 0.0005; static point_t origin = {0.0, 0.0, 0.0}; RT_CK_DB_INTERNAL(ip); half = (struct rt_half_internal *)ip->idb_ptr; RT_HALF_CK_MAGIC(half); MAT_IDN(mirmat); VMOVE(mirror_dir, plane); VSCALE(mirror_pt, plane, plane[W]); /* Build mirror transform matrix, for those who need it. */ /* First, perform a mirror down the X axis */ mirmat[0] = -1.0; /* Create the rotation matrix */ VSET(xvec, 1, 0, 0); VCROSS(nvec, xvec, mirror_dir); VUNITIZE(nvec); ang = -acos(VDOT(xvec, mirror_dir)); bn_mat_arb_rot(rmat, origin, nvec, ang*2.0); /* Add the rotation to mirmat */ MAT_COPY(temp, mirmat); bn_mat_mul(mirmat, temp, rmat); /* Add the translation to mirmat */ mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X]; mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y]; mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z]; /* FIXME: this is not using the mirmat we just computed, not clear * it's even right given it's only taking the mirror direction * into account and not the mirror point. */ VMOVE(n1, half->eqn); VCROSS(n2, mirror_dir, n1); VUNITIZE(n2); ang = M_PI_2 - acos(VDOT(n1, mirror_dir)); bn_mat_arb_rot(rmat, origin, n2, ang*2); MAT4X3VEC(half->eqn, rmat, n1); if (!NEAR_EQUAL(VDOT(n1, half->eqn), 1.0, tol_dist_sq)) { point_t ptA; point_t ptB; point_t ptC; vect_t h; fastf_t mag; fastf_t cosa; VSCALE(ptA, n1, half->eqn[H]); VADD2(ptB, ptA, mirror_dir); VSUB2(h, ptB, ptA); mag = MAGNITUDE(h); VUNITIZE(h); cosa = VDOT(h, mirror_dir); VSCALE(ptC, half->eqn, -mag * cosa); VADD2(ptC, ptC, ptA); half->eqn[H] = VDOT(half->eqn, ptC); } return 0; }
/** * Calculate a bounding RPP for a superell */ int rt_superell_bbox(struct rt_db_internal *ip, point_t *min, point_t *max, const struct bn_tol *UNUSED(tol)) { struct rt_superell_internal *eip; fastf_t magsq_a, magsq_b, magsq_c; vect_t Au, Bu, Cu; mat_t R; vect_t w1, w2, P; /* used for bounding RPP */ fastf_t f; eip = (struct rt_superell_internal *)ip->idb_ptr; RT_SUPERELL_CK_MAGIC(eip); magsq_a = MAGSQ(eip->a); magsq_b = MAGSQ(eip->b); magsq_c = MAGSQ(eip->c); /* Create unit length versions of A, B, C */ f = 1.0/sqrt(magsq_a); VSCALE(Au, eip->a, f); f = 1.0/sqrt(magsq_b); VSCALE(Bu, eip->b, f); f = 1.0/sqrt(magsq_c); VSCALE(Cu, eip->c, f); MAT_IDN(R); VMOVE(&R[0], Au); VMOVE(&R[4], Bu); VMOVE(&R[8], Cu); /* Compute bounding RPP */ VSET(w1, magsq_a, magsq_b, magsq_c); /* X */ VSET(P, 1.0, 0, 0); /* bounding plane normal */ MAT3X3VEC(w2, R, P); /* map plane to local coord syst */ VELMUL(w2, w2, w2); /* square each term */ f = VDOT(w1, w2); f = sqrt(f); (*min)[X] = eip->v[X] - f; /* V.P +/- f */ (*max)[X] = eip->v[X] + f; /* Y */ VSET(P, 0, 1.0, 0); /* bounding plane normal */ MAT3X3VEC(w2, R, P); /* map plane to local coord syst */ VELMUL(w2, w2, w2); /* square each term */ f = VDOT(w1, w2); f = sqrt(f); (*min)[Y] = eip->v[Y] - f; /* V.P +/- f */ (*max)[Y] = eip->v[Y] + f; /* Z */ VSET(P, 0, 0, 1.0); /* bounding plane normal */ MAT3X3VEC(w2, R, P); /* map plane to local coord syst */ VELMUL(w2, w2, w2); /* square each term */ f = VDOT(w1, w2); f = sqrt(f); (*min)[Z] = eip->v[Z] - f; /* V.P +/- f */ (*max)[Z] = eip->v[Z] + f; return 0; }
static void log_Run(void) { time_t clock_time; mat_t model2hv; /* model to h, v matrix */ mat_t hv2model; /* h, v tp model matrix */ quat_t orient; /* orientation */ point_t hv_eye; /* eye position in h, v coords */ point_t m_eye; /* eye position in model coords */ fastf_t hv_viewsize; /* size of view in h, v coords */ fastf_t m_viewsize; /* size of view in model coords. */ /* Current date and time get printed in header comment */ (void) time(&clock_time); (void) printf("# Log information produced by cell-fb %s\n", ctime(&clock_time)); (void) printf("az_el: %f %f\n", az, el); (void) printf("view_extrema: %f %f %f %f\n", SCRX2H(0), SCRX2H(fb_width), SCRY2V(0), SCRY2V(fb_height)); (void) printf("fb_size: %d %d\n", fb_width, fb_height); /* Produce the orientation, the model eye_pos, and the model * view size for input into rtregis. * First use the azimuth and elevation to produce the model2hv * matrix and use that to find the orientation. */ MAT_IDN(model2hv); MAT_IDN(hv2model); /* Print out the "view" just to keep rtregis from belly-aching */ printf("View: %g azimuth, %g elevation\n", az, el); /** mat_ae(model2hv, az, el); **/ /* Formula from rt/do.c */ bn_mat_angles(model2hv, 270.0+el, 0.0, 270.0-az); model2hv[15] = 25.4; /* input is in inches */ bn_mat_inv(hv2model, model2hv); quat_mat2quat(orient, model2hv); printf("Orientation: %.6f, %.6f, %.6f, %.6f\n", V4ARGS(orient)); /* Now find the eye position in h, v space. Note that the eye * is located at the center of the image; in this case, the center * of the screen space, i.e., the framebuffer.) * Also find the hv_viewsize at this time. */ hv_viewsize = SCRX2H((double)fb_width) - SCRX2H(0.0); hv_eye[0] = SCRX2H((double)fb_width/2); hv_eye[1] = SCRY2V((double)fb_height/2); hv_eye[2] = hv_viewsize/2; /* Debugging */ printf("hv_viewsize= %g\n", hv_viewsize); printf("hv_eye= %.6f, %.6f, %.6f\n", V3ARGS(hv_eye)); /* Now find the model eye_position and report on that */ MAT4X3PNT(m_eye, hv2model, hv_eye); printf("Eye_pos: %.6f, %.6f, %.6f\n", V3ARGS(m_eye)); /* * Find the view size in model coordinates and print that as well. * Important: Don't use %g format, it may round to nearest integer! */ m_viewsize = hv_viewsize/hv2model[15]; printf("Size: %.6f\n", m_viewsize); }
/** * Given a pointer to a GED database record, and a transformation * matrix, determine if this is a valid superellipsoid, and if so, * precompute various terms of the formula. * * Returns - * 0 SUPERELL is OK * !0 Error in description * * Implicit return - A struct superell_specific is created, and its * address is stored in stp->st_specific for use by rt_superell_shot() */ int rt_superell_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip) { struct superell_specific *superell; struct rt_superell_internal *eip; fastf_t magsq_a, magsq_b, magsq_c; mat_t R, TEMP; vect_t Au, Bu, Cu; /* A, B, C with unit length */ fastf_t f; eip = (struct rt_superell_internal *)ip->idb_ptr; RT_SUPERELL_CK_MAGIC(eip); /* Validate that |A| > 0, |B| > 0, |C| > 0 */ magsq_a = MAGSQ(eip->a); magsq_b = MAGSQ(eip->b); magsq_c = MAGSQ(eip->c); if (magsq_a < rtip->rti_tol.dist_sq || magsq_b < rtip->rti_tol.dist_sq || magsq_c < rtip->rti_tol.dist_sq) { bu_log("rt_superell_prep(): superell(%s) near-zero length A(%g), B(%g), or C(%g) vector\n", stp->st_name, magsq_a, magsq_b, magsq_c); return 1; /* BAD */ } if (eip->n < rtip->rti_tol.dist || eip->e < rtip->rti_tol.dist) { bu_log("rt_superell_prep(): superell(%s) near-zero length <n, e> curvature (%g, %g) causes problems\n", stp->st_name, eip->n, eip->e); /* BAD */ } if (eip->n > 10000.0 || eip->e > 10000.0) { bu_log("rt_superell_prep(): superell(%s) very large <n, e> curvature (%g, %g) causes problems\n", stp->st_name, eip->n, eip->e); /* BAD */ } /* Create unit length versions of A, B, C */ f = 1.0/sqrt(magsq_a); VSCALE(Au, eip->a, f); f = 1.0/sqrt(magsq_b); VSCALE(Bu, eip->b, f); f = 1.0/sqrt(magsq_c); VSCALE(Cu, eip->c, f); /* Validate that A.B == 0, B.C == 0, A.C == 0 (check dir only) */ f = VDOT(Au, Bu); if (! NEAR_ZERO(f, rtip->rti_tol.dist)) { bu_log("rt_superell_prep(): superell(%s) A not perpendicular to B, f=%f\n", stp->st_name, f); return 1; /* BAD */ } f = VDOT(Bu, Cu); if (! NEAR_ZERO(f, rtip->rti_tol.dist)) { bu_log("rt_superell_prep(): superell(%s) B not perpendicular to C, f=%f\n", stp->st_name, f); return 1; /* BAD */ } f = VDOT(Au, Cu); if (! NEAR_ZERO(f, rtip->rti_tol.dist)) { bu_log("rt_superell_prep(): superell(%s) A not perpendicular to C, f=%f\n", stp->st_name, f); return 1; /* BAD */ } /* Solid is OK, compute constant terms now */ BU_GET(superell, struct superell_specific); stp->st_specific = (void *)superell; superell->superell_n = eip->n; superell->superell_e = eip->e; VMOVE(superell->superell_V, eip->v); VSET(superell->superell_invsq, 1.0/magsq_a, 1.0/magsq_b, 1.0/magsq_c); VMOVE(superell->superell_Au, Au); VMOVE(superell->superell_Bu, Bu); VMOVE(superell->superell_Cu, Cu); /* compute the inverse magnitude square for equations during shot */ superell->superell_invmsAu = 1.0 / magsq_a; superell->superell_invmsBu = 1.0 / magsq_b; superell->superell_invmsCu = 1.0 / magsq_c; /* compute the rotation matrix */ MAT_IDN(R); VMOVE(&R[0], Au); VMOVE(&R[4], Bu); VMOVE(&R[8], Cu); bn_mat_trn(superell->superell_invR, R); /* computer invRSSR */ MAT_IDN(superell->superell_invRSSR); MAT_IDN(TEMP); TEMP[0] = superell->superell_invsq[0]; TEMP[5] = superell->superell_invsq[1]; TEMP[10] = superell->superell_invsq[2]; bn_mat_mul(TEMP, TEMP, R); bn_mat_mul(superell->superell_invRSSR, superell->superell_invR, TEMP); /* compute Scale(Rotate(vect)) */ MAT_IDN(superell->superell_SoR); VSCALE(&superell->superell_SoR[0], eip->a, superell->superell_invsq[0]); VSCALE(&superell->superell_SoR[4], eip->b, superell->superell_invsq[1]); VSCALE(&superell->superell_SoR[8], eip->c, superell->superell_invsq[2]); /* Compute bounding sphere */ VMOVE(stp->st_center, eip->v); f = magsq_a; if (magsq_b > f) f = magsq_b; if (magsq_c > f) f = magsq_c; stp->st_aradius = stp->st_bradius = sqrt(f); /* Compute bounding RPP */ if (rt_superell_bbox(ip, &(stp->st_min), &(stp->st_max), &rtip->rti_tol)) return 1; return 0; /* OK */ }
bool STEPWrapper::convert(BRLCADWrapper *dot_g) { MAP_OF_PRODUCT_NAME_TO_ENTITY_ID name2id_map; MAP_OF_ENTITY_ID_TO_PRODUCT_NAME id2name_map; MAP_OF_ENTITY_ID_TO_PRODUCT_ID id2productid_map; MAP_OF_PRODUCT_NAME_TO_ENTITY_ID::iterator niter = name2id_map.end(); if (!dot_g) { return false; } this->dotg = dot_g; int num_ents = instance_list->InstanceCount(); for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_definition_representation))) { ShapeDefinitionRepresentation *sdr = dynamic_cast<ShapeDefinitionRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (!sdr) { bu_exit(1, "ERROR: unable to allocate a 'ShapeDefinitionRepresentation' entity\n"); } else { int sdr_id = sdr->GetId(); std::string pname = sdr->GetProductName(); int product_id = sdr->GetProductId(); id2productid_map[sdr_id] = product_id; if (pname.empty()) { std::string str = "ShapeDefinitionRepresentation@"; str = dotg->GetBRLCADName(str); id2name_map[sdr_id] = pname; } else { std::string temp = pname; int index = 2; while ((niter=name2id_map.find(temp)) != name2id_map.end()) { temp = pname + "_" + static_cast<ostringstream*>( &(ostringstream() << (index++)) )->str(); } pname = temp; if ((niter=name2id_map.find(pname)) == name2id_map.end()) { id2name_map[sdr_id] = pname; name2id_map[pname] = product_id; id2name_map[product_id] = pname; } } AdvancedBrepShapeRepresentation *aBrep = sdr->GetAdvancedBrepShapeRepresentation(); if (aBrep) { if (pname.empty()) { std::string str = "product@"; pname = dotg->GetBRLCADName(str); id2name_map[aBrep->GetId()] = pname; id2name_map[product_id] = pname; } else { id2name_map[aBrep->GetId()] = pname; id2name_map[product_id] = pname; } id2productid_map[aBrep->GetId()] = product_id; if (Verbose()) { if (!pname.empty()) { std::cerr << std::endl << " Generating Product -" << pname ; } else { std::cerr << std::endl << " Generating Product"; } } LocalUnits::length = aBrep->GetLengthConversionFactor(); LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor(); LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor(); ON_Brep *onBrep = aBrep->GetONBrep(); if (!onBrep) { delete sdr; bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str()); } else { ON_TextLog tl; if (!onBrep->IsValid(&tl)) { bu_log("WARNING: %s is not valid\n", name.c_str()); } //onBrep->SpSplitClosedFaces(); //ON_Brep *tbrep = TightenBrep(onBrep); mat_t mat; MAT_IDN(mat); Axis2Placement3D *axis = aBrep->GetAxis2Placement3d(); if (axis != NULL) { //assign matrix values double translate_to[3]; const double *toXaxis = axis->GetXAxis(); const double *toYaxis = axis->GetYAxis(); const double *toZaxis = axis->GetZAxis(); mat_t rot_mat; VMOVE(translate_to,axis->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); MAT_IDN(rot_mat); VMOVE(&rot_mat[0], toXaxis); VMOVE(&rot_mat[4], toYaxis); VMOVE(&rot_mat[8], toZaxis); bn_mat_inv(mat, rot_mat); MAT_DELTAS_VEC(mat, translate_to); } dotg->WriteBrep(pname, onBrep,mat); delete onBrep; } } else { // must be an assembly if (pname.empty()) { std::string str = "assembly@"; pname = dotg->GetBRLCADName(str); } ShapeRepresentation *aSR = sdr->GetShapeRepresentation(); if (aSR) { int sr_id = aSR->GetId(); id2name_map[sr_id] = pname; id2name_map[product_id] = pname; id2productid_map[sr_id] = product_id; } } Factory::DeleteObjects(); } } } /* * Pickup BREP related to SHAPE_REPRESENTATION through SHAPE_REPRESENTATION_RELATIONSHIP * * like the following found in OpenBook Part 'C': * #21281=SHAPE_DEFINITION_REPRESENTATION(#21280,#21270); * #21280=PRODUCT_DEFINITION_SHAPE('','SHAPE FOR C.',#21279); * #21279=PRODUCT_DEFINITION('design','',#21278,#21275); * #21278=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('1','LAST_VERSION',#21277,.MADE.); * #21277=PRODUCT('C','C','NOT SPECIFIED',(#21276)); * #21270=SHAPE_REPRESENTATION('',(#21259),#21267); * #21259=AXIS2_PLACEMENT_3D('DANTE_BX_CPU_TOP_1',#21256,#21257,#21258); * #21267=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#21266)) * GLOBAL_UNIT_ASSIGNED_CONTEXT((#21260,#21264,#21265))REPRESENTATION_CONTEXT('ID1','3')); * * #21271=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21268); * #21268=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#21254),#21267); * #21272=SHAPE_REPRESENTATION_RELATIONSHIP('','',#21270,#21269); * #21269=MANIFOLD_SURFACE_SHAPE_REPRESENTATION('',(#21255),#21267); * */ for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_shape_representation_relationship))) { ShapeRepresentationRelationship *srr = dynamic_cast<ShapeRepresentationRelationship *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (srr) { ShapeRepresentation *aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1()); AdvancedBrepShapeRepresentation *aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2()); if (!aBrep) { //try rep_1 aBrep = dynamic_cast<AdvancedBrepShapeRepresentation *>(srr->GetRepresentationRelationshipRep_1()); aSR = dynamic_cast<ShapeRepresentation *>(srr->GetRepresentationRelationshipRep_2()); } if ((aSR) && (aBrep)) { int sr_id = aSR->GetId(); MAP_OF_ENTITY_ID_TO_PRODUCT_ID::iterator it = id2productid_map.find(sr_id); if (it != id2productid_map.end()) { // product found int product_id = (*it).second; int brep_id = aBrep->GetId(); it = id2productid_map.find(brep_id); if (it == id2productid_map.end()) { // brep not loaded yet so lets do that here. string pname = id2name_map[product_id]; id2productid_map[brep_id] = product_id; if (Verbose()) { if (!pname.empty()) { std::cerr << std::endl << " Generating Product -" << pname ; } else { std::cerr << std::endl << " Generating Product"; } } LocalUnits::length = aBrep->GetLengthConversionFactor(); LocalUnits::planeangle = aBrep->GetPlaneAngleConversionFactor(); LocalUnits::solidangle = aBrep->GetSolidAngleConversionFactor(); ON_Brep *onBrep = aBrep->GetONBrep(); if (!onBrep) { bu_exit(1, "ERROR: failure creating advanced boundary representation from %s\n", stepfile.c_str()); } else { ON_TextLog tl; if (!onBrep->IsValid(&tl)) { bu_log("WARNING: %s is not valid\n", name.c_str()); } //onBrep->SpSplitClosedFaces(); //ON_Brep *tbrep = TightenBrep(onBrep); mat_t mat; MAT_IDN(mat); Axis2Placement3D *axis = aBrep->GetAxis2Placement3d(); if (axis != NULL) { //assign matrix values double translate_to[3]; const double *toXaxis = axis->GetXAxis(); const double *toYaxis = axis->GetYAxis(); const double *toZaxis = axis->GetZAxis(); mat_t rot_mat; VMOVE(translate_to,axis->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); MAT_IDN(rot_mat); VMOVE(&rot_mat[0], toXaxis); VMOVE(&rot_mat[4], toYaxis); VMOVE(&rot_mat[8], toZaxis); bn_mat_inv(mat, rot_mat); MAT_DELTAS_VEC(mat, translate_to); } dotg->WriteBrep(pname, onBrep,mat); delete onBrep; } } } } Factory::DeleteObjects(); } } } if (Verbose()) { std::cerr << std::endl << " Generating BRL-CAD hierarchy." << std::endl; } for (int i = 0; i < num_ents; i++) { SDAI_Application_instance *sse = instance_list->GetSTEPentity(i); if (sse == NULL) { continue; } std::string name = sse->EntityName(); std::transform(name.begin(), name.end(), name.begin(), (int(*)(int))std::tolower); if ((sse->STEPfile_id > 0) && (sse->IsA(SCHEMA_NAMESPACE::e_context_dependent_shape_representation))) { ContextDependentShapeRepresentation *aCDSR = dynamic_cast<ContextDependentShapeRepresentation *>(Factory::CreateObject(this, (SDAI_Application_instance *)sse)); if (aCDSR) { int rep_1_id = aCDSR->GetRepresentationRelationshipRep_1()->GetId(); int rep_2_id = aCDSR->GetRepresentationRelationshipRep_2()->GetId(); int pid_1 = id2productid_map[rep_1_id]; int pid_2 = id2productid_map[rep_2_id]; Axis2Placement3D *axis1 = NULL; Axis2Placement3D *axis2 = NULL; if ((id2name_map.find(rep_1_id) != id2name_map.end()) && (id2name_map.find(rep_2_id) != id2name_map.end())) { string comb = id2name_map[rep_1_id]; string member = id2name_map[rep_2_id]; mat_t mat; MAT_IDN(mat); ProductDefinition *relatingProduct = aCDSR->GetRelatingProductDefinition(); ProductDefinition *relatedProduct = aCDSR->GetRelatedProductDefinition(); if (relatingProduct && relatedProduct) { string relatingName = relatingProduct->GetProductName(); int relatingID = relatingProduct->GetProductId(); string relatedName = relatedProduct->GetProductName(); int relatedID = relatedProduct->GetProductId(); if ((relatingID == pid_1) && (relatedID == pid_2)) { axis1 = aCDSR->GetTransformItem_1(); axis2 = aCDSR->GetTransformItem_2(); comb = id2name_map[rep_1_id]; member = id2name_map[rep_2_id]; } else if ((relatingID == pid_2) && (relatedID == pid_1)) { axis1 = aCDSR->GetTransformItem_2(); axis2 = aCDSR->GetTransformItem_1(); comb = id2name_map[rep_2_id]; member = id2name_map[rep_1_id]; } else { std::cerr << "Error: Found Representation Relationship Rep_1(name=" << comb << ",Id=" << rep_1_id << ")" << std::endl; std::cerr << "Error: Found Representation Relationship Rep_2(name=" << member << ",Id=" << rep_2_id << ")" << std::endl; std::cerr << "Error: but Relating ProductDefinition (name=" << relatingName << ",Id=" << relatingID << ")" << std::endl; std::cerr << "Error: Related ProductDefinition (name=" << relatedName << ",Id=" << relatedID << ")" << std::endl; } } if ((axis1 != NULL) && (axis2 != NULL)) { mat_t to_mat; mat_t from_mat; mat_t toinv_mat; //assign matrix values double translate_to[3]; double translate_from[3]; const double *toXaxis = axis1->GetXAxis(); const double *toYaxis = axis1->GetYAxis(); const double *toZaxis = axis1->GetZAxis(); const double *fromXaxis = axis2->GetXAxis(); const double *fromYaxis = axis2->GetYAxis(); const double *fromZaxis = axis2->GetZAxis(); VMOVE(translate_to,axis1->GetOrigin()); VSCALE(translate_to,translate_to,LocalUnits::length); VMOVE(translate_from,axis2->GetOrigin()); VSCALE(translate_from,translate_from,-LocalUnits::length); // undo from trans/rot MAT_IDN(from_mat); VMOVE(&from_mat[0], fromXaxis); VMOVE(&from_mat[4], fromYaxis); VMOVE(&from_mat[8], fromZaxis); MAT_DELTAS_VEC(from_mat, translate_from); // do to trans/rot MAT_IDN(to_mat); VMOVE(&to_mat[0], toXaxis); VMOVE(&to_mat[4], toYaxis); VMOVE(&to_mat[8], toZaxis); bn_mat_inv(toinv_mat, to_mat); MAT_DELTAS_VEC(toinv_mat, translate_to); bn_mat_mul(mat, toinv_mat, from_mat); } dotg->AddMember(comb,member,mat); } Factory::DeleteObjects(); } } } if (!dotg->WriteCombs()) { std::cerr << "Error writing BRL-CAD hierarchy." << std::endl; } return true; }
/** * Given a pointer to an internal GED database object, mirror the * object's values about the given transformation matrix. */ int rt_nurb_mirror(struct rt_db_internal *ip, register const plane_t plane) { struct rt_nurb_internal *nurb; mat_t mirmat; mat_t rmat; mat_t temp; vect_t nvec; vect_t xvec; vect_t mirror_dir; point_t mirror_pt; fastf_t ang; int i; int j; static point_t origin = {0.0, 0.0, 0.0}; RT_CK_DB_INTERNAL(ip); nurb = (struct rt_nurb_internal *)ip->idb_ptr; RT_PG_CK_MAGIC(nurb); MAT_IDN(mirmat); VMOVE(mirror_dir, plane); VSCALE(mirror_pt, plane, plane[W]); /* Build mirror transform matrix, for those who need it. */ /* First, perform a mirror down the X axis */ mirmat[0] = -1.0; /* Create the rotation matrix */ VSET(xvec, 1, 0, 0); VCROSS(nvec, xvec, mirror_dir); VUNITIZE(nvec); ang = -acos(VDOT(xvec, mirror_dir)); bn_mat_arb_rot(rmat, origin, nvec, ang*2.0); /* Add the rotation to mirmat */ MAT_COPY(temp, mirmat); bn_mat_mul(mirmat, temp, rmat); /* Add the translation to mirmat */ mirmat[3 + X*4] += mirror_pt[X] * mirror_dir[X]; mirmat[3 + Y*4] += mirror_pt[Y] * mirror_dir[Y]; mirmat[3 + Z*4] += mirror_pt[Z] * mirror_dir[Z]; for (i=0; i<nurb->nsrf; i++) { fastf_t *ptr; int tmp; int orig_size[2]; int ncoords; int m; int l; /* swap knot vectors between u and v */ ptr = nurb->srfs[i]->u.knots; tmp = nurb->srfs[i]->u.k_size; nurb->srfs[i]->u.knots = nurb->srfs[i]->v.knots; nurb->srfs[i]->u.k_size = nurb->srfs[i]->v.k_size; nurb->srfs[i]->v.knots = ptr; nurb->srfs[i]->v.k_size = tmp; /* swap order */ tmp = nurb->srfs[i]->order[0]; nurb->srfs[i]->order[0] = nurb->srfs[i]->order[1]; nurb->srfs[i]->order[1] = tmp; /* swap mesh size */ orig_size[0] = nurb->srfs[i]->s_size[0]; orig_size[1] = nurb->srfs[i]->s_size[1]; nurb->srfs[i]->s_size[0] = orig_size[1]; nurb->srfs[i]->s_size[1] = orig_size[0]; /* allocate memory for a new control mesh */ ncoords = RT_NURB_EXTRACT_COORDS(nurb->srfs[i]->pt_type); ptr = (fastf_t *)bu_calloc(orig_size[0]*orig_size[1]*ncoords, sizeof(fastf_t), "rt_mirror: ctl mesh ptr"); /* mirror each control point */ for (j=0; j<orig_size[0]*orig_size[1]; j++) { point_t pt; VMOVE(pt, &nurb->srfs[i]->ctl_points[j*ncoords]); MAT4X3PNT(&nurb->srfs[i]->ctl_points[j*ncoords], mirmat, pt); } /* copy mirrored control points into new mesh * while swapping u and v */ m = 0; for (j=0; j<orig_size[0]; j++) { for (l=0; l<orig_size[1]; l++) { VMOVEN(&ptr[(l*orig_size[0]+j)*ncoords], &nurb->srfs[i]->ctl_points[m*ncoords], ncoords); m++; } } /* free old mesh */ bu_free((char *)nurb->srfs[i]->ctl_points, "rt_mirror: ctl points"); /* put new mesh in place */ nurb->srfs[i]->ctl_points = ptr; } return 0; }