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