[Bf-blender-cvs] [62bd391187c] temp-enum-socket: improved inferencing
Jacques Lucke
noreply at git.blender.org
Mon Nov 8 16:07:04 CET 2021
Commit: 62bd391187c6b33734e94f3d8fe458ab77fcd682
Author: Jacques Lucke
Date: Mon Nov 8 13:51:57 2021 +0100
Branches: temp-enum-socket
https://developer.blender.org/rB62bd391187c6b33734e94f3d8fe458ab77fcd682
improved inferencing
===================================================================
M source/blender/blenkernel/intern/node.cc
M source/blender/makesdna/DNA_node_types.h
M source/blender/makesrna/intern/rna_nodetree.c
M source/blender/nodes/NOD_socket_declarations.hh
M source/blender/nodes/function/nodes/node_fn_enum.cc
M source/blender/nodes/intern/node_socket_declarations.cc
===================================================================
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 86b01991165..f345e7a604e 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -131,10 +131,6 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree),
static void nodeMuteRerouteOutputLinks(struct bNodeTree *ntree,
struct bNode *node,
const bool mute);
-static FieldInferencingInterface *node_field_inferencing_interface_copy(
- const FieldInferencingInterface &field_inferencing_interface);
-static void node_field_inferencing_interface_free(
- const FieldInferencingInterface *field_inferencing_interface);
static void ntree_init_data(ID *id)
{
@@ -247,9 +243,13 @@ static void ntree_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, c
ntree_dst->interface_type = nullptr;
if (ntree_src->field_inferencing_interface) {
- ntree_dst->field_inferencing_interface = node_field_inferencing_interface_copy(
+ ntree_dst->field_inferencing_interface = new blender::nodes::FieldInferencingInterface(
*ntree_src->field_inferencing_interface);
}
+ if (ntree_src->enum_inferencing_interface) {
+ ntree_dst->enum_inferencing_interface = new blender::nodes::EnumInferencingInterface(
+ *ntree_src->enum_inferencing_interface);
+ }
if (flag & LIB_ID_COPY_NO_PREVIEW) {
ntree_dst->preview = nullptr;
@@ -302,7 +302,8 @@ static void ntree_free_data(ID *id)
MEM_freeN(sock);
}
- node_field_inferencing_interface_free(ntree->field_inferencing_interface);
+ delete ntree->field_inferencing_interface;
+ delete ntree->enum_inferencing_interface;
/* free preview hash */
if (ntree->previews) {
@@ -4595,18 +4596,6 @@ void ntreeUpdateAllNew(Main *main)
FOREACH_NODETREE_END;
}
-static FieldInferencingInterface *node_field_inferencing_interface_copy(
- const FieldInferencingInterface &field_inferencing_interface)
-{
- return new FieldInferencingInterface(field_inferencing_interface);
-}
-
-static void node_field_inferencing_interface_free(
- const FieldInferencingInterface *field_inferencing_interface)
-{
- delete field_inferencing_interface;
-}
-
namespace blender::bke::node_field_inferencing {
static bool is_field_socket_type(eNodeSocketDatatype type)
@@ -5112,6 +5101,42 @@ static bool update_field_inferencing(const NodeTreeRef &tree)
namespace blender::bke::enum_inferencing {
+using namespace blender::nodes;
+
+static bool update_enum_inferencing(const NodeTreeRef &tree);
+
+static EnumInputInferencingInfo get_input_enum_socket_inferencing_info(
+ const InputSocketRef &socket)
+{
+ BLI_assert(socket.typeinfo()->type == SOCK_ENUM);
+ const NodeRef &node = socket.node();
+ if (node.is_group_node()) {
+ bNodeTree *group = (bNodeTree *)node.bnode()->id;
+ if (group == nullptr) {
+ return {};
+ }
+ if (!ntreeIsRegistered(group)) {
+ return {};
+ }
+ if (group->enum_inferencing_interface == nullptr) {
+ /* Update group recursively. */
+ const NodeTreeRef group_tree{group};
+ update_enum_inferencing(group_tree);
+ }
+ return group->enum_inferencing_interface->inputs[socket.index()];
+ }
+ if (node.is_reroute_node()) {
+ return {};
+ }
+ const decl::Enum &socket_decl = static_cast<const decl::Enum &>(*socket.bsocket()->declaration);
+ return socket_decl.inferencing_info();
+}
+
+struct EnumState {
+ std::shared_ptr<EnumItems> items;
+ int group_output_index = -1;
+};
+
static bool update_enum_inferencing(const NodeTreeRef &tree)
{
using namespace blender::nodes;
@@ -5121,40 +5146,45 @@ static bool update_enum_inferencing(const NodeTreeRef &tree)
const NodeTreeRef::ToposortResult toposort_result = tree.toposort(
NodeTreeRef::ToposortDirection::RightToLeft);
- Map<const SocketRef *, const std::shared_ptr<decl::EnumItems> *> enum_by_socket;
+ Map<const SocketRef *, EnumState> state_by_socket;
for (const NodeRef *node : toposort_result.sorted_nodes) {
bNode &bnode = *node->bnode();
nodeDeclarationEnsure(&btree, &bnode);
- const NodeDeclaration *node_decl = bnode.declaration;
+
+ if (node->is_group_output_node()) {
+ for (const InputSocketRef *input_socket : node->inputs()) {
+ if (input_socket->typeinfo()->type == SOCK_ENUM) {
+ state_by_socket.add(input_socket, EnumState{nullptr, input_socket->index()});
+ }
+ }
+ continue;
+ }
for (const OutputSocketRef *socket : node->outputs()) {
if (socket->typeinfo()->type != SOCK_ENUM) {
continue;
}
/* TODO: Handle case when connected to incompatible enums. */
+ EnumState enum_state;
for (const InputSocketRef *target_socket : socket->directly_linked_sockets()) {
- const std::shared_ptr<decl::EnumItems> *socket_items = enum_by_socket.lookup_default(
- target_socket, nullptr);
- enum_by_socket.add_new(socket, socket_items);
+ enum_state = state_by_socket.lookup(target_socket);
break;
}
+ state_by_socket.add_new(socket, enum_state);
}
for (const InputSocketRef *socket : node->inputs()) {
- const int index = socket->index();
if (socket->typeinfo()->type != SOCK_ENUM) {
continue;
}
- const nodes::decl::Enum &enum_decl = static_cast<const nodes::decl::Enum &>(
- *node_decl->inputs()[index]);
- const std::shared_ptr<decl::EnumItems> &items = enum_decl.items();
- const std::shared_ptr<decl::EnumItems> *socket_items = nullptr;
- if (items) {
- socket_items = &items;
+ EnumInputInferencingInfo inferencing_info = get_input_enum_socket_inferencing_info(*socket);
+ EnumState input_state;
+ if (inferencing_info.items) {
+ input_state.items = inferencing_info.items;
}
else {
- int inference_index = enum_decl.inference_index();
+ int inference_index = inferencing_info.inference_index;
if (inference_index == -1) {
for (const OutputSocketRef *output_socket : node->outputs()) {
if (output_socket->typeinfo()->type == SOCK_ENUM) {
@@ -5165,25 +5195,52 @@ static bool update_enum_inferencing(const NodeTreeRef &tree)
}
BLI_assert(inference_index >= 0);
const OutputSocketRef &output_socket = node->output(inference_index);
- socket_items = enum_by_socket.lookup_default(&output_socket, nullptr);
+ input_state = state_by_socket.lookup(&output_socket);
}
- enum_by_socket.add_new(socket, socket_items);
+ state_by_socket.add_new(socket, input_state);
}
}
- for (const auto item : enum_by_socket.items()) {
+ for (const auto item : state_by_socket.items()) {
const SocketRef *socket = item.key;
- const std::shared_ptr<decl::EnumItems> *socket_items = item.value;
+ const EnumState &state = item.value;
bNodeSocketValueEnum *socket_value = (bNodeSocketValueEnum *)socket->bsocket()->default_value;
- if (socket_items != nullptr) {
- socket_value->items = socket_items->get()->items();
+ if (state.items) {
+ socket_value->items = state.items->items();
}
else {
socket_value->items = nullptr;
}
}
- return false;
+ EnumInferencingInterface *new_inferencing_interface = new EnumInferencingInterface();
+ new_inferencing_interface->inputs.resize(BLI_listbase_count(&btree.inputs));
+
+ for (const NodeRef *node : tree.nodes_by_type("NodeGroupInput")) {
+ for (const OutputSocketRef *output_socket : node->outputs().drop_back(1)) {
+ if (output_socket->typeinfo()->type != SOCK_ENUM) {
+ continue;
+ }
+ const EnumState &state = state_by_socket.lookup(output_socket);
+ EnumInputInferencingInfo &group_input_info =
+ new_inferencing_interface->inputs[output_socket->index()];
+ if (state.items) {
+ group_input_info.items = state.items;
+ }
+ else if (state.group_output_index >= 0) {
+ group_input_info.inference_index = state.group_output_index;
+ }
+ else {
+ group_input_info.items = std::make_shared<EnumItems>();
+ }
+ }
+ }
+
+ delete btree.enum_inferencing_interface;
+ btree.enum_inferencing_interface = new_inferencing_interface;
+
+ /* TODO: Only return true when the interface changed. */
+ return true;
}
} // namespace blender::bke::enum_inferencing
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index cc2b90d93f3..756320d6c40 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -478,10 +478,13 @@ typedef struct bNodeLink {
#ifdef __cplusplus
namespace blender::nodes {
struct FieldInferencingInterface;
-}
+struct EnumInferencingInterface;
+} // namespace blender::nodes
using FieldInferencingInterfaceHandle = blender::nodes::FieldInferencingInterface;
+using EnumInferencingInterfaceHandle = blender::nodes::EnumInferencingInterface;
#else
typedef struct FieldInferencingInterfaceHandle FieldInferencingInterfaceHandle;
+typedef struct EnumInferencingInterfaceHandle EnumInferencingInterfaceHandle;
#endif
/* the basis for a Node tree, all links and nodes reside internal here */
@@ -508,6 +511,7 @@ typedef struct bNodeTree {
ListBase nodes, links;
/** Information about how inputs and outputs of the node group interact with fields. */
FieldInferencingInterfaceHandle *field_inferencing_interface;
+ EnumInferencingInterfaceHandle *enum_inferencing_interface;
/** Set init on fileread. */
int type, init;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 9ea945e91bf..519a070ffee 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -1237,8 +1237,8 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
ntreeTexCheckCyclics(ntree);
}
- ntreeUpdateTree(CTX_data_main(C), ntree);
nodeUpdate(ntree, node);
+ ntreeUpdateTree(CTX_data_main(C), ntree);
WM_main_add_notifier(NC_NODE | NA_ED
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list