Revision: 76337 http://sourceforge.net/p/brlcad/code/76337 Author: starseeker Date: 2020-07-14 21:34:33 +0000 (Tue, 14 Jul 2020) Log Message: ----------- Extract polygon logic into its own file - some of the mouse routines probably belong here as well...
Modified Paths: -------------- brlcad/trunk/src/libtclcad/CMakeLists.txt brlcad/trunk/src/libtclcad/tclcad_obj.c brlcad/trunk/src/libtclcad/tclcad_private.h Added Paths: ----------- brlcad/trunk/src/libtclcad/tclcad_polygons.c Modified: brlcad/trunk/src/libtclcad/CMakeLists.txt =================================================================== --- brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 20:46:34 UTC (rev 76336) +++ brlcad/trunk/src/libtclcad/CMakeLists.txt 2020-07-14 21:34:33 UTC (rev 76337) @@ -9,6 +9,7 @@ tclcad_eval.c tclcad_init.c tclcad_mouse.c + tclcad_polygons.c tclcad_views.c tkImgFmtPIX.c cmdhist_obj.c Modified: brlcad/trunk/src/libtclcad/tclcad_obj.c =================================================================== --- brlcad/trunk/src/libtclcad/tclcad_obj.c 2020-07-14 20:46:34 UTC (rev 76336) +++ brlcad/trunk/src/libtclcad/tclcad_obj.c 2020-07-14 21:34:33 UTC (rev 76337) @@ -88,12 +88,6 @@ #include "brlcad_version.h" -/* - * Weird upper limit from clipper ---> sqrt(2^63 -1)/2 - * Probably should be sqrt(2^63 -1) - */ -#define CLIPPER_MAX 1518500249 - HIDDEN int to_autoview(struct ged *gedp, int argc, const char *argv[], @@ -193,12 +187,6 @@ ged_func_ptr func, const char *usage, int maxargs); -HIDDEN int to_data_polygons(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr func, - const char *usage, - int maxargs); HIDDEN int to_data_move(struct ged *gedp, int argc, const char *argv[], @@ -476,65 +464,6 @@ const char *usage, int maxargs); #endif - -HIDDEN int to_poly_circ_mode(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr func, - const char *usage, - int maxargs); -HIDDEN int to_poly_circ_mode_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[], - const char *usage); -HIDDEN int to_poly_cont_build(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr func, - const char *usage, - int maxargs); -HIDDEN int to_poly_cont_build_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[], - const char *usage, - int doBind); -HIDDEN int to_poly_cont_build_end(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr func, - const char *usage, - int maxargs); -HIDDEN int to_poly_cont_build_end_func(struct ged_dm_view *gdvp, - int argc, - const char *argv[]); -HIDDEN int to_poly_ell_mode(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr func, - const char *usage, - int maxargs); -HIDDEN int to_poly_ell_mode_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[], - const char *usage); -HIDDEN int to_poly_rect_mode(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr func, - const char *usage, - int maxargs); -HIDDEN int to_poly_rect_mode_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[], - const char *usage); HIDDEN int to_prim_label(struct ged *gedp, int argc, const char *argv[], @@ -3468,1042 +3397,7 @@ return ret; } -/* These functions should be macros */ -HIDDEN void -to_polygon_free(struct bg_polygon *gpp) -{ - register size_t j; - - if (gpp->num_contours == 0) - return; - - for (j = 0; j < gpp->num_contours; ++j) - if (gpp->contour[j].num_points > 0) - bu_free((void *)gpp->contour[j].point, "contour points"); - - bu_free((void *)gpp->contour, "contour"); - bu_free((void *)gpp->hole, "hole"); - gpp->num_contours = 0; -} - - -HIDDEN void -to_polygons_free(struct bg_polygons *gpp) -{ - register size_t i; - - if (gpp->num_polygons == 0) - return; - - for (i = 0; i < gpp->num_polygons; ++i) { - to_polygon_free(&gpp->polygon[i]); - } - - bu_free((void *)gpp->polygon, "data polygons"); - gpp->polygon = (struct bg_polygon *)0; - gpp->num_polygons = 0; -} - - -HIDDEN int -to_extract_contours_av(Tcl_Interp *interp, struct ged *gedp, struct ged_dm_view *gdvp, struct bg_polygon *gpp, size_t contour_ac, const char **contour_av, int mode, int vflag) -{ - register size_t j = 0, k = 0; - - gpp->num_contours = contour_ac; - gpp->hole = NULL; - gpp->contour = NULL; - - if (contour_ac == 0) - return GED_OK; - - gpp->hole = (int *)bu_calloc(contour_ac, sizeof(int), "hole"); - gpp->contour = (struct bg_poly_contour *)bu_calloc(contour_ac, sizeof(struct bg_poly_contour), "contour"); - - for (j = 0; j < contour_ac; ++j) { - int ac; - size_t point_ac; - const char **point_av; - int hole; - - /* Split contour j into points */ - if (Tcl_SplitList(interp, contour_av[j], &ac, &point_av) != TCL_OK) { - bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); - return GED_ERROR; - } - point_ac = ac; - - /* point_ac includes a hole flag */ - if (mode != TCLCAD_POLY_CONTOUR_MODE && point_ac < 4) { - bu_vls_printf(gedp->ged_result_str, "There must be at least 3 points per contour"); - Tcl_Free((char *)point_av); - return GED_ERROR; - } - - gpp->contour[j].num_points = point_ac - 1; - gpp->contour[j].point = (point_t *)bu_calloc(point_ac, sizeof(point_t), "point"); - - if (bu_sscanf(point_av[0], "%d", &hole) != 1) { - bu_vls_printf(gedp->ged_result_str, "contour %zu, point %zu: bad hole flag - %s\n", - j, k, point_av[k]); - Tcl_Free((char *)point_av); - return GED_ERROR; - } - gpp->hole[j] = hole; - - for (k = 1; k < point_ac; ++k) { - double pt[ELEMENTS_PER_POINT]; /* must be double for scanf */ - - if (bu_sscanf(point_av[k], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) { - bu_vls_printf(gedp->ged_result_str, "contour %zu, point %zu: bad data point - %s\n", - j, k, point_av[k]); - Tcl_Free((char *)point_av); - return GED_ERROR; - } - - if (vflag) { - MAT4X3PNT(gpp->contour[j].point[k-1], gdvp->gdv_view->gv_view2model, pt); - } else { - VMOVE(gpp->contour[j].point[k-1], pt); - } - - } - - Tcl_Free((char *)point_av); - } - - return GED_OK; -} - - -HIDDEN int -to_extract_polygons_av(Tcl_Interp *interp, struct ged *gedp, struct ged_dm_view *gdvp, bview_data_polygon_state *gdpsp, size_t polygon_ac, const char **polygon_av, int mode, int vflag) -{ - register size_t i; - int ac; - - gdpsp->gdps_polygons.num_polygons = polygon_ac; - gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_calloc(polygon_ac, sizeof(struct bg_polygon), "data polygons"); - for (i = 0; i < polygon_ac; ++i) { - // TODO - allocate properties containers for each polygon - } - - for (i = 0; i < polygon_ac; ++i) { - size_t contour_ac; - const char **contour_av; - - /* Split polygon i into contours */ - if (Tcl_SplitList(interp, polygon_av[i], &ac, &contour_av) != TCL_OK) { - bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); - return GED_ERROR; - } - contour_ac = ac; - - if (to_extract_contours_av(interp, gedp, gdvp, &gdpsp->gdps_polygons.polygon[i], contour_ac, contour_av, mode, vflag) != GED_OK) { - Tcl_Free((char *)contour_av); - return GED_ERROR; - } - - VMOVE(gdpsp->gdps_polygons.polygon[i].gp_color, gdpsp->gdps_color); - if (contour_ac) - Tcl_Free((char *)contour_av); - } - - return GED_OK; -} - - int -go_data_polygons(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[], - const char *usage) -{ - 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 < 2 || 6 < argc) { - 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; - - ret = to_data_polygons_func(interp, gedp, gdvp, argc, argv); - if (ret == GED_ERROR) - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - - return ret; -} - - -HIDDEN int -to_data_polygons(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 < 3 || 7 < argc) { - 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_data_polygons_func */ - argv[1] = argv[0]; - ret = to_data_polygons_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1); - if (ret == GED_ERROR) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); - } - - return ret; -} - - -int -to_data_polygons_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[]) -{ - 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; - - gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; - gdpsp->gdps_data_vZ = gdvp->gdv_view->gv_data_vZ; - VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); - MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); - MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); - MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); - - if (BU_STR_EQUAL(argv[1], "target_poly")) { - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%lu", gdpsp->gdps_target_polygon_i); - return GED_OK; - } - - if (argc == 3) { - size_t i; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || i > gdpsp->gdps_polygons.num_polygons) - goto bad; - - gdpsp->gdps_target_polygon_i = i; - - return GED_OK; - } - - goto bad; - } - - if (BU_STR_EQUAL(argv[1], "clip_type")) { - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_clip_type); - return GED_OK; - } - - if (argc == 3) { - int op; - - if (bu_sscanf(argv[2], "%d", &op) != 1 || op > bg_Xor) - goto bad; - - gdpsp->gdps_clip_type = (bg_clip_t)op; - - return GED_OK; - } - - goto bad; - } - - if (BU_STR_EQUAL(argv[1], "draw")) { - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_draw); - return GED_OK; - } - - if (argc == 3) { - int i; - - if (bu_sscanf(argv[2], "%d", &i) != 1) - goto bad; - - if (i) - gdpsp->gdps_draw = 1; - else - gdpsp->gdps_draw = 0; - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - if (BU_STR_EQUAL(argv[1], "moveall")) { - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_moveAll); - return GED_OK; - } - - if (argc == 3) { - int i; - - if (bu_sscanf(argv[2], "%d", &i) != 1) - goto bad; - - if (i) - gdpsp->gdps_moveAll = 1; - else - gdpsp->gdps_moveAll = 0; - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: poly_color i [r g b] - * - * Set/get the color of polygon i. - */ - if (BU_STR_EQUAL(argv[1], "poly_color")) { - size_t i; - - if (argc == 3) { - /* Get the color for polygon i */ - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - bu_vls_printf(gedp->ged_result_str, "%d %d %d", - V3ARGS(gdpsp->gdps_polygons.polygon[i].gp_color)); - - return GED_OK; - } - - if (argc == 6) { - int r, g, b; - - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - /* set background color */ - if (bu_sscanf(argv[3], "%d", &r) != 1 || - bu_sscanf(argv[4], "%d", &g) != 1 || - bu_sscanf(argv[5], "%d", &b) != 1) - goto bad; - - /* validate color */ - if (r < 0 || 255 < r || - g < 0 || 255 < g || - b < 0 || 255 < b) - goto bad; - - /* Set the color for polygon i */ - VSET(gdpsp->gdps_polygons.polygon[i].gp_color, r, g, b); - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: color [r g b] - * - * Set the color of all polygons, or get the default polygon color. - */ - if (BU_STR_EQUAL(argv[1], "color")) { - size_t i; - - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%d %d %d", - V3ARGS(gdpsp->gdps_color)); - - return GED_OK; - } - - if (argc == 5) { - int r, g, b; - - /* set background color */ - if (bu_sscanf(argv[2], "%d", &r) != 1 || - bu_sscanf(argv[3], "%d", &g) != 1 || - bu_sscanf(argv[4], "%d", &b) != 1) - goto bad; - - /* validate color */ - if (r < 0 || 255 < r || - g < 0 || 255 < g || - b < 0 || 255 < b) - goto bad; - - /* Set the color for all polygons */ - for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { - VSET(gdpsp->gdps_polygons.polygon[i].gp_color, r, g, b); - } - - /* Set the default polygon color */ - VSET(gdpsp->gdps_color, r, g, b); - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: poly_line_width i [w] - * - * Set/get the line width of polygon i. - */ - if (BU_STR_EQUAL(argv[1], "poly_line_width")) { - size_t i; - - if (argc == 3) { - /* Get the line width for polygon i */ - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_polygons.polygon[i].gp_line_width); - - return GED_OK; - } - - if (argc == 4) { - int line_width; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%d", &line_width) != 1) - goto bad; - - if (line_width < 0) - line_width = 0; - - gdpsp->gdps_polygons.polygon[i].gp_line_width = line_width; - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: line_width [w] - * - * Set the line width of all polygons, or get the default polygon line width. - */ - if (BU_STR_EQUAL(argv[1], "line_width")) { - size_t i; - - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_line_width); - return GED_OK; - } - - if (argc == 3) { - int line_width; - - if (bu_sscanf(argv[2], "%d", &line_width) != 1) - goto bad; - - if (line_width < 0) - line_width = 0; - - /* Set the line width for all polygons */ - for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { - gdpsp->gdps_polygons.polygon[i].gp_line_width = line_width; - } - - /* Set the default line width */ - gdpsp->gdps_line_width = line_width; - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: poly_line_style i [w] - * - * Set/get the line style of polygon i. - */ - if (BU_STR_EQUAL(argv[1], "poly_line_style")) { - size_t i; - - if (argc == 3) { - /* Get the line style for polygon i */ - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_polygons.polygon[i].gp_line_style); - - return GED_OK; - } - - if (argc == 4) { - int line_style; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%d", &line_style) != 1) - goto bad; - - - if (line_style <= 0) - gdpsp->gdps_polygons.polygon[i].gp_line_style = 0; - else - gdpsp->gdps_polygons.polygon[i].gp_line_style = 1; - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: line_style [w] - * - * Set the line style of all polygons, or get the default polygon line style. - */ - if (BU_STR_EQUAL(argv[1], "line_style")) { - size_t i; - - if (argc == 2) { - bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_line_style); - return GED_OK; - } - - if (argc == 3) { - int line_style; - - if (bu_sscanf(argv[2], "%d", &line_style) != 1) - goto bad; - - if (line_style <= 0) - line_style = 0; - else - line_style = 1; - - /* Set the line width for all polygons */ - for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { - gdpsp->gdps_polygons.polygon[i].gp_line_style = line_style; - } - - /* Set the default line style */ - gdpsp->gdps_line_style = line_style; - - to_refresh_view(gdvp); - return GED_OK; - } - - goto bad; - } - - /* Usage: append_poly plist - * - * Append the polygon specified by plist. - */ - if (BU_STR_EQUAL(argv[1], "append_poly")) { - if (argc != 3) - goto bad; - - if (argc == 3) { - register size_t i; - int ac; - size_t contour_ac; - const char **contour_av; - - /* Split the polygon in argv[2] into contours */ - if (Tcl_SplitList(interp, argv[2], &ac, &contour_av) != TCL_OK || - ac < 1) { - bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); - return GED_ERROR; - } - contour_ac = ac; - - i = gdpsp->gdps_polygons.num_polygons; - ++gdpsp->gdps_polygons.num_polygons; - gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_realloc(gdpsp->gdps_polygons.polygon, - gdpsp->gdps_polygons.num_polygons * sizeof(struct bg_polygon), - "realloc polygon"); - - if (to_extract_contours_av(interp, gedp, gdvp, &gdpsp->gdps_polygons.polygon[i], - contour_ac, contour_av, gdvp->gdv_view->gv_mode, 0) != GED_OK) { - Tcl_Free((char *)contour_av); - return GED_ERROR; - } - - VMOVE(gdpsp->gdps_polygons.polygon[i].gp_color, gdpsp->gdps_color); - gdpsp->gdps_polygons.polygon[i].gp_line_style = gdpsp->gdps_line_style; - gdpsp->gdps_polygons.polygon[i].gp_line_width = gdpsp->gdps_line_width; - - Tcl_Free((char *)contour_av); - - to_refresh_view(gdvp); - return GED_OK; - } - } - - - /* Usage: clip [i j [op]] - * - * Clip polygon i using polygon j and op. - */ - if (BU_STR_EQUAL(argv[1], "clip")) { - size_t i, j; - int op; - struct bg_polygon *gpp; - - if (argc > 5) - goto bad; - - if (argc > 2) { - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - } else - i = gdpsp->gdps_target_polygon_i; - - if (argc > 3) { - if (bu_sscanf(argv[3], "%zu", &j) != 1 || - j >= gdpsp->gdps_polygons.num_polygons) - goto bad; - } else - j = gdpsp->gdps_polygons.num_polygons - 1; /* Default - use last polygon as the clip polygon */ - - /* Nothing to do */ - if (i == j) - return GED_OK; - - if (argc != 5) - op = gdpsp->gdps_clip_type; - else if (bu_sscanf(argv[4], "%d", &op) != 1 || op > bg_Xor) - goto bad; - - gpp = bg_clip_polygon((bg_clip_t)op, - &gdpsp->gdps_polygons.polygon[i], - &gdpsp->gdps_polygons.polygon[j], - CLIPPER_MAX, - gdpsp->gdps_model2view, - gdpsp->gdps_view2model); - - /* Free the target polygon */ - to_polygon_free(&gdpsp->gdps_polygons.polygon[i]); - - /* When using defaults, the clip polygon is assumed to be temporary and is removed after clipping */ - if (argc == 2) { - /* Free the clip polygon */ - to_polygon_free(&gdpsp->gdps_polygons.polygon[j]); - - /* No longer need space for the clip polygon */ - --gdpsp->gdps_polygons.num_polygons; - gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_realloc(gdpsp->gdps_polygons.polygon, - gdpsp->gdps_polygons.num_polygons * sizeof(struct bg_polygon), - "realloc polygon"); - } - - /* Replace the target polygon with the newly clipped polygon. */ - /* Not doing a struct copy to avoid overwriting the color, line width and line style. */ - gdpsp->gdps_polygons.polygon[i].num_contours = gpp->num_contours; - gdpsp->gdps_polygons.polygon[i].hole = gpp->hole; - gdpsp->gdps_polygons.polygon[i].contour = gpp->contour; - - /* Free the clipped polygon container */ - bu_free((void *)gpp, "clip gpp"); - - to_refresh_view(gdvp); - return GED_OK; - } - - /* Usage: export i sketch_name - * - * Export polygon i to sketch_name - */ - if (BU_STR_EQUAL(argv[1], "export")) { - size_t i; - int ret; - - if (argc != 4) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if ((ret = ged_export_polygon(gedp, gdpsp, i, argv[3])) != GED_OK) - bu_vls_printf(gedp->ged_result_str, "%s: failed to export polygon %lu to %s", argv[0], i, argv[3]); - - return ret; - } - - /* Usage: import sketch_name - * - * Import sketch_name and append - */ - if (BU_STR_EQUAL(argv[1], "import")) { - struct bg_polygon *gpp; - size_t i; - - if (argc != 3) - goto bad; - - if ((gpp = ged_import_polygon(gedp, argv[2])) == (struct bg_polygon *)0) { - bu_vls_printf(gedp->ged_result_str, "%s: failed to import sketch %s", argv[0], argv[2]); - return GED_ERROR; - } - - i = gdpsp->gdps_polygons.num_polygons; - ++gdpsp->gdps_polygons.num_polygons; - gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_realloc(gdpsp->gdps_polygons.polygon, - gdpsp->gdps_polygons.num_polygons * sizeof(struct bg_polygon), - "realloc polygon"); - - gdpsp->gdps_polygons.polygon[i] = *gpp; /* struct copy */ - VMOVE(gdpsp->gdps_polygons.polygon[i].gp_color, gdpsp->gdps_color); - gdpsp->gdps_polygons.polygon[i].gp_line_style = gdpsp->gdps_line_style; - gdpsp->gdps_polygons.polygon[i].gp_line_width = gdpsp->gdps_line_width; - - to_refresh_view(gdvp); - return GED_OK; - } - - if (BU_STR_EQUAL(argv[1], "fill")) { - size_t i; - vect2d_t vdir; - fastf_t vdelta; - - if (argc != 5) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%lf %lf", &vdir[X], &vdir[Y]) != 2) { - bu_vls_printf(gedp->ged_result_str, "%s: bad dir: %s", argv[0], argv[3]); - goto bad; - } - - if (bu_sscanf(argv[4], "%lf", &vdelta) != 1) { - bu_vls_printf(gedp->ged_result_str, "%s: bad delta: %s", argv[0], argv[4]); - goto bad; - } - - ged_polygon_fill_segments(gedp, &gdpsp->gdps_polygons.polygon[i], vdir, vdelta); - - return GED_OK; - } - - /* Usage: area i - * - * Find area of polygon i - */ - if (BU_STR_EQUAL(argv[1], "area")) { - size_t i; - double area; - - if (argc != 3) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - area = bg_find_polygon_area(&gdpsp->gdps_polygons.polygon[i], CLIPPER_MAX, - gdpsp->gdps_model2view, gdpsp->gdps_scale); - bu_vls_printf(gedp->ged_result_str, "%lf", area); - - return GED_OK; - } - - /* Usage: polygons_overlap i j - * - * Do polygons i and j overlap? - */ - if (BU_STR_EQUAL(argv[1], "polygons_overlap")) { - size_t i, j; - int ret; - - if (argc != 4) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%zu", &j) != 1 || - j >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - ret = ged_polygons_overlap(gedp, &gdpsp->gdps_polygons.polygon[i], &gdpsp->gdps_polygons.polygon[j]); - bu_vls_printf(gedp->ged_result_str, "%d", ret); - - return GED_OK; - } - - /* Usage: [v]polygons [poly_list] - * - * Set/get the polygon list. If vpolygons is specified then - * the polygon list is in view coordinates. - */ - if (BU_STR_EQUAL(argv[1], "polygons") || BU_STR_EQUAL(argv[1], "vpolygons")) { - register size_t i, j, k; - int ac; - int vflag; - - if (BU_STR_EQUAL(argv[1], "polygons")) - vflag = 0; - else - vflag = 1; - if (argc == 2) { - for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { - bu_vls_printf(gedp->ged_result_str, " {"); - - for (j = 0; j < gdpsp->gdps_polygons.polygon[i].num_contours; ++j) { - bu_vls_printf(gedp->ged_result_str, " {%d ", gdpsp->gdps_polygons.polygon[i].hole[j]); - - for (k = 0; k < gdpsp->gdps_polygons.polygon[i].contour[j].num_points; ++k) { - point_t pt; - - if (vflag) { - MAT4X3PNT(pt, gdvp->gdv_view->gv_model2view, gdpsp->gdps_polygons.polygon[i].contour[j].point[k]); - } else { - VMOVE(pt, gdpsp->gdps_polygons.polygon[i].contour[j].point[k]); - } - - bu_vls_printf(gedp->ged_result_str, " {%lf %lf %lf} ", V3ARGS(pt)); - } - - bu_vls_printf(gedp->ged_result_str, "} "); - } - - bu_vls_printf(gedp->ged_result_str, "} "); - } - - return GED_OK; - } - - if (argc == 3) { - size_t polygon_ac; - const char **polygon_av; - - /* Split into polygons */ - if (Tcl_SplitList(interp, argv[2], &ac, &polygon_av) != TCL_OK) { - bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); - return GED_ERROR; - } - polygon_ac = ac; - - to_polygons_free(&gdpsp->gdps_polygons); - gdpsp->gdps_target_polygon_i = 0; - - if (polygon_ac < 1) { - to_refresh_view(gdvp); - return GED_OK; - } - - if (to_extract_polygons_av(interp, gedp, gdvp, gdpsp, polygon_ac, polygon_av, gdvp->gdv_view->gv_mode, vflag) != GED_OK) { - Tcl_Free((char *)polygon_av); - return GED_ERROR; - } - - Tcl_Free((char *)polygon_av); - to_refresh_view(gdvp); - return GED_OK; - } - } - - /* Usage: replace_poly i plist - * - * Replace polygon i with plist. - */ - if (BU_STR_EQUAL(argv[1], "replace_poly")) { - size_t i; - int ac; - size_t contour_ac; - const char **contour_av; - struct bg_polygon gp; - - if (argc != 4) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - /* Split the polygon in argv[3] into contours */ - if (Tcl_SplitList(interp, argv[3], &ac, &contour_av) != TCL_OK || - ac < 1) { - bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); - return GED_ERROR; - } - contour_ac = ac; - - if (to_extract_contours_av(interp, gedp, gdvp, &gp, contour_ac, contour_av, gdvp->gdv_view->gv_mode, 0) != GED_OK) { - Tcl_Free((char *)contour_av); - return GED_ERROR; - } - - to_polygon_free(&gdpsp->gdps_polygons.polygon[i]); - - /* Not doing a struct copy to avoid overwriting the color, line width and line style. */ - gdpsp->gdps_polygons.polygon[i].num_contours = gp.num_contours; - gdpsp->gdps_polygons.polygon[i].hole = gp.hole; - gdpsp->gdps_polygons.polygon[i].contour = gp.contour; - - to_refresh_view(gdvp); - return GED_OK; - } - - /* Usage: append_point i j pt - * - * Append pt to polygon_i/contour_j - */ - if (BU_STR_EQUAL(argv[1], "append_point")) { - size_t i, j, k; - double pt[ELEMENTS_PER_POINT]; /* must be double for scan */ - - if (argc != 5) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%zu", &j) != 1 || - j >= gdpsp->gdps_polygons.polygon[i].num_contours) - goto bad; - - if (bu_sscanf(argv[4], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) - goto bad; - - k = gdpsp->gdps_polygons.polygon[i].contour[j].num_points; - ++gdpsp->gdps_polygons.polygon[i].contour[j].num_points; - gdpsp->gdps_polygons.polygon[i].contour[j].point = (point_t *)bu_realloc(gdpsp->gdps_polygons.polygon[i].contour[j].point, - gdpsp->gdps_polygons.polygon[i].contour[j].num_points * sizeof(point_t), - "realloc point"); - VMOVE(gdpsp->gdps_polygons.polygon[i].contour[j].point[k], pt); - to_refresh_view(gdvp); - return GED_OK; - } - - /* Usage: get_point i j k - * - * Get polygon_i/contour_j/point_k - */ - if (BU_STR_EQUAL(argv[1], "get_point")) { - size_t i, j, k; - - if (argc != 5) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%zu", &j) != 1 || - j >= gdpsp->gdps_polygons.polygon[i].num_contours) - goto bad; - - if (bu_sscanf(argv[4], "%zu", &k) != 1 || - k >= gdpsp->gdps_polygons.polygon[i].contour[j].num_points) - goto bad; - - bu_vls_printf(gedp->ged_result_str, "%lf %lf %lf", V3ARGS(gdpsp->gdps_polygons.polygon[i].contour[j].point[k])); - return GED_OK; - } - - /* Usage: replace_point i j k pt - * - * Replace polygon_i/contour_j/point_k with pt - */ - if (BU_STR_EQUAL(argv[1], "replace_point")) { - size_t i, j, k; - double pt[ELEMENTS_PER_POINT]; - - if (argc != 6) - goto bad; - - if (bu_sscanf(argv[2], "%zu", &i) != 1 || - i >= gdpsp->gdps_polygons.num_polygons) - goto bad; - - if (bu_sscanf(argv[3], "%zu", &j) != 1 || - j >= gdpsp->gdps_polygons.polygon[i].num_contours) - goto bad; - - if (bu_sscanf(argv[4], "%zu", &k) != 1 || - k >= gdpsp->gdps_polygons.polygon[i].contour[j].num_points) - goto bad; - - if (bu_sscanf(argv[5], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) - goto bad; - - VMOVE(gdpsp->gdps_polygons.polygon[i].contour[j].point[k], pt); - to_refresh_view(gdvp); - return GED_OK; - } - -bad: - - return GED_ERROR; -} - - -int go_data_move(Tcl_Interp *UNUSED(interp), struct ged *gedp, struct ged_dm_view *gdvp, @@ -8042,768 +6936,7 @@ } #endif - -int -go_poly_circ_mode(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_poly_circ_mode_func(interp, gedp, gdvp, argc, argv, usage); -} - - HIDDEN int -to_poly_circ_mode(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr UNUSED(func), - const char *usage, - int UNUSED(maxargs)) -{ - struct ged_dm_view *gdvp; - struct bu_vls bindings = BU_VLS_INIT_ZERO; - 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_poly_circ_mode_func */ - argv[1] = argv[0]; - ret = to_poly_circ_mode_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); - - if (dm_get_pathname(gdvp->gdv_dmp)) { - bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_circ %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)); - Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); - } - bu_vls_free(&bindings); - - to_refresh_view(gdvp); - - return ret; -} - - -HIDDEN int -to_poly_circ_mode_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[4]; - int x, y; - fastf_t fx, fy; - point_t v_pt, m_pt; - struct bu_vls plist = 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; - - gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; - VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); - MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); - MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); - MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); - - gedp->ged_gvp = gdvp->gdv_view; - - 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; - gdvp->gdv_view->gv_mode = TCLCAD_POLY_CIRCLE_MODE; - - 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); - int snapped = 0; - if (gedp->ged_gvp->gv_snap_lines) { - snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); - } - if (!snapped && gedp->ged_gvp->gv_grid.snap) { - ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); - } - - MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); - VMOVE(gdpsp->gdps_prev_point, v_pt); - - bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} }", - V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt)); - ac = 3; - av[0] = "data_polygons"; - av[1] = "append_poly"; - av[2] = bu_vls_addr(&plist); - av[3] = (char *)0; - - if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; - else - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; - - (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); - bu_vls_free(&plist); - - return GED_OK; -} - - -int -go_poly_cont_build(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_poly_cont_build_func(interp, gedp, gdvp, argc, argv, usage, 0); -} - - -HIDDEN int -to_poly_cont_build(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_poly_cont_build_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage, 1); - - to_refresh_view(gdvp); - - return ret; -} - - -HIDDEN int -to_poly_cont_build_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int UNUSED(argc), - const char *argv[], - const char *usage, - int doBind) -{ - 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; - - gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; - VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); - MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); - MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); - MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); - - gedp->ged_gvp = gdvp->gdv_view; - - 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; - gdvp->gdv_view->gv_mode = TCLCAD_POLY_CONTOUR_MODE; - - 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); - int snapped = 0; - if (gedp->ged_gvp->gv_snap_lines) { - snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); - } - if (!snapped && gedp->ged_gvp->gv_grid.snap) { - ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); - } - - MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); - - av[0] = "data_polygons"; - if (gdpsp->gdps_cflag == 0) { - struct bu_vls plist = BU_VLS_INIT_ZERO; - struct bu_vls bindings = BU_VLS_INIT_ZERO; - - if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; - else - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; - - gdpsp->gdps_cflag = 1; - gdpsp->gdps_curr_point_i = 1; - - bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} }", V3ARGS(m_pt), V3ARGS(m_pt)); - ac = 3; - av[1] = "append_poly"; - av[2] = bu_vls_addr(&plist); - av[3] = (char *)0; - - (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); - bu_vls_free(&plist); - - if (doBind && dm_get_pathname(gdvp->gdv_dmp)) { - bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_cont %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)); - Tcl_Eval(interp, bu_vls_addr(&bindings)); - } - bu_vls_free(&bindings); - } else { - 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[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); - - ac = 5; - av[1] = "append_point"; - av[4] = bu_vls_addr(&plist); - av[5] = (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); - - ++gdpsp->gdps_curr_point_i; - } - - return GED_OK; -} - - -int -go_poly_cont_build_end(Tcl_Interp *UNUSED(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); - - if (argc != 1) { - 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_poly_cont_build_end_func(gdvp, argc, argv); -} - - -HIDDEN int -to_poly_cont_build_end(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 != 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; - } - - /* shift the command name to argv[1] before calling to_poly_ell_mode_func */ - argv[1] = argv[0]; - ret = to_poly_cont_build_end_func(gdvp, argc-1, argv+1); - - to_refresh_view(gdvp); - return ret; -} - - -HIDDEN int -to_poly_cont_build_end_func(struct ged_dm_view *gdvp, - int UNUSED(argc), - const char *argv[]) -{ - if (argv[0][0] == 's') - gdvp->gdv_view->gv_sdata_polygons.gdps_cflag = 0; - else - gdvp->gdv_view->gv_data_polygons.gdps_cflag = 0; - - return GED_OK; -} - - -int -go_poly_ell_mode(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_poly_ell_mode_func(interp, gedp, gdvp, argc, argv, usage); -} - - -HIDDEN int -to_poly_ell_mode(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr UNUSED(func), - const char *usage, - int UNUSED(maxargs)) -{ - struct ged_dm_view *gdvp; - struct bu_vls bindings = BU_VLS_INIT_ZERO; - 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_poly_ell_mode_func */ - argv[1] = argv[0]; - ret = to_poly_ell_mode_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); - - if (dm_get_pathname(gdvp->gdv_dmp)) { - bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_ell %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)); - Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); - } - bu_vls_free(&bindings); - - to_refresh_view(gdvp); - - return ret; -} - - -HIDDEN int -to_poly_ell_mode_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[4]; - int x, y; - fastf_t fx, fy; - point_t v_pt, m_pt; - struct bu_vls plist = 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; - - gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; - VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); - MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); - MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); - MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); - - gedp->ged_gvp = gdvp->gdv_view; - - 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; - gdvp->gdv_view->gv_mode = TCLCAD_POLY_ELLIPSE_MODE; - - 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); - int snapped = 0; - if (gedp->ged_gvp->gv_snap_lines) { - snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); - } - if (!snapped && gedp->ged_gvp->gv_grid.snap) { - ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); - } - - MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); - VMOVE(gdpsp->gdps_prev_point, v_pt); - - bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} }", - V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt)); - ac = 3; - av[0] = "data_polygons"; - av[1] = "append_poly"; - av[2] = bu_vls_addr(&plist); - av[3] = (char *)0; - - if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; - else - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; - - (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); - bu_vls_free(&plist); - - return GED_OK; -} - - -int -go_poly_rect_mode(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 || 4 < argc) { - 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_poly_rect_mode_func(interp, gedp, gdvp, argc, argv, usage); -} - - -HIDDEN int -to_poly_rect_mode(struct ged *gedp, - int argc, - const char *argv[], - ged_func_ptr UNUSED(func), - const char *usage, - int UNUSED(maxargs)) -{ - struct ged_dm_view *gdvp; - struct bu_vls bindings = BU_VLS_INIT_ZERO; - 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 || 5 < argc) { - 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_poly_rect_mode_func */ - argv[1] = argv[0]; - ret = to_poly_rect_mode_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); - - if (dm_get_pathname(gdvp->gdv_dmp)) { - bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_rect %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)); - Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); - } - bu_vls_free(&bindings); - - to_refresh_view(gdvp); - - return ret; -} - - -HIDDEN int -to_poly_rect_mode_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[], - const char *usage) -{ - int ac; - char *av[4]; - int x, y; - int sflag; - fastf_t fx, fy; - point_t v_pt, m_pt; - struct bu_vls plist = 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; - - gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; - VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); - MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); - MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); - MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); - - gedp->ged_gvp = gdvp->gdv_view; - - 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; - } - - if (argc == 3) - sflag = 0; - else { - if (bu_sscanf(argv[3], "%d", &sflag) != 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; - - if (sflag) - gdvp->gdv_view->gv_mode = TCLCAD_POLY_SQUARE_MODE; - else - gdvp->gdv_view->gv_mode = TCLCAD_POLY_RECTANGLE_MODE; - - 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); - int snapped = 0; - if (gedp->ged_gvp->gv_snap_lines) { - snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); - } - if (!snapped && gedp->ged_gvp->gv_grid.snap) { - ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); - } - - MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); - VMOVE(gdpsp->gdps_prev_point, v_pt); - - bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} }", - V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt)); - ac = 3; - av[0] = "data_polygons"; - av[1] = "append_poly"; - av[2] = bu_vls_addr(&plist); - av[3] = (char *)0; - - if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; - else - gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; - - (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); - bu_vls_free(&plist); - - return GED_OK; -} - - -HIDDEN int to_prim_label(struct ged *gedp, int argc, const char *argv[], Added: brlcad/trunk/src/libtclcad/tclcad_polygons.c =================================================================== --- brlcad/trunk/src/libtclcad/tclcad_polygons.c (rev 0) +++ brlcad/trunk/src/libtclcad/tclcad_polygons.c 2020-07-14 21:34:33 UTC (rev 76337) @@ -0,0 +1,1849 @@ +/* T C L C A D _ O B J . 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_obj.c + * + * A quasi-object-oriented database interface. + * + * A GED object contains the attributes and methods for controlling a + * BRL-CAD geometry edit object. + * + */ +/** @} */ + +#include "common.h" + +#include "tclcad.h" + +/* Private headers */ +#include "tclcad_private.h" + +/* + * Weird upper limit from clipper ---> sqrt(2^63 -1)/2 + * Probably should be sqrt(2^63 -1) + */ +#define CLIPPER_MAX 1518500249 + + +/* These functions should be macros */ +static void +to_polygon_free(struct bg_polygon *gpp) +{ + register size_t j; + + if (gpp->num_contours == 0) + return; + + for (j = 0; j < gpp->num_contours; ++j) + if (gpp->contour[j].num_points > 0) + bu_free((void *)gpp->contour[j].point, "contour points"); + + bu_free((void *)gpp->contour, "contour"); + bu_free((void *)gpp->hole, "hole"); + gpp->num_contours = 0; +} + + +static void +to_polygons_free(struct bg_polygons *gpp) +{ + register size_t i; + + if (gpp->num_polygons == 0) + return; + + for (i = 0; i < gpp->num_polygons; ++i) { + to_polygon_free(&gpp->polygon[i]); + } + + bu_free((void *)gpp->polygon, "data polygons"); + gpp->polygon = (struct bg_polygon *)0; + gpp->num_polygons = 0; +} + + +static int +to_extract_contours_av(Tcl_Interp *interp, struct ged *gedp, struct ged_dm_view *gdvp, struct bg_polygon *gpp, size_t contour_ac, const char **contour_av, int mode, int vflag) +{ + register size_t j = 0, k = 0; + + gpp->num_contours = contour_ac; + gpp->hole = NULL; + gpp->contour = NULL; + + if (contour_ac == 0) + return GED_OK; + + gpp->hole = (int *)bu_calloc(contour_ac, sizeof(int), "hole"); + gpp->contour = (struct bg_poly_contour *)bu_calloc(contour_ac, sizeof(struct bg_poly_contour), "contour"); + + for (j = 0; j < contour_ac; ++j) { + int ac; + size_t point_ac; + const char **point_av; + int hole; + + /* Split contour j into points */ + if (Tcl_SplitList(interp, contour_av[j], &ac, &point_av) != TCL_OK) { + bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); + return GED_ERROR; + } + point_ac = ac; + + /* point_ac includes a hole flag */ + if (mode != TCLCAD_POLY_CONTOUR_MODE && point_ac < 4) { + bu_vls_printf(gedp->ged_result_str, "There must be at least 3 points per contour"); + Tcl_Free((char *)point_av); + return GED_ERROR; + } + + gpp->contour[j].num_points = point_ac - 1; + gpp->contour[j].point = (point_t *)bu_calloc(point_ac, sizeof(point_t), "point"); + + if (bu_sscanf(point_av[0], "%d", &hole) != 1) { + bu_vls_printf(gedp->ged_result_str, "contour %zu, point %zu: bad hole flag - %s\n", + j, k, point_av[k]); + Tcl_Free((char *)point_av); + return GED_ERROR; + } + gpp->hole[j] = hole; + + for (k = 1; k < point_ac; ++k) { + double pt[ELEMENTS_PER_POINT]; /* must be double for scanf */ + + if (bu_sscanf(point_av[k], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) { + bu_vls_printf(gedp->ged_result_str, "contour %zu, point %zu: bad data point - %s\n", + j, k, point_av[k]); + Tcl_Free((char *)point_av); + return GED_ERROR; + } + + if (vflag) { + MAT4X3PNT(gpp->contour[j].point[k-1], gdvp->gdv_view->gv_view2model, pt); + } else { + VMOVE(gpp->contour[j].point[k-1], pt); + } + + } + + Tcl_Free((char *)point_av); + } + + return GED_OK; +} + + +static int +to_extract_polygons_av(Tcl_Interp *interp, struct ged *gedp, struct ged_dm_view *gdvp, bview_data_polygon_state *gdpsp, size_t polygon_ac, const char **polygon_av, int mode, int vflag) +{ + register size_t i; + int ac; + + gdpsp->gdps_polygons.num_polygons = polygon_ac; + gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_calloc(polygon_ac, sizeof(struct bg_polygon), "data polygons"); + for (i = 0; i < polygon_ac; ++i) { + // TODO - allocate properties containers for each polygon + } + + for (i = 0; i < polygon_ac; ++i) { + size_t contour_ac; + const char **contour_av; + + /* Split polygon i into contours */ + if (Tcl_SplitList(interp, polygon_av[i], &ac, &contour_av) != TCL_OK) { + bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); + return GED_ERROR; + } + contour_ac = ac; + + if (to_extract_contours_av(interp, gedp, gdvp, &gdpsp->gdps_polygons.polygon[i], contour_ac, contour_av, mode, vflag) != GED_OK) { + Tcl_Free((char *)contour_av); + return GED_ERROR; + } + + VMOVE(gdpsp->gdps_polygons.polygon[i].gp_color, gdpsp->gdps_color); + if (contour_ac) + Tcl_Free((char *)contour_av); + } + + return GED_OK; +} + + + +int +to_data_polygons_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[]) +{ + 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; + + gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; + gdpsp->gdps_data_vZ = gdvp->gdv_view->gv_data_vZ; + VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); + MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); + MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); + MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); + + if (BU_STR_EQUAL(argv[1], "target_poly")) { + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%lu", gdpsp->gdps_target_polygon_i); + return GED_OK; + } + + if (argc == 3) { + size_t i; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || i > gdpsp->gdps_polygons.num_polygons) + goto bad; + + gdpsp->gdps_target_polygon_i = i; + + return GED_OK; + } + + goto bad; + } + + if (BU_STR_EQUAL(argv[1], "clip_type")) { + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_clip_type); + return GED_OK; + } + + if (argc == 3) { + int op; + + if (bu_sscanf(argv[2], "%d", &op) != 1 || op > bg_Xor) + goto bad; + + gdpsp->gdps_clip_type = (bg_clip_t)op; + + return GED_OK; + } + + goto bad; + } + + if (BU_STR_EQUAL(argv[1], "draw")) { + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_draw); + return GED_OK; + } + + if (argc == 3) { + int i; + + if (bu_sscanf(argv[2], "%d", &i) != 1) + goto bad; + + if (i) + gdpsp->gdps_draw = 1; + else + gdpsp->gdps_draw = 0; + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + if (BU_STR_EQUAL(argv[1], "moveall")) { + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_moveAll); + return GED_OK; + } + + if (argc == 3) { + int i; + + if (bu_sscanf(argv[2], "%d", &i) != 1) + goto bad; + + if (i) + gdpsp->gdps_moveAll = 1; + else + gdpsp->gdps_moveAll = 0; + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: poly_color i [r g b] + * + * Set/get the color of polygon i. + */ + if (BU_STR_EQUAL(argv[1], "poly_color")) { + size_t i; + + if (argc == 3) { + /* Get the color for polygon i */ + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + bu_vls_printf(gedp->ged_result_str, "%d %d %d", + V3ARGS(gdpsp->gdps_polygons.polygon[i].gp_color)); + + return GED_OK; + } + + if (argc == 6) { + int r, g, b; + + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + /* set background color */ + if (bu_sscanf(argv[3], "%d", &r) != 1 || + bu_sscanf(argv[4], "%d", &g) != 1 || + bu_sscanf(argv[5], "%d", &b) != 1) + goto bad; + + /* validate color */ + if (r < 0 || 255 < r || + g < 0 || 255 < g || + b < 0 || 255 < b) + goto bad; + + /* Set the color for polygon i */ + VSET(gdpsp->gdps_polygons.polygon[i].gp_color, r, g, b); + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: color [r g b] + * + * Set the color of all polygons, or get the default polygon color. + */ + if (BU_STR_EQUAL(argv[1], "color")) { + size_t i; + + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%d %d %d", + V3ARGS(gdpsp->gdps_color)); + + return GED_OK; + } + + if (argc == 5) { + int r, g, b; + + /* set background color */ + if (bu_sscanf(argv[2], "%d", &r) != 1 || + bu_sscanf(argv[3], "%d", &g) != 1 || + bu_sscanf(argv[4], "%d", &b) != 1) + goto bad; + + /* validate color */ + if (r < 0 || 255 < r || + g < 0 || 255 < g || + b < 0 || 255 < b) + goto bad; + + /* Set the color for all polygons */ + for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { + VSET(gdpsp->gdps_polygons.polygon[i].gp_color, r, g, b); + } + + /* Set the default polygon color */ + VSET(gdpsp->gdps_color, r, g, b); + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: poly_line_width i [w] + * + * Set/get the line width of polygon i. + */ + if (BU_STR_EQUAL(argv[1], "poly_line_width")) { + size_t i; + + if (argc == 3) { + /* Get the line width for polygon i */ + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_polygons.polygon[i].gp_line_width); + + return GED_OK; + } + + if (argc == 4) { + int line_width; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%d", &line_width) != 1) + goto bad; + + if (line_width < 0) + line_width = 0; + + gdpsp->gdps_polygons.polygon[i].gp_line_width = line_width; + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: line_width [w] + * + * Set the line width of all polygons, or get the default polygon line width. + */ + if (BU_STR_EQUAL(argv[1], "line_width")) { + size_t i; + + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_line_width); + return GED_OK; + } + + if (argc == 3) { + int line_width; + + if (bu_sscanf(argv[2], "%d", &line_width) != 1) + goto bad; + + if (line_width < 0) + line_width = 0; + + /* Set the line width for all polygons */ + for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { + gdpsp->gdps_polygons.polygon[i].gp_line_width = line_width; + } + + /* Set the default line width */ + gdpsp->gdps_line_width = line_width; + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: poly_line_style i [w] + * + * Set/get the line style of polygon i. + */ + if (BU_STR_EQUAL(argv[1], "poly_line_style")) { + size_t i; + + if (argc == 3) { + /* Get the line style for polygon i */ + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_polygons.polygon[i].gp_line_style); + + return GED_OK; + } + + if (argc == 4) { + int line_style; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%d", &line_style) != 1) + goto bad; + + + if (line_style <= 0) + gdpsp->gdps_polygons.polygon[i].gp_line_style = 0; + else + gdpsp->gdps_polygons.polygon[i].gp_line_style = 1; + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: line_style [w] + * + * Set the line style of all polygons, or get the default polygon line style. + */ + if (BU_STR_EQUAL(argv[1], "line_style")) { + size_t i; + + if (argc == 2) { + bu_vls_printf(gedp->ged_result_str, "%d", gdpsp->gdps_line_style); + return GED_OK; + } + + if (argc == 3) { + int line_style; + + if (bu_sscanf(argv[2], "%d", &line_style) != 1) + goto bad; + + if (line_style <= 0) + line_style = 0; + else + line_style = 1; + + /* Set the line width for all polygons */ + for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { + gdpsp->gdps_polygons.polygon[i].gp_line_style = line_style; + } + + /* Set the default line style */ + gdpsp->gdps_line_style = line_style; + + to_refresh_view(gdvp); + return GED_OK; + } + + goto bad; + } + + /* Usage: append_poly plist + * + * Append the polygon specified by plist. + */ + if (BU_STR_EQUAL(argv[1], "append_poly")) { + if (argc != 3) + goto bad; + + if (argc == 3) { + register size_t i; + int ac; + size_t contour_ac; + const char **contour_av; + + /* Split the polygon in argv[2] into contours */ + if (Tcl_SplitList(interp, argv[2], &ac, &contour_av) != TCL_OK || + ac < 1) { + bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); + return GED_ERROR; + } + contour_ac = ac; + + i = gdpsp->gdps_polygons.num_polygons; + ++gdpsp->gdps_polygons.num_polygons; + gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_realloc(gdpsp->gdps_polygons.polygon, + gdpsp->gdps_polygons.num_polygons * sizeof(struct bg_polygon), + "realloc polygon"); + + if (to_extract_contours_av(interp, gedp, gdvp, &gdpsp->gdps_polygons.polygon[i], + contour_ac, contour_av, gdvp->gdv_view->gv_mode, 0) != GED_OK) { + Tcl_Free((char *)contour_av); + return GED_ERROR; + } + + VMOVE(gdpsp->gdps_polygons.polygon[i].gp_color, gdpsp->gdps_color); + gdpsp->gdps_polygons.polygon[i].gp_line_style = gdpsp->gdps_line_style; + gdpsp->gdps_polygons.polygon[i].gp_line_width = gdpsp->gdps_line_width; + + Tcl_Free((char *)contour_av); + + to_refresh_view(gdvp); + return GED_OK; + } + } + + + /* Usage: clip [i j [op]] + * + * Clip polygon i using polygon j and op. + */ + if (BU_STR_EQUAL(argv[1], "clip")) { + size_t i, j; + int op; + struct bg_polygon *gpp; + + if (argc > 5) + goto bad; + + if (argc > 2) { + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + } else + i = gdpsp->gdps_target_polygon_i; + + if (argc > 3) { + if (bu_sscanf(argv[3], "%zu", &j) != 1 || + j >= gdpsp->gdps_polygons.num_polygons) + goto bad; + } else + j = gdpsp->gdps_polygons.num_polygons - 1; /* Default - use last polygon as the clip polygon */ + + /* Nothing to do */ + if (i == j) + return GED_OK; + + if (argc != 5) + op = gdpsp->gdps_clip_type; + else if (bu_sscanf(argv[4], "%d", &op) != 1 || op > bg_Xor) + goto bad; + + gpp = bg_clip_polygon((bg_clip_t)op, + &gdpsp->gdps_polygons.polygon[i], + &gdpsp->gdps_polygons.polygon[j], + CLIPPER_MAX, + gdpsp->gdps_model2view, + gdpsp->gdps_view2model); + + /* Free the target polygon */ + to_polygon_free(&gdpsp->gdps_polygons.polygon[i]); + + /* When using defaults, the clip polygon is assumed to be temporary and is removed after clipping */ + if (argc == 2) { + /* Free the clip polygon */ + to_polygon_free(&gdpsp->gdps_polygons.polygon[j]); + + /* No longer need space for the clip polygon */ + --gdpsp->gdps_polygons.num_polygons; + gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_realloc(gdpsp->gdps_polygons.polygon, + gdpsp->gdps_polygons.num_polygons * sizeof(struct bg_polygon), + "realloc polygon"); + } + + /* Replace the target polygon with the newly clipped polygon. */ + /* Not doing a struct copy to avoid overwriting the color, line width and line style. */ + gdpsp->gdps_polygons.polygon[i].num_contours = gpp->num_contours; + gdpsp->gdps_polygons.polygon[i].hole = gpp->hole; + gdpsp->gdps_polygons.polygon[i].contour = gpp->contour; + + /* Free the clipped polygon container */ + bu_free((void *)gpp, "clip gpp"); + + to_refresh_view(gdvp); + return GED_OK; + } + + /* Usage: export i sketch_name + * + * Export polygon i to sketch_name + */ + if (BU_STR_EQUAL(argv[1], "export")) { + size_t i; + int ret; + + if (argc != 4) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if ((ret = ged_export_polygon(gedp, gdpsp, i, argv[3])) != GED_OK) + bu_vls_printf(gedp->ged_result_str, "%s: failed to export polygon %lu to %s", argv[0], i, argv[3]); + + return ret; + } + + /* Usage: import sketch_name + * + * Import sketch_name and append + */ + if (BU_STR_EQUAL(argv[1], "import")) { + struct bg_polygon *gpp; + size_t i; + + if (argc != 3) + goto bad; + + if ((gpp = ged_import_polygon(gedp, argv[2])) == (struct bg_polygon *)0) { + bu_vls_printf(gedp->ged_result_str, "%s: failed to import sketch %s", argv[0], argv[2]); + return GED_ERROR; + } + + i = gdpsp->gdps_polygons.num_polygons; + ++gdpsp->gdps_polygons.num_polygons; + gdpsp->gdps_polygons.polygon = (struct bg_polygon *)bu_realloc(gdpsp->gdps_polygons.polygon, + gdpsp->gdps_polygons.num_polygons * sizeof(struct bg_polygon), + "realloc polygon"); + + gdpsp->gdps_polygons.polygon[i] = *gpp; /* struct copy */ + VMOVE(gdpsp->gdps_polygons.polygon[i].gp_color, gdpsp->gdps_color); + gdpsp->gdps_polygons.polygon[i].gp_line_style = gdpsp->gdps_line_style; + gdpsp->gdps_polygons.polygon[i].gp_line_width = gdpsp->gdps_line_width; + + to_refresh_view(gdvp); + return GED_OK; + } + + if (BU_STR_EQUAL(argv[1], "fill")) { + size_t i; + vect2d_t vdir; + fastf_t vdelta; + + if (argc != 5) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%lf %lf", &vdir[X], &vdir[Y]) != 2) { + bu_vls_printf(gedp->ged_result_str, "%s: bad dir: %s", argv[0], argv[3]); + goto bad; + } + + if (bu_sscanf(argv[4], "%lf", &vdelta) != 1) { + bu_vls_printf(gedp->ged_result_str, "%s: bad delta: %s", argv[0], argv[4]); + goto bad; + } + + ged_polygon_fill_segments(gedp, &gdpsp->gdps_polygons.polygon[i], vdir, vdelta); + + return GED_OK; + } + + /* Usage: area i + * + * Find area of polygon i + */ + if (BU_STR_EQUAL(argv[1], "area")) { + size_t i; + double area; + + if (argc != 3) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + area = bg_find_polygon_area(&gdpsp->gdps_polygons.polygon[i], CLIPPER_MAX, + gdpsp->gdps_model2view, gdpsp->gdps_scale); + bu_vls_printf(gedp->ged_result_str, "%lf", area); + + return GED_OK; + } + + /* Usage: polygons_overlap i j + * + * Do polygons i and j overlap? + */ + if (BU_STR_EQUAL(argv[1], "polygons_overlap")) { + size_t i, j; + int ret; + + if (argc != 4) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%zu", &j) != 1 || + j >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + ret = ged_polygons_overlap(gedp, &gdpsp->gdps_polygons.polygon[i], &gdpsp->gdps_polygons.polygon[j]); + bu_vls_printf(gedp->ged_result_str, "%d", ret); + + return GED_OK; + } + + /* Usage: [v]polygons [poly_list] + * + * Set/get the polygon list. If vpolygons is specified then + * the polygon list is in view coordinates. + */ + if (BU_STR_EQUAL(argv[1], "polygons") || BU_STR_EQUAL(argv[1], "vpolygons")) { + register size_t i, j, k; + int ac; + int vflag; + + if (BU_STR_EQUAL(argv[1], "polygons")) + vflag = 0; + else + vflag = 1; + if (argc == 2) { + for (i = 0; i < gdpsp->gdps_polygons.num_polygons; ++i) { + bu_vls_printf(gedp->ged_result_str, " {"); + + for (j = 0; j < gdpsp->gdps_polygons.polygon[i].num_contours; ++j) { + bu_vls_printf(gedp->ged_result_str, " {%d ", gdpsp->gdps_polygons.polygon[i].hole[j]); + + for (k = 0; k < gdpsp->gdps_polygons.polygon[i].contour[j].num_points; ++k) { + point_t pt; + + if (vflag) { + MAT4X3PNT(pt, gdvp->gdv_view->gv_model2view, gdpsp->gdps_polygons.polygon[i].contour[j].point[k]); + } else { + VMOVE(pt, gdpsp->gdps_polygons.polygon[i].contour[j].point[k]); + } + + bu_vls_printf(gedp->ged_result_str, " {%lf %lf %lf} ", V3ARGS(pt)); + } + + bu_vls_printf(gedp->ged_result_str, "} "); + } + + bu_vls_printf(gedp->ged_result_str, "} "); + } + + return GED_OK; + } + + if (argc == 3) { + size_t polygon_ac; + const char **polygon_av; + + /* Split into polygons */ + if (Tcl_SplitList(interp, argv[2], &ac, &polygon_av) != TCL_OK) { + bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); + return GED_ERROR; + } + polygon_ac = ac; + + to_polygons_free(&gdpsp->gdps_polygons); + gdpsp->gdps_target_polygon_i = 0; + + if (polygon_ac < 1) { + to_refresh_view(gdvp); + return GED_OK; + } + + if (to_extract_polygons_av(interp, gedp, gdvp, gdpsp, polygon_ac, polygon_av, gdvp->gdv_view->gv_mode, vflag) != GED_OK) { + Tcl_Free((char *)polygon_av); + return GED_ERROR; + } + + Tcl_Free((char *)polygon_av); + to_refresh_view(gdvp); + return GED_OK; + } + } + + /* Usage: replace_poly i plist + * + * Replace polygon i with plist. + */ + if (BU_STR_EQUAL(argv[1], "replace_poly")) { + size_t i; + int ac; + size_t contour_ac; + const char **contour_av; + struct bg_polygon gp; + + if (argc != 4) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + /* Split the polygon in argv[3] into contours */ + if (Tcl_SplitList(interp, argv[3], &ac, &contour_av) != TCL_OK || + ac < 1) { + bu_vls_printf(gedp->ged_result_str, "%s", Tcl_GetStringResult(interp)); + return GED_ERROR; + } + contour_ac = ac; + + if (to_extract_contours_av(interp, gedp, gdvp, &gp, contour_ac, contour_av, gdvp->gdv_view->gv_mode, 0) != GED_OK) { + Tcl_Free((char *)contour_av); + return GED_ERROR; + } + + to_polygon_free(&gdpsp->gdps_polygons.polygon[i]); + + /* Not doing a struct copy to avoid overwriting the color, line width and line style. */ + gdpsp->gdps_polygons.polygon[i].num_contours = gp.num_contours; + gdpsp->gdps_polygons.polygon[i].hole = gp.hole; + gdpsp->gdps_polygons.polygon[i].contour = gp.contour; + + to_refresh_view(gdvp); + return GED_OK; + } + + /* Usage: append_point i j pt + * + * Append pt to polygon_i/contour_j + */ + if (BU_STR_EQUAL(argv[1], "append_point")) { + size_t i, j, k; + double pt[ELEMENTS_PER_POINT]; /* must be double for scan */ + + if (argc != 5) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%zu", &j) != 1 || + j >= gdpsp->gdps_polygons.polygon[i].num_contours) + goto bad; + + if (bu_sscanf(argv[4], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) + goto bad; + + k = gdpsp->gdps_polygons.polygon[i].contour[j].num_points; + ++gdpsp->gdps_polygons.polygon[i].contour[j].num_points; + gdpsp->gdps_polygons.polygon[i].contour[j].point = (point_t *)bu_realloc(gdpsp->gdps_polygons.polygon[i].contour[j].point, + gdpsp->gdps_polygons.polygon[i].contour[j].num_points * sizeof(point_t), + "realloc point"); + VMOVE(gdpsp->gdps_polygons.polygon[i].contour[j].point[k], pt); + to_refresh_view(gdvp); + return GED_OK; + } + + /* Usage: get_point i j k + * + * Get polygon_i/contour_j/point_k + */ + if (BU_STR_EQUAL(argv[1], "get_point")) { + size_t i, j, k; + + if (argc != 5) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%zu", &j) != 1 || + j >= gdpsp->gdps_polygons.polygon[i].num_contours) + goto bad; + + if (bu_sscanf(argv[4], "%zu", &k) != 1 || + k >= gdpsp->gdps_polygons.polygon[i].contour[j].num_points) + goto bad; + + bu_vls_printf(gedp->ged_result_str, "%lf %lf %lf", V3ARGS(gdpsp->gdps_polygons.polygon[i].contour[j].point[k])); + return GED_OK; + } + + /* Usage: replace_point i j k pt + * + * Replace polygon_i/contour_j/point_k with pt + */ + if (BU_STR_EQUAL(argv[1], "replace_point")) { + size_t i, j, k; + double pt[ELEMENTS_PER_POINT]; + + if (argc != 6) + goto bad; + + if (bu_sscanf(argv[2], "%zu", &i) != 1 || + i >= gdpsp->gdps_polygons.num_polygons) + goto bad; + + if (bu_sscanf(argv[3], "%zu", &j) != 1 || + j >= gdpsp->gdps_polygons.polygon[i].num_contours) + goto bad; + + if (bu_sscanf(argv[4], "%zu", &k) != 1 || + k >= gdpsp->gdps_polygons.polygon[i].contour[j].num_points) + goto bad; + + if (bu_sscanf(argv[5], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) + goto bad; + + VMOVE(gdpsp->gdps_polygons.polygon[i].contour[j].point[k], pt); + to_refresh_view(gdvp); + return GED_OK; + } + +bad: + + return GED_ERROR; +} + +int +go_data_polygons(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage) +{ + 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 < 2 || 6 < argc) { + 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; + + ret = to_data_polygons_func(interp, gedp, gdvp, argc, argv); + if (ret == GED_ERROR) + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + + return ret; +} + + +int +to_data_polygons(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 < 3 || 7 < argc) { + 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_data_polygons_func */ + argv[1] = argv[0]; + ret = to_data_polygons_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1); + if (ret == GED_ERROR) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + } + + return ret; +} + + + +int +go_poly_circ_mode(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_poly_circ_mode_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_poly_circ_mode(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + struct bu_vls bindings = BU_VLS_INIT_ZERO; + 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_poly_circ_mode_func */ + argv[1] = argv[0]; + ret = to_poly_circ_mode_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); + + if (dm_get_pathname(gdvp->gdv_dmp)) { + bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_circ %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)); + Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); + } + bu_vls_free(&bindings); + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_poly_circ_mode_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[4]; + int x, y; + fastf_t fx, fy; + point_t v_pt, m_pt; + struct bu_vls plist = 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; + + gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; + VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); + MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); + MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); + MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); + + gedp->ged_gvp = gdvp->gdv_view; + + 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; + gdvp->gdv_view->gv_mode = TCLCAD_POLY_CIRCLE_MODE; + + 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); + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); + } + + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + VMOVE(gdpsp->gdps_prev_point, v_pt); + + bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} }", + V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt)); + ac = 3; + av[0] = "data_polygons"; + av[1] = "append_poly"; + av[2] = bu_vls_addr(&plist); + av[3] = (char *)0; + + if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; + else + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + + return GED_OK; +} + + +static int +to_poly_cont_build_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int UNUSED(argc), + const char *argv[], + const char *usage, + int doBind) +{ + 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; + + gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; + VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); + MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); + MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); + MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); + + gedp->ged_gvp = gdvp->gdv_view; + + 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; + gdvp->gdv_view->gv_mode = TCLCAD_POLY_CONTOUR_MODE; + + 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); + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); + } + + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + + av[0] = "data_polygons"; + if (gdpsp->gdps_cflag == 0) { + struct bu_vls plist = BU_VLS_INIT_ZERO; + struct bu_vls bindings = BU_VLS_INIT_ZERO; + + if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; + else + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; + + gdpsp->gdps_cflag = 1; + gdpsp->gdps_curr_point_i = 1; + + bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} }", V3ARGS(m_pt), V3ARGS(m_pt)); + ac = 3; + av[1] = "append_poly"; + av[2] = bu_vls_addr(&plist); + av[3] = (char *)0; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + + if (doBind && dm_get_pathname(gdvp->gdv_dmp)) { + bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_cont %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)); + Tcl_Eval(interp, bu_vls_addr(&bindings)); + } + bu_vls_free(&bindings); + } else { + 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[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); + + ac = 5; + av[1] = "append_point"; + av[4] = bu_vls_addr(&plist); + av[5] = (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); + + ++gdpsp->gdps_curr_point_i; + } + + return GED_OK; +} + +int +go_poly_cont_build(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_poly_cont_build_func(interp, gedp, gdvp, argc, argv, usage, 0); +} + + +int +to_poly_cont_build(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_poly_cont_build_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage, 1); + + to_refresh_view(gdvp); + + return ret; +} + + + +int +go_poly_cont_build_end(Tcl_Interp *UNUSED(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); + + if (argc != 1) { + 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_poly_cont_build_end_func(gdvp, argc, argv); +} + + +int +to_poly_cont_build_end(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 != 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; + } + + /* shift the command name to argv[1] before calling to_poly_ell_mode_func */ + argv[1] = argv[0]; + ret = to_poly_cont_build_end_func(gdvp, argc-1, argv+1); + + to_refresh_view(gdvp); + return ret; +} + + +int +to_poly_cont_build_end_func(struct ged_dm_view *gdvp, + int UNUSED(argc), + const char *argv[]) +{ + if (argv[0][0] == 's') + gdvp->gdv_view->gv_sdata_polygons.gdps_cflag = 0; + else + gdvp->gdv_view->gv_data_polygons.gdps_cflag = 0; + + return GED_OK; +} + + +int +go_poly_ell_mode(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_poly_ell_mode_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_poly_ell_mode(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + struct bu_vls bindings = BU_VLS_INIT_ZERO; + 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_poly_ell_mode_func */ + argv[1] = argv[0]; + ret = to_poly_ell_mode_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); + + if (dm_get_pathname(gdvp->gdv_dmp)) { + bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_ell %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)); + Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); + } + bu_vls_free(&bindings); + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_poly_ell_mode_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[4]; + int x, y; + fastf_t fx, fy; + point_t v_pt, m_pt; + struct bu_vls plist = 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; + + gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; + VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); + MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); + MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); + MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); + + gedp->ged_gvp = gdvp->gdv_view; + + 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; + gdvp->gdv_view->gv_mode = TCLCAD_POLY_ELLIPSE_MODE; + + 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); + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); + } + + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + VMOVE(gdpsp->gdps_prev_point, v_pt); + + bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} }", + V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt)); + ac = 3; + av[0] = "data_polygons"; + av[1] = "append_poly"; + av[2] = bu_vls_addr(&plist); + av[3] = (char *)0; + + if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; + else + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + + return GED_OK; +} + + +int +go_poly_rect_mode(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 || 4 < argc) { + 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_poly_rect_mode_func(interp, gedp, gdvp, argc, argv, usage); +} + + +int +to_poly_rect_mode(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr UNUSED(func), + const char *usage, + int UNUSED(maxargs)) +{ + struct ged_dm_view *gdvp; + struct bu_vls bindings = BU_VLS_INIT_ZERO; + 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 || 5 < argc) { + 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_poly_rect_mode_func */ + argv[1] = argv[0]; + ret = to_poly_rect_mode_func(current_top->to_interp, gedp, gdvp, argc-1, argv+1, usage); + + if (dm_get_pathname(gdvp->gdv_dmp)) { + bu_vls_printf(&bindings, "bind %s <Motion> {%s mouse_poly_rect %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)); + Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings)); + } + bu_vls_free(&bindings); + + to_refresh_view(gdvp); + + return ret; +} + + +int +to_poly_rect_mode_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage) +{ + int ac; + char *av[4]; + int x, y; + int sflag; + fastf_t fx, fy; + point_t v_pt, m_pt; + struct bu_vls plist = 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; + + gdpsp->gdps_scale = gdvp->gdv_view->gv_scale; + VMOVE(gdpsp->gdps_origin, gdvp->gdv_view->gv_center); + MAT_COPY(gdpsp->gdps_rotation, gdvp->gdv_view->gv_rotation); + MAT_COPY(gdpsp->gdps_model2view, gdvp->gdv_view->gv_model2view); + MAT_COPY(gdpsp->gdps_view2model, gdvp->gdv_view->gv_view2model); + + gedp->ged_gvp = gdvp->gdv_view; + + 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; + } + + if (argc == 3) + sflag = 0; + else { + if (bu_sscanf(argv[3], "%d", &sflag) != 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; + + if (sflag) + gdvp->gdv_view->gv_mode = TCLCAD_POLY_SQUARE_MODE; + else + gdvp->gdv_view->gv_mode = TCLCAD_POLY_RECTANGLE_MODE; + + 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); + int snapped = 0; + if (gedp->ged_gvp->gv_snap_lines) { + snapped = ged_snap_to_lines(gedp, &v_pt[X], &v_pt[Y]); + } + if (!snapped && gedp->ged_gvp->gv_grid.snap) { + ged_snap_to_grid(gedp, &v_pt[X], &v_pt[Y]); + } + + MAT4X3PNT(m_pt, gdvp->gdv_view->gv_view2model, v_pt); + VMOVE(gdpsp->gdps_prev_point, v_pt); + + bu_vls_printf(&plist, "{ {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} {%lf %lf %lf} }", + V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt), V3ARGS(m_pt)); + ac = 3; + av[0] = "data_polygons"; + av[1] = "append_poly"; + av[2] = bu_vls_addr(&plist); + av[3] = (char *)0; + + if (gdpsp->gdps_polygons.num_polygons == gdpsp->gdps_target_polygon_i) + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_target_polygon_i; + else + gdpsp->gdps_curr_polygon_i = gdpsp->gdps_polygons.num_polygons; + + (void)to_data_polygons_func(interp, gedp, gdvp, ac, (const char **)av); + bu_vls_free(&plist); + + 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_polygons.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_private.h =================================================================== --- brlcad/trunk/src/libtclcad/tclcad_private.h 2020-07-14 20:46:34 UTC (rev 76336) +++ brlcad/trunk/src/libtclcad/tclcad_private.h 2020-07-14 21:34:33 UTC (rev 76337) @@ -79,12 +79,6 @@ extern int Rt_Init(Tcl_Interp *interp); -extern int to_data_polygons_func(Tcl_Interp *interp, - struct ged *gedp, - struct ged_dm_view *gdvp, - int argc, - const char *argv[]); - /* Utility functions */ extern int to_edit_redraw(struct ged *gedp, int argc, const char *argv[]); @@ -324,8 +318,73 @@ const char *usage, int maxargs); +/* Tclcad polygon routines */ +extern int to_data_polygons_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[]); +extern int to_data_polygons(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr func, + const char *usage, + int maxargs); +extern int to_poly_circ_mode(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr func, + const char *usage, + int maxargs); +extern int to_poly_circ_mode_func(Tcl_Interp *interp, + struct ged *gedp, + struct ged_dm_view *gdvp, + int argc, + const char *argv[], + const char *usage); +extern int to_poly_cont_build(struct ged *gedp, + int argc, + const char *argv[], + ged_func_ptr func, + const char *usage, + int maxargs); @@ 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