diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-08-02 13:52:37 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-08-02 13:52:37 +0400 |
commit | 9d2173518cd7da7d18bb032c8537c8952abc2b78 (patch) | |
tree | 5fd02e1b8013ed6a37915cacfabb960dd9f66877 /source/blender/blenkernel/intern | |
parent | 0a782a4550904cdec15efbf5bf81c8be144896ee (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.c | 109 |
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)); |