Revision: 78121
http://sourceforge.net/p/brlcad/code/78121
Author: starseeker
Date: 2021-01-25 21:08:51 +0000 (Mon, 25 Jan 2021)
Log Message:
-----------
Various adjustments for shallower nesting of code.
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-25 20:43:17 UTC (rev
78120)
+++ brlcad/trunk/src/libged/npush/npush.cpp 2021-01-25 21:08:51 UTC (rev
78121)
@@ -144,15 +144,13 @@
}
};
-/* Container to hold information during tree walk. To generate names (or
- * recognize when a push would create a conflict) we keep track of how many
- * times we have encountered each dp during processing. */
+/* Container to hold information during tree walk. */
struct push_state {
/* Variables used for initial validity checking of specified push
- * object(s). target_objects are user specified - if objects are
- * specified that are below other target objects, flag valid_push
- * is set to false. */
+ * object(s). The target_objects set is user specified - if objects are
+ * specified that are below other target objects, flag valid_push is set to
+ * false and the user gets an error report. */
bool valid_push = true;
std::set<std::string> target_objs;
@@ -161,11 +159,15 @@
bool stop_at_regions = false;
bool stop_at_shapes = false;
- /* Containers for instance structures being
- * built up during the push walk. */
+ /* Containers for instance structures being built up during the push walk.
+ * We do not need to duplicate these - the combination of matrix and dp
+ * uniquely identifies a volume in space - so the C++ set container is used
+ * to ensure we end up with the set of just unique dp instances after tree
+ * walking. */
std::set<dp_i> instances;
- /* Tolerance to be used for matrix comparisons */
+ /* Tolerance to be used for matrix comparisons. Typically comes from the
+ * database tolerances. */
const struct bn_tol *tol;
/* Debugging related data and variables */
@@ -739,20 +741,21 @@
// Do a preliminary walk down the push objects to determine what impact the
// push operations would have on the comb trees and solids.
mat_t m;
- MAT_IDN(m);
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 && (dp->d_flags & RT_DIR_COMB)) {
+ MAT_IDN(m);
push_walk(dbip, dp, 0, &m, false, &s);
+
+ /* Sanity - if we didn't end up with m back at the identity matrix,
+ * something went wrong with the walk */
+ if (!bn_mat_is_equal(m, bn_mat_identity, &gedp->ged_wdbp->wdb_tol))
{
+ bu_vls_sprintf(gedp->ged_result_str, "Error - initial tree walk
down %s finished with non-IDN matrix.\n", dp->d_namep);
+ return GED_ERROR;
+ }
}
}
- /* Sanity - if we didn't end up with m back at the identity matrix,
- * something went wrong with the walk */
- if (!bn_mat_is_equal(m, bn_mat_identity, &gedp->ged_wdbp->wdb_tol)) {
- bu_vls_sprintf(gedp->ged_result_str, "Error - initial tree walk
finished with non-IDN matrix.\n");
- return GED_ERROR;
- }
if (local_changes_only) {
/* Because pushes have potentially global consequences, we provide an
@@ -776,10 +779,10 @@
std::vector<dp_i> uniq_instances(s.instances.size());
std::copy(s.instances.begin(), s.instances.end(), uniq_instances.begin());
- // Iterate over unique instances and count how many instances of each dp
- // are present. Any dp with multiple associated instances can't be pushed
- // without a copy being made, as the unique dp instances represent multiple
- // distinct volumes in space.
+ // Iterate over unique instances and build sets of indices to instances
+ // sharing a common directory pointer. Any dp with multiple associated
+ // instances can't be pushed without a copy being made, as the unique dp
+ // instances represent multiple distinct volumes in space.
std::map<struct directory *, std::vector<size_t>> i_cnt;
for (size_t i = 0; i < uniq_instances.size(); i++) {
i_cnt[uniq_instances[i].dp].push_back(i);
@@ -792,56 +795,67 @@
struct bu_vls msgs = BU_VLS_INIT_ZERO;
for (size_t i = 0; i < uniq_instances.size(); i++) {
const dp_i &dpi = uniq_instances[i];
- if (dpi.push_obj) {
- if (i_cnt[dpi.dp].size() > 1) {
- // This is the condition where xpush is needed - we can't
- // proceed.
- conflict = true;
+ // If we're not looking at a push object, or the dp mapping is
+ // unique, we don't need a force push for this case.
+ if (!dpi.push_obj || i_cnt[dpi.dp].size() < 2) {
+ continue;
+ }
- // If we're not being verbose, the first failure means we
- // can just immediately bail.
- if (!verbosity) {
- bu_vls_printf(gedp->ged_result_str, "Operation failed -
force not enabled and one or more solids are being moved in conflicting
directions by multiple comb instances.");
- return GED_ERROR;
- }
- }
+ // Push object with multiple mappings - this is the condition where
+ // xpush is needed. Since force is not enabled, we can't proceed.
+ conflict = true;
+
+ // If we're not being verbose, the first failure means we can just
+ // immediately bail.
+ if (!verbosity) {
+ bu_vls_printf(gedp->ged_result_str, "Operation failed - force
not enabled and one or more solids are being moved in conflicting directions by
multiple comb instances.");
+ return GED_ERROR;
}
}
if (conflict) {
+ // If we haven't already bailed, verbosity settings indicate the
user
+ // will want more information about the precise nature of the
failure.
std::set<struct directory *> reported;
for (size_t i = 0; i < uniq_instances.size(); i++) {
const dp_i &dpi = uniq_instances[i];
- if (dpi.push_obj) {
- if (i_cnt[dpi.dp].size() > 1) {
- if (reported.find(dpi.dp) != reported.end())
- continue;
- reported.insert(dpi.dp);
- if (s.verbosity > 1) {
- bu_vls_printf(&msgs, "Conflicting instances found:
%s->%s:\n", dpi.parent_dp->d_namep, dpi.dp->d_namep);
+ // If not a problem case, skip
+ if (!dpi.push_obj || i_cnt[dpi.dp].size() < 2) {
+ continue;
+ }
+
+ // If we have already reported on this dp's conflicts, skip
+ if (reported.find(dpi.dp) != reported.end())
+ continue;
+
+ // Reporting - mark so we don't repeat later
+ reported.insert(dpi.dp);
+
+ // Handle various verbosity settings
+ if (s.verbosity > 1) {
+ bu_vls_printf(&msgs, "Conflicting instances found:
%s->%s:\n", dpi.parent_dp->d_namep, dpi.dp->d_namep);
+ } else {
+ bu_vls_printf(&msgs, "Conflicting instances found:
%s->%s\n", dpi.parent_dp->d_namep, dpi.dp->d_namep);
+ }
+ // Itemize the instances causing the failure (potentially quite
+ // verbose, so require a higher verbosity setting for this...)
+ if (s.verbosity > 1) {
+ for (size_t j = 0; j < i_cnt[dpi.dp].size(); j++) {
+ const dp_i &dpc = uniq_instances[i_cnt[dpi.dp][j]];
+ struct bu_vls imat = BU_VLS_INIT_ZERO;
+ struct bu_vls ititle = BU_VLS_INIT_ZERO;
+ const char *title0 = "Initial instance";
+ if (j == 0) {
+ bu_vls_printf(&ititle, "%s", title0);
} else {
- bu_vls_printf(&msgs, "Conflicting instances found:
%s->%s\n", dpi.parent_dp->d_namep, dpi.dp->d_namep);
+ bu_vls_printf(&ititle, "Conflicting Instance #%zd",
j);
}
- if (s.verbosity > 1) {
- // If verbosity is high enough, itemize the
instances causing the failure
- for (size_t j = 0; j < i_cnt[dpi.dp].size(); j++) {
- const dp_i &dpc =
uniq_instances[i_cnt[dpi.dp][j]];
- struct bu_vls imat = BU_VLS_INIT_ZERO;
- struct bu_vls ititle = BU_VLS_INIT_ZERO;
- const char *title0 = "Initial instance";
- if (j == 0) {
- bu_vls_printf(&ititle, "%s", title0);
- } else {
- bu_vls_printf(&ititle, "Conflicting
Instance #%zd", j);
- }
- if (!dpc.push_obj) {
- bu_vls_printf(&ititle, " (non-local)");
- }
- bn_mat_print_vls(bu_vls_cstr(&ititle), dpc.mat,
&imat);
- bu_vls_printf(&msgs, "%s", bu_vls_cstr(&imat));
- bu_vls_free(&imat);
- }
+ if (!dpc.push_obj) {
+ bu_vls_printf(&ititle, " (non-local)");
}
+ bn_mat_print_vls(bu_vls_cstr(&ititle), dpc.mat, &imat);
+ bu_vls_printf(&msgs, "%s", bu_vls_cstr(&imat));
+ bu_vls_free(&imat);
}
}
}
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