コード例 #1
0
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;
}
コード例 #2
0
ファイル: symbol.c プロジェクト: cogitokat/brlcad
/*
 *			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 );
}
コード例 #3
0
ファイル: sh_wood.c プロジェクト: kanzure/brlcad
/*
 * 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);
}
コード例 #4
0
ファイル: bn_mat.c プロジェクト: kanzure/brlcad
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);
}
コード例 #5
0
ファイル: vutil.c プロジェクト: kanzure/brlcad
/**
 * 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);
}
コード例 #6
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);
}
コード例 #7
0
ファイル: protate.c プロジェクト: kanzure/brlcad
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;
}
コード例 #8
0
ファイル: bn_tcl.c プロジェクト: cciechad/brlcad
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;
}
コード例 #9
0
ファイル: clone.c プロジェクト: cogitokat/brlcad
/**
 * 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;
}
コード例 #10
0
ファイル: clone.c プロジェクト: cogitokat/brlcad
/**
 * 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;
}
コード例 #11
0
/*
 *  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 */
}
コード例 #12
0
ファイル: orotate.c プロジェクト: kanzure/brlcad
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, &gtd, 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;
}
コード例 #13
0
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 */
}