Revision: 76401
          http://sourceforge.net/p/brlcad/code/76401
Author:   starseeker
Date:     2020-07-22 00:38:30 +0000 (Wed, 22 Jul 2020)
Log Message:
-----------
checkpoint

Modified Paths:
--------------
    brlcad/branches/gedplugins/src/libged/view/aet.c
    brlcad/branches/gedplugins/src/libged/view/data_lines.c
    brlcad/branches/gedplugins/src/libged/view/eye.c
    brlcad/branches/gedplugins/src/libged/view/quat.c
    brlcad/branches/gedplugins/src/libged/view/size.c
    brlcad/branches/gedplugins/src/libged/view/snap.c
    brlcad/branches/gedplugins/src/libged/view/view.c
    brlcad/branches/gedplugins/src/libged/view/ypr.c

Added Paths:
-----------
    brlcad/branches/gedplugins/src/libged/exec_mapping.cpp
    brlcad/branches/gedplugins/src/libged/inside.c
    brlcad/branches/gedplugins/src/libged/snap.c
    brlcad/branches/gedplugins/src/libged/track.c
    brlcad/branches/gedplugins/src/libged/view/ged_view.h

Added: brlcad/branches/gedplugins/src/libged/exec_mapping.cpp
===================================================================
--- brlcad/branches/gedplugins/src/libged/exec_mapping.cpp                      
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/exec_mapping.cpp      2020-07-22 
00:38:30 UTC (rev 76401)
@@ -0,0 +1,1060 @@
+/*                    E X E C _ M A P P I N G . C P P
+ * BRL-CAD
+ *
+ * Copyright (c) 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.
+ */
+/** @file exec_wrapping.cpp
+ *
+ * Provide compile time wrappers that pass specific libged function
+ * calls through to the plugin system.
+ *
+ */
+
+#include "common.h"
+
+#include "ged.h"
+
+int ged_3ptarb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_E(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_adc(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_adjust(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ae2dir(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_aet(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_analyze(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_annotate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_arb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_arced(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_arot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_attr(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_autoview(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bev(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_blast(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bo(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_condense(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_decimate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_dump(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_face_fuse(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_face_sort(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_flip(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_fuse(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_merge(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_smooth(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_split(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_sync(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_bot_vertex_fuse(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_brep(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_cat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_cc(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_center(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_check(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_clone(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_coil(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_color(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_comb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_comb_color(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_comb_std(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_combmem(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_concat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_constraint(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_copy(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_copyeval(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_copymat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_cpi(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_dbip(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_dbot_dump(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_debug(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_debugbu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_debugdir(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_debuglib(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_debugnmg(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_decompose(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_delay(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_dir2ae(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_draw(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_dsp(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_dump(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_dup(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_eac(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_echo(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_edarb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_edcodes(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_edcolor(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_edcomb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_edit(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_editit(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_edmater(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_env(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_erase(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ev(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_exists(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_expand(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_eye(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_eye_pos(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_facetize(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_fb2pix(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_fbclear(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_find(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_find_arb_edge_nearest_pnt(struct ged *gedp, int argc, const char 
*argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_form(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_fracture(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_gdiff(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_get(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_get_autoview(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_get_comb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_get_eyemodel(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_get_type(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_glob(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_gqa(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_graph(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_grid(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_grid2model_lu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_grid2view_lu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_group(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_heal(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_help(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_hide(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_how(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_human(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_illum(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_importFg4Section(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_in(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_inside(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_instance(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_isize(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_item(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_joint(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_joint2(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_keep(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_keypoint(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_kill(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_killall(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_killrefs(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_killtree(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_lc(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_lint(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_list(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_loadview(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_lod(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_log(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_lookat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ls(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_lt(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_m2v_point(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_make(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_make_name(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_make_pnts(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_match(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_mater(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_mirror(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_model2grid_lu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_model2view(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_model2view_lu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_move(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_move_all(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_move_arb_edge(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_move_arb_face(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_mrot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_nirt(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_nmg(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_nmg_collapse(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_nmg_fix_normals(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_nmg_simplify(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ocenter(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_orient(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_orotate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_oscale(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_otranslate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_overlay(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pathlist(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pathsum(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_perspective(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pix2fb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_plot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pmat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pmodel2view(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_png(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_png2fb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pnts(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_prcolor(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_prefix(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_preview(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_process(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_protate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ps(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pscale(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pset(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ptranslate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_pull(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_push(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_put(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_put_comb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_putmat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_qray(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_quat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_qvrot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rcodes(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rect(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_red(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_redraw(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_regdef(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_region(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_remove(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_reopen(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rfarb(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rmap(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rmat(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rmater(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rot_point(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rrt(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rselect(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rt(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rtabort(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rtcheck(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_rtwizard(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_savekey(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_saveview(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_scale(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_screen_grab(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_search(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_select(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_set_output_script(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_set_transparency(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_set_uplotOutputMode(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_setview(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_shaded_mode(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_shader(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_shells(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_showmats(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_simulate(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_size(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_slew(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_solid_report(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_solids_on_ray(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_sphgroup(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_summary(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_sync(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tables(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tire(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_title(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tol(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tops(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tra(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_track(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tracker(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_tree(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_unhide(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_units(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_v2m_point(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_vdraw(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_version(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_view2grid_lu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_view2model(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_view2model_lu(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_view2model_vec(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_view_func(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_viewdir(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_vnirt(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_voxelize(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_vrot(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_wcodes(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_whatid(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_which(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_which_shader(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_who(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_wmater(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_xpush(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_ypr(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_zap(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+int ged_zoom(struct ged *gedp, int argc, const char *argv[])
+{
+    return ged_exec(gedp, argc, argv);
+}
+
+// Local Variables:
+// tab-width: 8
+// mode: C++
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// c-file-style: "stroustrup"
+// End:
+// ex: shiftwidth=4 tabstop=8
+


Property changes on: brlcad/branches/gedplugins/src/libged/exec_mapping.cpp
___________________________________________________________________
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
Added: brlcad/branches/gedplugins/src/libged/inside.c
===================================================================
--- brlcad/branches/gedplugins/src/libged/inside.c                              
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/inside.c      2020-07-22 00:38:30 UTC 
(rev 76401)
@@ -0,0 +1,1163 @@
+/*                        I N S I D E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-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.
+ */
+/** @file libged/inside.c
+ *
+ * The inside command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+
+
+#include "vmath.h"
+#include "bn.h"
+#include "nmg.h"
+#include "rt/geom.h"
+#include "raytrace.h"
+#include "rt/db4.h"
+
+#include "./ged_private.h"
+
+
+static char *p_arb4[] = {
+    "Enter thickness for face 123: ",
+    "Enter thickness for face 124: ",
+    "Enter thickness for face 234: ",
+    "Enter thickness for face 134: ",
+};
+
+
+static char *p_arb5[] = {
+    "Enter thickness for face 1234: ",
+    "Enter thickness for face 125: ",
+    "Enter thickness for face 235: ",
+    "Enter thickness for face 345: ",
+    "Enter thickness for face 145: ",
+};
+
+
+static char *p_arb6[] = {
+    "Enter thickness for face 1234: ",
+    "Enter thickness for face 2356: ",
+    "Enter thickness for face 1564: ",
+    "Enter thickness for face 125: ",
+    "Enter thickness for face 346: ",
+};
+
+
+static char *p_arb7[] = {
+    "Enter thickness for face 1234: ",
+    "Enter thickness for face 567: ",
+    "Enter thickness for face 145: ",
+    "Enter thickness for face 2376: ",
+    "Enter thickness for face 1265: ",
+    "Enter thickness for face 3475: ",
+};
+
+
+static char *p_arb8[] = {
+    "Enter thickness for face 1234: ",
+    "Enter thickness for face 5678: ",
+    "Enter thickness for face 1485: ",
+    "Enter thickness for face 2376: ",
+    "Enter thickness for face 1265: ",
+    "Enter thickness for face 3487: ",
+};
+
+
+static char *p_tgcin[] = {
+    "Enter thickness for base (AxB): ",
+    "Enter thickness for top (CxD): ",
+    "Enter thickness for side: ",
+};
+
+
+static char *p_partin[] = {
+    "Enter thickness for body: ",
+};
+
+
+static char *p_rpcin[] = {
+    "Enter thickness for front plate (contains V): ",
+    "Enter thickness for back plate: ",
+    "Enter thickness for top plate: ",
+    "Enter thickness for body: ",
+};
+
+
+static char *p_rhcin[] = {
+    "Enter thickness for front plate (contains V): ",
+    "Enter thickness for back plate: ",
+    "Enter thickness for top plate: ",
+    "Enter thickness for body: ",
+};
+
+
+static char *p_epain[] = {
+    "Enter thickness for top plate: ",
+    "Enter thickness for body: ",
+};
+
+
+static char *p_ehyin[] = {
+    "Enter thickness for top plate: ",
+    "Enter thickness for body: ",
+};
+
+
+static char *p_etoin[] = {
+    "Enter thickness for body: ",
+};
+
+
+static char *p_nmgin[] = {
+    "Enter thickness for shell: ",
+};
+
+
+/* finds inside arbs */
+static int
+arbin(struct ged *gedp,
+      struct rt_db_internal *ip,
+      fastf_t thick[6],
+      size_t nface,
+      int cgtype,              /* # of points, 4..8 */
+      plane_t planes[6])
+{
+    struct rt_arb_internal *arb = (struct rt_arb_internal *)ip->idb_ptr;
+    point_t center_pt = VINIT_ZERO;
+    size_t num_pts=8;  /* number of points to solve using 
rt_arb_3face_intersect */
+    size_t i;
+
+    RT_ARB_CK_MAGIC(arb);
+
+    /* find reference point (center_pt[3]) to find direction of normals */
+    rt_arb_centroid(&center_pt, ip);
+
+    /* move new face planes for the desired thicknesses
+     * don't do this yet for an arb7 */
+    if (cgtype != 7) {
+       for (i = 0; i < nface; i++) {
+           if ((planes[i][W] - VDOT(center_pt, &planes[i][0])) > 0.0)
+               thick[i] *= -1.0;
+           planes[i][W] += thick[i];
+       }
+    }
+
+    if (cgtype == 5)
+       num_pts = 4;    /* use rt_arb_3face_intersect for first 4 points */
+    else if (cgtype == 7)
+       num_pts = 0;    /* don't use rt_arb_3face_intersect for any points */
+
+    /* find the new vertices by intersecting the new face planes */
+    for (i = 0; i < num_pts; i++) {
+       if (rt_arb_3face_intersect(arb->pt[i], (const plane_t *)planes, cgtype, 
i*3) < 0) {
+           bu_vls_printf(gedp->ged_result_str, "cannot find inside arb\n");
+           return GED_ERROR;
+       }
+    }
+
+    /* The following is code for the special cases of arb5 and arb7
+     * These arbs have a vertex that is the intersection of four planes, and
+     * the inside solid may have a single vertex or an edge replacing this 
vertex
+     */
+    if (cgtype == 5) {
+       /* Here we are only concerned with the one vertex where 4 planes 
intersect
+        * in the original solid
+        */
+       point_t pt[4];
+       fastf_t dist0, dist1;
+
+       /* calculate the four possible intersect points */
+       if (bn_make_pnt_3planes(pt[0], planes[1], planes[2], planes[3])) {
+           bu_vls_printf(gedp->ged_result_str, "Cannot find inside arb5\n");
+           bu_vls_printf(gedp->ged_result_str, "Cannot find intersection of 
three planes for point 0:\n");
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[1]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[2]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[3]));
+           return GED_ERROR;
+       }
+       if (bn_make_pnt_3planes(pt[1], planes[2], planes[3], planes[4])) {
+           bu_vls_printf(gedp->ged_result_str, "Cannot find inside arb5\n");
+           bu_vls_printf(gedp->ged_result_str, "Cannot find intersection of 
three planes for point 1:\n");
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[2]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[3]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[4]));
+           return GED_ERROR;
+       }
+       if (bn_make_pnt_3planes(pt[2], planes[3], planes[4], planes[1])) {
+           bu_vls_printf(gedp->ged_result_str, "Cannot find inside arb5\n");
+           bu_vls_printf(gedp->ged_result_str, "Cannot find intersection of 
three planes for point 2:\n");
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[3]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[4]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[1]));
+           return GED_ERROR;
+       }
+       if (bn_make_pnt_3planes(pt[3], planes[4], planes[1], planes[2])) {
+           bu_vls_printf(gedp->ged_result_str, "Cannot find inside arb5\n");
+           bu_vls_printf(gedp->ged_result_str, "Cannot find intersection of 
three planes for point 3:\n");
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[4]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[1]));
+           bu_vls_printf(gedp->ged_result_str, "\t%f %f %f %f\n", 
V4ARGS(planes[2]));
+           return GED_ERROR;
+       }
+
+       if (bn_pnt3_pnt3_equal(pt[0], pt[1], &gedp->ged_wdbp->wdb_tol)) {
+           /* if any two of the calculates intersection points are equal,
+            * then all four must be equal
+            */
+           for (i = 4; i < 8; i++)
+               VMOVE(arb->pt[i], pt[0]);
+
+           return GED_OK;
+       }
+
+       /* There will be an edge where the four planes come together
+        * Two edges of intersection have been calculated
+        * pt[0]<->pt[2]
+        * pt[1]<->pt[3]
+        * the one closest to the non-involved plane (planes[0]) is the
+        * one we want
+        */
+
+       dist0 = DIST_PNT_PLANE(pt[0], planes[0]);
+       if (dist0 < 0.0)
+           dist0 = (-dist0);
+
+       dist1 = DIST_PNT_PLANE(pt[1], planes[0]);
+       if (dist1 < 0.0)
+           dist1 = (-dist1);
+
+       if (dist0 < dist1) {
+           VMOVE(arb->pt[5], pt[0]);
+           VMOVE(arb->pt[6], pt[0]);
+           VMOVE(arb->pt[4], pt[2]);
+           VMOVE(arb->pt[7], pt[2]);
+       } else {
+           VMOVE(arb->pt[4], pt[3]);
+           VMOVE(arb->pt[5], pt[3]);
+           VMOVE(arb->pt[6], pt[1]);
+           VMOVE(arb->pt[7], pt[1]);
+       }
+    } else if (cgtype == 7) {
+       struct model *m;
+       struct nmgregion *r;
+       struct shell *s = NULL;
+       struct faceuse *fu;
+       struct bg_tess_tol ttol;
+       struct bu_ptbl vert_tab;
+       struct rt_bot_internal *bot;
+
+       ttol.magic = BG_TESS_TOL_MAGIC;
+       ttol.abs = gedp->ged_wdbp->wdb_ttol.abs;
+       ttol.rel = gedp->ged_wdbp->wdb_ttol.rel;
+       ttol.norm = gedp->ged_wdbp->wdb_ttol.norm;
+
+       /* Make a model to hold the inside solid */
+       m = nmg_mm();
+
+       /* get an NMG version of this arb7 */
+       if (!OBJ[ip->idb_type].ft_tessellate || 
OBJ[ip->idb_type].ft_tessellate(&r, m, ip, &ttol, &gedp->ged_wdbp->wdb_tol)) {
+           bu_vls_printf(gedp->ged_result_str, "Cannot tessellate arb7\n");
+           rt_db_free_internal(ip);
+           return GED_ERROR;
+       }
+
+       /* move face planes */
+       for (i = 0; i < nface; i++) {
+           int found=0;
+
+           /* look for the face plane with the same geometry as the arb7 
planes */
+           s = BU_LIST_FIRST(shell, &r->s_hd);
+           for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
+               struct face_g_plane *fg;
+               plane_t pl;
+
+               NMG_CK_FACEUSE(fu);
+               if (fu->orientation != OT_SAME)
+                   continue;
+
+               NMG_GET_FU_PLANE(pl, fu);
+               if (bn_coplanar(planes[i], pl, &gedp->ged_wdbp->wdb_tol) > 0) {
+                   /* found the NMG face geometry that matches arb face i */
+                   found = 1;
+                   fg = fu->f_p->g.plane_p;
+                   NMG_CK_FACE_G_PLANE(fg);
+
+                   /* move the face by distance "thick[i]" */
+                   if (fu->f_p->flip)
+                       fg->N[3] += thick[i];
+                   else
+                       fg->N[3] -= thick[i];
+
+                   break;
+               }
+           }
+           if (!found) {
+               bu_vls_printf(gedp->ged_result_str, "Could not move face plane 
for arb7, face #%zu\n", i);
+               nmg_km(m);
+               return GED_ERROR;
+           }
+       }
+
+       /* solve for new vertex geometry
+        * This does all the vertices
+        */
+       bu_ptbl_init(&vert_tab, 64, "vert_tab");
+       nmg_vertex_tabulate(&vert_tab, &m->magic, &RTG.rtg_vlfree);
+       for (i = 0; i < BU_PTBL_LEN(&vert_tab); i++) {
+           struct vertex *v;
+
+           v = (struct vertex *)BU_PTBL_GET(&vert_tab, i);
+           NMG_CK_VERTEX(v);
+
+           if (nmg_in_vert(v, 0, &RTG.rtg_vlfree, &gedp->ged_wdbp->wdb_tol)) {
+               bu_vls_printf(gedp->ged_result_str, "Could not find coordinates 
for inside arb7\n");
+               nmg_km(m);
+               bu_ptbl_free(&vert_tab);
+               return GED_ERROR;
+           }
+       }
+       bu_ptbl_free(&vert_tab);
+
+       /* rebound model */
+       nmg_rebound(m, &gedp->ged_wdbp->wdb_tol);
+
+       nmg_extrude_cleanup(s, 0, &RTG.rtg_vlfree, &gedp->ged_wdbp->wdb_tol);
+
+       /* free old ip pointer */
+       rt_db_free_internal(ip);
+
+       /* convert the NMG to a BOT */
+       bot = (struct rt_bot_internal *)nmg_bot(s, &RTG.rtg_vlfree, 
&gedp->ged_wdbp->wdb_tol);
+       nmg_km(m);
+
+       /* put new solid in "ip" */
+       ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
+       ip->idb_type = ID_BOT;
+       ip->idb_meth = &OBJ[ID_BOT];
+       ip->idb_ptr = (void *)bot;
+    }
+
+    return GED_OK;
+}
+
+
+/* Calculates inside TGC
+ *
+ * thick[0] is thickness for base (AxB)
+ * thick[1] is thickness for top (CxD)
+ * thick[2] is thickness for side
+ */
+static int
+tgcin(struct ged *gedp, struct rt_db_internal *ip, fastf_t thick[6])
+{
+    struct rt_tgc_internal *tgc = (struct rt_tgc_internal *)ip->idb_ptr;
+    vect_t norm;               /* unit vector normal to base */
+    fastf_t normal_height;     /* height in direction normal to base */
+    vect_t v, h;               /* parameters for inside TGC */
+    point_t top;               /* vertex at top of inside TGC */
+    fastf_t mag_a, mag_b, mag_c, mag_d; /* lengths of original semi-radii */
+    fastf_t new_mag_a, new_mag_b, new_mag_c, new_mag_d; /* new lengths */
+    vect_t unit_a, unit_b, unit_c, unit_d; /* unit vectors along semi radii */
+    fastf_t ratio;
+
+    RT_TGC_CK_MAGIC(tgc);
+
+    VSETALL(unit_a, 0);
+    VSETALL(unit_b, 0);
+    VSETALL(unit_c, 0);
+    VSETALL(unit_d, 0);
+
+    VCROSS(norm, tgc->a, tgc->b);
+    VUNITIZE(norm);
+
+    normal_height = VDOT(norm, tgc->h);
+    if (normal_height < 0.0) {
+       normal_height = (-normal_height);
+       VREVERSE(norm, norm);
+    }
+
+    if ((thick[0] + thick[1]) >= normal_height) {
+       bu_vls_printf(gedp->ged_result_str, "TGC shorter than base and top 
thicknesses\n");
+       return GED_ERROR;
+    }
+
+    mag_a = MAGNITUDE(tgc->a);
+    mag_b = MAGNITUDE(tgc->b);
+    mag_c = MAGNITUDE(tgc->c);
+    mag_d = MAGNITUDE(tgc->d);
+
+    if ((mag_a < VDIVIDE_TOL && mag_c < VDIVIDE_TOL) ||
+       (mag_b < VDIVIDE_TOL && mag_d < VDIVIDE_TOL)) {
+       bu_vls_printf(gedp->ged_result_str, "TGC is too small too create inside 
solid");
+       return GED_ERROR;
+    }
+
+    if (mag_a >= VDIVIDE_TOL) {
+       VSCALE(unit_a, tgc->a, 1.0/mag_a);
+    } else if (mag_c >= VDIVIDE_TOL) {
+       VSCALE(unit_a, tgc->c, 1.0/mag_c);
+    }
+
+    if (mag_c >= VDIVIDE_TOL) {
+       VSCALE(unit_c, tgc->c, 1.0/mag_c);
+    } else if (mag_a >= VDIVIDE_TOL) {
+       VSCALE(unit_c, tgc->a, 1.0/mag_a);
+    }
+
+    if (mag_b >= VDIVIDE_TOL) {
+       VSCALE(unit_b, tgc->b, 1.0/mag_b);
+    } else if (mag_d >= VDIVIDE_TOL) {
+       VSCALE(unit_b, tgc->d, 1.0/mag_d);
+    }
+
+    if (mag_d >= VDIVIDE_TOL) {
+       VSCALE(unit_d, tgc->d, 1.0/mag_d);
+    } else if (mag_c >= VDIVIDE_TOL) {
+       VSCALE(unit_d, tgc->b, 1.0/mag_b);
+    }
+
+    /* Calculate new vertex from base thickness */
+    if (!ZERO(thick[0])) {
+       /* calculate new vertex using similar triangles */
+       ratio = thick[0]/normal_height;
+       VJOIN1(v, tgc->v, ratio, tgc->h);
+
+       /* adjust lengths of a and c to account for new vertex position */
+       new_mag_a = mag_a + (mag_c - mag_a)*ratio;
+       new_mag_b = mag_b + (mag_d - mag_b)*ratio;
+    } else {
+       /* just copy the existing values */
+       VMOVE(v, tgc->v);
+       new_mag_a = mag_a;
+       new_mag_b = mag_b;
+    }
+
+    /* calculate new height vector */
+    if (!ZERO(thick[1])) {
+       /* calculate new height vector using similar triangles */
+       ratio = thick[1]/normal_height;
+       VJOIN1(top, tgc->v, 1.0 - ratio, tgc->h);
+
+       /* adjust lengths of c and d */
+       new_mag_c = mag_c + (mag_a - mag_c)*ratio;
+       new_mag_d = mag_d + (mag_b - mag_d)*ratio;
+    } else {
+       /* just copy existing values */
+       VADD2(top, tgc->v, tgc->h);
+       new_mag_c = mag_c;
+       new_mag_d = mag_d;
+    }
+
+    /* calculate new height vector based on new vertex and top */
+    VSUB2(h, top, v);
+
+    if (!ZERO(thick[2])) {
+       /* there is a side thickness */
+       vect_t ctoa;    /* unit vector from tip of C to tip of A */
+       vect_t dtob;    /* unit vector from tip of D to tip of B */
+       point_t pt_a, pt_b, pt_c, pt_d; /* points at tips of semi radii */
+       fastf_t delta_ac, delta_bd;     /* radius change for thickness */
+       fastf_t dot;    /* dot product */
+       fastf_t ratio1, ratio2;
+
+       if ((thick[2] >= new_mag_a || thick[2] >= new_mag_b) &&
+           (thick[2] >= new_mag_c || thick[2] >= new_mag_d)) {
+           /* can't make a small enough TGC */
+           bu_vls_printf(gedp->ged_result_str, "Side thickness too large\n");
+           return GED_ERROR;
+       }
+
+       /* approach this as two 2D problems. One is in the plane containing
+        * the a, h, and c vectors. The other is in the plane containing
+        * the b, h, and d vectors.
+        * In the ahc plane:
+        * Calculate the amount that both a and c must be changed to produce
+        * a normal thickness of thick[2]. Use the vector from tip of c to tip
+        * of a and the unit_a vector to get sine of angle that the normal
+        * side thickness makes with vector a (and so also with vector c).
+        * The amount vectors a and c must change is thick[2]/(cosine of that 
angle).
+        * Similar for the bhd plane.
+        */
+
+       /* Calculate unit vectors from tips of c/d to tips of a/b */
+       VJOIN1(pt_a, v, new_mag_a, unit_a);
+       VJOIN1(pt_b, v, new_mag_b, unit_b);
+       VJOIN2(pt_c, v, 1.0, h, new_mag_c, unit_c);
+       VJOIN2(pt_d, v, 1.0, h, new_mag_d, unit_d);
+       VSUB2(ctoa, pt_a, pt_c);
+       VSUB2(dtob, pt_b, pt_d);
+       VUNITIZE(ctoa);
+       VUNITIZE(dtob);
+
+       /* Calculate amount vectors a and c must change */
+       dot = VDOT(ctoa, unit_a);
+       delta_ac = thick[2]/sqrt(1.0 - dot*dot);
+
+       /* Calculate amount vectors d and d must change */
+       dot = VDOT(dtob, unit_b);
+       delta_bd = thick[2]/sqrt(1.0 - dot*dot);
+
+       if ((delta_ac > new_mag_a || delta_bd > new_mag_b) &&
+           (delta_ac > new_mag_c || delta_bd > new_mag_d)) {
+           /* Can't make TGC small enough */
+           bu_vls_printf(gedp->ged_result_str, "Side thickness too large\n");
+           return GED_ERROR;
+       }
+
+       /* Check if changes will make vectors a or d lengths negative */
+       if (delta_ac >= new_mag_c || delta_bd >= new_mag_d) {
+           /* top vertex (height) must move. Calculate similar triangle ratios 
*/
+           if (delta_ac >= new_mag_c)
+               ratio1 = (new_mag_a - delta_ac)/(new_mag_a - new_mag_c);
+           else
+               ratio1 = 1.0;
+
+           if (delta_bd >= new_mag_d)
+               ratio2 = (new_mag_b - delta_bd)/(new_mag_b - new_mag_d);
+           else
+               ratio2 = 1.0;
+
+           /* choose the smallest similar triangle for setting new top vertex 
*/
+           if (ratio1 < ratio2)
+               ratio = ratio1;
+           else
+               ratio = ratio2;
+
+           if (ZERO(ratio1 - ratio) && ratio1 < 1.0) /* c vector must go to 
zero */
+               new_mag_c = SQRT_SMALL_FASTF;
+           else if (ratio1 > ratio && ratio < 1.0) {
+               /* vector d will go to zero, but vector c will not */
+
+               /* calculate original length of vector c at new top vertex */
+               new_mag_c = new_mag_c + (new_mag_a - new_mag_c)*(1.0 - ratio);
+
+               /* now just subtract delta */
+               new_mag_c -= delta_ac;
+           } else /* just change c vector length by delta */
+               new_mag_c -= delta_ac;
+
+           if (ZERO(ratio2 - ratio) && ratio2 < 1.0) /* vector d must go to 
zero */
+               new_mag_d = SQRT_SMALL_FASTF;
+           else if (ratio2 > ratio && ratio < 1.0) {
+               /* calculate vector length at new top vertex */
+               new_mag_d = new_mag_d + (new_mag_b - new_mag_d)*(1.0 - ratio);
+
+               /* now just subtract delta */
+               new_mag_d -= delta_bd;
+           } else /* just adjust length */
+               new_mag_d -= delta_bd;
+
+           VSCALE(h, h, ratio);
+           new_mag_a -= delta_ac;
+           new_mag_b -= delta_bd;
+       } else if (delta_ac >= new_mag_a || delta_bd >= new_mag_b) {
+           /* base vertex (v) must move */
+
+           /* Calculate similar triangle ratios */
+           if (delta_ac >= new_mag_a)
+               ratio1 = (new_mag_c - delta_ac)/(new_mag_c - new_mag_a);
+           else
+               ratio1 = 1.0;
+
+           if (delta_bd >= new_mag_b)
+               ratio2 = (new_mag_d - delta_bd)/(new_mag_d - new_mag_b);
+           else
+               ratio2 = 1.0;
+
+           /* select smallest triangle to set new base vertex */
+           if (ratio1 < ratio2)
+               ratio = ratio1;
+           else
+               ratio = ratio2;
+
+           if (ZERO(ratio1 - ratio) && ratio1 < 1.0) /* vector a must go to 
zero */
+               new_mag_a = SQRT_SMALL_FASTF;
+           else if (ratio1 > ratio && ratio < 1.0) {
+               /* calculate length of vector a if it were at new base location 
*/
+               new_mag_a = new_mag_c + (new_mag_a - new_mag_c)*ratio;
+
+               /* now just subtract delta */
+               new_mag_a -= delta_ac;
+           } else /* just subtract delta */
+               new_mag_a -= delta_ac;
+
+           if (ZERO(ratio2 - ratio) && ratio2 < 1.0) /* vector b must go to 
zero */
+               new_mag_b = SQRT_SMALL_FASTF;
+           else if (ratio2 > ratio && ratio < 1.0) {
+               /* Calculate length of b if it were at new base vector */
+               new_mag_b = new_mag_d + (new_mag_b - new_mag_d)*ratio;
+
+               /* now just subtract delta */
+               new_mag_b -= delta_bd;
+           } else /* just subtract delta */
+               new_mag_b -= delta_bd;
+
+           /* adjust height vector using smallest similar triangle ratio */
+           VJOIN1(v, v, 1.0-ratio, h);
+           VSUB2(h, top, v);
+           new_mag_c -= delta_ac;
+           new_mag_d -= delta_bd;
+       } else {
+           /* just change the vector lengths */
+           new_mag_a -= delta_ac;
+           new_mag_b -= delta_bd;
+           new_mag_c -= delta_ac;
+           new_mag_d -= delta_bd;
+       }
+    }
+
+/* copy new values into the TGC */
+    VMOVE(tgc->v, v);
+    VMOVE(tgc->h, h);
+    VSCALE(tgc->a, unit_a, new_mag_a);
+    VSCALE(tgc->b, unit_b, new_mag_b);
+    VSCALE(tgc->c, unit_c, new_mag_c);
+    VSCALE(tgc->d, unit_d, new_mag_d);
+
+    return GED_OK;
+}
+
+
+/* finds inside of torus */
+static int
+torin(struct ged *gedp, struct rt_db_internal *ip, fastf_t thick[6])
+{
+    struct rt_tor_internal *tor = (struct rt_tor_internal *)ip->idb_ptr;
+
+    RT_TOR_CK_MAGIC(tor);
+    if (ZERO(thick[0]))
+       return GED_OK;
+
+    if (thick[0] < 0) {
+       if ((tor->r_h - thick[0]) > (tor->r_a + .01)) {
+           bu_vls_printf(gedp->ged_result_str, "cannot do: r2 > r1\n");
+           return GED_ERROR;
+       }
+    }
+    if (thick[0] >= tor->r_h) {
+       bu_vls_printf(gedp->ged_result_str, "cannot do: r2 <= 0\n");
+       return GED_ERROR;
+    }
+
+    tor->r_h = tor->r_h - thick[0];
+
+    return GED_OK;
+}
+
+
+/* finds inside ell */
+static int
+ellin(struct ged *gedp, struct rt_db_internal *ip, fastf_t thick[6])
+{
+    struct rt_ell_internal *ell = (struct rt_ell_internal *)ip->idb_ptr;
+    int i;
+    fastf_t mag[3], nmag[3];
+
+    thick[2] = thick[1] = thick[0];    /* uniform thickness */
+
+    RT_ELL_CK_MAGIC(ell);
+    mag[0] = MAGNITUDE(ell->a);
+    mag[1] = MAGNITUDE(ell->b);
+    mag[2] = MAGNITUDE(ell->c);
+
+    if (thick[0] > 0 && (mag[0] < thick[0] + RT_LEN_TOL)){
+       bu_vls_printf(gedp->ged_result_str, "Magnitude of ell->a (%.2f) is too 
small for an inside thickness of %.2f \n", mag[0], thick[0]);
+       return GED_ERROR;
+    }
+    if (thick[1] > 0 && (mag[1] < thick[1] + RT_LEN_TOL)){
+       bu_vls_printf(gedp->ged_result_str, "Magnitude of ell->b (%.2f) is too 
small for an inside thickness of %.2f \n", mag[1], thick[1]);
+       return GED_ERROR;
+    }
+    if (thick[2] > 0 && (mag[2] < thick[2] + RT_LEN_TOL)){
+       bu_vls_printf(gedp->ged_result_str, "Magnitude of ell->c (%.2f) is too 
small for an inside thickness of %.2f \n", mag[2], thick[2]);
+       return GED_ERROR;
+    }
+
+    for (i = 0; i < 3; i++) {
+       nmag[i] = mag[i] - thick[i];
+    }
+    VSCALE(ell->a, ell->a, nmag[0]/mag[0]);
+    VSCALE(ell->b, ell->b, nmag[1]/mag[1]);
+    VSCALE(ell->c, ell->c, nmag[2]/mag[2]);
+
+    return GED_OK;
+}
+
+
+/* find inside of particle solid */
+static int
+partin(struct ged *UNUSED(gedp), struct rt_db_internal *ip, fastf_t *thick)
+{
+    struct rt_part_internal *part = (struct rt_part_internal *)ip->idb_ptr;
+
+    RT_PART_CK_MAGIC(part);
+
+    if (*thick >= part->part_vrad || *thick >= part->part_hrad)
+       return 1;    /* BAD */
+
+    part->part_vrad -= *thick;
+    part->part_hrad -= *thick;
+
+    return GED_OK;
+}
+
+
+/* finds inside of rpc, not quite right - r needs to be smaller */
+static int
+rpcin(struct ged *UNUSED(gedp), struct rt_db_internal *ip, fastf_t thick[4])
+{
+    struct rt_rpc_internal *rpc = (struct rt_rpc_internal *)ip->idb_ptr;
+    fastf_t b;
+    vect_t Bu, Hu, Ru;
+
+    RT_RPC_CK_MAGIC(rpc);
+
+    /* get unit coordinate axes */
+    VMOVE(Bu, rpc->rpc_B);
+    VMOVE(Hu, rpc->rpc_H);
+    VCROSS(Ru, Hu, Bu);
+    VUNITIZE(Bu);
+    VUNITIZE(Hu);
+    VUNITIZE(Ru);
+
+    b = MAGNITUDE(rpc->rpc_B);
+    VJOIN2(rpc->rpc_V, rpc->rpc_V, thick[0], Hu, thick[2], Bu);
+    VSCALE(rpc->rpc_H, Hu, MAGNITUDE(rpc->rpc_H) - thick[0] - thick[1]);
+    VSCALE(rpc->rpc_B, Bu, b - thick[2] - thick[3]);
+    rpc->rpc_r -= thick[3];
+
+    return GED_OK;
+}
+
+
+/* XXX finds inside of rhc, not quite right */
+static int
+rhcin(struct ged *UNUSED(gedp), struct rt_db_internal *ip, fastf_t thick[4])
+{
+    struct rt_rhc_internal *rhc = (struct rt_rhc_internal *)ip->idb_ptr;
+    vect_t Bn, Hn, Bu, Hu, Ru;
+
+    RT_RHC_CK_MAGIC(rhc);
+
+    VMOVE(Bn, rhc->rhc_B);
+    VMOVE(Hn, rhc->rhc_H);
+
+    /* get unit coordinate axes */
+    VMOVE(Bu, Bn);
+    VMOVE(Hu, Hn);
+    VCROSS(Ru, Hu, Bu);
+    VUNITIZE(Bu);
+    VUNITIZE(Hu);
+    VUNITIZE(Ru);
+
+    VJOIN2(rhc->rhc_V, rhc->rhc_V, thick[0], Hu, thick[2], Bu);
+    VSCALE(rhc->rhc_H, Hu, MAGNITUDE(rhc->rhc_H) - thick[0] - thick[1]);
+    VSCALE(rhc->rhc_B, Bu, MAGNITUDE(rhc->rhc_B) - thick[2] - thick[3]);
+    rhc->rhc_r -= thick[3];
+
+    return GED_OK;
+}
+
+
+/* finds inside of epa, not quite right */
+static int
+epain(struct ged *UNUSED(gedp), struct rt_db_internal *ip, fastf_t thick[2])
+{
+    struct rt_epa_internal *epa = (struct rt_epa_internal *)ip->idb_ptr;
+    vect_t Hu;
+
+    RT_EPA_CK_MAGIC(epa);
+
+    VMOVE(Hu, epa->epa_H);
+    VUNITIZE(Hu);
+
+    VJOIN1(epa->epa_V, epa->epa_V, thick[0], Hu);
+    VSCALE(epa->epa_H, Hu, MAGNITUDE(epa->epa_H) - thick[0] - thick[1]);
+    epa->epa_r1 -= thick[1];
+    epa->epa_r2 -= thick[1];
+
+    return GED_OK;
+}
+
+
+/* finds inside of ehy, not quite right, */
+static int
+ehyin(struct ged *UNUSED(gedp), struct rt_db_internal *ip, fastf_t thick[2])
+{
+    struct rt_ehy_internal *ehy = (struct rt_ehy_internal *)ip->idb_ptr;
+    vect_t Hu;
+
+    RT_EHY_CK_MAGIC(ehy);
+
+    VMOVE(Hu, ehy->ehy_H);
+    VUNITIZE(Hu);
+
+    VJOIN1(ehy->ehy_V, ehy->ehy_V, thick[0], Hu);
+    VSCALE(ehy->ehy_H, Hu, MAGNITUDE(ehy->ehy_H) - thick[0] - thick[1]);
+    ehy->ehy_r1 -= thick[1];
+    ehy->ehy_r2 -= thick[1];
+
+    return GED_OK;
+}
+
+
+/* finds inside of eto */
+static int
+etoin(struct ged *UNUSED(gedp), struct rt_db_internal *ip, fastf_t thick[1])
+{
+    fastf_t c;
+    struct rt_eto_internal *eto = (struct rt_eto_internal *)ip->idb_ptr;
+
+    RT_ETO_CK_MAGIC(eto);
+
+    c = 1.0 - thick[0]/MAGNITUDE(eto->eto_C);
+    VSCALE(eto->eto_C, eto->eto_C, c);
+    eto->eto_rd -= thick[0];
+
+    return GED_OK;
+}
+
+
+/* find inside for NMG */
+static int
+nmgin(struct ged *gedp, struct rt_db_internal *ip, fastf_t thick)
+{
+    struct model *m;
+    struct nmgregion *r;
+
+    if (ip->idb_type != ID_NMG)
+       return GED_ERROR;
+
+    m = (struct model *)ip->idb_ptr;
+    NMG_CK_MODEL(m);
+
+    r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+    while (BU_LIST_NOT_HEAD(r, &m->r_hd)) {
+       struct nmgregion *next_r;
+       struct shell *s;
+
+       NMG_CK_REGION(r);
+
+       next_r = BU_LIST_PNEXT(nmgregion, &r->l);
+
+       s = BU_LIST_FIRST(shell, &r->s_hd);
+       while (BU_LIST_NOT_HEAD(s, &r->s_hd)) {
+           struct shell *next_s;
+
+           next_s = BU_LIST_PNEXT(shell, &s->l);
+
+           nmg_shell_coplanar_face_merge(s, &gedp->ged_wdbp->wdb_tol, 1, 
&RTG.rtg_vlfree);
+           if (!nmg_kill_cracks(s))
+               (void)nmg_extrude_shell(s, thick, 0, 0, &RTG.rtg_vlfree, 
&gedp->ged_wdbp->wdb_tol);
+
+           s = next_s;
+       }
+
+       if (BU_LIST_IS_EMPTY(&r->s_hd))
+           nmg_kr(r);
+
+       r = next_r;
+    }
+
+    if (BU_LIST_IS_EMPTY(&m->r_hd)) {
+       bu_vls_printf(gedp->ged_result_str, "No inside created\n");
+       nmg_km(m);
+       return GED_ERROR;
+    } else
+       return GED_OK;
+}
+
+
+int
+ged_inside_internal(struct ged *gedp, struct rt_db_internal *ip, int argc, 
const char *argv[], int arg, char *o_name)
+{
+    size_t i;
+    struct directory *dp;
+    int cgtype = 8;            /* cgtype ARB 4..8 */
+    size_t nface;
+    fastf_t thick[6];
+    plane_t planes[6];
+    char *newname;
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    if (ip->idb_type == ID_ARB8) {
+       /* find the comgeom arb type, & reorganize */
+       int uvec[8], svec[11];
+       struct bu_vls error_msg = BU_VLS_INIT_ZERO;
+
+       if (rt_arb_get_cgtype(&cgtype, (struct rt_arb_internal *)ip->idb_ptr, 
&gedp->ged_wdbp->wdb_tol, uvec, svec) == 0) {
+           bu_vls_printf(gedp->ged_result_str, "%s: BAD ARB\n", o_name);
+           return GED_ERROR;
+       }
+
+       /* must find new plane equations to account for
+        * any editing in the es_mat matrix or path to this solid.
+        */
+       if (rt_arb_calc_planes(&error_msg, (struct rt_arb_internal 
*)ip->idb_ptr, cgtype, planes, &gedp->ged_wdbp->wdb_tol) < 0) {
+           bu_vls_printf(gedp->ged_result_str, "%s\nrt_arb_calc_planes(%s): 
failed\n", bu_vls_addr(&error_msg), o_name);
+           bu_vls_free(&error_msg);
+           return GED_ERROR;
+       }
+       bu_vls_free(&error_msg);
+    }
+
+    /* "ip" is loaded with the outside solid data */
+
+    /* get the inside solid name */
+    if (argc < arg+1) {
+       bu_vls_printf(gedp->ged_result_str, "Enter name of the inside solid: ");
+       return GED_MORE;
+    }
+    if (db_lookup(gedp->ged_wdbp->dbip, argv[arg], LOOKUP_QUIET) != 
RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s: %s already exists.\n", 
argv[0], argv[arg]);
+       return GED_ERROR;
+    }
+    if (db_version(gedp->ged_wdbp->dbip) < 5 && (int)strlen(argv[arg]) > 
NAMESIZE) {
+       bu_vls_printf(gedp->ged_result_str, "Database version 4 names are 
limited to %d characters\n", NAMESIZE);
+       return GED_ERROR;
+    }
+    newname = (char *)argv[arg];
+    ++arg;
+
+    /* get thicknesses and calculate parameters for newrec */
+    switch (ip->idb_type) {
+
+       case ID_ARB8: {
+           char **prompt = p_arb6;
+           struct rt_arb_internal *arb = (struct rt_arb_internal *)ip->idb_ptr;
+
+           nface = 6;
+
+           switch (cgtype) {
+               case 8:
+                   prompt = p_arb8;
+                   break;
+
+               case 7:
+                   prompt = p_arb7;
+                   break;
+
+               case 6:
+                   prompt = p_arb6;
+                   nface = 5;
+                   VMOVE(arb->pt[5], arb->pt[6]);
+                   break;
+
+               case 5:
+                   prompt = p_arb5;
+                   nface = 5;
+                   break;
+
+               case 4:
+                   prompt = p_arb4;
+                   nface = 4;
+                   VMOVE(arb->pt[3], arb->pt[4]);
+                   break;
+           }
+
+           for (i = 0; i < nface; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", prompt[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (arbin(gedp, ip, thick, nface, cgtype, planes))
+               return GED_ERROR;
+           break;
+       }
+
+       case ID_TGC:
+           for (i = 0; i < 3; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_tgcin[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (tgcin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_ELL:
+           if (argc < arg+1) {
+               bu_vls_printf(gedp->ged_result_str, "Enter desired thickness: 
");
+               return GED_MORE;
+           }
+           thick[0] = atof(argv[arg]) * gedp->ged_wdbp->dbip->dbi_local2base;
+           ++arg;
+
+           if (ellin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_TOR:
+           if (argc < arg+1) {
+               bu_vls_printf(gedp->ged_result_str, "Enter desired thickness: 
");
+               return GED_MORE;
+           }
+           thick[0] = atof(argv[arg]) * gedp->ged_wdbp->dbip->dbi_local2base;
+           ++arg;
+
+           if (torin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_PARTICLE:
+           for (i = 0; i < 1; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_partin[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (partin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_RPC:
+           for (i = 0; i < 4; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_rpcin[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (rpcin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_RHC:
+           for (i = 0; i < 4; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_rhcin[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (rhcin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_EPA:
+           for (i = 0; i < 2; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_epain[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (epain(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_EHY:
+           for (i = 0; i < 2; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_ehyin[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (ehyin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_ETO:
+           for (i = 0; i < 1; i++) {
+               if (argc < arg+1) {
+                   bu_vls_printf(gedp->ged_result_str, "%s", p_etoin[i]);
+                   return GED_MORE;
+               }
+               thick[i] = atof(argv[arg]) * 
gedp->ged_wdbp->dbip->dbi_local2base;
+               ++arg;
+           }
+
+           if (etoin(gedp, ip, thick))
+               return GED_ERROR;
+           break;
+
+       case ID_NMG:
+           if (argc < arg+1) {
+               bu_vls_printf(gedp->ged_result_str, "%s", *p_nmgin);
+               return GED_MORE;
+           }
+           thick[0] = atof(argv[arg]) * gedp->ged_wdbp->dbip->dbi_local2base;
+           ++arg;
+           if (nmgin(gedp,  ip, thick[0]))
+               return GED_ERROR;
+           break;
+
+       default:
+           if (ip->idb_type < 0) {
+               bu_vls_printf(gedp->ged_result_str, "Cannot find inside of 
uninitialized object.\n");
+           } else {
+               bu_vls_printf(gedp->ged_result_str, "Cannot find inside for 
'%s' solid\n", OBJ[ip->idb_type].ft_name);
+           }
+           return GED_ERROR;
+    }
+
+    /* Add to in-core directory */
+    dp = db_diradd(gedp->ged_wdbp->dbip, newname, RT_DIR_PHONY_ADDR, 0, 
RT_DIR_SOLID, (void *)&ip->idb_type);
+    if (dp == RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s: Database alloc error, 
aborting\n", argv[0]);
+       return GED_ERROR;
+    }
+    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, ip, &rt_uniresource) < 0) 
{
+       bu_vls_printf(gedp->ged_result_str, "%s: Database write error, 
aborting\n", argv[0]);
+       return GED_ERROR;
+    }
+
+    bu_vls_printf(gedp->ged_result_str, "%s", argv[2]);
+    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/branches/gedplugins/src/libged/inside.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
Added: brlcad/branches/gedplugins/src/libged/snap.c
===================================================================
--- brlcad/branches/gedplugins/src/libged/snap.c                                
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/snap.c        2020-07-22 00:38:30 UTC 
(rev 76401)
@@ -0,0 +1,251 @@
+/*                         S N A P . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2008-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.
+ */
+/** @file libged/snap.c
+ *
+ * Logic for snapping points to visual elements.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#include "bu/opt.h"
+#include "bu/vls.h"
+#include "bg/lseg.h"
+#include "dm.h"
+#include "./ged_private.h"
+
+struct ged_cp_info {
+    double ctol_sq; // square of the distance that defines "close to a line"
+
+    struct bview_data_line_state *c_lset; // container holding closest line
+    point_t cp;  // closest point on closest line
+    int c_l;     // index of closest line
+    double dsq;  // squared distance to closest line
+
+    struct bview_data_line_state *c_lset2; // container holding 2nd closest 
line
+    point_t cp2;  // closest point on closest line
+    int c_l2;   // index of 2nd closest line
+    double dsq2; // squared distance to 2nd closest line
+};
+#define GED_CP_INFO_INIT {BN_TOL_DIST, NULL, VINIT_ZERO, -1, DBL_MAX, NULL, 
VINIT_ZERO, -1, DBL_MAX}
+
+static
+int
+_find_closest_point(struct ged_cp_info *s, point_t *p, struct 
bview_data_line_state *lines)
+{
+    int ret = 0;
+    point_t P0, P1;
+
+    if (lines->gdls_num_points < 2) {
+       return ret;
+    }
+
+    // TODO - if we have a large number of lines drawn, we could really benefit
+    // from an acceleration structure such as the RTree to localize these tests
+    // rather than checking everything...
+    for (int i = 0; i < lines->gdls_num_points; i+=2) {
+       if (s->c_l == i && s->c_lset == lines) {
+           continue;
+       }
+       point_t c;
+       VMOVE(P0, lines->gdls_points[i]);
+       VMOVE(P1, lines->gdls_points[i+1]);
+       double dsq = bg_lseg_pt_dist_sq(&c, P0, P1, *p);
+       // If we're outside tolerance, continue
+       if (dsq > s->ctol_sq) {
+           continue;
+       }
+       // If this is the closest we've seen, record it
+       if (s->dsq > dsq) {
+           // Closest is now second closest
+           VMOVE(s->cp2, s->cp);
+           s->dsq2 = s->dsq;
+           s->c_l2 = s->c_l;
+           s->c_lset2 = s->c_lset;
+
+           // set new closest
+           VMOVE(s->cp, c);
+           s->dsq = dsq;
+           s->c_l = i;
+           s->c_lset = lines;
+           ret = 1;
+           continue;
+       }
+       // Not the closest - is it closer than the second closest?
+       if (s->dsq2 > dsq) {
+           VMOVE(s->cp2, c);
+           s->dsq2 = dsq;
+           s->c_l2 = i;
+           s->c_lset2 = lines;
+           ret = 2;
+           continue;
+       }
+    }
+
+    return ret;
+}
+
+void
+_find_close_isect(struct ged_cp_info *s, point_t *p)
+{
+    point_t P0, P1, Q0, Q1;
+    point_t c1, c2;
+
+    VMOVE(P0, s->c_lset->gdls_points[s->c_l]);
+    VMOVE(P1, s->c_lset->gdls_points[s->c_l+1]);
+
+    VMOVE(Q0, s->c_lset2->gdls_points[s->c_l2]);
+    VMOVE(Q1, s->c_lset2->gdls_points[s->c_l2+1]);
+
+    double csdist_sq = bg_lseg_lseg_dist_sq(&c1, &c2, P0, P1, Q0, Q1);
+    if (csdist_sq > s->ctol_sq) {
+       // Line segments are too far away to use both of them to override the
+       // original answer
+       return;
+    }
+
+    // If either closest segment point is too far from the test point, go with
+    // the original answer rather than changing it
+    double d1_sq = DIST_PNT_PNT_SQ(*p, c1);
+    if (d1_sq > s->ctol_sq) {
+       // Too far away to work
+       return;
+    }
+
+    double d2_sq = DIST_PNT_PNT_SQ(*p, c2);
+     if (d2_sq > s->ctol_sq) {
+       // Too far away to work
+       return;
+    }
+
+    // Go with the closest segment point to the original point.  If
+    // the segments intersect the two points should be the same and
+    // it won't matter which is chosen, but if they don't then the
+    // intuitive behavior is to prefer the closest point that attempts
+    // to satisfy both line segments
+    if (d1_sq < d2_sq) {
+       VMOVE(s->cp, c1);
+    } else {
+       VMOVE(s->cp, c2);
+    }
+}
+
+static double
+line_tol_sq(struct ged *gedp, struct bview_data_line_state *gdlsp)
+{
+    if (!gedp->ged_dmp) {
+       return 100*100;
+    }
+    double width = dm_get_width((struct dm *)gedp->ged_dmp);
+    double height = dm_get_height((struct dm *)gedp->ged_dmp);
+    double lavg = (width + height) * 0.5;
+    double lwidth = (gdlsp->gdls_line_width) ? gdlsp->gdls_line_width : 1;
+    double lratio = lwidth/lavg;
+    double lrsize = gedp->ged_gvp->gv_size * lratio * 
gedp->ged_gvp->gv_snap_tol_factor;
+    return lrsize*lrsize;
+}
+
+int
+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;
+
+    // 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
+    // probably want to prefer intersections between lines to closest line
+    // point if we are close to multiple lines...
+    int ret = 0;
+    cpinfo.ctol_sq = line_tol_sq(gedp, &gedp->ged_gvp->gv_data_lines);
+    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);
+    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
+    // closest approach point.  The intersection may not be close enough to
+    // use, but if it is prefer it as it satisfies two lines instead of one.
+    if (ret > 1) {
+       _find_close_isect(&cpinfo, p);
+    }
+
+    // If we found something, we can snap
+    if (ret) {
+       VMOVE(*out_pt, cpinfo.cp);
+       return GED_OK;
+    }
+
+    return GED_ERROR;
+}
+
+int
+ged_snap_to_lines(struct ged *gedp, fastf_t *vx, fastf_t *vy)
+{
+    if (!gedp || !vx || !vy) return 0;
+    if (!gedp->ged_gvp) return 0;
+
+    point2d_t p2d = {0.0, 0.0};
+    point_t p = VINIT_ZERO;
+    point_t vp = VINIT_ZERO;
+    point_t out_pt = VINIT_ZERO;
+
+    V2SET(p2d, *vx, *vy);
+    VSET(vp, p2d[0], p2d[1], 0);
+    MAT4X3PNT(p, gedp->ged_gvp->gv_view2model, vp);
+    if (ged_snap_lines(&out_pt, gedp, &p) == GED_OK) {
+       MAT4X3PNT(vp, gedp->ged_gvp->gv_model2view, out_pt);
+       (*vx) = vp[0];
+       (*vy) = vp[1];
+       return 1;
+    }
+
+    return 0;
+}
+
+// TODO - this is another function that belongs in libdm...
+void
+ged_view_center_linesnap(struct ged *gedp)
+{
+    point_t view_pt;
+    point_t model_pt;
+
+    MAT_DELTAS_GET_NEG(model_pt, gedp->ged_gvp->gv_center);
+    MAT4X3PNT(view_pt, gedp->ged_gvp->gv_model2view, model_pt);
+    ged_snap_to_lines(gedp, &view_pt[X], &view_pt[Y]);
+    MAT4X3PNT(model_pt, gedp->ged_gvp->gv_view2model, view_pt);
+    MAT_DELTAS_VEC_NEG(gedp->ged_gvp->gv_center, model_pt);
+    bview_update(gedp->ged_gvp);
+}
+
+/*
+ * Local Variables:
+ * tab-width: 8
+ * mode: C
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */


Property changes on: brlcad/branches/gedplugins/src/libged/snap.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
Added: brlcad/branches/gedplugins/src/libged/track.c
===================================================================
--- brlcad/branches/gedplugins/src/libged/track.c                               
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/track.c       2020-07-22 00:38:30 UTC 
(rev 76401)
@@ -0,0 +1,1200 @@
+/*                         T R A C K . C
+ * BRL-CAD
+ *
+ * Copyright (c) 1994-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 librt */
+/** @{ */
+/** @file libged/track.c
+ *
+ * Adds "tracks" to the data file given the required info
+ *
+ * Acknowledgements:
+ * Modifications by Bob Parker (SURVICE Engineering):
+ * *- adapt for use in LIBRT's database object
+ * *- removed prompting for input
+ * *- removed signal catching
+ * *- added basename parameter
+ */
+/** @} */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+
+#include "vmath.h"
+#include "bn.h"
+#include "rt/geom.h"
+#include "raytrace.h"
+#include "wdb.h"
+#include "ged.h"
+
+static int Trackpos = 0;
+static int mat_default = 1;
+static int los_default = 50;
+static int item_default = 500;
+static fastf_t plano[4], plant[4];
+static int grpname_len;
+static int extraTypeChars = 3;
+static int extraChars = 4;
+
+static struct track_solid {
+    int s_type;
+    char *s_name;
+    fastf_t s_values[24];
+} sol;
+
+
+/*
+ * convert integer to ascii wd format
+ */
+static void
+track_itoa(struct bu_vls *log_str,
+     int n,
+     char s[],
+     int w) {
+    int c, i, j, sign;
+
+    if ((sign = n) < 0) n = -n;
+    i = 0;
+    do s[i++] = n % 10 + '0';  while ((n /= 10) > 0);
+    if (sign < 0) s[i++] = '-';
+
+    /* blank fill array
+     */
+    for (j = i; j < w; j++) s[j] = ' ';
+    if (i > w)
+       bu_vls_printf(log_str, "track_itoa: field length too small\n");
+    s[w] = '\0';
+    /* reverse the array
+     */
+    for (i = 0, j = w - 1; i < j; i++, j--) {
+       c    = s[i];
+       s[i] = s[j];
+       s[j] =    c;
+    }
+}
+
+
+static void
+crname(struct bu_vls *log_str,
+       char name[],
+       int pos,
+       int maxlen)
+{
+    char temp[4];
+
+    track_itoa(log_str, pos, temp, 1);
+    bu_strlcat(name, temp, maxlen);
+}
+
+
+static void
+track_mk_freemembers(struct bu_list *headp)
+{
+    struct wmember *wp;
+
+    while (BU_LIST_WHILE(wp, wmember, headp)) {
+       WDB_CK_WMEMBER(wp);
+       BU_LIST_DEQUEUE(&wp->l);
+       bu_free((char *)wp->wm_name, "wm_name");
+       BU_PUT(wp, struct wmember);
+    }
+}
+
+
+/*
+ * Add some nodes to a new or existing combination's tree,
+ * with GIFT precedence and semantics.
+ *
+ * NON-PARALLEL due to rt_uniresource
+ *
+ * Returns -
+ * -1 ERROR
+ * 0 OK
+ */
+static int
+track_mk_tree_gift(struct rt_comb_internal *comb, struct bu_list *member_hd)
+{
+    struct wmember *wp;
+    union tree *tp;
+    struct rt_tree_array *tree_list;
+    size_t node_count;
+    size_t actual_count;
+    int new_nodes;
+
+    if ((new_nodes = bu_list_len(member_hd)) <= 0)
+       return 0;       /* OK, nothing to do */
+
+    if (comb->tree && db_ck_v4gift_tree(comb->tree) < 0) {
+       db_non_union_push(comb->tree, &rt_uniresource);
+       if (db_ck_v4gift_tree(comb->tree) < 0) {
+           bu_log("track_mk_tree_gift() Cannot flatten tree for editing\n");
+           return -1;
+       }
+    }
+
+    /* make space for an extra leaf */
+    node_count = db_tree_nleaves(comb->tree);
+    tree_list = (struct rt_tree_array *)bu_calloc(node_count + 
(size_t)new_nodes, sizeof(struct rt_tree_array), "tree list");
+
+    /* flatten tree */
+    if (comb->tree) {
+       /* Release storage for non-leaf nodes, steal leaves */
+       actual_count = (struct rt_tree_array *)db_flatten_tree(
+           tree_list, comb->tree, OP_UNION,
+           1, &rt_uniresource) - tree_list;
+       BU_ASSERT(actual_count == node_count);
+       comb->tree = TREE_NULL;
+    } else {
+       actual_count = 0;
+    }
+
+    /* Add new members to the array */
+    for (BU_LIST_FOR(wp, wmember, member_hd)) {
+       WDB_CK_WMEMBER(wp);
+
+       switch (wp->wm_op) {
+           case WMOP_INTERSECT:
+               tree_list[node_count].tl_op = OP_INTERSECT;
+               break;
+           case WMOP_SUBTRACT:
+               tree_list[node_count].tl_op = OP_SUBTRACT;
+               break;
+           default:
+               bu_log("track_mk_tree_gift() unrecognized relation %c (assuming 
UNION)\n", wp->wm_op);
+               /* Fall through */
+           case WMOP_UNION:
+               tree_list[node_count].tl_op = OP_UNION;
+               break;
+       }
+
+       /* make new leaf node, and insert at end of array */
+       BU_ALLOC(tp, union tree);
+       RT_TREE_INIT(tp);
+       tree_list[node_count++].tl_tree = tp;
+       tp->tr_l.tl_op = OP_DB_LEAF;
+       tp->tr_l.tl_name = bu_strdup(wp->wm_name);
+       if (!bn_mat_is_identity(wp->wm_mat)) {
+           tp->tr_l.tl_mat = bn_mat_dup(wp->wm_mat);
+       } else {
+           tp->tr_l.tl_mat = (matp_t)NULL;
+       }
+    }
+    BU_ASSERT(node_count == actual_count + (size_t)new_nodes);
+
+    /* rebuild the tree with GIFT semantics */
+    comb->tree = (union tree *)db_mkgift_tree(tree_list, node_count, 
&rt_uniresource);
+
+    bu_free((char *)tree_list, "track_mk_tree_gift: tree_list");
+
+    return 0;  /* OK */
+}
+
+
+/*
+ * Given a list of wmember structures, build a tree that performs
+ * the boolean operations in the given sequence.
+ * No GIFT semantics or precedence is provided.
+ * For that, use mk_tree_gift().
+ */
+static void
+track_mk_tree_pure(struct rt_comb_internal *comb, struct bu_list *member_hd)
+{
+    struct wmember *wp;
+
+    for (BU_LIST_FOR(wp, wmember, member_hd)) {
+       union tree *leafp, *nodep;
+
+       WDB_CK_WMEMBER(wp);
+
+       BU_ALLOC(leafp, union tree);
+       RT_TREE_INIT(leafp);
+       leafp->tr_l.tl_op = OP_DB_LEAF;
+       leafp->tr_l.tl_name = bu_strdup(wp->wm_name);
+       if (!bn_mat_is_identity(wp->wm_mat)) {
+           leafp->tr_l.tl_mat = bn_mat_dup(wp->wm_mat);
+       }
+
+       if (!comb->tree) {
+           comb->tree = leafp;
+           continue;
+       }
+       /* Build a left-heavy tree */
+       BU_ALLOC(nodep, union tree);
+       RT_TREE_INIT(nodep);
+       switch (wp->wm_op) {
+           case WMOP_UNION:
+               nodep->tr_b.tb_op = OP_UNION;
+               break;
+           case WMOP_INTERSECT:
+               nodep->tr_b.tb_op = OP_INTERSECT;
+               break;
+           case WMOP_SUBTRACT:
+               nodep->tr_b.tb_op = OP_SUBTRACT;
+               break;
+           default:
+               bu_bomb("track_mk_tree_pure() bad wm_op");
+       }
+       nodep->tr_b.tb_left = comb->tree;
+       nodep->tr_b.tb_right = leafp;
+       comb->tree = nodep;
+    }
+}
+
+
+/*
+ * Make a combination, where the
+ * members are described by a linked list of wmember structs.
+ *
+ * The linked list is freed when it has been output.
+ *
+ * Has many operating modes.
+ *
+ * Returns -
+ * -1 ERROR
+ * 0 OK
+ */
+static int
+track_mk_comb(
+    struct rt_wdb *wdbp,
+    const char *combname,
+    struct bu_list *headp,             /* Made by mk_addmember() */
+    int region_kind,   /* 1 => region.  'P' and 'V' for FASTGEN */
+    const char *shadername,    /* shader name, or NULL */
+    const char *shaderargs,    /* shader args, or NULL */
+    const unsigned char *rgb,          /* NULL => no color */
+    int id,            /* region_id */
+    int air,           /* aircode */
+    int material,      /* GIFTmater */
+    int los,
+    int inherit,
+    int append_ok,     /* 0 = obj must not exit */
+    int gift_semantics)        /* 0 = pure, 1 = gift */
+{
+    struct rt_db_internal intern;
+    struct rt_comb_internal *comb;
+    int fresh_combination;
+
+    RT_CK_WDB(wdbp);
+
+    RT_DB_INTERNAL_INIT(&intern);
+
+    if (append_ok &&
+       wdb_import(wdbp, &intern, combname, (matp_t)NULL) >= 0) {
+       /* We retrieved an existing object, append to it */
+       comb = (struct rt_comb_internal *)intern.idb_ptr;
+       RT_CK_COMB(comb);
+
+       fresh_combination = 0;
+    } else {
+       /* Create a fresh new object for export */
+       BU_ALLOC(comb, struct rt_comb_internal);
+       RT_COMB_INTERNAL_INIT(comb);
+
+       intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+       intern.idb_type = ID_COMBINATION;
+       intern.idb_ptr = (void *)comb;
+       intern.idb_meth = &OBJ[ID_COMBINATION];
+
+       fresh_combination = 1;
+    }
+
+    if (gift_semantics)
+       track_mk_tree_gift(comb, headp);
+    else
+       track_mk_tree_pure(comb, headp);
+
+    /* Release the wmember list dynamic storage */
+    track_mk_freemembers(headp);
+
+    /* Don't change these things when appending to existing combination */
+    if (fresh_combination) {
+       if (region_kind) {
+           comb->region_flag = 1;
+           switch (region_kind) {
+               case 'P':
+                   comb->is_fastgen = REGION_FASTGEN_PLATE;
+                   break;
+               case 'V':
+                   comb->is_fastgen = REGION_FASTGEN_VOLUME;
+                   break;
+               case 'R':
+               case 1:
+                   /* Regular non-FASTGEN Region */
+                   break;
+               default:
+                   bu_log("mk_comb(%s) unknown region_kind=%d (%c), assuming 
normal non-FASTGEN\n",
+                          combname, region_kind, region_kind);
+           }
+       }
+       if (shadername) bu_vls_strcat(&comb->shader, shadername);
+       if (shaderargs) {
+           bu_vls_strcat(&comb->shader, " ");
+           bu_vls_strcat(&comb->shader, shaderargs);
+           /* Convert to Tcl form if necessary.  Use heuristics */
+           if (strchr(shaderargs, '=') != NULL &&
+               strchr(shaderargs, '{') == NULL)
+           {
+               struct bu_vls old = BU_VLS_INIT_ZERO;
+               bu_vls_vlscatzap(&old, &comb->shader);
+               if (bu_shader_to_list(bu_vls_addr(&old), &comb->shader))
+                   bu_log("Unable to convert shader string '%s %s'\n", 
shadername, shaderargs);
+               bu_vls_free(&old);
+           }
+       }
+
+       if (rgb) {
+           comb->rgb_valid = 1;
+           comb->rgb[0] = rgb[0];
+           comb->rgb[1] = rgb[1];
+           comb->rgb[2] = rgb[2];
+       }
+
+       comb->region_id = id;
+       comb->aircode = air;
+       comb->GIFTmater = material;
+       comb->los = los;
+
+       comb->inherit = inherit;
+    }
+
+    /* The internal representation will be freed */
+    return wdb_put_internal(wdbp, combname, &intern, 1.0);
+}
+
+
+/*
+ * Obtain dynamic storage for a new wmember structure, fill in the
+ * name, default the operation and matrix, and add to doubly linked
+ * list.  In typical use, a one-line call is sufficient.  To change
+ * the defaults, catch the pointer that is returned, and adjust the
+ * structure to taste.
+ *
+ * The caller is responsible for initializing the header structures
+ * forward and backward links.
+ */
+static struct wmember *
+track_mk_addmember(
+    const char *name,
+    struct bu_list *headp,
+    mat_t mat,
+    int op)
+{
+    struct wmember *wp;
+
+    BU_GET(wp, struct wmember);
+    wp->l.magic = WMEMBER_MAGIC;
+    wp->wm_name = bu_strdup(name);
+    switch (op) {
+       case WMOP_UNION:
+       case WMOP_INTERSECT:
+       case WMOP_SUBTRACT:
+           wp->wm_op = op;
+           break;
+       default:
+           bu_log("mk_addmember() op=x%x is bad\n", op);
+           return WMEMBER_NULL;
+    }
+
+    /* if the user gave a matrix, use it.  otherwise use identity matrix*/
+    if (mat) {
+       MAT_COPY(wp->wm_mat, mat);
+    } else {
+       MAT_IDN(wp->wm_mat);
+    }
+
+    /* Append to end of doubly linked list */
+    BU_LIST_INSERT(headp, &wp->l);
+    return wp;
+}
+
+
+static void
+crregion(struct bu_vls *log_str,
+        struct rt_wdb *wdbp,
+        char region[],
+        char op[],
+        int members[],
+        int number,
+        char solidname[],
+        int maxlen)
+{
+    int i;
+    struct bu_list head;
+
+    if (wdbp->dbip == DBI_NULL)
+       return;
+
+    BU_LIST_INIT(&head);
+
+    for (i = 0; i < number; i++) {
+       solidname[grpname_len + extraTypeChars] = '\0';
+       crname(log_str, solidname, members[i], maxlen);
+       if (db_lookup(wdbp->dbip, solidname, LOOKUP_QUIET) == RT_DIR_NULL) {
+           bu_vls_printf(log_str, "region: %s will skip member: %s\n", region, 
solidname);
+           continue;
+       }
+       track_mk_addmember(solidname, &head, NULL, op[i]);
+    }
+    (void)track_mk_comb(wdbp, region, &head,
+                       1, NULL, NULL, NULL,
+                       500+Trackpos+i, 0, mat_default, los_default,
+                       0, 1, 1);
+}
+
+
+static int
+wrobj(struct bu_vls *log_str,
+      struct rt_wdb *wdbp,
+      const char name[],
+      int flags)
+{
+    struct directory *tdp;
+    struct rt_db_internal intern;
+    int i;
+
+    if (wdbp->dbip == DBI_NULL)
+       return GED_OK;
+
+    if (db_lookup(wdbp->dbip, name, LOOKUP_QUIET) != RT_DIR_NULL) {
+       bu_vls_printf(log_str, "track naming error: %s already exists\n", name);
+       return -1;
+    }
+
+    if (flags != RT_DIR_SOLID) {
+       bu_vls_printf(log_str, "wrobj can only write solids, aborting\n");
+       return -1;
+    }
+
+    RT_DB_INTERNAL_INIT(&intern);
+    switch (sol.s_type) {
+       case ID_ARB8: {
+           struct rt_arb_internal *arb;
+
+           BU_ALLOC(arb, struct rt_arb_internal);
+
+           arb->magic = RT_ARB_INTERNAL_MAGIC;
+
+           VMOVE(arb->pt[0], &sol.s_values[0]);
+           for (i = 1; i < 8; i++)
+               VADD2(arb->pt[i], &sol.s_values[i*3], arb->pt[0]);
+
+           intern.idb_ptr = (void *)arb;
+           intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+           intern.idb_type = ID_ARB8;
+           intern.idb_meth = &OBJ[ID_ARB8];
+       }
+           break;
+       case ID_TGC: {
+           struct rt_tgc_internal *tgc;
+
+           BU_ALLOC(tgc, struct rt_tgc_internal);
+
+           tgc->magic = RT_TGC_INTERNAL_MAGIC;
+
+           VMOVE(tgc->v, &sol.s_values[0]);
+           VMOVE(tgc->h, &sol.s_values[3]);
+           VMOVE(tgc->a, &sol.s_values[6]);
+           VMOVE(tgc->b, &sol.s_values[9]);
+           VMOVE(tgc->c, &sol.s_values[12]);
+           VMOVE(tgc->d, &sol.s_values[15]);
+
+           intern.idb_ptr = (void *)tgc;
+           intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+           intern.idb_type = ID_TGC;
+           intern.idb_meth = &OBJ[ID_TGC];
+       }
+           break;
+       default:
+           bu_vls_printf(log_str, "Unrecognized solid type in 'wrobj', 
aborting\n");
+           return GED_ERROR;
+    }
+
+    if ((tdp = db_diradd(wdbp->dbip, name, RT_DIR_PHONY_ADDR, 0, flags, (void 
*)&intern.idb_type)) == RT_DIR_NULL) {
+       rt_db_free_internal(&intern);
+       bu_vls_printf(log_str, "Cannot add '%s' to directory, aborting\n", 
name);
+       return GED_ERROR;
+    }
+
+    if (rt_db_put_internal(tdp, wdbp->dbip, &intern, &rt_uniresource) < 0) {
+       rt_db_free_internal(&intern);
+       bu_vls_printf(log_str, "write error\n");
+       bu_vls_printf(log_str, "The in-memory table of contents may not match 
the status of the on-disk\ndatabase.  The on-disk database should still be 
intact.  For safety, \nyou should exit now, and resolve the I/O problem, before 
continuing.\n");
+       return GED_ERROR;
+    }
+    return GED_OK;
+}
+
+static void
+tancir(struct bu_vls *log_str,
+       fastf_t cir1[],
+       fastf_t cir2[]) {
+    static fastf_t mag;
+    vect_t work;
+    fastf_t f;
+    static fastf_t temp, tempp, ang, angc;
+
+    work[0] = cir2[0] - cir1[0];
+    work[2] = cir2[1] - cir1[1];
+    work[1] = 0.0;
+    mag = MAGNITUDE(work);
+    if (mag > 1.0e-20 || mag < -1.0e-20) {
+       f = 1.0/mag;
+    } else {
+       bu_vls_printf(log_str, "tancir():  0-length vector!\n");
+       return;
+    }
+    VSCALE(work, work, f);
+    temp = acos(work[0]);
+    if (work[2] < 0.0)
+       temp = 6.28318512717958646 - temp;
+    tempp = acos((cir1[2] - cir2[2]) * f);
+    ang = temp + tempp;
+    angc = temp - tempp;
+    if ((cir1[1] + cir1[2] * sin(ang)) >
+       (cir1[1] + cir1[2] * sin(angc)))
+       ang = angc;
+    plano[0] = cir1[0] + cir1[2] * cos(ang);
+    plano[1] = cir1[1] + cir1[2] * sin(ang);
+    plant[0] = cir2[0] + cir2[2] * cos(ang);
+    plant[1] = cir2[1] + cir2[2] * sin(ang);
+
+    return;
+}
+
+
+static void
+slope(struct bu_vls *log_str,
+      fastf_t wh1[],
+      fastf_t wh2[],
+      fastf_t t[]) {
+    int i, j, switchs;
+    fastf_t temp;
+    fastf_t mag;
+    fastf_t z, r, b;
+    vect_t del, work;
+
+    switchs = 0;
+    if (wh1[2] < wh2[2]) {
+       switchs++;
+       for (i = 0; i < 3; i++) {
+           temp = wh1[i];
+           wh1[i] = wh2[i];
+           wh2[i] = temp;
+       }
+    }
+    tancir(log_str, wh1, wh2);
+    if (switchs) {
+       for (i = 0; i < 3; i++) {
+           temp = wh1[i];
+           wh1[i] = wh2[i];
+           wh2[i] = temp;
+       }
+    }
+    if (plano[1] <= plant[1]) {
+       for (i = 0; i < 2; i++) {
+           temp = plano[i];
+           plano[i] = plant[i];
+           plant[i] = temp;
+       }
+    }
+    del[1] = 0.0;
+    del[0] = plano[0] - plant[0];
+    del[2] = plano[1] - plant[1];
+    mag = MAGNITUDE(del);
+    work[0] = -1.0 * t[2] * del[2] / mag;
+    if (del[0] < 0.0)
+       work[0] *= -1.0;
+    work[1] = 0.0;
+    work[2] = t[2] * fabs(del[0]) / mag;
+    b = (plano[1] - work[2]) - (del[2]/del[0]*(plano[0] - work[0]));
+    z = wh1[1];
+    r = wh1[2];
+    if (wh1[1] >= wh2[1]) {
+       z = wh2[1];
+       r = wh2[2];
+    }
+    sol.s_values[2] = z - r - t[2];
+    sol.s_values[1] = t[0];
+    sol.s_values[0] = (sol.s_values[2] - b) / (del[2] / del[0]);
+    sol.s_values[3] = plano[0] + (del[0]/mag) - work[0] - sol.s_values[0];
+    sol.s_values[4] = 0.0;
+    sol.s_values[5] = plano[1] + (del[2]/mag) - work[2] - sol.s_values[2];
+    VADD2(&sol.s_values[6], &sol.s_values[3], work);
+    VMOVE(&sol.s_values[9], work);
+    work[0] = work[2] = 0.0;
+    work[1] = t[1] - t[0];
+    VMOVE(&sol.s_values[12], work);
+    for (i = 3; i <= 9; i += 3) {
+       j = i + 12;
+       VADD2(&sol.s_values[j], &sol.s_values[i], work);
+    }
+
+    return;
+}
+
+
+static void
+crdummy(fastf_t w[3], fastf_t t[3], int flag)
+{
+    fastf_t temp;
+    vect_t vec;
+    int i, j;
+
+    vec[1] = 0.0;
+    if (plano[1] <= plant[1]) {
+       for (i = 0; i < 2; i++) {
+           temp = plano[i];
+           plano[i] = plant[i];
+           plant[i] = temp;
+       }
+    }
+
+    vec[0] = w[2] + t[2] + 1.0;
+    vec[2] = ((plano[1] - w[1]) * vec[0]) / (plano[0] - w[0]);
+    if (flag > 1)
+       vec[0] *= -1.0;
+    if (vec[2] >= 0.0)
+       vec[2] *= -1.0;
+    sol.s_values[0] = w[0];
+    sol.s_values[1] = t[0] -1.0;
+    sol.s_values[2] = w[1];
+    VMOVE(&sol.s_values[3], vec);
+    vec[2] = w[2] + t[2] + 1.0;
+    VMOVE(&sol.s_values[6], vec);
+    vec[0] = 0.0;
+    VMOVE(&sol.s_values[9], vec);
+    vec[2] = 0.0;
+    vec[1] = t[1] - t[0] + 2.0;
+    VMOVE(&sol.s_values[12], vec);
+    for (i = 3; i <=9; i += 3) {
+       j = i + 12;
+       VADD2(&sol.s_values[j], &sol.s_values[i], vec);
+    }
+
+    return;
+
+}
+
+
+static void
+trcurve(fastf_t wh[], fastf_t t[])
+{
+    sol.s_values[0] = wh[0];
+    sol.s_values[1] = t[0];
+    sol.s_values[2] = wh[1];
+    sol.s_values[4] = t[1] - t[0];
+    sol.s_values[6] = wh[2] + t[2];
+    sol.s_values[11] = wh[2] + t[2];
+    VMOVE(&sol.s_values[12], &sol.s_values[6]);
+    VMOVE(&sol.s_values[15], &sol.s_values[9]);
+}
+
+
+static void
+bottom(vect_t vec1, vect_t vec2, fastf_t t[])
+{
+    vect_t tvec;
+    int i, j;
+
+    VMOVE(&sol.s_values[0], vec1);
+    tvec[0] = vec2[0] - vec1[0];
+    tvec[1] = tvec[2] = 0.0;
+    VMOVE(&sol.s_values[3], tvec);
+    tvec[0] = tvec[1] = 0.0;
+    tvec[2] = t[2];
+    VADD2(&sol.s_values[6], &sol.s_values[3], tvec);
+    VMOVE(&sol.s_values[9], tvec);
+    tvec[0] = tvec[2] = 0.0;
+    tvec[1] = t[1] - t[0];
+    VMOVE(&sol.s_values[12], tvec);
+
+    for (i = 3; i <=9; i += 3) {
+       j = i + 12;
+       VADD2(&sol.s_values[j], &sol.s_values[i], tvec);
+    }
+}
+
+
+static void
+top(vect_t vec1, vect_t vec2, fastf_t t[])
+{
+    fastf_t tooch, mag;
+    vect_t del, tvec;
+    int i, j;
+
+    tooch = t[2] * .25;
+    del[0] = vec2[0] - vec1[0];
+    del[1] = 0.0;
+    del[2] = vec2[2] - vec1[2];
+    mag = MAGNITUDE(del);
+    VSCALE(tvec, del, tooch/mag);
+    VSUB2(&sol.s_values[0], vec1, tvec);
+    VADD2(del, del, tvec);
+    VADD2(&sol.s_values[3], del, tvec);
+    tvec[0] = tvec[2] = 0.0;
+    tvec[1] = t[1] - t[0];
+    VCROSS(del, tvec, &sol.s_values[3]);
+    mag = MAGNITUDE(del);
+    if (del[2] < 0)
+       mag *= -1.0;
+    VSCALE(&sol.s_values[9], del, t[2]/mag);
+    VADD2(&sol.s_values[6], &sol.s_values[3], &sol.s_values[9]);
+    VMOVE(&sol.s_values[12], tvec);
+
+    for (i = 3; i <= 9; i += 3) {
+       j = i + 12;
+       VADD2(&sol.s_values[j], &sol.s_values[i], tvec);
+    }
+}
+
+
+/*
+ * The following functions were pulled in from libwdb
+ * to prevent creating a new dependency.
+ */
+
+/*
+ *
+ * Adds track given "wheel" info. This only needs a logging VLS and a
+ * database, so it can be used as a replacement for wdb_track_cmd when
+ * no struct ged is available.
+ *
+ */
+int
+ged_track2(struct bu_vls *log_str, struct rt_wdb *wdbp, const char *argv[])
+{
+    fastf_t fw[3], lw[3], iw[3], dw[3], tr[3];
+    char *solname = NULL;
+    char *regname = NULL;
+    char *grpname = NULL;
+    char oper[3];
+    int i, memb[4];
+    vect_t temp1, temp2;
+    int item, mat, los;
+    int arg;
+    int edit_result = GED_OK;
+    struct bu_list head;
+    int len;
+
+    BU_LIST_INIT(&head);
+
+    oper[0] = oper[2] = WMOP_INTERSECT;
+    oper[1] = WMOP_SUBTRACT;
+
+    /* base name */
+    arg = 1;
+    grpname = bu_strdup(argv[arg]);
+    grpname_len = (int)strlen(grpname);
+    len = grpname_len + 1 + extraChars;
+    solname = (char *)bu_malloc(len, "solid name");
+    regname = (char *)bu_malloc(len, "region name");
+    sol.s_name = (char *)bu_malloc(len, "sol.s_name");
+
+    /* first road wheel X */
+    ++arg;
+    fw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    /* last road wheel X */
+    ++arg;
+    lw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (fw[0] <= lw[0]) {
+       bu_vls_printf(log_str, "First wheel after last wheel - STOP\n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    /* road wheel Z */
+    ++arg;
+    fw[1] = lw[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    /* roadwheel radius */
+    ++arg;
+    fw[2] = lw[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (fw[2] <= 0) {
+       bu_vls_printf(log_str, "Radius <= 0 - STOP\n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    /* drive sprocket X */
+    ++arg;
+    dw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (dw[0] >= lw[0]) {
+       bu_vls_printf(log_str, "DRIVE wheel not in the rear - STOP \n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    /* drive sprocket Z */
+    ++arg;
+    dw[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    /* drive sprocket radius */
+    ++arg;
+    dw[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (dw[2] <= 0) {
+       bu_vls_printf(log_str, "Radius <= 0 - STOP\n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    /* idler wheel X */
+    ++arg;
+    iw[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (iw[0] <= fw[0]) {
+       bu_vls_printf(log_str, "IDLER wheel not in the front - STOP \n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    /* idler wheel Z */
+    ++arg;
+    iw[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    /* idler wheel radius */
+    ++arg;
+    iw[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (iw[2] <= 0) {
+       bu_vls_printf(log_str, "Radius <= 0 - STOP\n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    /* track MIN Y */
+    ++arg;
+    tr[2] = tr[0] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    /* track MAX Y */
+    ++arg;
+    tr[1] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (EQUAL(tr[0], tr[1])) {
+       bu_vls_printf(log_str, "MIN == MAX ... STOP\n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+    if (tr[0] > tr[1]) {
+       bu_vls_printf(log_str, "MIN > MAX .... will switch\n");
+       tr[1] = tr[0];
+       tr[0] = tr[2];
+    }
+
+    /* track thickness */
+    ++arg;
+    tr[2] = atof(argv[arg]) * wdbp->dbip->dbi_local2base;
+
+    if (tr[2] <= 0) {
+       bu_vls_printf(log_str, "Track thickness <= 0 - STOP\n");
+       edit_result = GED_ERROR;
+       goto end;
+    }
+
+    for (i = 0; i < grpname_len; ++i) {
+       solname[i] = grpname[i];
+       regname[i] = grpname[i];
+    }
+
+    solname[i] = regname[i] = '.';
+    ++i;
+    solname[i] = 's';
+    regname[i] = 'r';
+    ++i;
+    solname[i] = regname[i] = '.';
+    ++i;
+    solname[i] = regname[i] = '\0';
+/*
+  bu_log("\nX of first road wheel  %10.4f\n", fw[0]);
+  bu_log("X of last road wheel   %10.4f\n", lw[0]);
+  bu_log("Z of road wheels       %10.4f\n", fw[1]);
+  bu_log("radius of road wheels  %10.4f\n", fw[2]);
+  bu_log("\nX of drive wheel       %10.4f\n", dw[0]);
+  bu_log("Z of drive wheel       %10.4f\n", dw[1]);
+  bu_log("radius of drive wheel  %10.4f\n", dw[2]);
+  bu_log("\nX of idler wheel       %10.4f\n", iw[0]);
+  bu_log("Z of idler wheel       %10.4f\n", iw[1]);
+  bu_log("radius of idler wheel  %10.4f\n", iw[2]);
+  bu_log("\nY MIN of track         %10.4f\n", tr[0]);
+  bu_log("Y MAX of track         %10.4f\n", tr[1]);
+  bu_log("thickness of track     %10.4f\n", tr[2]);
+*/
+
+/* Check for names to use:
+ * grpname.s.0->9 and grpname.r.0->9
+ */
+
+    for (i = 0; i < 10; i++) {
+       crname(log_str, solname, i, len);
+       crname(log_str, regname, i, len);
+       if ((db_lookup(wdbp->dbip, solname, LOOKUP_QUIET) != RT_DIR_NULL) ||
+           (db_lookup(wdbp->dbip, regname, LOOKUP_QUIET) != RT_DIR_NULL)) {
+           /* name already exists */
+           bu_vls_printf(log_str, "Track: naming error -- STOP\n");
+           edit_result = GED_ERROR;
+           goto end;
+       }
+
+       solname[grpname_len + extraTypeChars] = '\0';
+       regname[grpname_len + extraTypeChars] = '\0';
+    }
+
+    /* find the front track slope to the idler */
+    for (i = 0; i < 24; i++)
+       sol.s_values[i] = 0.0;
+
+    /* add the solids */
+    /* solid 0 */
+    slope(log_str, fw, iw, tr);
+    VMOVE(temp2, &sol.s_values[0]);
+    crname(log_str, solname, 0, len);
+    bu_strlcpy(sol.s_name, solname, len);
+
+    sol.s_type = ID_ARB8;
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 1 */
+    /* find track around idler */
+    for (i = 0; i < 24; i++)
+       sol.s_values[i] = 0.0;
+    sol.s_type = ID_TGC;
+    trcurve(iw, tr);
+    crname(log_str, solname, 1, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+    /* idler dummy rcc */
+    sol.s_values[6] = iw[2];
+    sol.s_values[11] = iw[2];
+    VMOVE(&sol.s_values[12], &sol.s_values[6]);
+    VMOVE(&sol.s_values[15], &sol.s_values[9]);
+    /* solid 2 */
+    crname(log_str, solname, 2, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 3 */
+    /* find idler track dummy arb8 */
+    for (i = 0; i < 24; i++)
+       sol.s_values[i] = 0.0;
+    crname(log_str, solname, 3, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    sol.s_type = ID_ARB8;
+    crdummy(iw, tr, 1);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 4 */
+    /* track slope to drive */
+    for (i = 0; i < 24; i++)
+       sol.s_values[i] = 0.0;
+    slope(log_str, lw, dw, tr);
+    VMOVE(temp1, &sol.s_values[0]);
+    crname(log_str, solname, 4, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 5 */
+    /* track around drive */
+    for (i = 0; i < 24; i++)
+       sol.s_values[i] = 0.0;
+    sol.s_type = ID_TGC;
+    trcurve(dw, tr);
+    crname(log_str, solname, 5, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 6 */
+    /* drive dummy rcc */
+    sol.s_values[6] = dw[2];
+    sol.s_values[11] = dw[2];
+    VMOVE(&sol.s_values[12], &sol.s_values[6]);
+    VMOVE(&sol.s_values[15], &sol.s_values[9]);
+    crname(log_str, solname, 6, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 7 */
+    /* drive dummy arb8 */
+    for (i = 0; i < 24; i++)
+       sol.s_values[i] = 0.0;
+    crname(log_str, solname, 7, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    sol.s_type = ID_ARB8;
+    crdummy(dw, tr, 2);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 8 */
+    /* track bottom */
+    temp1[1] = temp2[1] = tr[0];
+    bottom(temp1, temp2, tr);
+    crname(log_str, solname, 8, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* solid 9 */
+    /* track top */
+    temp1[0] = dw[0];
+    temp1[1] = temp2[1] = tr[0];
+    temp1[2] = dw[1] + dw[2];
+    temp2[0] = iw[0];
+    temp2[2] = iw[1] + iw[2];
+    top(temp1, temp2, tr);
+    crname(log_str, solname, 9, len);
+    bu_strlcpy(sol.s_name, solname, len);
+    if (wrobj(log_str, wdbp, solname, RT_DIR_SOLID))
+       return GED_ERROR;
+    solname[grpname_len + extraTypeChars] = '\0';
+
+    /* add the regions */
+    /* region 0 */
+    item = item_default;
+    mat = mat_default;
+    los = los_default;
+    item_default = 500;
+    mat_default = 1;
+    los_default = 50;
+    /* region 1 */
+    memb[0] = 0;
+    memb[1] = 3;
+    crname(log_str, regname, 0, len);
+    crregion(log_str, wdbp, regname, oper, memb, 2, solname, len);
+    solname[grpname_len + extraTypeChars] = '\0';
+    regname[grpname_len + extraTypeChars] = '\0';
+
+    /* region 1 */
+    crname(log_str, regname, 1, len);
+    memb[0] = 1;
+    memb[1] = 2;
+    memb[2] = 3;
+    crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
+    solname[grpname_len + extraTypeChars] = '\0';
+    regname[grpname_len + extraTypeChars] = '\0';
+
+    /* region 4 */
+    crname(log_str, regname, 4, len);
+    memb[0] = 4;
+    memb[1] = 7;
+    crregion(log_str, wdbp, regname, oper, memb, 2, solname, len);
+    solname[grpname_len + extraTypeChars] = '\0';
+    regname[grpname_len + extraTypeChars] = '\0';
+
+    /* region 5 */
+    crname(log_str, regname, 5, len);
+    memb[0] = 5;
+    memb[1] = 6;
+    memb[2] = 7;
+    crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
+    solname[grpname_len + extraTypeChars] = '\0';
+    regname[grpname_len + extraTypeChars] = '\0';
+
+    /* region 8 */
+    crname(log_str, regname, 8, len);
+    memb[0] = 8;
+    memb[1] = 0;
+    memb[2] = 4;
+    oper[2] = WMOP_SUBTRACT;
+    crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
+    solname[grpname_len + extraTypeChars] = '\0';
+    regname[grpname_len + extraTypeChars] = '\0';
+
+    /* region 9 */
+    crname(log_str, regname, 9, len);
+    memb[0] = 9;
+    memb[1] = 3;
+    memb[2] = 7;
+    crregion(log_str, wdbp, regname, oper, memb, 3, solname, len);
+    solname[grpname_len + extraTypeChars] = '\0';
+    regname[grpname_len + extraTypeChars] = '\0';
+
+    /* group all the track regions */
+    for (i = 0; i < 10; i++) {
+       if (i == 2 || i == 3 || i == 6 || i == 7)
+           continue;
+       regname[grpname_len + extraTypeChars] = '\0';
+       crname(log_str, regname, i, len);
+       if (db_lookup(wdbp->dbip, regname, LOOKUP_QUIET) == RT_DIR_NULL) {
+           bu_vls_printf(log_str, "group: %s will skip member: %s\n", grpname, 
regname);
+           continue;
+       }
+       track_mk_addmember(regname, &head, NULL, WMOP_UNION);
+    }
+
+    /* Add them all at once */
+    if (track_mk_comb(wdbp, grpname, &head,
+                     0, NULL, NULL, NULL,
+                     0, 0, 0, 0,
+                     0, 1, 1) < 0) {

@@ 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to