예제 #1
0
파일: vutil.c 프로젝트: kanzure/brlcad
int
_ged_do_tra(struct ged *gedp,
            char coord,
            vect_t tvec,
            int (*func)())
{
    point_t delta;
    point_t work;
    point_t vc, nvc;

    if (func != (int (*)())0)
        return (*func)(gedp, coord, tvec);

    switch (coord) {
    case 'm':
        VSCALE(delta, tvec, -gedp->ged_wdbp->dbip->dbi_base2local);
        MAT_DELTAS_GET_NEG(vc, gedp->ged_gvp->gv_center);
        break;
    case 'v':
    default:
        VSCALE(tvec, tvec, -2.0*gedp->ged_wdbp->dbip->dbi_base2local*gedp->ged_gvp->gv_isize);
        MAT4X3PNT(work, gedp->ged_gvp->gv_view2model, tvec);
        MAT_DELTAS_GET_NEG(vc, gedp->ged_gvp->gv_center);
        VSUB2(delta, work, vc);
        break;
    }

    VSUB2(nvc, vc, delta);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, nvc);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #2
0
int
ged_scale(struct ged *gedp, int argc, const char *argv[])
{
    int ret;
    fastf_t sf1;
    fastf_t sf2;
    fastf_t sf3;

    if ((ret = ged_scale_args(gedp, argc, argv, &sf1, &sf2, &sf3)) != GED_OK)
	return ret;

    if (argc != 2) {
	bu_vls_printf(gedp->ged_result_str, "Can not scale xyz independently on a view.");
	return GED_ERROR;
    }

    if (sf1 <= SMALL_FASTF || INFINITY < sf1)
	return GED_OK;

    /* scale the view */
    gedp->ged_gvp->gv_scale *= sf1;

    if (gedp->ged_gvp->gv_scale < RT_MINVIEWSIZE)
	gedp->ged_gvp->gv_scale = RT_MINVIEWSIZE;
    gedp->ged_gvp->gv_size = 2.0 * gedp->ged_gvp->gv_scale;
    gedp->ged_gvp->gv_isize = 1.0 / gedp->ged_gvp->gv_size;
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
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;
}
예제 #4
0
파일: vutil.c 프로젝트: kanzure/brlcad
int
_ged_do_slew(struct ged *gedp, vect_t svec)
{
    point_t model_center;

    MAT4X3PNT(model_center, gedp->ged_gvp->gv_view2model, svec);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, model_center);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #5
0
HIDDEN int
zoom(struct ged *gedp, double sf)
{
    gedp->ged_gvp->gv_scale /= sf;
    if (gedp->ged_gvp->gv_scale < RT_MINVIEWSCALE)
	gedp->ged_gvp->gv_scale = RT_MINVIEWSCALE;
    gedp->ged_gvp->gv_size = 2.0 * gedp->ged_gvp->gv_scale;
    gedp->ged_gvp->gv_isize = 1.0 / gedp->ged_gvp->gv_size;
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #6
0
파일: orient.c 프로젝트: cogitokat/brlcad
int
ged_orient(struct ged *gedp, int argc, const char *argv[])
{
    quat_t quat;
    static const char *usage = "quat";

    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 != 5) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    /* set view orientation */
    if (argc == 2) {
	if (bn_decode_quat(quat, argv[1]) != 4) {
	    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	    return GED_ERROR;
	}
    } else {
	int i;

	for (i = 1; i < 5; ++i) {
	    double scan;
	    if (sscanf(argv[i], "%lf", &scan) != 1) {
		bu_vls_printf(gedp->ged_result_str, "ged_orient: bad value - %s\n", argv[i-1]);
		return GED_ERROR;
	    }
	    /* convert from double to fastf_t */
	    quat[i-1] = scan;
	}
    }

    quat_quat2mat(gedp->ged_gvp->gv_rotation, quat);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #7
0
int
ged_size(struct ged *gedp, int argc, const char *argv[])
{
    /* intentionally double for scan */
    double size;
    static const char *usage = "[s]";

    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);

    /* get view size */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "%g",
		      gedp->ged_gvp->gv_size * gedp->ged_wdbp->dbip->dbi_base2local);
	return GED_OK;
    }

    /* set view size */
    if (argc == 2) {
	if (sscanf(argv[1], "%lf", &size) != 1
	    || size <= 0
	    || ZERO(size))
	{
	    bu_vls_printf(gedp->ged_result_str, "bad size - %s", argv[1]);
	    return GED_ERROR;
	}

	gedp->ged_gvp->gv_size = gedp->ged_wdbp->dbip->dbi_local2base * size;
	if (gedp->ged_gvp->gv_size < RT_MINVIEWSIZE)
	    gedp->ged_gvp->gv_size = RT_MINVIEWSIZE;
	gedp->ged_gvp->gv_isize = 1.0 / gedp->ged_gvp->gv_size;
	gedp->ged_gvp->gv_scale = 0.5 * gedp->ged_gvp->gv_size;
	ged_view_update(gedp->ged_gvp);

	return GED_OK;
    }

    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
    return GED_ERROR;
}
예제 #8
0
int
ged_perspective(struct ged *gedp, int argc, const char *argv[])
{
    /* intentionally double for scan */
    double perspective;
    static const char *usage = "[angle]";

    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);

    /* get the perspective angle */
    if (argc == 1) {
	bu_vls_printf(gedp->ged_result_str, "%g", gedp->ged_gvp->gv_perspective);
	return GED_OK;
    }

    /* set perspective angle */
    if (argc == 2) {
	if (sscanf(argv[1], "%lf", &perspective) != 1) {
	    bu_vls_printf(gedp->ged_result_str, "bad perspective angle - %s", argv[1]);
	    return GED_ERROR;
	}

	gedp->ged_gvp->gv_perspective = perspective;

	if (SMALL_FASTF < gedp->ged_gvp->gv_perspective) {
	    ged_persp_mat(gedp->ged_gvp->gv_pmat, gedp->ged_gvp->gv_perspective,
			  (fastf_t)1.0f, (fastf_t)0.01f, (fastf_t)1.0e10f, (fastf_t)1.0f);
	} else {
	    MAT_COPY(gedp->ged_gvp->gv_pmat, bn_mat_identity);
	}

	ged_view_update(gedp->ged_gvp);

	return GED_OK;
    }

    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
    return GED_ERROR;
}
예제 #9
0
파일: quat.c 프로젝트: cogitokat/brlcad
int
ged_quat(struct ged *gedp, int argc, const char *argv[])
{
    quat_t quat;
    double scan[4];
    static const char *usage = "a b c d";

    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);

    /* return Viewrot as a quaternion */
    if (argc == 1) {
	quat_mat2quat(quat, gedp->ged_gvp->gv_rotation);
	bu_vls_printf(gedp->ged_result_str, "%.12g %.12g %.12g %.12g", V4ARGS(quat));
	return GED_OK;
    }

    if (argc != 5) {
	bu_vls_printf(gedp->ged_result_str, "Usage: view %s %s", argv[0], usage);
	return GED_ERROR;
    }

    /* Set the view orientation given a quaternion */
    if (sscanf(argv[1], "%lf", &scan[0]) != 1
	|| sscanf(argv[2], "%lf", &scan[1]) != 1
	|| sscanf(argv[3], "%lf", &scan[2]) != 1
	|| sscanf(argv[4], "%lf", &scan[3]) != 1)
    {
	bu_vls_printf(gedp->ged_result_str, "view %s: bad value detected - %s %s %s %s",
		      argv[0], argv[1], argv[2], argv[3], argv[4]);
	return GED_ERROR;
    }
    HMOVE(quat, scan);

    quat_quat2mat(gedp->ged_gvp->gv_rotation, quat);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #10
0
파일: pov.c 프로젝트: cogitokat/brlcad
int
ged_pov(struct ged *gedp, int argc, const char *argv[])
{
    vect_t center;
    quat_t quat;
    vect_t eye_pos;

    /* intentionally double for scan */
    double scale;
    double perspective;

    static const char *usage = "center quat scale eye_pos perspective";

    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 != 6) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    }

    /***************** Get the arguments *******************/

    if (bn_decode_vect(center, argv[1]) != 3) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad center - %s\n", argv[1]);
	return TCL_ERROR;
    }

    if (bn_decode_quat(quat, argv[2]) != 4) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad quat - %s\n", argv[2]);
	return TCL_ERROR;
    }

    if (sscanf(argv[3], "%lf", &scale) != 1) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad scale - %s\n", argv[3]);
	return TCL_ERROR;
    }

    if (bn_decode_vect(eye_pos, argv[4]) != 3) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad eye position - %s\n", argv[4]);
	return TCL_ERROR;
    }

    if (sscanf(argv[5], "%lf", &perspective) != 1) {
	bu_vls_printf(gedp->ged_result_str, "ged_pov: bad perspective - %s\n", argv[5]);
	return TCL_ERROR;
    }

    /***************** Use the arguments *******************/

    VSCALE(center, center, gedp->ged_wdbp->dbip->dbi_local2base);
    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, center);
    quat_quat2mat(gedp->ged_gvp->gv_rotation, quat);
    gedp->ged_gvp->gv_scale = gedp->ged_wdbp->dbip->dbi_local2base * scale;
    VSCALE(eye_pos, eye_pos, gedp->ged_wdbp->dbip->dbi_local2base);
    VMOVE(gedp->ged_gvp->gv_eye_pos, eye_pos);
    gedp->ged_gvp->gv_perspective = perspective;

    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #11
0
파일: vutil.c 프로젝트: kanzure/brlcad
int
_ged_do_rot(struct ged *gedp,
            char coord,
            mat_t rmat,
            int (*func)())
{
    mat_t temp1, temp2;

    if (func != (int (*)())0)
        return (*func)(gedp, coord, gedp->ged_gvp->gv_rotate_about, rmat);

    switch (coord) {
    case 'm':
        /* transform model rotations into view rotations */
        bn_mat_inv(temp1, gedp->ged_gvp->gv_rotation);
        bn_mat_mul(temp2, gedp->ged_gvp->gv_rotation, rmat);
        bn_mat_mul(rmat, temp2, temp1);
        break;
    case 'v':
    default:
        break;
    }

    /* Calculate new view center */
    if (gedp->ged_gvp->gv_rotate_about != 'v') {
        point_t rot_pt;
        point_t new_origin;
        mat_t viewchg, viewchginv;
        point_t new_cent_view;
        point_t new_cent_model;

        switch (gedp->ged_gvp->gv_rotate_about) {
        case 'e':
            VSET(rot_pt, 0.0, 0.0, 1.0);
            break;
        case 'k':
            MAT4X3PNT(rot_pt, gedp->ged_gvp->gv_model2view, gedp->ged_gvp->gv_keypoint);
            break;
        case 'm':
            /* rotate around model center (0, 0, 0) */
            VSET(new_origin, 0.0, 0.0, 0.0);
            MAT4X3PNT(rot_pt, gedp->ged_gvp->gv_model2view, new_origin);
            break;
        default:
            return GED_ERROR;
        }

        bn_mat_xform_about_pt(viewchg, rmat, rot_pt);
        bn_mat_inv(viewchginv, viewchg);

        /* Convert origin in new (viewchg) coords back to old view coords */
        VSET(new_origin, 0.0, 0.0, 0.0);
        MAT4X3PNT(new_cent_view, viewchginv, new_origin);
        MAT4X3PNT(new_cent_model, gedp->ged_gvp->gv_view2model, new_cent_view);
        MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, new_cent_model);
    }

    /* pure rotation */
    bn_mat_mul2(rmat, gedp->ged_gvp->gv_rotation);
    ged_view_update(gedp->ged_gvp);

    return GED_OK;
}
예제 #12
0
파일: mirror.c 프로젝트: kanzure/brlcad
int
ged_mirror(struct ged *gedp, int argc, const char *argv[])
{
    /* trailing x|y|z intentionally not documented */
    static const char *usage = "[-h] [-p \"point\"] [-d \"dir\"] [-x|-y|-z] [-o offset] old new";

    int k;

    point_t mirror_pt = {0.0, 0.0, 0.0};
    vect_t mirror_dir = {1.0, 0.0, 0.0};

    /* intentionally double for scanning */
    double scanpt[3];
    double scandir[3];
    double mirror_offset = 0.0;

    int ret;
    struct rt_db_internal *ip;
    struct rt_db_internal internal;
    struct directory *dp;

    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;
    }

    bu_optind = 1;
    while ((k = bu_getopt(argc, (char * const *)argv, (const char *)"d:D:hHo:O:p:P:xXyYzZ")) != -1) {
	switch (k) {
	    case 'p':
	    case 'P':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scanpt[X],
			   &scanpt[Y],
			   &scanpt[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}

		/* convert from double to fastf_t */
		VMOVE(mirror_pt, scanpt);

		break;
	    case 'd':
	    case 'D':
		if (sscanf(bu_optarg, "%lf %lf %lf",
			   &scandir[X],
			   &scandir[Y],
			   &scandir[Z]) != 3) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}

		/* convert from double to fastf_t */
		VMOVE(mirror_dir, scandir);

		break;
	    case 'o':
	    case 'O':
		if (sscanf(bu_optarg, "%lf", &mirror_offset) != 1) {
		    bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		    return GED_ERROR;
		}
		break;
	    case 'x':
	    case 'X':
		VSET(mirror_dir, 1.0, 0.0, 0.0);
		break;
	    case 'y':
	    case 'Y':
		VSET(mirror_dir, 0.0, 1.0, 0.0);
		break;
	    case 'z':
	    case 'Z':
		VSET(mirror_dir, 0.0, 0.0, 1.0);
		break;
	    case 'h':
	    case 'H':
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_HELP;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
		break;
	}
    }

    argc -= bu_optind;

    if (argc < 2 || argc > 4) {
	bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
	return GED_ERROR;
    } else if (argc == 3) {
	/* support a trailing x|y|z option as classic command
	 * behavior.  THIS IS INTENTIONALLY UNDOCUMENTED.  if users
	 * have to read the usage, they can learn the new form.
	 */
	switch (argv[bu_optind+2][0]) {
	    case 'x':
	    case 'X':
		VSET(mirror_dir, 1.0, 0.0, 0.0);
		break;
	    case 'y':
	    case 'Y':
		VSET(mirror_dir, 0.0, 1.0, 0.0);
		break;
	    case 'z':
	    case 'Z':
		VSET(mirror_dir, 0.0, 0.0, 1.0);
		break;
	    default:
		bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
		return GED_ERROR;
		break;
	}
    }

    /* make sure object mirroring to does not already exist */
    if (db_lookup(gedp->ged_wdbp->dbip, argv[bu_optind+1], LOOKUP_QUIET) != RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "%s already exists\n", argv[bu_optind+1]);
	return GED_ERROR;
    }

    /* look up the object being mirrored */
    if ((dp = db_lookup(gedp->ged_wdbp->dbip, argv[bu_optind], LOOKUP_NOISY)) == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to find solid [%s]\n", argv[bu_optind]);
	return GED_ERROR;
    }

    /* get object being mirrored */
    ret = rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip, NULL, gedp->ged_wdbp->wdb_resp);
    if (ret < 0) {
	bu_vls_printf(gedp->ged_result_str, "Unable to load solid [%s]\n", argv[bu_optind]);
	return GED_ERROR;
    }

    mirror_offset *= gedp->ged_wdbp->dbip->dbi_local2base;
    VUNITIZE(mirror_dir);
    VJOIN1(mirror_pt, mirror_pt, mirror_offset, mirror_dir);

    /* mirror the object */
    ip = rt_mirror(gedp->ged_wdbp->dbip,
		   &internal,
		   mirror_pt,
		   mirror_dir,
		   gedp->ged_wdbp->wdb_resp);
    if (ip == NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to mirror [%s]", argv[bu_optind]);
	return GED_ERROR;
    }

    /* add the mirrored object to the directory */
    dp = db_diradd(gedp->ged_wdbp->dbip, argv[bu_optind+1], RT_DIR_PHONY_ADDR, 0, dp->d_flags, (void *)&ip->idb_type);
    if (dp == RT_DIR_NULL) {
	bu_vls_printf(gedp->ged_result_str, "Unable to add [%s] to the database directory", argv[bu_optind+1]);
	return GED_ERROR;
    }
    /* save the mirrored object to disk */
    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, gedp->ged_wdbp->wdb_resp) < 0) {
	bu_vls_printf(gedp->ged_result_str, "Unable to store [%s] to the database", argv[bu_optind+1]);
	return GED_ERROR;
    }

    {
	/* draw the new object */
	const char *object = (const char *)argv[bu_optind+1];
	const char *e_argv[3] = {0, 0, 0};

	e_argv[0] = "draw";
	e_argv[1] = object;
	e_argv[2] = NULL;

	(void)ged_draw(gedp, 2, e_argv);
	ged_view_update(gedp->ged_gvp);
    }

    return GED_OK;
}