Revision: 78133
http://sourceforge.net/p/brlcad/code/78133
Author: starseeker
Date: 2021-01-27 17:43:45 +0000 (Wed, 27 Jan 2021)
Log Message:
-----------
Do write operations on a separate copy of the tree. This may not be necessary,
but until I can prove overwriting data mid-walk can never cause a problem go
with the safer option.
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-27 03:02:06 UTC (rev
78132)
+++ brlcad/trunk/src/libged/npush/npush.cpp 2021-01-27 17:43:45 UTC (rev
78133)
@@ -354,7 +354,7 @@
} else {
MAT_IDN(nm);
}
- bn_mat_mul(*curr_mat, om, nm);
+ bn_mat_mul(*curr_mat, om, nm);
if (s->verbosity > 2) {
if (tp->tr_l.tl_mat && !bn_mat_is_equal(*curr_mat,
bn_mat_identity, s->tol)) {
@@ -502,6 +502,7 @@
write_walk_subtree(
const dp_i &parent_dpi,
union tree *tp,
+ union tree *wtp,
int depth,
mat_t *curr_mat,
bool *tree_altered,
@@ -509,10 +510,9 @@
{
struct directory *dp;
struct push_state *s = (struct push_state *)client_data;
+ std::set<dp_i>::iterator dpii, i_it;
mat_t om, nm;
- std::set<dp_i>::iterator dpii;
dp_i ldpi;
- std::set<dp_i>::iterator i_it;
if (!tp)
return;
@@ -569,25 +569,32 @@
}
}
+ /* Tree editing operations - form the tree that will be used in the
final
+ * output of this comb object. These operations should use the
writable
+ * tree (wtp) to ensure we don't cause any inadvertent issues with
the
+ * tree walk. (If it can be proven that this can never happen we
could
+ * edit directly on the original tp, but until that's certain
working on
+ * a copy of the tree is safer. */
+
// Comb tree edit: if this is a push leaf, set final matrix, else
// set IDN and keep walking down.
if (dpii->is_leaf && !dpii->apply_to_solid) {
- if (tp->tr_l.tl_mat) {
- if (!bn_mat_is_equal(tp->tr_l.tl_mat, dpii->mat, s->tol)) {
- MAT_COPY(tp->tr_l.tl_mat, dpii->mat);
+ if (wtp->tr_l.tl_mat) {
+ if (!bn_mat_is_equal(wtp->tr_l.tl_mat, dpii->mat, s->tol)) {
+ MAT_COPY(wtp->tr_l.tl_mat, dpii->mat);
(*tree_altered) = true;
}
} else {
if (!bn_mat_is_identity(dpii->mat)) {
- tp->tr_l.tl_mat = bn_mat_dup(dpii->mat);
+ wtp->tr_l.tl_mat = bn_mat_dup(dpii->mat);
(*tree_altered) = true;
}
}
} else {
- if (tp->tr_l.tl_mat) {
+ if (wtp->tr_l.tl_mat) {
// IDN matrix
- bu_free(tp->tr_l.tl_mat, "free mat");
- tp->tr_l.tl_mat = NULL;
+ bu_free(wtp->tr_l.tl_mat, "free mat");
+ wtp->tr_l.tl_mat = NULL;
(*tree_altered) = true;
}
}
@@ -594,8 +601,8 @@
// Comb tree edit: if we have an iname, update the tree name.
if (dpii->iname.length()) {
- bu_free(tp->tr_l.tl_name, "free old name");
- tp->tr_l.tl_name = bu_strdup(dpii->iname.c_str());
+ bu_free(wtp->tr_l.tl_name, "free old name");
+ wtp->tr_l.tl_name = bu_strdup(dpii->iname.c_str());
(*tree_altered) = true;
}
@@ -610,8 +617,8 @@
case OP_INTERSECT:
case OP_SUBTRACT:
case OP_XOR:
- write_walk_subtree(parent_dpi, tp->tr_b.tb_left, depth, curr_mat,
tree_altered, client_data);
- write_walk_subtree(parent_dpi, tp->tr_b.tb_right, depth, curr_mat,
tree_altered, client_data);
+ write_walk_subtree(parent_dpi, tp->tr_b.tb_left, wtp->tr_b.tb_left,
depth, curr_mat, tree_altered, client_data);
+ write_walk_subtree(parent_dpi, tp->tr_b.tb_right,
wtp->tr_b.tb_right, depth, curr_mat, tree_altered, client_data);
break;
default:
bu_log("write_walk_subtree: unrecognized operator %d\n", tp->tr_op);
@@ -637,19 +644,30 @@
bu_log("comb walk: %s\n", dpi.dp->d_namep);
}
- struct rt_db_internal *in;
+ /* Read only copy of comb tree - use for steering the walk */
+ struct rt_db_internal intern;
struct rt_comb_internal *comb;
bool tree_altered = false;
+ if (rt_db_get_internal5(&intern, dpi.dp, s->wdbp->dbip, NULL,
&rt_uniresource) < 0) {
+ return;
+ }
+ comb = (struct rt_comb_internal *)intern.idb_ptr;
+
+ /* Copy of comb tree for editing - use for recording new tree */
+ struct rt_db_internal *in;
+ struct rt_comb_internal *wcomb;
BU_GET(in, struct rt_db_internal);
-
if (rt_db_get_internal5(in, dpi.dp, s->wdbp->dbip, NULL,
&rt_uniresource) < 0) {
BU_PUT(in, struct rt_db_internal);
return;
}
+ wcomb = (struct rt_comb_internal *)in->idb_ptr;
- comb = (struct rt_comb_internal *)in->idb_ptr;
- write_walk_subtree(dpi, comb->tree, depth + 1, curr_mat, &tree_altered,
client_data);
+ write_walk_subtree(dpi, comb->tree, wcomb->tree, depth + 1, curr_mat,
&tree_altered, client_data);
+ // Read-only copy is done
+ rt_db_free_internal(&intern);
+
// If we didn't alter this comb tree, we're done.
if (!tree_altered) {
bu_log("unaltered\n");
@@ -742,7 +760,7 @@
dp = dpi.dp;
}
-
+
if (!s->dry_run) {
if (rt_db_put_internal(dp, s->wdbp->dbip, &intern,
s->wdbp->wdb_resp) < 0) {
bu_log("Unable to store %s to the database", dp->d_namep);
@@ -789,7 +807,7 @@
BU_OPT(d[6], "s", "solids", "", NULL, &to_solids, "Halt
push at solids (matrix will be above solid reference)");
BU_OPT(d[7], "d", "max-depth", "", &bu_opt_int, &max_depth, "Halt at
depth # from tree root (matrix will be above item # layers deep)");
BU_OPT(d[8], "L", "local", "", NULL, &local_changes_only, "Ensure
push operations do not impact geometry outside the specified trees.");
- BU_OPT(d[8], "D", "dry-run", "", NULL, &dry_run, "Calculate the
changes but do not apply them.");
+ BU_OPT(d[9], "D", "dry-run", "", NULL, &dry_run, "Calculate the
changes but do not apply them.");
BU_OPT_NULL(d[10]);
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