Revision: 76336 http://sourceforge.net/p/brlcad/code/76336 Author: starseeker Date: 2020-07-14 20:46:34 +0000 (Tue, 14 Jul 2020) Log Message: ----------- Group mouse related functions
Modified Paths: -------------- brlcad/trunk/src/libtclcad/CMakeLists.txt brlcad/trunk/src/libtclcad/tclcad_obj.c brlcad/trunk/src/libtclcad/tclcad_private.h brlcad/trunk/src/libtclcad/tclcad_views.c Added Paths: ----------- brlcad/trunk/src/libtclcad/tclcad_mouse.c Modified: brlcad/trunk/src/libtclcad/CMakeLists.txt =================================================================== --- brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 20:18:22 UTC (rev 76335) +++ brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 20:46:34 UTC (rev 76336) @@ -8,6 +8,7 @@ tclcad_obj_wrapper.c tclcad_eval.c tclcad_init.c + tclcad_mouse.c tclcad_views.c tkImgFmtPIX.c cmdhist_obj.c Added: brlcad/trunk/src/libtclcad/tclcad_mouse.c =================================================================== --- brlcad/trunk/src/libtclcad/tclcad_mouse.c (rev 0) +++ brlcad/trunk/src/libtclcad/tclcad_mouse.c 2020-07-14 20:46:34 UTC (rev 76336) @@ -0,0 +1,3693 @@ +/* T C L C A D _ M O U S E . C + * BRL-CAD + * + * Copyright (c) 2000-2020 United States Government as represented by + * the U.S. Army Research Laboratory. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; see the file named COPYING for more + * information. + */ +/** @addtogroup libtclcad */ +/** @{ */ +/** @file libtclcad/tclcad_mouse.c + * + */ +/** @} */ + +#include "common.h" + +#include "bu/path.h" +#include "tclcad.h" + +/* Private headers */ +#include "tclcad_private.h" + +int +to_get_prev_mouse(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + + /* 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) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + bu_vls_printf(gedp->ged_result_str, "%d %d", (int)gdvp->gdv_view->gv_prevMouseX, (int)gdvp->gdv_view->gv_prevMouseY); + return GED_OK; +} + + +int +to_mouse_append_pnt_common(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr func, + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + char *av[4]; + point_t view; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + x = screen_to_view_x(gdvp->gdv_dmp, x); + y = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(view, x, y, 0.0); + + gedp->ged_gvp = gdvp->gdv_view; + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &view[X], &view[Y]); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &view[X], &view[Y]); + } + + bu_vls_printf(&pt_vls, "%lf %lf %lf", view[X], view[Y], view[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = (char *)argv[0]; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&pt_vls); + av[3] = (char *)0; + + ret = (*func)(gedp, 3, (const char **)av); + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_brep_selection_append(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int maxargs) +{ + const char *cmd_argv[11] = {"brep", NULL, "selection", "append", "active"}; + int ret, cmd_argc = (int)(sizeof(cmd_argv) / sizeof(const char *)); + struct ged_dm_view *gdvp; + char *brep_name; + char *end; + struct bu_vls bindings = BU_VLS_INIT_ZERO; + struct bu_vls start[] = {BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO}; + struct bu_vls dir[] = {BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO}; + point_t screen_pt, view_pt, model_pt; + vect_t view_dir, model_dir; + mat_t invRot; + + if (argc != maxargs) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + /* parse args */ + brep_name = bu_path_basename(argv[2], NULL); + + screen_pt[X] = strtol(argv[3], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad x value %f\n", screen_pt[X]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + screen_pt[Y] = strtol(argv[4], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad y value: %f\n", screen_pt[Y]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* stash point coordinates for future drag handling */ + gdvp->gdv_view->gv_prevMouseX = screen_pt[X]; + gdvp->gdv_view->gv_prevMouseY = screen_pt[Y]; + + /* convert screen point to model-space start point and direction */ + view_pt[X] = screen_to_view_x(gdvp->gdv_dmp, screen_pt[X]); + view_pt[Y] = screen_to_view_y(gdvp->gdv_dmp, screen_pt[Y]); + view_pt[Z] = 1.0; + + MAT4X3PNT(model_pt, gdvp->gdv_view->gv_view2model, view_pt); + + VSET(view_dir, 0.0, 0.0, -1.0); + bn_mat_inv(invRot, gedp->ged_gvp->gv_rotation); + MAT4X3PNT(model_dir, invRot, view_dir); + + /* brep brep_name selection append selection_name startx starty startz dirx diry dirz */ + bu_vls_printf(&start[X], "%f", model_pt[X]); + bu_vls_printf(&start[Y], "%f", model_pt[Y]); + bu_vls_printf(&start[Z], "%f", model_pt[Z]); + + cmd_argv[1] = brep_name; + cmd_argv[5] = bu_vls_addr(&start[X]); + cmd_argv[6] = bu_vls_addr(&start[Y]); + cmd_argv[7] = bu_vls_addr(&start[Z]); + + bu_vls_printf(&dir[X], "%f", model_dir[X]); + bu_vls_printf(&dir[Y], "%f", model_dir[Y]); + bu_vls_printf(&dir[Z], "%f", model_dir[Z]); + + cmd_argv[8] = bu_vls_addr(&dir[X]); + cmd_argv[9] = bu_vls_addr(&dir[Y]); + cmd_argv[10] = bu_vls_addr(&dir[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + ret = ged_brep(gedp, cmd_argc, cmd_argv); + + bu_vls_free(&start[X]); + bu_vls_free(&start[Y]); + bu_vls_free(&start[Z]); + bu_vls_free(&dir[X]); + bu_vls_free(&dir[Y]); + bu_vls_free(&dir[Z]); + + if (ret != GED_OK) { + return GED_ERROR; + } + + if (dm_get_pathname(gdvp->gdv_dmp)) { + bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_brep_selection_translate %s %s %%x %%y; " + "%s brep %s plot SCV}", + bu_vls_addr(dm_get_pathname(gdvp->gdv_dmp)), + bu_vls_addr(¤t_top->to_gop->go_name), + bu_vls_addr(&gdvp->gdv_name), + brep_name, + bu_vls_addr(¤t_top->to_gop->go_name), + brep_name); + Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); + } + bu_vls_free(&bindings); + + bu_free((void *)brep_name, "brep_name"); + + return GED_OK; +} + + +int +to_mouse_brep_selection_translate(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int maxargs) +{ + const char *cmd_argv[8] = {"brep", NULL, "selection", "translate", "active"}; + int ret, cmd_argc = (int)(sizeof(cmd_argv) / sizeof(const char *)); + struct ged_dm_view *gdvp; + char *brep_name; + char *end; + point_t screen_end, view_start, view_end, model_start, model_end; + vect_t model_delta; + struct bu_vls delta[] = {BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO}; + + if (argc != maxargs) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + brep_name = bu_path_basename(argv[2], NULL); + + screen_end[X] = strtol(argv[3], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad x value %f\n", screen_end[X]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + screen_end[Y] = strtol(argv[4], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad y value: %f\n", screen_end[Y]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* convert screen-space delta to model-space delta */ + view_start[X] = screen_to_view_x(gdvp->gdv_dmp, gdvp->gdv_view->gv_prevMouseX); + view_start[Y] = screen_to_view_y(gdvp->gdv_dmp, gdvp->gdv_view->gv_prevMouseY); + view_start[Z] = 1; + MAT4X3PNT(model_start, gdvp->gdv_view->gv_view2model, view_start); + + view_end[X] = screen_to_view_x(gdvp->gdv_dmp, screen_end[X]); + view_end[Y] = screen_to_view_y(gdvp->gdv_dmp, screen_end[Y]); + view_end[Z] = 1; + MAT4X3PNT(model_end, gdvp->gdv_view->gv_view2model, view_end); + + VSUB2(model_delta, model_end, model_start); + + bu_vls_printf(&delta[X], "%f", model_delta[X]); + bu_vls_printf(&delta[Y], "%f", model_delta[Y]); + bu_vls_printf(&delta[Z], "%f", model_delta[Z]); + + cmd_argv[1] = brep_name; + cmd_argv[5] = bu_vls_addr(&delta[X]); + cmd_argv[6] = bu_vls_addr(&delta[Y]); + cmd_argv[7] = bu_vls_addr(&delta[Z]); + + ret = ged_brep(gedp, cmd_argc, cmd_argv); + + bu_free((void *)brep_name, "brep_name"); + bu_vls_free(&delta[X]); + bu_vls_free(&delta[Y]); + bu_vls_free(&delta[Z]); + + if (ret != GED_OK) { + return GED_ERROR; + } + + /* need to tell front-end that we've modified the db */ + tclcad_eval_noresult(current_top->to_interp, "$::ArcherCore::application setSave", 0, NULL); + + gdvp->gdv_view->gv_prevMouseX = screen_end[X]; + gdvp->gdv_view->gv_prevMouseY = screen_end[Y]; + + cmd_argc = 2; + cmd_argv[0] = "draw"; + cmd_argv[1] = argv[2]; + cmd_argv[2] = NULL; + ret = to_edit_redraw(gedp, cmd_argc, cmd_argv); + + return ret; +} + + +int +to_mouse_constrain_rot(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + int ac; + char *av[4]; + fastf_t dx, dy; + fastf_t sf; + struct bu_vls rot_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if ((argv[2][0] != 'x' && argv[2][0] != 'y' && argv[2][0] != 'z') || argv[2][1] != '\0') { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + dx *= gdvp->gdv_view->gv_rscale; + dy *= gdvp->gdv_view->gv_rscale; + + if (fabs(dx) > fabs(dy)) + sf = dx; + else + sf = dy; + + switch (argv[2][0]) { + case 'x': + bu_vls_printf(&rot_vls, "%lf 0 0", -sf); + break; + case 'y': + bu_vls_printf(&rot_vls, "0 %lf 0", -sf); + break; + case 'z': + bu_vls_printf(&rot_vls, "0 0 %lf", -sf); + } + + gedp->ged_gvp = gdvp->gdv_view; + ac = 3; + av[0] = "rot"; + av[1] = "-m"; + av[2] = bu_vls_addr(&rot_vls); + av[3] = (char *)0; + + ret = ged_rot(gedp, ac, (const char **)av); + bu_vls_free(&rot_vls); + + if (ret == GED_OK) { + if (0 < bu_vls_strlen(&gdvp->gdv_callback)) { + tclcad_eval_noresult(current_top->to_interp, bu_vls_addr(&gdvp->gdv_callback), 0, NULL); + } + + to_refresh_view(gdvp); + } + + return GED_OK; +} + + +int +to_mouse_constrain_trans(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int width; + int ret; + int ac; + char *av[4]; + fastf_t dx, dy; + fastf_t sf; + fastf_t inv_width; + struct bu_vls tran_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if ((argv[2][0] != 'x' && argv[2][0] != 'y' && argv[2][0] != 'z') || argv[2][1] != '\0') { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_local2base; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_local2base; + + if (fabs(dx) > fabs(dy)) + sf = dx; + else + sf = dy; + + switch (argv[2][0]) { + case 'x': + bu_vls_printf(&tran_vls, "%lf 0 0", -sf); + break; + case 'y': + bu_vls_printf(&tran_vls, "0 %lf 0", -sf); + break; + case 'z': + bu_vls_printf(&tran_vls, "0 0 %lf", -sf); + } + + gedp->ged_gvp = gdvp->gdv_view; + ac = 3; + av[0] = "tra"; + av[1] = "-m"; + av[2] = bu_vls_addr(&tran_vls); + av[3] = (char *)0; + + ret = ged_tra(gedp, ac, (const char **)av); + bu_vls_free(&tran_vls); + + if (ret == GED_OK) { + if (0 < bu_vls_strlen(&gdvp->gdv_callback)) { + tclcad_eval_noresult(current_top->to_interp, bu_vls_addr(&gdvp->gdv_callback), 0, NULL); + } + + to_refresh_view(gdvp); + } + + return GED_OK; +} + + +int +to_mouse_find_arb_edge(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + char *av[6]; + point_t view; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + x = screen_to_view_x(gdvp->gdv_dmp, x); + y = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(view, x, y, 0.0); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", view[X], view[Y], view[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "find_arb_edge_nearest_pnt"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&pt_vls); + av[3] = (char *)argv[5]; + av[4] = (char *)0; + + (void)ged_find_arb_edge_nearest_pnt(gedp, 4, (const char **)av); + bu_vls_free(&pt_vls); + + return GED_OK; +} + + +int +to_mouse_find_bot_edge(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + char *av[6]; + point_t view; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + x = screen_to_view_x(gdvp->gdv_dmp, x); + y = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(view, x, y, 0.0); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", view[X], view[Y], view[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "find_bot_edge_nearest_pnt"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&pt_vls); + av[3] = (char *)0; + + (void)ged_find_bot_edge_nearest_pnt(gedp, 3, (const char **)av); + bu_vls_free(&pt_vls); + + return GED_OK; +} + + +int +to_mouse_find_bot_pnt(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + char *av[6]; + point_t view; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + x = screen_to_view_x(gdvp->gdv_dmp, x); + y = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(view, x, y, 0.0); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", view[X], view[Y], view[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "find_bot_pnt_nearest_pnt"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&pt_vls); + av[3] = (char *)0; + + (void)ged_find_bot_pnt_nearest_pnt(gedp, 3, (const char **)av); + bu_vls_free(&pt_vls); + + return GED_OK; +} + + +int +to_mouse_find_metaball_pnt(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + char *av[6]; + point_t model; + point_t view; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + x = screen_to_view_x(gdvp->gdv_dmp, x); + y = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(view, x, y, 0.0); + MAT4X3PNT(model, gdvp->gdv_view->gv_view2model, view); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "find_metaball_pnt_nearest_pnt"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&pt_vls); + av[3] = (char *)0; + + (void)ged_find_metaball_pnt_nearest_pnt(gedp, 3, (const char **)av); + bu_vls_free(&pt_vls); + + return GED_OK; +} + + +int +to_mouse_find_pipe_pnt(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + char *av[6]; + point_t model; + point_t view; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + x = screen_to_view_x(gdvp->gdv_dmp, x); + y = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(view, x, y, 0.0); + MAT4X3PNT(model, gdvp->gdv_view->gv_view2model, view); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "find_pipe_pnt_nearest_pnt"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&pt_vls); + av[3] = (char *)0; + + (void)ged_find_pipe_pnt_nearest_pnt(gedp, 3, (const char **)av); + bu_vls_free(&pt_vls); + + return GED_OK; +} + + +int +to_mouse_joint_select( + struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int maxargs) +{ + const char *cmd_argv[11] = {"joint2", NULL, "selection", "replace", "active"}; + int ret, cmd_argc = (int)(sizeof(cmd_argv) / sizeof(const char *)); + struct ged_dm_view *gdvp; + char *joint_name; + char *end; + struct bu_vls bindings = BU_VLS_INIT_ZERO; + struct bu_vls start[] = {BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO}; + struct bu_vls dir[] = {BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO}; + point_t screen_pt, view_pt, model_pt; + vect_t view_dir, model_dir; + mat_t invRot; + + if (argc != maxargs) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + /* parse args */ + joint_name = bu_path_basename(argv[2], NULL); + + screen_pt[X] = strtol(argv[3], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad x value %f\n", screen_pt[X]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + screen_pt[Y] = strtol(argv[4], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad y value: %f\n", screen_pt[Y]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* stash point coordinates for future drag handling */ + gdvp->gdv_view->gv_prevMouseX = screen_pt[X]; + gdvp->gdv_view->gv_prevMouseY = screen_pt[Y]; + + /* convert screen point to model-space start point and direction */ + view_pt[X] = screen_to_view_x(gdvp->gdv_dmp, screen_pt[X]); + view_pt[Y] = screen_to_view_y(gdvp->gdv_dmp, screen_pt[Y]); + view_pt[Z] = 1.0; + + MAT4X3PNT(model_pt, gdvp->gdv_view->gv_view2model, view_pt); + + VSET(view_dir, 0.0, 0.0, -1.0); + bn_mat_inv(invRot, gedp->ged_gvp->gv_rotation); + MAT4X3PNT(model_dir, invRot, view_dir); + + /* joint2 joint_name selection append selection_name startx starty startz dirx diry dirz */ + bu_vls_printf(&start[X], "%f", model_pt[X]); + bu_vls_printf(&start[Y], "%f", model_pt[Y]); + bu_vls_printf(&start[Z], "%f", model_pt[Z]); + + cmd_argv[1] = joint_name; + cmd_argv[5] = bu_vls_addr(&start[X]); + cmd_argv[6] = bu_vls_addr(&start[Y]); + cmd_argv[7] = bu_vls_addr(&start[Z]); + + bu_vls_printf(&dir[X], "%f", model_dir[X]); + bu_vls_printf(&dir[Y], "%f", model_dir[Y]); + bu_vls_printf(&dir[Z], "%f", model_dir[Z]); + + cmd_argv[8] = bu_vls_addr(&dir[X]); + cmd_argv[9] = bu_vls_addr(&dir[Y]); + cmd_argv[10] = bu_vls_addr(&dir[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + ret = ged_joint2(gedp, cmd_argc, cmd_argv); + + bu_vls_free(&start[X]); + bu_vls_free(&start[Y]); + bu_vls_free(&start[Z]); + bu_vls_free(&dir[X]); + bu_vls_free(&dir[Y]); + bu_vls_free(&dir[Z]); + + if (ret != GED_OK) { + return GED_ERROR; + } + + if (dm_get_pathname(gdvp->gdv_dmp)) { + bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_joint_selection_translate %s %s %%x %%y}", + bu_vls_addr(dm_get_pathname(gdvp->gdv_dmp)), + bu_vls_addr(¤t_top->to_gop->go_name), + bu_vls_addr(&gdvp->gdv_name), + joint_name); + Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); + } + bu_vls_free(&bindings); + + bu_free((void *)joint_name, "joint_name"); + + return GED_OK; +} + + +int +to_mouse_joint_selection_translate( + struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int maxargs) +{ + const char *cmd_argv[8] = {"joint2", NULL, "selection", "translate", "active"}; + int ret, cmd_argc = (int)(sizeof(cmd_argv) / sizeof(const char *)); + struct ged_dm_view *gdvp; + char *joint_name; + char *end; + point_t screen_end, view_start, view_end, model_start, model_end; + vect_t model_delta; + struct bu_vls delta[] = {BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO, BU_VLS_INIT_ZERO}; + + if (argc != maxargs) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + joint_name = bu_path_basename(argv[2], NULL); + + screen_end[X] = strtol(argv[3], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad x value %f\n", screen_end[X]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + screen_end[Y] = strtol(argv[4], &end, 10); + if (*end != '\0') { + bu_vls_printf(gedp->ged_result_str, "ERROR: bad y value: %f\n", screen_end[Y]); + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* convert screen-space delta to model-space delta */ + view_start[X] = screen_to_view_x(gdvp->gdv_dmp, gdvp->gdv_view->gv_prevMouseX); + view_start[Y] = screen_to_view_y(gdvp->gdv_dmp, gdvp->gdv_view->gv_prevMouseY); + view_start[Z] = 1; + MAT4X3PNT(model_start, gdvp->gdv_view->gv_view2model, view_start); + + view_end[X] = screen_to_view_x(gdvp->gdv_dmp, screen_end[X]); + view_end[Y] = screen_to_view_y(gdvp->gdv_dmp, screen_end[Y]); + view_end[Z] = 1; + MAT4X3PNT(model_end, gdvp->gdv_view->gv_view2model, view_end); + + VSUB2(model_delta, model_end, model_start); + + bu_vls_printf(&delta[X], "%f", model_delta[X]); + bu_vls_printf(&delta[Y], "%f", model_delta[Y]); + bu_vls_printf(&delta[Z], "%f", model_delta[Z]); + + cmd_argv[1] = joint_name; + cmd_argv[5] = bu_vls_addr(&delta[X]); + cmd_argv[6] = bu_vls_addr(&delta[Y]); + cmd_argv[7] = bu_vls_addr(&delta[Z]); + + ret = ged_joint2(gedp, cmd_argc, cmd_argv); + + if (ret != GED_OK) { + bu_free((void *)joint_name, "joint_name"); + bu_vls_free(&delta[X]); + bu_vls_free(&delta[Y]); + bu_vls_free(&delta[Z]); + return GED_ERROR; + } + + /* need to tell front-end that we've modified the db */ + Tcl_Eval(current_top->to_interp, "$::ArcherCore::application setSave"); + + gdvp->gdv_view->gv_prevMouseX = screen_end[X]; + gdvp->gdv_view->gv_prevMouseY = screen_end[Y]; + + cmd_argc = 3; + cmd_argv[0] = "get"; + cmd_argv[1] = joint_name; + cmd_argv[2] = "RP1"; + cmd_argv[3] = NULL; + ret = ged_get(gedp, cmd_argc, cmd_argv); + + if (ret == GED_OK) { + char *path_name = bu_strdup(bu_vls_cstr(gedp->ged_result_str)); + int dmode = 0; + struct bu_vls path_dmode = BU_VLS_INIT_ZERO; + + /* get current display mode of path */ + cmd_argc = 2; + cmd_argv[0] = "how"; + cmd_argv[1] = path_name; + cmd_argv[2] = NULL; + ret = ged_how(gedp, cmd_argc, cmd_argv); + + if (ret == GED_OK) { + ret = bu_sscanf(bu_vls_cstr(gedp->ged_result_str), "%d", &dmode); + } + if (dmode == 4) { + bu_vls_printf(&path_dmode, "-h"); + } else { + bu_vls_printf(&path_dmode, "-m%d", dmode); + } + + /* erase path to split it from visible vlists */ + cmd_argc = 2; + cmd_argv[0] = "erase"; + cmd_argv[1] = path_name; + cmd_argv[2] = NULL; + ret = ged_erase(gedp, cmd_argc, cmd_argv); + + if (ret == GED_OK) { + /* redraw path with its previous display mode */ + cmd_argc = 4; + cmd_argv[0] = "draw"; + cmd_argv[1] = "-R"; + cmd_argv[2] = bu_vls_cstr(&path_dmode); + cmd_argv[3] = path_name; + cmd_argv[4] = NULL; + ret = ged_draw(gedp, cmd_argc, cmd_argv); + + to_refresh_all_views(current_top); + } + bu_vls_free(&path_dmode); + bu_free(path_name, "path_name"); + } + + bu_free((void *)joint_name, "joint_name"); + bu_vls_free(&delta[X]); + bu_vls_free(&delta[Y]); + bu_vls_free(&delta[Z]); + + return ret; +} + + +int +to_mouse_move_arb_edge(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int width; + int ret; + char *av[6]; + fastf_t dx, dy; + fastf_t inv_width; + point_t model; + point_t view; + mat_t inv_rot; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + /* ged_move_arb_edge expects things to be in local units */ + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "move_arb_edge"; + av[1] = "-r"; + av[2] = (char *)argv[2]; + av[3] = (char *)argv[3]; + av[4] = bu_vls_addr(&pt_vls); + av[5] = (char *)0; + + ret = ged_move_arb_edge(gedp, 5, (const char **)av); + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_move_arb_face(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int width; + int ret; + char *av[6]; + fastf_t dx, dy; + fastf_t inv_width; + point_t model; + point_t view; + mat_t inv_rot; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + /* ged_move_arb_face expects things to be in local units */ + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "move_arb_face"; + av[1] = "-r"; + av[2] = (char *)argv[2]; + av[3] = (char *)argv[3]; + av[4] = bu_vls_addr(&pt_vls); + av[5] = (char *)0; + + ret = ged_move_arb_face(gedp, 5, (const char **)av); + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_move_bot_pnt(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int width; + int ret; + int rflag; + char *av[6]; + const char *cmd; + fastf_t dx, dy, dz; + fastf_t inv_width; + point_t model; + point_t view; + mat_t v2m_mat; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + cmd = argv[0]; + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_HELP; + } + + if (argc == 7) { + if (argv[1][0] != '-' || argv[1][1] != 'r' || argv[1][2] != '\0') { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_ERROR; + } + + rflag = 1; + --argc; + ++argv; + } else + rflag = 0; + + if (argc != 6) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "%s: View not found - %s", cmd, argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_ERROR; + } + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + + if (rflag) { + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + dz = 0.0; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + bn_mat_inv(v2m_mat, gdvp->gdv_view->gv_rotation); + + dx *= inv_width * gdvp->gdv_view->gv_size; + dy *= inv_width * gdvp->gdv_view->gv_size; + } else { + struct rt_db_internal intern; + struct rt_bot_internal *botip; + mat_t mat; + size_t vertex_i; + char *last; + + if ((last = strrchr(argv[2], '/')) == NULL) + last = (char *)argv[2]; + else + ++last; + + if (last[0] == '\0') { + bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", cmd, argv[2]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%zu", &vertex_i) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", cmd, argv[3]); + return GED_ERROR; + } + + if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[2], gedp->ged_wdbp, mat) == GED_ERROR) { + bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", cmd, argv[2]); + return GED_ERROR; + } + + if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD || + intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) { + bu_vls_printf(gedp->ged_result_str, "Object is not a BOT"); + rt_db_free_internal(&intern); + + return GED_ERROR; + } + + botip = (struct rt_bot_internal *)intern.idb_ptr; + + if (vertex_i >= botip->num_vertices) { + bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", cmd, argv[3]); + rt_db_free_internal(&intern); + return GED_ERROR; + } + + MAT4X3PNT(view, gdvp->gdv_view->gv_model2view, &botip->vertices[vertex_i*3]); + MAT_COPY(v2m_mat, gdvp->gdv_view->gv_view2model); + + dx = screen_to_view_x(gdvp->gdv_dmp, x); + dy = screen_to_view_y(gdvp->gdv_dmp, y); + dz = view[Z]; + + rt_db_free_internal(&intern); + } + + VSET(view, dx, dy, dz); + MAT4X3PNT(model, v2m_mat, view); + + /* ged_bot_move_pnt expects things to be in local units */ + VSCALE(model, model, gedp->ged_wdbp->dbip->dbi_base2local); + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "bot_move_pnt"; + + if (rflag) { + av[1] = "-r"; + av[2] = (char *)argv[2]; + av[3] = (char *)argv[3]; + av[4] = bu_vls_addr(&pt_vls); + av[5] = (char *)0; + + ret = ged_bot_move_pnt(gedp, 5, (const char **)av); + } else { + av[1] = (char *)argv[2]; + av[2] = (char *)argv[3]; + av[3] = bu_vls_addr(&pt_vls); + av[4] = (char *)0; + + ret = ged_bot_move_pnt(gedp, 4, (const char **)av); + } + + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_move_bot_pnts(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret, width; + const char *cmd; + fastf_t dx, dy, dz; + fastf_t inv_width; + point_t model; + point_t view; + mat_t v2m_mat; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + cmd = argv[0]; + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_HELP; + } + + if (argc < 6) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "%s: View not found - %s", cmd, argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[2], "%lf", &x) != 1 || + bu_sscanf(argv[3], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", cmd, usage); + return GED_ERROR; + } + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + dz = 0.0; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + bn_mat_inv(v2m_mat, gdvp->gdv_view->gv_rotation); + + dx *= inv_width * gdvp->gdv_view->gv_size; + dy *= inv_width * gdvp->gdv_view->gv_size; + + VSET(view, dx, dy, dz); + MAT4X3PNT(model, v2m_mat, view); + + /* ged_bot_move_pnts expects things to be in local units */ + VSCALE(model, model, gedp->ged_wdbp->dbip->dbi_base2local); + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + + { + register int i, j; + int ac = argc - 2; + char **av = (char **)bu_calloc(ac, sizeof(char *), "to_mouse_move_bot_pnts: av[]"); + av[0] = "bot_move_pnts"; + + av[1] = (char *)argv[4]; + av[2] = bu_vls_addr(&pt_vls); + av[ac-1] = (char *)0; + + for (i=3, j=5; i < ac; ++i, ++j) + av[i] = (char *)argv[j]; + + ret = ged_bot_move_pnts(gedp, ac, (const char **)av); + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[4]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + bu_free((void *)av, "to_mouse_move_bot_pnts: av[]"); + } + + return GED_OK; +} + + +int +to_mouse_move_pnt_common(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr func, + const char *usage, + int UNUSED(maxargs)) +{ + int ret, width; + char *av[6]; + fastf_t dx, dy; + fastf_t inv_width; + point_t model; + point_t view; + mat_t inv_rot; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + /* ged_pipe_move_pnt expects things to be in local units */ + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = (char *)argv[0]; + av[1] = "-r"; + av[2] = (char *)argv[2]; + av[3] = (char *)argv[3]; + av[4] = bu_vls_addr(&pt_vls); + av[5] = (char *)0; + + ret = (*func)(gedp, 5, (const char **)av); + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_orotate(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + fastf_t dx, dy; + point_t model; + point_t view; + mat_t inv_rot; + struct bu_vls rot_x_vls = BU_VLS_INIT_ZERO; + struct bu_vls rot_y_vls = BU_VLS_INIT_ZERO; + struct bu_vls rot_z_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = y - gdvp->gdv_view->gv_prevMouseY; + dy = x - gdvp->gdv_view->gv_prevMouseX; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + dx *= gdvp->gdv_view->gv_rscale; + dy *= gdvp->gdv_view->gv_rscale; + + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&rot_x_vls, "%lf", model[X]); + bu_vls_printf(&rot_y_vls, "%lf", model[Y]); + bu_vls_printf(&rot_z_vls, "%lf", model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + + if (0 < bu_vls_strlen(&gdvp->gdv_edit_motion_delta_callback)) { + const char *command = bu_vls_addr(&gdvp->gdv_edit_motion_delta_callback); + const char *args[4]; + args[0] = "orotate"; + args[1] = bu_vls_addr(&rot_x_vls); + args[2] = bu_vls_addr(&rot_y_vls); + args[3] = bu_vls_addr(&rot_z_vls); + tclcad_eval(current_top->to_interp, command, sizeof(args) / sizeof(args[0]), args); + } else { + char *av[6]; + + av[0] = "orotate"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&rot_x_vls); + av[3] = bu_vls_addr(&rot_y_vls); + av[4] = bu_vls_addr(&rot_z_vls); + av[5] = (char *)0; + + if (ged_orotate(gedp, 5, (const char **)av) == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + } + + bu_vls_free(&rot_x_vls); + bu_vls_free(&rot_y_vls); + bu_vls_free(&rot_z_vls); + + return GED_OK; +} + + +int +to_mouse_oscale(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int width; + fastf_t dx, dy; + fastf_t sf; + fastf_t inv_width; + struct bu_vls sf_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + dx *= inv_width * gdvp->gdv_view->gv_sscale; + dy *= inv_width * gdvp->gdv_view->gv_sscale; + + if (fabs(dx) < fabs(dy)) + sf = 1.0 + dy; + else + sf = 1.0 + dx; + + bu_vls_printf(&sf_vls, "%lf", sf); + + gedp->ged_gvp = gdvp->gdv_view; + + if (0 < bu_vls_strlen(&gdvp->gdv_edit_motion_delta_callback)) { + struct bu_vls tcl_cmd; + + bu_vls_init(&tcl_cmd); + bu_vls_printf(&tcl_cmd, "%s oscale %s", bu_vls_addr(&gdvp->gdv_edit_motion_delta_callback), bu_vls_addr(&sf_vls)); + Tcl_Eval(current_top->to_interp, bu_vls_addr(&tcl_cmd)); + bu_vls_free(&tcl_cmd); + } else { + char *av[6]; + + av[0] = "oscale"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&sf_vls); + av[3] = (char *)0; + + if (ged_oscale(gedp, 3, (const char **)av) == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + } + + bu_vls_free(&sf_vls); + + return GED_OK; +} + + +int +to_mouse_otranslate(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int width; + fastf_t dx, dy; + fastf_t inv_width; + point_t model = VINIT_ZERO; + point_t view = VINIT_ZERO; + mat_t inv_rot; + struct bu_vls tran_x_vls = BU_VLS_INIT_ZERO; + struct bu_vls tran_y_vls = BU_VLS_INIT_ZERO; + struct bu_vls tran_z_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 5) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[3], "%lf", &x) != 1 || + bu_sscanf(argv[4], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + /* ged_otranslate expects things to be in local units */ + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + + VSET(view, dx, dy, 0.0); + bu_vls_printf(&tran_x_vls, "%lf", model[X]); + bu_vls_printf(&tran_y_vls, "%lf", model[Y]); + bu_vls_printf(&tran_z_vls, "%lf", model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + + if (0 < bu_vls_strlen(&gdvp->gdv_edit_motion_delta_callback)) { + const char *path_string = argv[2]; + vect_t dvec; + struct path_edit_params *params = (struct path_edit_params *)bu_hash_get(current_top->to_gop->go_edited_paths, + (uint8_t *)path_string, + sizeof(char) * strlen(path_string) + 1); + + if (!params) { + BU_GET(params, struct path_edit_params); + params->edit_mode = gdvp->gdv_view->gv_mode; + params->dx = params->dy = 0.0; + (void)bu_hash_set(current_top->to_gop->go_edited_paths, + (uint8_t *)path_string, + sizeof(char) * strlen(path_string) + 1, (void *)params); + } + + params->dx += dx; + params->dy += dy; + VSET(view, params->dx, params->dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + MAT_IDN(params->edit_mat); + MAT4X3PNT(model, inv_rot, view); + VSCALE(dvec, model, gedp->ged_wdbp->dbip->dbi_local2base); + MAT_DELTAS_VEC(params->edit_mat, dvec); + + to_refresh_view(gdvp); + } else { + char *av[6]; + + av[0] = "otranslate"; + av[1] = (char *)argv[2]; + av[2] = bu_vls_addr(&tran_x_vls); + av[3] = bu_vls_addr(&tran_y_vls); + av[4] = bu_vls_addr(&tran_z_vls); + av[5] = (char *)0; + + if (ged_otranslate(gedp, 5, (const char **)av) == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + } + + bu_vls_free(&tran_x_vls); + bu_vls_free(&tran_y_vls); + bu_vls_free(&tran_z_vls); + + return GED_OK; +} + + +int +go_mouse_poly_circ(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage) +{ + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* Don't allow go_refresh() to be called */ + if (current_top != NULL) + current_top->to_gop->go_refresh_on = 0; + + return to_mouse_poly_circ_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_mouse_poly_circ(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + int ret; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + /* shift the command name to argv[1] before calling to_mouse_poly_circ_func */ + argv[1] = argv[0]; + ret = to_mouse_poly_circ_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); +#if 0 + if (ret == GED_ERROR) + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); +#endif + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_mouse_poly_circ_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int UNUSED(argc), + const char *argv[], + const char *usage) +{ + int ac; + char *av[5]; + int x, y; + fastf_t fx, fy; + point_t v_pt, m_pt; + struct bu_vls plist = BU_VLS_INIT_ZERO; + struct bu_vls i_vls = BU_VLS_INIT_ZERO; + bview_data_polygon_state *gdpsp; + + if (argv[0][0] == 's') + gdpsp = &gdvp->gdv_view->gv_sdata_polygons; + else + gdpsp = &gdvp->gdv_view->gv_data_polygons; + + if (bu_sscanf(argv[1], "%d", &x) != 1 || + bu_sscanf(argv[2], "%d", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + fx = screen_to_view_x(gdvp->gdv_dmp, x); + fy = screen_to_view_y(gdvp->gdv_dmp, y); + + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &fx, &fy); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &fx, &fy); + } + + bu_vls_printf(&plist, "{0 "); + + { + vect_t vdiff; + fastf_t r, arc; + fastf_t curr_fx, curr_fy; + register int nsegs, n; + + VSET(v_pt, fx, fy, gdvp->gdv_view->gv_data_vZ); + VSUB2(vdiff, v_pt, gdpsp->gdps_prev_point); + r = MAGNITUDE(vdiff); + + /* use a variable number of segments based on the size of the + * circle being created so small circles have few segments and + * large ones are nice and smooth. select a chord length that + * results in segments approximately 4 pixels in length. + * + * circumference / 4 = PI * diameter / 4 + * + */ + nsegs = M_PI_2 * r * gdvp->gdv_view->gv_scale; + + if (nsegs < 32) + nsegs = 32; + + arc = 360.0 / nsegs; + for (n = 0; n < nsegs; ++n) { + fastf_t ang = n * arc; + + curr_fx = cos(ang*DEG2RAD) * r + gdpsp->gdps_prev_point[X]; + curr_fy = sin(ang*DEG2RAD) * r + gdpsp->gdps_prev_point[Y]; + VSET(v_pt, curr_fx, curr_fy, gdvp->gdv_view->gv_data_vZ); + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + bu_vls_printf(&plist, " {%lf %lf %lf}", V3ARGS(m_pt)); + } + } + + bu_vls_printf(&plist, " }"); + bu_vls_printf(&i_vls, "%zu", gdpsp->gdps_curr_polygon_i); + + gedp->ged_gvp = gdvp->gdv_view; + ac = 4; + av[0] = "data_polygons"; + av[1] = "replace_poly"; + av[2] = bu_vls_addr(&i_vls); + av[3] = bu_vls_addr(&plist); + av[4] = (char *)0; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + bu_vls_free(&i_vls); + + return GED_OK; +} + + +int +go_mouse_poly_cont(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage) +{ + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* Don't allow go_refresh() to be called */ + if (current_top != NULL) + current_top->to_gop->go_refresh_on = 0; + + return to_mouse_poly_cont_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_mouse_poly_cont(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + int ret; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + /* shift the command name to argv[1] before calling to_mouse_poly_cont_func */ + argv[1] = argv[0]; + ret = to_mouse_poly_cont_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); +#if 0 + if (ret == GED_ERROR) + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); +#endif + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_mouse_poly_cont_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int UNUSED(argc), + const char *argv[], + const char *usage) +{ + int ac; + char *av[7]; + int x, y; + fastf_t fx, fy; + point_t v_pt, m_pt; + bview_data_polygon_state *gdpsp; + + if (argv[0][0] == 's') + gdpsp = &gdvp->gdv_view->gv_sdata_polygons; + else + gdpsp = &gdvp->gdv_view->gv_data_polygons; + + if (bu_sscanf(argv[1], "%d", &x) != 1 || + bu_sscanf(argv[2], "%d", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + fx = screen_to_view_x(gdvp->gdv_dmp, x); + fy = screen_to_view_y(gdvp->gdv_dmp, y); + VSET(v_pt, fx, fy, gdvp->gdv_view->gv_data_vZ); + + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + gedp->ged_gvp = gdvp->gdv_view; + + { + struct bu_vls i_vls = BU_VLS_INIT_ZERO; + struct bu_vls k_vls = BU_VLS_INIT_ZERO; + struct bu_vls plist = BU_VLS_INIT_ZERO; + + bu_vls_printf(&i_vls, "%zu", gdpsp->gdps_curr_polygon_i); + bu_vls_printf(&k_vls, "%zu", gdpsp->gdps_curr_point_i); + bu_vls_printf(&plist, "%lf %lf %lf", V3ARGS(m_pt)); + + ac = 6; + av[0] = "data_polygons"; + av[1] = "replace_point"; + av[2] = bu_vls_addr(&i_vls); + av[3] = "0"; + av[4] = bu_vls_addr(&k_vls); + av[5] = bu_vls_addr(&plist); + av[6] = (char *)0; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&i_vls); + bu_vls_free(&k_vls); + bu_vls_free(&plist); + } + + return GED_OK; +} + + +int +go_mouse_poly_ell(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage) +{ + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* Don't allow go_refresh() to be called */ + if (current_top != NULL) + current_top->to_gop->go_refresh_on = 0; + + return to_mouse_poly_ell_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_mouse_poly_ell(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + int ret; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + /* shift the command name to argv[1] before calling to_mouse_poly_ell_func */ + argv[1] = argv[0]; + ret = to_mouse_poly_ell_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); +#if 0 + if (ret == GED_ERROR) + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); +#endif + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_mouse_poly_ell_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int UNUSED(argc), + const char *argv[], + const char *usage) +{ + int ac; + char *av[5]; + int x, y; + fastf_t fx, fy; + point_t m_pt; + struct bu_vls plist = BU_VLS_INIT_ZERO; + struct bu_vls i_vls = BU_VLS_INIT_ZERO; + bview_data_polygon_state *gdpsp; + + if (argv[0][0] == 's') + gdpsp = &gdvp->gdv_view->gv_sdata_polygons; + else + gdpsp = &gdvp->gdv_view->gv_data_polygons; + + if (bu_sscanf(argv[1], "%d", &x) != 1 || + bu_sscanf(argv[2], "%d", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + fx = screen_to_view_x(gdvp->gdv_dmp, x); + fy = screen_to_view_y(gdvp->gdv_dmp, y); + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &fx, &fy); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &fx, &fy); + } + + bu_vls_printf(&plist, "{0 "); + + { + fastf_t a, b, arc; + point_t ellout; + point_t A, B; + register int nsegs, n; + + a = fx - gdpsp->gdps_prev_point[X]; + b = fy - gdpsp->gdps_prev_point[Y]; + + /* + * For angle alpha, compute surface point as + * + * V + cos(alpha) * A + sin(alpha) * B + * + * note that sin(alpha) is cos(90-alpha). + */ + + VSET(A, a, 0, gdvp->gdv_view->gv_data_vZ); + VSET(B, 0, b, gdvp->gdv_view->gv_data_vZ); + + /* use a variable number of segments based on the size of the + * circle being created so small circles have few segments and + * large ones are nice and smooth. select a chord length that + * results in segments approximately 4 pixels in length. + * + * circumference / 4 = PI * diameter / 4 + * + */ + nsegs = M_PI_2 * FMAX(a, b) * gdvp->gdv_view->gv_scale; + + if (nsegs < 32) + nsegs = 32; + + arc = 360.0 / nsegs; + for (n = 0; n < nsegs; ++n) { + fastf_t cosa = cos(n * arc * DEG2RAD); + fastf_t sina = sin(n * arc * DEG2RAD); + + VJOIN2(ellout, gdpsp->gdps_prev_point, cosa, A, sina, B); + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, ellout); + bu_vls_printf(&plist, " {%lf %lf %lf}", V3ARGS(m_pt)); + } + } + + bu_vls_printf(&plist, " }"); + bu_vls_printf(&i_vls, "%zu", gdpsp->gdps_curr_polygon_i); + + gedp->ged_gvp = gdvp->gdv_view; + ac = 4; + av[0] = "data_polygons"; + av[1] = "replace_poly"; + av[2] = bu_vls_addr(&i_vls); + av[3] = bu_vls_addr(&plist); + av[4] = (char *)0; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + bu_vls_free(&i_vls); + + return GED_OK; +} + + +int +go_mouse_poly_rect(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage) +{ + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + /* Don't allow go_refresh() to be called */ + if (current_top != NULL) + current_top->to_gop->go_refresh_on = 0; + + return to_mouse_poly_rect_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_mouse_poly_rect(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + int ret; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + /* shift the command name to argv[1] before calling to_mouse_poly_rect_func */ + argv[1] = argv[0]; + ret = to_mouse_poly_rect_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); +#if 0 + if (ret == GED_ERROR) + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); +#endif + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_mouse_poly_rect_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int UNUSED(argc), + const char *argv[], + const char *usage) +{ + int ac; + char *av[5]; + int x, y; + fastf_t fx, fy; + point_t v_pt, m_pt; + struct bu_vls plist = BU_VLS_INIT_ZERO; + struct bu_vls i_vls = BU_VLS_INIT_ZERO; + bview_data_polygon_state *gdpsp; + + if (argv[0][0] == 's') + gdpsp = &gdvp->gdv_view->gv_sdata_polygons; + else + gdpsp = &gdvp->gdv_view->gv_data_polygons; + + if (bu_sscanf(argv[1], "%d", &x) != 1 || + bu_sscanf(argv[2], "%d", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + fx = screen_to_view_x(gdvp->gdv_dmp, x); + fy = screen_to_view_y(gdvp->gdv_dmp, y); + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &fx, &fy); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &fx, &fy); + } + + + if (gdvp->gdv_view->gv_mode == TCLCAD_POLY_SQUARE_MODE) { + fastf_t dx, dy; + + dx = fx - gdpsp->gdps_prev_point[X]; + dy = fy - gdpsp->gdps_prev_point[Y]; + + if (fabs(dx) > fabs(dy)) { + if (dy < 0.0) + fy = gdpsp->gdps_prev_point[Y] - fabs(dx); + else + fy = gdpsp->gdps_prev_point[Y] + fabs(dx); + } else { + if (dx < 0.0) + fx = gdpsp->gdps_prev_point[X] - fabs(dy); + else + fx = gdpsp->gdps_prev_point[X] + fabs(dy); + } + } + + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, gdpsp->gdps_prev_point); + bu_vls_printf(&plist, "{0 {%lf %lf %lf} ", V3ARGS(m_pt)); + + VSET(v_pt, gdpsp->gdps_prev_point[X], fy, gdvp->gdv_view->gv_data_vZ); + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + bu_vls_printf(&plist, "{%lf %lf %lf} ", V3ARGS(m_pt)); + + VSET(v_pt, fx, fy, gdvp->gdv_view->gv_data_vZ); + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + bu_vls_printf(&plist, "{%lf %lf %lf} ", V3ARGS(m_pt)); + VSET(v_pt, fx, gdpsp->gdps_prev_point[Y], gdvp->gdv_view->gv_data_vZ); + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + bu_vls_printf(&plist, "{%lf %lf %lf} }", V3ARGS(m_pt)); + + bu_vls_printf(&i_vls, "%zu", gdpsp->gdps_curr_polygon_i); + + gedp->ged_gvp = gdvp->gdv_view; + ac = 4; + av[0] = "data_polygons"; + av[1] = "replace_poly"; + av[2] = bu_vls_addr(&i_vls); + av[3] = bu_vls_addr(&plist); + av[4] = (char *)0; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + bu_vls_free(&i_vls); + + return GED_OK; +} + + +int +to_mouse_ray(struct ged *UNUSED(gedp), + int UNUSED(argc), + const char *UNUSED(argv[]), + ged_func_ptr UNUSED(func), + const char *UNUSED(usage), + int UNUSED(maxargs)) +{ + return GED_OK; +} + + +int +to_mouse_rect(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + int ac; + char *av[5]; + int x, y; + int dx, dy; + struct bu_vls dx_vls = BU_VLS_INIT_ZERO; + struct bu_vls dy_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[2], "%d", &x) != 1 || + bu_sscanf(argv[3], "%d", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = dm_get_height(gdvp->gdv_dmp) - y - gdvp->gdv_view->gv_prevMouseY; + + bu_vls_printf(&dx_vls, "%d", dx); + bu_vls_printf(&dy_vls, "%d", dy); + gedp->ged_gvp = gdvp->gdv_view; + ac = 4; + av[0] = "rect"; + av[1] = "dim"; + av[2] = bu_vls_addr(&dx_vls); + av[3] = bu_vls_addr(&dy_vls); + av[4] = (char *)0; + + ret = ged_rect(gedp, ac, (const char **)av); + bu_vls_free(&dx_vls); + bu_vls_free(&dy_vls); + + if (ret == GED_OK) + to_refresh_view(gdvp); + + return GED_OK; +} + + +int +to_mouse_rot(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + int ac; + char *av[4]; + fastf_t dx, dy; + struct bu_vls rot_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[2], "%lf", &x) != 1 || + bu_sscanf(argv[3], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = gdvp->gdv_view->gv_prevMouseY - y; + dy = gdvp->gdv_view->gv_prevMouseX - x; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + dx *= gdvp->gdv_view->gv_rscale; + dy *= gdvp->gdv_view->gv_rscale; + + bu_vls_printf(&rot_vls, "%lf %lf 0", dx, dy); + + gedp->ged_gvp = gdvp->gdv_view; + ac = 3; + av[0] = "rot"; + av[1] = "-v"; + av[2] = bu_vls_addr(&rot_vls); + av[3] = (char *)0; + + ret = ged_rot(gedp, ac, (const char **)av); + bu_vls_free(&rot_vls); + + if (ret == GED_OK) { + if (0 < bu_vls_strlen(&gdvp->gdv_callback)) { + Tcl_Eval(current_top->to_interp, bu_vls_addr(&gdvp->gdv_callback)); + } + + to_refresh_view(gdvp); + } + + return GED_OK; +} + + +int +to_mouse_rotate_arb_face(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + char *av[6]; + fastf_t dx, dy; + point_t model; + point_t view; + mat_t inv_rot; + struct bu_vls pt_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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 != 7) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[5], "%lf", &x) != 1 || + bu_sscanf(argv[6], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = y - gdvp->gdv_view->gv_prevMouseY; + dy = x - gdvp->gdv_view->gv_prevMouseX; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + dx *= gdvp->gdv_view->gv_rscale; + dy *= gdvp->gdv_view->gv_rscale; + + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "rotate_arb_face"; + av[1] = (char *)argv[2]; + av[2] = (char *)argv[3]; + av[3] = (char *)argv[4]; + av[4] = bu_vls_addr(&pt_vls); + av[5] = (char *)0; + + ret = ged_rotate_arb_face(gedp, 5, (const char **)av); + bu_vls_free(&pt_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +#define TO_COMMON_MOUSE_SCALE(_gdvp, _zoom_vls, _argc, _argv, _usage) { \ + int _width; \ + fastf_t _dx, _dy; \ + fastf_t _inv_width; \ + fastf_t _sf; \ + \ + /* must be double for scanf */ \ + double _x, _y; \ + \ + /* 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; \ + } \ + \ + for (BU_LIST_FOR((_gdvp), ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { \ + if (BU_STR_EQUAL(bu_vls_addr(&(_gdvp)->gdv_name), (_argv)[1])) \ + break; \ + } \ + \ + if (BU_LIST_IS_HEAD(&(_gdvp)->l, ¤t_top->to_gop->go_head_views.l)) { \ + bu_vls_printf(gedp->ged_result_str, "View not found - %s", (_argv)[1]); \ + return GED_ERROR; \ + } \ + \ + if (bu_sscanf((_argv)[2], "%lf", &_x) != 1 || \ + bu_sscanf((_argv)[3], "%lf", &_y) != 1) { \ + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", (_argv)[0], (_usage)); \ + return GED_ERROR; \ + } \ + \ + _dx = _x - (_gdvp)->gdv_view->gv_prevMouseX; \ + _dy = (_gdvp)->gdv_view->gv_prevMouseY - _y; \ + \ + (_gdvp)->gdv_view->gv_prevMouseX = _x; \ + (_gdvp)->gdv_view->gv_prevMouseY = _y; \ + \ + if (_dx < (_gdvp)->gdv_view->gv_minMouseDelta) \ + _dx = (_gdvp)->gdv_view->gv_minMouseDelta; \ + else if ((_gdvp)->gdv_view->gv_maxMouseDelta < _dx) \ + _dx = (_gdvp)->gdv_view->gv_maxMouseDelta; \ + \ + if (_dy < (_gdvp)->gdv_view->gv_minMouseDelta) \ + _dy = (_gdvp)->gdv_view->gv_minMouseDelta; \ + else if ((_gdvp)->gdv_view->gv_maxMouseDelta < _dy) \ + _dy = (_gdvp)->gdv_view->gv_maxMouseDelta; \ + \ + _width = dm_get_width((_gdvp)->gdv_dmp); \ + _inv_width = 1.0 / (fastf_t)_width; \ + _dx *= _inv_width * (_gdvp)->gdv_view->gv_sscale; \ + _dy *= _inv_width * (_gdvp)->gdv_view->gv_sscale; \ + \ + if (fabs(_dx) > fabs(_dy)) \ + _sf = 1.0 + _dx; \ + else \ + _sf = 1.0 + _dy; \ + \ + bu_vls_printf(&(_zoom_vls), "%lf", _sf); \ + } + +/* + * Usage: data_scale vname dtype sf + */ +static int +to_data_scale(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + register int i; + struct ged_dm_view *gdvp; + fastf_t sf; + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + usage = "vname dtype sf"; + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_HELP; + } + + if (argc != 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[2], "%lf", &sf) != 1 || sf < 0) { + bu_vls_printf(gedp->ged_result_str, "Invalid scale factor - %s", argv[2]); + return GED_ERROR; + } + + /* scale data arrows */ + { + struct bview_data_arrow_state *gdasp = &gdvp->gdv_view->gv_data_arrows; + point_t vcenter = {0, 0, 0}; + + /* Scale the length of each arrow */ + for (i = 0; i < gdasp->gdas_num_points; i += 2) { + vect_t diff; + point_t vpoint; + + MAT4X3PNT(vpoint, gedp->ged_gvp->gv_model2view, gdasp->gdas_points[i]); + vcenter[Z] = vpoint[Z]; + VSUB2(diff, vpoint, vcenter); + VSCALE(diff, diff, sf); + VADD2(vpoint, vcenter, diff); + MAT4X3PNT(gdasp->gdas_points[i], gedp->ged_gvp->gv_view2model, vpoint); + } + } + + /* scale data labels */ + { + struct bview_data_label_state *gdlsp = &gdvp->gdv_view->gv_data_labels; + point_t vcenter = {0, 0, 0}; + point_t vpoint; + + /* Scale the location of each label WRT the view center */ + for (i = 0; i < gdlsp->gdls_num_labels; ++i) { + vect_t diff; + + MAT4X3PNT(vpoint, gedp->ged_gvp->gv_model2view, gdlsp->gdls_points[i]); + vcenter[Z] = vpoint[Z]; + VSUB2(diff, vpoint, vcenter); + VSCALE(diff, diff, sf); + VADD2(vpoint, vcenter, diff); + MAT4X3PNT(gdlsp->gdls_points[i], gedp->ged_gvp->gv_view2model, vpoint); + } + } + + + to_refresh_view(gdvp); + return GED_OK; +} + +int +to_mouse_data_scale(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + char *av[4]; + struct bu_vls scale_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + TO_COMMON_MOUSE_SCALE(gdvp, scale_vls, argc, argv, usage); + gedp->ged_gvp = gdvp->gdv_view; + + av[0] = "to_data_scale"; + av[1] = (char *)argv[1]; + av[2] = bu_vls_addr(&scale_vls); + av[3] = (char *)0; + + ret = to_data_scale(gedp, 3, (const char **)av, (ged_func_ptr)NULL, NULL, 4); + + bu_vls_free(&scale_vls); + + return ret; +} + + +int +to_mouse_scale(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + char *av[3]; + struct bu_vls zoom_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + TO_COMMON_MOUSE_SCALE(gdvp, zoom_vls, argc, argv, usage); + gedp->ged_gvp = gdvp->gdv_view; + + av[0] = "zoom"; + av[1] = bu_vls_addr(&zoom_vls); + av[2] = (char *)0; + ret = ged_zoom(gedp, 2, (const char **)av); + bu_vls_free(&zoom_vls); + + if (ret == GED_OK) { + if (0 < bu_vls_strlen(&gdvp->gdv_callback)) { + Tcl_Eval(current_top->to_interp, bu_vls_addr(&gdvp->gdv_callback)); + } + + to_refresh_view(gdvp); + } + + return GED_OK; +} + + +int +to_mouse_protate(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret; + char *av[6]; + fastf_t dx, dy; + point_t model; + point_t view; + mat_t inv_rot; + struct bu_vls mrot_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = y - gdvp->gdv_view->gv_prevMouseY; + dy = x - gdvp->gdv_view->gv_prevMouseX; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + dx *= gdvp->gdv_view->gv_rscale; + dy *= gdvp->gdv_view->gv_rscale; + + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&mrot_vls, "%lf %lf %lf", V3ARGS(model)); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "protate"; + av[1] = (char *)argv[2]; + av[2] = (char *)argv[3]; + av[3] = bu_vls_addr(&mrot_vls); + av[4] = (char *)0; + + ret = ged_protate(gedp, 4, (const char **)av); + bu_vls_free(&mrot_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_pscale(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret, width; + char *av[6]; + fastf_t dx, dy; + fastf_t sf; + fastf_t inv_width; + struct bu_vls sf_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + dx *= inv_width * gdvp->gdv_view->gv_sscale; + dy *= inv_width * gdvp->gdv_view->gv_sscale; + + if (fabs(dx) < fabs(dy)) + sf = 1.0 + dy; + else + sf = 1.0 + dx; + + bu_vls_printf(&sf_vls, "%lf", sf); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "pscale"; + av[1] = "-r"; + av[2] = (char *)argv[2]; + av[3] = (char *)argv[3]; + av[4] = bu_vls_addr(&sf_vls); + av[5] = (char *)0; + + ret = ged_pscale(gedp, 5, (const char **)av); + bu_vls_free(&sf_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_ptranslate(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret, width; + char *av[6]; + fastf_t dx, dy; + point_t model; + point_t view; + fastf_t inv_width; + mat_t inv_rot; + struct bu_vls tvec_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[4], "%lf", &x) != 1 || + bu_sscanf(argv[5], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = x - gdvp->gdv_view->gv_prevMouseX; + dy = gdvp->gdv_view->gv_prevMouseY - y; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + /* ged_ptranslate expects things to be in local units */ + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_base2local; + VSET(view, dx, dy, 0.0); + bn_mat_inv(inv_rot, gdvp->gdv_view->gv_rotation); + MAT4X3PNT(model, inv_rot, view); + + bu_vls_printf(&tvec_vls, "%lf %lf %lf", V3ARGS(model)); + + gedp->ged_gvp = gdvp->gdv_view; + av[0] = "ptranslate"; + av[1] = "-r"; + av[2] = (char *)argv[2]; + av[3] = (char *)argv[3]; + av[4] = bu_vls_addr(&tvec_vls); + av[5] = (char *)0; + + ret = ged_ptranslate(gedp, 5, (const char **)av); + bu_vls_free(&tvec_vls); + + if (ret == GED_OK) { + av[0] = "draw"; + av[1] = (char *)argv[2]; + av[2] = (char *)0; + to_edit_redraw(gedp, 2, (const char **)av); + } + + return GED_OK; +} + + +int +to_mouse_trans(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + int ret, width; + int ac; + char *av[4]; + fastf_t dx, dy; + fastf_t inv_width; + struct bu_vls trans_vls = BU_VLS_INIT_ZERO; + struct ged_dm_view *gdvp; + + /* must be double for scanf */ + double x, y; + + /* 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; + } + + for (BU_LIST_FOR(gdvp, ged_dm_view, ¤t_top->to_gop->go_head_views.l)) { + if (BU_STR_EQUAL(bu_vls_addr(&gdvp->gdv_name), argv[1])) + break; + } + + if (BU_LIST_IS_HEAD(&gdvp->l, ¤t_top->to_gop->go_head_views.l)) { + bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]); + return GED_ERROR; + } + + if (bu_sscanf(argv[2], "%lf", &x) != 1 || + bu_sscanf(argv[3], "%lf", &y) != 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + return GED_ERROR; + } + + dx = gdvp->gdv_view->gv_prevMouseX - x; + dy = y - gdvp->gdv_view->gv_prevMouseY; + + gdvp->gdv_view->gv_prevMouseX = x; + gdvp->gdv_view->gv_prevMouseY = y; + + if (dx < gdvp->gdv_view->gv_minMouseDelta) + dx = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dx) + dx = gdvp->gdv_view->gv_maxMouseDelta; + + if (dy < gdvp->gdv_view->gv_minMouseDelta) + dy = gdvp->gdv_view->gv_minMouseDelta; + else if (gdvp->gdv_view->gv_maxMouseDelta < dy) + dy = gdvp->gdv_view->gv_maxMouseDelta; + + width = dm_get_width(gdvp->gdv_dmp); + inv_width = 1.0 / (fastf_t)width; + dx *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_local2base; + dy *= inv_width * gdvp->gdv_view->gv_size * gedp->ged_wdbp->dbip->dbi_local2base; + + bu_vls_printf(&trans_vls, "%lf %lf 0", dx, dy); + + gedp->ged_gvp = gdvp->gdv_view; + ac = 3; + av[0] = "tra"; + av[1] = "-v"; + av[2] = bu_vls_addr(&trans_vls); + av[3] = (char *)0; + + ret = ged_tra(gedp, ac, (const char **)av); + bu_vls_free(&trans_vls); + + if (ret == GED_OK) { + if (0 < bu_vls_strlen(&gdvp->gdv_callback)) { + Tcl_Eval(current_top->to_interp, bu_vls_addr(&gdvp->gdv_callback)); + } + + to_refresh_view(gdvp); + } + + return GED_OK; +} + +/* + * Local Variables: + * mode: C + * tab-width: 8 + * indent-tabs-mode: t + * c-file-style: "stroustrup" + * End: + * ex: shiftwidth=4 tabstop=8 + */ Property changes on: brlcad/trunk/src/libtclcad/tclcad_mouse.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Modified: brlcad/trunk/src/libtclcad/tclcad_obj.c =================================================================== --- brlcad/trunk/src/libtclcad/tclcad_obj.c 2020-07-14 20:18:22 UTC (rev 76335) +++ brlcad/trunk/src/libtclcad/tclcad_obj.c 2020-07-14 20:46:34 UTC (rev 76336) @@ -199,11 +199,6 @@ ged_func_ptr func, const char *usage, int maxargs); -HIDDEN int to_data_polygons_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, @@ Diff output truncated at 100000 characters. @@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits