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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2019-04-20 21:25:22 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2019-04-24 13:44:27 +0300
commitd730e512ac56bd68c75f8c44ff186b51010db4c7 (patch)
treedddf69daf78ac1627db7069ef3012b8ecb54017f /source/blender/blenkernel
parent62421470ee09fb70f343eb9fd48b093316c8eea1 (diff)
Nodes: avoid slow and unecessary node group updates on file read
On file read we need to update group nodes in case the group they refer to has changed its inputs and outputs. This had O(n^2) time complexity and was updating all datablocks even if they did not change.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_node.h16
-rw-r--r--source/blender/blenkernel/intern/library_remap.c11
-rw-r--r--source/blender/blenkernel/intern/node.c52
3 files changed, 50 insertions, 29 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 682d0b981fa..70b4903e746 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -218,7 +218,7 @@ typedef struct bNodeType {
/// Called when the node is updated in the editor.
void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node);
/// Check and update if internal ID data has changed.
- void (*verifyfunc)(struct bNodeTree *ntree, struct bNode *node, struct ID *id);
+ void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node);
/// Initialize a new node instance of this type after creation.
void (*initfunc)(struct bNodeTree *ntree, struct bNode *node);
@@ -395,10 +395,8 @@ 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);
-/* XXX Currently each tree update call does call to ntreeVerifyNodes too.
- * Some day this should be replaced by a decent depsgraph automatism!
- */
-void ntreeVerifyNodes(struct Main *main, struct ID *id);
+void ntreeUpdateAllNew(struct Main *main);
+void ntreeUpdateAllUsers(struct Main *main, struct ID *id);
void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes);
@@ -736,10 +734,10 @@ void node_type_label(
struct bNodeType *ntype,
void (*labelfunc)(struct bNodeTree *ntree, struct bNode *, char *label, int maxlen));
void node_type_update(struct bNodeType *ntype,
- void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node),
- void (*verifyfunc)(struct bNodeTree *ntree,
- struct bNode *node,
- struct ID *id));
+ void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node));
+void node_type_group_update(struct bNodeType *ntype,
+ void (*group_update_func)(struct bNodeTree *ntree,
+ struct bNode *node));
void node_type_exec(struct bNodeType *ntype,
NodeInitExecFunction initexecfunc,
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 7657b47bcf5..4ed3c4f9501 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -387,15 +387,8 @@ 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)
{
- /* Verify all nodetree user nodes. */
- ntreeVerifyNodes(bmain, new_id);
-
- /* Update node trees as necessary. */
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- /* make an update call for the tree */
- ntreeUpdateTree(bmain, ntree);
- }
- FOREACH_NODETREE_END;
+ /* Update all group nodes using a node group. */
+ ntreeUpdateAllUsers(bmain, new_id);
}
/**
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 0fbddaf3597..3b46727c33f 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -3206,16 +3206,44 @@ static void ntree_validate_links(bNodeTree *ntree)
}
}
-void ntreeVerifyNodes(struct Main *main, struct ID *id)
+void ntreeUpdateAllNew(Main *main)
{
+ /* 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) {
- bNode *node;
+ if (owner_id->tag & LIB_TAG_NEW) {
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->typeinfo->group_update_func) {
+ node->typeinfo->group_update_func(ntree, node);
+ }
+ }
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->typeinfo->verifyfunc) {
- node->typeinfo->verifyfunc(ntree, node, id);
+ ntreeUpdateTree(NULL, ntree);
+ }
+ }
+ FOREACH_NODETREE_END;
+}
+
+void ntreeUpdateAllUsers(Main *main, ID *ngroup)
+{
+ /* Update all users of ngroup, to add/remove sockets as needed. */
+ FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
+ bool need_update = false;
+
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->id == ngroup) {
+ if (node->typeinfo->group_update_func) {
+ node->typeinfo->group_update_func(ntree, node);
+ }
+
+ need_update = true;
}
}
+
+ if (need_update) {
+ ntreeUpdateTree(NULL, ntree);
+ }
}
FOREACH_NODETREE_END;
}
@@ -3264,7 +3292,7 @@ void ntreeUpdateTree(Main *bmain, bNodeTree *ntree)
/* XXX hack, should be done by depsgraph!! */
if (bmain) {
- ntreeVerifyNodes(bmain, &ntree->id);
+ ntreeUpdateAllUsers(bmain, &ntree->id);
}
if (ntree->update & (NTREE_UPDATE_LINKS | NTREE_UPDATE_NODES)) {
@@ -3581,13 +3609,15 @@ void node_type_label(
}
void node_type_update(struct bNodeType *ntype,
- void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node),
- void (*verifyfunc)(struct bNodeTree *ntree,
- struct bNode *node,
- struct ID *id))
+ void (*updatefunc)(struct bNodeTree *ntree, struct bNode *node))
{
ntype->updatefunc = updatefunc;
- ntype->verifyfunc = verifyfunc;
+}
+
+void node_type_group_update(struct bNodeType *ntype,
+ void (*group_update_func)(struct bNodeTree *ntree, struct bNode *node))
+{
+ ntype->group_update_func = group_update_func;
}
void node_type_exec(struct bNodeType *ntype,