Revision: 76395
          http://sourceforge.net/p/brlcad/code/76395
Author:   starseeker
Date:     2020-07-21 18:53:10 +0000 (Tue, 21 Jul 2020)
Log Message:
-----------
Consolidate the nmg related commands into a single plugin

Modified Paths:
--------------
    brlcad/branches/gedplugins/src/libged/CMakeLists.txt
    brlcad/branches/gedplugins/src/libged/nmg/CMakeLists.txt
    brlcad/branches/gedplugins/src/libged/nmg/nmg.c

Added Paths:
-----------
    brlcad/branches/gedplugins/src/libged/nmg/nmg_cmface.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_collapse.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_fix_normals.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_f.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_v.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_make_v.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_mm.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_move_v.c
    brlcad/branches/gedplugins/src/libged/nmg/nmg_simplify.c

Removed Paths:
-------------
    brlcad/branches/gedplugins/src/libged/nmg_cmface/
    brlcad/branches/gedplugins/src/libged/nmg_collapse/
    brlcad/branches/gedplugins/src/libged/nmg_fix_normals/
    brlcad/branches/gedplugins/src/libged/nmg_kill_f/
    brlcad/branches/gedplugins/src/libged/nmg_kill_v/
    brlcad/branches/gedplugins/src/libged/nmg_make_v/
    brlcad/branches/gedplugins/src/libged/nmg_mm/
    brlcad/branches/gedplugins/src/libged/nmg_move_v/
    brlcad/branches/gedplugins/src/libged/nmg_simplify/

Modified: brlcad/branches/gedplugins/src/libged/CMakeLists.txt
===================================================================
--- brlcad/branches/gedplugins/src/libged/CMakeLists.txt        2020-07-21 
18:31:24 UTC (rev 76394)
+++ brlcad/branches/gedplugins/src/libged/CMakeLists.txt        2020-07-21 
18:53:10 UTC (rev 76395)
@@ -234,15 +234,15 @@
   mrot/mrot.c
   nirt/nirt.c
   nmg/nmg.c
-  nmg_cmface/nmg_cmface.c
-  nmg_collapse/nmg_collapse.c
-  nmg_fix_normals/nmg_fix_normals.c
-  nmg_kill_f/nmg_kill_f.c
-  nmg_kill_v/nmg_kill_v.c
-  nmg_make_v/nmg_make_v.c
-  nmg_mm/nmg_mm.c
-  nmg_move_v/nmg_move_v.c
-  nmg_simplify/nmg_simplify.c
+  nmg/nmg_cmface.c
+  nmg/nmg_collapse.c
+  nmg/nmg_fix_normals.c
+  nmg/nmg_kill_f.c
+  nmg/nmg_kill_v.c
+  nmg/nmg_make_v.c
+  nmg/nmg_mm.c
+  nmg/nmg_move_v.c
+  nmg/nmg_simplify.c
   ocenter/ocenter.c
   open/open.c
   orient/orient.c
@@ -588,15 +588,6 @@
 add_subdirectory(mrot)
 add_subdirectory(nirt)
 add_subdirectory(nmg)
-add_subdirectory(nmg_cmface)
-add_subdirectory(nmg_collapse)
-add_subdirectory(nmg_fix_normals)
-add_subdirectory(nmg_kill_f)
-add_subdirectory(nmg_kill_v)
-add_subdirectory(nmg_make_v)
-add_subdirectory(nmg_mm)
-add_subdirectory(nmg_move_v)
-add_subdirectory(nmg_simplify)
 add_subdirectory(ocenter)
 add_subdirectory(open)
 add_subdirectory(orient)

Modified: brlcad/branches/gedplugins/src/libged/nmg/CMakeLists.txt
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/CMakeLists.txt    2020-07-21 
18:31:24 UTC (rev 76394)
+++ brlcad/branches/gedplugins/src/libged/nmg/CMakeLists.txt    2020-07-21 
18:53:10 UTC (rev 76395)
@@ -6,11 +6,24 @@
   ${GED_INCLUDE_DIRS}
   )
 
+set(NMG_SRCS
+       nmg.c
+       nmg_cmface.c
+       nmg_collapse.c
+       nmg_fix_normals.c
+       nmg_kill_f.c
+       nmg_kill_v.c
+       nmg_make_v.c
+       nmg_mm.c
+       nmg_move_v.c
+       nmg_simplify.c
+       )
+
 add_definitions(-DGED_PLUGIN)
-add_library(ged-nmg SHARED nmg.c)
+add_library(ged-nmg SHARED ${NMG_SRCS})
 target_link_libraries(ged-nmg libged libbu)
 set_property(TARGET ged-nmg APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD 
HAVE_CONFIG_H)
-VALIDATE_STYLE(ged-nmg nmg.c)
+VALIDATE_STYLE(ged-nmg ${NMG_SRCS})
 PLUGIN_SETUP(ged-nmg ged)
 
 # Local Variables:
@@ -19,3 +32,4 @@
 # indent-tabs-mode: t
 # End:
 # ex: shiftwidth=2 tabstop=8
+

Modified: brlcad/branches/gedplugins/src/libged/nmg/nmg.c
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg.c     2020-07-21 18:31:24 UTC 
(rev 76394)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg.c     2020-07-21 18:53:10 UTC 
(rev 76395)
@@ -126,17 +126,52 @@
 
 #ifdef GED_PLUGIN
 #include "../include/plugin.h"
-struct ged_cmd_impl nmg_cmd_impl = {
-    "nmg",
-    ged_nmg,
-    GED_CMD_DEFAULT
+struct ged_cmd_impl nmg_cmd_impl = {"nmg", ged_nmg, GED_CMD_DEFAULT};
+const struct ged_cmd nmg_cmd = { &nmg_cmd_impl };
+
+struct ged_cmd_impl nmg_cmface_cmd_impl = {"nmg_cmface", ged_nmg_cmface, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_cmface_cmd = { &nmg_cmface_cmd_impl };
+
+struct ged_cmd_impl nmg_collapse_cmd_impl = {"nmg_collapse", ged_nmg_collapse, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_collapse_cmd = { &nmg_collapse_cmd_impl };
+
+struct ged_cmd_impl nmg_fix_normals_cmd_impl = {"nmg_fix_normals", 
ged_nmg_fix_normals, GED_CMD_DEFAULT};
+const struct ged_cmd nmg_fix_normals_cmd = { &nmg_fix_normals_cmd_impl };
+
+struct ged_cmd_impl nmg_kill_f_cmd_impl = {"nmg_kill_f", ged_nmg_kill_f, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_kill_f_cmd = { &nmg_kill_f_cmd_impl };
+
+struct ged_cmd_impl nmg_kill_v_cmd_impl = {"nmg_kill_v", ged_nmg_kill_v, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_kill_v_cmd = { &nmg_kill_v_cmd_impl };
+
+struct ged_cmd_impl nmg_make_v_cmd_impl = {"nmg_make_v", ged_nmg_make_v, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_make_v_cmd = { &nmg_make_v_cmd_impl };
+
+struct ged_cmd_impl nmg_mm_cmd_impl = {"nmg_mm", ged_nmg_mm, GED_CMD_DEFAULT};
+const struct ged_cmd nmg_mm_cmd = { &nmg_mm_cmd_impl };
+
+struct ged_cmd_impl nmg_move_v_cmd_impl = {"nmg_move_v", ged_nmg_move_v, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_move_v_cmd = { &nmg_move_v_cmd_impl };
+
+struct ged_cmd_impl nmg_simplify_cmd_impl = {"nmg_simplify", ged_nmg_simplify, 
GED_CMD_DEFAULT};
+const struct ged_cmd nmg_simplify_cmd = { &nmg_simplify_cmd_impl };
+
+const struct ged_cmd *nmg_cmds[] = {
+    &nmg_cmd,
+    &nmg_cmface_cmd,
+    &nmg_collapse_cmd,
+    &nmg_fix_normals_cmd,
+    &nmg_kill_f_cmd,
+    &nmg_kill_v_cmd,
+    &nmg_make_v_cmd,
+    &nmg_mm_cmd,
+    &nmg_move_v_cmd,
+    &nmg_simplify_cmd,
+    NULL
 };
 
-const struct ged_cmd nmg_cmd = { &nmg_cmd_impl };
-const struct ged_cmd *nmg_cmds[] = { &nmg_cmd, NULL };
+static const struct ged_plugin pinfo = { nmg_cmds, 10 };
 
-static const struct ged_plugin pinfo = { nmg_cmds, 1 };
-
 COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info()
 {
     return &pinfo;

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_cmface.c (from rev 76394, 
brlcad/branches/gedplugins/src/libged/nmg_cmface/nmg_cmface.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_cmface.c                      
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_cmface.c      2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,162 @@
+/*                         N M G _ C M F A C E . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2015-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/nmg_cmface.c
+ *
+ * The cmface command.
+ *
+ */
+
+#include "common.h"
+#include "nmg.h"
+
+#include <signal.h>
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+struct tmp_v {
+    point_t pt;
+    struct vertex *v;
+};
+
+GED_EXPORT int
+ged_nmg_cmface(struct ged *gedp, int argc, const char *argv[])
+{
+    struct rt_db_internal internal;
+    struct directory *dp;
+    struct model* m;
+    const char* name;
+    struct nmgregion* r;
+    struct shell* s;
+    struct tmp_v* verts;
+    struct faceuse *fu;
+    struct bn_tol tol;
+    struct vertex ***face_verts;
+    int idx, num_verts;
+
+    static const char *usage = "nmg_name cmface x0 y0 z0 ... xn yn zn";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    num_verts = (argc - 2) / 3;
+
+    /* check for less than three vertices or incomplete vertex coordinates */
+    if (argc < ELEMENTS_PER_POINT * 3 + 2 || (argc - 2) % 3 != 0) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    /* attempt to resolve and verify */
+    name = argv[0];
+
+    if ( (dp=db_lookup(gedp->ged_wdbp->dbip, name, LOOKUP_QUIET))
+         == RT_DIR_NULL ) {
+       bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", name);
+       return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip,
+       bn_mat_identity, &rt_uniresource) < 0) {
+       bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+       return GED_ERROR;
+    }
+
+    if (internal.idb_type != ID_NMG) {
+       bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", name);
+       rt_db_free_internal(&internal);
+       return GED_ERROR;
+    }
+
+    m = (struct model *)internal.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    if (BU_LIST_IS_EMPTY(&m->r_hd)) {
+        r = nmg_mrsv(m);
+        s = BU_LIST_FIRST(shell, &r->s_hd);
+    } else {
+        r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+        s = BU_LIST_FIRST(shell, &r->s_hd);
+    }
+
+    NMG_CK_REGION(r);
+    NMG_CK_SHELL(s);
+
+    verts = (struct tmp_v *)NULL;
+    verts = (struct tmp_v *)bu_calloc(num_verts,
+            sizeof(struct tmp_v), "verts");
+    face_verts = (struct vertex ***) bu_calloc( num_verts,
+               sizeof(struct vertex **), "face_verts");
+
+    for (idx=0; idx < num_verts; idx++){
+        verts[idx].pt[0] = (fastf_t)atof(argv[idx*3+2]);
+        verts[idx].pt[1] = (fastf_t)atof(argv[idx*3+3]);
+        verts[idx].pt[2] = (fastf_t)atof(argv[idx*3+4]);
+        face_verts[idx] = &verts[idx].v;
+    }
+
+    fu = nmg_cmface( s, face_verts, num_verts );
+    bu_free((char *) face_verts, "face_verts");
+
+    /* assign geometry for entire vertex list (if we have one) */
+    for (idx=0; idx < num_verts; idx++) {
+        if (verts[idx].v) nmg_vertex_gv(verts[idx].v, verts[idx].pt);
+    }
+
+    /* assign face geometry */
+    if (s) {
+        for (BU_LIST_FOR (fu, faceuse, &s->fu_hd)) {
+            if (fu->orientation != OT_SAME) continue;
+            nmg_calc_face_g(fu, &RTG.rtg_vlfree);
+        }
+    }
+
+    tol.magic = BN_TOL_MAGIC;
+    tol.dist = 0.0005;
+    tol.dist_sq = tol.dist * tol.dist;
+    tol.perp = 1e-6;
+    tol.para = 1 - tol.perp;
+
+    nmg_rebound(m, &tol);
+
+    if ( wdb_put_internal(gedp->ged_wdbp, name, &internal, 1.0) < 0 ) {
+        bu_vls_printf(gedp->ged_result_str, "wdb_put_internal(%s)", argv[1]);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    rt_db_free_internal(&internal);
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_collapse.c (from rev 
76394, brlcad/branches/gedplugins/src/libged/nmg_collapse/nmg_collapse.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_collapse.c                    
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_collapse.c    2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,163 @@
+/*                         N M G _ C O L L A P S 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/nmg_collapse.c
+ *
+ * The nmg_collapse command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "bu/cmd.h"
+
+#include "../ged_private.h"
+
+
+GED_EXPORT int
+ged_nmg_collapse(struct ged *gedp, int argc, const char *argv[])
+{
+    char *new_name;
+    struct model *m;
+    struct rt_db_internal intern;
+    struct directory *dp;
+    struct bu_ptbl faces;
+    struct face *fp;
+    size_t count;
+    fastf_t tol_coll;
+    fastf_t min_angle;
+    static const char *usage = "nmg_prim new_prim max_err_dist [min_angle]";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc == 1) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    if (argc < 4) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_ERROR;
+    }
+
+    if (strchr(argv[2], '/')) {
+       bu_vls_printf(gedp->ged_result_str, "Do not use '/' in solid names: 
%s\n", argv[2]);
+       return GED_ERROR;
+    }
+
+    new_name = (char *)argv[2];
+
+    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != 
RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s already exists\n", new_name);
+       return GED_ERROR;
+    }
+
+    if ((dp=db_lookup(gedp->ged_wdbp->dbip, argv[1], LOOKUP_NOISY)) == 
RT_DIR_NULL)
+       return GED_ERROR;
+
+    if (dp->d_flags & RT_DIR_COMB) {
+       bu_vls_printf(gedp->ged_result_str, "%s is a combination, only NMG 
primitives are allowed here\n", argv[1]);
+       return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&intern, dp, gedp->ged_wdbp->dbip, (matp_t)NULL, 
&rt_uniresource) < 0) {
+       bu_vls_printf(gedp->ged_result_str, "Failed to get internal form of 
%s!!!!\n", argv[1]);
+       return GED_ERROR;
+    }
+
+    if (intern.idb_type != ID_NMG) {
+       bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid!!!!\n", 
argv[1]);
+       rt_db_free_internal(&intern);
+       return GED_ERROR;
+    }
+
+    tol_coll = atof(argv[3]) * gedp->ged_wdbp->dbip->dbi_local2base;
+    if (tol_coll <= 0.0) {
+       bu_vls_printf(gedp->ged_result_str, "tolerance distance too small\n");
+       return GED_ERROR;
+    }
+
+    if (argc == 5) {
+       min_angle = atof(argv[4]);
+       if (min_angle < 0.0) {
+           bu_vls_printf(gedp->ged_result_str, "Minimum angle cannot be less 
than zero\n");
+           return GED_ERROR;
+       }
+    } else
+       min_angle = 0.0;
+
+    m = (struct model *)intern.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    /* check that all faces are planar */
+    nmg_face_tabulate(&faces, &m->magic, &RTG.rtg_vlfree);
+    for (BU_PTBL_FOR(fp, (struct face *), &faces)) {
+       if (fp->g.magic_p != NULL && *(fp->g.magic_p) != 
NMG_FACE_G_PLANE_MAGIC) {
+           bu_log("\tnot planar\n");
+           bu_ptbl_free(&faces);
+           bu_vls_printf(gedp->ged_result_str,
+                         "nmg_collapse can only be applied to NMG primitives 
with planar faces\n");
+           return GED_ERROR;
+       }
+    }
+    bu_ptbl_free(&faces);
+
+    /* triangulate model */
+    nmg_triangulate_model(m, &RTG.rtg_vlfree, &gedp->ged_wdbp->wdb_tol);
+
+    count = (size_t)nmg_edge_collapse(m, &gedp->ged_wdbp->wdb_tol, tol_coll, 
min_angle, &RTG.rtg_vlfree);
+
+    dp=db_diradd(gedp->ged_wdbp->dbip, new_name, RT_DIR_PHONY_ADDR, 0, 
RT_DIR_SOLID, (void *)&intern.idb_type);
+    if (dp == RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "Cannot add %s to directory\n", 
new_name);
+       rt_db_free_internal(&intern);
+       return GED_ERROR;
+    }
+
+    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &intern, &rt_uniresource) 
< 0) {
+       rt_db_free_internal(&intern);
+       bu_vls_printf(gedp->ged_result_str, "Database write error, 
aborting.\n");
+       return GED_ERROR;
+    }
+
+    rt_db_free_internal(&intern);
+
+    bu_vls_printf(gedp->ged_result_str, "%zu edges collapsed\n", count);
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_fix_normals.c (from rev 
76394, brlcad/branches/gedplugins/src/libged/nmg_fix_normals/nmg_fix_normals.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_fix_normals.c                 
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_fix_normals.c 2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,105 @@
+/*                  N M G _ F I X _ N O R M A L S . C
+ * BRL-CAD
+ *
+ * Copyright (c) 2009-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/nmg_fix_normals.c
+ *
+ * The nmg_fix_normals command.
+ *
+ */
+
+#include "common.h"
+
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+GED_EXPORT int
+ged_nmg_fix_normals(struct ged *gedp, int argc, const char *argv[])
+{
+    struct directory *dp;
+    struct rt_db_internal nmg_intern;
+    struct model *m;
+    struct nmgregion *r;
+    struct shell *s;
+    const char *nmg_name;
+    struct bn_tol tol;
+
+    static const char *usage = "nmg_prim";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* in theory, we should probably allow the user to override this. */
+    tol.magic = BN_TOL_MAGIC;
+    tol.dist = 0.01;
+    tol.dist_sq = tol.dist * tol.dist;
+    tol.perp = 0.001;
+    tol.para = 0.999;
+
+    if (argc != 2) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    /* attempt to resolve and verify before we jump in */
+    nmg_name = argv[1];
+
+    if ((dp=db_lookup(gedp->ged_wdbp->dbip, nmg_name, LOOKUP_QUIET)) == 
RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", nmg_name);
+       return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&nmg_intern, dp, gedp->ged_wdbp->dbip, 
bn_mat_identity, &rt_uniresource) < 0) {
+       bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+       return GED_ERROR;
+    }
+
+    if (nmg_intern.idb_type != ID_NMG) {
+       bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", 
nmg_name);
+       rt_db_free_internal(&nmg_intern);
+       return GED_ERROR;
+    }
+
+    m = (struct model *)nmg_intern.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    /* hum, here we go */
+    for (BU_LIST_FOR(r, nmgregion, &m->r_hd))
+       for (BU_LIST_FOR(s, shell, &r->s_hd))
+           nmg_fix_normals(s, &RTG.rtg_vlfree, &tol);
+
+    return GED_OK;
+}
+
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_f.c (from rev 76394, 
brlcad/branches/gedplugins/src/libged/nmg_kill_f/nmg_kill_f.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_f.c                      
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_f.c      2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,148 @@
+/*                         N M G _ K I L L _ F. C
+ * BRL-CAD
+ *
+ * Copyright (c) 2015-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/nmg_kill_f.c
+ *
+ * The kill F subcommand for nmg top-level command.
+ *
+ */
+
+#include "common.h"
+
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+void remove_face(const struct model* m, long int fid)
+{
+    struct nmgregion *r;
+    struct shell *s;
+    struct faceuse *fu;
+    struct face *f;
+
+    NMG_CK_MODEL(m);
+
+    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
+       NMG_CK_REGION(r);
+
+       if (r->ra_p) {
+           NMG_CK_REGION_A(r->ra_p);
+       }
+
+       for (BU_LIST_FOR(s, shell, &r->s_hd)) {
+           NMG_CK_SHELL(s);
+
+           if (s->sa_p) {
+               NMG_CK_SHELL_A(s->sa_p);
+           }
+
+           /* Faces in shell */
+           for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
+               NMG_CK_FACEUSE(fu);
+               f = fu->f_p;
+               NMG_CK_FACE(f);
+
+               if ( fid == f->index ) {
+                   /* this kills both facesuses using the face,
+                    * and the face itself.
+                    */
+                   nmg_kfu(fu);
+               }
+           }
+       }
+    }
+}
+
+GED_EXPORT int
+ged_nmg_kill_f(struct ged* gedp, int argc, const char* argv[])
+{
+    struct rt_db_internal internal;
+    struct directory *dp;
+    struct model* m;
+    const char* name;
+    long int fid;
+
+    static const char *usage = "kill F id";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_DRAWABLE(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc < 4) {
+        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+        return GED_HELP;
+    }
+
+    /* attempt to resolve and verify */
+    name = argv[0];
+
+    if ( (dp=db_lookup(gedp->ged_wdbp->dbip, name, LOOKUP_QUIET))
+        == RT_DIR_NULL ) {
+        bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", name);
+        return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip,
+        bn_mat_identity, &rt_uniresource) < 0) {
+        bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+        return GED_ERROR;
+    }
+
+    if (internal.idb_type != ID_NMG) {
+        bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", name);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    /* get face index from command line */
+    fid = (long int)atoi(argv[3]);
+
+    m = (struct model *)internal.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    remove_face(m, fid);
+
+    if ( wdb_put_internal(gedp->ged_wdbp, name, &internal, 1.0) < 0 ) {
+        bu_vls_printf(gedp->ged_result_str, "wdb_put_internal(%s)", argv[1]);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    rt_db_free_internal(&internal);
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_v.c (from rev 76394, 
brlcad/branches/gedplugins/src/libged/nmg_kill_v/nmg_kill_v.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_v.c                      
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_kill_v.c      2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,329 @@
+/*                         N M G _ K I L L _ V. C
+ * BRL-CAD
+ *
+ * Copyright (c) 2015-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/nmg_kill_v.c
+ *
+ * The kill V subcommand for nmg top-level command.
+ *
+ */
+
+#include "common.h"
+
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+void remove_vertex(const struct model* m, point_t rv)
+{
+    struct nmgregion *r;
+    struct shell *s;
+    struct faceuse *fu;
+    struct face *f;
+    struct loopuse *lu;
+    struct loop *l;
+    struct edgeuse *eu;
+    struct edge *e;
+    struct vertexuse *vu;
+    struct vertex *v;
+
+    NMG_CK_MODEL(m);
+
+    /* Traverse NMG model and remove instances of vertexuses.
+     * In addition to vertex being removed, associated faceuses, loopuses
+     * and edgeuses need to be removed that contained the deleted vertexuse.
+     */
+
+    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
+        NMG_CK_REGION(r);
+
+        if (r->ra_p) {
+            NMG_CK_REGION_A(r->ra_p);
+        }
+
+        for (BU_LIST_FOR(s, shell, &r->s_hd)) {
+            NMG_CK_SHELL(s);
+
+            if (s->sa_p) {
+                NMG_CK_SHELL_A(s->sa_p);
+            }
+
+            /* Faces in shell */
+            for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
+                NMG_CK_FACEUSE(fu);
+                f = fu->f_p;
+                NMG_CK_FACE(f);
+
+                if (f->g.magic_p) switch (*f->g.magic_p) {
+                    case NMG_FACE_G_PLANE_MAGIC:
+                        break;
+                    case NMG_FACE_G_SNURB_MAGIC:
+                        break;
+                }
+
+                /* Loops in face */
+                for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
+                    NMG_CK_LOOPUSE(lu);
+                    l = lu->l_p;
+                    NMG_CK_LOOP(l);
+
+                    if (l->lg_p) {
+                        NMG_CK_LOOP_G(l->lg_p);
+                    }
+
+                    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == 
NMG_VERTEXUSE_MAGIC) {
+                        /* Loop of Lone vertex */
+                        vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
+
+                        /* check and remove vertexuse */
+                        NMG_CK_VERTEXUSE(vu);
+                        v = vu->v_p;
+                        NMG_CK_VERTEX(v);
+
+                        if (v->vg_p) {
+                            NMG_CK_VERTEX_G(v->vg_p);
+
+                            if ( VNEAR_EQUAL(v->vg_p->coord, rv, BN_TOL_DIST) 
) {
+                                nmg_kvu(vu);
+                                nmg_klu(lu);
+                            }
+                        }
+
+                        continue;
+                    }
+
+                    for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+                        NMG_CK_EDGEUSE(eu);
+                        e = eu->e_p;
+                        NMG_CK_EDGE(e);
+
+                        if (eu->g.magic_p) {
+                            switch (*eu->g.magic_p) {
+                            case NMG_EDGE_G_LSEG_MAGIC:
+                                break;
+                            case NMG_EDGE_G_CNURB_MAGIC:
+                                break;
+                            }
+                        }
+
+                        vu = eu->vu_p;
+
+                        /* check and remove vertexuse */
+                        NMG_CK_VERTEXUSE(vu);
+                        v = vu->v_p;
+                        NMG_CK_VERTEX(v);
+
+                        if (v->vg_p) {
+                            NMG_CK_VERTEX_G(v->vg_p);
+
+                            if ( VNEAR_EQUAL(v->vg_p->coord,
+                                 rv, BN_TOL_DIST) ) {
+                                nmg_kvu(vu);
+                                nmg_keu(eu);
+                                nmg_klu(lu);
+                            }
+                        }
+                    }
+                }
+            }
+
+            /* Wire loops in shell */
+            for (BU_LIST_FOR(lu, loopuse, &s->lu_hd)) {
+                NMG_CK_LOOPUSE(lu);
+                l = lu->l_p;
+                NMG_CK_LOOP(l);
+
+                if (l->lg_p) {
+                    NMG_CK_LOOP_G(l->lg_p);
+                }
+
+                if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_VERTEXUSE_MAGIC) {
+                    /* Wire loop of Lone vertex */
+                    vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
+                    /* check and remove vertexuse */
+                    NMG_CK_VERTEXUSE(vu);
+                    v = vu->v_p;
+                    NMG_CK_VERTEX(v);
+                    if (v->vg_p) {
+                        NMG_CK_VERTEX_G(v->vg_p);
+                        if ( VNEAR_EQUAL(v->vg_p->coord, rv, BN_TOL_DIST) ) {
+                            nmg_kvu(vu);
+                            nmg_klu(lu);
+                        }
+                    }
+                    continue;
+                }
+
+                for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+                    NMG_CK_EDGEUSE(eu);
+                    e = eu->e_p;
+                    NMG_CK_EDGE(e);
+
+                    if (eu->g.magic_p) switch (*eu->g.magic_p) {
+                        case NMG_EDGE_G_LSEG_MAGIC:
+                        break;
+                        case NMG_EDGE_G_CNURB_MAGIC:
+                        break;
+                    }
+                    vu = eu->vu_p;
+
+                    /* check and remove vertexuse */
+                    NMG_CK_VERTEXUSE(vu);
+                    v = vu->v_p;
+                    NMG_CK_VERTEX(v);
+
+                    if (v->vg_p) {
+                        NMG_CK_VERTEX_G(v->vg_p);
+                        if ( VNEAR_EQUAL(v->vg_p->coord, rv, BN_TOL_DIST) ) {
+                            nmg_kvu(vu);
+                            nmg_keu(eu);
+                            nmg_klu(lu);
+                        }
+                    }
+                }
+            }
+
+            /* Wire edges in shell */
+            for (BU_LIST_FOR(eu, edgeuse, &s->eu_hd)) {
+                NMG_CK_EDGEUSE(eu);
+                e = eu->e_p;
+                NMG_CK_EDGE(e);
+
+                if (eu->g.magic_p) {
+                    switch (*eu->g.magic_p) {
+                    case NMG_EDGE_G_LSEG_MAGIC:
+                        break;
+                    case NMG_EDGE_G_CNURB_MAGIC:
+                        break;
+                    }
+                }
+
+                vu = eu->vu_p;
+
+                /* check and remove vertexuse */
+                NMG_CK_VERTEXUSE(vu);
+                v = vu->v_p;
+                NMG_CK_VERTEX(v);
+
+                if (v->vg_p) {
+                    NMG_CK_VERTEX_G(v->vg_p);
+
+                    if ( VNEAR_EQUAL(v->vg_p->coord, rv, BN_TOL_DIST) ) {
+                        nmg_kvu(vu);
+                        nmg_keu(eu);
+                    }
+                }
+            }
+
+            /* Lone vertex in shell */
+            vu = s->vu_p;
+
+            if (vu) {
+                /* check and remove vertexuse */
+                NMG_CK_VERTEXUSE(vu);
+                v = vu->v_p;
+                NMG_CK_VERTEX(v);
+
+                if (v->vg_p) {
+                    NMG_CK_VERTEX_G(v->vg_p);
+
+                    if ( VNEAR_EQUAL(v->vg_p->coord, rv, BN_TOL_DIST) ) {
+                        nmg_kvu(vu);
+                    }
+                }
+            }
+        }
+    }
+}
+
+GED_EXPORT int
+ged_nmg_kill_v(struct ged* gedp, int argc, const char* argv[])
+{
+    struct rt_db_internal internal;
+    struct directory *dp;
+    struct model* m;
+    const char* name;
+    point_t vt;
+
+    static const char *usage = "kill V x y z";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_DRAWABLE(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc < 6) {
+        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+        return GED_HELP;
+    }
+
+    /* attempt to resolve and verify */
+    name = argv[0];
+
+    if ( (dp=db_lookup(gedp->ged_wdbp->dbip, name, LOOKUP_QUIET))
+        == RT_DIR_NULL ) {
+        bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", name);
+        return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip,
+        bn_mat_identity, &rt_uniresource) < 0) {
+        bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+        return GED_ERROR;
+    }
+
+    if (internal.idb_type != ID_NMG) {
+        bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", name);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    vt[0] = atof(argv[3]); vt[1] = atof(argv[4]); vt[2] = atof(argv[5]);
+
+    m = (struct model *)internal.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    remove_vertex(m, vt);
+
+    if ( wdb_put_internal(gedp->ged_wdbp, name, &internal, 1.0) < 0 ) {
+        bu_vls_printf(gedp->ged_result_str, "wdb_put_internal(%s)", argv[1]);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    rt_db_free_internal(&internal);
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_make_v.c (from rev 76394, 
brlcad/branches/gedplugins/src/libged/nmg_make_v/nmg_make_v.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_make_v.c                      
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_make_v.c      2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,147 @@
+/*                         N M G _ M A K E _ V. C
+ * BRL-CAD
+ *
+ * Copyright (c) 2015-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/nmg_make_v.c
+ *
+ * The make V subcommand for nmg top-level command.
+ *
+ */
+
+#include "common.h"
+#include "nmg.h"
+
+#include <signal.h>
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+struct tmp_v {
+    point_t pt;
+    struct vertex *v;
+};
+
+GED_EXPORT int
+ged_nmg_make_v(struct ged *gedp, int argc, const char *argv[])
+{
+    struct rt_db_internal internal;
+    struct directory *dp;
+    struct model* m;
+    const char* name;
+    struct nmgregion* r;
+    struct shell* s;
+    struct tmp_v* verts;
+    struct bn_tol tol;
+    int idx;
+    int num_verts;
+    static const char *usage = "make V x0 y0 z0 ... xn yn zn";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    num_verts = (argc - 3) / 3;
+
+    /* check for less than three vertices or incomplete vertex coordinates */
+    if (argc < ELEMENTS_PER_POINT + 3 || (argc - 3) % 3 != 0) {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       return GED_HELP;
+    }
+
+    /* attempt to resolve and verify */
+    name = argv[0];
+
+    if ( (dp=db_lookup(gedp->ged_wdbp->dbip, name, LOOKUP_QUIET))
+         == RT_DIR_NULL ) {
+       bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", name);
+       return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip,
+       bn_mat_identity, &rt_uniresource) < 0) {
+       bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+       return GED_ERROR;
+    }
+
+    if (internal.idb_type != ID_NMG) {
+       bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", name);
+       rt_db_free_internal(&internal);
+       return GED_ERROR;
+    }
+
+    m = (struct model *)internal.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    if (BU_LIST_IS_EMPTY(&m->r_hd)) {
+        r = nmg_mrsv(m);
+        s = BU_LIST_FIRST(shell, &r->s_hd);
+    } else {
+        r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+        s = BU_LIST_FIRST(shell, &r->s_hd);
+    }
+
+    NMG_CK_REGION(r);
+    NMG_CK_SHELL(s);
+
+    verts = (struct tmp_v *)NULL;
+    verts = (struct tmp_v *)bu_calloc(num_verts,
+            sizeof(struct tmp_v), "verts");
+
+    for (idx=0; idx < num_verts; idx++){
+        struct shell* ns = nmg_msv(r);
+        NMG_CK_SHELL(ns);
+
+        verts[idx].pt[0] = (fastf_t)atof(argv[idx*3+3]);
+        verts[idx].pt[1] = (fastf_t)atof(argv[idx*3+4]);
+        verts[idx].pt[2] = (fastf_t)atof(argv[idx*3+5]);
+
+        nmg_vertex_gv( ns->vu_p->v_p, verts[idx].pt);
+    }
+
+    tol.magic = BN_TOL_MAGIC;
+    tol.dist = 0.0005;
+    tol.dist_sq = tol.dist * tol.dist;
+    tol.perp = 1e-6;
+    tol.para = 1 - tol.perp;
+
+    nmg_rebound(m, &tol);
+
+    if ( wdb_put_internal(gedp->ged_wdbp, name, &internal, 1.0) < 0 ) {
+        bu_vls_printf(gedp->ged_result_str, "wdb_put_internal(%s)", argv[1]);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    rt_db_free_internal(&internal);
+    bu_free(verts, "new verts");
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_mm.c (from rev 76394, 
brlcad/branches/gedplugins/src/libged/nmg_mm/nmg_mm.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_mm.c                          
(rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_mm.c  2020-07-21 18:53:10 UTC 
(rev 76395)
@@ -0,0 +1,86 @@
+/*                         N M G _ M M . 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/nmg_mm.c
+ *
+ * The mm subcommand.
+ *
+ */
+
+#include "common.h"
+
+#include <signal.h>
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+GED_EXPORT int
+ged_nmg_mm(struct ged *gedp, int argc, const char *argv[])
+{
+    struct rt_db_internal internal;
+    struct model *m;
+    struct directory *dp;
+    const char *name;
+    static const char *usage = "name";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    if (argc != 2) {
+        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+        return GED_HELP;
+    }
+
+    /* attempt to resolve and verify */
+    name = argv[1];
+
+    GED_CHECK_EXISTS(gedp, name, LOOKUP_QUIET, GED_ERROR);
+    RT_DB_INTERNAL_INIT(&internal);
+
+    m = nmg_mm();
+
+    internal.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+    internal.idb_type = ID_NMG;
+    internal.idb_meth = &OBJ[ID_NMG];
+    internal.idb_ptr = (void *)m;
+
+    /* no interrupts */
+    (void)signal(SIGINT, SIG_IGN);
+
+    /* add model to database */
+    GED_DB_DIRADD(gedp, dp, name, RT_DIR_PHONY_ADDR, 0,
+            RT_DIR_SOLID, (void *)&internal.idb_type, GED_ERROR);
+    GED_DB_PUT_INTERNAL(gedp, dp, &internal, &rt_uniresource, GED_ERROR);
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_move_v.c (from rev 76394, 
brlcad/branches/gedplugins/src/libged/nmg_move_v/nmg_move_v.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_move_v.c                      
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_move_v.c      2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,339 @@
+/*                         N M G _ M O V E _ V. C
+ * BRL-CAD
+ *
+ * Copyright (c) 2015-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/nmg_move_v.c
+ *
+ * The move V subcommand for nmg top-level command.
+ *
+ */
+
+#include "common.h"
+
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+void move_vertex(const struct model* m, point_t v_old, point_t v_new)
+{
+    struct nmgregion *r;
+    struct shell *s;
+    struct faceuse *fu;
+    struct face *f;
+    struct loopuse *lu;
+    struct loop *l;
+    struct edgeuse *eu;
+    struct edge *e;
+    struct vertexuse *vu;
+    struct vertex *v;
+
+    NMG_CK_MODEL(m);
+
+    /* Traverse NMG model to find specified vertex and sets the new coords.
+     */
+
+    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
+        NMG_CK_REGION(r);
+
+        if (r->ra_p) {
+            NMG_CK_REGION_A(r->ra_p);
+        }
+
+        for (BU_LIST_FOR(s, shell, &r->s_hd)) {
+            NMG_CK_SHELL(s);
+
+            if (s->sa_p) {
+                NMG_CK_SHELL_A(s->sa_p);
+            }
+
+            /* Faces in shell */
+            for (BU_LIST_FOR(fu, faceuse, &s->fu_hd)) {
+                NMG_CK_FACEUSE(fu);
+                f = fu->f_p;
+                NMG_CK_FACE(f);
+
+                if (f->g.magic_p) switch (*f->g.magic_p) {
+                    case NMG_FACE_G_PLANE_MAGIC:
+                        break;
+                    case NMG_FACE_G_SNURB_MAGIC:
+                        break;
+                }
+
+                /* Loops in face */
+                for (BU_LIST_FOR(lu, loopuse, &fu->lu_hd)) {
+                    NMG_CK_LOOPUSE(lu);
+                    l = lu->l_p;
+                    NMG_CK_LOOP(l);
+
+                    if (l->lg_p) {
+                        NMG_CK_LOOP_G(l->lg_p);
+                    }
+
+                    if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == 
NMG_VERTEXUSE_MAGIC) {
+                        /* Loop of Lone vertex */
+                        vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
+
+                        /* check and remove vertexuse */
+                        NMG_CK_VERTEXUSE(vu);
+                        v = vu->v_p;
+                        NMG_CK_VERTEX(v);
+
+                        if (v->vg_p) {
+                            NMG_CK_VERTEX_G(v->vg_p);
+
+                            if ( VNEAR_EQUAL(v->vg_p->coord, v_old, 
BN_TOL_DIST) ) {
+                                v->vg_p->coord[0] = v_new[0];
+                                v->vg_p->coord[1] = v_new[1];
+                                v->vg_p->coord[2] = v_new[2];
+                            }
+                        }
+
+                        continue;
+                    }
+
+                    for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+                        NMG_CK_EDGEUSE(eu);
+                        e = eu->e_p;
+                        NMG_CK_EDGE(e);
+
+                        if (eu->g.magic_p) {
+                            switch (*eu->g.magic_p) {
+                            case NMG_EDGE_G_LSEG_MAGIC:
+                                break;
+                            case NMG_EDGE_G_CNURB_MAGIC:
+                                break;
+                            }
+                        }
+
+                        vu = eu->vu_p;
+
+                        /* check and remove vertexuse */
+                        NMG_CK_VERTEXUSE(vu);
+                        v = vu->v_p;
+                        NMG_CK_VERTEX(v);
+
+                        if (v->vg_p) {
+                            NMG_CK_VERTEX_G(v->vg_p);
+
+                            if ( VNEAR_EQUAL(v->vg_p->coord,
+                                 v_old, BN_TOL_DIST) ) {
+                                v->vg_p->coord[0] = v_new[0];
+                                v->vg_p->coord[1] = v_new[1];
+                                v->vg_p->coord[2] = v_new[2];
+                            }
+                        }
+                    }
+                }
+            }
+
+            /* Wire loops in shell */
+            for (BU_LIST_FOR(lu, loopuse, &s->lu_hd)) {
+                NMG_CK_LOOPUSE(lu);
+                l = lu->l_p;
+                NMG_CK_LOOP(l);
+
+                if (l->lg_p) {
+                    NMG_CK_LOOP_G(l->lg_p);
+                }
+
+                if (BU_LIST_FIRST_MAGIC(&lu->down_hd) == NMG_VERTEXUSE_MAGIC) {
+                    /* Wire loop of Lone vertex */
+                    vu = BU_LIST_FIRST(vertexuse, &lu->down_hd);
+                    /* check and remove vertexuse */
+                    NMG_CK_VERTEXUSE(vu);
+                    v = vu->v_p;
+                    NMG_CK_VERTEX(v);
+                    if (v->vg_p) {
+                        NMG_CK_VERTEX_G(v->vg_p);
+                        if ( VNEAR_EQUAL(v->vg_p->coord, v_old, BN_TOL_DIST) ) 
{
+                            v->vg_p->coord[0] = v_new[0];
+                            v->vg_p->coord[1] = v_new[1];
+                            v->vg_p->coord[2] = v_new[2];
+                        }
+                    }
+                    continue;
+                }
+
+                for (BU_LIST_FOR(eu, edgeuse, &lu->down_hd)) {
+                    NMG_CK_EDGEUSE(eu);
+                    e = eu->e_p;
+                    NMG_CK_EDGE(e);
+
+                    if (eu->g.magic_p) switch (*eu->g.magic_p) {
+                        case NMG_EDGE_G_LSEG_MAGIC:
+                        break;
+                        case NMG_EDGE_G_CNURB_MAGIC:
+                        break;
+                    }
+                    vu = eu->vu_p;
+
+                    /* check and remove vertexuse */
+                    NMG_CK_VERTEXUSE(vu);
+                    v = vu->v_p;
+                    NMG_CK_VERTEX(v);
+
+                    if (v->vg_p) {
+                        NMG_CK_VERTEX_G(v->vg_p);
+                        if ( VNEAR_EQUAL(v->vg_p->coord, v_old, BN_TOL_DIST) ) 
{
+                            v->vg_p->coord[0] = v_new[0];
+                            v->vg_p->coord[1] = v_new[1];
+                            v->vg_p->coord[2] = v_new[2];
+                        }
+                    }
+                }
+            }
+
+            /* Wire edges in shell */
+            for (BU_LIST_FOR(eu, edgeuse, &s->eu_hd)) {
+                NMG_CK_EDGEUSE(eu);
+                e = eu->e_p;
+                NMG_CK_EDGE(e);
+
+                if (eu->g.magic_p) {
+                    switch (*eu->g.magic_p) {
+                    case NMG_EDGE_G_LSEG_MAGIC:
+                        break;
+                    case NMG_EDGE_G_CNURB_MAGIC:
+                        break;
+                    }
+                }
+
+                vu = eu->vu_p;
+
+                /* check and remove vertexuse */
+                NMG_CK_VERTEXUSE(vu);
+                v = vu->v_p;
+                NMG_CK_VERTEX(v);
+
+                if (v->vg_p) {
+                    NMG_CK_VERTEX_G(v->vg_p);
+
+                    if ( VNEAR_EQUAL(v->vg_p->coord, v_old, BN_TOL_DIST) ) {
+                        v->vg_p->coord[0] = v_new[0];
+                        v->vg_p->coord[1] = v_new[1];
+                        v->vg_p->coord[2] = v_new[2];
+                    }
+                }
+            }
+
+            /* Lone vertex in shell */
+            vu = s->vu_p;
+
+            if (vu) {
+                /* check and remove vertexuse */
+                NMG_CK_VERTEXUSE(vu);
+                v = vu->v_p;
+                NMG_CK_VERTEX(v);
+
+                if (v->vg_p) {
+                    NMG_CK_VERTEX_G(v->vg_p);
+
+                    if ( VNEAR_EQUAL(v->vg_p->coord, v_old, BN_TOL_DIST) ) {
+                        v->vg_p->coord[0] = v_new[0];
+                        v->vg_p->coord[1] = v_new[1];
+                        v->vg_p->coord[2] = v_new[2];
+                    }
+                }
+            }
+        }
+    }
+}
+
+GED_EXPORT int
+ged_nmg_move_v(struct ged* gedp, int argc, const char* argv[])
+{
+    struct rt_db_internal internal;
+    struct directory *dp;
+    struct model* m;
+    const char* name;
+    point_t vtold;
+    point_t vtnew;
+
+    static const char *usage = "move V x_old y_old z_old x_new y_new z_new";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_DRAWABLE(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    /* must be wanting help */
+    if (argc != 9 ) {
+        bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+        return GED_HELP;
+    }
+
+    /* attempt to resolve and verify */
+    name = argv[0];
+
+    if ( (dp=db_lookup(gedp->ged_wdbp->dbip, name, LOOKUP_QUIET))
+        == RT_DIR_NULL ) {
+        bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", name);
+        return GED_ERROR;
+    }
+
+    if (rt_db_get_internal(&internal, dp, gedp->ged_wdbp->dbip,
+        bn_mat_identity, &rt_uniresource) < 0) {
+        bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+        return GED_ERROR;
+    }
+
+    if (internal.idb_type != ID_NMG) {
+        bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", name);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    vtold[0] = atof(argv[3]);
+    vtold[1] = atof(argv[4]);
+    vtold[2] = atof(argv[5]);
+
+    vtnew[0] = atof(argv[6]);
+    vtnew[1] = atof(argv[7]);
+    vtnew[2] = atof(argv[8]);
+
+    m = (struct model *)internal.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    move_vertex(m, vtold, vtnew);
+
+    if ( wdb_put_internal(gedp->ged_wdbp, name, &internal, 1.0) < 0 ) {
+        bu_vls_printf(gedp->ged_result_str, "wdb_put_internal(%s)", argv[1]);
+        rt_db_free_internal(&internal);
+        return GED_ERROR;
+    }
+
+    rt_db_free_internal(&internal);
+
+    return GED_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

Copied: brlcad/branches/gedplugins/src/libged/nmg/nmg_simplify.c (from rev 
76394, brlcad/branches/gedplugins/src/libged/nmg_simplify/nmg_simplify.c)
===================================================================
--- brlcad/branches/gedplugins/src/libged/nmg/nmg_simplify.c                    
        (rev 0)
+++ brlcad/branches/gedplugins/src/libged/nmg/nmg_simplify.c    2020-07-21 
18:53:10 UTC (rev 76395)
@@ -0,0 +1,308 @@
+/*                         N M G _ S I M P L I F Y . 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/nmg_simplify.c
+ *
+ * The nmg_simplify command.
+ *
+ */
+
+#include "common.h"
+
+#include <string.h>
+
+#include "bu/cmd.h"
+#include "rt/geom.h"
+
+#include "../ged_private.h"
+
+
+GED_EXPORT int
+ged_nmg_simplify(struct ged *gedp, int argc, const char *argv[])
+{
+    struct directory *dp;
+    struct rt_db_internal nmg_intern;
+    struct rt_db_internal new_intern;
+    struct model *m;
+    struct nmgregion *r;
+    struct shell *s;
+    struct bu_ptbl faces;
+    struct face *fp;
+    int do_all=1;
+    int do_arb=0;
+    int do_tgc=0;
+    int do_poly=0;
+    char *new_name;
+    char *nmg_name;
+    int success = 0;
+    int shell_count=0;
+    int ret = GED_ERROR;
+    size_t i;
+
+    static const char *usage = "[arb|tgc|poly] new_prim nmg_prim";
+
+    GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR);
+    GED_CHECK_READ_ONLY(gedp, GED_ERROR);
+    GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR);
+
+    /* initialize result */
+    bu_vls_trunc(gedp->ged_result_str, 0);
+
+    if (argc == 1) {
+       /* must be wanting help */
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s\n", argv[0], usage);
+       ret = GED_HELP;
+       goto out3;
+    } else if (argc == 3) {
+       /* FIXME: if you use the default but have a TGC, the cleanup
+        * for ARB breaks TGC.
+        */
+       do_arb = do_tgc = do_poly = do_all = 1; /* do all */
+       new_name = (char *)argv[1];
+       nmg_name = (char *)argv[2];
+    } else if (argc == 4) {
+       do_all = 0;
+       if (!bu_strncmp(argv[1], "arb", 3)) {
+           do_arb = 1;
+       } else if (!bu_strncmp(argv[1], "tgc", 3)) {
+           do_tgc = 1;
+       } else if (!bu_strncmp(argv[1], "poly", 4)) {
+           do_poly = 1;
+       } else {
+           bu_vls_printf(gedp->ged_result_str,
+                         "%s is unknown or simplification is not yet 
supported\n", argv[1]);
+           bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+           ret = GED_ERROR;
+           goto out3;
+       }
+       new_name = (char *)argv[2];
+       nmg_name = (char *)argv[3];
+    } else {
+       bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage);
+       success = 0;
+       ret = GED_ERROR;
+       goto out3;
+    }
+
+    if (db_lookup(gedp->ged_wdbp->dbip, new_name, LOOKUP_QUIET) != 
RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s already exists\n", new_name);
+       ret = GED_ERROR;
+       goto out3;
+    }
+
+    if ((dp=db_lookup(gedp->ged_wdbp->dbip, nmg_name, LOOKUP_QUIET)) == 
RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "%s does not exist\n", nmg_name);
+       ret = GED_ERROR;
+       goto out3;
+    }
+
+    if (rt_db_get_internal(&nmg_intern, dp, gedp->ged_wdbp->dbip, 
bn_mat_identity, &rt_uniresource) < 0) {
+       bu_vls_printf(gedp->ged_result_str, "rt_db_get_internal() error\n");
+       ret = GED_ERROR;
+       goto out3;
+    }
+
+    if (nmg_intern.idb_type != ID_NMG) {
+       bu_vls_printf(gedp->ged_result_str, "%s is not an NMG solid\n", 
nmg_name);
+       ret = GED_ERROR;
+       goto out2;
+    }
+
+    m = (struct model *)nmg_intern.idb_ptr;
+    NMG_CK_MODEL(m);
+
+    /* check that all faces are planar */
+    nmg_face_tabulate(&faces, &m->magic, &RTG.rtg_vlfree);
+
+    for (i = 0 ; i < BU_PTBL_LEN(&faces) ; i++) {
+       fp = (struct face *)BU_PTBL_GET(&faces, i);
+       if (fp->g.magic_p != NULL && *(fp->g.magic_p) != 
NMG_FACE_G_PLANE_MAGIC) {
+           bu_ptbl_free(&faces);
+           bu_vls_printf(gedp->ged_result_str,
+               "%s cannot be applied to \"%s\" because it has non-planar 
faces\n", argv[0], nmg_name);
+           ret = GED_ERROR;
+           goto out2;
+       }
+    }
+    bu_ptbl_free(&faces);
+
+    /* count shells */
+    shell_count = 0;
+    for (BU_LIST_FOR(r, nmgregion, &m->r_hd)) {
+       for (BU_LIST_FOR(s, shell, &r->s_hd)) {
+           shell_count++;
+       }
+    }
+
+    if (shell_count != 1) {
+       bu_vls_printf(gedp->ged_result_str, "shell count is not one\n");
+       ret = GED_ERROR;
+       goto out2;
+    }
+
+    success = 0;
+
+    /* see if we can get an arb by simplifying the nmg */
+    if (do_arb) {
+       struct rt_arb_internal *arb_int;
+
+       RT_DB_INTERNAL_INIT(&new_intern);
+       BU_ALLOC(arb_int, struct rt_arb_internal);
+
+       new_intern.idb_ptr = (void *)(arb_int);
+       new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+       new_intern.idb_type = ID_ARB8;
+       new_intern.idb_meth = &OBJ[ID_ARB8];
+
+       r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+       s = BU_LIST_FIRST(shell, &r->s_hd);
+       nmg_shell_coplanar_face_merge(s, &gedp->ged_wdbp->wdb_tol, 0, 
&RTG.rtg_vlfree);
+       nmg_simplify_shell(s, &RTG.rtg_vlfree);
+
+       if (nmg_to_arb(m, arb_int)) {
+           success = 1;
+           ret = GED_OK;
+           goto out1;
+       } else {
+           rt_db_free_internal(&new_intern);
+           if (!do_all) {
+               ret = GED_ERROR;
+               goto out2;
+           }
+       }
+    }
+
+    /* see if we can get a tgc by simplifying the nmg */
+    if (do_tgc) {
+       struct rt_tgc_internal *tgc_int;
+
+       RT_DB_INTERNAL_INIT(&new_intern);
+       BU_ALLOC(tgc_int, struct rt_tgc_internal);
+
+       new_intern.idb_ptr = (void *)(tgc_int);
+       new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+       new_intern.idb_type = ID_TGC;
+       new_intern.idb_meth = &OBJ[ID_TGC];
+
+       if (nmg_to_tgc(m, tgc_int, &gedp->ged_wdbp->wdb_tol)) {
+           success = 1;
+           ret = GED_OK;
+           goto out1;
+       } else {
+           rt_db_free_internal(&new_intern);
+           if (!do_all) {
+               ret = GED_ERROR;
+               goto out2;
+           }
+       }
+    }
+
+    /* see if we can get a poly by simplifying the nmg */
+    if (do_poly) {
+       struct rt_pg_internal *poly_int;
+
+       RT_DB_INTERNAL_INIT(&new_intern);
+       BU_ALLOC(poly_int, struct rt_pg_internal);
+
+       new_intern.idb_ptr = (void *)(poly_int);
+       new_intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
+       new_intern.idb_type = ID_POLY;
+       new_intern.idb_meth = &OBJ[ID_POLY];
+
+       if (nmg_to_poly(m, poly_int, &RTG.rtg_vlfree, 
&gedp->ged_wdbp->wdb_tol)) {
+           success = 1;
+           ret = GED_OK;
+           goto out1;
+       } else {
+           rt_db_free_internal(&new_intern);
+           if (!do_all) {
+               ret = GED_ERROR;
+               goto out2;
+           }
+       }
+    }
+
+out1:
+    r = BU_LIST_FIRST(nmgregion, &m->r_hd);
+    s = BU_LIST_FIRST(shell, &r->s_hd);
+
+    if (BU_LIST_NON_EMPTY(&s->lu_hd))
+       bu_vls_printf(gedp->ged_result_str,
+               "wire loops in %s have been ignored in conversion\n",  
nmg_name);
+
+    if (BU_LIST_NON_EMPTY(&s->eu_hd))
+       bu_vls_printf(gedp->ged_result_str,
+               "wire edges in %s have been ignored in conversion\n",  
nmg_name);
+
+    if (s->vu_p)
+       bu_vls_printf(gedp->ged_result_str,
+               "Single vertexuse in shell of %s has been ignored in 
conversion\n", nmg_name);
+
+    dp = db_diradd(gedp->ged_wdbp->dbip, new_name,
+       RT_DIR_PHONY_ADDR, 0, RT_DIR_SOLID, (void *)&new_intern.idb_type);
+
+    if (dp == RT_DIR_NULL) {
+       bu_vls_printf(gedp->ged_result_str, "Cannot add %s to directory\n", 
new_name);
+       success = 0;
+       ret = GED_ERROR;
+       goto out2;
+    }
+
+    if (rt_db_put_internal(dp, gedp->ged_wdbp->dbip, &new_intern, 
&rt_uniresource) < 0) {
+       rt_db_free_internal(&new_intern);
+       bu_vls_printf(gedp->ged_result_str, "Database write error, 
aborting.\n");
+       success = 0;
+       ret = GED_ERROR;
+       goto out2;
+    }
+
+    ret = GED_OK;
+
+out2:
+    rt_db_free_internal(&nmg_intern);
+
+    if (!success) {
+       if (do_arb && !do_all) {
+           bu_vls_printf(gedp->ged_result_str,
+               "Failed to construct an ARB equivalent to %s\n", nmg_name);
+       } else if (do_tgc && !do_all) {
+           bu_vls_printf(gedp->ged_result_str,
+               "Failed to construct a TGC equivalent to %s\n", nmg_name);
+       } else if (do_poly && !do_all) {
+           bu_vls_printf(gedp->ged_result_str,
+               "Failed to construct a POLY equivalent to %s\n", nmg_name);
+       } else {
+           bu_vls_printf(gedp->ged_result_str,
+               "Failed to construct an ARB or TGC or POLY equivalent to %s\n", 
nmg_name);
+       }
+    }
+
+out3:
+    return ret;
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */

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