Compare commits
20 Commits
bevelv2
...
node-tree-
Author | SHA1 | Date | |
---|---|---|---|
83276fa0ee | |||
00a0d3315a | |||
861f65040b | |||
677dc13e12 | |||
339839d58d | |||
cb5569f849 | |||
d77d9e8f6e | |||
57ecab5509 | |||
5c70f5a7f7 | |||
a9ac8b44d5 | |||
36bf158e5c | |||
262efaf860 | |||
2fa85494fc | |||
c608858dd2 | |||
d57ec78e6e | |||
1d614fcfb1 | |||
af5a4034b9 | |||
053909a824 | |||
c853595d3a | |||
c02fa53f54 |
@@ -482,13 +482,13 @@ void ntreeFreeLocalTree(struct bNodeTree *ntree);
|
||||
struct bNode *ntreeFindType(const struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasType(const struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
|
||||
void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);
|
||||
void ntreeUpdateAllNew(struct Main *main);
|
||||
void ntreeUpdateAllUsers(struct Main *main, struct ID *id, int tree_update_flag);
|
||||
void ntreeUpdateAllUsers(struct Main *main, struct ID *id);
|
||||
|
||||
void ntreeGetDependencyList(struct bNodeTree *ntree,
|
||||
struct bNode ***r_deplist,
|
||||
int *r_deplist_len);
|
||||
void ntreeUpdateNodeLevels(struct bNodeTree *ntree);
|
||||
|
||||
/* XXX old trees handle output flags automatically based on special output
|
||||
* node types and last active selection.
|
||||
|
98
source/blender/blenkernel/BKE_node_tree_update.h
Normal file
98
source/blender/blenkernel/BKE_node_tree_update.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
struct bNode;
|
||||
struct bNodeSocket;
|
||||
struct bNodeTree;
|
||||
struct bNodeLink;
|
||||
struct Main;
|
||||
struct ID;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Tag tree as changed without providing any more information about what has changed exactly.
|
||||
* The update process has to assume that everything may have changed.
|
||||
*/
|
||||
void BKE_node_tree_update_tag(struct bNodeTree *ntree);
|
||||
|
||||
/**
|
||||
* More specialized tag functions that may result in a more efficient update.
|
||||
*/
|
||||
void BKE_node_tree_update_tag_node(struct bNodeTree *ntree, struct bNode *node);
|
||||
void BKE_node_tree_update_tag_socket(struct bNodeTree *ntree, struct bNodeSocket *socket);
|
||||
void BKE_node_tree_update_tag_link(struct bNodeTree *ntree);
|
||||
void BKE_node_tree_update_tag_node_removed(struct bNodeTree *ntree);
|
||||
void BKE_node_tree_update_tag_node_added(struct bNodeTree *ntree, struct bNode *node);
|
||||
void BKE_node_tree_update_tag_link_removed(struct bNodeTree *ntree);
|
||||
void BKE_node_tree_update_tag_link_added(struct bNodeTree *ntree, struct bNodeLink *link);
|
||||
void BKE_node_tree_update_tag_link_mute(struct bNodeTree *ntree, struct bNodeLink *link);
|
||||
void BKE_node_tree_update_tag_missing_runtime_data(struct bNodeTree *ntree);
|
||||
void BKE_node_tree_update_tag_interface(struct bNodeTree *ntree);
|
||||
|
||||
typedef struct NodeTreeUpdateExtraParams {
|
||||
/**
|
||||
* Data passed into the callbacks.
|
||||
*/
|
||||
void *user_data;
|
||||
|
||||
/**
|
||||
* Called for every tree that has been changed during the update. This can be used to send
|
||||
* notifiers to trigger redraws or depsgraph updates.
|
||||
*/
|
||||
void (*tree_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
|
||||
|
||||
/**
|
||||
* Called for every tree whose interface (e.g. input sockets) changed in some way.
|
||||
*/
|
||||
void (*tree_interface_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
|
||||
|
||||
/**
|
||||
* Called for every tree whose output value may have changed based on the provided update tags.
|
||||
* This can be used to tag the depsgraph if necessary.
|
||||
*/
|
||||
void (*tree_output_changed_fn)(struct ID *, struct bNodeTree *, void *user_data);
|
||||
} NodeTreeUpdateExtraParams;
|
||||
|
||||
/**
|
||||
* Updates #bmain based on changes to node trees.
|
||||
*/
|
||||
void BKE_node_tree_update_main(struct Main *bmain, struct NodeTreeUpdateExtraParams *params);
|
||||
|
||||
/**
|
||||
* Same as #BKE_node_tree_update_main, but will first only look at the provided tree and only looks
|
||||
* at #bmain when something relevant for other data-blocks changed.
|
||||
*
|
||||
* If #bmain is null, only the provided tree is updated. This should only be used in very rare
|
||||
* cases because it may result it incorrectly synced data in DNA.
|
||||
*
|
||||
* If #tree is null, this will update everything.
|
||||
*/
|
||||
void BKE_node_tree_update_main_rooted(struct Main *bmain,
|
||||
struct bNodeTree *ntree,
|
||||
struct NodeTreeUpdateExtraParams *params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -226,6 +226,7 @@ set(SRC
|
||||
intern/multires_versioning.c
|
||||
intern/nla.c
|
||||
intern/node.cc
|
||||
intern/node_tree_update.cc
|
||||
intern/object.cc
|
||||
intern/object_deform.c
|
||||
intern/object_dupli.cc
|
||||
@@ -418,6 +419,7 @@ set(SRC
|
||||
BKE_multires.h
|
||||
BKE_nla.h
|
||||
BKE_node.h
|
||||
BKE_node_tree_update.h
|
||||
BKE_object.h
|
||||
BKE_object_deform.h
|
||||
BKE_object_facemap.h
|
||||
|
@@ -346,7 +346,7 @@ static void libblock_remap_data_postprocess_obdata_relink(Main *bmain, Object *o
|
||||
static void libblock_remap_data_postprocess_nodetree_update(Main *bmain, ID *new_id)
|
||||
{
|
||||
/* Update all group nodes using a node group. */
|
||||
ntreeUpdateAllUsers(bmain, new_id, 0);
|
||||
ntreeUpdateAllUsers(bmain, new_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -50,6 +50,7 @@
|
||||
#include "BKE_linestyle.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_texture.h"
|
||||
|
||||
#include "BLO_read_write.h"
|
||||
@@ -2087,5 +2088,5 @@ void BKE_linestyle_default_shader(const bContext *C, FreestyleLineStyle *linesty
|
||||
tosock = BLI_findlink(&output_linestyle->inputs, 0); /* Color */
|
||||
nodeAddLink(ntree, input_texure, fromsock, output_linestyle, tosock);
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(C), ntree, NULL);
|
||||
}
|
||||
|
@@ -73,6 +73,7 @@
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_threads.h"
|
||||
@@ -99,6 +100,7 @@
|
||||
#define NODE_DEFAULT_MAX_WIDTH 700
|
||||
|
||||
using blender::Array;
|
||||
using blender::Map;
|
||||
using blender::MutableSpan;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
@@ -695,6 +697,7 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
|
||||
ntree->execdata = nullptr;
|
||||
|
||||
ntree->field_inferencing_interface = nullptr;
|
||||
BKE_node_tree_update_tag_missing_runtime_data(ntree);
|
||||
|
||||
BLO_read_data_address(reader, &ntree->adt);
|
||||
BKE_animdata_blend_read_data(reader, ntree->adt);
|
||||
@@ -838,11 +841,6 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
|
||||
/* TODO: should be dealt by new generic cache handling of IDs... */
|
||||
ntree->previews = nullptr;
|
||||
|
||||
if (ntree->type == NTREE_GEOMETRY) {
|
||||
/* Update field referencing for the geometry nodes modifier. */
|
||||
ntree->update |= NTREE_UPDATE_FIELD_INFERENCING;
|
||||
}
|
||||
|
||||
BLO_read_data_address(reader, &ntree->preview);
|
||||
BKE_previewimg_blend_read(reader, ntree->preview);
|
||||
|
||||
@@ -1217,6 +1215,7 @@ static void node_socket_set_typeinfo(bNodeTree *ntree,
|
||||
|
||||
ntree->init &= ~NTREE_TYPE_INIT;
|
||||
}
|
||||
BKE_node_tree_update_tag_socket(ntree, sock);
|
||||
}
|
||||
|
||||
/* Set specific typeinfo pointers in all node trees on register/unregister */
|
||||
@@ -1707,7 +1706,7 @@ bNodeSocket *nodeAddSocket(bNodeTree *ntree,
|
||||
BLI_remlink(lb, sock); /* does nothing for new socket */
|
||||
BLI_addtail(lb, sock);
|
||||
|
||||
node->update |= NODE_UPDATE;
|
||||
BKE_node_tree_update_tag_socket(ntree, sock);
|
||||
|
||||
return sock;
|
||||
}
|
||||
@@ -2160,7 +2159,7 @@ static void iter_backwards_ex(const bNodeTree *ntree,
|
||||
* Can be called recursively (using another nodeChainIterBackwards) by
|
||||
* setting the recursion_lvl accordingly.
|
||||
*
|
||||
* \note Needs updated socket links (ntreeUpdateTree).
|
||||
* \note Needs updated socket links (BKE_node_tree_update_main).
|
||||
* \note Recursive
|
||||
*/
|
||||
void nodeChainIterBackwards(const bNodeTree *ntree,
|
||||
@@ -2218,7 +2217,7 @@ bNode *nodeAddNode(const struct bContext *C, bNodeTree *ntree, const char *idnam
|
||||
BLI_strncpy(node->idname, idname, sizeof(node->idname));
|
||||
node_set_typeinfo(C, ntree, node, nodeTypeFind(idname));
|
||||
|
||||
ntree->update |= NTREE_UPDATE_NODES;
|
||||
BKE_node_tree_update_tag_node(ntree, node);
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -2347,7 +2346,7 @@ bNode *BKE_node_copy_ex(bNodeTree *ntree,
|
||||
}
|
||||
|
||||
if (ntree) {
|
||||
ntree->update |= NTREE_UPDATE_NODES;
|
||||
BKE_node_tree_update_tag_node(ntree, node_dst);
|
||||
}
|
||||
|
||||
/* Reset the declaration of the new node. */
|
||||
@@ -2445,7 +2444,7 @@ bNodeLink *nodeAddLink(
|
||||
}
|
||||
|
||||
if (ntree) {
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link_added(ntree, link);
|
||||
}
|
||||
|
||||
if (link != nullptr && link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
@@ -2468,7 +2467,7 @@ void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
|
||||
MEM_freeN(link);
|
||||
|
||||
if (ntree) {
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link_removed(ntree);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2568,7 +2567,7 @@ void nodeMuteLinkToggle(bNodeTree *ntree, bNodeLink *link)
|
||||
}
|
||||
|
||||
if (ntree) {
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link_mute(ntree, link);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2579,8 +2578,6 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
|
||||
nodeRemLink(ntree, link);
|
||||
}
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
}
|
||||
|
||||
bool nodeLinkIsHidden(const bNodeLink *link)
|
||||
@@ -2645,7 +2642,7 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
|
||||
link->flag |= NODE_LINK_MUTED;
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link(ntree);
|
||||
}
|
||||
else {
|
||||
if (link->tosock->flag & SOCK_MULTI_INPUT) {
|
||||
@@ -3189,7 +3186,7 @@ static void node_free_node(bNodeTree *ntree, bNode *node)
|
||||
MEM_freeN(node);
|
||||
|
||||
if (ntree) {
|
||||
ntree->update |= NTREE_UPDATE_NODES;
|
||||
BKE_node_tree_update_tag_node_removed(ntree);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3576,12 +3573,11 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree,
|
||||
bNodeSocket *iosock = make_socket_interface(ntree, in_out, idname, name);
|
||||
if (in_out == SOCK_IN) {
|
||||
BLI_addtail(&ntree->inputs, iosock);
|
||||
ntree->update |= NTREE_UPDATE_GROUP_IN;
|
||||
}
|
||||
else if (in_out == SOCK_OUT) {
|
||||
BLI_addtail(&ntree->outputs, iosock);
|
||||
ntree->update |= NTREE_UPDATE_GROUP_OUT;
|
||||
}
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
return iosock;
|
||||
}
|
||||
|
||||
@@ -3594,12 +3590,11 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree,
|
||||
bNodeSocket *iosock = make_socket_interface(ntree, in_out, idname, name);
|
||||
if (in_out == SOCK_IN) {
|
||||
BLI_insertlinkbefore(&ntree->inputs, next_sock, iosock);
|
||||
ntree->update |= NTREE_UPDATE_GROUP_IN;
|
||||
}
|
||||
else if (in_out == SOCK_OUT) {
|
||||
BLI_insertlinkbefore(&ntree->outputs, next_sock, iosock);
|
||||
ntree->update |= NTREE_UPDATE_GROUP_OUT;
|
||||
}
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
return iosock;
|
||||
}
|
||||
|
||||
@@ -3645,7 +3640,7 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock)
|
||||
node_socket_interface_free(ntree, sock, true);
|
||||
MEM_freeN(sock);
|
||||
|
||||
ntree->update |= NTREE_UPDATE_GROUP;
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
}
|
||||
|
||||
/* generates a valid RNA identifier from the node tree name */
|
||||
@@ -4459,7 +4454,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***r_deplist,
|
||||
}
|
||||
|
||||
/* only updates node->level for detecting cycles links */
|
||||
static void ntree_update_node_level(bNodeTree *ntree)
|
||||
void ntreeUpdateNodeLevels(bNodeTree *ntree)
|
||||
{
|
||||
/* first clear tag */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
@@ -4494,598 +4489,49 @@ void ntreeTagUsedSockets(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
|
||||
static void ntree_update_link_pointers(bNodeTree *ntree)
|
||||
{
|
||||
/* first clear data */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
|
||||
sock->link = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
||||
link->tosock->link = link;
|
||||
}
|
||||
|
||||
ntreeTagUsedSockets(ntree);
|
||||
}
|
||||
|
||||
static void ntree_validate_links(bNodeTree *ntree)
|
||||
{
|
||||
LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
|
||||
link->flag |= NODE_LINK_VALID;
|
||||
if (link->fromnode && link->tonode && link->fromnode->level <= link->tonode->level) {
|
||||
link->flag &= ~NODE_LINK_VALID;
|
||||
}
|
||||
else if (ntree->typeinfo->validate_link) {
|
||||
if (!ntree->typeinfo->validate_link(ntree, link)) {
|
||||
link->flag &= ~NODE_LINK_VALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ntreeUpdateAllNew(Main *main)
|
||||
{
|
||||
Vector<bNodeTree *> new_ntrees;
|
||||
|
||||
/* Update all new node trees on file read or append, to add/remove sockets
|
||||
* in groups nodes if the group changed, and handle any update flags that
|
||||
* might have been set in file reading or versioning. */
|
||||
FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
|
||||
if (owner_id->tag & LIB_TAG_NEW) {
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
/* TODO: Move to update function. */
|
||||
if (node->typeinfo->group_update_func) {
|
||||
node->typeinfo->group_update_func(ntree, node);
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(nullptr, ntree);
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
BKE_node_tree_update_main(main, nullptr);
|
||||
}
|
||||
|
||||
namespace blender::bke::node_field_inferencing {
|
||||
|
||||
static bool is_field_socket_type(eNodeSocketDatatype type)
|
||||
{
|
||||
return ELEM(type, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_VECTOR, SOCK_RGBA);
|
||||
}
|
||||
|
||||
static bool is_field_socket_type(const SocketRef &socket)
|
||||
{
|
||||
return is_field_socket_type((eNodeSocketDatatype)socket.typeinfo()->type);
|
||||
}
|
||||
|
||||
static bool update_field_inferencing(bNodeTree &btree);
|
||||
|
||||
static InputSocketFieldType get_interface_input_field_type(const NodeRef &node,
|
||||
const InputSocketRef &socket)
|
||||
{
|
||||
if (!is_field_socket_type(socket)) {
|
||||
return InputSocketFieldType::None;
|
||||
}
|
||||
if (node.is_reroute_node()) {
|
||||
return InputSocketFieldType::IsSupported;
|
||||
}
|
||||
if (node.is_group_output_node()) {
|
||||
/* Outputs always support fields when the data type is correct. */
|
||||
return InputSocketFieldType::IsSupported;
|
||||
}
|
||||
if (node.is_undefined()) {
|
||||
return InputSocketFieldType::None;
|
||||
}
|
||||
|
||||
const NodeDeclaration *node_decl = node.declaration();
|
||||
|
||||
/* Node declarations should be implemented for nodes involved here. */
|
||||
BLI_assert(node_decl != nullptr);
|
||||
|
||||
/* Get the field type from the declaration. */
|
||||
const SocketDeclaration &socket_decl = *node_decl->inputs()[socket.index()];
|
||||
const InputSocketFieldType field_type = socket_decl.input_field_type();
|
||||
if (field_type == InputSocketFieldType::Implicit) {
|
||||
return field_type;
|
||||
}
|
||||
if (node_decl->is_function_node()) {
|
||||
/* In a function node, every socket supports fields. */
|
||||
return InputSocketFieldType::IsSupported;
|
||||
}
|
||||
return field_type;
|
||||
}
|
||||
|
||||
static OutputFieldDependency get_interface_output_field_dependency(const NodeRef &node,
|
||||
const OutputSocketRef &socket)
|
||||
{
|
||||
if (!is_field_socket_type(socket)) {
|
||||
/* Non-field sockets always output data. */
|
||||
return OutputFieldDependency::ForDataSource();
|
||||
}
|
||||
if (node.is_reroute_node()) {
|
||||
/* The reroute just forwards what is passed in. */
|
||||
return OutputFieldDependency::ForDependentField();
|
||||
}
|
||||
if (node.is_group_input_node()) {
|
||||
/* Input nodes get special treatment in #determine_group_input_states. */
|
||||
return OutputFieldDependency::ForDependentField();
|
||||
}
|
||||
if (node.is_undefined()) {
|
||||
return OutputFieldDependency::ForDataSource();
|
||||
}
|
||||
|
||||
const NodeDeclaration *node_decl = node.declaration();
|
||||
|
||||
/* Node declarations should be implemented for nodes involved here. */
|
||||
BLI_assert(node_decl != nullptr);
|
||||
|
||||
if (node_decl->is_function_node()) {
|
||||
/* In a generic function node, all outputs depend on all inputs. */
|
||||
return OutputFieldDependency::ForDependentField();
|
||||
}
|
||||
|
||||
/* Use the socket declaration. */
|
||||
const SocketDeclaration &socket_decl = *node_decl->outputs()[socket.index()];
|
||||
return socket_decl.output_field_dependency();
|
||||
}
|
||||
|
||||
static FieldInferencingInterface get_dummy_field_inferencing_interface(const NodeRef &node)
|
||||
{
|
||||
FieldInferencingInterface inferencing_interface;
|
||||
inferencing_interface.inputs.append_n_times(InputSocketFieldType::None, node.inputs().size());
|
||||
inferencing_interface.outputs.append_n_times(OutputFieldDependency::ForDataSource(),
|
||||
node.outputs().size());
|
||||
return inferencing_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves information about how the node interacts with fields.
|
||||
* In the future, this information can be stored in the node declaration. This would allow this
|
||||
* function to return a reference, making it more efficient.
|
||||
*/
|
||||
static FieldInferencingInterface get_node_field_inferencing_interface(const NodeRef &node)
|
||||
{
|
||||
/* Node groups already reference all required information, so just return that. */
|
||||
if (node.is_group_node()) {
|
||||
bNodeTree *group = (bNodeTree *)node.bnode()->id;
|
||||
if (group == nullptr) {
|
||||
return FieldInferencingInterface();
|
||||
}
|
||||
if (!ntreeIsRegistered(group)) {
|
||||
/* This can happen when there is a linked node group that was not found (see T92799). */
|
||||
return get_dummy_field_inferencing_interface(node);
|
||||
}
|
||||
if (group->field_inferencing_interface == nullptr) {
|
||||
/* Update group recursively. */
|
||||
update_field_inferencing(*group);
|
||||
}
|
||||
return *group->field_inferencing_interface;
|
||||
}
|
||||
|
||||
FieldInferencingInterface inferencing_interface;
|
||||
for (const InputSocketRef *input_socket : node.inputs()) {
|
||||
inferencing_interface.inputs.append(get_interface_input_field_type(node, *input_socket));
|
||||
}
|
||||
|
||||
for (const OutputSocketRef *output_socket : node.outputs()) {
|
||||
inferencing_interface.outputs.append(
|
||||
get_interface_output_field_dependency(node, *output_socket));
|
||||
}
|
||||
return inferencing_interface;
|
||||
}
|
||||
|
||||
/**
|
||||
* This struct contains information for every socket. The values are propagated through the
|
||||
* network.
|
||||
*/
|
||||
struct SocketFieldState {
|
||||
/* This socket starts a new field. */
|
||||
bool is_field_source = false;
|
||||
/* This socket can never become a field, because the node itself does not support it. */
|
||||
bool is_always_single = false;
|
||||
/* This socket is currently a single value. It could become a field though. */
|
||||
bool is_single = true;
|
||||
/* This socket is required to be a single value. This can be because the node itself only
|
||||
* supports this socket to be a single value, or because a node afterwards requires this to be a
|
||||
* single value. */
|
||||
bool requires_single = false;
|
||||
};
|
||||
|
||||
static Vector<const InputSocketRef *> gather_input_socket_dependencies(
|
||||
const OutputFieldDependency &field_dependency, const NodeRef &node)
|
||||
{
|
||||
const OutputSocketFieldType type = field_dependency.field_type();
|
||||
Vector<const InputSocketRef *> input_sockets;
|
||||
switch (type) {
|
||||
case OutputSocketFieldType::FieldSource:
|
||||
case OutputSocketFieldType::None: {
|
||||
break;
|
||||
}
|
||||
case OutputSocketFieldType::DependentField: {
|
||||
/* This output depends on all inputs. */
|
||||
input_sockets.extend(node.inputs());
|
||||
break;
|
||||
}
|
||||
case OutputSocketFieldType::PartiallyDependent: {
|
||||
/* This output depends only on a few inputs. */
|
||||
for (const int i : field_dependency.linked_input_indices()) {
|
||||
input_sockets.append(&node.input(i));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return input_sockets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check what the group output socket depends on. Potentially traverses the node tree
|
||||
* to figure out if it is always a field or if it depends on any group inputs.
|
||||
*/
|
||||
static OutputFieldDependency find_group_output_dependencies(
|
||||
const InputSocketRef &group_output_socket,
|
||||
const Span<SocketFieldState> field_state_by_socket_id)
|
||||
{
|
||||
if (!is_field_socket_type(group_output_socket)) {
|
||||
return OutputFieldDependency::ForDataSource();
|
||||
}
|
||||
|
||||
/* Use a Set here instead of an array indexed by socket id, because we my only need to look at
|
||||
* very few sockets. */
|
||||
Set<const InputSocketRef *> handled_sockets;
|
||||
Stack<const InputSocketRef *> sockets_to_check;
|
||||
|
||||
handled_sockets.add(&group_output_socket);
|
||||
sockets_to_check.push(&group_output_socket);
|
||||
|
||||
/* Keeps track of group input indices that are (indirectly) connected to the output. */
|
||||
Vector<int> linked_input_indices;
|
||||
|
||||
while (!sockets_to_check.is_empty()) {
|
||||
const InputSocketRef *input_socket = sockets_to_check.pop();
|
||||
|
||||
for (const OutputSocketRef *origin_socket : input_socket->directly_linked_sockets()) {
|
||||
const NodeRef &origin_node = origin_socket->node();
|
||||
const SocketFieldState &origin_state = field_state_by_socket_id[origin_socket->id()];
|
||||
|
||||
if (origin_state.is_field_source) {
|
||||
if (origin_node.is_group_input_node()) {
|
||||
/* Found a group input that the group output depends on. */
|
||||
linked_input_indices.append_non_duplicates(origin_socket->index());
|
||||
}
|
||||
else {
|
||||
/* Found a field source that is not the group input. So the output is always a field. */
|
||||
return OutputFieldDependency::ForFieldSource();
|
||||
}
|
||||
}
|
||||
else if (!origin_state.is_single) {
|
||||
const FieldInferencingInterface inferencing_interface =
|
||||
get_node_field_inferencing_interface(origin_node);
|
||||
const OutputFieldDependency &field_dependency =
|
||||
inferencing_interface.outputs[origin_socket->index()];
|
||||
|
||||
/* Propagate search further to the left. */
|
||||
for (const InputSocketRef *origin_input_socket :
|
||||
gather_input_socket_dependencies(field_dependency, origin_node)) {
|
||||
if (!origin_input_socket->is_available()) {
|
||||
continue;
|
||||
}
|
||||
if (!field_state_by_socket_id[origin_input_socket->id()].is_single) {
|
||||
if (handled_sockets.add(origin_input_socket)) {
|
||||
sockets_to_check.push(origin_input_socket);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return OutputFieldDependency::ForPartiallyDependentField(std::move(linked_input_indices));
|
||||
}
|
||||
|
||||
static void propagate_data_requirements_from_right_to_left(
|
||||
const NodeTreeRef &tree, const MutableSpan<SocketFieldState> field_state_by_socket_id)
|
||||
{
|
||||
const NodeTreeRef::ToposortResult toposort_result = tree.toposort(
|
||||
NodeTreeRef::ToposortDirection::RightToLeft);
|
||||
|
||||
for (const NodeRef *node : toposort_result.sorted_nodes) {
|
||||
const FieldInferencingInterface inferencing_interface = get_node_field_inferencing_interface(
|
||||
*node);
|
||||
|
||||
for (const OutputSocketRef *output_socket : node->outputs()) {
|
||||
SocketFieldState &state = field_state_by_socket_id[output_socket->id()];
|
||||
|
||||
const OutputFieldDependency &field_dependency =
|
||||
inferencing_interface.outputs[output_socket->index()];
|
||||
|
||||
if (field_dependency.field_type() == OutputSocketFieldType::FieldSource) {
|
||||
continue;
|
||||
}
|
||||
if (field_dependency.field_type() == OutputSocketFieldType::None) {
|
||||
state.requires_single = true;
|
||||
state.is_always_single = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The output is required to be a single value when it is connected to any input that does
|
||||
* not support fields. */
|
||||
for (const InputSocketRef *target_socket : output_socket->directly_linked_sockets()) {
|
||||
state.requires_single |= field_state_by_socket_id[target_socket->id()].requires_single;
|
||||
}
|
||||
|
||||
if (state.requires_single) {
|
||||
bool any_input_is_field_implicitly = false;
|
||||
const Vector<const InputSocketRef *> connected_inputs = gather_input_socket_dependencies(
|
||||
field_dependency, *node);
|
||||
for (const InputSocketRef *input_socket : connected_inputs) {
|
||||
if (!input_socket->is_available()) {
|
||||
continue;
|
||||
}
|
||||
if (inferencing_interface.inputs[input_socket->index()] ==
|
||||
InputSocketFieldType::Implicit) {
|
||||
if (!input_socket->is_logically_linked()) {
|
||||
any_input_is_field_implicitly = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (any_input_is_field_implicitly) {
|
||||
/* This output isn't a single value actually. */
|
||||
state.requires_single = false;
|
||||
}
|
||||
else {
|
||||
/* If the output is required to be a single value, the connected inputs in the same node
|
||||
* must not be fields as well. */
|
||||
for (const InputSocketRef *input_socket : connected_inputs) {
|
||||
field_state_by_socket_id[input_socket->id()].requires_single = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Some inputs do not require fields independent of what the outputs are connected to. */
|
||||
for (const InputSocketRef *input_socket : node->inputs()) {
|
||||
SocketFieldState &state = field_state_by_socket_id[input_socket->id()];
|
||||
if (inferencing_interface.inputs[input_socket->index()] == InputSocketFieldType::None) {
|
||||
state.requires_single = true;
|
||||
state.is_always_single = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void determine_group_input_states(
|
||||
const NodeTreeRef &tree,
|
||||
FieldInferencingInterface &new_inferencing_interface,
|
||||
const MutableSpan<SocketFieldState> field_state_by_socket_id)
|
||||
{
|
||||
{
|
||||
/* Non-field inputs never support fields. */
|
||||
int index;
|
||||
LISTBASE_FOREACH_INDEX (bNodeSocket *, group_input, &tree.btree()->inputs, index) {
|
||||
if (!is_field_socket_type((eNodeSocketDatatype)group_input->type)) {
|
||||
new_inferencing_interface.inputs[index] = InputSocketFieldType::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Check if group inputs are required to be single values, because they are (indirectly)
|
||||
* connected to some socket that does not support fields. */
|
||||
for (const NodeRef *node : tree.nodes_by_type("NodeGroupInput")) {
|
||||
for (const OutputSocketRef *output_socket : node->outputs().drop_back(1)) {
|
||||
SocketFieldState &state = field_state_by_socket_id[output_socket->id()];
|
||||
if (state.requires_single) {
|
||||
new_inferencing_interface.inputs[output_socket->index()] = InputSocketFieldType::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If an input does not support fields, this should be reflected in all Group Input nodes. */
|
||||
for (const NodeRef *node : tree.nodes_by_type("NodeGroupInput")) {
|
||||
for (const OutputSocketRef *output_socket : node->outputs().drop_back(1)) {
|
||||
SocketFieldState &state = field_state_by_socket_id[output_socket->id()];
|
||||
const bool supports_field = new_inferencing_interface.inputs[output_socket->index()] !=
|
||||
InputSocketFieldType::None;
|
||||
if (supports_field) {
|
||||
state.is_single = false;
|
||||
state.is_field_source = true;
|
||||
}
|
||||
else {
|
||||
state.requires_single = true;
|
||||
}
|
||||
}
|
||||
SocketFieldState &dummy_socket_state = field_state_by_socket_id[node->outputs().last()->id()];
|
||||
dummy_socket_state.requires_single = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void propagate_field_status_from_left_to_right(
|
||||
const NodeTreeRef &tree, const MutableSpan<SocketFieldState> field_state_by_socket_id)
|
||||
{
|
||||
const NodeTreeRef::ToposortResult toposort_result = tree.toposort(
|
||||
NodeTreeRef::ToposortDirection::LeftToRight);
|
||||
|
||||
for (const NodeRef *node : toposort_result.sorted_nodes) {
|
||||
if (node->is_group_input_node()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const FieldInferencingInterface inferencing_interface = get_node_field_inferencing_interface(
|
||||
*node);
|
||||
|
||||
/* Update field state of input sockets, also taking into account linked origin sockets. */
|
||||
for (const InputSocketRef *input_socket : node->inputs()) {
|
||||
SocketFieldState &state = field_state_by_socket_id[input_socket->id()];
|
||||
if (state.is_always_single) {
|
||||
state.is_single = true;
|
||||
continue;
|
||||
}
|
||||
state.is_single = true;
|
||||
if (input_socket->directly_linked_sockets().is_empty()) {
|
||||
if (inferencing_interface.inputs[input_socket->index()] ==
|
||||
InputSocketFieldType::Implicit) {
|
||||
state.is_single = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const OutputSocketRef *origin_socket : input_socket->directly_linked_sockets()) {
|
||||
if (!field_state_by_socket_id[origin_socket->id()].is_single) {
|
||||
state.is_single = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update field state of output sockets, also taking into account input sockets. */
|
||||
for (const OutputSocketRef *output_socket : node->outputs()) {
|
||||
SocketFieldState &state = field_state_by_socket_id[output_socket->id()];
|
||||
const OutputFieldDependency &field_dependency =
|
||||
inferencing_interface.outputs[output_socket->index()];
|
||||
|
||||
switch (field_dependency.field_type()) {
|
||||
case OutputSocketFieldType::None: {
|
||||
state.is_single = true;
|
||||
break;
|
||||
}
|
||||
case OutputSocketFieldType::FieldSource: {
|
||||
state.is_single = false;
|
||||
state.is_field_source = true;
|
||||
break;
|
||||
}
|
||||
case OutputSocketFieldType::PartiallyDependent:
|
||||
case OutputSocketFieldType::DependentField: {
|
||||
for (const InputSocketRef *input_socket :
|
||||
gather_input_socket_dependencies(field_dependency, *node)) {
|
||||
if (!input_socket->is_available()) {
|
||||
continue;
|
||||
}
|
||||
if (!field_state_by_socket_id[input_socket->id()].is_single) {
|
||||
state.is_single = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void determine_group_output_states(const NodeTreeRef &tree,
|
||||
FieldInferencingInterface &new_inferencing_interface,
|
||||
const Span<SocketFieldState> field_state_by_socket_id)
|
||||
{
|
||||
for (const NodeRef *group_output_node : tree.nodes_by_type("NodeGroupOutput")) {
|
||||
/* Ignore inactive group output nodes. */
|
||||
if (!(group_output_node->bnode()->flag & NODE_DO_OUTPUT)) {
|
||||
continue;
|
||||
}
|
||||
/* Determine dependencies of all group outputs. */
|
||||
for (const InputSocketRef *group_output_socket : group_output_node->inputs().drop_back(1)) {
|
||||
OutputFieldDependency field_dependency = find_group_output_dependencies(
|
||||
*group_output_socket, field_state_by_socket_id);
|
||||
new_inferencing_interface.outputs[group_output_socket->index()] = std::move(
|
||||
field_dependency);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_socket_shapes(const NodeTreeRef &tree,
|
||||
const Span<SocketFieldState> field_state_by_socket_id)
|
||||
{
|
||||
const eNodeSocketDisplayShape requires_data_shape = SOCK_DISPLAY_SHAPE_CIRCLE;
|
||||
const eNodeSocketDisplayShape data_but_can_be_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND_DOT;
|
||||
const eNodeSocketDisplayShape is_field_shape = SOCK_DISPLAY_SHAPE_DIAMOND;
|
||||
|
||||
auto get_shape_for_state = [&](const SocketFieldState &state) {
|
||||
if (state.is_always_single) {
|
||||
return requires_data_shape;
|
||||
}
|
||||
if (!state.is_single) {
|
||||
return is_field_shape;
|
||||
}
|
||||
if (state.requires_single) {
|
||||
return requires_data_shape;
|
||||
}
|
||||
return data_but_can_be_field_shape;
|
||||
};
|
||||
|
||||
for (const InputSocketRef *socket : tree.input_sockets()) {
|
||||
bNodeSocket *bsocket = socket->bsocket();
|
||||
const SocketFieldState &state = field_state_by_socket_id[socket->id()];
|
||||
bsocket->display_shape = get_shape_for_state(state);
|
||||
}
|
||||
for (const OutputSocketRef *socket : tree.output_sockets()) {
|
||||
bNodeSocket *bsocket = socket->bsocket();
|
||||
const SocketFieldState &state = field_state_by_socket_id[socket->id()];
|
||||
bsocket->display_shape = get_shape_for_state(state);
|
||||
}
|
||||
}
|
||||
|
||||
static bool update_field_inferencing(bNodeTree &btree)
|
||||
{
|
||||
using namespace blender::nodes;
|
||||
if (btree.type != NTREE_GEOMETRY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create new inferencing interface for this node group. */
|
||||
FieldInferencingInterface *new_inferencing_interface = new FieldInferencingInterface();
|
||||
new_inferencing_interface->inputs.resize(BLI_listbase_count(&btree.inputs),
|
||||
InputSocketFieldType::IsSupported);
|
||||
new_inferencing_interface->outputs.resize(BLI_listbase_count(&btree.outputs),
|
||||
OutputFieldDependency::ForDataSource());
|
||||
|
||||
/* Create #NodeTreeRef to accelerate various queries on the node tree (e.g. linked sockets). */
|
||||
const NodeTreeRef tree{&btree};
|
||||
|
||||
/* Keep track of the state of all sockets. The index into this array is #SocketRef::id(). */
|
||||
Array<SocketFieldState> field_state_by_socket_id(tree.sockets().size());
|
||||
|
||||
propagate_data_requirements_from_right_to_left(tree, field_state_by_socket_id);
|
||||
determine_group_input_states(tree, *new_inferencing_interface, field_state_by_socket_id);
|
||||
propagate_field_status_from_left_to_right(tree, field_state_by_socket_id);
|
||||
determine_group_output_states(tree, *new_inferencing_interface, field_state_by_socket_id);
|
||||
update_socket_shapes(tree, field_state_by_socket_id);
|
||||
|
||||
/* Update the previous group interface. */
|
||||
const bool group_interface_changed = btree.field_inferencing_interface == nullptr ||
|
||||
*btree.field_inferencing_interface !=
|
||||
*new_inferencing_interface;
|
||||
delete btree.field_inferencing_interface;
|
||||
btree.field_inferencing_interface = new_inferencing_interface;
|
||||
|
||||
return group_interface_changed;
|
||||
}
|
||||
|
||||
} // namespace blender::bke::node_field_inferencing
|
||||
|
||||
/**
|
||||
* \param tree_update_flag: #eNodeTreeUpdate enum.
|
||||
*/
|
||||
void ntreeUpdateAllUsers(Main *main, ID *id, const int tree_update_flag)
|
||||
void ntreeUpdateAllUsers(Main *main, ID *id)
|
||||
{
|
||||
if (id == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool need_update = false;
|
||||
|
||||
/* Update all users of ngroup, to add/remove sockets as needed. */
|
||||
FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
|
||||
bool need_update = false;
|
||||
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (node->id == id) {
|
||||
if (node->typeinfo->group_update_func) {
|
||||
node->typeinfo->group_update_func(ntree, node);
|
||||
}
|
||||
|
||||
BKE_node_tree_update_tag_node(ntree, node);
|
||||
need_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntree->update |= tree_update_flag;
|
||||
ntreeUpdateTree(tree_update_flag ? main : nullptr, ntree);
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
if (need_update) {
|
||||
BKE_node_tree_update_main(main, nullptr);
|
||||
}
|
||||
|
||||
if (GS(id->name) == ID_NT) {
|
||||
bNodeTree *ngroup = (bNodeTree *)id;
|
||||
@@ -5104,80 +4550,6 @@ void ntreeUpdateAllUsers(Main *main, ID *id, const int tree_update_flag)
|
||||
}
|
||||
}
|
||||
|
||||
void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
|
||||
{
|
||||
if (!ntree) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Avoid re-entrant updates, can be caused by RNA update callbacks. */
|
||||
if (ntree->is_updating) {
|
||||
return;
|
||||
}
|
||||
ntree->is_updating = true;
|
||||
|
||||
if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) {
|
||||
/* set the bNodeSocket->link pointers */
|
||||
ntree_update_link_pointers(ntree);
|
||||
}
|
||||
|
||||
/* update individual nodes */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
/* node tree update tags override individual node update flags */
|
||||
if ((node->update & NODE_UPDATE) || (ntree->update & NTREE_UPDATE)) {
|
||||
if (node->typeinfo->updatefunc) {
|
||||
node->typeinfo->updatefunc(ntree, node);
|
||||
}
|
||||
|
||||
nodeUpdateInternalLinks(ntree, node);
|
||||
}
|
||||
}
|
||||
|
||||
/* generic tree update callback */
|
||||
if (ntree->typeinfo->update) {
|
||||
ntree->typeinfo->update(ntree);
|
||||
}
|
||||
/* XXX this should be moved into the tree type update callback for tree supporting node groups.
|
||||
* Currently the node tree interface is still a generic feature of the base NodeTree type.
|
||||
*/
|
||||
if (ntree->update & NTREE_UPDATE_GROUP) {
|
||||
ntreeInterfaceTypeUpdate(ntree);
|
||||
}
|
||||
|
||||
int tree_user_update_flag = 0;
|
||||
|
||||
if (ntree->update & NTREE_UPDATE) {
|
||||
/* If the field interface of this node tree has changed, all node trees using
|
||||
* this group will need to recalculate their interface as well. */
|
||||
if (blender::bke::node_field_inferencing::update_field_inferencing(*ntree)) {
|
||||
tree_user_update_flag |= NTREE_UPDATE_FIELD_INFERENCING;
|
||||
}
|
||||
}
|
||||
|
||||
if (bmain) {
|
||||
ntreeUpdateAllUsers(bmain, &ntree->id, tree_user_update_flag);
|
||||
}
|
||||
|
||||
if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) {
|
||||
/* node updates can change sockets or links, repeat link pointer update afterward */
|
||||
ntree_update_link_pointers(ntree);
|
||||
|
||||
/* update the node level from link dependencies */
|
||||
ntree_update_node_level(ntree);
|
||||
|
||||
/* check link validity */
|
||||
ntree_validate_links(ntree);
|
||||
}
|
||||
|
||||
/* clear update flags */
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
node->update = 0;
|
||||
}
|
||||
ntree->update = 0;
|
||||
|
||||
ntree->is_updating = false;
|
||||
}
|
||||
|
||||
void nodeUpdate(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
/* Avoid re-entrant updates, can be caused by RNA update callbacks. */
|
||||
|
1056
source/blender/blenkernel/intern/node_tree_update.cc
Normal file
1056
source/blender/blenkernel/intern/node_tree_update.cc
Normal file
File diff suppressed because it is too large
Load Diff
@@ -70,6 +70,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -590,7 +591,7 @@ static bNodeSocket *do_versions_node_group_add_socket_2_56_2(bNodeTree *ngroup,
|
||||
|
||||
BLI_addtail(in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs, gsock);
|
||||
|
||||
ngroup->update |= (in_out == SOCK_IN ? NTREE_UPDATE_GROUP_IN : NTREE_UPDATE_GROUP_OUT);
|
||||
BKE_node_tree_update_tag_interface(ngroup);
|
||||
|
||||
return gsock;
|
||||
}
|
||||
@@ -2019,7 +2020,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
||||
link->fromsock = gsock;
|
||||
link->tonode = node;
|
||||
link->tosock = sock;
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link_added(ntree, link);
|
||||
|
||||
sock->link = link;
|
||||
}
|
||||
@@ -2042,7 +2043,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
||||
link->fromsock = sock;
|
||||
link->tonode = NULL;
|
||||
link->tosock = gsock;
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link_added(ntree, link);
|
||||
|
||||
gsock->link = link;
|
||||
}
|
||||
@@ -2282,7 +2283,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain)
|
||||
do_versions_socket_default_value_259(sock);
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
|
@@ -88,6 +88,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_report.h"
|
||||
@@ -810,7 +811,9 @@ static void do_versions_seq_alloc_transform_and_crop(ListBase *seqbase)
|
||||
}
|
||||
|
||||
/* Return true if there is something to convert. */
|
||||
static void do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, char blend_method)
|
||||
static void do_versions_material_convert_legacy_blend_mode(Main *bmain,
|
||||
bNodeTree *ntree,
|
||||
char blend_method)
|
||||
{
|
||||
bool need_update = false;
|
||||
|
||||
@@ -896,7 +899,7 @@ static void do_versions_material_convert_legacy_blend_mode(bNodeTree *ntree, cha
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1594,13 +1597,13 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
|
||||
bNodeTree *ntree = ma->nodetree;
|
||||
if (ma->blend_method == 1 /* MA_BM_ADD */) {
|
||||
if (ma->use_nodes) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, 1 /* MA_BM_ADD */);
|
||||
do_versions_material_convert_legacy_blend_mode(bmain, ntree, 1 /* MA_BM_ADD */);
|
||||
}
|
||||
ma->blend_method = MA_BM_BLEND;
|
||||
}
|
||||
else if (ma->blend_method == 2 /* MA_BM_MULTIPLY */) {
|
||||
if (ma->use_nodes) {
|
||||
do_versions_material_convert_legacy_blend_mode(ntree, 2 /* MA_BM_MULTIPLY */);
|
||||
do_versions_material_convert_legacy_blend_mode(bmain, ntree, 2 /* MA_BM_MULTIPLY */);
|
||||
}
|
||||
ma->blend_method = MA_BM_BLEND;
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_enum_types.h"
|
||||
@@ -585,7 +586,7 @@ static bNodeTree *add_realize_node_tree(Main *bmain)
|
||||
nodeSetSelected(node, false);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, node_tree);
|
||||
BKE_node_tree_update_main_rooted(bmain, node_tree, NULL);
|
||||
return node_tree;
|
||||
}
|
||||
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "BKE_idprop.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -170,7 +171,7 @@ static void displacement_node_insert(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +244,7 @@ static void square_roughness_node_insert(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +319,7 @@ static void ambient_occlusion_node_relink(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,7 +467,7 @@ static void update_math_node_single_operand_operators(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,7 +529,7 @@ static void update_vector_math_node_add_and_subtract_operators(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,7 +567,7 @@ static void update_vector_math_node_dot_product_operator(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -631,7 +632,7 @@ static void update_vector_math_node_cross_product_operator(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,7 +684,7 @@ static void update_vector_math_node_normalize_operator(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,7 +786,7 @@ static void update_vector_math_node_average_operator(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -974,7 +975,7 @@ static void update_mapping_node_inputs_and_properties(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1149,7 +1150,7 @@ static void update_voronoi_node_crackle(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1191,7 +1192,7 @@ static void update_voronoi_node_coloring(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1234,7 +1235,7 @@ static void update_voronoi_node_square_distance(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1279,7 +1280,7 @@ static void update_noise_and_wave_distortion(bNodeTree *ntree)
|
||||
}
|
||||
|
||||
if (need_update) {
|
||||
ntreeUpdateTree(NULL, ntree);
|
||||
BKE_node_tree_update_main_rooted(NULL, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -120,6 +120,25 @@ void ED_node_set_active(struct Main *bmain,
|
||||
struct bNode *node,
|
||||
bool *r_active_texture_changed);
|
||||
|
||||
/**
|
||||
* Call after one or more node trees have been changed and have been tagged accordingly.
|
||||
*
|
||||
* This function will make sure that other parts of Blender update accordingly. For example, if the
|
||||
* node group interface changed, parent node groups have to be updated as well.
|
||||
*
|
||||
* Additionally, this will send notifiers and tag the depsgraph based on the changes. Depsgraph
|
||||
* relation updates have to be triggered by the caller.
|
||||
*
|
||||
* \param C: Context if available. This can be null.
|
||||
* \param bmain: Main whose data-blocks should be updated based on the changes.
|
||||
* \param only_tagged_tree: Under some circumstances the caller knows that only one node tree has
|
||||
* changed since the last update. In this case the function may be able to skip scanning bmain
|
||||
* for other things that have to be changed.
|
||||
*/
|
||||
void ED_node_tree_propagate_change(const struct bContext *C,
|
||||
struct Main *bmain,
|
||||
struct bNodeTree *ntree);
|
||||
|
||||
void ED_node_composite_job(const struct bContext *C,
|
||||
struct bNodeTree *nodetree,
|
||||
struct Scene *scene_owner);
|
||||
|
@@ -6636,7 +6636,7 @@ static bool proj_paint_add_slot(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
ED_node_tree_propagate_change(C, bmain, ntree);
|
||||
/* In case we added more than one node, position them too. */
|
||||
nodePositionPropagate(out_node);
|
||||
|
||||
|
@@ -29,6 +29,7 @@ set(INC
|
||||
../../imbuf
|
||||
../../makesdna
|
||||
../../makesrna
|
||||
../../modifiers
|
||||
../../nodes
|
||||
../../render
|
||||
../../windowmanager
|
||||
|
@@ -3323,7 +3323,8 @@ static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), Poin
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
UNUSED_VARS(node);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
|
||||
static void node_socket_template_properties_update(bNodeType *ntype, bNodeSocketTemplate *stemp)
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_texture.h"
|
||||
@@ -89,7 +90,7 @@ bNode *node_add_node(const bContext *C, const char *idname, int type, float locx
|
||||
|
||||
nodeSetSelected(node, true);
|
||||
|
||||
ntreeUpdateTree(bmain, snode->edittree);
|
||||
BKE_node_tree_update_main_rooted(bmain, snode->edittree, nullptr);
|
||||
ED_node_set_active(bmain, snode, snode->edittree, node, nullptr);
|
||||
|
||||
snode_update(snode, node);
|
||||
@@ -288,9 +289,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op)
|
||||
BLI_freelistN(&input_links);
|
||||
|
||||
/* always last */
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -392,11 +391,7 @@ static int node_add_group_exec(bContext *C, wmOperator *op)
|
||||
id_us_plus(group_node->id);
|
||||
|
||||
nodeSetActive(ntree, group_node);
|
||||
ntreeUpdateTree(bmain, node_group);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, nullptr);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -487,12 +482,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op)
|
||||
id_us_plus(&object->id);
|
||||
|
||||
nodeSetActive(ntree, object_node);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, object_node);
|
||||
ED_node_tree_propagate_change(C, bmain, ntree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -587,14 +577,9 @@ static int node_add_texture_exec(bContext *C, wmOperator *op)
|
||||
id_us_plus(&texture->id);
|
||||
|
||||
nodeSetActive(ntree, texture_node);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, ntree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, texture_node);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -693,14 +678,9 @@ static int node_add_collection_exec(bContext *C, wmOperator *op)
|
||||
id_us_plus(&collection->id);
|
||||
|
||||
nodeSetActive(ntree, collection_node);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, ntree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, collection_node);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -817,8 +797,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -913,8 +892,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op)
|
||||
node->id = mask;
|
||||
id_us_plus(mask);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "DNA_light_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
#include "DNA_world_types.h"
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_workspace.h"
|
||||
@@ -63,6 +65,8 @@
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "MOD_nodes.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
@@ -440,6 +444,53 @@ void snode_notify(bContext *C, SpaceNode *snode)
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_tree_change(ID *id, bNodeTree *ntree)
|
||||
{
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, nullptr);
|
||||
|
||||
if (ntree->type == NTREE_SHADER) {
|
||||
if (GS(id->name) == ID_MA) {
|
||||
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, id);
|
||||
}
|
||||
else if (GS(id->name) == ID_LA) {
|
||||
WM_main_add_notifier(NC_LAMP | ND_LIGHTING, id);
|
||||
}
|
||||
else if (GS(id->name) == ID_WO) {
|
||||
WM_main_add_notifier(NC_WORLD | ND_WORLD, id);
|
||||
}
|
||||
}
|
||||
else if (ntree->type == NTREE_COMPOSIT) {
|
||||
WM_main_add_notifier(NC_SCENE | ND_NODES, id);
|
||||
}
|
||||
else if (ntree->type == NTREE_TEXTURE) {
|
||||
WM_main_add_notifier(NC_TEXTURE | ND_NODES, id);
|
||||
}
|
||||
else if (ntree->type == NTREE_GEOMETRY) {
|
||||
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, id);
|
||||
}
|
||||
}
|
||||
|
||||
void ED_node_tree_propagate_change(const bContext *UNUSED(C), Main *bmain, bNodeTree *ntree)
|
||||
{
|
||||
struct UserData {
|
||||
Main *bmain;
|
||||
} user_data = {bmain};
|
||||
|
||||
NodeTreeUpdateExtraParams params = {0};
|
||||
params.user_data = &user_data;
|
||||
params.tree_changed_fn = [](ID *id, bNodeTree *ntree, void *UNUSED(user_data)) {
|
||||
handle_tree_change(id, ntree);
|
||||
};
|
||||
params.tree_output_changed_fn = [](ID *id, bNodeTree *ntree, void *UNUSED(user_data)) {
|
||||
if (id != nullptr) {
|
||||
DEG_id_tag_update(id, 0);
|
||||
}
|
||||
DEG_id_tag_update(&ntree->id, 0);
|
||||
};
|
||||
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, ¶ms);
|
||||
}
|
||||
|
||||
void ED_node_set_tree_type(SpaceNode *snode, bNodeTreeType *typeinfo)
|
||||
{
|
||||
if (typeinfo) {
|
||||
@@ -490,7 +541,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
|
||||
}
|
||||
|
||||
ma->nodetree = ntreeCopyTree(bmain, ma_default->nodetree);
|
||||
ntreeUpdateTree(bmain, ma->nodetree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ma->nodetree, nullptr);
|
||||
}
|
||||
else if (ELEM(GS(id->name), ID_WO, ID_LA)) {
|
||||
/* Emission */
|
||||
@@ -530,7 +581,7 @@ void ED_node_shader_default(const bContext *C, ID *id)
|
||||
output->locx = 300.0f;
|
||||
output->locy = 300.0f;
|
||||
nodeSetActive(ntree, output);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, nullptr);
|
||||
}
|
||||
else {
|
||||
printf("ED_node_shader_default called on wrong ID type.\n");
|
||||
@@ -570,7 +621,7 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
|
||||
bNodeSocket *tosock = (bNodeSocket *)out->inputs.first;
|
||||
nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), sce->nodetree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(C), sce->nodetree, nullptr);
|
||||
}
|
||||
|
||||
/* assumes nothing being done in ntree yet, sets the default in/out node */
|
||||
@@ -600,7 +651,7 @@ void ED_node_texture_default(const bContext *C, Tex *tex)
|
||||
bNodeSocket *tosock = (bNodeSocket *)out->inputs.first;
|
||||
nodeAddLink(tex->nodetree, in, fromsock, out, tosock);
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), tex->nodetree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(C), tex->nodetree, nullptr);
|
||||
}
|
||||
|
||||
/* Here we set the active tree(s), even called for each redraw now, so keep it fast :) */
|
||||
@@ -712,14 +763,10 @@ void ED_node_set_active(
|
||||
}
|
||||
|
||||
node->flag |= NODE_DO_OUTPUT;
|
||||
if (was_output == 0) {
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
}
|
||||
}
|
||||
else if (do_update) {
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
}
|
||||
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
|
||||
if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) {
|
||||
/* If active texture changed, free glsl materials. */
|
||||
LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
|
||||
@@ -765,7 +812,7 @@ void ED_node_set_active(
|
||||
if (r_active_texture_changed) {
|
||||
*r_active_texture_changed = true;
|
||||
}
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
WM_main_add_notifier(NC_IMAGE, nullptr);
|
||||
}
|
||||
|
||||
@@ -782,7 +829,7 @@ void ED_node_set_active(
|
||||
|
||||
node->flag |= NODE_DO_OUTPUT;
|
||||
if (was_output == 0) {
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
|
||||
/* Adding a node doesn't link this yet. */
|
||||
@@ -797,11 +844,11 @@ void ED_node_set_active(
|
||||
}
|
||||
|
||||
node->flag |= NODE_DO_OUTPUT;
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
}
|
||||
else if (do_update) {
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
}
|
||||
else if (ntree->type == NTREE_TEXTURE) {
|
||||
@@ -1398,12 +1445,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
if (do_tag_update) {
|
||||
snode_dag_update(C, snode);
|
||||
}
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1495,8 +1537,7 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1663,7 +1704,7 @@ static int node_preview_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
||||
node_flag_toggle_exec(snode, NODE_PREVIEW);
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1742,7 +1783,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
|
||||
@@ -1783,10 +1824,7 @@ static int node_mute_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
if (do_tag_update) {
|
||||
snode_dag_update(C, snode);
|
||||
}
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1823,12 +1861,7 @@ static int node_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
if (do_tag_update) {
|
||||
snode_dag_update(C, snode);
|
||||
}
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1872,10 +1905,7 @@ static int node_switch_view_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1910,10 +1940,7 @@ static int node_delete_reconnect_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1960,7 +1987,7 @@ static int node_output_file_add_socket_exec(bContext *C, wmOperator *op)
|
||||
RNA_string_get(op->ptr, "file_path", file_path);
|
||||
ntreeCompositOutputFileAddSocket(ntree, node, file_path, &scene->r.im_format);
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -2009,7 +2036,7 @@ static int node_output_file_remove_active_socket_exec(bContext *C, wmOperator *U
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -2076,7 +2103,7 @@ static int node_output_file_move_active_socket_exec(bContext *C, wmOperator *op)
|
||||
nimf->active_input++;
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -2322,10 +2349,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ntreeUpdateTree(bmain, snode->edittree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, snode->edittree);
|
||||
/* Pasting nodes can create arbitrary new relations, because nodes can reference IDs. */
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
@@ -2393,10 +2417,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op)
|
||||
/* make the new socket active */
|
||||
sock->flag |= SELECT;
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
|
||||
@@ -2443,10 +2464,7 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *op)
|
||||
active_sock->flag |= SELECT;
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
|
||||
@@ -2497,7 +2515,7 @@ static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Need the extra update here because the loop above does not check for valid links in the node
|
||||
* group we're currently editing. */
|
||||
ntree->update |= NTREE_UPDATE_GROUP | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
|
||||
/* Deactivate sockets. */
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) {
|
||||
@@ -2506,10 +2524,7 @@ static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
|
||||
/* Make the new socket active. */
|
||||
iosock->flag |= SELECT;
|
||||
|
||||
ntreeUpdateTree(main, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, main, ntree);
|
||||
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
|
||||
@@ -2620,11 +2635,8 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_GROUP;
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, nullptr);
|
||||
|
||||
@@ -2940,7 +2952,7 @@ static int node_cryptomatte_add_socket_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
||||
ntreeCompositCryptomatteAddSocket(ntree, node);
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -2986,7 +2998,7 @@ static int node_cryptomatte_remove_socket_exec(bContext *C, wmOperator *UNUSED(o
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "DEG_depsgraph_build.h"
|
||||
@@ -391,7 +392,7 @@ static int node_group_ungroup(Main *bmain, bNodeTree *ntree, bNode *gnode)
|
||||
/* delete the group instance and dereference group tree */
|
||||
nodeRemoveNode(bmain, ntree, gnode, true);
|
||||
|
||||
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -410,16 +411,14 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (gnode->id && node_group_ungroup(bmain, snode->edittree, gnode)) {
|
||||
ntreeUpdateTree(bmain, snode->nodetree);
|
||||
BKE_node_tree_update_main_rooted(bmain, snode->edittree, nullptr);
|
||||
}
|
||||
else {
|
||||
BKE_report(op->reports, RPT_WARNING, "Cannot ungroup");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), nullptr);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -554,9 +553,9 @@ static int node_group_separate_selected(
|
||||
}
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
if (!make_copy) {
|
||||
ngroup->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ngroup);
|
||||
}
|
||||
|
||||
return 1;
|
||||
@@ -611,10 +610,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
|
||||
/* switch to parent tree */
|
||||
ED_node_tree_pop(snode);
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->nodetree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), nullptr);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -982,9 +978,9 @@ static void node_group_make_insert_selected(const bContext *C, bNodeTree *ntree,
|
||||
}
|
||||
|
||||
/* update of the group tree */
|
||||
ngroup->update |= NTREE_UPDATE | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ngroup);
|
||||
/* update of the tree containing the group instance node */
|
||||
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
}
|
||||
|
||||
static bNode *node_group_make_from_selected(const bContext *C,
|
||||
@@ -1014,7 +1010,7 @@ static bNode *node_group_make_from_selected(const bContext *C,
|
||||
node_group_make_insert_selected(C, ntree, gnode);
|
||||
|
||||
/* update of the tree containing the group instance node */
|
||||
ntree->update |= NTREE_UPDATE_NODES;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
|
||||
return gnode;
|
||||
}
|
||||
@@ -1044,14 +1040,10 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
|
||||
LISTBASE_FOREACH (bNode *, node, &ngroup->nodes) {
|
||||
sort_multi_input_socket_links(snode, node, nullptr, nullptr);
|
||||
}
|
||||
ntreeUpdateTree(bmain, ngroup);
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, nullptr);
|
||||
|
||||
/* We broke relations in node tree, need to rebuild them in the graphs. */
|
||||
DEG_relations_tag_update(bmain);
|
||||
@@ -1104,12 +1096,7 @@ static int node_group_insert_exec(bContext *C, wmOperator *op)
|
||||
|
||||
nodeSetActive(ntree, gnode);
|
||||
ED_node_tree_push(snode, ngroup, gnode);
|
||||
ntreeUpdateTree(bmain, ngroup);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, bmain, nullptr);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_node.h" /* own include */
|
||||
@@ -604,7 +605,7 @@ static void snode_autoconnect(Main *bmain,
|
||||
}
|
||||
|
||||
if (numlinks > 0) {
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, nullptr);
|
||||
}
|
||||
|
||||
BLI_freelistN(nodelist);
|
||||
@@ -851,7 +852,7 @@ static int link_socket_to_viewer(const bContext *C,
|
||||
else {
|
||||
link_to_change->fromnode = bnode_to_view;
|
||||
link_to_change->fromsock = bsocket_to_view;
|
||||
btree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link(btree);
|
||||
}
|
||||
|
||||
remove_links_to_unavailable_viewer_sockets(*btree, *viewer_bnode);
|
||||
@@ -860,7 +861,7 @@ static int link_socket_to_viewer(const bContext *C,
|
||||
ED_spreadsheet_context_paths_set_geometry_node(CTX_data_main(C), snode, viewer_bnode);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), btree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(C), btree, nullptr);
|
||||
snode_update(snode, viewer_bnode);
|
||||
DEG_id_tag_update(&btree->id, 0);
|
||||
|
||||
@@ -908,7 +909,7 @@ static int node_active_link_viewer_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
snode_notify(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1037,8 +1038,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
|
||||
|
||||
/* add link to the node tree */
|
||||
BLI_addtail(&ntree->links, link);
|
||||
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link(ntree);
|
||||
|
||||
/* tag tonode for update */
|
||||
link->tonode->update |= NODE_UPDATE;
|
||||
@@ -1058,11 +1058,7 @@ static void node_link_exit(bContext *C, wmOperator *op, bool apply_links)
|
||||
}
|
||||
ntree->is_updating = false;
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
snode_notify(C, snode);
|
||||
if (do_tag_update) {
|
||||
snode_dag_update(C, snode);
|
||||
}
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
|
||||
if (reset_view) {
|
||||
UI_view2d_edge_pan_cancel(C, &nldrag->pan_data);
|
||||
@@ -1425,9 +1421,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op)
|
||||
node_deselect_all_input_sockets(snode, false);
|
||||
node_deselect_all_output_sockets(snode, false);
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -1530,12 +1524,7 @@ static int cut_links_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
if (found) {
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
snode_notify(C, snode);
|
||||
if (do_tag_update) {
|
||||
snode_dag_update(C, snode);
|
||||
}
|
||||
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -1639,12 +1628,7 @@ static int mute_links_exec(bContext *C, wmOperator *op)
|
||||
link->flag &= ~NODE_LINK_TEST;
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), snode->edittree);
|
||||
snode_notify(C, snode);
|
||||
if (do_tag_update) {
|
||||
snode_dag_update(C, snode);
|
||||
}
|
||||
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -1695,11 +1679,7 @@ static int detach_links_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
|
||||
snode_notify(C, snode);
|
||||
snode_dag_update(C, snode);
|
||||
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), ntree);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -2616,7 +2596,7 @@ void ED_node_link_insert(Main *bmain, ScrArea *area)
|
||||
snode->runtime->iofsd = iofsd;
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, snode->edittree); /* needed for pointers */
|
||||
BKE_node_tree_update_main_rooted(bmain, snode->edittree, nullptr); /* needed for pointers */
|
||||
snode_update(snode, select);
|
||||
ED_node_tag_update_id((ID *)snode->edittree);
|
||||
ED_node_tag_update_id(snode->id);
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
@@ -84,7 +85,7 @@ static void node_link_item_apply(Main *bmain, bNode *node, NodeLinkItem *item)
|
||||
{
|
||||
if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) {
|
||||
node->id = (ID *)item->ngroup;
|
||||
ntreeUpdateTree(bmain, item->ngroup);
|
||||
BKE_node_tree_update_main_rooted(bmain, item->ngroup, nullptr);
|
||||
}
|
||||
else {
|
||||
/* nothing to do for now */
|
||||
@@ -180,9 +181,7 @@ static void node_socket_disconnect(Main *bmain,
|
||||
sock_to->flag |= SOCK_COLLAPSED;
|
||||
|
||||
nodeUpdate(ntree, node_to);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node_to);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
|
||||
/* remove all nodes connected to this socket, if they aren't connected to other nodes */
|
||||
@@ -196,9 +195,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN
|
||||
sock_to->flag |= SOCK_COLLAPSED;
|
||||
|
||||
nodeUpdate(ntree, node_to);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node_to);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
|
||||
/* add new node connected to this socket, or replace an existing one */
|
||||
@@ -301,9 +298,7 @@ static void node_socket_add_replace(const bContext *C,
|
||||
|
||||
nodeUpdate(ntree, node_from);
|
||||
nodeUpdate(ntree, node_to);
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
|
||||
ED_node_tag_update_nodetree(CTX_data_main(C), ntree, node_to);
|
||||
ED_node_tree_propagate_change(nullptr, bmain, ntree);
|
||||
}
|
||||
|
||||
/****************************** Node Link Menu *******************************/
|
||||
|
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "ED_node.h"
|
||||
@@ -246,7 +247,7 @@ void special_aftertrans_update__node(bContext *C, TransInfo *t)
|
||||
nodeRemoveNode(bmain, ntree, node, true);
|
||||
}
|
||||
}
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -180,7 +180,7 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i
|
||||
|
||||
if (node && is_image_texture_node(node)) {
|
||||
node->id = &ima->id;
|
||||
ED_node_tag_update_nodetree(bmain, ma->nodetree, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ma->nodetree);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -48,6 +48,7 @@
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
@@ -415,7 +416,7 @@ Material *BlenderStrokeRenderer::GetStrokeShader(Main *bmain,
|
||||
}
|
||||
|
||||
nodeSetActive(ntree, output_material);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
|
||||
return ma;
|
||||
}
|
||||
|
@@ -16,6 +16,8 @@
|
||||
|
||||
#include "Materials.h"
|
||||
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
MaterialNode::MaterialNode(bContext *C, Material *ma, KeyImageMap &key_image_map)
|
||||
: mContext(C), material(ma), effect(nullptr), key_image_map(&key_image_map)
|
||||
{
|
||||
@@ -107,7 +109,7 @@ bNodeTree *MaterialNode::prepare_material_nodetree()
|
||||
|
||||
void MaterialNode::update_material_nodetree()
|
||||
{
|
||||
ntreeUpdateTree(CTX_data_main(mContext), ntree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(mContext), ntree, NULL);
|
||||
}
|
||||
|
||||
bNode *MaterialNode::add_node(int node_type, int locx, int locy, std::string label)
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
@@ -340,7 +341,7 @@ void USDMaterialReader::import_usd_preview(Material *mtl,
|
||||
|
||||
nodeSetActive(ntree, output);
|
||||
|
||||
ntreeUpdateTree(bmain_, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain_, ntree, nullptr);
|
||||
|
||||
/* Optionally, set the material blend mode. */
|
||||
|
||||
|
@@ -159,7 +159,7 @@ typedef struct bNodeSocket {
|
||||
* restores pointer from matching own_index. */
|
||||
struct bNodeSocket *groupsock DNA_DEPRECATED;
|
||||
|
||||
/** A link pointer, set in ntreeUpdateTree. */
|
||||
/** A link pointer, set in BKE_node_tree_update_main. */
|
||||
struct bNodeLink *link;
|
||||
|
||||
/* XXX deprecated, socket input values are stored in default_value now.
|
||||
@@ -172,6 +172,9 @@ typedef struct bNodeSocket {
|
||||
* data. It has to be updated when the node declaration changes.
|
||||
*/
|
||||
const SocketDeclarationHandle *declaration;
|
||||
|
||||
uint8_t changed_flag;
|
||||
char _pad[7];
|
||||
} bNodeSocket;
|
||||
|
||||
/* sock->type */
|
||||
@@ -261,7 +264,7 @@ typedef struct bNode {
|
||||
/** Used as a boolean for execution. */
|
||||
uint8_t need_exec;
|
||||
|
||||
char _pad[1];
|
||||
uint8_t changed_flag;
|
||||
|
||||
/** Custom user-defined color. */
|
||||
float color[3];
|
||||
@@ -551,7 +554,8 @@ typedef struct bNodeTree {
|
||||
* in case multiple different editors are used and make context ambiguous.
|
||||
*/
|
||||
bNodeInstanceKey active_viewer_key;
|
||||
char _pad[4];
|
||||
char _pad[3];
|
||||
uint8_t changed_flag;
|
||||
|
||||
/** Execution data.
|
||||
*
|
||||
@@ -576,6 +580,31 @@ typedef struct bNodeTree {
|
||||
struct PreviewImage *preview;
|
||||
} bNodeTree;
|
||||
|
||||
/** bNodeSocket->changed_flag */
|
||||
typedef enum eNodeSocketChangedFlag {
|
||||
SOCK_CHANGED_NONE = 0,
|
||||
SOCK_CHANGED_ANY = (1 << 0),
|
||||
} eNodeSocketChangedFlag;
|
||||
|
||||
/** bNode->changed_flag */
|
||||
typedef enum eNodeChangedFlag {
|
||||
NODE_CHANGED_NONE = 0,
|
||||
NODE_CHANGED_ANY = (1 << 0),
|
||||
} eNodeChangedFlag;
|
||||
|
||||
/** bNodeTree->changed_flag */
|
||||
typedef enum eNodeTreeChangedFlag {
|
||||
NTREE_CHANGED_NONE = 0,
|
||||
NTREE_CHANGED_ANY = (1 << 0),
|
||||
NTREE_CHANGED_SOCKET = (1 << 1),
|
||||
NTREE_CHANGED_NODE = (1 << 2),
|
||||
NTREE_CHANGED_LINK = (1 << 3),
|
||||
NTREE_CHANGED_REMOVED_ANY = (1 << 4),
|
||||
NTREE_CHANGED_MISSING_RUNTIME_DATA = (1 << 5),
|
||||
NTREE_CHANGED_INTERFACE = (1 << 6),
|
||||
NTREE_CHANGED_ALL = -1,
|
||||
} eNodeTreeChangedFlag;
|
||||
|
||||
/* ntree->type, index */
|
||||
|
||||
#define NTREE_UNDEFINED -2 /* Represents #NodeTreeTypeUndefined type. */
|
||||
|
@@ -321,7 +321,7 @@ static void rna_ColorRamp_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
|
||||
CMP_NODE_VALTORGB,
|
||||
TEX_NODE_VALTORGB,
|
||||
GEO_NODE_LEGACY_ATTRIBUTE_COLOR_RAMP)) {
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@@ -168,7 +168,7 @@ static void rna_ImageUser_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
if (id) {
|
||||
if (GS(id->name) == ID_NT) {
|
||||
/* Special update for nodetrees to find parent datablock. */
|
||||
ED_node_tag_update_nodetree(bmain, (bNodeTree *)id, NULL);
|
||||
ED_node_tree_propagate_change(NULL, bmain, NULL);
|
||||
}
|
||||
else {
|
||||
/* Update material or texture for render preview. */
|
||||
|
@@ -41,6 +41,7 @@
|
||||
#include "BKE_cryptomatte.h"
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_texture.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
@@ -1186,7 +1187,7 @@ static void rna_NodeTree_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *p
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
|
||||
WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, NULL);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
|
||||
static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
|
||||
@@ -1235,7 +1236,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
|
||||
ntreeTexCheckCyclics(ntree);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(C), ntree, NULL);
|
||||
nodeUpdate(ntree, node);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
|
||||
@@ -1262,7 +1263,7 @@ static void rna_NodeTree_node_remove(bNodeTree *ntree,
|
||||
|
||||
RNA_POINTER_INVALIDATE(node_ptr);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree); /* update group node socket links */
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL); /* update group node socket links */
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -1282,7 +1283,7 @@ static void rna_NodeTree_node_clear(bNodeTree *ntree, Main *bmain, ReportList *r
|
||||
node = next_node;
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
@@ -1366,9 +1367,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
|
||||
nodeUpdate(ntree, tonode);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, ret->tonode);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
return ret;
|
||||
@@ -1393,7 +1392,7 @@ static void rna_NodeTree_link_remove(bNodeTree *ntree,
|
||||
nodeRemLink(ntree, link);
|
||||
RNA_POINTER_INVALIDATE(link_ptr);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -1412,7 +1411,7 @@ static void rna_NodeTree_link_clear(bNodeTree *ntree, Main *bmain, ReportList *r
|
||||
|
||||
link = next_link;
|
||||
}
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
@@ -1470,7 +1469,7 @@ static bNodeSocket *rna_NodeTree_inputs_new(
|
||||
|
||||
bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
|
||||
return sock;
|
||||
@@ -1485,7 +1484,7 @@ static bNodeSocket *rna_NodeTree_outputs_new(
|
||||
|
||||
bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
|
||||
return sock;
|
||||
@@ -1506,7 +1505,7 @@ static void rna_NodeTree_socket_remove(bNodeTree *ntree,
|
||||
else {
|
||||
ntreeRemoveSocketInterface(ntree, sock);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
DEG_id_tag_update(&ntree->id, 0);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
@@ -1522,7 +1521,7 @@ static void rna_NodeTree_inputs_clear(bNodeTree *ntree, Main *bmain, ReportList
|
||||
ntreeRemoveSocketInterface(ntree, socket);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -1536,7 +1535,7 @@ static void rna_NodeTree_outputs_clear(bNodeTree *ntree, Main *bmain, ReportList
|
||||
ntreeRemoveSocketInterface(ntree, socket);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -1565,9 +1564,9 @@ static void rna_NodeTree_inputs_move(bNodeTree *ntree, Main *bmain, int from_ind
|
||||
}
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_GROUP_IN;
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -1596,9 +1595,9 @@ static void rna_NodeTree_outputs_move(bNodeTree *ntree, Main *bmain, int from_in
|
||||
}
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_GROUP_OUT;
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -1606,10 +1605,8 @@ static void rna_NodeTree_interface_update(bNodeTree *ntree, bContext *C)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
|
||||
ntree->update |= NTREE_UPDATE_GROUP;
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, NULL);
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
|
||||
/* ******** NodeLink ******** */
|
||||
@@ -2489,7 +2486,8 @@ static void rna_Node_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
UNUSED_VARS(node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
|
||||
static void rna_Node_update_relations(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
@@ -2498,9 +2496,9 @@ static void rna_Node_update_relations(Main *bmain, Scene *scene, PointerRNA *ptr
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
static void rna_Node_socket_value_update(ID *id, bNode *node, bContext *C)
|
||||
static void rna_Node_socket_value_update(ID *id, bNode *UNUSED(node), bContext *C)
|
||||
{
|
||||
ED_node_tag_update_nodetree(CTX_data_main(C), (bNodeTree *)id, node);
|
||||
ED_node_tree_propagate_change(C, CTX_data_main(C), (bNodeTree *)id);
|
||||
}
|
||||
|
||||
static void rna_Node_select_set(PointerRNA *ptr, bool value)
|
||||
@@ -2554,7 +2552,7 @@ static bNodeSocket *rna_Node_inputs_new(ID *id,
|
||||
BKE_report(reports, RPT_ERROR, "Unable to create socket");
|
||||
}
|
||||
else {
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -2588,7 +2586,7 @@ static bNodeSocket *rna_Node_outputs_new(ID *id,
|
||||
BKE_report(reports, RPT_ERROR, "Unable to create socket");
|
||||
}
|
||||
else {
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -2606,7 +2604,7 @@ static void rna_Node_socket_remove(
|
||||
else {
|
||||
nodeRemoveSocket(ntree, node, sock);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
}
|
||||
@@ -2621,7 +2619,7 @@ static void rna_Node_inputs_clear(ID *id, bNode *node, Main *bmain)
|
||||
nodeRemoveSocket(ntree, node, sock);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -2635,7 +2633,7 @@ static void rna_Node_outputs_clear(ID *id, bNode *node, Main *bmain)
|
||||
nodeRemoveSocket(ntree, node, sock);
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -2667,7 +2665,7 @@ static void rna_Node_inputs_move(ID *id, bNode *node, Main *bmain, int from_inde
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -2699,7 +2697,7 @@ static void rna_Node_outputs_move(ID *id, bNode *node, Main *bmain, int from_ind
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
}
|
||||
|
||||
@@ -2928,9 +2926,8 @@ static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNodeSocket *sock = (bNodeSocket *)ptr->data;
|
||||
bNode *node;
|
||||
if (nodeFindNode(ntree, sock, &node, NULL)) {
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
}
|
||||
UNUSED_VARS(sock, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
|
||||
static bool rna_NodeSocket_is_output_get(PointerRNA *ptr)
|
||||
@@ -3220,10 +3217,8 @@ static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), Po
|
||||
return;
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_GROUP;
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, NULL);
|
||||
BKE_node_tree_update_tag_interface(ntree);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
|
||||
/* ******** Standard Node Socket Base Types ******** */
|
||||
@@ -3342,7 +3337,7 @@ static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C,
|
||||
rna_NodeSocketStandard_value_update(C, ptr);
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
Main *bmain = CTX_data_main(C);
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, NULL);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
@@ -3589,21 +3584,17 @@ static void rna_Node_tex_image_update(Main *bmain, Scene *UNUSED(scene), Pointer
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
UNUSED_VARS(node);
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
WM_main_add_notifier(NC_IMAGE, NULL);
|
||||
}
|
||||
|
||||
static void rna_NodeGroup_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
|
||||
{
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
bNode *node = (bNode *)ptr->data;
|
||||
|
||||
if (node->id) {
|
||||
ntreeUpdateTree(bmain, (bNodeTree *)node->id);
|
||||
}
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
@@ -4264,7 +4255,7 @@ static bNodeSocket *rna_NodeOutputFile_slots_new(
|
||||
|
||||
sock = ntreeCompositOutputFileAddSocket(ntree, node, name, im_format);
|
||||
|
||||
ntreeUpdateTree(CTX_data_main(C), ntree);
|
||||
BKE_node_tree_update_main_rooted(CTX_data_main(C), ntree, NULL);
|
||||
WM_main_add_notifier(NC_NODE | NA_EDITED, ntree);
|
||||
|
||||
return sock;
|
||||
@@ -4373,7 +4364,7 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
|
||||
RE_engine_free(engine);
|
||||
}
|
||||
|
||||
ED_node_tag_update_nodetree(bmain, ntree, node);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
|
||||
static void rna_ShaderNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
|
@@ -199,7 +199,7 @@ static void rna_Texture_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *pt
|
||||
}
|
||||
else if (GS(id->name) == ID_NT) {
|
||||
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
|
||||
ED_node_tag_update_nodetree(bmain, ntree, NULL);
|
||||
ED_node_tree_propagate_change(NULL, bmain, ntree);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -60,6 +60,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_pointcloud.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -695,7 +696,7 @@ void MOD_nodes_init(Main *bmain, NodesModifierData *nmd)
|
||||
group_input_node,
|
||||
(bNodeSocket *)group_input_node->outputs.first);
|
||||
|
||||
ntreeUpdateTree(bmain, ntree);
|
||||
BKE_node_tree_update_main_rooted(bmain, ntree, nullptr);
|
||||
}
|
||||
|
||||
static void initialize_group_input(NodesModifierData &nmd,
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "RNA_types.h"
|
||||
|
||||
@@ -145,7 +146,7 @@ static bNodeSocket *group_verify_socket(bNodeTree *ntree,
|
||||
if (sock->typeinfo != iosock->typeinfo) {
|
||||
nodeModifySocketType(ntree, gnode, sock, iosock->idname);
|
||||
/* Flag the tree to make sure link validity is updated after type changes. */
|
||||
ntree->update |= NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag_link(ntree);
|
||||
}
|
||||
|
||||
if (iosock->typeinfo->interface_verify_socket) {
|
||||
|
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -172,7 +173,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context,
|
||||
/* Using global main here is likely totally wrong, not sure what to do about that one though...
|
||||
* We cannot even check ntree is in global main,
|
||||
* since most of the time it won't be (thanks to ntree design)!!! */
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, nullptr);
|
||||
|
||||
/* get a dependency-sorted list of nodes */
|
||||
ntreeGetDependencyList(ntree, &nodelist, &totnodes);
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_linestyle.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_node_tree_update.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
@@ -375,7 +376,7 @@ static void ntree_shader_unlink_hidden_value_sockets(bNode *group_node, bNodeSoc
|
||||
}
|
||||
|
||||
if (removed_link) {
|
||||
ntreeUpdateTree(G.main, group_ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, group_ntree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +435,7 @@ static void ntree_shader_groups_expand_inputs(bNodeTree *localtree)
|
||||
}
|
||||
|
||||
if (link_added) {
|
||||
ntreeUpdateTree(G.main, localtree);
|
||||
BKE_node_tree_update_main_rooted(G.main, localtree, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,7 +515,7 @@ static void flatten_group_do(bNodeTree *ntree, bNode *gnode)
|
||||
ntreeFreeLocalNode(ntree, node);
|
||||
}
|
||||
|
||||
ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
|
||||
BKE_node_tree_update_tag(ntree);
|
||||
}
|
||||
|
||||
/* Flatten group to only have a simple single tree */
|
||||
@@ -539,7 +540,7 @@ static void ntree_shader_groups_flatten(bNodeTree *localtree)
|
||||
}
|
||||
}
|
||||
|
||||
ntreeUpdateTree(G.main, localtree);
|
||||
BKE_node_tree_update_main_rooted(G.main, localtree, NULL);
|
||||
}
|
||||
|
||||
/* Check whether shader has a displacement.
|
||||
@@ -559,7 +560,7 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
|
||||
return false;
|
||||
}
|
||||
/* Make sure sockets links pointers are correct. */
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
|
||||
bNodeSocket *displacement = ntree_shader_node_find_input(output_node, "Displacement");
|
||||
|
||||
if (displacement == NULL) {
|
||||
@@ -648,7 +649,7 @@ static void ntree_shader_bypass_tagged_bump_nodes(bNodeTree *ntree)
|
||||
ntree_shader_bypass_bump_link(ntree, node, link);
|
||||
}
|
||||
}
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
|
||||
}
|
||||
|
||||
static bool ntree_branch_count_and_tag_nodes(bNode *fromnode, bNode *tonode, void *userdata)
|
||||
@@ -733,7 +734,7 @@ static void ntree_shader_copy_branch_displacement(bNodeTree *ntree,
|
||||
nodeRemLink(ntree, displacement_link);
|
||||
nodeAddLink(ntree, displacement_node, displacement_socket, tonode, tosock);
|
||||
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
|
||||
}
|
||||
|
||||
/* Re-link displacement output to unconnected normal sockets via bump node.
|
||||
@@ -797,12 +798,12 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree, bNode *output_nod
|
||||
geo_node->tmp_flag = -2;
|
||||
bump_node->tmp_flag = -2;
|
||||
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
|
||||
|
||||
/* Connect all free-standing Normal inputs and relink geometry/coordinate nodes. */
|
||||
ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
|
||||
/* We modified the tree, it needs to be updated now. */
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
|
||||
}
|
||||
|
||||
static void node_tag_branch_as_derivative(bNode *node, int dx)
|
||||
@@ -882,7 +883,7 @@ void ntree_shader_tag_nodes(bNodeTree *ntree, bNode *output_node, nTreeTags *tag
|
||||
return;
|
||||
}
|
||||
/* Make sure sockets links pointers are correct. */
|
||||
ntreeUpdateTree(G.main, ntree);
|
||||
BKE_node_tree_update_main_rooted(G.main, ntree, NULL);
|
||||
|
||||
nodeChainIterBackwards(ntree, output_node, ntree_tag_bsdf_cb, tags, 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user