Revision: 46661
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=46661
Author:   lukastoenne
Date:     2012-05-15 12:40:43 +0000 (Tue, 15 May 2012)
Log Message:
-----------
A generalization of the modal node linking operator (for dragging from socket 
to socket).

This operator still had some built-in assumptions about the connectivity of 
input/output sockets (1-to-n in all current node systems). For future node 
systems (e.g. flow-based particles) and for general customizable nodes the 
operator is now fully symmetric and supports all kinds of connectivity limits 
(1:1, 1:n, m:1, m:n).

The operator data can also store a list of node links as opposed to a single 
link now, so that multiple links can be redirected at once. Holding the CTRL 
key when clicking a socket, all links from/to that socket are detached and can 
be moved to a different socket. This is useful for quickly appending a node 
without moving every individual link.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/space_node/node_draw.c
    trunk/blender/source/blender/editors/space_node/node_edit.c
    trunk/blender/source/blender/editors/space_node/node_intern.h
    trunk/blender/source/blender/editors/space_node/node_ops.c

Modified: trunk/blender/source/blender/editors/space_node/node_draw.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_draw.c 2012-05-15 
12:26:29 UTC (rev 46660)
+++ trunk/blender/source/blender/editors/space_node/node_draw.c 2012-05-15 
12:40:43 UTC (rev 46661)
@@ -914,6 +914,7 @@
        Scene *scene= CTX_data_scene(C);
        int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
        bNodeLinkDrag *nldrag;
+       LinkData *linkdata;
        
        UI_ThemeClearColor(TH_BACK);
        glClear(GL_COLOR_BUFFER_BIT);
@@ -965,8 +966,10 @@
        /* temporary links */
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH);
-       for (nldrag= snode->linkdrag.first; nldrag; nldrag= nldrag->next)
-               node_draw_link(&ar->v2d, snode, nldrag->link);
+       for (nldrag= snode->linkdrag.first; nldrag; nldrag= nldrag->next) {
+               for (linkdata=nldrag->links.first; linkdata; 
linkdata=linkdata->next)
+                       node_draw_link(&ar->v2d, snode, (bNodeLink 
*)linkdata->data);
+       }
        glDisable(GL_LINE_SMOOTH);
        glDisable(GL_BLEND);
        

Modified: trunk/blender/source/blender/editors/space_node/node_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_edit.c 2012-05-15 
12:26:29 UTC (rev 46660)
+++ trunk/blender/source/blender/editors/space_node/node_edit.c 2012-05-15 
12:40:43 UTC (rev 46661)
@@ -2324,15 +2324,13 @@
        SpaceNode *snode= CTX_wm_space_node(C);
        ARegion *ar= CTX_wm_region(C);
        bNodeLinkDrag *nldrag= op->customdata;
-       bNode *tnode, *node;
-       bNodeSocket *tsock= NULL, *sock;
+       bNode *tnode;
+       bNodeSocket *tsock= NULL;
        bNodeLink *link;
+       LinkData *linkdata;
        int in_out;
 
-       in_out= nldrag->in_out;
-       node= nldrag->node;
-       sock= nldrag->sock;
-       link= nldrag->link;
+       in_out = nldrag->in_out;
        
        UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1],
                                                         &snode->mx, 
&snode->my);
@@ -2342,57 +2340,86 @@
                        
                        if (in_out==SOCK_OUT) {
                                if (node_find_indicated_socket(snode, &tnode, 
&tsock, SOCK_IN)) {
-                                       if (nodeFindLink(snode->edittree, sock, 
tsock)==NULL) {
-                                               if ( link->tosock!= tsock && 
(!tnode || (tnode!=node && link->tonode!=tnode)) ) {
-                                                       link->tonode= tnode;
-                                                       link->tosock= tsock;
-                                                       if (link->prev==NULL && 
link->next==NULL) {
-                                                               
BLI_addtail(&snode->edittree->links, link);
-                                                       }
+                                       for (linkdata=nldrag->links.first; 
linkdata; linkdata=linkdata->next) {
+                                               link = linkdata->data;
+                                               
+                                               /* skip if this is already the 
target socket */
+                                               if (link->tosock == tsock)
+                                                       continue;
+                                               /* skip if socket is on the 
same node as the fromsock */
+                                               if (tnode && link->fromnode == 
tnode)
+                                                       continue;
+                                               
+                                               /* attach links to the socket */
+                                               link->tonode = tnode;
+                                               link->tosock = tsock;
+                                               /* add it to the node tree 
temporarily */
+                                               if (link->prev==NULL && 
link->next==NULL)
+                                                       
BLI_addtail(&snode->edittree->links, link);
+                                               
+                                               snode->edittree->update |= 
NTREE_UPDATE_LINKS;
+                                       }
+                                       ntreeUpdateTree(snode->edittree);
+                               }
+                               else {
+                                       int do_update = 0;
+                                       for (linkdata=nldrag->links.first; 
linkdata; linkdata=linkdata->next) {
+                                               link = linkdata->data;
+                                               
+                                               if (link->tonode || 
link->tosock) {
+                                                       
BLI_remlink(&snode->edittree->links, link);
+                                                       link->prev = link->next 
= NULL;
+                                                       link->tonode= NULL;
+                                                       link->tosock= NULL;
                                                        
                                                        snode->edittree->update 
|= NTREE_UPDATE_LINKS;
-                                                       
ntreeUpdateTree(snode->edittree);
+                                                       do_update = 1;
                                                }
                                        }
-                               }
-                               else {
-                                       if (link->tonode || link->tosock) {
-                                               
BLI_remlink(&snode->edittree->links, link);
-                                               link->prev = link->next = NULL;
-                                               link->tonode= NULL;
-                                               link->tosock= NULL;
-                                               
-                                               snode->edittree->update |= 
NTREE_UPDATE_LINKS;
+                                       if (do_update)
                                                
ntreeUpdateTree(snode->edittree);
-                                       }
                                }
                        }
                        else {
                                if (node_find_indicated_socket(snode, &tnode, 
&tsock, SOCK_OUT)) {
-                                       if (nodeFindLink(snode->edittree, sock, 
tsock)==NULL) {
-                                               if 
(nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) {
-                                                       if ( link->fromsock!= 
tsock && (!tnode || (tnode!=node && link->fromnode!=tnode)) ) {
-                                                               link->fromnode= 
tnode;
-                                                               link->fromsock= 
tsock;
-                                                               if 
(link->prev==NULL && link->next==NULL) {
-                                                                       
BLI_addtail(&snode->edittree->links, link);
-                                                               }
-                                                               
-                                                               
snode->edittree->update |= NTREE_UPDATE_LINKS;
-                                                               
ntreeUpdateTree(snode->edittree);
-                                                       }
-                                               }
+                                       for (linkdata=nldrag->links.first; 
linkdata; linkdata=linkdata->next) {
+                                               link = linkdata->data;
+                                               
+                                               /* skip if this is already the 
target socket */
+                                               if (link->fromsock == tsock)
+                                                       continue;
+                                               /* skip if socket is on the 
same node as the fromsock */
+                                               if (tnode && link->tonode == 
tnode)
+                                                       continue;
+                                               
+                                               /* attach links to the socket */
+                                               link->fromnode = tnode;
+                                               link->fromsock = tsock;
+                                               /* add it to the node tree 
temporarily */
+                                               if (link->prev==NULL && 
link->next==NULL)
+                                                       
BLI_addtail(&snode->edittree->links, link);
+                                               
+                                               snode->edittree->update |= 
NTREE_UPDATE_LINKS;
                                        }
+                                       ntreeUpdateTree(snode->edittree);
                                }
                                else {
-                                       if (link->tonode || link->tosock) {
-                                               
BLI_remlink(&snode->edittree->links, link);
-                                               link->prev = link->next = NULL;
-                                               link->fromnode= NULL;
-                                               link->fromsock= NULL;
-                                               snode->edittree->update |= 
NTREE_UPDATE_LINKS;
+                                       int do_update = 0;
+                                       for (linkdata=nldrag->links.first; 
linkdata; linkdata=linkdata->next) {
+                                               link = linkdata->data;
+                                               
+                                               if (link->fromnode || 
link->fromsock) {
+                                                       
BLI_remlink(&snode->edittree->links, link);
+                                                       link->prev = link->next 
= NULL;
+                                                       link->fromnode= NULL;
+                                                       link->fromsock= NULL;
+                                                       
+                                                       snode->edittree->update 
|= NTREE_UPDATE_LINKS;
+                                                       do_update = 1;
+                                               }
+                                       }
+                                       if (do_update)
                                                
ntreeUpdateTree(snode->edittree);
-                                       }
                                }
                        }
                        
@@ -2401,139 +2428,161 @@
                        
                case LEFTMOUSE:
                case RIGHTMOUSE:
-               case MIDDLEMOUSE:
-                       if (link->tosock && link->fromsock) {
-                               /* send changed events for original tonode and 
new */
-                               snode_update(snode, link->tonode);
+               case MIDDLEMOUSE: {
+                       for (linkdata=nldrag->links.first; linkdata; 
linkdata=linkdata->next) {
+                               link = linkdata->data;
                                
-                               /* we might need to remove a link */
-                               if (in_out==SOCK_OUT)
-                                       node_remove_extra_links(snode, 
link->tosock, link);
-                               
-                               /* when linking to group outputs, update the 
socket type */
-                               /* XXX this should all be part of a generic 
update system */
-                               if (!link->tonode) {
-                                       if(link->tosock->type != 
link->fromsock->type)
-                                               nodeSocketSetType(link->tosock, 
link->fromsock->type);
-                               }
-                       }
-                       else if (outside_group_rect(snode) && (link->tonode || 
link->fromnode)) {
-                               /* automatically add new group socket */
-                               if (link->tonode && link->tosock) {
-                                       link->fromsock = 
node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN);
-                                       link->fromnode = NULL;
-                                       if (link->prev==NULL && 
link->next==NULL) {
-                                               
BLI_addtail(&snode->edittree->links, link);
+                               if (link->tosock && link->fromsock) {
+                                       /* send changed events for original 
tonode and new */
+                                       if (link->tonode)
+                                               snode_update(snode, 
link->tonode);
+                                       
+                                       /* we might need to remove a link */
+                                       if (in_out==SOCK_OUT)
+                                               node_remove_extra_links(snode, 
link->tosock, link);
+                                       
+                                       /* when linking to group outputs, 
update the socket type */
+                                       /* XXX this should all be part of a 
generic update system */
+                                       if (!link->tonode) {
+                                               if(link->tosock->type != 
link->fromsock->type)
+                                                       
nodeSocketSetType(link->tosock, link->fromsock->type);
                                        }
-                                       snode->edittree->update |= 
NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
                                }
-                               else if (link->fromnode && link->fromsock) {
-                                       link->tosock = 
node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT);
-                                       link->tonode = NULL;
-                                       if (link->prev==NULL && 
link->next==NULL) {
-                                               
BLI_addtail(&snode->edittree->links, link);
+                               else if (outside_group_rect(snode) && 
(link->tonode || link->fromnode)) {
+                                       /* automatically add new group socket */
+                                       if (link->tonode && link->tosock) {
+                                               link->fromsock = 
node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN);
+                                               link->fromnode = NULL;
+                                               if (link->prev==NULL && 
link->next==NULL)
+                                                       
BLI_addtail(&snode->edittree->links, link);
+                                               
+                                               snode->edittree->update |= 
NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS;
                                        }
-                                       snode->edittree->update |= 
NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
+                                       else if (link->fromnode && 
link->fromsock) {
+                                               link->tosock = 
node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT);
+                                               link->tonode = NULL;
+                                               if (link->prev==NULL && 
link->next==NULL)
+                                                       
BLI_addtail(&snode->edittree->links, link);
+                                               
+                                               snode->edittree->update |= 
NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS;
+                                       }
                                }
+                               else
+                                       nodeRemLink(snode->edittree, link);
                        }
-                       else
-                               nodeRemLink(snode->edittree, link);
                        
                        ntreeUpdateTree(snode->edittree);
                        snode_notify(C, snode);
                        snode_dag_update(C, snode);
                        
                        BLI_remlink(&snode->linkdrag, nldrag);
+                       /* links->data pointers are either held by the tree or 
freed already */
+                       BLI_freelistN(&nldrag->links);
                        MEM_freeN(nldrag);
                        
                        return OPERATOR_FINISHED;
+               }
        }
        
        return OPERATOR_RUNNING_MODAL;
 }
 
 /* return 1 when socket clicked */
-static int node_link_init(SpaceNode *snode, bNodeLinkDrag *nldrag)
+static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
 {
-       bNodeLink *link;
-       int in_out = 0;
-
+       bNode *node;
+       bNodeSocket *sock;
+       bNodeLink *link, *link_next, *oplink;
+       bNodeLinkDrag *nldrag = NULL;
+       LinkData *linkdata;
+       int num_links;
+       
        /* output indicated? */
-       if (node_find_indicated_socket(snode, &nldrag->node, &nldrag->sock, 
SOCK_OUT)) {
-               if (nodeCountSocketLinks(snode->edittree, nldrag->sock) < 
nldrag->sock->limit)
-                       in_out = SOCK_OUT;
-               else {
-                       /* find if we break a link */
-                       for (link= snode->edittree->links.first; link; link= 
link->next) {
-                               if (link->fromsock==nldrag->sock)
-                                       break;
+       if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) {
+               nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op 
customdata");
+               

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to