diff options
author | Jacques Lucke <jacques@blender.org> | 2022-04-21 16:10:07 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-04-21 16:10:07 +0300 |
commit | 0178e694b72d32ee9805b2f854d1dc4cc46d481f (patch) | |
tree | 73a06b5bcc499d40710a4cf6a4b76b0487f9f0bb /source/blender/modifiers | |
parent | ed971a19fad4ce0c8b81dc4613336eff9322bd20 (diff) |
Geometry Nodes: show used named attributes in modifier
This adds a new subpanel to the geometry nodes modifier which is just
used to display information about used attributes.
* A new panel is used because adding this information anywhere else
clutters the ui too much imo.
* The general layout is similar to that in the tooltip. I found it to be more
trouble than it's worth to share this code.
Possible future improvements:
* Don't show the panel if there are no used named attributes.
* Add some heuristics to determine which named attributes the user does
not have to care about because they are only used in the node group
and don't affect anything else.
Differential Revision: https://developer.blender.org/D14701
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/intern/MOD_nodes.cc | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 7545bae43b3..b904a23eb58 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -119,6 +119,7 @@ using blender::threading::EnumerableThreadSpecific; using namespace blender::fn::multi_function_types; using namespace blender::nodes::derived_node_tree_types; using geo_log::GeometryAttributeInfo; +using geo_log::NamedAttributeUsage; static void initData(ModifierData *md) { @@ -1619,6 +1620,71 @@ static void output_attribute_panel_draw(const bContext *C, Panel *panel) } } +static void used_attributes_panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); + NodesModifierData *nmd = static_cast<NodesModifierData *>(ptr->data); + + if (nmd->runtime_eval_log == nullptr) { + return; + } + const geo_log::ModifierLog &log = *static_cast<geo_log::ModifierLog *>(nmd->runtime_eval_log); + Map<std::string, NamedAttributeUsage> usage_by_attribute; + log.foreach_node_log([&](const geo_log::NodeLog &node_log) { + for (const geo_log::UsedNamedAttribute &used_attribute : node_log.used_named_attributes()) { + usage_by_attribute.lookup_or_add_as(used_attribute.name, + used_attribute.usage) |= used_attribute.usage; + } + }); + + if (usage_by_attribute.is_empty()) { + uiItemL(layout, IFACE_("No named attributes used"), ICON_INFO); + return; + } + + Vector<std::pair<StringRefNull, NamedAttributeUsage>> sorted_used_attribute; + for (auto &&item : usage_by_attribute.items()) { + sorted_used_attribute.append({item.key, item.value}); + } + std::sort(sorted_used_attribute.begin(), sorted_used_attribute.end()); + + for (const auto &pair : sorted_used_attribute) { + const StringRefNull attribute_name = pair.first; + const NamedAttributeUsage usage = pair.second; + + /* #uiLayoutRowWithHeading doesn't seem to work in this case. */ + uiLayout *split = uiLayoutSplit(layout, 0.4f, false); + + std::stringstream ss; + Vector<std::string> usages; + if ((usage & NamedAttributeUsage::Read) != NamedAttributeUsage::None) { + usages.append(TIP_("Read")); + } + if ((usage & NamedAttributeUsage::Write) != NamedAttributeUsage::None) { + usages.append(TIP_("Write")); + } + if ((usage & NamedAttributeUsage::Remove) != NamedAttributeUsage::None) { + usages.append(TIP_("Remove")); + } + for (const int i : usages.index_range()) { + ss << usages[i]; + if (i < usages.size() - 1) { + ss << ", "; + } + } + + uiLayout *row = uiLayoutRow(split, false); + uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); + uiLayoutSetActive(row, false); + uiItemL(row, ss.str().c_str(), ICON_NONE); + + row = uiLayoutRow(split, false); + uiItemL(row, attribute_name.c_str(), ICON_NONE); + } +} + static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Nodes, panel_draw); @@ -1628,6 +1694,12 @@ static void panelRegister(ARegionType *region_type) nullptr, output_attribute_panel_draw, panel_type); + modifier_subpanel_register(region_type, + "used_attributes", + N_("Used Attributes"), + nullptr, + used_attributes_panel_draw, + panel_type); } static void blendWrite(BlendWriter *writer, const ModifierData *md) |