Revision: 52026
          http://brlcad.svn.sourceforge.net/brlcad/?rev=52026&view=rev
Author:   bob1961
Date:     2012-08-15 12:57:50 +0000 (Wed, 15 Aug 2012)
Log Message:
-----------
This is the initial installment of code to support bot editing in Archer. Also 
a few tweaks for editing pipes in Archer.

Modified Paths:
--------------
    brlcad/trunk/include/ged.h
    brlcad/trunk/include/tclcad.h
    brlcad/trunk/src/libged/CMakeLists.txt
    brlcad/trunk/src/libtclcad/tclcad_obj.c
    brlcad/trunk/src/tclscripts/archer/Archer.tcl
    brlcad/trunk/src/tclscripts/archer/CMakeLists.txt
    brlcad/trunk/src/tclscripts/lib/Ged.tcl

Added Paths:
-----------
    brlcad/trunk/src/libged/edbot.c
    brlcad/trunk/src/tclscripts/archer/BotEditFrame.tcl

Modified: brlcad/trunk/include/ged.h
===================================================================
--- brlcad/trunk/include/ged.h  2012-08-15 09:26:28 UTC (rev 52025)
+++ brlcad/trunk/include/ged.h  2012-08-15 12:57:50 UTC (rev 52026)
@@ -1078,6 +1078,11 @@
 GED_EXPORT extern int ged_find(struct ged *gedp, int argc, const char *argv[]);
 
 /**
+ * Find the bot point nearest the specified point in view coordinates.
+ */
+GED_EXPORT extern int ged_find_botpt_nearest_pt(struct ged *gedp, int argc, 
const char *argv[]);
+
+/**
  * Find the pipe point nearest the specified point in model coordinates.
  */
 GED_EXPORT extern int ged_find_pipept_nearest_pt(struct ged *gedp, int argc, 
const char *argv[]);
@@ -1340,6 +1345,11 @@
 GED_EXPORT extern int ged_move_arb_face(struct ged *gedp, int argc, const char 
*argv[]);
 
 /**
+ * Move the specified bot point.
+ */
+GED_EXPORT extern int ged_move_botpt(struct ged *gedp, int argc, const char 
*argv[]);
+
+/**
  * Move the specified pipe point.
  */
 GED_EXPORT extern int ged_move_pipept(struct ged *gedp, int argc, const char 
*argv[]);

Modified: brlcad/trunk/include/tclcad.h
===================================================================
--- brlcad/trunk/include/tclcad.h       2012-08-15 09:26:28 UTC (rev 52025)
+++ brlcad/trunk/include/tclcad.h       2012-08-15 12:57:50 UTC (rev 52026)
@@ -74,8 +74,9 @@
 #define TCLCAD_POLY_SQUARE_MODE 19
 #define TCLCAD_RECTANGLE_MODE 20
 #define TCLCAD_MOVE_PIPE_POINT_MODE 21
-#define TCLCAD_DATA_MOVE_OBJECT_MODE 22
-#define TCLCAD_DATA_MOVE_POINT_MODE 23
+#define TCLCAD_MOVE_BOT_POINT_MODE 22
+#define TCLCAD_DATA_MOVE_OBJECT_MODE 23
+#define TCLCAD_DATA_MOVE_POINT_MODE 24
 
 #define TCLCAD_OBJ_FB_MODE_OFF 0
 #define TCLCAD_OBJ_FB_MODE_UNDERLAY 1

Modified: brlcad/trunk/src/libged/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libged/CMakeLists.txt      2012-08-15 09:26:28 UTC (rev 
52025)
+++ brlcad/trunk/src/libged/CMakeLists.txt      2012-08-15 12:57:50 UTC (rev 
52026)
@@ -103,6 +103,7 @@
   dup.c
   eac.c
   echo.c
+  edbot.c
   edcodes.c
   edcomb.c
   edit.c

Added: brlcad/trunk/src/libged/edbot.c
===================================================================
--- brlcad/trunk/src/libged/edbot.c                             (rev 0)
+++ brlcad/trunk/src/libged/edbot.c     2012-08-15 12:57:50 UTC (rev 52026)
@@ -0,0 +1,233 @@
+/*                        E D B O T . C
+ * BRL-CAD
+ *
+ * Copyright (c) 1995-2012 United States Government as represented by
+ * the U.S. Army Research Laboratory.
+ *
+ * This program 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 program 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.
+ */
+/** @file libged/edbot.c
+ *
+ */
+
+#include "common.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#include "bio.h"
+#include "vmath.h"
+#include "nmg.h"
+#include "rtgeom.h"
+#include "ged.h"
+#include "nurb.h"
+#include "wdb.h"
+
+
+
+int
+ged_find_botpt_nearest_pt(struct ged *gedp, int argc, const char *argv[])
+{
+    static const char *usage = "bot view_xyz";
+    struct rt_db_internal intern;
+    struct rt_bot_internal *botip;
+    mat_t mat;
+    char *last;
+    vect_t view;
+    int nearest_pt;
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_VIEW(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc != 3) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    if ((last = strrchr(argv[1], '/')) == NULL)
+       last = (char *)argv[1];
+    else
+       ++last;
+
+    if (last[0] == '\0') {
+       bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    if (sscanf(argv[2], "%lf %lf %lf", &view[X], &view[Y], &view[Z]) != 3) {
+       bu_vls_printf(gedp->ged_result_str, "%s: bad view location - %s", 
argv[0], argv[2]);
+       return GED_ERROR;
+    }
+
+    /* This won't be used by rt_bot_find_v_nearest. Setting it anyway. */
+    view[Z] = 0.0;
+
+    if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], 
gedp->ged_wdbp, mat) == GED_ERROR) {
+       bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
+       intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+       bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
+       rt_db_free_internal(&intern);
+
+       return GED_ERROR;
+    }
+
+    botip = (struct rt_bot_internal *)intern.idb_ptr;
+    nearest_pt = rt_bot_find_v_nearest_pt2(botip, view, 
gedp->ged_gvp->gv_model2view);
+    bu_vls_printf(gedp->ged_result_str, "%d", nearest_pt);
+
+    rt_db_free_internal(&intern);
+    return GED_OK;
+}
+
+
+int
+ged_move_botpt(struct ged *gedp, int argc, const char *argv[])
+{
+    struct directory *dp;
+    static const char *usage = "[-r] bot vertex_i pt";
+    struct rt_db_internal intern;
+    struct rt_bot_internal *botip;
+    mat_t mat;
+    point_t pt;
+    size_t vertex_i;
+    int rflag = 0;
+    char *last;
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc < 4 || 5 < argc) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    if (argc == 5) {
+       if (argv[1][0] != '-' || argv[1][1] != 'r' || argv[1][2] != '\0') {
+           bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+           return GED_ERROR;
+       }
+
+       rflag = 1;
+       --argc;
+       ++argv;
+    }
+
+    if ((last = strrchr(argv[1], '/')) == NULL)
+       last = (char *)argv[1];
+    else
+       ++last;
+
+    if (last[0] == '\0') {
+       bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    dp = db_lookup(gedp->ged_wdbp->dbip, last, LOOKUP_QUIET);
+    if (dp == RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    if (sscanf(argv[2], "%zu", &vertex_i) != 1) {
+       bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", 
argv[0], argv[2]);
+       return GED_ERROR;
+    }
+
+    if (sscanf(argv[3], "%lf %lf %lf", &pt[X], &pt[Y], &pt[Z]) != 3) {
+       bu_vls_printf(gedp->ged_result_str, "%s: bad point - %s", argv[0], 
argv[3]);
+       return GED_ERROR;
+    }
+
+    VSCALE(pt, pt, gedp->ged_wdbp->dbip->dbi_local2base);
+
+    if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[1], 
gedp->ged_wdbp, mat) == GED_ERROR) {
+       bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
+       intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+       bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
+       rt_db_free_internal(&intern);
+
+       return GED_ERROR;
+    }
+
+    botip = (struct rt_bot_internal *)intern.idb_ptr;
+
+    if (vertex_i >= botip->num_vertices) {
+       bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - %s", 
argv[0], argv[2]);
+       rt_db_free_internal(&intern);
+       return GED_ERROR;
+    }
+
+    if (rflag) {
+       VADD2(&botip->vertices[vertex_i*3], pt, &botip->vertices[vertex_i*3]);
+    } else {
+       VMOVE(&botip->vertices[vertex_i*3], pt);
+    }
+
+    {
+       mat_t invmat;
+       point_t curr_pt;
+       size_t idx;
+
+       bn_mat_inv(invmat, mat);
+       for (idx = 0; idx < botip->num_vertices; idx++) {
+           MAT4X3PNT(curr_pt, invmat, &botip->vertices[idx*3]);
+           VMOVE(&botip->vertices[idx*3], curr_pt);
+       }
+    }
+
+    GED_DB_PUT_INTERNAL(gedp, dp, &intern, &rt_uniresource, GED_ERROR);
+    rt_db_free_internal(&intern);
+
+    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/libged/edbot.c
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Modified: brlcad/trunk/src/libtclcad/tclcad_obj.c
===================================================================
--- brlcad/trunk/src/libtclcad/tclcad_obj.c     2012-08-15 09:26:28 UTC (rev 
52025)
+++ brlcad/trunk/src/libtclcad/tclcad_obj.c     2012-08-15 12:57:50 UTC (rev 
52026)
@@ -251,6 +251,12 @@
                        ged_func_ptr func,
                        const char *usage,
                        int maxargs);
+HIDDEN int to_find_botpt(struct ged *gedp,
+                        int argc,
+                        const char *argv[],
+                        ged_func_ptr func,
+                        const char *usage,
+                        int maxargs);
 HIDDEN int to_handle_expose(struct ged *gedp,
                            int argc,
                            const char *argv[],
@@ -338,6 +344,12 @@
                                    ged_func_ptr func,
                                    const char *usage,
                                    int maxargs);
+HIDDEN int to_mouse_find_botpt(struct ged *gedp,
+                              int argc,
+                              const char *argv[],
+                              ged_func_ptr func,
+                              const char *usage,
+                              int maxargs);
 HIDDEN int to_mouse_find_pipept(struct ged *gedp,
                                int argc,
                                const char *argv[],
@@ -356,6 +368,12 @@
                                  ged_func_ptr func,
                                  const char *usage,
                                  int maxargs);
+HIDDEN int to_mouse_move_botpt(struct ged *gedp,
+                              int argc,
+                              const char *argv[],
+                              ged_func_ptr func,
+                              const char *usage,
+                              int maxargs);
 HIDDEN int to_mouse_move_pipept(struct ged *gedp,
                                int argc,
                                const char *argv[],
@@ -470,6 +488,18 @@
                                 ged_func_ptr func,
                                 const char *usage,
                                 int maxargs);
+HIDDEN int to_move_botpt(struct ged *gedp,
+                        int argc,
+                        const char *argv[],
+                        ged_func_ptr func,
+                        const char *usage,
+                        int maxargs);
+HIDDEN int to_move_botpt_mode(struct ged *gedp,
+                             int argc,
+                             const char *argv[],
+                             ged_func_ptr func,
+                             const char *usage,
+                             int maxargs);
 HIDDEN int to_move_pipept(struct ged *gedp,
                          int argc,
                          const char *argv[],
@@ -907,6 +937,7 @@
     {"facetize",       (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_facetize},
     {"voxelize",       (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_voxelize},
     {"fb2pix",         "[-h -i -c] [-s squaresize] [-w width] [-n height] 
[file.pix]", TO_UNLIMITED, to_view_func, ged_fb2pix},
+    {"find_botpt",     "pipe vx vy", 5, to_view_func, 
ged_find_botpt_nearest_pt},
     {"find_pipept",    "pipe x y z", 6, to_view_func, 
ged_find_pipept_nearest_pt},
     {"fontsize",       "[fontsize]", 3, to_fontsize, GED_FUNC_PTR_NULL},
     {"form",   (char *)0, TO_UNLIMITED, to_pass_through_func, ged_form},
@@ -970,14 +1001,18 @@
     {"move_arb_edge_mode",     "obj edge x y", TO_UNLIMITED, 
to_move_arb_edge_mode, GED_FUNC_PTR_NULL},
     {"move_arb_face",  (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_move_arb_face},
     {"move_arb_face_mode",     "obj face x y", TO_UNLIMITED, 
to_move_arb_face_mode, GED_FUNC_PTR_NULL},
+    {"move_botpt",     (char *)0, TO_UNLIMITED, to_move_botpt, 
GED_FUNC_PTR_NULL},
+    {"move_botpt_mode",        "obj i x y", TO_UNLIMITED, to_move_botpt_mode, 
GED_FUNC_PTR_NULL},
     {"move_pipept",    (char *)0, TO_UNLIMITED, to_move_pipept, 
GED_FUNC_PTR_NULL},
     {"move_pipept_mode",       "obj seg_i x y", TO_UNLIMITED, 
to_move_pipept_mode, GED_FUNC_PTR_NULL},
     {"mouse_append_pipept",    "obj x y", TO_UNLIMITED, 
to_mouse_append_pipept_common, ged_append_pipept},
     {"mouse_constrain_rot",    "coord x y", TO_UNLIMITED, 
to_mouse_constrain_rot, GED_FUNC_PTR_NULL},
     {"mouse_constrain_trans",  "coord x y", TO_UNLIMITED, 
to_mouse_constrain_trans, GED_FUNC_PTR_NULL},
+    {"mouse_find_botpt",       "obj mx my", TO_UNLIMITED, to_mouse_find_botpt, 
GED_FUNC_PTR_NULL},
     {"mouse_find_pipept",      "obj x y", TO_UNLIMITED, to_mouse_find_pipept, 
GED_FUNC_PTR_NULL},
     {"mouse_move_arb_edge",    "obj edge x y", TO_UNLIMITED, 
to_mouse_move_arb_edge, GED_FUNC_PTR_NULL},
     {"mouse_move_arb_face",    "obj face x y", TO_UNLIMITED, 
to_mouse_move_arb_face, GED_FUNC_PTR_NULL},
+    {"mouse_move_botpt",       "[-r] obj i x y", TO_UNLIMITED, 
to_mouse_move_botpt, GED_FUNC_PTR_NULL},
     {"mouse_move_pipept",      "obj i x y", TO_UNLIMITED, 
to_mouse_move_pipept, GED_FUNC_PTR_NULL},
     {"mouse_orotate",  "obj x y", TO_UNLIMITED, to_mouse_orotate, 
GED_FUNC_PTR_NULL},
     {"mouse_oscale",   "obj x y", TO_UNLIMITED, to_mouse_oscale, 
GED_FUNC_PTR_NULL},
@@ -5581,6 +5616,7 @@
     return GED_ERROR;
 }
 
+
 HIDDEN int
 to_handle_expose(struct ged *gedp,
                 int argc,
@@ -6352,6 +6388,75 @@
 }
 
 HIDDEN int
+to_mouse_find_botpt(struct ged *gedp,
+                   int argc,
+                   const char *argv[],
+                   ged_func_ptr UNUSED(func),
+                   const char *usage,
+                   int UNUSED(maxargs))
+{
+    char *av[6];
+    fastf_t x, y;
+    fastf_t inv_width;
+    fastf_t inv_height;
+    fastf_t inv_aspect;
+    point_t view;
+    struct bu_vls pt_vls = BU_VLS_INIT_ZERO;
+    struct ged_dm_view *gdvp;
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc != 5) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    for (BU_LIST_FOR(gdvp, ged_dm_view, 
&current_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, &current_top->to_gop->go_head_views.l)) {
+       bu_vls_printf(gedp->ged_result_str, "View not found - %s", argv[1]);
+       return GED_ERROR;
+    }
+
+    if (bu_sscanf(argv[3], "%lf", &x) != 1 ||
+       bu_sscanf(argv[4], "%lf", &y) != 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    inv_width = 1.0 / (fastf_t)gdvp->gdv_dmp->dm_width;
+    inv_height = 1.0 / (fastf_t)gdvp->gdv_dmp->dm_height;
+    inv_aspect = (fastf_t)gdvp->gdv_dmp->dm_height / 
(fastf_t)gdvp->gdv_dmp->dm_width;
+    x = x * inv_width * 2.0 - 1.0;
+    y = (y * inv_height * -2.0 + 1.0) * inv_aspect;
+    VSET(view, x, y, 0.0);
+
+    bu_vls_printf(&pt_vls, "%lf %lf %lf", view[X], view[Y], view[Z]);
+
+    gedp->ged_gvp = gdvp->gdv_view;
+    av[0] = "find_botpt_nearest_pt";
+    av[1] = (char *)argv[2];
+    av[2] = bu_vls_addr(&pt_vls);
+    av[3] = (char *)0;
+
+    (void)ged_find_botpt_nearest_pt(gedp, 3, (const char **)av);
+    bu_vls_free(&pt_vls);
+
+    return GED_OK;
+}
+
+
+HIDDEN int
 to_mouse_find_pipept(struct ged *gedp,
                     int argc,
                     const char *argv[],
@@ -6613,7 +6718,195 @@
     return GED_OK;
 }
 
+
 HIDDEN int
+to_mouse_move_botpt(struct ged *gedp,
+                   int argc,
+                   const char *argv[],
+                   ged_func_ptr UNUSED(func),
+                   const char *usage,
+                   int UNUSED(maxargs))
+{
+    int ret;
+    int rflag;
+    char *av[6];
+    const char *cmd;
+    fastf_t x, y;
+    fastf_t dx, dy, dz;
+    fastf_t inv_width;
+    point_t model;
+    point_t view;
+    mat_t v2m_mat;
+    struct bu_vls pt_vls = BU_VLS_INIT_ZERO;
+    struct ged_dm_view *gdvp;
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    cmd = argv[0];
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc == 7) {
+       if (argv[1][0] != '-' || argv[1][1] != 'r' || argv[1][2] != '\0') {
+           bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+           return GED_ERROR;
+       }
+
+       rflag = 1;
+       --argc;
+       ++argv;
+    } else
+       rflag = 0;
+
+    if (argc != 6) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    for (BU_LIST_FOR(gdvp, ged_dm_view, 
&current_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, &current_top->to_gop->go_head_views.l)) {
+       bu_vls_printf(gedp->ged_result_str, "%s: View not found - %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    if (bu_sscanf(argv[4], "%lf", &x) != 1 ||
+       bu_sscanf(argv[5], "%lf", &y) != 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    inv_width = 1.0 / (fastf_t)gdvp->gdv_dmp->dm_width;
+
+    if (rflag) {
+       dx = x - gdvp->gdv_view->gv_prevMouseX;
+       dy = gdvp->gdv_view->gv_prevMouseY - y;
+       dz = 0.0;
+
+       gdvp->gdv_view->gv_prevMouseX = x;
+       gdvp->gdv_view->gv_prevMouseY = y;
+
+       if (dx < gdvp->gdv_view->gv_minMouseDelta)
+           dx = gdvp->gdv_view->gv_minMouseDelta;
+       else if (gdvp->gdv_view->gv_maxMouseDelta < dx)
+           dx = gdvp->gdv_view->gv_maxMouseDelta;
+
+       if (dy < gdvp->gdv_view->gv_minMouseDelta)
+           dy = gdvp->gdv_view->gv_minMouseDelta;
+       else if (gdvp->gdv_view->gv_maxMouseDelta < dy)
+           dy = gdvp->gdv_view->gv_maxMouseDelta;
+
+       bn_mat_inv(v2m_mat, gdvp->gdv_view->gv_rotation);
+
+       dx *= inv_width * gdvp->gdv_view->gv_size;
+       dy *= inv_width * gdvp->gdv_view->gv_size;
+    } else {
+       struct rt_db_internal intern;
+       struct rt_bot_internal *botip;
+       mat_t mat;
+       size_t vertex_i;
+       char *last;
+       fastf_t inv_height;
+       fastf_t inv_aspect;
+
+       if ((last = strrchr(argv[2], '/')) == NULL)
+           last = (char *)argv[2];
+       else
+           ++last;
+
+       if (last[0] == '\0') {
+           bu_vls_printf(gedp->ged_result_str, "%s: illegal input - %s", cmd, 
argv[2]);
+           return GED_ERROR;
+       }
+
+       if (sscanf(argv[3], "%zu", &vertex_i) != 1) {
+           bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - 
%s", cmd, argv[3]);
+           return GED_ERROR;
+       }
+
+       if (wdb_import_from_path2(gedp->ged_result_str, &intern, argv[2], 
gedp->ged_wdbp, mat) == GED_ERROR) {
+           bu_vls_printf(gedp->ged_result_str, "%s: failed to find %s", cmd, 
argv[2]);
+           return GED_ERROR;
+       }
+
+       if (intern.idb_major_type != DB5_MAJORTYPE_BRLCAD ||
+           intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
+           bu_vls_printf(gedp->ged_result_str, "Object is not a BOT");
+           rt_db_free_internal(&intern);
+
+           return GED_ERROR;
+       }
+
+       botip = (struct rt_bot_internal *)intern.idb_ptr;
+
+       if (vertex_i >= botip->num_vertices) {
+           bu_vls_printf(gedp->ged_result_str, "%s: bad bot vertex index - 
%s", cmd, argv[3]);
+           rt_db_free_internal(&intern);
+           return GED_ERROR;
+       }
+
+       MAT4X3PNT(view, gdvp->gdv_view->gv_model2view, 
&botip->vertices[vertex_i*3]);
+       MAT_COPY(v2m_mat, gdvp->gdv_view->gv_view2model);
+
+       inv_width = 1.0 / (fastf_t)gdvp->gdv_dmp->dm_width;
+       inv_height = 1.0 / (fastf_t)gdvp->gdv_dmp->dm_height;
+       inv_aspect = (fastf_t)gdvp->gdv_dmp->dm_height / 
(fastf_t)gdvp->gdv_dmp->dm_width;
+       dx = x * inv_width * 2.0 - 1.0;
+       dy = (y * inv_height * -2.0 + 1.0) * inv_aspect;
+       dz = view[Z];
+
+       rt_db_free_internal(&intern);
+    }
+
+    VSET(view, dx, dy, dz);
+    MAT4X3PNT(model, v2m_mat, view);
+
+    /* ged_move_botpt expects things to be in local units */
+    VSCALE(model, model, gedp->ged_wdbp->dbip->dbi_base2local);
+    bu_vls_printf(&pt_vls, "%lf %lf %lf", model[X], model[Y], model[Z]);
+
+    gedp->ged_gvp = gdvp->gdv_view;
+    av[0] = "move_botpt";
+
+    if (rflag) {
+       av[1] = "-r";
+       av[2] = (char *)argv[2];
+       av[3] = (char *)argv[3];
+       av[4] = bu_vls_addr(&pt_vls);
+       av[5] = (char *)0;
+
+       ret = ged_move_botpt(gedp, 5, (const char **)av);
+    } else {
+       av[1] = (char *)argv[2];
+       av[2] = (char *)argv[3];
+       av[3] = bu_vls_addr(&pt_vls);
+       av[4] = (char *)0;
+
+       ret = ged_move_botpt(gedp, 4, (const char **)av);
+    }
+
+    bu_vls_free(&pt_vls);
+
+    if (ret == GED_OK) {
+       av[0] = "draw";
+       av[1] = (char *)argv[2];
+       av[2] = (char *)0;
+       to_edit_redraw(gedp, 2, (const char **)av);
+    }
+
+    return GED_OK;
+}
+
+
+HIDDEN int
 to_mouse_move_pipept(struct ged *gedp,
                     int argc,
                     const char *argv[],
@@ -6679,7 +6972,7 @@
        dy = gdvp->gdv_view->gv_maxMouseDelta;
 
     inv_width = 1.0 / (fastf_t)gdvp->gdv_dmp->dm_width;
-    /* ged_move_arb_face expects things to be in local units */
+    /* ged_move_pipept expects things to be in local units */
     dx *= inv_width * gdvp->gdv_view->gv_size * 
gedp->ged_wdbp->dbip->dbi_base2local;
     dy *= inv_width * gdvp->gdv_view->gv_size * 
gedp->ged_wdbp->dbip->dbi_base2local;
     VSET(view, dx, dy, 0.0);
@@ -8245,36 +8538,7 @@
     return TCL_OK;
 }
 
-HIDDEN int
-to_move_pipept(struct ged *gedp,
-              int argc,
-              const char *argv[],
-              ged_func_ptr UNUSED(func),
-              const char *UNUSED(usage),
-              int UNUSED(maxargs))
-{
-    int ret;
 
-    if ((ret = ged_move_pipept(gedp, argc, argv)) == GED_OK) {
-       char *av[3];
-       int i;
-
-       if (argc == 4)
-           i = 1;
-       else
-           i = 2;
-
-       av[0] = "draw";
-       av[1] = (char *)argv[i];
-       av[2] = (char *)0;
-       to_edit_redraw(gedp, 2, (const char **)av);
-
-       return GED_OK;
-    }
-
-    return ret;
-}
-
 HIDDEN int
 to_move_arb_edge_mode(struct ged *gedp,
                      int argc,
@@ -8333,6 +8597,7 @@
     return GED_OK;
 }
 
+
 HIDDEN int
 to_move_arb_face_mode(struct ged *gedp,
                      int argc,
@@ -8391,7 +8656,129 @@
     return GED_OK;
 }
 
+
 HIDDEN int
+to_move_botpt(struct ged *gedp,
+             int argc,
+             const char *argv[],
+             ged_func_ptr UNUSED(func),
+             const char *UNUSED(usage),
+             int UNUSED(maxargs))
+{
+    int ret;
+
+    if ((ret = ged_move_botpt(gedp, argc, argv)) == GED_OK) {
+       char *av[3];
+       int i;
+
+       if (argc == 4)
+           i = 1;
+       else
+           i = 2;
+
+       av[0] = "draw";
+       av[1] = (char *)argv[i];
+       av[2] = (char *)0;
+       to_edit_redraw(gedp, 2, (const char **)av);
+
+       return GED_OK;
+    }
+
+    return ret;
+}
+
+
+HIDDEN int
+to_move_botpt_mode(struct ged *gedp,
+                  int argc,
+                  const char *argv[],
+                  ged_func_ptr UNUSED(func),
+                  const char *usage,
+                  int UNUSED(maxargs))
+{
+    fastf_t x, y;
+    struct bu_vls bindings = BU_VLS_INIT_ZERO;
+    struct ged_dm_view *gdvp;
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc != 6) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    for (BU_LIST_FOR(gdvp, ged_dm_view, 
&current_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, &current_top->to_gop->go_head_views.l)) {
+       bu_vls_printf(gedp->ged_result_str, "%s: View not found - %s", argv[0], 
argv[1]);
+       return GED_ERROR;
+    }
+
+    if (bu_sscanf(argv[4], "%lf", &x) != 1 ||
+       bu_sscanf(argv[5], "%lf", &y) != 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    gdvp->gdv_view->gv_prevMouseX = x;
+    gdvp->gdv_view->gv_prevMouseY = y;
+    gdvp->gdv_view->gv_mode = TCLCAD_MOVE_BOT_POINT_MODE;
+
+    bu_vls_printf(&bindings, "bind %V <Motion> {%V mouse_move_botpt -r %V %s 
%s %%x %%y}",
+                 &gdvp->gdv_dmp->dm_pathName,
+                 &current_top->to_gop->go_name,
+                 &gdvp->gdv_name,
+                 argv[2],
+                 argv[3]);
+    Tcl_Eval(current_top->to_interp, bu_vls_addr(&bindings));
+    bu_vls_free(&bindings);
+
+    return GED_OK;
+}
+
+
+HIDDEN int
+to_move_pipept(struct ged *gedp,
+              int argc,
+              const char *argv[],
+              ged_func_ptr UNUSED(func),
+              const char *UNUSED(usage),
+              int UNUSED(maxargs))
+{
+    int ret;
+
+    if ((ret = ged_move_pipept(gedp, argc, argv)) == GED_OK) {
+       char *av[3];
+       int i;
+
+       if (argc == 4)
+           i = 1;
+       else
+           i = 2;
+
+       av[0] = "draw";
+       av[1] = (char *)argv[i];
+       av[2] = (char *)0;
+       to_edit_redraw(gedp, 2, (const char **)av);
+
+       return GED_OK;
+    }
+
+    return ret;
+}
+
+
+HIDDEN int
 to_move_pipept_mode(struct ged *gedp,
                    int argc,
                    const char *argv[],

Modified: brlcad/trunk/src/tclscripts/archer/Archer.tcl
===================================================================
--- brlcad/trunk/src/tclscripts/archer/Archer.tcl       2012-08-15 09:26:28 UTC 
(rev 52025)
+++ brlcad/trunk/src/tclscripts/archer/Archer.tcl       2012-08-15 12:57:50 UTC 
(rev 52026)
@@ -153,6 +153,7 @@
 
        method importFg4Sections   {_slist _wlist _delta}
        method initAppendPipePoint {_obj _button _callback}
+       method initFindBotPoint {_obj _button _callback}
        method initFindPipePoint {_obj _button _callback}
        method initPrependPipePoint {_obj _button _callback}
 
@@ -747,6 +748,18 @@
 }
 
 
+::itcl::body Archer::initFindBotPoint {_obj _button _callback} {
+    if {![info exists itk_component(ged)]} {
+       return
+    }
+
+    # This deselects the selected mouse mode in the primary toolbar
+    set mDefaultBindingMode FIRST_FREE_BINDING_MODE
+
+    $itk_component(ged) init_find_botpt $_obj $_button $_callback
+}
+
+
 ::itcl::body Archer::initFindPipePoint {_obj _button _callback} {
     if {![info exists itk_component(ged)]} {
        return
@@ -5771,11 +5784,7 @@
        return
     }
 
-    if {$mSelectedObjType != "bot"} {
-       set odata [lrange [gedCmd get $mSelectedObj] 1 end]
-    } else {
-       set odata ""
-    }
+    set odata [lrange [gedCmd get $mSelectedObj] 1 end]
 
     if {$_initEditMode && [info exists GeometryEditFrame::mEditCommand]} {
        set GeometryEditFrame::mEditMode 0
@@ -6023,7 +6032,11 @@
        set win [$itk_component(ged) component $dname]
 
        if {$GeometryEditFrame::mEditCommand != ""} {
-           bind $win <1> "$itk_component(ged) 
pane_$GeometryEditFrame::mEditCommand\_mode $dname $obj 
$GeometryEditFrame::mEditParam1 %x %y; break"
+           if {$mSelectedObjType == "bot"} {
+               bind $win <1> "$itk_component(botView) moveBotPtMode $dname 
$obj %x %y; break"
+           } else {
+               bind $win <1> "$itk_component(ged) 
pane_$GeometryEditFrame::mEditCommand\_mode $dname $obj 
$GeometryEditFrame::mEditParam1 %x %y; break"
+           }
        } else {
            bind $win <1> "$itk_component(ged) pane_otranslate_mode $dname $obj 
%x %y; break"
        }
@@ -6066,7 +6079,8 @@
     updateSaveMode
     initEdit 0
 
-    if {$mSelectedObjType != "pipe" || $GeometryEditFrame::mEditParam1 == ""} {
+    if {$GeometryEditFrame::mEditParam1 == "" ||
+       ($mSelectedObjType != "pipe" && $mSelectedObjType != "bot")} {
        set center [$itk_component(ged) ocenter $_obj]
        addHistory "ocenter $_obj $center"
     }
@@ -6102,18 +6116,12 @@
 ::itcl::body Archer::endObjTranslate {_dm _obj _mx _my} {
     $itk_component(ged) pane_idle_mode $_dm
 
-    if {$mSelectedObjType == "pipe" && $GeometryEditFrame::mEditParam1 != ""} {
-       set sx $_mx
-       set sy $_my
-    } else {
-       set ocenter [gedCmd ocenter $_obj]
-       set vcenter [gedCmd pane_m2v_point $_dm $ocenter]
-       set screen [gedCmd pane_view2screen $_dm $vcenter]
-       set sx [lindex $screen 0]
-       set sy [lindex $screen 1]
+    if {![$itk_component(ged) pane_grid $_dm snap]} {
+       endObjCenter $_obj
+       return
     }
 
-    handleObjCenter $_dm $_obj $sx $sy
+    handleObjCenter $_dm $_obj $_mx $_my
     endObjCenter $_obj
 }
 
@@ -6143,7 +6151,12 @@
            eval editMotionDeltaCallback otranslate $diff
        } else {
            if {$GeometryEditFrame::mEditCommand != ""} {
-               gedCmd $GeometryEditFrame::mEditCommand $_obj 
$GeometryEditFrame::mEditParam1 $new_ocenter
+               if {$mSelectedObjType == "bot"} {
+                   set sl [gedCmd pane_view2screen $_dm [list $vx $vy]]
+                   $itk_component(botView) moveBotPt $_dm $_obj [lindex $sl 0] 
[lindex $sl 1]
+               } else {
+                   $itk_component(ged) $GeometryEditFrame::mEditCommand $_obj 
$GeometryEditFrame::mEditParam1 $new_ocenter
+               }
            } else {
                eval gedCmd ocenter $_obj $new_ocenter
            }
@@ -6209,9 +6222,6 @@
 
 
 ::itcl::body Archer::buildBotEditView {} {
-    #XXX Not ready yet
-    return
-
     set parent $itk_component(objEditView)
     itk_component add botView {
        BotEditFrame $parent.botview \
@@ -6825,22 +6835,19 @@
 
 
 ::itcl::body Archer::initBotEditView {odata} {
-    #XXX Not ready yet
-    return
+    $itk_component(botView) configure \
+       -geometryObject $mSelectedObj \
+       -geometryObjectPath $mSelectedObjPath \
+       -geometryChangedCallback [::itcl::code $this updateObjEditView] \
+       -mged $itk_component(ged) \
+       -labelFont $mFontText \
+       -boldLabelFont $mFontTextBold \
+       -entryFont $mFontText
+    $itk_component(botView) initGeometry $odata
 
-    #     $itk_component(botView) configure \
-       #       -geometryObject $mSelectedObj \
-       #       -geometryObjectPath $mSelectedObjPath \
-       #       -geometryChangedCallback [::itcl::code $this updateObjEditView] 
\
-       #       -mged $itk_component(ged) \
-       #       -labelFont $mFontText \
-       #       -boldLabelFont $mFontTextBold \
-       #       -entryFont $mFontText
-    #     $itk_component(botView) initGeometry $odata
-
-    #     pack $itk_component(botView) \
-       #       -expand yes \
-       #       -fill both
+    pack $itk_component(botView) \
+       -expand yes \
+       -fill both
 }
 
 
@@ -9006,9 +9013,6 @@
 
 
 ::itcl::body Archer::createBot {name} {
-    #XXX Not ready yet
-    return
-
     if {![info exists itk_component(botView)]} {
        buildBotEditView
        $itk_component(botView) configure \

Added: brlcad/trunk/src/tclscripts/archer/BotEditFrame.tcl
===================================================================
--- brlcad/trunk/src/tclscripts/archer/BotEditFrame.tcl                         
(rev 0)
+++ brlcad/trunk/src/tclscripts/archer/BotEditFrame.tcl 2012-08-15 12:57:50 UTC 
(rev 52026)
@@ -0,0 +1,452 @@
+#                P I P E E D I T F R A M E . T C L
+# BRL-CAD
+#
+# Copyright (c) 2002-2012 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.
+#
+###
+#
+# Author:
+#    Bob Parker
+#
+# Description:
+#    The class for editing bots within Archer.
+#
+
+::itcl::class BotEditFrame {
+    inherit GeometryEditFrame
+
+    constructor {args} {}
+    destructor {}
+
+    public {
+       common SELECT_COL 0
+       common X_COL 1
+       common Y_COL 2
+       common Z_COL 3
+
+       common selectPoint 1
+       common movePoint 2
+
+       common mDetailHeadings {{} X Y Z}
+       common mEditLabels {
+           {Select Point}
+           {Move Point}
+       }
+
+       # Override what's in GeometryEditFrame
+       method initGeometry {gdata}
+       method updateGeometry {}
+       method createGeometry {_name}
+       method p {obj args}
+       method moveBotPtMode {_dname _obj _x _y}
+       method moveBotPt {_dname _obj _x _y}
+    }
+
+    protected {
+       variable mDetail
+       variable mCurrentBotPoint 1
+
+       # Methods used by the constructor
+       # override methods in GeometryEditFrame
+       method buildUpperPanel
+       method buildLowerPanel
+
+       # Override what's in GeometryEditFrame
+       method updateGeometryIfMod {}
+       method initEditState {}
+
+       method applyData {}
+       method detailBrowseCommand {_row _col}
+       method handleDetailPopup {_index _X _Y}
+       method handleEnter {_row _col}
+       method botPointSelectCallback {_pindex}
+       method singleSelectCallback {_pindex}
+       method validateDetailEntry {_row _col _newval _clientdata}
+    }
+
+    private {}
+}
+
+
+# ------------------------------------------------------------
+#                      CONSTRUCTOR
+# ------------------------------------------------------------
+
+::itcl::body BotEditFrame::constructor {args} {
+    eval itk_initialize $args
+}
+
+# ------------------------------------------------------------
+#                        OPTIONS
+# ------------------------------------------------------------
+
+
+# ------------------------------------------------------------
+#                      PUBLIC METHODS
+# ------------------------------------------------------------
+
+## - initGeometry
+#
+# Initialize the variables containing the object's specification.
+#
+::itcl::body BotEditFrame::initGeometry {gdata} {
+    unset mDetail
+    set mDetail(active) ""
+
+    set col 0
+    foreach heading $mDetailHeadings {
+       set mDetail(0,$col) $heading
+       incr col
+    }
+
+    foreach {attr val} $gdata {
+       switch -- $attr {
+           "mode" {
+           }
+           "orient" {
+           }
+           "flags" {
+           }
+           "V" {
+               set index 1
+               foreach item $val {
+                   set mDetail($index,$SELECT_COL) ""
+                   set mDetail($index,$X_COL) [lindex $item 0]
+                   set mDetail($index,$Y_COL) [lindex $item 1]
+                   set mDetail($index,$Z_COL) [lindex $item 2]
+                   incr index
+               }
+           }
+           "F" {
+           }
+           default {
+               # Shouldn't get here
+               puts "Encountered bad one - $attr"
+           }
+       }
+    }
+
+    GeometryEditFrame::initGeometry $gdata
+
+    if {$itk_option(-geometryObject) != $mPrevGeometryObject} {
+       set mCurrentBotPoint 1
+       set mPrevGeometryObject $itk_option(-geometryObject)
+    }
+    botPointSelectCallback [expr {$mCurrentBotPoint - 1}]
+}
+
+::itcl::body BotEditFrame::updateGeometry {} {
+    # Not ready
+    return
+
+    if {$itk_option(-mged) == "" ||
+       $itk_option(-geometryObject) == ""} {
+       return
+    }
+
+    set pipe_spec {}
+    set pt {}
+
+    foreach aname [lsort [array names mDetail]] {
+       set alist [split $aname ","]
+       if {[llength $alist] != 2} {
+           continue
+       }
+
+       set row [lindex $alist 0]
+       if {$row == 0} {
+           continue
+       }
+
+       set index [expr {$row - 1}]
+       set col [lindex $alist 1]
+       if {$col == 0} {
+           continue
+       }
+
+       switch -- $col \
+           $OD_COL {
+               lappend pipe_spec O$index $mDetail($row,$col)
+           } \
+           $ID_COL {
+               lappend pipe_spec I$index $mDetail($row,$col)
+           } \
+           $RADIUS_COL {
+               lappend pipe_spec R$index $mDetail($row,$col)
+           } \
+           $PX_COL - \
+           $PY_COL {
+               lappend pt $mDetail($row,$col)
+           } \
+           $PZ_COL {
+               lappend pt $mDetail($row,$col)
+               lappend pipe_spec V$index $pt
+               set pt {}
+           } \
+           default {
+               puts "Encountered bad one - $mDetail($row,$col)"
+           }
+    }
+
+    eval $itk_option(-mged) adjust $itk_option(-geometryObject) $pipe_spec
+    GeometryEditFrame::updateGeometry
+}
+
+::itcl::body BotEditFrame::createGeometry {obj} {
+    #Not ready yet
+    return
+
+    if {![GeometryEditFrame::createGeometry $obj]} {
+       return
+    }
+
+    set od [expr {$mDelta * 0.2}]
+    set id [expr {$od * 0.5}]
+    set br $od
+
+    $itk_option(-mged) put $obj pipe \
+       V0 [list $mCenterX $mCenterY $mZmin] \
+       O0 $od \
+       I0 $id \
+       R0 $br \
+       V1 [list $mCenterX $mCenterY $mZmax] \
+       O1 $od \
+       I1 $id \
+       R1 $br
+}
+
+::itcl::body BotEditFrame::p {obj args} {
+    if {[llength $args] != 1 || ![string is double $args]} {
+       return "Usage: p sf"
+    }
+#XXX Need to update this method
+    return
+
+    switch -- $mEditMode \
+       $setA {
+           $::ArcherCore::application p_pscale $obj a $args
+       } \
+       $setB {
+           $::ArcherCore::application p_pscale $obj b $args
+       } \
+       $setC {
+           $::ArcherCore::application p_pscale $obj c $args
+       } \
+       $setABC {
+           $::ArcherCore::application p_pscale $obj abc $args
+       }
+
+    return ""
+}
+
+
+::itcl::body BotEditFrame::moveBotPtMode {_dname _obj _x _y} {
+    set mEditParam1 [$itk_option(-mged) pane_mouse_find_botpt $_dname $_obj 
$_x $_y]
+    $itk_option(-mged) pane_move_botpt_mode $_dname $_obj $mEditParam1 $_x $_y
+}
+
+
+::itcl::body BotEditFrame::moveBotPt {_dname _obj _x _y} {
+    $itk_option(-mged) pane_mouse_move_botpt $_dname $_obj $mEditParam1 $_x $_y
+}
+
+
+# ------------------------------------------------------------
+#                      PROTECTED METHODS
+# ------------------------------------------------------------
+
+::itcl::body BotEditFrame::buildUpperPanel {} {
+    set parent [$this childsite]
+
+    itk_component add detailTab {
+       ::cadwidgets::TkTable $parent.detailTab \
+           [::itcl::scope mDetail] \
+           $mDetailHeadings \
+           -cursor arrow \
+           -height 0 \
+           -maxheight 2000 \
+           -width 0 \
+           -rows 100000 \
+           -colstretchmode unset \
+           -validate 1 \
+           -validatecommand [::itcl::code $this validateDetailEntry] \
+           -tablePopupHandler [::itcl::code $this handleDetailPopup] \
+           -entercommand [::itcl::code $this handleEnter] \
+           -singleSelectCallback [::itcl::code $this singleSelectCallback]
+    } {}
+#          -browsecommand [::itcl::code $this detailBrowseCommand %r %c]
+#          -dataCallback [::itcl::code $this applyData]
+
+    # Set width of column 0
+    $itk_component(detailTab) width 0 3
+
+    pack $itk_component(detailTab) -expand yes -fill both
+    pack $parent -expand yes -fill both
+}
+
+::itcl::body BotEditFrame::buildLowerPanel {} {
+    set parent [$this childsite lower]
+    set i 1
+    foreach label $mEditLabels {
+       itk_component add editRB$i {
+           ::ttk::radiobutton $parent.editRB$i \
+               -variable [::itcl::scope mEditMode] \
+               -value $i \
+               -text $label \
+               -command [::itcl::code $this initEditState]
+       } {}
+
+       pack $itk_component(editRB$i) \
+           -anchor w \
+           -expand yes
+
+       incr i
+    }
+}
+
+::itcl::body BotEditFrame::updateGeometryIfMod {} {
+    if {$itk_option(-mged) == "" ||
+       $itk_option(-geometryObject) == ""} {
+       return
+    }
+
+    set doUpdate 0
+    set gdata [$itk_option(-mged) get $itk_option(-geometryObject)]
+    set gdata [lrange $gdata 1 end]
+
+    foreach {attr val} $gdata {
+       if {![regexp {^[VOIRvoir]([0-9]+)$} $attr all index]} {
+           puts "Encountered bad one - $attr"
+           continue
+       }
+
+       incr index
+
+       switch -regexp -- $attr {
+           {[Vv][0-9]+} {
+               if {$mDetail($index,$PX_COL) != [lindex $val 0] ||
+                   $mDetail($index,$PY_COL) != [lindex $val 1] ||
+                   $mDetail($index,$PZ_COL) != [lindex $val 2]} {
+                   set doUpdate 1
+               }
+           }
+           {[Oo][0-9]+} {
+               if {$mDetail($index,$OD_COL) != $val} {
+                   set doUpdate 1
+               }
+           }
+           {[Ii][0-9]+} {
+               if {$mDetail($index,$ID_COL) != $val} {
+                   set doUpdate 1
+               }
+           }
+           {[Rr][0-9]+} {
+               if {$mDetail($index,$RADIUS_COL) != $val} {
+                   set doUpdate 1
+               }
+           }
+           default {
+               # Shouldn't get here
+               puts "Encountered bad one - $attr"
+           }
+       }
+
+       if {$doUpdate} {
+           updateGeometry
+           return
+       }
+    }
+}
+
+::itcl::body BotEditFrame::initEditState {} {
+#    set mEditCommand pscale
+#    set mEditClass $EDIT_CLASS_SCALE
+#    configure -valueUnits "mm"
+
+    set mEditPCommand [::itcl::code $this p]
+    set mEditParam1 [expr {$mCurrentBotPoint - 1}]
+
+    switch -- $mEditMode \
+       $selectPoint {
+           set mEditCommand ""
+           set mEditClass ""
+           $::ArcherCore::application initFindBotPoint 
$itk_option(-geometryObjectPath) 1 [::itcl::code $this botPointSelectCallback]
+       } \
+       $movePoint {
+           set mEditCommand move_botpt
+           set mEditClass $EDIT_CLASS_TRANS
+       }
+
+    GeometryEditFrame::initEditState
+}
+
+::itcl::body BotEditFrame::applyData {} {
+}
+
+::itcl::body BotEditFrame::detailBrowseCommand {_row _col} {
+    if {![info exists mDetail($_row,0)]} {
+       return 0
+    }
+
+    $itk_component(detailTab) see $_row,$_col
+}
+
+::itcl::body BotEditFrame::handleDetailPopup {_index _X _Y} {
+}
+
+::itcl::body BotEditFrame::handleEnter {_row _col} {
+    if {$itk_option(-mged) == "" ||
+       $itk_option(-geometryObject) == "" ||
+       $_row < 1 ||
+       $_col < 1 ||
+       $_col > $PZ_COL} {
+       return
+    }
+
+    updateGeometryIfMod
+}
+
+::itcl::body BotEditFrame::botPointSelectCallback {_pindex} {
+    set mEditParam1 $_pindex
+    incr _pindex
+    set mCurrentBotPoint $_pindex
+    $itk_component(detailTab) selectSingleRow $_pindex
+}
+
+::itcl::body BotEditFrame::singleSelectCallback {_pindex} {
+    set mCurrentBotPoint $_pindex
+    set mEditParam1 [expr {$mCurrentBotPoint - 1}]
+    initEditState
+}
+
+::itcl::body BotEditFrame::validateDetailEntry {_row _col _newval _clientdata} 
{
+    if {![info exists mDetail($_row,0)]} {
+       return 0
+    }
+
+    return [::cadwidgets::Ged::validateDouble $_newval]
+}
+
+
+# Local Variables:
+# mode: Tcl
+# tab-width: 8
+# c-basic-offset: 4
+# tcl-indent-level: 4
+# indent-tabs-mode: t
+# End:
+# ex: shiftwidth=4 tabstop=8


Property changes on: brlcad/trunk/src/tclscripts/archer/BotEditFrame.tcl
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Modified: brlcad/trunk/src/tclscripts/archer/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/tclscripts/archer/CMakeLists.txt   2012-08-15 09:26:28 UTC 
(rev 52025)
+++ brlcad/trunk/src/tclscripts/archer/CMakeLists.txt   2012-08-15 12:57:50 UTC 
(rev 52026)
@@ -9,6 +9,7 @@
   Archer.tcl
   ArcherCore.tcl
   AttrGroupsDisplayUtility.tcl
+  BotEditFrame.tcl
   BotUtility.tcl
   CombEditFrame.tcl
   DataUtils.tcl

Modified: brlcad/trunk/src/tclscripts/lib/Ged.tcl
===================================================================
--- brlcad/trunk/src/tclscripts/lib/Ged.tcl     2012-08-15 09:26:28 UTC (rev 
52025)
+++ brlcad/trunk/src/tclscripts/lib/Ged.tcl     2012-08-15 12:57:50 UTC (rev 
52026)
@@ -255,6 +255,7 @@
        method mouse_append_pipept {args}
        method mouse_constrain_rot {args}
        method mouse_constrain_trans {args}
+       method mouse_find_botpt {args}
        method mouse_find_pipept {args}
        method mouse_move_arb_edge {args}
        method mouse_move_arb_face {args}
@@ -279,6 +280,8 @@
        method move_arb_edge_mode {args}
        method move_arb_face {args}
        method move_arb_face_mode {args}
+       method move_botpt {args}
+       method move_botpt_mode {args}
        method move_pipept {args}
        method move_pipept_mode {args}
        method mv {args}
@@ -309,6 +312,7 @@
        method pane_eye {_pane args}
        method pane_eye_pos {_pane args}
        method pane_fb2pix {_pane args}
+       method pane_find_botpt {args}
        method pane_find_pipept {args}
        method pane_fontsize {_pane args}
        method pane_get_eyemodel {_pane args}
@@ -325,13 +329,16 @@
        method pane_edit_motion_delta_callback {_pane args}
        method pane_move_arb_edge_mode {_pane args}
        method pane_move_arb_face_mode {_pane args}
+       method pane_move_botpt_mode {_pane args}
        method pane_move_pipept_mode {_pane args}
        method pane_mouse_append_pipept {_pane args}
        method pane_mouse_constrain_rot {_pane args}
        method pane_mouse_constrain_trans {_pane args}
+       method pane_mouse_find_botpt {_pane args}
        method pane_mouse_find_pipept {_pane args}
        method pane_mouse_move_arb_edge {_pane args}
        method pane_mouse_move_arb_face {_pane args}
+       method pane_mouse_move_botpt {_pane args}
        method pane_mouse_move_pipept {_pane args}
        method pane_mouse_orotate {_pane args}
        method pane_mouse_oscale {_pane args}
@@ -602,6 +609,7 @@
        method init_data_poly_cont {{_button 1}}
        method init_data_poly_ell {{_button 1}}
        method init_data_poly_rect {{_button 1} {_sflag 0}}
+       method init_find_botpt {_obj {_button 1} {_callback {}}}
        method init_find_pipept {_obj {_button 1} {_callback {}}}
        method init_prepend_pipept {_obj {_button 1} {_callback {}}}
        method init_view_bindings {{_type default}}
@@ -694,6 +702,7 @@
        variable mGed ""
        variable mSharedGed 0
        variable mHistoryCallback ""
+       variable mBotPointCallback ""
        variable mPipePointCallback ""
        variable mMeasuringStickColorVDraw2D ff00ff
        variable mMeasuringStickColorVDraw3D ffff00
@@ -1756,8 +1765,16 @@
     eval $mGed mouse_constrain_trans $itk_component($itk_option(-pane)) $args
 }
 
+::itcl::body cadwidgets::Ged::mouse_find_botpt {args} {
+    eval $mGed mouse_find_botpt $itk_component($itk_option(-pane)) $args
+}
+
 ::itcl::body cadwidgets::Ged::mouse_find_pipept {args} {
     set i [eval $mGed mouse_find_pipept $itk_component($itk_option(-pane)) 
$args]
+
+    if {$mPipePointCallback != ""} {
+       catch {$mPipePointCallback $i}
+    }
 }
 
 ::itcl::body cadwidgets::Ged::mouse_move_arb_edge {args} {
@@ -1853,6 +1870,14 @@
     eval $mGed move_arb_face_mode $itk_component($itk_option(-pane)) $args
 }
 
+::itcl::body cadwidgets::Ged::move_botpt {args} {
+    eval $mGed move_botpt $args
+}
+
+::itcl::body cadwidgets::Ged::move_botpt_mode {args} {
+    eval $mGed move_botpt_mode $itk_component($itk_option(-pane)) $args
+}
+
 ::itcl::body cadwidgets::Ged::move_pipept {args} {
     eval $mGed move_pipept $args
 }
@@ -1977,6 +2002,10 @@
     eval $mGed fb2pix $itk_component($_pane) $args
 }
 
+::itcl::body cadwidgets::Ged::pane_find_botpt {_pane args} {
+    eval $mGed find_botpt $itk_component($_pane) $args
+}
+
 ::itcl::body cadwidgets::Ged::pane_find_pipept {_pane args} {
     eval $mGed find_pipept $itk_component($_pane) $args
 }
@@ -2041,6 +2070,10 @@
     eval $mGed move_arb_face_mode $itk_component($_pane) $args
 }
 
+::itcl::body cadwidgets::Ged::pane_move_botpt_mode {_pane args} {
+    eval $mGed move_botpt_mode $itk_component($_pane) $args
+}
+
 ::itcl::body cadwidgets::Ged::pane_move_pipept_mode {_pane args} {
     eval $mGed move_pipept_mode $itk_component($_pane) $args
 }
@@ -2061,12 +2094,24 @@
     eval $mGed mouse_constrain_trans $itk_component($_pane) $args
 }
 
+::itcl::body cadwidgets::Ged::pane_mouse_find_botpt {_pane args} {
+    set i [eval $mGed mouse_find_botpt $itk_component($_pane) $args]
+
+    if {$mBotPointCallback != ""} {
+       catch {$mBotPointCallback $i}
+    }
+
+    return $i
+}
+
 ::itcl::body cadwidgets::Ged::pane_mouse_find_pipept {_pane args} {
     set i [eval $mGed mouse_find_pipept $itk_component($_pane) $args]
 
     if {$mPipePointCallback != ""} {
        catch {$mPipePointCallback $i}
     }
+
+    return $i
 }
 
 ::itcl::body cadwidgets::Ged::pane_mouse_move_arb_edge {_pane args} {
@@ -2077,8 +2122,11 @@
     eval $mGed mouse_move_arb_face $itk_component($_pane) $args
 }
 
+::itcl::body cadwidgets::Ged::pane_mouse_move_botpt {_pane args} {
+    eval $mGed mouse_move_botpt $itk_component($_pane) $args
+}
+
 ::itcl::body cadwidgets::Ged::pane_mouse_move_pipept {_pane args} {
-    puts "cadwidgets::Ged::pane_mouse_move_pipept $_pane $args"
     eval $mGed mouse_move_pipept $itk_component($_pane) $args
 }
 
@@ -3825,6 +3873,18 @@
 }
 
 
+::itcl::body cadwidgets::Ged::init_find_botpt {_obj {_button 1} {_callback 
{}}} {
+    measure_line_erase
+
+    set mBotPointCallback $_callback
+
+    foreach dm {ur ul ll lr} {
+       bind $itk_component($dm) <$_button> "[::itcl::code $this 
pane_mouse_find_botpt $dm $_obj %x %y]; focus %W; break"
+       bind $itk_component($dm) <ButtonRelease-$_button> ""
+    }
+}
+
+
 ::itcl::body cadwidgets::Ged::init_find_pipept {_obj {_button 1} {_callback 
{}}} {
     measure_line_erase
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
BRL-CAD Source Commits mailing list
brlcad-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to