int ged_setview(struct ged *gedp, int argc, const char *argv[]) { vect_t rvec; static const char *usage = "x y z"; GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); GED_CHECK_VIEW(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 != 2 && argc != 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } /* set view center */ if (argc == 2) { if (bn_decode_vect(rvec, argv[1]) != 3) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } } else { double scan[3]; if (sscanf(argv[1], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "ged_setview: bad X value - %s\n", argv[1]); return GED_ERROR; } if (sscanf(argv[2], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "ged_setview: bad Y value - %s\n", argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "ged_setview: bad Z value - %s\n", argv[3]); return GED_ERROR; } /* convert from double to fastf_t */ VMOVE(rvec, scan); } bn_mat_angles(gedp->ged_gvp->gv_rotation, rvec[X], rvec[Y], rvec[Z]); ged_view_update(gedp->ged_gvp); return GED_OK; }
/* * T P _ 2 S Y M B O L */ void tp_2symbol(FILE *fp, char *string, double x, double y, double scale, double theta) /* string of chars to be plotted */ /* x, y of lower left corner of 1st char */ /* scale factor to change 1x1 char sz */ /* degrees ccw from X-axis */ { mat_t mat; vect_t p; bn_mat_angles( mat, 0.0, 0.0, theta ); VSET( p, x, y, 0 ); tp_3symbol( fp, string, p, mat, scale ); }
/* * Phase 2 setup routine */ HIDDEN void wood_setup_2(struct wood_specific *wd) { mat_t xlate; int i; vect_t a_vertex, a_dir; register struct resource *resp = &rt_uniresource; /* * See if the user specified absolute coordinates for the vertex and * direction. If so, use those instead of the RPP. */ bn_mat_angles(xlate, V3ARGS(wd->rot)); if (wd->flags & EXPLICIT_VERTEX) { MAT4X3PNT(wd->vertex, xlate, wd->V); MAT4X3PNT(wd->dir, xlate, wd->D); } else { if (wd->dz > 0.0) { for (i = 0; i < 2; i++) { a_vertex[i] = wd->b_min[i]; a_dir[i] = wd->b_max[i]; } /* Z component is [2] */ a_vertex[2] = ((wd->b_max[2] - wd->b_min[2]) * (bn_rand0to1(resp->re_randptr) * wd->dz)) + wd->b_min[2]; a_dir[2] = ((wd->b_max[2] - wd->b_min[2]) * (bn_rand0to1(resp->re_randptr) * wd->dz)) + wd->b_min[2]; } else { for (i = 0; i < 3; i++) { a_vertex[i] = ((wd->b_max[i] - wd->b_min[i]) * (bn_rand0to1(resp->re_randptr) * wd->dd)) + wd->b_min[i]; a_dir[i] = ((wd->b_max[i] - wd->b_min[i]) * (bn_rand0to1(resp->re_randptr) * wd->dd)) + wd->b_max[i]; } } MAT4X3PNT(wd->vertex, xlate, a_vertex); MAT4X3PNT(wd->dir, xlate, a_dir); } VSUB2(wd->dir, wd->dir, wd->vertex); VUNITIZE(wd->dir); }
static int test_bn_mat_angles(int argc, char *argv[]) { mat_t expected, actual; double x, y, z; if (argc != 6) { bu_exit(1, "<args> format: x y z <expected_result> [%s]\n", argv[0]); } sscanf(argv[2], "%lg", &x); sscanf(argv[3], "%lg", &y); sscanf(argv[4], "%lg", &z); scan_mat_args(argv, 5, &expected); bn_mat_angles(actual, x, y, z); return !mat_equal(expected, actual); }
/** * FIXME: this routine is suspect and needs investigating. if run * during view initialization, the shaders regression test fails. */ void _ged_mat_aet(struct ged_view *gvp) { mat_t tmat; fastf_t twist; fastf_t c_twist; fastf_t s_twist; bn_mat_angles(gvp->gv_rotation, 270.0 + gvp->gv_aet[1], 0.0, 270.0 - gvp->gv_aet[0]); twist = -gvp->gv_aet[2] * DEG2RAD; c_twist = cos(twist); s_twist = sin(twist); bn_mat_zrot(tmat, s_twist, c_twist); bn_mat_mul2(tmat, gvp->gv_rotation); }
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); }
int ged_protate(struct ged *gedp, int argc, const char *argv[]) { int ret; mat_t rmat; char *last; struct rt_db_internal intern; struct directory *dp; /* intentionally double for scan */ double rx, ry, rz; static const char *usage = "obj attribute rvec"; 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 != 4) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (sscanf(argv[3], "%lf %lf %lf", &rx, &ry, &rz) != 3) { bu_vls_printf(gedp->ged_result_str, "%s: bad rotation vector - %s", argv[0], argv[3]); return GED_ERROR; } if ((last = strrchr(argv[1], '/')) == NULL) last = (char *)argv[1]; else ++last; if (last[0] == '\0') { bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], argv[1]); return GED_ERROR; } if ((dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s not found", argv[0], argv[1]); return GED_ERROR; } GED_DB_GET_INTERNAL(gedp, &intern, dp, (matp_t)NULL, &rt_uniresource, GED_ERROR); RT_CK_DB_INTERNAL(&intern); if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD) { bu_vls_printf(gedp->ged_result_str, "%s: Object not eligible for rotating.", argv[0]); rt_db_free_internal(&intern); return GED_ERROR; } bn_mat_angles(rmat, rx, ry, rz); switch (intern.idb_minor_type) { case DB5_MINORTYPE_BRLCAD_ETO: ret = _ged_rotate_eto(gedp, (struct rt_eto_internal *)intern.idb_ptr, argv[2], rmat); break; case DB5_MINORTYPE_BRLCAD_EXTRUDE: ret = _ged_rotate_extrude(gedp, (struct rt_extrude_internal *)intern.idb_ptr, argv[2], rmat); break; case DB5_MINORTYPE_BRLCAD_HYP: ret = _ged_rotate_hyp(gedp, (struct rt_hyp_internal *)intern.idb_ptr, argv[2], rmat); break; case DB5_MINORTYPE_BRLCAD_TGC: ret = _ged_rotate_tgc(gedp, (struct rt_tgc_internal *)intern.idb_ptr, argv[2], rmat); break; default: bu_vls_printf(gedp->ged_result_str, "%s: Object not yet supported.", argv[0]); rt_db_free_internal(&intern); return GED_ERROR; } if (ret == GED_OK) { GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR); } else if (ret == GED_ERROR) { rt_db_free_internal(&intern); } return ret; }
int bn_math_cmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { void (*math_func)(); struct bu_vls result; math_func = (void (*)())clientData; /* object-to-function cast */ bu_vls_init(&result); if (math_func == bn_mat_mul) { mat_t o, a, b; if (argc < 3 || bn_decode_mat(a, argv[1]) < 16 || bn_decode_mat(b, argv[2]) < 16) { bu_vls_printf(&result, "usage: %s matA matB", argv[0]); goto error; } bn_mat_mul(o, a, b); bn_encode_mat(&result, o); } else if (math_func == bn_mat_inv || math_func == bn_mat_trn) { mat_t o, a; if (argc < 2 || bn_decode_mat(a, argv[1]) < 16) { bu_vls_printf(&result, "usage: %s mat", argv[0]); goto error; } (*math_func)(o, a); bn_encode_mat(&result, o); } else if (math_func == bn_matXvec) { mat_t m; hvect_t i, o; if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || bn_decode_hvect(i, argv[2]) < 4) { bu_vls_printf(&result, "usage: %s mat hvect", argv[0]); goto error; } bn_matXvec(o, m, i); bn_encode_hvect(&result, o); } else if (math_func == bn_mat4x3pnt) { mat_t m; point_t i, o; if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || bn_decode_vect(i, argv[2]) < 3) { bu_vls_printf(&result, "usage: %s mat point", argv[0]); goto error; } bn_mat4x3pnt(o, m, i); bn_encode_vect(&result, o); } else if (math_func == bn_mat4x3vec) { mat_t m; vect_t i, o; if (argc < 3 || bn_decode_mat(m, argv[1]) < 16 || bn_decode_vect(i, argv[2]) < 3) { bu_vls_printf(&result, "usage: %s mat vect", argv[0]); goto error; } bn_mat4x3vec(o, m, i); bn_encode_vect(&result, o); } else if (math_func == bn_hdivide) { hvect_t i; vect_t o; if (argc < 2 || bn_decode_hvect(i, argv[1]) < 4) { bu_vls_printf(&result, "usage: %s hvect", argv[0]); goto error; } bn_hdivide(o, i); bn_encode_vect(&result, o); } else if (math_func == bn_vjoin1) { point_t o; point_t b, d; fastf_t c; if (argc < 4) { bu_vls_printf(&result, "usage: %s pnt scale dir", argv[0]); goto error; } if ( bn_decode_vect(b, argv[1]) < 3) goto error; if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; if ( bn_decode_vect(d, argv[3]) < 3) goto error; VJOIN1( o, b, c, d ); /* bn_vjoin1( o, b, c, d ) */ bn_encode_vect(&result, o); } else if ( math_func == bn_vblend) { point_t a, c, e; fastf_t b, d; if ( argc < 5 ) { bu_vls_printf(&result, "usage: %s scale pnt scale pnt", argv[0]); goto error; } if ( Tcl_GetDouble(interp, argv[1], &b) != TCL_OK) goto error; if ( bn_decode_vect( c, argv[2] ) < 3) goto error; if ( Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error; if ( bn_decode_vect( e, argv[4] ) < 3) goto error; VBLEND2( a, b, c, d, e ) bn_encode_vect( &result, a ); } else if (math_func == bn_mat_ae) { mat_t o; double az, el; if (argc < 3) { bu_vls_printf(&result, "usage: %s azimuth elevation", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[1], &az) != TCL_OK) goto error; if (Tcl_GetDouble(interp, argv[2], &el) != TCL_OK) goto error; bn_mat_ae(o, (fastf_t)az, (fastf_t)el); bn_encode_mat(&result, o); } else if (math_func == bn_ae_vec) { fastf_t az, el; vect_t v; if (argc < 2 || bn_decode_vect(v, argv[1]) < 3) { bu_vls_printf(&result, "usage: %s vect", argv[0]); goto error; } bn_ae_vec(&az, &el, v); bu_vls_printf(&result, "%g %g", az, el); } else if (math_func == bn_aet_vec) { fastf_t az, el, twist, accuracy; vect_t vec_ae, vec_twist; if (argc < 4 || bn_decode_vect(vec_ae, argv[1]) < 3 || bn_decode_vect(vec_twist, argv[2]) < 3 || sscanf(argv[3], "%lf", &accuracy) < 1) { bu_vls_printf(&result, "usage: %s vec_ae vec_twist accuracy", argv[0]); goto error; } bn_aet_vec(&az, &el, &twist, vec_ae, vec_twist, accuracy); bu_vls_printf(&result, "%g %g %g", az, el, twist); } else if (math_func == bn_mat_angles) { mat_t o; double alpha, beta, ggamma; if (argc < 4) { bu_vls_printf(&result, "usage: %s alpha beta gamma", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[1], &alpha) != TCL_OK) goto error; if (Tcl_GetDouble(interp, argv[2], &beta) != TCL_OK) goto error; if (Tcl_GetDouble(interp, argv[3], &ggamma) != TCL_OK) goto error; bn_mat_angles(o, alpha, beta, ggamma); bn_encode_mat(&result, o); } else if (math_func == bn_eigen2x2) { fastf_t val1, val2; vect_t vec1, vec2; double a, b, c; if (argc < 4) { bu_vls_printf(&result, "usage: %s a b c", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[1], &a) != TCL_OK) goto error; if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; if (Tcl_GetDouble(interp, argv[3], &b) != TCL_OK) goto error; bn_eigen2x2(&val1, &val2, vec1, vec2, (fastf_t)a, (fastf_t)b, (fastf_t)c); bu_vls_printf(&result, "%g %g {%g %g %g} {%g %g %g}", val1, val2, V3ARGS(vec1), V3ARGS(vec2)); } else if (math_func == bn_mat_fromto) { mat_t o; vect_t from, to; if (argc < 3 || bn_decode_vect(from, argv[1]) < 3 || bn_decode_vect(to, argv[2]) < 3) { bu_vls_printf(&result, "usage: %s vecFrom vecTo", argv[0]); goto error; } bn_mat_fromto(o, from, to); bn_encode_mat(&result, o); } else if (math_func == bn_mat_xrot || math_func == bn_mat_yrot || math_func == bn_mat_zrot) { mat_t o; double s, c; if (argc < 3) { bu_vls_printf(&result, "usage: %s sinAngle cosAngle", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[1], &s) != TCL_OK) goto error; if (Tcl_GetDouble(interp, argv[2], &c) != TCL_OK) goto error; (*math_func)(o, s, c); bn_encode_mat(&result, o); } else if (math_func == bn_mat_lookat) { mat_t o; vect_t dir; int yflip; if (argc < 3 || bn_decode_vect(dir, argv[1]) < 3) { bu_vls_printf(&result, "usage: %s dir yflip", argv[0]); goto error; } if (Tcl_GetBoolean(interp, argv[2], &yflip) != TCL_OK) goto error; bn_mat_lookat(o, dir, yflip); bn_encode_mat(&result, o); } else if (math_func == bn_vec_ortho || math_func == bn_vec_perp) { vect_t ov, vec; if (argc < 2 || bn_decode_vect(vec, argv[1]) < 3) { bu_vls_printf(&result, "usage: %s vec", argv[0]); goto error; } (*math_func)(ov, vec); bn_encode_vect(&result, ov); } else if (math_func == bn_mat_scale_about_pt_wrapper) { mat_t o; vect_t v; double scale; int status; if (argc < 3 || bn_decode_vect(v, argv[1]) < 3) { bu_vls_printf(&result, "usage: %s pt scale", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[2], &scale) != TCL_OK) goto error; bn_mat_scale_about_pt_wrapper(&status, o, v, scale); if (status != 0) { bu_vls_printf(&result, "error performing calculation"); goto error; } bn_encode_mat(&result, o); } else if (math_func == bn_mat_xform_about_pt) { mat_t o, xform; vect_t v; if (argc < 3 || bn_decode_mat(xform, argv[1]) < 16 || bn_decode_vect(v, argv[2]) < 3) { bu_vls_printf(&result, "usage: %s xform pt", argv[0]); goto error; } bn_mat_xform_about_pt(o, xform, v); bn_encode_mat(&result, o); } else if (math_func == bn_mat_arb_rot) { mat_t o; point_t pt; vect_t dir; double angle; if (argc < 4 || bn_decode_vect(pt, argv[1]) < 3 || bn_decode_vect(dir, argv[2]) < 3) { bu_vls_printf(&result, "usage: %s pt dir angle", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[3], &angle) != TCL_OK) return TCL_ERROR; bn_mat_arb_rot(o, pt, dir, (fastf_t)angle); bn_encode_mat(&result, o); } else if (math_func == quat_mat2quat) { mat_t mat; quat_t quat; if (argc < 2 || bn_decode_mat(mat, argv[1]) < 16) { bu_vls_printf(&result, "usage: %s mat", argv[0]); goto error; } quat_mat2quat(quat, mat); bn_encode_quat(&result, quat); } else if (math_func == quat_quat2mat) { mat_t mat; quat_t quat; if (argc < 2 || bn_decode_quat(quat, argv[1]) < 4) { bu_vls_printf(&result, "usage: %s quat", argv[0]); goto error; } quat_quat2mat(mat, quat); bn_encode_mat(&result, mat); } else if (math_func == bn_quat_distance_wrapper) { quat_t q1, q2; double d; if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || bn_decode_quat(q2, argv[2]) < 4) { bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); goto error; } bn_quat_distance_wrapper(&d, q1, q2); bu_vls_printf(&result, "%g", d); } else if (math_func == quat_double || math_func == quat_bisect || math_func == quat_make_nearest) { quat_t oqot, q1, q2; if (argc < 3 || bn_decode_quat(q1, argv[1]) < 4 || bn_decode_quat(q2, argv[2]) < 4) { bu_vls_printf(&result, "usage: %s quatA quatB", argv[0]); goto error; } (*math_func)(oqot, q1, q2); bn_encode_quat(&result, oqot); } else if (math_func == quat_slerp) { quat_t oq, q1, q2; double d; if (argc < 4 || bn_decode_quat(q1, argv[1]) < 4 || bn_decode_quat(q2, argv[2]) < 4) { bu_vls_printf(&result, "usage: %s quat1 quat2 factor", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[3], &d) != TCL_OK) goto error; quat_slerp(oq, q1, q2, d); bn_encode_quat(&result, oq); } else if (math_func == quat_sberp) { quat_t oq, q1, qa, qb, q2; double d; if (argc < 6 || bn_decode_quat(q1, argv[1]) < 4 || bn_decode_quat(qa, argv[2]) < 4 || bn_decode_quat(qb, argv[3]) < 4 || bn_decode_quat(q2, argv[4]) < 4) { bu_vls_printf(&result, "usage: %s quat1 quatA quatB quat2 factor", argv[0]); goto error; } if (Tcl_GetDouble(interp, argv[5], &d) != TCL_OK) goto error; quat_sberp(oq, q1, qa, qb, q2, d); bn_encode_quat(&result, oq); } else if (math_func == quat_exp || math_func == quat_log) { quat_t qout, qin; if (argc < 2 || bn_decode_quat(qin, argv[1]) < 4) { bu_vls_printf(&result, "usage: %s quat", argv[0]); goto error; } (*math_func)(qout, qin); bn_encode_quat(&result, qout); } else if (math_func == (void (*)())bn_isect_line3_line3) { double t, u; point_t pt, a; vect_t dir, c; int i; static const struct bn_tol tol = { BN_TOL_MAGIC, 0.005, 0.005*0.005, 1e-6, 1-1e-6 }; if (argc != 5) { bu_vls_printf(&result, "Usage: bn_isect_line3_line3 pt dir pt dir (%d args specified)", argc-1); goto error; } if (bn_decode_vect(pt, argv[1]) < 3) { bu_vls_printf(&result, "bn_isect_line3_line3 no pt: %s\n", argv[0]); goto error; } if (bn_decode_vect(dir, argv[2]) < 3) { bu_vls_printf(&result, "bn_isect_line3_line3 no dir: %s\n", argv[0]); goto error; } if (bn_decode_vect(a, argv[3]) < 3) { bu_vls_printf(&result, "bn_isect_line3_line3 no a pt: %s\n", argv[0]); goto error; } if (bn_decode_vect(c, argv[4]) < 3) { bu_vls_printf(&result, "bn_isect_line3_line3 no c dir: %s\n", argv[0]); goto error; } i = bn_isect_line3_line3(&t, &u, pt, dir, a, c, &tol); if (i != 1) { bu_vls_printf(&result, "bn_isect_line3_line3 no intersection: %s\n", argv[0]); goto error; } VJOIN1(a, pt, t, dir); bn_encode_vect(&result, a); } else if (math_func == (void (*)())bn_isect_line2_line2) { double dist[2]; point_t pt, a; vect_t dir, c; int i; static const struct bn_tol tol = { BN_TOL_MAGIC, 0.005, 0.005*0.005, 1e-6, 1-1e-6 }; if (argc != 5) { bu_vls_printf(&result, "Usage: bn_isect_line2_line2 pt dir pt dir (%d args specified)", argc-1); goto error; } /* i = bn_isect_line2_line2 {0 0} {1 0} {1 1} {0 -1} */ VSETALL(pt, 0.0); VSETALL(dir, 0.0); VSETALL(a, 0.0); VSETALL(c, 0.0); if (bn_decode_vect(pt, argv[1]) < 2) { bu_vls_printf(&result, "bn_isect_line2_line2 no pt: %s\n", argv[0]); goto error; } if (bn_decode_vect(dir, argv[2]) < 2) { bu_vls_printf(&result, "bn_isect_line2_line2 no dir: %s\n", argv[0]); goto error; } if (bn_decode_vect(a, argv[3]) < 2) { bu_vls_printf(&result, "bn_isect_line2_line2 no a pt: %s\n", argv[0]); goto error; } if (bn_decode_vect(c, argv[4]) < 2) { bu_vls_printf(&result, "bn_isect_line2_line2 no c dir: %s\n", argv[0]); goto error; } i = bn_isect_line2_line2(dist, pt, dir, a, c, &tol); if (i != 1) { bu_vls_printf(&result, "bn_isect_line2_line2 no intersection: %s\n", argv[0]); goto error; } VJOIN1(a, pt, dist[0], dir); bu_vls_printf(&result, "%g %g", a[0], a[1]); } else { bu_vls_printf(&result, "libbn/bn_tcl.c: math function %s not supported yet\n", argv[0]); goto error; } Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); bu_vls_free(&result); return TCL_OK; error: Tcl_AppendResult(interp, bu_vls_addr(&result), (char *)NULL); bu_vls_free(&result); return TCL_ERROR; }
/** * make a copy of a v5 solid by adding it to our book-keeping list, * adding it to the db directory, and writing it out to disk. */ static void copy_v5_solid(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { size_t i; mat_t matrix; MAT_IDN(matrix); /* mirror */ if (state->miraxis != W) { matrix[state->miraxis*5] = -1.0; matrix[3 + state->miraxis*4] -= 2 * (matrix[3 + state->miraxis*4] - state->mirpos); } /* translate */ if (state->trans[W] > SMALL_FASTF) MAT_DELTAS_ADD_VEC(matrix, state->trans); /* rotation */ if (state->rot[W] > SMALL_FASTF) { mat_t m2, t; bn_mat_angles(m2, state->rot[X], state->rot[Y], state->rot[Z]); if (state->rpnt[W] > SMALL_FASTF) { mat_t m3; bn_mat_xform_about_pt(m3, m2, state->rpnt); bn_mat_mul(t, matrix, m3); } else bn_mat_mul(t, matrix, m2); MAT_COPY(matrix, t); } /* make n copies */ for (i = 0; i < state->n_copies; i++) { char *argv[6] = {"wdb_copy", (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL}; struct bu_vls *name; int ret; struct directory *dp = (struct directory *)NULL; struct rt_db_internal intern; if (i==0) dp = proto; else dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); /* get new name */ bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); /* actually copy the primitive to the new name */ argv[1] = proto->d_namep; argv[2] = bu_vls_addr(name); ret = wdb_copy_cmd(_dbip->dbi_wdbp, 3, (const char **)argv); if (ret != TCL_OK) bu_log("WARNING: failure cloning \"%s\" to \"%s\"\n", proto->d_namep, bu_vls_addr(name)); /* get the original objects matrix */ if (rt_db_get_internal(&intern, dp, _dbip, matrix, &rt_uniresource) < 0) { bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); bu_vls_free(name); return; } RT_CK_DB_INTERNAL(&intern); /* pull the new name */ dp = db_lookup(_dbip, bu_vls_addr(name), LOOKUP_QUIET); bu_vls_free(name); if (!dp) { bu_vls_free(name); continue; } /* write the new matrix to the new object */ if (rt_db_put_internal(dp, wdbp->dbip, &intern, &rt_uniresource) < 0) bu_log("ERROR: clone internal error copying %s\n", proto->d_namep); rt_db_free_internal(&intern); } /* end iteration over each copy */ return; }
/** * make a copy of a v4 solid by adding it to our book-keeping list, * adding it to the db directory, and writing it out to disk. */ static void copy_v4_solid(struct db_i *_dbip, struct directory *proto, struct clone_state *state, int idx) { struct directory *dp = (struct directory *)NULL; union record *rp = (union record *)NULL; size_t i, j; /* make n copies */ for (i = 0; i < state->n_copies; i++) { struct bu_vls *name; if (i==0) name = get_name(_dbip, proto, state, i); else { dp = db_lookup(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i-1]), LOOKUP_QUIET); if (!dp) { continue; } name = get_name(_dbip, dp, state, i); } /* XXX: this can probably be optimized. */ bu_vls_strcpy(&obj_list.names[idx].dest[i], bu_vls_addr(name)); bu_vls_free(name); /* add the object to the directory */ dp = db_diradd(_dbip, bu_vls_addr(&obj_list.names[idx].dest[i]), RT_DIR_PHONY_ADDR, proto->d_len, proto->d_flags, &proto->d_minor_type); if ((dp == RT_DIR_NULL) || (db_alloc(_dbip, dp, proto->d_len) < 0)) { TCL_ALLOC_ERR; return; } /* get an in-memory reference to the object being copied */ if ((rp = db_getmrec(_dbip, proto)) == (union record *)0) { TCL_READ_ERR; return; } if (rp->u_id == ID_SOLID) { bu_strlcpy(rp->s.s_name, dp->d_namep, NAMESIZE); /* mirror */ if (state->miraxis != W) { /* XXX er, this seems rather wrong .. but it's v4 so punt */ rp->s.s_values[state->miraxis] += 2 * (state->mirpos - rp->s.s_values[state->miraxis]); for (j = 3+state->miraxis; j < 24; j++) rp->s.s_values[j] = -rp->s.s_values[j]; } /* translate */ if (state->trans[W] > SMALL_FASTF) /* assumes primitive's first parameter is its position */ VADD2(rp->s.s_values, rp->s.s_values, state->trans); /* rotate */ if (state->rot[W] > SMALL_FASTF) { mat_t r; vect_t vec, ovec; if (state->rpnt[W] > SMALL_FASTF) VSUB2(rp->s.s_values, rp->s.s_values, state->rpnt); MAT_IDN(r); bn_mat_angles(r, state->rot[X], state->rot[Y], state->rot[Z]); for (j = 0; j < 24; j+=3) { VMOVE(vec, rp->s.s_values+j); MAT4X3VEC(ovec, r, vec); VMOVE(rp->s.s_values+j, ovec); } if (state->rpnt[W] > SMALL_FASTF) VADD2(rp->s.s_values, rp->s.s_values, state->rpnt); } } else bu_log("mods not available on %s\n", proto->d_namep); /* write the object to disk */ if (db_put(_dbip, dp, rp, 0, dp->d_len) < 0) { bu_log("ERROR: clone internal error writing to the database\n"); return; } } if (rp) bu_free((char *)rp, "copy_solid record[]"); return; }
/* * Returns - * -2 unknown keyword * -1 error in processing keyword * 0 OK */ int multi_words( char *words[], int nwords ) { if ( strcmp( words[0], "rot" ) == 0 ) { mat_t mat; /* Expects rotations rx, ry, rz, in degrees */ if ( nwords < 4 ) return(-1); MAT_IDN( mat ); bn_mat_angles( mat, atof( words[1] ), atof( words[2] ), atof( words[3] ) ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "xlate" ) == 0 ) { mat_t mat; if ( nwords < 4 ) return(-1); /* Expects translations tx, ty, tz */ MAT_IDN( mat ); MAT_DELTAS( mat, atof( words[1] ), atof( words[2] ), atof( words[3] ) ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "rot_at" ) == 0 ) { mat_t mat; mat_t mat1; mat_t mat2; mat_t mat3; /* JG - Expects x, y, z, rx, ry, rz */ /* Translation back to the origin by (-x, -y, -z) */ /* is done first, then the rotation, and finally */ /* back into the original position by (+x, +y, +z). */ if ( nwords < 7 ) return(-1); MAT_IDN( mat1 ); MAT_IDN( mat2 ); MAT_IDN( mat3 ); MAT_DELTAS( mat1, -atof( words[1] ), -atof( words[2] ), -atof( words[3] ) ); bn_mat_angles( mat2, atof( words[4] ), atof( words[5] ), atof( words[6] ) ); MAT_DELTAS( mat3, atof( words[1] ), atof( words[2] ), atof( words[3] ) ); bn_mat_mul( mat, mat2, mat1 ); bn_mat_mul2( mat3, mat ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "orient" ) == 0 ) { register int i; mat_t mat; double args[8]; /* Expects tx, ty, tz, rx, ry, rz, [scale]. */ /* All rotation is done first, then translation */ /* Note: word[0] and args[0] are the keyword */ if ( nwords < 6+1 ) return(-1); for ( i=1; i<6+1; i++ ) args[i] = 0; args[7] = 1.0; /* optional arg, default to 1 */ for ( i=1; i<nwords; i++ ) args[i] = atof( words[i] ); MAT_IDN( mat ); bn_mat_angles( mat, args[4], args[5], args[6] ); MAT_DELTAS( mat, args[1], args[2], args[3] ); if ( NEAR_ZERO( args[7], VDIVIDE_TOL ) ) { /* Nearly zero, signal error */ fprintf(stderr, "Orient scale arg is near zero ('%s')\n", words[7] ); return(-1); } else { mat[15] = 1 / args[7]; } out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "ae" ) == 0 ) { mat_t mat; fastf_t az, el; if ( nwords < 3 ) return(-1); /* Expects azimuth, elev, optional twist */ az = atof(words[1]); el = atof(words[2]); #if 0 if ( nwords == 3 ) twist = 0.0; else twist = atof(words[3]); #endif MAT_IDN( mat ); /* XXX does not take twist, for now XXX */ bn_mat_ae( mat, az, el ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "arb_rot_pt" ) == 0 ) { mat_t mat; point_t pt1, pt2; vect_t dir; fastf_t ang; if ( nwords < 1+3+3+1 ) return(-1); /* Expects point1, point2, angle */ VSET( pt1, atof(words[1]), atof(words[2]), atof(words[3]) ); VSET( pt2, atof(words[4]), atof(words[5]), atof(words[6]) ); ang = atof(words[7]) * bn_degtorad; VSUB2( dir, pt2, pt2 ); VUNITIZE(dir); MAT_IDN( mat ); bn_mat_arb_rot( mat, pt1, dir, ang ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "arb_rot_dir" ) == 0 ) { mat_t mat; point_t pt1; vect_t dir; fastf_t ang; if ( nwords < 1+3+3+1 ) return(-1); /* Expects point1, dir, angle */ VSET( pt1, atof(words[1]), atof(words[2]), atof(words[3]) ); VSET( dir, atof(words[4]), atof(words[5]), atof(words[6]) ); ang = atof(words[7]) * bn_degtorad; VUNITIZE(dir); MAT_IDN( mat ); bn_mat_arb_rot( mat, pt1, dir, ang ); out_mat( mat, stdout ); return(0); } if ( strcmp( words[0], "quat" ) == 0 ) { mat_t mat; quat_t quat; /* Usage: quat x, y, z, w */ if ( nwords < 5 ) return -1; QSET( quat, atof(words[1]), atof(words[2]), atof(words[3]), atof(words[4]) ); quat_quat2mat( mat, quat ); out_mat( mat, stdout); return 0; } if ( strcmp( words[0], "fromto" ) == 0 ) { mat_t mat; point_t cur; point_t next; vect_t from; vect_t to; /* Usage: fromto +Z cur_xyz next_xyz */ if ( nwords < 8 ) return -1; if ( strcmp( words[1], "+X" ) == 0 ) { VSET( from, 1, 0, 0 ); } else if ( strcmp( words[1], "-X" ) == 0 ) { VSET( from, -1, 0, 0 ); } else if ( strcmp( words[1], "+Y" ) == 0 ) { VSET( from, 0, 1, 0 ); } else if ( strcmp( words[1], "-Y" ) == 0 ) { VSET( from, 0, -1, 0 ); } else if ( strcmp( words[1], "+Z" ) == 0 ) { VSET( from, 0, 0, 1 ); } else if ( strcmp( words[1], "-Z" ) == 0 ) { VSET( from, 0, 0, -1 ); } else { fprintf(stderr, "fromto '%s' is not +/-XYZ\n", words[1]); return -1; } VSET( cur, atof(words[2]), atof(words[3]), atof(words[4]) ); VSET( next, atof(words[5]), atof(words[6]), atof(words[7]) ); VSUB2( to, next, cur ); VUNITIZE(to); bn_mat_fromto( mat, from, to ); /* Check to see if it worked. */ { vect_t got; MAT4X3VEC( got, mat, from ); if ( VDOT( got, to ) < 0.9 ) { bu_log("\ntabsub ERROR: At t=%s, bn_mat_fromto failed!\n", chanwords[0] ); VPRINT("\tfrom", from); VPRINT("\tto", to); VPRINT("\tgot", got); } } out_mat( mat, stdout ); return 0; } return(-2); /* Unknown keyword */ }
int ged_orotate(struct ged *gedp, int argc, const char *argv[]) { struct directory *dp; struct _ged_trace_data gtd; struct rt_db_internal intern; /* intentionally double for scan */ double xrot, yrot, zrot; mat_t rmat; mat_t pmat; mat_t emat; mat_t tmpMat; mat_t invXform; point_t rpp_min; point_t rpp_max; point_t keypoint; static const char *usage = "obj rX rY rZ [kX kY kZ]"; 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 && argc != 8) { bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); return GED_ERROR; } if (sscanf(argv[2], "%lf", &xrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rX value - %s", argv[0], argv[2]); return GED_ERROR; } if (sscanf(argv[3], "%lf", &yrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rY value - %s", argv[0], argv[3]); return GED_ERROR; } if (sscanf(argv[4], "%lf", &zrot) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad rZ value - %s", argv[0], argv[4]); return GED_ERROR; } if (argc == 5) { /* Use the object's center as the keypoint. */ 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; } VADD2(keypoint, rpp_min, rpp_max); VSCALE(keypoint, keypoint, 0.5); } else { double scan[3]; /* The user has provided the keypoint. */ MAT_IDN(gtd.gtd_xform); if (sscanf(argv[5], "%lf", &scan[X]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kX value - %s", argv[0], argv[5]); return GED_ERROR; } if (sscanf(argv[6], "%lf", &scan[Y]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kY value - %s", argv[0], argv[6]); return GED_ERROR; } if (sscanf(argv[7], "%lf", &scan[Z]) != 1) { bu_vls_printf(gedp->ged_result_str, "%s: bad kZ value - %s", argv[0], argv[7]); return GED_ERROR; } VSCALE(keypoint, scan, gedp->ged_wdbp->dbip->dbi_local2base); if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_QUIET)) == RT_DIR_NULL) { bu_vls_printf(gedp->ged_result_str, "%s: %s not found", argv[0], argv[1]); return GED_ERROR; } } bn_mat_angles(rmat, xrot, yrot, zrot); bn_mat_xform_about_pt(pmat, rmat, keypoint); bn_mat_inv(invXform, gtd.gtd_xform); bn_mat_mul(tmpMat, invXform, pmat); 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; }
int get_args(int argc, register char **argv) { register int c; mat_t tmp, m; int i, num; double mtmp[16]; MAT_IDN( rmat ); scale = 1.0; while ( (c = bu_getopt( argc, argv, "S:m:vMga:e:x:y:z:X:Y:Z:s:" )) != EOF ) { switch ( c ) { case 'M': /* take model RPP from space() command */ rpp++; Mflag = 1; /* don't rebound */ break; case 'g': bn_mat_angles( tmp, -90.0, 0.0, -90.0 ); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 'a': bn_mat_angles( tmp, 0.0, 0.0, -atof(bu_optarg) ); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); rpp++; break; case 'e': bn_mat_angles( tmp, 0.0, -atof(bu_optarg), 0.0 ); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); rpp++; break; case 'x': bn_mat_angles( tmp, atof(bu_optarg), 0.0, 0.0 ); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 'y': bn_mat_angles( tmp, 0.0, atof(bu_optarg), 0.0 ); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 'z': bn_mat_angles( tmp, 0.0, 0.0, atof(bu_optarg) ); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 'm': num = sscanf(&bu_optarg[0], "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &mtmp[0], &mtmp[1], &mtmp[2], &mtmp[3], &mtmp[4], &mtmp[5], &mtmp[6], &mtmp[7], &mtmp[8], &mtmp[9], &mtmp[10], &mtmp[11], &mtmp[12], &mtmp[13], &mtmp[14], &mtmp[15]); if ( num != 16) { fprintf(stderr, "Num of arguments to -m only %d, should be 16\n", num); bu_exit (1, NULL); } /* Now copy the array of doubles into mat. */ for (i=0; i < 16; i++ ) { rmat[i] = mtmp[i]; } break; case 'X': MAT_IDN( tmp ); tmp[MDX] = atof(bu_optarg); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 'Y': MAT_IDN( tmp ); tmp[MDY] = atof(bu_optarg); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 'Z': MAT_IDN( tmp ); tmp[MDZ] = atof(bu_optarg); MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); break; case 's': scale *= atof(bu_optarg); /* * If rpp flag has already been set, defer * application of scale until after the * xlate to space-center, in model_rpp(). * Otherwise, do it here, in the sequence * seen in the arg list. */ if ( !rpp ) { MAT_IDN( tmp ); tmp[15] = 1/scale; MAT_COPY( m, rmat ); bn_mat_mul( rmat, tmp, m ); scale = 1.0; } break; case 'v': verbose++; break; case 'S': num = sscanf(bu_optarg, "%lf %lf %lf %lf %lf %lf", &mtmp[0], &mtmp[1], &mtmp[2], &mtmp[3], &mtmp[4], &mtmp[5]); VSET(forced_space_min, mtmp[0], mtmp[1], mtmp[2]); VSET(forced_space_max, mtmp[3], mtmp[4], mtmp[5]); /* Write it now, in case input does not have one */ pdv_3space( stdout, forced_space_min, forced_space_max ); forced_space = 1; break; default: /* '?' */ return(0); /* Bad */ } } if ( isatty(fileno(stdout)) || (isatty(fileno(stdin)) && (bu_optind >= argc)) ) { return(0); /* Bad */ } return(1); /* OK */ }