[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [18069] branches/blender2.5/blender/source /blender/editors: 2.5 - Action Editor: All Keyframe Selection Tools Ported

Joshua Leung aligorith at gmail.com
Fri Dec 26 11:55:09 CET 2008


Revision: 18069
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18069
Author:   aligorith
Date:     2008-12-26 11:55:07 +0100 (Fri, 26 Dec 2008)

Log Message:
-----------
2.5 - Action Editor: All Keyframe Selection Tools Ported

User Notes (for using tools whose behaviour has changed):
* Mouse Selection Tools: 
1) Click on keyframe to modify its selection. Holding the 'Shift' modifier when doing so, will result in keyframe selection being toggled instead of replacing existing selections.
2) Click on either side of the current frame indicator while holding the 'Alt' modifier. This will select only all the keyframes on the relevant side of the current frame indicator.
3) Click on a keyframe while holding the 'Ctrl' modifier. This will select all the keyframes that fall on that frame.

* Borderselect Tools 
1) BKEY selects all the keyframes within the specified range (as per normal)
2) ALT-BKEY will select either all the keyframes in the frame-range specified or the channel range specified, depending on which axis of the select region was larger. This method is prejudiced towards frame-range selection.

Code Notes:
* Finished porting over all of the remaining keyframe selection tools, and recoded the ported ones to make them easier to use (after running into some technical limitations)

* Simplified the way to check if 'animation context' is valid by moving a necessary check into that function.

* Refactored internal keyframe-looping tools to reduce the amount of code needed per tool to edit keyframes, removing a lot of the unnecessary bulk. Now, the ipo/icu_keys_bezier_loop functions recieve a few more arguments (1st arg is pointer to generic customdata, and another defines a validation callback which makes it easier to reuse some of the select callbacks).

* Added 'totrect' adjustment for number of channels being shown in Action Editor, so that scrolling will be limited to where there is data (and also so that scroller displays more relevant context info). 
For this to work, filtering channels now returns the number of channels extracted. This may come into use for other tools if there's such a need.

* I still need to port over some code for markers, which is required for some of the tools which use them. For now, those tools do nothing.

* Grease-Pencil editing mode in Action Editor is currently non-functional (code is commented out due to missing dependencies). This is currently pending the re-implementation of Grease Pencil in 2.5

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/animation/anim_filter.c
    branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c
    branches/blender2.5/blender/source/blender/editors/include/ED_anim_api.h
    branches/blender2.5/blender/source/blender/editors/include/ED_keyframes_edit.h
    branches/blender2.5/blender/source/blender/editors/space_action/action_draw.c
    branches/blender2.5/blender/source/blender/editors/space_action/action_intern.h
    branches/blender2.5/blender/source/blender/editors/space_action/action_ops.c
    branches/blender2.5/blender/source/blender/editors/space_action/action_select.c
    branches/blender2.5/blender/source/blender/editors/space_action/space_action.c
    branches/blender2.5/blender/source/blender/editors/space_ipo/space_ipo.c

Modified: branches/blender2.5/blender/source/blender/editors/animation/anim_filter.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/anim_filter.c	2008-12-26 10:31:44 UTC (rev 18068)
+++ branches/blender2.5/blender/source/blender/editors/animation/anim_filter.c	2008-12-26 10:55:07 UTC (rev 18069)
@@ -210,9 +210,10 @@
  */
 short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
 {
-	ScrArea *sa= CTX_wm_area(C); // XXX it is assumed that this will always be valid
+	ScrArea *sa= CTX_wm_area(C);
 	ARegion *ar= CTX_wm_region(C);
 	Scene *scene= CTX_data_scene(C);
+	short ok= 0;
 	
 	/* clear old context info */
 	if (ac == NULL) return 0;
@@ -231,20 +232,23 @@
 		case SPACE_ACTION:
 		{
 			SpaceAction *saction= (SpaceAction *)CTX_wm_space_data(C);
-			return actedit_get_context(C, ac, saction);
+			ok= actedit_get_context(C, ac, saction);
 		}
 			break;
 			
 		case SPACE_IPO:
 		{
 			SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
-			return ipoedit_get_context(C, ac, sipo);
+			ok= ipoedit_get_context(C, ac, sipo);
 		}
 			break;
 	}
 	
-	/* nothing appropriate */
-	return 0;
+	/* check if there's any valid data */
+	if (ok && ac->data)
+		return 1;
+	else
+		return 0;
 }
 
 /* ************************************************************ */

Modified: branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c	2008-12-26 10:31:44 UTC (rev 18068)
+++ branches/blender2.5/blender/source/blender/editors/animation/keyframes_edit.c	2008-12-26 10:55:07 UTC (rev 18069)
@@ -28,6 +28,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
+#include <float.h>
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
@@ -60,6 +61,10 @@
  * appropriate bezier-modify function to set. These functions (ANIM_editkeyframes_*) will need
  * to be called before getting any channels.
  * 
+ * A set of 'validation' callbacks are provided for checking if a BezTriple should be operated on.
+ * These should only be used when using a 'general' BezTriple editor (i.e. selection setters which 
+ * don't check existing selection status).
+ * 
  * - Joshua Leung, Dec 2008
  */
 
@@ -74,19 +79,35 @@
 /* This function is used to loop over BezTriples in the given IpoCurve, applying a given 
  * operation on them, and optionally applies an IPO-curve validate function afterwards.
  */
-short icu_keys_bezier_loop(Scene *scene, IpoCurve *icu, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) 
+short icu_keys_bezier_loop(BeztEditData *bed, IpoCurve *icu, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb) 
 {
     BezTriple *bezt;
 	int b;
 	
 	/* if function to apply to bezier curves is set, then loop through executing it on beztriples */
     if (bezt_cb) {
-		for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
-			/* Exit with return-code '1' if function returns positive
-			 * This is useful if finding if some BezTriple satisfies a condition.
-			 */
-	        if (bezt_cb(scene, bezt)) return 1;
+		/* if there's a validation func, include that check in the loop 
+		 * (this is should be more efficient than checking for it in every loop)
+		 */
+		if (bezt_ok) {
+			for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
+				/* Only operate on this BezTriple if it fullfills the criteria of the validation func */
+				if (bezt_ok(bed, bezt)) {
+					/* Exit with return-code '1' if function returns positive
+					 * This is useful if finding if some BezTriple satisfies a condition.
+					 */
+			        if (bezt_cb(bed, bezt)) return 1;
+				}
+			}
 		}
+		else {
+			for (b=0, bezt=icu->bezt; b < icu->totvert; b++, bezt++) {
+				/* Exit with return-code '1' if function returns positive
+				 * This is useful if finding if some BezTriple satisfies a condition.
+				 */
+		        if (bezt_cb(bed, bezt)) return 1;
+			}
+		}
     }
 
     /* if ipocurve_function has been specified then execute it */
@@ -98,7 +119,7 @@
 }
 
 /* This function is used to loop over the IPO curves (and subsequently the keyframes in them) */
-short ipo_keys_bezier_loop(Scene *scene, Ipo *ipo, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+short ipo_keys_bezier_loop(BeztEditData *bed, Ipo *ipo, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
 {
     IpoCurve *icu;
 	
@@ -108,54 +129,98 @@
 	
     /* Loop through each curve in the Ipo */
     for (icu= ipo->curve.first; icu; icu=icu->next) {
-        if (icu_keys_bezier_loop(scene, icu, bezt_cb, icu_cb))
+        if (icu_keys_bezier_loop(bed, icu, bezt_ok, bezt_cb, icu_cb))
             return 1;
     }
 
     return 0;
 }
 
-/* This function is used to loop over the channels in an Action Group to modify the IPO blocks within them */
-short actgroup_keys_bezier_loop(Scene *scene, bActionGroup *agrp, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+/* -------------------------------- Further Abstracted ----------------------------- */
+
+/* This function is used to apply operation to all keyframes, regardless of the type */
+short animchannel_keys_bezier_loop(BeztEditData *bed, bAnimListElem *ale, BeztEditFunc bezt_ok, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
 {
-	
+	return 0;
 }
 
-/* -------------------------------- Further Abstracted ----------------------------- */
+/* ************************************************************************** */
+/* BezTriple Validation Callbacks */
 
-/* this function is called to apply the same operation to all types of channels */
-short animchannel_keys_bezier_loop(Scene *scene, bAnimListElem *ale, BeztEditFunc bezt_cb, IcuEditFunc icu_cb)
+static short ok_bezier_frame(BeztEditData *bed, BezTriple *bezt)
 {
+	/* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
+	return IS_EQ(bezt->vec[1][0], bed->f1);
+}
 
+static short ok_bezier_framerange(BeztEditData *bed, BezTriple *bezt)
+{
+	/* frame range is stored in float properties */
+	return ((bezt->vec[1][0] > bed->f1) && (bezt->vec[1][0] < bed->f2));
 }
 
+static short ok_bezier_selected(BeztEditData *bed, BezTriple *bezt)
+{
+	/* this macro checks all beztriple handles for selection... */
+	return BEZSELECTED(bezt);
+}
 
+static short ok_bezier_value(BeztEditData *bed, BezTriple *bezt)
+{
+	/* value is stored in f1 property 
+	 *	- this float accuracy check may need to be dropped?
+	 *	- should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
+	 */
+	return IS_EQ(bezt->vec[1][1], bed->f1);
+}
+
+
+BeztEditFunc ANIM_editkeyframes_ok(short mode)
+{
+	/* eEditKeyframes_Validate */
+	switch (mode) {
+		case BEZT_OK_FRAME: /* only if bezt falls on the right frame (float) */
+			return ok_bezier_frame;
+		case BEZT_OK_FRAMERANGE: /* only if bezt falls within the specified frame range (floats) */
+			return ok_bezier_framerange;
+		case BEZT_OK_SELECTED:	/* only if bezt is selected */
+			return ok_bezier_selected;
+		case BEZT_OK_VALUE: /* only if bezt value matches (float) */
+			return ok_bezier_value;
+		default: /* nothing was ok */
+			return NULL;
+	}
+}
+
 /* ******************************************* */
 /* Transform */
 
-static short snap_bezier_nearest(Scene *scene, BezTriple *bezt)
+static short snap_bezier_nearest(BeztEditData *bed, BezTriple *bezt)
 {
 	if (bezt->f2 & SELECT)
 		bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
 	return 0;
 }
 
-static short snap_bezier_nearestsec(Scene *scene, BezTriple *bezt)
+static short snap_bezier_nearestsec(BeztEditData *bed, BezTriple *bezt)
 {
-	float secf = FPS;
+	const Scene *scene= bed->scene;
+	const float secf = FPS;
+	
 	if (bezt->f2 & SELECT)
 		bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]/secf + 0.5f) * secf);
 	return 0;
 }
 
-static short snap_bezier_cframe(Scene *scene, BezTriple *bezt)
+static short snap_bezier_cframe(BeztEditData *bed, BezTriple *bezt)
 {
+	const Scene *scene= bed->scene;
 	if (bezt->f2 & SELECT)
 		bezt->vec[1][0]= (float)CFRA;
 	return 0;
 }
 
-static short snap_bezier_nearmarker(Scene *scene, BezTriple *bezt)
+static short snap_bezier_nearmarker(BeztEditData *bed, BezTriple *bezt)
 {
 	//if (bezt->f2 & SELECT)
 	//	bezt->vec[1][0]= (float)find_nearest_marker_time(bezt->vec[1][0]);  // XXX missing function!
@@ -163,8 +228,9 @@
 }
 
 // calchandles_ipocurve
-BeztEditFunc ANIM_editkeys_snap(short type)
+BeztEditFunc ANIM_editkeyframes_snap(short type)
 {
+	/* eEditKeyframes_Snap */
 	switch (type) {
 		case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
 			return snap_bezier_nearest;
@@ -181,8 +247,9 @@
 
 /* --------- */
 
-static short mirror_bezier_cframe(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_cframe(BeztEditData *bed, BezTriple *bezt)
 {
+	const Scene *scene= bed->scene;
 	float diff;
 	
 	if (bezt->f2 & SELECT) {
@@ -193,7 +260,7 @@
 	return 0;
 }
 
-static short mirror_bezier_yaxis(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_yaxis(BeztEditData *bed, BezTriple *bezt)
 {
 	float diff;
 	
@@ -205,7 +272,7 @@
 	return 0;
 }
 
-static short mirror_bezier_xaxis(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_xaxis(BeztEditData *bed, BezTriple *bezt)
 {
 	float diff;
 	
@@ -217,10 +284,11 @@
 	return 0;
 }
 
-static short mirror_bezier_marker(Scene *scene, BezTriple *bezt)
+static short mirror_bezier_marker(BeztEditData *bed, BezTriple *bezt)
 {
 	static TimeMarker *marker;
 	static short initialised = 0;
+	const Scene *scene= bed->scene;
 	
 	/* In order for this mirror function to work without
 	 * any extra arguments being added, we use the case
@@ -288,11 +356,13 @@
  *	for (ipo...) snap_cfra_ipo_keys(scene, ipo, 0); // sum up keyframe times
  *	snap_cfra_ipo_keys(scene, NULL, 1); // set current frame after taking average
  */
-void snap_cfra_ipo_keys(Scene *scene, Ipo *ipo, short mode)
+// XXX this thing needs to be refactored!
+void snap_cfra_ipo_keys(BeztEditData *bed, Ipo *ipo, short mode)
 {
 	static int cfra;
 	static int tot;
 	
+	Scene *scene= bed->scene;
 	IpoCurve *icu;
 	BezTriple *bezt;
 	int a;
@@ -330,7 +400,7 @@
 /* Settings */
 
 /* Sets the selected bezier handles to type 'auto' */
-static short set_bezier_auto(Scene *scene, BezTriple *bezt) 
+static short set_bezier_auto(BeztEditData *bed, BezTriple *bezt) 
 {
 	/* is a handle selected? If so set it to type auto */
 	if((bezt->f1  & SELECT) || (bezt->f3 & SELECT)) {
@@ -349,7 +419,7 @@
 }
 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list