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:
-rw-r--r--source/blender/blenkernel/BKE_node.h24
-rw-r--r--source/blender/blenkernel/intern/lamp.c4
-rw-r--r--source/blender/blenkernel/intern/library.c4
-rw-r--r--source/blender/blenkernel/intern/material.c12
-rw-r--r--source/blender/blenkernel/intern/node.c65
-rw-r--r--source/blender/blenkernel/intern/scene.c6
-rw-r--r--source/blender/blenkernel/intern/texture.c4
-rw-r--r--source/blender/blenkernel/intern/world.c4
-rw-r--r--source/blender/editors/space_node/node_group.c2
9 files changed, 92 insertions, 33 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index c45afbe77a9..2a0679e3977 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -301,21 +301,29 @@ struct bNodeType *ntreeGetNodeType(struct bNodeTree *ntree);
struct bNodeSocketType *ntreeGetSocketType(int type);
struct bNodeTree *ntreeAddTree(const char *name, int type, int nodetype);
-void ntreeInitTypes(struct bNodeTree *ntree);
+void ntreeInitTypes(struct bNodeTree *ntree);
-void ntreeFreeTree(struct bNodeTree *ntree);
+/* copy/free funcs, need to manage ID users */
+void ntreeFreeTree_ex(struct bNodeTree *ntree, const short do_id_user);
+void ntreeFreeTree(struct bNodeTree *ntree);
+struct bNodeTree *ntreeCopyTree_ex(struct bNodeTree *ntree, const short do_id_user);
struct bNodeTree *ntreeCopyTree(struct bNodeTree *ntree);
-void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to);
-void ntreeMakeLocal(struct bNodeTree *ntree);
-int ntreeHasType(struct bNodeTree *ntree, int type);
+void ntreeSwitchID_ex(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to, const short do_id_user);
+void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to);
+/* node->id user count */
+void ntreeUserIncrefID(struct bNodeTree *ntree);
+void ntreeUserDecrefID(struct bNodeTree *ntree);
-void ntreeUpdateTree(struct bNodeTree *ntree);
+
+void ntreeMakeLocal(struct bNodeTree *ntree);
+int ntreeHasType(struct bNodeTree *ntree, int type);
+void ntreeUpdateTree(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 ntreeVerifyNodes(struct Main *main, struct ID *id);
-void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes);
+void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, int *totnodes);
/* XXX old trees handle output flags automatically based on special output node types and last active selection.
* new tree types have a per-output socket flag to indicate the final output to use explicitly.
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 4782d09a7c8..6a802236ec4 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -120,7 +120,7 @@ Lamp *BKE_lamp_copy(Lamp *la)
lan->curfalloff = curvemapping_copy(la->curfalloff);
if (la->nodetree)
- lan->nodetree = ntreeCopyTree(la->nodetree);
+ lan->nodetree = ntreeCopyTree_ex(la->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
if (la->preview)
lan->preview = BKE_previewimg_copy(la->preview);
@@ -223,7 +223,7 @@ void BKE_lamp_free(Lamp *la)
/* is no lib link block, but lamp extension */
if (la->nodetree) {
- ntreeFreeTree(la->nodetree);
+ ntreeFreeTree_ex(la->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(la->nodetree);
}
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index e073cfdf76d..f1d1d128c16 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -348,7 +348,7 @@ int id_copy(ID *id, ID **newid, int test)
if (!test) *newid = (ID *)BKE_action_copy((bAction *)id);
return 1;
case ID_NT:
- if (!test) *newid = (ID *)ntreeCopyTree((bNodeTree *)id);
+ if (!test) *newid = (ID *)ntreeCopyTree_ex((bNodeTree *)id, FALSE); /* TODO: do_id_user arg needs checking */
return 1;
case ID_BR:
if (!test) *newid = (ID *)BKE_brush_copy((Brush *)id);
@@ -881,7 +881,7 @@ void BKE_libblock_free(ListBase *lb, void *idv)
BKE_action_free((bAction *)id);
break;
case ID_NT:
- ntreeFreeTree((bNodeTree *)id);
+ ntreeFreeTree_ex((bNodeTree *)id, FALSE); /* TODO: do_id_user arg needs checking */
break;
case ID_BR:
BKE_brush_free((Brush *)id);
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index e5f392e4bce..a1288b8af08 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -101,7 +101,7 @@ void BKE_material_free(Material *ma)
/* is no lib link block, but material extension */
if (ma->nodetree) {
- ntreeFreeTree(ma->nodetree);
+ ntreeFreeTree_ex(ma->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(ma->nodetree);
}
@@ -235,7 +235,7 @@ Material *BKE_material_copy(Material *ma)
if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
if (ma->nodetree) {
- man->nodetree = ntreeCopyTree(ma->nodetree); /* 0 == full new tree */
+ man->nodetree = ntreeCopyTree_ex(ma->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
}
man->gpumaterial.first = man->gpumaterial.last = NULL;
@@ -1511,7 +1511,7 @@ void free_matcopybuf(void)
matcopybuf.ramp_spec = NULL;
if (matcopybuf.nodetree) {
- ntreeFreeTree(matcopybuf.nodetree);
+ ntreeFreeTree_ex(matcopybuf.nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(matcopybuf.nodetree);
matcopybuf.nodetree = NULL;
}
@@ -1537,7 +1537,7 @@ void copy_matcopybuf(Material *ma)
matcopybuf.mtex[a] = MEM_dupallocN(mtex);
}
}
- matcopybuf.nodetree = ntreeCopyTree(ma->nodetree);
+ matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
matcopybuf.preview = NULL;
matcopybuf.gpumaterial.first = matcopybuf.gpumaterial.last = NULL;
matcopied = 1;
@@ -1561,7 +1561,7 @@ void paste_matcopybuf(Material *ma)
}
if (ma->nodetree) {
- ntreeFreeTree(ma->nodetree);
+ ntreeFreeTree_ex(ma->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(ma->nodetree);
}
@@ -1582,7 +1582,7 @@ void paste_matcopybuf(Material *ma)
}
}
- ma->nodetree = ntreeCopyTree(matcopybuf.nodetree);
+ ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, FALSE); /* TODO: do_id_user arg needs checking */
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 62e80645a35..56ae912756e 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -671,7 +671,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
* copying for internal use (threads for eg), where you wont want it to modify the
* scene data.
*/
-static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_extern)
+static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_user, const short do_make_extern)
{
bNodeTree *newtree;
bNode *node /*, *nnode */ /* UNUSED */, *last;
@@ -702,6 +702,11 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e
last = ntree->nodes.last;
for (node = ntree->nodes.first; node; node = node->next) {
+ /* ntreeUserDecrefID inline */
+ if (do_id_user) {
+ id_us_min(node->id);
+ }
+
if (do_make_extern) {
id_lib_extern(node->id);
}
@@ -751,22 +756,56 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e
return newtree;
}
+bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, const short do_id_user)
+{
+ return ntreeCopyTree_internal(ntree, do_id_user, TRUE);
+}
bNodeTree *ntreeCopyTree(bNodeTree *ntree)
{
- return ntreeCopyTree_internal(ntree, TRUE);
+ return ntreeCopyTree_ex(ntree, TRUE);
}
/* use when duplicating scenes */
-void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
+void ntreeSwitchID_ex(bNodeTree *ntree, ID *id_from, ID *id_to, const short do_id_user)
{
bNode *node;
+
+ if (id_from == id_to) {
+ /* should never happen but may as well skip if it does */
+ return;
+ }
+
/* for scene duplication only */
for (node = ntree->nodes.first; node; node = node->next) {
if (node->id == id_from) {
+ if (do_id_user) {
+ id_us_min(id_from);
+ id_us_plus(id_to);
+ }
+
node->id = id_to;
}
}
}
+void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
+{
+ ntreeSwitchID_ex(ntree, id_from, id_to, TRUE);
+}
+
+void ntreeUserIncrefID(bNodeTree *ntree)
+{
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ id_us_plus(node->id);
+ }
+}
+void ntreeUserDecrefID(bNodeTree *ntree)
+{
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ id_us_min(node->id);
+ }
+}
/* *************** preview *********** */
/* if node->preview, then we assume the rect to exist */
@@ -913,6 +952,7 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
}
}
+/** \note caller needs to manage node->id user */
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock, *nextsock;
@@ -956,7 +996,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
}
/* do not free ntree itself here, BKE_libblock_free calls this function too */
-void ntreeFreeTree(bNodeTree *ntree)
+void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
{
bNode *node, *next;
bNodeSocket *sock;
@@ -990,6 +1030,12 @@ void ntreeFreeTree(bNodeTree *ntree)
for (node = ntree->nodes.first; node; node = next) {
next = node->next;
+
+ /* ntreeUserIncrefID inline */
+ if (do_id_user) {
+ id_us_min(node->id);
+ }
+
nodeFreeNode(ntree, node);
}
@@ -1000,6 +1046,11 @@ void ntreeFreeTree(bNodeTree *ntree)
node_socket_free_default_value(sock->type, sock->default_value);
BLI_freelistN(&ntree->outputs);
}
+/* same as ntreeFreeTree_ex but always manage users */
+void ntreeFreeTree(bNodeTree *ntree)
+{
+ ntreeFreeTree_ex(ntree, TRUE);
+}
void ntreeFreeCache(bNodeTree *ntree)
{
@@ -1137,7 +1188,7 @@ void ntreeMakeLocal(bNodeTree *ntree)
}
else if (cd.local && cd.lib) {
/* this is the mixed case, we copy the tree and assign it to local users */
- bNodeTree *newtree = ntreeCopyTree(ntree);
+ bNodeTree *newtree = ntreeCopyTree_ex(ntree, FALSE); /* TODO: do_id_user arg needs checking */
newtree->id.us = 0;
@@ -1188,7 +1239,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
}
/* node copy func */
- ltree = ntreeCopyTree_internal(ntree, FALSE);
+ ltree = ntreeCopyTree_internal(ntree, FALSE, FALSE);
if (adt) {
AnimData *ladt = BKE_animdata_from_id(&ltree->id);
@@ -1248,7 +1299,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
if (ntreetype->local_merge)
ntreetype->local_merge(localtree, ntree);
- ntreeFreeTree(localtree);
+ ntreeFreeTree_ex(localtree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(localtree);
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d476e90498c..4fd08c8f6f8 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -153,8 +153,8 @@ Scene *BKE_scene_copy(Scene *sce, int type)
BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
if (sce->nodetree) {
- scen->nodetree = ntreeCopyTree(sce->nodetree); /* copies actions */
- ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
+ scen->nodetree = ntreeCopyTree_ex(sce->nodetree, FALSE); /* TODO: do_id_user arg needs checking */ /* copies actions */
+ ntreeSwitchID_ex(scen->nodetree, &sce->id, &scen->id, FALSE);
}
obase = sce->base.first;
@@ -321,7 +321,7 @@ void BKE_scene_free(Scene *sce)
}
if (sce->nodetree) {
- ntreeFreeTree(sce->nodetree);
+ ntreeFreeTree_ex(sce->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(sce->nodetree);
}
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 2f54fe6cebd..66b096b14f1 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -430,7 +430,7 @@ void BKE_texture_free(Tex *tex)
tex->id.icon_id = 0;
if (tex->nodetree) {
- ntreeFreeTree(tex->nodetree);
+ ntreeFreeTree_ex(tex->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(tex->nodetree);
}
}
@@ -697,7 +697,7 @@ Tex *BKE_texture_copy(Tex *tex)
if (tex->nodetree->execdata) {
ntreeTexEndExecTree(tex->nodetree->execdata, 1);
}
- texn->nodetree = ntreeCopyTree(tex->nodetree);
+ texn->nodetree = ntreeCopyTree_ex(tex->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
}
return texn;
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index dd71e43182e..418d7da6b85 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -67,7 +67,7 @@ void BKE_world_free(World *wrld)
/* is no lib link block, but world extension */
if (wrld->nodetree) {
- ntreeFreeTree(wrld->nodetree);
+ ntreeFreeTree_ex(wrld->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
MEM_freeN(wrld->nodetree);
}
@@ -129,7 +129,7 @@ World *BKE_world_copy(World *wrld)
}
if (wrld->nodetree) {
- wrldn->nodetree = ntreeCopyTree(wrld->nodetree);
+ wrldn->nodetree = ntreeCopyTree_ex(wrld->nodetree, FALSE); /* TODO: do_id_user arg needs checking */
}
if (wrld->preview)
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index efd2378bf31..4e3529738e6 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -424,7 +424,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
* - all of wgroup's nodes are transferred across to their new home
* - ngroup (i.e. the source NodeTree) is left unscathed
*/
- wgroup = ntreeCopyTree(ngroup);
+ wgroup = ntreeCopyTree_ex(ngroup, FALSE); /* TODO: do_id_user arg needs checking */
/* add the nodes into the ntree */
for (node = wgroup->nodes.first; node; node = nextn) {