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:
authorLukas Toenne <lukas.toenne@googlemail.com>2012-08-02 13:52:37 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2012-08-02 13:52:37 +0400
commit9d2173518cd7da7d18bb032c8537c8952abc2b78 (patch)
tree5fd02e1b8013ed6a37915cacfabb960dd9f66877 /source/blender/blenkernel/intern
parent0a782a4550904cdec15efbf5bf81c8be144896ee (diff)
Clipboard feature for nodes. With the Copy operator a copy of all selected nodes and links between them is stored in an offscreen list (not in the library). The Paste operator then in turn copies these into the active node tree in the editor.
Currently does not support copying of animation data. This would require copying of individual fcurves etc. between data block, which is not implemented yet. Also it is currently possible to circumvent some constraints of the nodes, in particular for node groups (e.g. no groups inside groups, render layer not inside groups).
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/node.c109
1 files changed, 88 insertions, 21 deletions
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 592bc10424f..565e2de79f8 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -347,9 +347,12 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
bNodeSocket *sock, *oldsock;
*nnode = *node;
- nodeUniqueName(ntree, nnode);
-
- BLI_addtail(&ntree->nodes, nnode);
+ /* can be called for nodes outside a node tree (e.g. clipboard) */
+ if (ntree) {
+ nodeUniqueName(ntree, nnode);
+
+ BLI_addtail(&ntree->nodes, nnode);
+ }
BLI_duplicatelist(&nnode->inputs, &node->inputs);
oldsock = node->inputs.first;
@@ -390,7 +393,8 @@ bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
nnode->new_node = NULL;
nnode->preview = NULL;
- ntree->update |= NTREE_UPDATE_NODES;
+ if (ntree)
+ ntree->update |= NTREE_UPDATE_NODES;
return nnode;
}
@@ -417,7 +421,7 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
from = -1; /* OK but flip */
}
}
- else {
+ else if (ntree) {
/* check tree sockets */
for (sock = ntree->inputs.first; sock; sock = sock->next)
if (sock == fromsock)
@@ -446,7 +450,7 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
to = -1; /* OK but flip */
}
}
- else {
+ else if (ntree) {
/* check tree sockets */
for (sock = ntree->outputs.first; sock; sock = sock->next)
if (sock == tosock)
@@ -464,7 +468,8 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
if (from >= 0 && to >= 0) {
link = MEM_callocN(sizeof(bNodeLink), "link");
- BLI_addtail(&ntree->links, link);
+ if (ntree)
+ BLI_addtail(&ntree->links, link);
link->fromnode = fromnode;
link->fromsock = fromsock;
link->tonode = tonode;
@@ -472,26 +477,32 @@ bNodeLink *nodeAddLink(bNodeTree *ntree, bNode *fromnode, bNodeSocket *fromsock,
}
else if (from <= 0 && to <= 0) {
link = MEM_callocN(sizeof(bNodeLink), "link");
- BLI_addtail(&ntree->links, link);
+ if (ntree)
+ BLI_addtail(&ntree->links, link);
link->fromnode = tonode;
link->fromsock = tosock;
link->tonode = fromnode;
link->tosock = fromsock;
}
- ntree->update |= NTREE_UPDATE_LINKS;
+ if (ntree)
+ ntree->update |= NTREE_UPDATE_LINKS;
return link;
}
void nodeRemLink(bNodeTree *ntree, bNodeLink *link)
{
- BLI_remlink(&ntree->links, link);
+ /* can be called for links outside a node tree (e.g. clipboard) */
+ if (ntree)
+ BLI_remlink(&ntree->links, link);
+
if (link->tosock)
link->tosock->link = NULL;
MEM_freeN(link);
- ntree->update |= NTREE_UPDATE_LINKS;
+ if (ntree)
+ ntree->update |= NTREE_UPDATE_LINKS;
}
void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
@@ -885,20 +896,24 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
- bNodeTreeType *treetype = ntreeGetType(ntree->type);
bNodeSocket *sock, *nextsock;
- /* remove all references to this node */
- nodeUnlinkNode(ntree, node);
- node_unlink_attached(ntree, node);
-
- BLI_remlink(&ntree->nodes, node);
+ /* can be called for nodes outside a node tree (e.g. clipboard) */
+ if (ntree) {
+ bNodeTreeType *treetype = ntreeGetType(ntree->type);
+
+ /* remove all references to this node */
+ nodeUnlinkNode(ntree, node);
+ node_unlink_attached(ntree, node);
+
+ BLI_remlink(&ntree->nodes, node);
+
+ if (treetype->free_node_cache)
+ treetype->free_node_cache(ntree, node);
+ }
/* since it is called while free database, node->id is undefined */
- if (treetype->free_node_cache)
- treetype->free_node_cache(ntree, node);
-
if (node->typeinfo && node->typeinfo->freestoragefunc)
node->typeinfo->freestoragefunc(node);
@@ -917,7 +932,8 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
MEM_freeN(node);
- ntree->update |= NTREE_UPDATE_NODES;
+ if (ntree)
+ ntree->update |= NTREE_UPDATE_NODES;
}
/* do not free ntree itself here, BKE_libblock_free calls this function too */
@@ -1388,6 +1404,53 @@ void nodeSocketSetType(bNodeSocket *sock, int type)
node_socket_free_default_value(old_type, old_default_value);
}
+/* ************** Node Clipboard *********** */
+
+typedef struct bNodeClipboard {
+ ListBase nodes;
+ ListBase links;
+} bNodeClipboard;
+
+bNodeClipboard node_clipboard;
+
+void nodeClipboardClear(void)
+{
+ bNode *node, *node_next;
+ bNodeLink *link, *link_next;
+
+ for (link = node_clipboard.links.first; link; link=link_next) {
+ link_next = link->next;
+ nodeRemLink(NULL, link);
+ }
+ node_clipboard.links.first = node_clipboard.links.last = NULL;
+
+ for (node = node_clipboard.nodes.first; node; node=node_next) {
+ node_next = node->next;
+ nodeFreeNode(NULL, node);
+ }
+ node_clipboard.nodes.first = node_clipboard.nodes.last = NULL;
+}
+
+void nodeClipboardAddNode(bNode *node)
+{
+ BLI_addtail(&node_clipboard.nodes, node);
+}
+
+void nodeClipboardAddLink(bNodeLink *link)
+{
+ BLI_addtail(&node_clipboard.links, link);
+}
+
+const ListBase *nodeClipboardGetNodes(void)
+{
+ return &node_clipboard.nodes;
+}
+
+const ListBase *nodeClipboardGetLinks(void)
+{
+ return &node_clipboard.links;
+}
+
/* ************** dependency stuff *********** */
/* node is guaranteed to be not checked before */
@@ -2085,6 +2148,10 @@ static void free_typeinfos(ListBase *list)
void init_nodesystem(void)
{
+ /* init clipboard */
+ node_clipboard.nodes.first = node_clipboard.nodes.last = NULL;
+ node_clipboard.links.first = node_clipboard.links.last = NULL;
+
registerCompositNodes(ntreeGetType(NTREE_COMPOSIT));
registerShaderNodes(ntreeGetType(NTREE_SHADER));
registerTextureNodes(ntreeGetType(NTREE_TEXTURE));