[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [47777] trunk/blender/source/blender: Modification of node groups by adding/removing nodes is not possible yet.

Lukas Toenne lukas.toenne at googlemail.com
Tue Jun 12 10:44:59 CEST 2012


Revision: 47777
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=47777
Author:   lukastoenne
Date:     2012-06-12 08:44:46 +0000 (Tue, 12 Jun 2012)
Log Message:
-----------
Modification of node groups by adding/removing nodes is not possible yet. This patch extends the 'Make Group' operator and adds a new 'Separate' operator to add such functionality.

1) For inserting into existing groups:
  The 'Make Group from selected' (CTRL+g) operator shows a selection popup (like the object parenting operator), with options depending on the type of the active node (last selected):
  * "New" -> regular operator, creates new group type with all selected nodes inside.
  * "Insert" (only if active node is a group) -> adds all other selected nodes into the group.

  Currently still prohibits groups inside groups in general, though would be technically possible as long as no actual recursion occurs (group containing itself).

2) For extracting from an existing group:
  New 'Separate from group' operator (p), works similar to separating vertices/edges/faces from mesh. Two modes:
  * "Copy" makes a copy of the nodes in the parent tree, but keeps the original group intact.
  * "Move" removes selected nodes from the node group and adds them to the parent tree

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_node.h
    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
    trunk/blender/source/blender/nodes/intern/node_common.c
    trunk/blender/source/blender/nodes/intern/node_common.h

Modified: trunk/blender/source/blender/blenkernel/BKE_node.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_node.h	2012-06-12 08:32:06 UTC (rev 47776)
+++ trunk/blender/source/blender/blenkernel/BKE_node.h	2012-06-12 08:44:46 UTC (rev 47777)
@@ -448,10 +448,8 @@
 struct bNodeSocket *node_group_expose_socket(struct bNodeTree *ngroup, struct bNodeSocket *sock, int in_out);
 void node_group_expose_all_sockets(struct bNodeTree *ngroup);
 void node_group_remove_socket(struct bNodeTree *ngroup, struct bNodeSocket *gsock, int in_out);
+struct bNodeSocket *node_group_add_extern_socket(struct bNodeTree *ntree, ListBase *lb, int in_out, struct bNodeSocket *gsock);
 
-struct bNode	*node_group_make_from_selected(struct bNodeTree *ntree);
-int				node_group_ungroup(struct bNodeTree *ntree, struct bNode *gnode);
-
 /* in node_common.c */
 void register_node_type_frame(struct bNodeTreeType *ttype);
 void register_node_type_reroute(struct bNodeTreeType *ttype);

Modified: trunk/blender/source/blender/editors/space_node/node_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_node/node_edit.c	2012-06-12 08:32:06 UTC (rev 47776)
+++ trunk/blender/source/blender/editors/space_node/node_edit.c	2012-06-12 08:44:46 UTC (rev 47777)
@@ -46,11 +46,15 @@
 #include "DNA_particle_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_world_types.h"
+#include "DNA_action_types.h"
+#include "DNA_anim_types.h"
 
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_action.h"
+#include "BKE_animsys.h"
 #include "BKE_context.h"
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
@@ -94,6 +98,7 @@
 #include "GPU_material.h"
 
 #include "node_intern.h"
+#include "NOD_socket.h"
 
 static EnumPropertyItem socket_in_out_items[] = {
 	{ SOCK_IN, "SOCK_IN", 0, "Input", "" },
@@ -1109,6 +1114,155 @@
 
 /* ******************** Ungroup operator ********************** */
 
+/* returns 1 if its OK */
+static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
+{
+	bNodeLink *link, *linkn;
+	bNode *node, *nextn;
+	bNodeTree *ngroup, *wgroup;
+	ListBase anim_basepaths = {NULL, NULL};
+	
+	ngroup= (bNodeTree *)gnode->id;
+	if (ngroup==NULL) return 0;
+	
+	/* clear new pointers, set in copytree */
+	for (node= ntree->nodes.first; node; node= node->next)
+		node->new_node= NULL;
+	
+	/* wgroup is a temporary copy of the NodeTree we're merging in
+	 *	- all of wgroup's nodes are transferred across to their new home
+	 *	- ngroup (i.e. the source NodeTree) is left unscathed
+	 */
+	wgroup= ntreeCopyTree(ngroup);
+	
+	/* add the nodes into the ntree */
+	for (node= wgroup->nodes.first; node; node= nextn) {
+		nextn= node->next;
+		
+		/* keep track of this node's RNA "base" path (the part of the path identifying the node) 
+		 * if the old nodetree has animation data which potentially covers this node
+		 */
+		if (wgroup->adt) {
+			PointerRNA ptr;
+			char *path;
+			
+			RNA_pointer_create(&wgroup->id, &RNA_Node, node, &ptr);
+			path = RNA_path_from_ID_to_struct(&ptr);
+			
+			if (path)
+				BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+		}
+		
+		/* migrate node */
+		BLI_remlink(&wgroup->nodes, node);
+		BLI_addtail(&ntree->nodes, node);
+		
+		node->locx += gnode->locx;
+		node->locy += gnode->locy;
+		
+		node->flag |= NODE_SELECT;
+	}
+	
+	/* restore external links to and from the gnode */
+	for (link= ntree->links.first; link; link= link->next) {
+		if (link->fromnode==gnode) {
+			if (link->fromsock->groupsock) {
+				bNodeSocket *gsock= link->fromsock->groupsock;
+				if (gsock->link) {
+					if (gsock->link->fromnode) {
+						/* NB: using the new internal copies here! the groupsock pointer still maps to the old tree */
+						link->fromnode = (gsock->link->fromnode ? gsock->link->fromnode->new_node : NULL);
+						link->fromsock = gsock->link->fromsock->new_sock;
+					}
+					else {
+						/* group output directly maps to group input */
+						bNodeSocket *insock= node_group_find_input(gnode, gsock->link->fromsock);
+						if (insock->link) {
+							link->fromnode = insock->link->fromnode;
+							link->fromsock = insock->link->fromsock;
+						}
+					}
+				}
+				else {
+					/* copy the default input value from the group socket default to the external socket */
+					node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, gsock->type, gsock->default_value);
+				}
+			}
+		}
+	}
+	/* remove internal output links, these are not used anymore */
+	for (link=wgroup->links.first; link; link= linkn) {
+		linkn = link->next;
+		if (!link->tonode)
+			nodeRemLink(wgroup, link);
+	}
+	/* restore links from internal nodes */
+	for (link= wgroup->links.first; link; link= link->next) {
+		/* indicates link to group input */
+		if (!link->fromnode) {
+			/* NB: can't use find_group_node_input here,
+			 * because gnode sockets still point to the old tree!
+			 */
+			bNodeSocket *insock;
+			for (insock= gnode->inputs.first; insock; insock= insock->next)
+				if (insock->groupsock->new_sock == link->fromsock)
+					break;
+			if (insock->link) {
+				link->fromnode = insock->link->fromnode;
+				link->fromsock = insock->link->fromsock;
+			}
+			else {
+				/* copy the default input value from the group node socket default to the internal socket */
+				node_socket_convert_default_value(link->tosock->type, link->tosock->default_value, insock->type, insock->default_value);
+				nodeRemLink(wgroup, link);
+			}
+		}
+	}
+	
+	/* add internal links to the ntree */
+	for (link= wgroup->links.first; link; link= linkn) {
+		linkn= link->next;
+		BLI_remlink(&wgroup->links, link);
+		BLI_addtail(&ntree->links, link);
+	}
+	
+	/* and copy across the animation,
+	 * note that the animation data's action can be NULL here */
+	if (wgroup->adt) {
+		LinkData *ld, *ldn=NULL;
+		bAction *waction;
+		
+		/* firstly, wgroup needs to temporary dummy action that can be destroyed, as it shares copies */
+		waction = wgroup->adt->action = BKE_action_copy(wgroup->adt->action);
+		
+		/* now perform the moving */
+		BKE_animdata_separate_by_basepath(&wgroup->id, &ntree->id, &anim_basepaths);
+		
+		/* paths + their wrappers need to be freed */
+		for (ld = anim_basepaths.first; ld; ld = ldn) {
+			ldn = ld->next;
+			
+			MEM_freeN(ld->data);
+			BLI_freelinkN(&anim_basepaths, ld);
+		}
+		
+		/* free temp action too */
+		if (waction) {
+			BKE_libblock_free(&G.main->action, waction);
+		}
+	}
+	
+	/* delete the group instance. this also removes old input links! */
+	nodeFreeNode(ntree, gnode);
+
+	/* free the group tree (takes care of user count) */
+	BKE_libblock_free(&G.main->nodetree, wgroup);
+	
+	ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+	
+	return 1;
+}
+
 static int node_group_ungroup_exec(bContext *C, wmOperator *op)
 {
 	SpaceNode *snode = CTX_wm_space_node(C);
@@ -1129,7 +1283,10 @@
 		BKE_report(op->reports, RPT_WARNING, "Not a group");
 		return OPERATOR_CANCELLED;
 	}
-	else if (!node_group_ungroup(snode->edittree, gnode)) {
+	else if (node_group_ungroup(snode->nodetree, gnode)) {
+		ntreeUpdateTree(snode->nodetree);
+	}
+	else {
 		BKE_report(op->reports, RPT_WARNING, "Can't ungroup");
 		return OPERATOR_CANCELLED;
 	}
@@ -1155,6 +1312,200 @@
 	ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
+/* ******************** Separate operator ********************** */
+
+/* returns 1 if its OK */
+static int node_group_separate_selected(bNodeTree *ntree, bNode *gnode, int make_copy)
+{
+	bNodeLink *link, *link_next;
+	bNode *node, *node_next, *newnode;
+	bNodeTree *ngroup;
+	ListBase anim_basepaths = {NULL, NULL};
+	
+	ngroup= (bNodeTree *)gnode->id;
+	if (ngroup==NULL) return 0;
+	
+	/* deselect all nodes in the target tree */
+	for (node=ntree->nodes.first; node; node=node->next)
+		node_deselect(node);
+	
+	/* clear new pointers, set in nodeCopyNode */
+	for (node= ngroup->nodes.first; node; node= node->next)
+		node->new_node= NULL;
+	
+	/* add selected nodes into the ntree */
+	for (node= ngroup->nodes.first; node; node= node_next) {
+		node_next = node->next;
+		if (!(node->flag & NODE_SELECT))
+			continue;
+		
+		if (make_copy) {
+			/* make a copy */
+			newnode = nodeCopyNode(ngroup, node);
+		}
+		else {
+			/* use the existing node */
+			newnode = node;
+		}
+		
+		/* keep track of this node's RNA "base" path (the part of the path identifying the node) 
+		 * if the old nodetree has animation data which potentially covers this node
+		 */
+		if (ngroup->adt) {
+			PointerRNA ptr;
+			char *path;
+			
+			RNA_pointer_create(&ngroup->id, &RNA_Node, newnode, &ptr);
+			path = RNA_path_from_ID_to_struct(&ptr);
+			
+			if (path)
+				BLI_addtail(&anim_basepaths, BLI_genericNodeN(path));
+		}
+		
+		/* ensure valid parent pointers, detach if parent stays inside the group */
+		if (newnode->parent && !(newnode->parent->flag & NODE_SELECT))
+			nodeDetachNode(newnode);
+		
+		/* migrate node */
+		BLI_remlink(&ngroup->nodes, newnode);
+		BLI_addtail(&ntree->nodes, newnode);
+		
+		newnode->locx += gnode->locx;
+		newnode->locy += gnode->locy;
+	}
+	
+	/* add internal links to the ntree */
+	for (link= ngroup->links.first; link; link= link_next) {
+		int fromselect = (link->fromnode && (link->fromnode->flag & NODE_SELECT));
+		int toselect = (link->tonode && (link->tonode->flag & NODE_SELECT));
+		link_next = link->next;
+		
+		if (make_copy) {
+			/* make a copy of internal links */
+			if (fromselect && toselect)
+				nodeAddLink(ntree, link->fromnode->new_node, link->fromsock->new_sock, link->tonode->new_node, link->tosock->new_sock);
+		}
+		else {
+			/* move valid links over, delete broken links */
+			if (fromselect && toselect) {
+				BLI_remlink(&ngroup->links, link);
+				BLI_addtail(&ntree->links, link);
+			}
+			else if (fromselect || toselect) {
+				nodeRemLink(ngroup, link);
+			}
+		}
+	}
+	
+	/* and copy across the animation,
+	 * note that the animation data's action can be NULL here */
+	if (ngroup->adt) {
+		LinkData *ld, *ldn=NULL;
+		
+		/* now perform the moving */
+		BKE_animdata_separate_by_basepath(&ngroup->id, &ntree->id, &anim_basepaths);
+		
+		/* paths + their wrappers need to be freed */
+		for (ld = anim_basepaths.first; ld; ld = ldn) {
+			ldn = ld->next;
+			
+			MEM_freeN(ld->data);
+			BLI_freelinkN(&anim_basepaths, ld);
+		}
+	}
+	
+	ntree->update |= NTREE_UPDATE_NODES | NTREE_UPDATE_LINKS;
+	if (!make_copy)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list