[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15794] trunk/blender/source/blender/src/ poseobject.c: == Pose Mode - Copy Menu (Ctrl C) ==

Joshua Leung aligorith at gmail.com
Sun Jul 27 05:15:18 CEST 2008


Revision: 15794
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15794
Author:   aligorith
Date:     2008-07-27 05:15:17 +0200 (Sun, 27 Jul 2008)

Log Message:
-----------
== Pose Mode - Copy Menu (Ctrl C) ==

This now works even when there is a proxy-protected bone selected with a few differences.
* The Transform Locks, IK-Flags, and Custom Bone Shape settings are unavailable, as they would be reset by the proxy protection anyway

Also, the Copy Constraints options have been altered so that they do NOT free all existing constraints on the target bones before copying.
* Constraints are now appended to the end of the constraint stacks, with those added to bones belonging on proxy protected layers getting tagged as 'local' constraints.
* This is more useful for riggers than the previous behaviour (which was quite nasty too).

Modified Paths:
--------------
    trunk/blender/source/blender/src/poseobject.c

Modified: trunk/blender/source/blender/src/poseobject.c
===================================================================
--- trunk/blender/source/blender/src/poseobject.c	2008-07-27 00:22:59 UTC (rev 15793)
+++ trunk/blender/source/blender/src/poseobject.c	2008-07-27 03:15:17 UTC (rev 15794)
@@ -180,27 +180,26 @@
 	return NULL;
 }
 
-/* if a selected or active bone is protected, throw error and return 1 */
+/* if a selected or active bone is protected, throw error (oonly if warn==1) and return 1 */
 /* only_selected==1 : the active bone is allowed to be protected */
-static int pose_has_protected_selected(Object *ob, int only_selected)
+static short pose_has_protected_selected(Object *ob, short only_selected, short warn)
 {
-	
 	/* check protection */
-	if(ob->proxy) {
+	if (ob->proxy) {
 		bPoseChannel *pchan;
 		bArmature *arm= ob->data;
 		
-		for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-			if(pchan->bone && (pchan->bone->layer & arm->layer)) {
-				if(pchan->bone->layer & arm->layer_protected) {
-					if(only_selected && (pchan->bone->flag & BONE_ACTIVE));
-					else if(pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) 
+		for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+			if (pchan->bone && (pchan->bone->layer & arm->layer)) {
+				if (pchan->bone->layer & arm->layer_protected) {
+					if (only_selected && (pchan->bone->flag & BONE_ACTIVE));
+					else if (pchan->bone->flag & (BONE_ACTIVE|BONE_SELECTED)) 
 					   break;
 				}
 			}
 		}
-		if(pchan) {
-			error("Cannot change Proxy protected bones");
+		if (pchan) {
+			if (warn) error("Cannot change Proxy protected bones");
 			return 1;
 		}
 	}
@@ -540,7 +539,7 @@
 	if(!ob && !ob->pose) return;
 	if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
 	
-	if(pose_has_protected_selected(ob, 0))
+	if(pose_has_protected_selected(ob, 0, 1))
 		return;
 	
 	if(okee("Remove IK constraint(s)")==0) return;
@@ -581,7 +580,7 @@
 	if(!ob && !ob->pose) return;
 	if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
 	
-	if(pose_has_protected_selected(ob, 0))
+	if(pose_has_protected_selected(ob, 0, 1))
 		return;
 	
 	if(okee("Remove Constraints")==0) return;
@@ -612,38 +611,49 @@
 	Object *ob= OBACT;
 	bArmature *arm= ob->data;
 	bPoseChannel *pchan, *pchanact;
-	short nr;
+	short nr=0;
 	int i=0;
 	
 	/* paranoia checks */
-	if(!ob && !ob->pose) return;
-	if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
+	if (ELEM(NULL, ob, ob->pose)) return;
+	if ((ob==G.obedit) || (ob->flag & OB_POSEMODE)==0) return;
 	
 	/* find active */
-	for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-		if(pchan->bone->flag & BONE_ACTIVE) break;
+	for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+		if (pchan->bone->flag & BONE_ACTIVE) 
+			break;
 	}
 	
-	if(pchan==NULL) return;
+	if (pchan==NULL) return;
+	pchanact= pchan;
 	
-	if(pose_has_protected_selected(ob, 1))
+	/* if proxy-protected bones selected, some things (such as locks + displays) shouldn't be changable, 
+	 * but for constraints (just add local constraints)
+	 */
+	if (pose_has_protected_selected(ob, 1, 0)) {
+		i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
+		if (i < 25)
+			nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5");
+		else
+			nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4");
+	}
+	else {
+		i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
+		if (i < 25)
+			nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
+		else
+			nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
+	}
+	
+	if (nr <= 0) 
 		return;
-
-	pchanact= pchan;
 	
-	i= BLI_countlist(&(pchanact->constraints)); /* if there are 24 or less, allow for the user to select constraints */
-	if (i<25)
-		nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|Constraints...%x5|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
-	else
-		nr= pupmenu("Copy Pose Attributes %t|Local Location%x1|Local Rotation%x2|Local Size%x3|%l|Visual Location %x9|Visual Rotation%x10|Visual Size%x11|%l|Constraints (All)%x4|%l|Transform Locks%x6|IK Limits%x7|Bone Shape%x8");
-	
-	if(nr==-1) return;
-	if(nr!=5)  {
-		for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-			if(	(arm->layer & pchan->bone->layer) &&
-				(pchan->bone->flag & BONE_SELECTED) &&
-				(pchan!=pchanact)
-			) {
+	if (nr != 5)  {
+		for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+			if ( (arm->layer & pchan->bone->layer) &&
+				 (pchan->bone->flag & BONE_SELECTED) &&
+				 (pchan != pchanact) ) 
+			{
 				switch (nr) {
 					case 1: /* Local Location */
 						VECCOPY(pchan->loc, pchanact->loc);
@@ -656,13 +666,26 @@
 						break;
 					case 4: /* All Constraints */
 					{
-						free_constraints(&pchan->constraints);
-						copy_constraints(&pchan->constraints, &pchanact->constraints);
-						pchan->constflag = pchanact->constflag;
+						ListBase tmp_constraints = {NULL, NULL};
 						
-						if (ob->pose) {
+						/* copy constraints to tmpbase and apply 'local' tags before 
+						 * appending to list of constraints for this channel
+						 */
+						copy_constraints(&tmp_constraints, &pchanact->constraints);
+						if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
+							bConstraint *con;
+							
+							/* add proxy-local tags */
+							for (con= tmp_constraints.first; con; con= con->next)
+								con->flag |= CONSTRAINT_PROXY_LOCAL;
+						}
+						addlisttolist(&pchan->constraints, &tmp_constraints);
+						
+						/* update flags (need to add here, not just copy) */
+						pchan->constflag |= pchanact->constflag;
+						
+						if (ob->pose)
 							ob->pose->flag |= POSE_RECALC;
-						}
 					}
 						break;
 					case 6: /* Transform Locks */
@@ -703,12 +726,13 @@
 				}
 			}
 		}
-	} else { /* constraints, optional */
+	} 
+	else { /* constraints, optional (note: max we can have is 24 constraints) */
 		bConstraint *con, *con_back;
 		int const_toggle[24];
-		ListBase const_copy={0, 0};
+		ListBase const_copy = {NULL, NULL};
 		
-		duplicatelist (&const_copy, &(pchanact->constraints));
+		duplicatelist(&const_copy, &(pchanact->constraints));
 		
 		/* build the puplist of constraints */
 		for (con = pchanact->constraints.first, i=0; con; con=con->next, i++){
@@ -723,32 +747,46 @@
 		
 		/* now build a new listbase from the options selected */
 		for (i=0, con=const_copy.first; con; i++) {
+			/* if not selected, free/remove it from the list */
 			if (!const_toggle[i]) {
 				con_back= con->next;
 				BLI_freelinkN(&const_copy, con);
 				con= con_back;
-			} else {
+			} 
+			else
 				con= con->next;
-			}
 		}
 		
 		/* Copy the temo listbase to the selected posebones */
-		for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-			if(	(arm->layer & pchan->bone->layer) &&
-				(pchan->bone->flag & BONE_SELECTED) &&
-				(pchan!=pchanact)
-			) {
-				free_constraints(&pchan->constraints);
-				copy_constraints(&pchan->constraints, &const_copy);
-				pchan->constflag = pchanact->constflag;
+		for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+			if ( (arm->layer & pchan->bone->layer) &&
+				 (pchan->bone->flag & BONE_SELECTED) &&
+				 (pchan!=pchanact) ) 
+			{
+				ListBase tmp_constraints = {NULL, NULL};
+				
+				/* copy constraints to tmpbase and apply 'local' tags before 
+				 * appending to list of constraints for this channel
+				 */
+				copy_constraints(&tmp_constraints, &const_copy);
+				if ((ob->proxy) && (pchan->bone->layer & arm->layer_protected)) {
+					bConstraint *con;
+					
+					/* add proxy-local tags */
+					for (con= tmp_constraints.first; con; con= con->next)
+						con->flag |= CONSTRAINT_PROXY_LOCAL;
+				}
+				addlisttolist(&pchan->constraints, &tmp_constraints);
+				
+				/* update flags (need to add here, not just copy) */
+				pchan->constflag |= pchanact->constflag;
 			}
 		}
 		BLI_freelistN(&const_copy);
 		update_pose_constraint_flags(ob->pose); /* we could work out the flags but its simpler to do this */
 		
-		if (ob->pose) {
+		if (ob->pose)
 			ob->pose->flag |= POSE_RECALC;
-		}
 	}
 	
 	DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);	// and all its relations
@@ -808,7 +846,7 @@
 	
 	/*
 	// disabled until protected bones in proxies follow the rules everywhere else!
-	if(pose_has_protected_selected(ob, 1))
+	if(pose_has_protected_selected(ob, 1, 1))
 		return;
 	*/
 	
@@ -1249,7 +1287,7 @@
 	if(!ob && !ob->pose) return;
 	if(ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
 	
-	if(pose_has_protected_selected(ob, 0))
+	if(pose_has_protected_selected(ob, 0, 1))
 		return;
 	
 	for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
@@ -1282,7 +1320,7 @@
 	if (ELEM(NULL, ob, ob->pose)) return;
 	if (ob==G.obedit || (ob->flag & OB_POSEMODE)==0) return;
 	
-	if (pose_has_protected_selected(ob, 0))
+	if (pose_has_protected_selected(ob, 0, 1))
 		return;
 	
 	for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
@@ -1415,7 +1453,7 @@
 		/* pose-channel layers */
 		bPoseChannel *pchan;
 		
-		if (pose_has_protected_selected(ob, 0))
+		if (pose_has_protected_selected(ob, 0, 1))
 			return;
 		
 		for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {





More information about the Bf-blender-cvs mailing list