Revision: 78080
          http://sourceforge.net/p/brlcad/code/78080
Author:   starseeker
Date:     2021-01-14 19:44:59 +0000 (Thu, 14 Jan 2021)
Log Message:
-----------
Check list of objects against the active trees - don't try to push if an object 
that is below a specified object is also specified.  Particularly if depth 
limitations are specified, I don't know whether this is safe (or guaranteed to 
produce intuitive results) in all cases.

Modified Paths:
--------------
    brlcad/trunk/src/libged/npush/npush.cpp

Modified: brlcad/trunk/src/libged/npush/npush.cpp
===================================================================
--- brlcad/trunk/src/libged/npush/npush.cpp     2021-01-14 18:48:40 UTC (rev 
78079)
+++ brlcad/trunk/src/libged/npush/npush.cpp     2021-01-14 19:44:59 UTC (rev 
78080)
@@ -136,6 +136,8 @@
  * times we have encountered each dp during processing. */
 struct push_state {
     bool survey = false;
+    bool valid_push = true;
+    std::string problem_obj;
     std::set<std::string> target_objs;
     std::set<dp_i> s_i;
     std::map<struct directory *, int> s_c;
@@ -186,6 +188,83 @@
 }
 
 static void
+validate_walk(struct db_i *dbip,
+       struct directory *dp,
+       void *client_data);
+
+static void
+validate_walk_subtree(struct db_i *dbip,
+                   union tree *tp,
+                   void *client_data)
+{
+    struct directory *dp;
+    struct push_state *s = (struct push_state *)client_data;
+
+    if (!tp || !s->valid_push)
+       return;
+
+    RT_CK_TREE(tp);
+
+    switch (tp->tr_op) {
+
+       case OP_DB_LEAF:
+
+           if ((dp=db_lookup(dbip, tp->tr_l.tl_name, LOOKUP_NOISY)) == 
RT_DIR_NULL)
+               return;
+       
+           if (s->target_objs.find(std::string(dp->d_namep)) != 
s->target_objs.end()) {
+               s->valid_push = false;
+               s->problem_obj = std::string(dp->d_namep);
+               return;
+           }
+
+           if (!(dp->d_flags & RT_DIR_COMB)) {
+               return;
+           }
+           validate_walk(dbip, dp, client_data);
+           break;
+
+       case OP_UNION:
+       case OP_INTERSECT:
+       case OP_SUBTRACT:
+       case OP_XOR:
+           validate_walk_subtree(dbip, tp->tr_b.tb_left, client_data);
+           validate_walk_subtree(dbip, tp->tr_b.tb_right, client_data);
+           break;
+       default:
+           bu_log("validate_walk_subtree: unrecognized operator %d\n", 
tp->tr_op);
+           bu_bomb("validate_walk_subtree: unrecognized operator\n");
+    }
+}
+
+static void
+validate_walk(struct db_i *dbip,
+           struct directory *dp,
+           void *client_data)
+{
+    struct push_state *s = (struct push_state *)client_data;
+    RT_CK_DBI(dbip);
+
+    if (!dp || !s->valid_push) {
+       return; /* nothing to do */
+    }
+
+    if (dp->d_flags & RT_DIR_COMB) {
+
+       struct rt_db_internal in;
+       struct rt_comb_internal *comb;
+
+       if (rt_db_get_internal5(&in, dp, dbip, NULL, &rt_uniresource) < 0)
+           return;
+
+       comb = (struct rt_comb_internal *)in.idb_ptr;
+       validate_walk_subtree(dbip, comb->tree, client_data);
+       rt_db_free_internal(&in);
+
+    }
+}
+
+static void
 process_comb(struct db_i *dbip,
        struct directory *dp,
        int depth,
@@ -488,13 +567,23 @@
        s.target_objs.insert(std::string(argv[i]));
     }
 
-    // TODO - either need to validate that no target_obj is underneath another 
target obj,
-    // or fully process the first target obj before moving on to the second.  
Otherwise
+
+    // Validate that no target_obj is underneath another target obj. Otherwise,
     // multiple push operations may collide.
-
     std::set<std::string>::iterator s_it;
     for (s_it = s.target_objs.begin(); s_it != s.target_objs.end(); s_it++) {
        struct directory *dp = db_lookup(dbip, s_it->c_str(), LOOKUP_NOISY);
+       validate_walk(dbip, dp, &s);
+       if (!s.valid_push) {
+           bu_vls_printf(gedp->ged_result_str, "%s has another specified 
target object (%s), below it.", dp->d_namep, s.problem_obj.c_str());
+           return GED_ERROR;
+       }
+    }
+
+    // Do a preliminary walk down the push objects to determine what impact the
+    // push operations would have on the comb trees and solids.
+    for (s_it = s.target_objs.begin(); s_it != s.target_objs.end(); s_it++) {
+       struct directory *dp = db_lookup(dbip, s_it->c_str(), LOOKUP_NOISY);
        if (dp != RT_DIR_NULL)
            push_walk(dbip, dp, 0, &rt_uniresource, 0, &m, &s);
     }

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