diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-11-04 15:57:49 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-11-04 15:57:49 +0400 |
commit | f32113bbc8b44edb2b2b9d52732e26e4c7d7f66c (patch) | |
tree | a44ce76df7e8ef667e40e26cf20a95833864e360 /source/blender | |
parent | 2122eda05ab3e44fe0b45603725135d8983b82b7 (diff) |
Node reroute cut operator update.
Cutting mulitple links with for inserting reroute nodes would previously insert only one reroute node for the first cut link.
Now the operator will insert a reroute node for every link in the cut line. Also, if several links share the same input/output socket, it will insert only a single reroute node, which all affected links will then share.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/space_node/node_add.c | 176 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_node_types.h | 1 |
2 files changed, 139 insertions, 38 deletions
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index df8a6f94d24..04d2947ce89 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -31,8 +31,11 @@ #include <errno.h> +#include "MEM_guardedalloc.h" + #include "DNA_node_types.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLF_translation.h" @@ -133,14 +136,105 @@ static int add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int return 0; } +typedef struct bNodeSocketLink { + struct bNodeSocketLink *next, *prev; + + struct bNodeSocket *sock; + struct bNodeLink *link; + float point[2]; +} bNodeSocketLink; + +static bNodeSocketLink *add_reroute_insert_socket_link(ListBase *lb, bNodeSocket *sock, bNodeLink *link, float point[2]) +{ + bNodeSocketLink *socklink, *prev; + + socklink = MEM_callocN(sizeof(bNodeSocketLink), "socket link"); + socklink->sock = sock; + socklink->link = link; + copy_v2_v2(socklink->point, point); + + for (prev = lb->last; prev; prev = prev->prev) { + if (prev->sock == sock) + break; + } + BLI_insertlinkafter(lb, prev, socklink); + return socklink; +} + +static bNodeSocketLink *add_reroute_do_socket_section(bContext *C, bNodeSocketLink *socklink, int in_out) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeTree *ntree = snode->edittree; + bNode *reroute_node = NULL; + bNodeSocket *cursock = socklink->sock; + float insert_point[2]; + int num_links; + + zero_v2(insert_point); + num_links = 0; + + while (socklink && socklink->sock == cursock) { + if (!(socklink->link->flag & NODE_LINK_TEST)) { + socklink->link->flag |= NODE_LINK_TEST; + + /* create the reroute node for this cursock */ + if (!reroute_node) { + bNodeTemplate ntemp; + ntemp.type = NODE_REROUTE; + reroute_node = nodeAddNode(ntree, &ntemp); + + /* add a single link to/from the reroute node to replace multiple links */ + if (in_out == SOCK_OUT) { + nodeAddLink(ntree, socklink->link->fromnode, socklink->link->fromsock, reroute_node, reroute_node->inputs.first); + } + else { + nodeAddLink(ntree, reroute_node, reroute_node->outputs.first, socklink->link->tonode, socklink->link->tosock); + } + } + + /* insert the reroute node into the link */ + if (in_out == SOCK_OUT) { + socklink->link->fromnode = reroute_node; + socklink->link->fromsock = reroute_node->outputs.first; + } + else { + socklink->link->tonode = reroute_node; + socklink->link->tosock = reroute_node->inputs.first; + } + + add_v2_v2(insert_point, socklink->point); + ++num_links; + } + socklink = socklink->next; + } + + if (num_links > 0) { + bNode *gnode = node_tree_get_editgroup(snode->nodetree); + + /* average cut point from shared links */ + mul_v2_fl(insert_point, 1.0f / num_links); + + if (gnode) { + nodeFromView(gnode, insert_point[0], insert_point[1], &reroute_node->locx, &reroute_node->locy); + } + else { + reroute_node->locx = insert_point[0]; + reroute_node->locy = insert_point[1]; + } + } + + return socklink; +} + static int add_reroute_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); ARegion *ar = CTX_wm_region(C); - bNode *gnode = node_tree_get_editgroup(snode->nodetree); + bNodeTree *ntree = snode->edittree; float mcoords[256][2]; int i = 0; - + + /* Get the cut path */ RNA_BEGIN(op->ptr, itemptr, "path") { float loc[2]; @@ -154,46 +248,52 @@ static int add_reroute_exec(bContext *C, wmOperator *op) RNA_END; if (i > 1) { + ListBase output_links, input_links; bNodeLink *link; - float insertPoint[2]; - - for (link = snode->edittree->links.first; link; link = link->next) { - if (add_reroute_intersect_check(link, mcoords, i, insertPoint)) { - bNodeTemplate ntemp; - bNode *rerouteNode; - - /* always first */ - ED_preview_kill_jobs(C); - - node_deselect_all(snode); - - ntemp.type = NODE_REROUTE; - rerouteNode = nodeAddNode(snode->edittree, &ntemp); - if (gnode) { - nodeFromView(gnode, insertPoint[0], insertPoint[1], &rerouteNode->locx, &rerouteNode->locy); - } - else { - rerouteNode->locx = insertPoint[0]; - rerouteNode->locy = insertPoint[1]; - } - - nodeAddLink(snode->edittree, link->fromnode, link->fromsock, rerouteNode, rerouteNode->inputs.first); - link->fromnode = rerouteNode; - link->fromsock = rerouteNode->outputs.first; - - /* always last */ - ntreeUpdateTree(snode->edittree); - snode_notify(C, snode); - snode_dag_update(C, snode); - - return OPERATOR_FINISHED; // add one reroute at the time. + bNodeSocketLink *socklink; + float insert_point[2]; + + /* always first */ + ED_preview_kill_jobs(C); + + node_deselect_all(snode); + + /* Find cut links and sort them by sockets */ + output_links.first = output_links.last = NULL; + input_links.first = input_links.last = NULL; + for (link = ntree->links.first; link; link = link->next) { + if (add_reroute_intersect_check(link, mcoords, i, insert_point)) { + add_reroute_insert_socket_link(&output_links, link->fromsock, link, insert_point); + add_reroute_insert_socket_link(&input_links, link->tosock, link, insert_point); + + /* Clear flag */ + link->flag &= ~NODE_LINK_TEST; } } - - return OPERATOR_CANCELLED; - + + /* Create reroute nodes for intersected links. + * Only one reroute if links share the same input/output socket. + */ + socklink = output_links.first; + while (socklink) { + socklink = add_reroute_do_socket_section(C, socklink, SOCK_OUT); + } + socklink = input_links.first; + while (socklink) { + socklink = add_reroute_do_socket_section(C, socklink, SOCK_IN); + } + + BLI_freelistN(&output_links); + BLI_freelistN(&input_links); + + /* always last */ + ntreeUpdateTree(ntree); + snode_notify(C, snode); + snode_dag_update(C, snode); + + return OPERATOR_FINISHED; } - + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index bebe2ba20d5..c73ba87754f 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -241,6 +241,7 @@ typedef struct bNodeLink { /* link->flag */ #define NODE_LINKFLAG_HILITE 1 /* link has been successfully validated */ #define NODE_LINK_VALID 2 +#define NODE_LINK_TEST 4 /* free test flag, undefined */ /* tree->edit_quality/tree->render_quality */ #define NTREE_QUALITY_HIGH 0 |