[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [18824] branches/blender2.5/blender/source /blender: 2.5 Armature Editing - Restored 'Align Bones' (Ctrl Alt A)

Joshua Leung aligorith at gmail.com
Fri Feb 6 02:39:56 CET 2009


Revision: 18824
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18824
Author:   aligorith
Date:     2009-02-06 02:39:55 +0100 (Fri, 06 Feb 2009)

Log Message:
-----------
2.5 Armature Editing - Restored 'Align Bones' (Ctrl Alt A)

* I've had to remap 'Duplicate window' to Ctrl Alt W instead...

* Fixed some bugs with armature context iterators for X-Axis Mirroring. Now, the code there checks for mirrored bones in the right way. 
For details on how to write tools that need to cope with this option, refer to the 'Align Bones' operator. I'll port another simple operator as another good example soon. 

Additional notes:
Currently, armature_sync_selection() is really buggy (not part of this commit), and needs further attention.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/armature/armature_intern.h
    branches/blender2.5/blender/source/blender/editors/armature/armature_ops.c
    branches/blender2.5/blender/source/blender/editors/armature/editarmature.c
    branches/blender2.5/blender/source/blender/editors/space_view3d/space_view3d.c
    branches/blender2.5/blender/source/blender/windowmanager/intern/wm_operators.c

Modified: branches/blender2.5/blender/source/blender/editors/armature/armature_intern.h
===================================================================
--- branches/blender2.5/blender/source/blender/editors/armature/armature_intern.h	2009-02-06 01:21:38 UTC (rev 18823)
+++ branches/blender2.5/blender/source/blender/editors/armature/armature_intern.h	2009-02-06 01:39:55 UTC (rev 18824)
@@ -35,6 +35,8 @@
 void armature_bone_rename(Object *ob, char *oldnamep, char *newnamep);
 EditBone *armature_bone_get_mirrored(ListBase *edbo, EditBone *ebo); // XXX this is needed for populating the context iterators
 
+void ARMATURE_OT_align_bones(struct wmOperatorType *ot);
+
 void POSE_OT_hide(struct wmOperatorType *ot);
 void POSE_OT_reveil(struct wmOperatorType *ot);
 void POSE_OT_rot_clear(struct wmOperatorType *ot);

Modified: branches/blender2.5/blender/source/blender/editors/armature/armature_ops.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/armature/armature_ops.c	2009-02-06 01:21:38 UTC (rev 18823)
+++ branches/blender2.5/blender/source/blender/editors/armature/armature_ops.c	2009-02-06 01:39:55 UTC (rev 18824)
@@ -107,6 +107,8 @@
 /* Both operators ARMATURE_OT_xxx and POSE_OT_xxx here */
 void ED_operatortypes_armature(void)
 {
+	WM_operatortype_append(ARMATURE_OT_align_bones);
+	
 	WM_operatortype_append(POSE_OT_hide);
 	WM_operatortype_append(POSE_OT_reveil);
 	WM_operatortype_append(POSE_OT_rot_clear);
@@ -126,6 +128,7 @@
 	
 	/* only set in editmode armature, by space_view3d listener */
 //	WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
+	WM_keymap_add_item(keymap, "ARMATURE_OT_align_bones", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
 	WM_keymap_add_item(keymap, "ARMATURE_OT_test", TKEY, KM_PRESS, 0, 0);  // XXX temp test for context iterators... to be removed
 	
 	/* Pose ------------------------ */

Modified: branches/blender2.5/blender/source/blender/editors/armature/editarmature.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/armature/editarmature.c	2009-02-06 01:21:38 UTC (rev 18823)
+++ branches/blender2.5/blender/source/blender/editors/armature/editarmature.c	2009-02-06 01:39:55 UTC (rev 18824)
@@ -67,6 +67,7 @@
 #include "BKE_global.h"
 #include "BKE_main.h"
 #include "BKE_object.h"
+#include "BKE_report.h"
 #include "BKE_subsurf.h"
 #include "BKE_utildefines.h"
 #include "BKE_modifier.h"
@@ -108,6 +109,7 @@
 /* **************** tools on Editmode Armature **************** */
 
 /* Sync selection to parent for connected children */
+// XXX this is really buggy code! do not use this for now - Aligorith, 6Feb2009
 static void armature_sync_selection(ListBase *edbo)
 {
 	EditBone *ebo;
@@ -1561,6 +1563,9 @@
 	EditBone *eboflip= NULL;
 	char name[32];
 	
+	if (ebo == NULL)
+		return NULL;
+	
 	BLI_strncpy(name, ebo->name, sizeof(name));
 	bone_flip_name(name, 0);		// 0 = don't strip off number extensions
 	
@@ -3346,7 +3351,7 @@
 	BIF_undo_push("Switch Direction");
 }
 
-/* editbone alignment */
+/* ***************** EditBone Alignment ********************* */
 
 /* helper to fix a ebone position if its parent has moved due to alignment*/
 static void fix_connected_bone(EditBone *ebone)
@@ -3398,87 +3403,81 @@
 	return;
 }
 
-void align_selected_bones(Scene *scene)
+static int armature_align_bones_exec(bContext *C, wmOperator *op) 
 {
-	Object *obedit= scene->obedit; // XXX get from context
-	bArmature *arm= obedit->data;
-	EditBone *actbone, *ebone, *selbone;
-	EditBone *flipbone, *flippar;
-	short allchildbones= 0, foundselbone= 0;
+	Object *ob= CTX_data_edit_object(C);
+	bArmature *arm= (bArmature *)ob->data;
+	EditBone *actbone= CTX_data_active_bone(C);
+	EditBone *actmirb= NULL;
 	
-	/* find active bone to align to */
-	for (actbone = arm->edbo->first; actbone; actbone=actbone->next) {
-		if (arm->layer & actbone->layer) {
-			if (actbone->flag & BONE_ACTIVE)
-				break;
-		}
-	}
+	/* there must be an active bone */
 	if (actbone == NULL) {
-		error("Needs an active bone");
-		return; 
+		BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone");
+		return OPERATOR_CANCELLED;
 	}
-
-	/* find selected bones */
-	for (ebone = arm->edbo->first; ebone; ebone=ebone->next) {
-		if (arm->layer & ebone->layer) {
-			if ((ebone->flag & BONE_SELECTED) && (ebone != actbone)) {
-				foundselbone++;
-				if (ebone->parent != actbone) allchildbones= 1; 
-			}	
-		}
+	else if (arm->flag & ARM_MIRROR_EDIT) {
+		/* For X-Axis Mirror Editing option, we may need a mirror copy of actbone
+		 * - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
+		 *	(i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
+		 *	This is useful for arm-chains, for example parenting lower arm to upper arm
+		 * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
+		 *	then just use actbone. Useful when doing upper arm to spine.
+		 */
+		actmirb= armature_bone_get_mirrored(arm->edbo, actbone);
+		if (actmirb == NULL) 
+			actmirb= actbone;
 	}
-	/* abort if no selected bones, and active bone doesn't have a parent to work with instead */
-	if (foundselbone==0 && actbone->parent==NULL) {
-		error("Need selected bone(s)");
-		return;
-	}
 	
-	if (foundselbone==0 && actbone->parent) {
+	/* if there is only 1 selected bone, we assume that that is the active bone, 
+	 * since a user will need to have clicked on a bone (thus selecting it) to make it active
+	 */
+	if (CTX_DATA_COUNT(C, selected_editable_bones) <= 1) {
 		/* When only the active bone is selected, and it has a parent,
 		 * align it to the parent, as that is the only possible outcome. 
 		 */
-		bone_align_to_bone(arm->edbo, actbone, actbone->parent);
-		
-		if (arm->flag & ARM_MIRROR_EDIT) {
-			flipbone = armature_bone_get_mirrored(arm->edbo, actbone);
-			if (flipbone)
-				bone_align_to_bone(arm->edbo, flipbone, flipbone->parent);
+		if (actbone->parent) {
+			bone_align_to_bone(arm->edbo, actbone, actbone->parent);
+			
+			if ((arm->flag & ARM_MIRROR_EDIT) && (actmirb->parent))
+				bone_align_to_bone(arm->edbo, actmirb, actmirb->parent);
 		}
 	}
 	else {
-		/* loop through all editbones, aligning all selected bones to the active bone */
-		for (selbone = arm->edbo->first; selbone; selbone=selbone->next) {
-			if (arm->layer & selbone->layer) {
-				if ((selbone->flag & BONE_SELECTED) && (selbone!=actbone)) {
-					/* align selbone to actbone */
-					bone_align_to_bone(arm->edbo, selbone, actbone);
-					
-					if (arm->flag & ARM_MIRROR_EDIT) {
-						/* - if there's a mirrored copy of selbone, try to find a mirrored copy of actbone 
-						 *	(i.e.  selbone="child.L" and actbone="parent.L", find "child.R" and "parent.R").
-						 *	This is useful for arm-chains, for example parenting lower arm to upper arm
-						 * - if there's no mirrored copy of actbone (i.e. actbone = "parent.C" or "parent")
-						 *	then just use actbone. Useful when doing upper arm to spine.
-						 */
-						flipbone = armature_bone_get_mirrored(arm->edbo, selbone);
-						flippar = armature_bone_get_mirrored(arm->edbo, actbone);
-						
-						if (flipbone) {
-							if (flippar)
-								bone_align_to_bone(arm->edbo, flipbone, flippar);
-							else
-								bone_align_to_bone(arm->edbo, flipbone, actbone);
-						}
-					}
-				}
-			}
+		/* Align 'selected' bones to the active one
+		 * - the context iterator contains both selected bones and their mirrored copies,
+		 *   so we assume that unselected bones are mirrored copies of some selected bone
+		 */
+		
+		/* align selected bones to the active one */
+		CTX_DATA_BEGIN(C, EditBone *, ebone, selected_editable_bones) {
+			if (ebone->flag & BONE_SELECTED)
+				bone_align_to_bone(arm->edbo, ebone, actbone);
+			else
+				bone_align_to_bone(arm->edbo, ebone, actmirb);
 		}
+		CTX_DATA_END;
 	}
+	
 
-	countall(); /* checks selection */
-	BIF_undo_push("Align bones");
+	/* note, notifier might evolve */
+	WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
+	
+	return OPERATOR_FINISHED;
+}
 
-	return;
+void ARMATURE_OT_align_bones(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name= "Align Bones";
+	ot->idname= "ARMATURE_OT_align_bones";
+	
+	/* api callbacks */
+	ot->invoke = WM_operator_confirm;
+	ot->exec = armature_align_bones_exec;
+	ot->poll = ED_operator_editarmature;
+	
+	/* flags */
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
 /* ***************** Pose tools ********************* */
@@ -4052,7 +4051,7 @@
 	ot->poll = ED_operator_posemode;
 	
 	/* flags */
-	ot->flag= OPTYPE_UNDO;
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
 static int pose_clear_loc_exec(bContext *C, wmOperator *op) 
@@ -4094,7 +4093,7 @@
 	ot->poll = ED_operator_posemode;
 	
 	/* flags */
-	ot->flag= OPTYPE_UNDO;
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 }
 
 static int pose_clear_rot_exec(bContext *C, wmOperator *op) 
@@ -4169,7 +4168,7 @@
 	ot->poll = ED_operator_posemode;
 	
 	/* flags */
-	ot->flag= OPTYPE_UNDO;
+	ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
 } 
 /* ************* hide/unhide pose bones ******************* */

Modified: branches/blender2.5/blender/source/blender/editors/space_view3d/space_view3d.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/space_view3d/space_view3d.c	2009-02-06 01:21:38 UTC (rev 18823)
+++ branches/blender2.5/blender/source/blender/editors/space_view3d/space_view3d.c	2009-02-06 01:39:55 UTC (rev 18824)
@@ -469,10 +469,13 @@
 		if (arm && arm->edbo) {
 			/* Attention: X-Axis Mirroring is also handled here... */
 			for (ebone= arm->edbo->first; ebone; ebone= ebone->next) {
-				/* first and foremost, bone must be visible */
-				if (EBONE_VISIBLE(arm, ebone)) {
-					/* get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
-					 * so that users of this data don't need to check for it themselves
+				/* first and foremost, bone must be visible and selected */
+				if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
+					/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
+					 * so that most users of this data don't need to explicitly check for it themselves.
+					 * 
+					 * We need to make sure that these mirrored copies are not selected, otherwise some
+					 * bones will be operated on twice.
 					 */

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list