[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [46661] trunk/blender/source/blender/ editors/space_node: A generalization of the modal node linking operator ( for dragging from socket to socket).

Lukas Toenne lukas.toenne at googlemail.com
Tue May 15 14:40:44 CEST 2012


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. @@



More information about the Bf-blender-cvs mailing list