Revision: 76226
          http://sourceforge.net/p/brlcad/code/76226
Author:   starseeker
Date:     2020-06-26 17:11:19 +0000 (Fri, 26 Jun 2020)
Log Message:
-----------
Make the 'closeness' required for snapping at least theoretically adjustable

Modified Paths:
--------------
    brlcad/trunk/include/dm/bview.h
    brlcad/trunk/src/libged/ged.c
    brlcad/trunk/src/libged/view/snap.c

Modified: brlcad/trunk/include/dm/bview.h
===================================================================
--- brlcad/trunk/include/dm/bview.h     2020-06-26 16:43:05 UTC (rev 76225)
+++ brlcad/trunk/include/dm/bview.h     2020-06-26 17:11:19 UTC (rev 76226)
@@ -253,6 +253,7 @@
     struct bview_data_axes_state        gv_sdata_axes;
     struct bview_data_label_state gv_sdata_labels;
     struct bview_data_line_state  gv_sdata_lines;
+    double                       gv_snap_tol_factor;
     bview_data_polygon_state      gv_sdata_polygons;
     struct bview_grid_state     gv_grid;
     struct bview_other_state      gv_center_dot;

Modified: brlcad/trunk/src/libged/ged.c
===================================================================
--- brlcad/trunk/src/libged/ged.c       2020-06-26 16:43:05 UTC (rev 76225)
+++ brlcad/trunk/src/libged/ged.c       2020-06-26 17:11:19 UTC (rev 76226)
@@ -376,6 +376,9 @@
     /* FIXME: this causes the shaders.sh regression to fail */
     /* _ged_mat_aet(gvp); */
 
+    // Higher values indicate more aggressive behavior (i.e. points further 
away will be snapped).
+    gvp->gv_snap_tol_factor = 10;
+
     ged_view_update(gvp);
 }
 

Modified: brlcad/trunk/src/libged/view/snap.c
===================================================================
--- brlcad/trunk/src/libged/view/snap.c 2020-06-26 16:43:05 UTC (rev 76225)
+++ brlcad/trunk/src/libged/view/snap.c 2020-06-26 17:11:19 UTC (rev 76226)
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <ctype.h>
 #include <string.h>
+#include <errno.h>
 
 #include "bu/opt.h"
 #include "bu/vls.h"
@@ -35,13 +36,6 @@
 #include "dm.h"
 #include "../ged_private.h"
 
-int
-ged_snap_lines_2d(struct ged *gedp, point2d_t *p)
-{
-    if (!p || !gedp) return GED_ERROR;
-    return GED_ERROR;
-}
-
 struct ged_cp_info {
     double ctol_sq; // square of the distance that defines "close to a line"
 
@@ -96,7 +90,6 @@
            s->dsq = dsq;
            s->c_l = i;
            s->c_lset = lines;
-           printf("1st: %g: %g %g %g\n", sqrt(dsq), V3ARGS(c));
            ret = 1;
            continue;
        }
@@ -106,7 +99,6 @@
            s->dsq2 = dsq;
            s->c_l2 = i;
            s->c_lset2 = lines;
-           printf("2nd: %g: %g %g %g\n", sqrt(dsq), V3ARGS(c));
            ret = 2;
            continue;
        }
@@ -171,24 +163,17 @@
     double lavg = (width + height) * 0.5;
     double lwidth = (gdlsp->gdls_line_width) ? gdlsp->gdls_line_width : 1;
     double lratio = lwidth/lavg;
-    // TODO - need a scale factor to allow user to adjust this,
-    // rather than hard-coding 10...
-    double lrsize = gedp->ged_gvp->gv_size * lratio * 10;
+    double lrsize = gedp->ged_gvp->gv_size * lratio * 
gedp->ged_gvp->gv_snap_tol_factor;
     return lrsize*lrsize;
 }
 
 int
-ged_snap_lines_3d(struct ged *gedp, point_t *p)
+ged_snap_lines(point_t *out_pt, struct ged *gedp, point_t *p)
 {
     struct ged_cp_info cpinfo = GED_CP_INFO_INIT;
 
     if (!p || !gedp) return GED_ERROR;
 
-    // TODO - investigate how gv_scale, gv_size and friends are used.  
Somewhere
-    // in the view we should have enough information to get a pixel's physical
-    // size, and that should let us define a sane "close enough' based on the
-    // current active view.
-
     // There are some issues with line snapping that don't come up with grid
     // snapping - in particular, when are we "close enough" to a line to snap,
     // and how do we handle snapping when close enough to multiple lines?  We
@@ -196,10 +181,8 @@
     // point if we are close to multiple lines...
     int ret = 0;
     cpinfo.ctol_sq = line_tol_sq(gedp, &gedp->ged_gvp->gv_data_lines);
-    bu_log("%g\n", cpinfo.ctol_sq);
     ret += _find_closest_point(&cpinfo, p, &gedp->ged_gvp->gv_data_lines);
     cpinfo.ctol_sq = line_tol_sq(gedp, &gedp->ged_gvp->gv_sdata_lines);
-    bu_log("%g\n", cpinfo.ctol_sq);
     ret += _find_closest_point(&cpinfo, p, &gedp->ged_gvp->gv_sdata_lines);
 
     // Check if we are close enough to two line segments to warrant using the
@@ -211,19 +194,51 @@
 
     // If we found something, we can snap
     if (ret) {
-       bu_log("%g %g %g\n", V3ARGS(cpinfo.cp));
-    } else {
-       bu_log("no lines close enough for snapping\n");
+       VMOVE(*out_pt, cpinfo.cp);
+       return GED_OK;
     }
 
-    return GED_OK;
+    return GED_ERROR;
 }
 
 int
+_ged_opt_tol(struct bu_vls *msg, size_t argc, const char **argv, void *set_var)
+{
+    double *tol_set = (double *)set_var;
+
+    if (!argc) {
+       if (tol_set) (*tol_set) = -DBL_MAX;
+       return 0;
+    }
+
+    char *endptr = NULL;
+    errno = 0;
+    double d = strtod(argv[0], &endptr);
+
+    if (endptr != NULL && strlen(endptr) > 0) {
+        /* Had some invalid character in the input, fail */
+        if (msg) {
+            bu_vls_printf(msg, "Invalid string specifier for double: %s\n", 
argv[0]);
+        }
+        return -1;
+    }
+
+    if (errno == ERANGE) {
+        if (msg) {
+            bu_vls_printf(msg, "Invalid input for double (range error): %s\n", 
argv[0]);
+        }
+        return -1;
+    }
+
+    if (tol_set) (*tol_set) = d;
+    return 1;
+}
+
+int
 ged_view_snap(struct ged *gedp, int argc, const char *argv[])
 {
     static const char *usage = "[options] x y [z]";
-    int in_dim = 0;
+    double stol = DBL_MAX;
     int print_help = 0;
     int use_grid = 0;
     int use_lines = 0;
@@ -233,13 +248,14 @@
     point_t view_pt = VINIT_ZERO;
     struct bu_vls msg = BU_VLS_INIT_ZERO;
 
-    struct bu_opt_desc d[6];
+    struct bu_opt_desc d[7];
     BU_OPT(d[0], "h", "help",      "",  NULL,  &print_help,           "Print 
help and exit");
-    BU_OPT(d[1], "g", "grid",      "",  NULL,  &use_grid,             "Snap to 
the view grid");
-    BU_OPT(d[2], "l", "lines",     "",  NULL,  &use_lines,            "Snap to 
the view lines");
-    BU_OPT(d[3], "o", "obj-keypt", "",  NULL,  &use_object_keypoints, "Snap to 
drawn object keypoints");
-    BU_OPT(d[4], "w", "obj-lines", "",  NULL,  &use_object_lines,     "Snap to 
drawn object lines");
-    BU_OPT_NULL(d[5]);
+    BU_OPT(d[1], "t", "tol",    "[#]",  &_ged_opt_tol,  &stol,                 
"Set or report tolerance scale factor for snapping.");
+    BU_OPT(d[2], "g", "grid",      "",  NULL,  &use_grid,             "Snap to 
the view grid");
+    BU_OPT(d[3], "l", "lines",     "",  NULL,  &use_lines,            "Snap to 
the view lines");
+    BU_OPT(d[4], "o", "obj-keypt", "",  NULL,  &use_object_keypoints, "Snap to 
drawn object keypoints");
+    BU_OPT(d[5], "w", "obj-lines", "",  NULL,  &use_object_lines,     "Snap to 
drawn object lines");
+    BU_OPT_NULL(d[6]);
 
     argc-=(argc>0); argv+=(argc>0); /* skip command name argv[0] */
 
@@ -257,6 +273,21 @@
        return GED_OK;
     }
 
+    /* Handle tolerance */
+    if (stol < DBL_MAX || stol < -DBL_MAX + 1) {
+       if (stol > -DBL_MAX) {
+           gedp->ged_gvp->gv_snap_tol_factor = stol;
+           if (!opt_ret) {
+               bu_vls_printf(gedp->ged_result_str, "%g", 
gedp->ged_gvp->gv_snap_tol_factor);
+               return GED_OK;
+           }
+       } else {
+           // Report current tolerance
+           bu_vls_printf(gedp->ged_result_str, "%g", 
gedp->ged_gvp->gv_snap_tol_factor);
+           return GED_OK;
+       }
+    }
+
     /* adjust argc to match the leftovers of the options parsing */
     argc = opt_ret;
     if (argc != 2 && argc != 3) {
@@ -285,7 +316,6 @@
        VSET(vp, p[0], p[1], 0);
        MAT4X3PNT(p, gedp->ged_gvp->gv_view2model, vp);
        VMOVE(view_pt, p);
-       in_dim = 2;
     }
     /* We may get a 3D point instead */
     if (argc == 3) {
@@ -299,7 +329,6 @@
        MAT4X3PNT(vp, gedp->ged_gvp->gv_model2view, p);
        V2SET(view_pt_2d, vp[0], vp[1]);
        VMOVE(view_pt, p);
-       in_dim = 3;
     }
 
     GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
@@ -316,18 +345,23 @@
     }
 
     if (use_lines) {
-#if 0
-       if (in_dim == 2) {
-           ged_snap_lines_2d(gedp, &view_pt_2d);
+       point_t out_pt = VINIT_ZERO;
+       point_t vp = VINIT_ZERO;
+       // It's OK if we have no lines close enough to snap to -
+       // in that case just pass back the view pt.  If we do
+       // have a snap, update the output
+       if (ged_snap_lines(&out_pt, gedp, &view_pt) == GED_OK) {
+           MAT4X3PNT(vp, gedp->ged_gvp->gv_model2view, out_pt);
+           V2SET(view_pt_2d, vp[0], vp[1]);
+           VMOVE(view_pt, out_pt);
+       } else {
+           bu_vls_printf(gedp->ged_result_str, "no lines close enough for 
snapping");
+           return GED_OK;
        }
-#endif
-
-       if (in_dim == 3) {
-           ged_snap_lines_3d(gedp, &view_pt);
-       }
     }
 
-    bu_vls_printf(gedp->ged_result_str, "%g %g %g", V3ARGS(view_pt));
+    bu_vls_printf(gedp->ged_result_str, "%g %g %g\n", V3ARGS(view_pt));
+    bu_vls_printf(gedp->ged_result_str, "%g %g\n", view_pt_2d[X], 
view_pt_2d[Y]);
 
     bu_vls_free(&msg);
     return GED_OK;

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

Reply via email to