Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/intern')
-rw-r--r--source/blender/nodes/intern/geometry_nodes_lazy_function.cc58
-rw-r--r--source/blender/nodes/intern/geometry_nodes_log.cc5
-rw-r--r--source/blender/nodes/intern/node_common.cc150
-rw-r--r--source/blender/nodes/intern/node_socket.cc7
4 files changed, 80 insertions, 140 deletions
diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
index 96c369f2f6b..d9e82c6b4ee 100644
--- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
+++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
@@ -16,6 +16,7 @@
#include "NOD_multi_function.hh"
#include "NOD_node_declaration.hh"
+#include "BLI_cpp_types.hh"
#include "BLI_lazy_threading.hh"
#include "BLI_map.hh"
@@ -53,14 +54,11 @@ static const CPPType *get_socket_cpp_type(const bNodeSocket &socket)
static const CPPType *get_vector_type(const CPPType &type)
{
- /* This could be generalized in the future. For now we only support a small set of vectors. */
- if (type.is<GeometrySet>()) {
- return &CPPType::get<Vector<GeometrySet>>();
- }
- if (type.is<ValueOrField<std::string>>()) {
- return &CPPType::get<Vector<ValueOrField<std::string>>>();
+ const VectorCPPType *vector_type = VectorCPPType::get_from_value(type);
+ if (vector_type == nullptr) {
+ return nullptr;
}
- return nullptr;
+ return &vector_type->self;
}
/**
@@ -296,19 +294,17 @@ static void execute_multi_function_on_value_or_field(
for (const int i : input_types.index_range()) {
const ValueOrFieldCPPType &type = *input_types[i];
- const CPPType &base_type = type.base_type();
const void *value_or_field = input_values[i];
const void *value = type.get_value_ptr(value_or_field);
- params.add_readonly_single_input(GVArray::ForSingleRef(base_type, 1, value));
+ params.add_readonly_single_input(GVArray::ForSingleRef(type.value, 1, value));
}
for (const int i : output_types.index_range()) {
const ValueOrFieldCPPType &type = *output_types[i];
- const CPPType &base_type = type.base_type();
void *value_or_field = output_values[i];
- type.default_construct(value_or_field);
+ type.self.default_construct(value_or_field);
void *value = type.get_value_ptr(value_or_field);
- base_type.destruct(value);
- params.add_uninitialized_single_output(GMutableSpan{base_type, value, 1});
+ type.value.destruct(value);
+ params.add_uninitialized_single_output(GMutableSpan{type.value, value, 1});
}
fn.call(IndexRange(1), params, context);
}
@@ -380,16 +376,14 @@ class LazyFunctionForMutedNode : public LazyFunction {
}
/* Perform a type conversion and then format the value. */
const bke::DataTypeConversions &conversions = bke::get_implicit_type_conversions();
- const auto *from_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&input_type);
- const auto *to_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&output_type);
- if (from_field_type != nullptr && to_field_type != nullptr) {
- const CPPType &from_base_type = from_field_type->base_type();
- const CPPType &to_base_type = to_field_type->base_type();
- if (conversions.is_convertible(from_base_type, to_base_type)) {
+ const auto *from_type = ValueOrFieldCPPType::get_from_self(input_type);
+ const auto *to_type = ValueOrFieldCPPType::get_from_self(output_type);
+ if (from_type != nullptr && to_type != nullptr) {
+ if (conversions.is_convertible(from_type->value, to_type->value)) {
const MultiFunction &multi_fn = *conversions.get_conversion_multi_function(
- MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type));
+ MFDataType::ForSingle(from_type->value), MFDataType::ForSingle(to_type->value));
execute_multi_function_on_value_or_field(
- multi_fn, {}, {from_field_type}, {to_field_type}, {input_value}, {output_value});
+ multi_fn, {}, {from_type}, {to_type}, {input_value}, {output_value});
}
params.output_set(output_i);
continue;
@@ -420,8 +414,8 @@ class LazyFunctionForMultiFunctionConversion : public LazyFunction {
: fn_(fn), from_type_(from), to_type_(to), target_sockets_(std::move(target_sockets))
{
debug_name_ = "Convert";
- inputs_.append({"From", from});
- outputs_.append({"To", to});
+ inputs_.append({"From", from.self});
+ outputs_.append({"To", to.self});
}
void execute_impl(lf::Params &params, const lf::Context & /*context*/) const override
@@ -458,10 +452,10 @@ class LazyFunctionForMultiFunctionNode : public LazyFunction {
debug_name_ = node.name;
lazy_function_interface_from_node(node, r_used_inputs, r_used_outputs, inputs_, outputs_);
for (const lf::Input &fn_input : inputs_) {
- input_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_input.type));
+ input_types_.append(ValueOrFieldCPPType::get_from_self(*fn_input.type));
}
for (const lf::Output &fn_output : outputs_) {
- output_types_.append(dynamic_cast<const ValueOrFieldCPPType *>(fn_output.type));
+ output_types_.append(ValueOrFieldCPPType::get_from_self(*fn_output.type));
}
}
@@ -552,8 +546,7 @@ class LazyFunctionForViewerNode : public LazyFunction {
if (use_field_input_) {
const void *value_or_field = params.try_get_input_data_ptr(1);
BLI_assert(value_or_field != nullptr);
- const ValueOrFieldCPPType &value_or_field_type = static_cast<const ValueOrFieldCPPType &>(
- *inputs_[1].type);
+ const auto &value_or_field_type = *ValueOrFieldCPPType::get_from_self(*inputs_[1].type);
GField field = value_or_field_type.as_field(value_or_field);
const eAttrDomain domain = eAttrDomain(storage->domain);
const StringRefNull viewer_attribute_name = ".viewer";
@@ -1193,14 +1186,13 @@ struct GeometryNodesLazyFunctionGraphBuilder {
if (from_type == to_type) {
return &from_socket;
}
- const auto *from_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&from_type);
- const auto *to_field_type = dynamic_cast<const ValueOrFieldCPPType *>(&to_type);
+ const auto *from_field_type = ValueOrFieldCPPType::get_from_self(from_type);
+ const auto *to_field_type = ValueOrFieldCPPType::get_from_self(to_type);
if (from_field_type != nullptr && to_field_type != nullptr) {
- const CPPType &from_base_type = from_field_type->base_type();
- const CPPType &to_base_type = to_field_type->base_type();
- if (conversions_->is_convertible(from_base_type, to_base_type)) {
+ if (conversions_->is_convertible(from_field_type->value, to_field_type->value)) {
const MultiFunction &multi_fn = *conversions_->get_conversion_multi_function(
- MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type));
+ MFDataType::ForSingle(from_field_type->value),
+ MFDataType::ForSingle(to_field_type->value));
auto fn = std::make_unique<LazyFunctionForMultiFunctionConversion>(
multi_fn, *from_field_type, *to_field_type, std::move(target_sockets));
lf::Node &conversion_node = lf_graph_->add_function(*fn);
diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc
index 0f122307328..640296ead66 100644
--- a/source/blender/nodes/intern/geometry_nodes_log.cc
+++ b/source/blender/nodes/intern/geometry_nodes_log.cc
@@ -166,10 +166,9 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons
const GeometrySet &geometry = *value.get<GeometrySet>();
store_logged_value(this->allocator->construct<GeometryInfoLog>(geometry));
}
- else if (const auto *value_or_field_type = dynamic_cast<const fn::ValueOrFieldCPPType *>(
- &type)) {
+ else if (const auto *value_or_field_type = fn::ValueOrFieldCPPType::get_from_self(type)) {
const void *value_or_field = value.get();
- const CPPType &base_type = value_or_field_type->base_type();
+ const CPPType &base_type = value_or_field_type->value;
if (value_or_field_type->is_field(value_or_field)) {
const GField *field = value_or_field_type->get_field_ptr(value_or_field);
if (field->node().depends_on_input()) {
diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc
index d7cc0b6065a..975bf0c01ca 100644
--- a/source/blender/nodes/intern/node_common.cc
+++ b/source/blender/nodes/intern/node_common.cc
@@ -22,6 +22,7 @@
#include "BLT_translation.h"
#include "BKE_node.h"
+#include "BKE_node_runtime.hh"
#include "BKE_node_tree_update.h"
#include "RNA_types.h"
@@ -86,8 +87,6 @@ bool nodeGroupPoll(const bNodeTree *nodetree,
const bNodeTree *grouptree,
const char **r_disabled_hint)
{
- bool valid = true;
-
/* unspecified node group, generally allowed
* (if anything, should be avoided on operator level)
*/
@@ -106,11 +105,10 @@ bool nodeGroupPoll(const bNodeTree *nodetree,
if (node->typeinfo->poll_instance &&
!node->typeinfo->poll_instance(
const_cast<bNode *>(node), const_cast<bNodeTree *>(nodetree), r_disabled_hint)) {
- valid = false;
- break;
+ return false;
}
}
- return valid;
+ return true;
}
static void add_new_socket_from_interface(bNodeTree &node_tree,
@@ -255,7 +253,7 @@ void register_node_type_frame()
ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
node_type_base(ntype, NODE_FRAME, "Frame", NODE_CLASS_LAYOUT);
- node_type_init(ntype, node_frame_init);
+ ntype->initfunc = node_frame_init;
node_type_storage(ntype, "NodeFrame", node_free_standard_storage, node_copy_standard_storage);
node_type_size(ntype, 150, 100, 0);
ntype->flag |= NODE_BACKGROUND;
@@ -285,7 +283,7 @@ void register_node_type_reroute()
ntype->free_self = (void (*)(bNodeType *))MEM_freeN;
node_type_base(ntype, NODE_REROUTE, "Reroute", NODE_CLASS_LAYOUT);
- node_type_init(ntype, node_reroute_init);
+ ntype->initfunc = node_reroute_init;
nodeRegisterType(ntype);
}
@@ -381,53 +379,29 @@ void ntree_update_reroute_nodes(bNodeTree *ntree)
}
}
-static bool node_is_connected_to_output_recursive(bNodeTree *ntree, bNode *node)
+bool BKE_node_is_connected_to_output(const bNodeTree *ntree, const bNode *node)
{
- bNodeLink *link;
-
- /* avoid redundant checks, and infinite loops in case of cyclic node links */
- if (node->done) {
- return false;
- }
- node->done = 1;
-
- /* main test, done before child loop so it catches output nodes themselves as well */
- if (node->typeinfo->nclass == NODE_CLASS_OUTPUT && node->flag & NODE_DO_OUTPUT) {
- return true;
+ ntree->ensure_topology_cache();
+ Stack<const bNode *> nodes_to_check;
+ for (const bNodeSocket *socket : node->output_sockets()) {
+ for (const bNodeLink *link : socket->directly_linked_links()) {
+ nodes_to_check.push(link->tonode);
+ }
}
-
- /* test all connected nodes, first positive find is sufficient to return true */
- for (link = (bNodeLink *)ntree->links.first; link; link = link->next) {
- if (link->fromnode == node) {
- if (node_is_connected_to_output_recursive(ntree, link->tonode)) {
- return true;
+ while (!nodes_to_check.is_empty()) {
+ const bNode *next_node = nodes_to_check.pop();
+ for (const bNodeSocket *socket : next_node->output_sockets()) {
+ for (const bNodeLink *link : socket->directly_linked_links()) {
+ if (link->tonode->typeinfo->nclass == NODE_CLASS_OUTPUT &&
+ link->tonode->flag & NODE_DO_OUTPUT) {
+ return true;
+ }
+ nodes_to_check.push(link->tonode);
}
}
}
- return false;
-}
-
-bool BKE_node_is_connected_to_output(bNodeTree *ntree, bNode *node)
-{
- bNode *tnode;
- /* clear flags */
- for (tnode = (bNode *)ntree->nodes.first; tnode; tnode = tnode->next) {
- tnode->done = 0;
- }
-
- return node_is_connected_to_output_recursive(ntree, node);
-}
-
-void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree)
-{
- bNode *node;
-
- for (node = (bNode *)ntree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- node->id = nullptr;
- }
- }
+ return false;
}
/** \} */
@@ -460,62 +434,53 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier)
void node_group_input_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = (bNodeSocket *)node->outputs.last;
- bNodeLink *link, *linknext, *exposelink;
/* Adding a tree socket and verifying will remove the extension socket!
* This list caches the existing links from the extension socket
- * so they can be recreated after verification.
- */
- ListBase tmplinks;
+ * so they can be recreated after verification. */
+ Vector<bNodeLink> temp_links;
/* find links from the extension socket and store them */
- BLI_listbase_clear(&tmplinks);
- for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
- linknext = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (nodeLinkIsHidden(link)) {
continue;
}
if (link->fromsock == extsock) {
- bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
- *tlink = *link;
- BLI_addtail(&tmplinks, tlink);
-
+ temp_links.append(*link);
nodeRemLink(ntree, link);
}
}
/* find valid link to expose */
- exposelink = nullptr;
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
+ bNodeLink *exposelink = nullptr;
+ for (bNodeLink &link : temp_links) {
/* XXX Multiple sockets can be connected to the extension socket at once,
* in that case the arbitrary first link determines name and type.
* This could be improved by choosing the "best" type among all links,
* whatever that means.
*/
- if (!is_group_extension_socket(link->tonode, link->tosock)) {
- exposelink = link;
+ if (!is_group_extension_socket(link.tonode, link.tosock)) {
+ exposelink = &link;
break;
}
}
if (exposelink) {
- bNodeSocket *gsock, *newsock;
-
- gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->tonode, exposelink->tosock);
+ bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(
+ ntree, exposelink->tonode, exposelink->tosock);
node_group_input_update(ntree, node);
- newsock = node_group_input_find_socket(node, gsock->identifier);
+ bNodeSocket *newsock = node_group_input_find_socket(node, gsock->identifier);
/* redirect links from the extension socket */
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
- bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link->tonode, link->tosock);
+ for (bNodeLink &link : temp_links) {
+ bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link.tonode, link.tosock);
if (newlink->tosock->flag & SOCK_MULTI_INPUT) {
- newlink->multi_input_socket_index = link->multi_input_socket_index;
+ newlink->multi_input_socket_index = link.multi_input_socket_index;
}
}
}
- BLI_freelistN(&tmplinks);
group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT, true);
}
@@ -527,8 +492,8 @@ void register_node_type_group_input()
node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE);
node_type_size(ntype, 140, 80, 400);
- node_type_init(ntype, node_group_input_init);
- node_type_update(ntype, node_group_input_update);
+ ntype->initfunc = node_group_input_init;
+ ntype->updatefunc = node_group_input_update;
nodeRegisterType(ntype);
}
@@ -552,60 +517,51 @@ bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier)
void node_group_output_update(bNodeTree *ntree, bNode *node)
{
bNodeSocket *extsock = (bNodeSocket *)node->inputs.last;
- bNodeLink *link, *linknext, *exposelink;
/* Adding a tree socket and verifying will remove the extension socket!
* This list caches the existing links to the extension socket
- * so they can be recreated after verification.
- */
- ListBase tmplinks;
+ * so they can be recreated after verification. */
+ Vector<bNodeLink> temp_links;
/* find links to the extension socket and store them */
- BLI_listbase_clear(&tmplinks);
- for (link = (bNodeLink *)ntree->links.first; link; link = linknext) {
- linknext = link->next;
+ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) {
if (nodeLinkIsHidden(link)) {
continue;
}
if (link->tosock == extsock) {
- bNodeLink *tlink = MEM_cnew<bNodeLink>("temporary link");
- *tlink = *link;
- BLI_addtail(&tmplinks, tlink);
-
+ temp_links.append(*link);
nodeRemLink(ntree, link);
}
}
/* find valid link to expose */
- exposelink = nullptr;
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
+ bNodeLink *exposelink = nullptr;
+ for (bNodeLink &link : temp_links) {
/* XXX Multiple sockets can be connected to the extension socket at once,
* in that case the arbitrary first link determines name and type.
* This could be improved by choosing the "best" type among all links,
* whatever that means.
*/
- if (!is_group_extension_socket(link->fromnode, link->fromsock)) {
- exposelink = link;
+ if (!is_group_extension_socket(link.fromnode, link.fromsock)) {
+ exposelink = &link;
break;
}
}
if (exposelink) {
- bNodeSocket *gsock, *newsock;
-
/* XXX what if connecting virtual to virtual socket?? */
- gsock = ntreeAddSocketInterfaceFromSocket(ntree, exposelink->fromnode, exposelink->fromsock);
+ bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(
+ ntree, exposelink->fromnode, exposelink->fromsock);
node_group_output_update(ntree, node);
- newsock = node_group_output_find_socket(node, gsock->identifier);
+ bNodeSocket *newsock = node_group_output_find_socket(node, gsock->identifier);
/* redirect links to the extension socket */
- for (link = (bNodeLink *)tmplinks.first; link; link = link->next) {
- nodeAddLink(ntree, link->fromnode, link->fromsock, node, newsock);
+ for (bNodeLink &link : temp_links) {
+ nodeAddLink(ntree, link.fromnode, link.fromsock, node, newsock);
}
}
- BLI_freelistN(&tmplinks);
group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN, true);
}
@@ -617,8 +573,8 @@ void register_node_type_group_output()
node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE);
node_type_size(ntype, 140, 80, 400);
- node_type_init(ntype, node_group_output_init);
- node_type_update(ntype, node_group_output_update);
+ ntype->initfunc = node_group_output_init;
+ ntype->updatefunc = node_group_output_update;
ntype->no_muting = true;
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index f2f4519625a..6d02ed7d553 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -10,7 +10,6 @@
#include "DNA_node_types.h"
#include "BLI_color.hh"
-#include "BLI_cpp_type_make.hh"
#include "BLI_listbase.h"
#include "BLI_math_vec_types.hh"
#include "BLI_string.h"
@@ -779,12 +778,6 @@ static bNodeSocketType *make_socket_type_string()
return socktype;
}
-BLI_CPP_TYPE_MAKE(Object, Object *, CPPTypeFlags::BasicType)
-BLI_CPP_TYPE_MAKE(Collection, Collection *, CPPTypeFlags::BasicType)
-BLI_CPP_TYPE_MAKE(Texture, Tex *, CPPTypeFlags::BasicType)
-BLI_CPP_TYPE_MAKE(Image, Image *, CPPTypeFlags::BasicType)
-BLI_CPP_TYPE_MAKE(Material, Material *, CPPTypeFlags::BasicType)
-
static bNodeSocketType *make_socket_type_object()
{
bNodeSocketType *socktype = make_standard_socket_type(SOCK_OBJECT, PROP_NONE);