Revision: 78051
          http://sourceforge.net/p/brlcad/code/78051
Author:   starseeker
Date:     2021-01-07 15:27:12 +0000 (Thu, 07 Jan 2021)
Log Message:
-----------
Rough in a command for experimenting with push/xpush style logic.

Modified Paths:
--------------
    brlcad/trunk/include/ged/commands.h
    brlcad/trunk/src/libged/CMakeLists.txt
    brlcad/trunk/src/libged/exec_mapping.cpp
    brlcad/trunk/src/libged/xpush/xpush.c
    brlcad/trunk/src/libtclcad/commands.c
    brlcad/trunk/src/mged/setup.c

Added Paths:
-----------
    brlcad/trunk/src/libged/npush/
    brlcad/trunk/src/libged/npush/CMakeLists.txt
    brlcad/trunk/src/libged/npush/npush.cpp

Modified: brlcad/trunk/include/ged/commands.h
===================================================================
--- brlcad/trunk/include/ged/commands.h 2021-01-07 14:04:33 UTC (rev 78050)
+++ brlcad/trunk/include/ged/commands.h 2021-01-07 15:27:12 UTC (rev 78051)
@@ -785,6 +785,7 @@
  * Push object path transformations to solids, creating primitives if necessary
  */
 GED_EXPORT extern int ged_xpush(struct ged *gedp, int argc, const char 
*argv[]);
+GED_EXPORT extern int ged_npush(struct ged *gedp, int argc, const char 
*argv[]);
 
 /**
  * Voxelize the specified objects

Modified: brlcad/trunk/src/libged/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libged/CMakeLists.txt      2021-01-07 14:04:33 UTC (rev 
78050)
+++ brlcad/trunk/src/libged/CMakeLists.txt      2021-01-07 15:27:12 UTC (rev 
78051)
@@ -256,6 +256,7 @@
 add_subdirectory(mrot)
 add_subdirectory(nirt)
 add_subdirectory(nmg)
+add_subdirectory(npush)
 add_subdirectory(ocenter)
 add_subdirectory(open)
 add_subdirectory(orient)

Modified: brlcad/trunk/src/libged/exec_mapping.cpp
===================================================================
--- brlcad/trunk/src/libged/exec_mapping.cpp    2021-01-07 14:04:33 UTC (rev 
78050)
+++ brlcad/trunk/src/libged/exec_mapping.cpp    2021-01-07 15:27:12 UTC (rev 
78051)
@@ -243,6 +243,7 @@
 GED_CMD(nmg_collapse)
 GED_CMD(nmg_fix_normals)
 GED_CMD(nmg_simplify)
+GED_CMD(npush)
 GED_CMD(ocenter)
 GED_CMD(orient)
 GED_CMD(orientation)

Added: brlcad/trunk/src/libged/npush/CMakeLists.txt
===================================================================
--- brlcad/trunk/src/libged/npush/CMakeLists.txt                                
(rev 0)
+++ brlcad/trunk/src/libged/npush/CMakeLists.txt        2021-01-07 15:27:12 UTC 
(rev 78051)
@@ -0,0 +1,26 @@
+include_directories(
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${BRLCAD_BINARY_DIR}/include
+  ${BRLCAD_SOURCE_DIR}/include
+  ${BU_INCLUDE_DIRS}
+  ${GED_INCLUDE_DIRS}
+  )
+
+add_definitions(-DGED_PLUGIN)
+ged_plugin_library(ged-npush SHARED npush.cpp)
+target_link_libraries(ged-npush libged libbu)
+set_property(TARGET ged-npush APPEND PROPERTY COMPILE_DEFINITIONS BRLCADBUILD 
HAVE_CONFIG_H)
+VALIDATE_STYLE(ged-npush npush.cpp)
+PLUGIN_SETUP(ged-npush ged)
+
+CMAKEFILES(
+  CMakeLists.txt
+  npush.cpp
+  )
+
+# Local Variables:
+# tab-width: 8
+# mode: cmake
+# indent-tabs-mode: t
+# End:
+# ex: shiftwidth=2 tabstop=8


Property changes on: brlcad/trunk/src/libged/npush/CMakeLists.txt
___________________________________________________________________
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/trunk/src/libged/npush/npush.cpp
===================================================================
--- brlcad/trunk/src/libged/npush/npush.cpp                             (rev 0)
+++ brlcad/trunk/src/libged/npush/npush.cpp     2021-01-07 15:27:12 UTC (rev 
78051)
@@ -0,0 +1,373 @@
+/*                         P U S H . 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/push.c
+ *
+ * The push command.
+ *
+ */
+
+#include "common.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "bu/cmd.h"
+#include "bu/getopt.h"
+
+#include "../ged_private.h"
+
+
+#define PUSH_MAGIC_ID 0x50495323
+#define FOR_ALL_PUSH_SOLIDS(_p, _phead) \
+    for (_p=_phead.forw; _p!=&_phead; _p=_p->forw)
+
+/** structure to hold all solids that have been pushed. */
+struct push_id {
+    uint32_t magic;
+    struct push_id *forw, *back;
+    struct directory *pi_dir;
+    mat_t pi_mat;
+};
+
+
+struct push_data {
+    struct ged *gedp;
+    struct push_id pi_head;
+    int push_error;
+};
+
+
+static void
+do_identitize(struct db_i *dbip, struct rt_comb_internal *UNUSED(comb), union 
tree *comb_leaf, void *user_ptr1, void *UNUSED(user_ptr2), void 
*UNUSED(user_ptr3), void *UNUSED(user_ptr4));
+
+
+/**
+ * Traverses an objects paths, setting all member matrices == identity
+ */
+static void
+identitize(struct directory *dp,
+          struct db_i *dbip,
+          struct bu_vls *msg)
+{
+    struct rt_db_internal intern;
+    struct rt_comb_internal *comb;
+
+    if (dp->d_flags & RT_DIR_SOLID)
+       return;
+    if (rt_db_get_internal(&intern, dp, dbip, (fastf_t *)NULL, 
&rt_uniresource) < 0) {
+       bu_vls_printf(msg, "Database read error, aborting\n");
+       return;
+    }
+    comb = (struct rt_comb_internal *)intern.idb_ptr;
+    if (comb->tree) {
+       db_tree_funcleaf(dbip, comb, comb->tree, do_identitize,
+                        (void *)msg, (void *)NULL, (void *)NULL, (void *)NULL);
+       if (rt_db_put_internal(dp, dbip, &intern, &rt_uniresource) < 0) {
+           bu_vls_printf(msg, "Cannot write modified combination (%s) to 
database\n", dp->d_namep);
+           return;
+       }
+    }
+}
+
+
+/**
+ * This routine must be prepared to run in parallel.
+ *
+ * @brief
+ * This routine is called once for eas leaf (solid) that is to
+ * be pushed.  All it does is build at push_id linked list.  The
+ * linked list could be handled by bu_list macros but it is simple
+ * enough to do hear with out them.
+ */
+static union tree *
+push_leaf(struct db_tree_state *tsp,
+         const struct db_full_path *pathp,
+         struct rt_db_internal *ip,
+         void *client_data)
+{
+    union tree *curtree;
+    struct directory *dp;
+    struct push_id *gpip;
+    struct push_data *gpdp = (struct push_data *)client_data;
+
+    BG_CK_TESS_TOL(tsp->ts_ttol);
+    BN_CK_TOL(tsp->ts_tol);
+    RT_CK_RESOURCE(tsp->ts_resp);
+
+    dp = pathp->fp_names[pathp->fp_len-1];
+
+    if (RT_G_DEBUG&RT_DEBUG_TREEWALK) {
+       char *sofar = db_path_to_string(pathp);
+
+       bu_vls_printf(gpdp->gedp->ged_result_str, "push_leaf(%s) path='%s'\n", 
ip->idb_meth->ft_name, sofar);
+       bu_free((void *)sofar, "path string");
+    }
+/*
+ * XXX - This will work but is not the best method.  dp->d_uses tells us
+ * if this solid (leaf) has been seen before.  If it hasn't just add
+ * it to the list.  If it has, search the list to see if the matrices
+ * match and do the "right" thing.
+ *
+ * (There is a question as to whether dp->d_uses is reset to zero
+ * for each tree walk.  If it is not, then d_uses is NOT a safe
+ * way to check and this method will always work.)
+ */
+    bu_semaphore_acquire(RT_SEM_WORKER);
+    FOR_ALL_PUSH_SOLIDS(gpip, gpdp->pi_head) {
+       if (gpip->pi_dir == dp) {
+           if (!bn_mat_is_equal(gpip->pi_mat,
+                                tsp->ts_mat, tsp->ts_tol)) {
+               char *sofar = db_path_to_string(pathp);
+
+               bu_vls_printf(gpdp->gedp->ged_result_str, "push_leaf: matrix 
mismatch between '%s' and prior reference.\n", sofar);
+               bu_free((void *)sofar, "path string");
+               gpdp->push_error = 1;
+           }
+
+           bu_semaphore_release(RT_SEM_WORKER);
+           BU_GET(curtree, union tree);
+           RT_TREE_INIT(curtree);
+           curtree->tr_op = OP_NOP;
+           return curtree;
+       }
+    }
+/*
+ * This is the first time we have seen this solid.
+ */
+    BU_ALLOC(gpip, struct push_id);
+    gpip->magic = PUSH_MAGIC_ID;
+    gpip->pi_dir = dp;
+    MAT_COPY(gpip->pi_mat, tsp->ts_mat);
+    gpip->back = gpdp->pi_head.back;
+    gpdp->pi_head.back = gpip;
+    gpip->forw = &gpdp->pi_head;
+    gpip->back->forw = gpip;
+    bu_semaphore_release(RT_SEM_WORKER);
+    BU_GET(curtree, union tree);
+    RT_TREE_INIT(curtree);
+    curtree->tr_op = OP_NOP;
+    return curtree;
+}
+
+
+/**
+ * @brief
+ * A null routine that does nothing.
+ */
+static union tree *
+push_region_end(struct db_tree_state *UNUSED(tsp), const struct db_full_path 
*UNUSED(pathp), union tree *curtree, void *UNUSED(client_data))
+{
+    return curtree;
+}
+
+
+extern "C" int
+ged_npush_core(struct ged *gedp, int argc, const char *argv[])
+{
+    struct push_data *gpdp;
+    struct push_id *gpip;
+    struct rt_db_internal es_int;
+    int i;
+    int ncpu;
+    int c;
+    int old_debug;
+    int push_error;
+    static const char *usage = "object(s)";
+
+    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;
+    }
+
+    BU_GET(gpdp, struct push_data);
+    gpdp->gedp = gedp;
+    gpdp->push_error = 0;
+    gpdp->pi_head.magic = PUSH_MAGIC_ID;
+    gpdp->pi_head.forw = gpdp->pi_head.back = &gpdp->pi_head;
+    gpdp->pi_head.pi_dir = (struct directory *) 0;
+
+    old_debug = RT_G_DEBUG;
+
+    /* Initial values for options, must be reset each time */
+    ncpu = 1;
+
+    /* Parse options */
+    bu_optind = 1;     /* re-init bu_getopt() */
+    while ((c=bu_getopt(argc, (char * const *)argv, "P:d")) != -1) {
+       switch (c) {
+           case 'P':
+               ncpu = atoi(bu_optarg);
+               if (ncpu<1) ncpu = 1;
+               break;
+           case 'd':
+               rt_debug |= RT_DEBUG_TREEWALK;
+               break;
+           case '?':
+           default:
+               bu_vls_printf(gedp->ged_result_str, "ged_push_core: usage push 
[-P processors] [-d] root [root2 ...]\n");
+               break;
+       }
+    }
+
+    argc -= bu_optind;
+    argv += bu_optind;
+
+    /*
+     * build a linked list of solids with the correct
+     * matrix to apply to each solid.  This will also
+     * check to make sure that a solid is not pushed in two
+     * different directions at the same time.
+     */
+    i = db_walk_tree(gedp->ged_wdbp->dbip, argc, (const char **)argv,
+                    ncpu,
+                    &gedp->ged_wdbp->wdb_initial_tree_state,
+                    0,                         /* take all regions */
+                    push_region_end,
+                    push_leaf, (void *)gpdp);
+
+    /*
+     * If there was any error, then just free up the solid
+     * list we just built.
+     */
+    if (i < 0 || gpdp->push_error) {
+       while (gpdp->pi_head.forw != &gpdp->pi_head) {
+           gpip = gpdp->pi_head.forw;
+           gpip->forw->back = gpip->back;
+           gpip->back->forw = gpip->forw;
+           bu_free((void *)gpip, "Push ident");
+       }
+       rt_debug = old_debug;
+       BU_PUT(gpdp, struct push_data);
+       bu_vls_printf(gedp->ged_result_str, "ged_push_core:\tdb_walk_tree 
failed or there was a solid moving\n\tin two or more directions");
+       return GED_ERROR;
+    }
+/*
+ * We've built the push solid list, now all we need to do is apply
+ * the matrix we've stored for each solid.
+ */
+    FOR_ALL_PUSH_SOLIDS(gpip, gpdp->pi_head) {
+       if (rt_db_get_internal(&es_int, gpip->pi_dir, gedp->ged_wdbp->dbip, 
gpip->pi_mat, &rt_uniresource) < 0) {
+           bu_vls_printf(gedp->ged_result_str, "ged_push_core: Read error 
fetching '%s'\n", gpip->pi_dir->d_namep);
+           gpdp->push_error = -1;
+           continue;
+       }
+       RT_CK_DB_INTERNAL(&es_int);
+
+       if (rt_db_put_internal(gpip->pi_dir, gedp->ged_wdbp->dbip, &es_int, 
&rt_uniresource) < 0) {
+           bu_vls_printf(gedp->ged_result_str, "ged_push_core(%s): solid 
export failure\n", gpip->pi_dir->d_namep);
+       }
+       rt_db_free_internal(&es_int);
+    }
+
+    /*
+     * Now use the wdb_identitize() tree walker to turn all the
+     * matrices in a combination to the identity matrix.
+     * It would be nice to use db_tree_walker() but the tree
+     * walker does not give us all combinations, just regions.
+     * This would work if we just processed all matrices backwards
+     * from the leaf (solid) towards the root, but all in all it
+     * seems that this is a better method.
+     */
+
+    while (argc > 0) {
+       struct directory *db;
+       db = db_lookup(gedp->ged_wdbp->dbip, *argv++, 0);
+       if (db)
+           identitize(db, gedp->ged_wdbp->dbip, gedp->ged_result_str);
+       --argc;
+    }
+
+    /*
+     * Free up the solid table we built.
+     */
+    while (gpdp->pi_head.forw != &gpdp->pi_head) {
+       gpip = gpdp->pi_head.forw;
+       gpip->forw->back = gpip->back;
+       gpip->back->forw = gpip->forw;
+       bu_free((void *)gpip, "Push ident");
+    }
+
+    rt_debug = old_debug;
+    push_error = gpdp->push_error;
+    BU_PUT(gpdp, struct push_data);
+
+    return push_error ? GED_ERROR : GED_OK;
+}
+
+
+static void
+do_identitize(struct db_i *dbip, struct rt_comb_internal *UNUSED(comb), union 
tree *comb_leaf, void *user_ptr1, void *UNUSED(user_ptr2), void 
*UNUSED(user_ptr3), void *UNUSED(user_ptr4))
+{
+    struct directory *dp;
+    struct bu_vls *msg = (struct bu_vls *)user_ptr1;
+
+    RT_CK_DBI(dbip);
+    RT_CK_TREE(comb_leaf);
+
+    if (!comb_leaf->tr_l.tl_mat) {
+       comb_leaf->tr_l.tl_mat = (matp_t)bu_malloc(sizeof(mat_t), "tl_mat");
+    }
+    MAT_IDN(comb_leaf->tr_l.tl_mat);
+    if ((dp = db_lookup(dbip, comb_leaf->tr_l.tl_name, LOOKUP_NOISY)) == 
RT_DIR_NULL)
+       return;
+
+    identitize(dp, dbip, msg);
+}
+
+
+extern "C" {
+#ifdef GED_PLUGIN
+#include "../include/plugin.h"
+struct ged_cmd_impl npush_cmd_impl = {
+    "npush",
+    ged_npush_core,
+    GED_CMD_DEFAULT
+};
+
+const struct ged_cmd npush_cmd = { &npush_cmd_impl };
+const struct ged_cmd *npush_cmds[] = { &npush_cmd, NULL };
+
+static const struct ged_plugin pinfo = { GED_API,  npush_cmds, 1 };
+
+COMPILER_DLLEXPORT const struct ged_plugin *ged_plugin_info()
+{
+    return &pinfo;
+}
+#endif /* GED_PLUGIN */
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-file-style: "stroustrup"
+ * End:
+ * ex: shiftwidth=4 tabstop=8
+ */


Property changes on: brlcad/trunk/src/libged/npush/npush.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
Modified: brlcad/trunk/src/libged/xpush/xpush.c
===================================================================
--- brlcad/trunk/src/libged/xpush/xpush.c       2021-01-07 14:04:33 UTC (rev 
78050)
+++ brlcad/trunk/src/libged/xpush/xpush.c       2021-01-07 15:27:12 UTC (rev 
78051)
@@ -260,6 +260,12 @@
 
     RT_CK_DIR(dp);
 
+    /*
+    struct rt_i *rtip = rt_new_rti(gedp->ged_wdbp->dbip);
+    if (rt_gettree(rtip, dp->d_namep) < 0) return NULL;
+    rt_free_rti(rtip);
+    */
+
     if (!(dp->d_flags & RT_DIR_SOLID)) {
        bu_vls_printf(gedp->ged_result_str, "Copy_solid: %s is not a 
solid!!!!\n", dp->d_namep);
        return RT_DIR_NULL;
@@ -416,9 +422,6 @@
 
 static struct directory *Copy_object(struct ged *gedp, struct directory *dp, 
fastf_t *xform);
 
-static void Do_ref_incr(struct db_i *dbip, struct rt_comb_internal *comb, 
union tree *comb_leaf, void *user_ptr1, void *user_ptr2, void *user_ptr3, void 
*UNUSED(user_ptr4));
-
-
 int
 ged_xpush_core(struct ged *gedp, int argc, const char *argv[])
 {

Modified: brlcad/trunk/src/libtclcad/commands.c
===================================================================
--- brlcad/trunk/src/libtclcad/commands.c       2021-01-07 14:04:33 UTC (rev 
78050)
+++ brlcad/trunk/src/libtclcad/commands.c       2021-01-07 15:27:12 UTC (rev 
78051)
@@ -707,6 +707,7 @@
     {"nmg_collapse",   (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_nmg_collapse},
     {"nmg_fix_normals",        (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_nmg_fix_normals},
     {"nmg_simplify",   (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_nmg_simplify},
+    {"npush",  (char *)0, TO_UNLIMITED, to_pass_through_func, ged_npush},
     {"ocenter",        (char *)0, TO_UNLIMITED, to_pass_through_func, 
ged_ocenter},
     {"open",   (char *)0, TO_UNLIMITED, to_pass_through_and_refresh_func, 
ged_reopen},
     {"orient", "quat", 6, to_view_func_plus, ged_orient},

Modified: brlcad/trunk/src/mged/setup.c
===================================================================
--- brlcad/trunk/src/mged/setup.c       2021-01-07 14:04:33 UTC (rev 78050)
+++ brlcad/trunk/src/mged/setup.c       2021-01-07 15:27:12 UTC (rev 78051)
@@ -235,6 +235,7 @@
     {"nmg_fix_normals", cmd_ged_plain_wrapper, ged_nmg_fix_normals},
     {"nmg_simplify", cmd_ged_plain_wrapper, ged_nmg_simplify},
     {"nmg", cmd_ged_plain_wrapper, ged_nmg},
+    {"npush", cmd_ged_plain_wrapper, ged_npush},
     {"o_rotate", f_be_o_rotate, GED_FUNC_PTR_NULL},
     {"o_scale", f_be_o_scale, GED_FUNC_PTR_NULL},
     {"oed", cmd_oed, GED_FUNC_PTR_NULL},

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