This removes the "Geometry" part from their name because we want to use them in other node tree types too (see #141936). Usually, we don't change idnames because they are the primary identifier of nodes and is expected to stay the same. Since they are generally not shown to users (just Python developers), it's also not urgent to change them. However, in this specific case we have the opportunity to update the idname before the node becomes an official feature, so it's not as bad to change it. This patch has full backward compatibility, but no forward compatibility (for files that used the experimental feature). Pull Request: https://projects.blender.org/blender/blender/pulls/143823
130 lines
3.8 KiB
C++
130 lines
3.8 KiB
C++
/* SPDX-FileCopyrightText: 2025 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#include "BKE_node_runtime.hh"
|
|
|
|
#include "NOD_geometry_nodes_closure.hh"
|
|
|
|
namespace blender::nodes {
|
|
|
|
std::optional<int> ClosureSignature::find_input_index(const StringRef key) const
|
|
{
|
|
for (const int i : this->inputs.index_range()) {
|
|
const Item &item = this->inputs[i];
|
|
if (item.key == key) {
|
|
return i;
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
std::optional<int> ClosureSignature::find_output_index(const StringRef key) const
|
|
{
|
|
for (const int i : this->outputs.index_range()) {
|
|
const Item &item = this->outputs[i];
|
|
if (item.key == key) {
|
|
return i;
|
|
}
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
|
|
static bool items_equal(const ClosureSignature::Item &a, const ClosureSignature::Item &b)
|
|
{
|
|
if (a.key != b.key) {
|
|
return false;
|
|
}
|
|
if (a.type != b.type) {
|
|
return false;
|
|
}
|
|
if (a.structure_type.has_value() && b.structure_type.has_value()) {
|
|
if (*a.structure_type != *b.structure_type) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ClosureSignature::matches_exactly(const ClosureSignature &other) const
|
|
{
|
|
if (inputs.size() != other.inputs.size()) {
|
|
return false;
|
|
}
|
|
if (outputs.size() != other.outputs.size()) {
|
|
return false;
|
|
}
|
|
for (const Item &item : inputs) {
|
|
if (std::none_of(other.inputs.begin(), other.inputs.end(), [&](const Item &other_item) {
|
|
return items_equal(item, other_item);
|
|
}))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
for (const Item &item : outputs) {
|
|
if (std::none_of(other.outputs.begin(), other.outputs.end(), [&](const Item &other_item) {
|
|
return items_equal(item, other_item);
|
|
}))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool ClosureSignature::all_matching_exactly(const Span<ClosureSignature> signatures)
|
|
{
|
|
if (signatures.is_empty()) {
|
|
return true;
|
|
}
|
|
for (const ClosureSignature &signature : signatures.drop_front(1)) {
|
|
if (!signatures[0].matches_exactly(signature)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
ClosureSignature ClosureSignature::from_closure_output_node(const bNode &node)
|
|
{
|
|
BLI_assert(node.is_type("NodeClosureOutput"));
|
|
const auto &storage = *static_cast<const NodeClosureOutput *>(node.storage);
|
|
nodes::ClosureSignature signature;
|
|
for (const int i : IndexRange(storage.input_items.items_num)) {
|
|
const NodeClosureInputItem &item = storage.input_items.items[i];
|
|
if (const bke::bNodeSocketType *stype = bke::node_socket_type_find_static(item.socket_type)) {
|
|
signature.inputs.add({item.name, stype});
|
|
}
|
|
}
|
|
for (const int i : IndexRange(storage.output_items.items_num)) {
|
|
const NodeClosureOutputItem &item = storage.output_items.items[i];
|
|
if (const bke::bNodeSocketType *stype = bke::node_socket_type_find_static(item.socket_type)) {
|
|
signature.outputs.add({item.name, stype});
|
|
}
|
|
}
|
|
return signature;
|
|
}
|
|
|
|
ClosureSignature ClosureSignature::from_evaluate_closure_node(const bNode &node)
|
|
{
|
|
BLI_assert(node.is_type("NodeEvaluateClosure"));
|
|
const auto &storage = *static_cast<const NodeEvaluateClosure *>(node.storage);
|
|
nodes::ClosureSignature signature;
|
|
for (const int i : IndexRange(storage.input_items.items_num)) {
|
|
const NodeEvaluateClosureInputItem &item = storage.input_items.items[i];
|
|
if (const bke::bNodeSocketType *stype = bke::node_socket_type_find_static(item.socket_type)) {
|
|
signature.inputs.add({item.name, stype, nodes::StructureType(item.structure_type)});
|
|
}
|
|
}
|
|
for (const int i : IndexRange(storage.output_items.items_num)) {
|
|
const NodeEvaluateClosureOutputItem &item = storage.output_items.items[i];
|
|
if (const bke::bNodeSocketType *stype = bke::node_socket_type_find_static(item.socket_type)) {
|
|
signature.outputs.add({item.name, stype, nodes::StructureType(item.structure_type)});
|
|
}
|
|
}
|
|
return signature;
|
|
}
|
|
|
|
} // namespace blender::nodes
|