Geometry Nodes: support customizing warning propagation
Previously, all errors, warnings and info messages were propagated from the node that generates it to the top level node group. This is a good default, but may not always be desirable. For example, someone may build a node group asset that generates some warning that is irrelevant to the user to the asset. Now, the asset author can selectively disable propagating warnings from that node. Each node has a new `Warning Propagation` setting. It controls if warnings from this node should be propagated to the parent group node. By default, everything is propagated. One can also choose to propagate nothing, only errors or only errors and warnings. Note, this does not affect whether the warning is shown in the node itself, only if the warning is propagated one level up! Pull Request: https://projects.blender.org/blender/blender/pulls/126786
This commit is contained in:
@@ -689,10 +689,17 @@ class NODE_PT_active_node_generic(Panel):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
node = context.active_node
|
||||
tree = node.id_data
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
layout.prop(node, "name", icon='NODE')
|
||||
layout.prop(node, "label", icon='NODE')
|
||||
|
||||
if tree.type == "GEOMETRY":
|
||||
layout.prop(node, "warning_propagation")
|
||||
|
||||
|
||||
class NODE_PT_active_node_color(Panel):
|
||||
bl_space_type = 'NODE_EDITOR'
|
||||
|
||||
@@ -571,7 +571,7 @@ static int run_node_group_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
geo_log::GeoTreeLog &tree_log = eval_log.log->get_tree_log(compute_context.hash());
|
||||
tree_log.ensure_node_warnings();
|
||||
tree_log.ensure_node_warnings(node_tree);
|
||||
for (const geo_log::NodeWarning &warning : tree_log.all_warnings) {
|
||||
if (warning.type == geo_log::NodeWarningType::Info) {
|
||||
BKE_report(op->reports, RPT_INFO, warning.message.c_str());
|
||||
|
||||
@@ -4773,7 +4773,7 @@ static void draw_nodetree(const bContext &C,
|
||||
tree_draw_ctx.geo_log_by_zone = geo_log::GeoModifierLog::get_tree_log_by_zone_for_node_editor(
|
||||
*snode);
|
||||
for (geo_log::GeoTreeLog *log : tree_draw_ctx.geo_log_by_zone.values()) {
|
||||
log->ensure_node_warnings();
|
||||
log->ensure_node_warnings(&ntree);
|
||||
log->ensure_node_run_time();
|
||||
}
|
||||
const WorkSpace *workspace = CTX_wm_workspace(&C);
|
||||
|
||||
@@ -348,6 +348,13 @@ typedef struct bNodePanelState {
|
||||
#endif
|
||||
} bNodePanelState;
|
||||
|
||||
typedef enum NodeWarningPropagation {
|
||||
NODE_WARNING_PROPAGATION_ALL = 0,
|
||||
NODE_WARNING_PROPAGATION_NONE = 1,
|
||||
NODE_WARNING_PROPAGATION_ONLY_ERRORS = 2,
|
||||
NODE_WARNING_PROPAGATION_ONLY_ERRORS_AND_WARNINGS = 3,
|
||||
} NodeWarningPropagation;
|
||||
|
||||
typedef struct bNode {
|
||||
struct bNode *next, *prev;
|
||||
|
||||
@@ -394,6 +401,12 @@ typedef struct bNode {
|
||||
int16_t custom1, custom2;
|
||||
float custom3, custom4;
|
||||
|
||||
/**
|
||||
* #NodeWarningPropagation.
|
||||
*/
|
||||
int8_t warning_propagation;
|
||||
char _pad[7];
|
||||
|
||||
/**
|
||||
* Optional link to libdata.
|
||||
*
|
||||
|
||||
@@ -10299,6 +10299,18 @@ static void rna_def_node(BlenderRNA *brna)
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem warning_propagation_items[] = {
|
||||
{NODE_WARNING_PROPAGATION_ALL, "ALL", 0, "All", ""},
|
||||
{NODE_WARNING_PROPAGATION_NONE, "NONE", 0, "None", ""},
|
||||
{NODE_WARNING_PROPAGATION_ONLY_ERRORS, "ERRORS", 0, "Errors", ""},
|
||||
{NODE_WARNING_PROPAGATION_ONLY_ERRORS_AND_WARNINGS,
|
||||
"ERRORS_AND_WARNINGS",
|
||||
0,
|
||||
"Errors and Warnings",
|
||||
""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Node", nullptr);
|
||||
RNA_def_struct_ui_text(srna, "Node", "Node in a node tree");
|
||||
RNA_def_struct_sdna(srna, "bNode");
|
||||
@@ -10411,6 +10423,14 @@ static void rna_def_node(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "Node");
|
||||
RNA_def_property_ui_text(prop, "Parent", "Parent this node is attached to");
|
||||
|
||||
prop = RNA_def_property(srna, "warning_propagation", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, warning_propagation_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Warning Propagation",
|
||||
"The kinds of messages that should be propagated from this node to the parent group node");
|
||||
RNA_def_property_update(prop, 0, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "use_custom_color", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "flag", NODE_CUSTOM_COLOR);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
||||
@@ -2341,7 +2341,7 @@ static void panel_draw(const bContext *C, Panel *panel)
|
||||
/* Draw node warnings. */
|
||||
geo_log::GeoTreeLog *tree_log = get_root_tree_log(*nmd);
|
||||
if (tree_log != nullptr) {
|
||||
tree_log->ensure_node_warnings();
|
||||
tree_log->ensure_node_warnings(nmd->node_group);
|
||||
for (const geo_log::NodeWarning &warning : tree_log->all_warnings) {
|
||||
if (warning.type != geo_log::NodeWarningType::Info) {
|
||||
uiItemL(layout,
|
||||
|
||||
@@ -313,7 +313,7 @@ class GeoTreeLog {
|
||||
GeoTreeLog(GeoModifierLog *modifier_log, Vector<GeoTreeLogger *> tree_loggers);
|
||||
~GeoTreeLog();
|
||||
|
||||
void ensure_node_warnings();
|
||||
void ensure_node_warnings(const bNodeTree *tree);
|
||||
void ensure_node_run_time();
|
||||
void ensure_socket_values();
|
||||
void ensure_viewer_node_logs();
|
||||
|
||||
@@ -266,15 +266,41 @@ void GeoTreeLogger::log_viewer_node(const bNode &viewer_node, bke::GeometrySet g
|
||||
this->viewer_node_logs.append(*this->allocator, {viewer_node.identifier, std::move(log)});
|
||||
}
|
||||
|
||||
void GeoTreeLog::ensure_node_warnings()
|
||||
static bool warning_is_propagated(const NodeWarningPropagation propagation,
|
||||
const NodeWarningType warning_type)
|
||||
{
|
||||
switch (propagation) {
|
||||
case NODE_WARNING_PROPAGATION_ALL:
|
||||
return true;
|
||||
case NODE_WARNING_PROPAGATION_NONE:
|
||||
return false;
|
||||
case NODE_WARNING_PROPAGATION_ONLY_ERRORS:
|
||||
return warning_type == NodeWarningType::Error;
|
||||
case NODE_WARNING_PROPAGATION_ONLY_ERRORS_AND_WARNINGS:
|
||||
return ELEM(warning_type, NodeWarningType::Error, NodeWarningType::Warning);
|
||||
}
|
||||
BLI_assert_unreachable();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GeoTreeLog::ensure_node_warnings(const bNodeTree *tree)
|
||||
{
|
||||
if (reduced_node_warnings_) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (GeoTreeLogger *tree_logger : tree_loggers_) {
|
||||
for (const GeoTreeLogger::WarningWithNode &warnings : tree_logger->node_warnings) {
|
||||
this->nodes.lookup_or_add_default(warnings.node_id).warnings.add(warnings.warning);
|
||||
this->all_warnings.add(warnings.warning);
|
||||
for (const GeoTreeLogger::WarningWithNode &warning : tree_logger->node_warnings) {
|
||||
NodeWarningPropagation propagation = NODE_WARNING_PROPAGATION_ALL;
|
||||
if (tree) {
|
||||
if (const bNode *node = tree->node_by_id(warning.node_id)) {
|
||||
propagation = NodeWarningPropagation(node->warning_propagation);
|
||||
}
|
||||
}
|
||||
this->nodes.lookup_or_add_default(warning.node_id).warnings.add(warning.warning);
|
||||
if (warning_is_propagated(propagation, warning.warning.type)) {
|
||||
this->all_warnings.add(warning.warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const ComputeContextHash &child_hash : children_hashes_) {
|
||||
@@ -282,13 +308,31 @@ void GeoTreeLog::ensure_node_warnings()
|
||||
if (child_log.tree_loggers_.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
child_log.ensure_node_warnings();
|
||||
NodeWarningPropagation propagation = NODE_WARNING_PROPAGATION_ALL;
|
||||
const bNodeTree *child_tree = nullptr;
|
||||
const std::optional<int32_t> &parent_node_id = child_log.tree_loggers_[0]->parent_node_id;
|
||||
if (tree && parent_node_id) {
|
||||
if (const bNode *node = tree->node_by_id(*parent_node_id)) {
|
||||
propagation = NodeWarningPropagation(node->warning_propagation);
|
||||
if (node->is_group() && node->id) {
|
||||
child_tree = reinterpret_cast<const bNodeTree *>(node->id);
|
||||
}
|
||||
else if (bke::all_zone_output_node_types().contains(node->type)) {
|
||||
child_tree = tree;
|
||||
}
|
||||
}
|
||||
}
|
||||
child_log.ensure_node_warnings(child_tree);
|
||||
if (parent_node_id.has_value()) {
|
||||
this->nodes.lookup_or_add_default(*parent_node_id)
|
||||
.warnings.add_multiple(child_log.all_warnings);
|
||||
}
|
||||
this->all_warnings.add_multiple(child_log.all_warnings);
|
||||
for (const NodeWarning &warning : child_log.all_warnings) {
|
||||
if (warning_is_propagated(propagation, warning.type)) {
|
||||
this->all_warnings.add(warning);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
reduced_node_warnings_ = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user