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.
This commit is contained in:
2019-04-20 20:25:22 +02:00
parent 62421470ee
commit d730e512ac
20 changed files with 119 additions and 124 deletions

View File

@@ -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,

View File

@@ -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);
}
/**

View File

@@ -3206,15 +3206,43 @@ 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;
for (node = ntree->nodes.first; node; node = node->next) {
if (node->typeinfo->verifyfunc) {
node->typeinfo->verifyfunc(ntree, node, id);
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);
}
}
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,