Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2008-12-29 04:19:25 +0300
committerJoshua Leung <aligorith@gmail.com>2008-12-29 04:19:25 +0300
commit97a82102d4d24a94d8360a6f5f054e44f6fb1993 (patch)
treef204580537752d9aa602aaaae66246affe042f66
parent87cae4caed35c50b2ef70fb104d6f057670eb94e (diff)
2.5 - Action Editor / Animation Stuff:
* Brought back clean (OKEY), sample (Shift-OKEY), and delete (XKEY/DELKEY) tools for the Action Editor. Currently clean uses a predefined threshold (as a rna-prop, though it's still lacking the popup to set this when it is called) * Added new file for 'destructive' keyframe operations/tools. * Got keyframing.c compiling. Now, some of these tools need to be operatorised. Also, the API there might change when enough of the system is stable for RNA-IPO work to take place (so that it can be tested).
-rw-r--r--source/blender/blenkernel/BKE_action.h1
-rw-r--r--source/blender/blenkernel/intern/action.c11
-rw-r--r--source/blender/editors/animation/anim_deps.c2
-rw-r--r--source/blender/editors/animation/keyframes_edit.c5
-rw-r--r--source/blender/editors/animation/keyframes_general.c364
-rw-r--r--source/blender/editors/animation/keyframing.c533
-rw-r--r--source/blender/editors/include/ED_anim_api.h4
-rw-r--r--source/blender/editors/include/ED_keyframes_edit.h13
-rw-r--r--source/blender/editors/include/ED_keyframing.h11
-rw-r--r--source/blender/editors/space_action/action_edit_keyframes.c257
-rw-r--r--source/blender/editors/space_action/action_header.c157
-rw-r--r--source/blender/editors/space_action/action_intern.h4
-rw-r--r--source/blender/editors/space_action/action_ops.c10
-rw-r--r--source/blender/editors/space_action/action_select.c40
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h2
16 files changed, 1254 insertions, 161 deletions
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index a0c8be7d7f8..574d4154e86 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -51,6 +51,7 @@ struct ID;
extern "C" {
#endif
+struct bAction *add_empty_action(const char name[]);
/**
* Removes and deallocates all channels from a pose.
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index beef3e1ef1d..f2a92b9024f 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -81,6 +81,17 @@
/* ***************** Library data level operations on action ************** */
+bAction *add_empty_action(const char name[])
+{
+ bAction *act;
+
+ act= alloc_libblock(&G.main->action, ID_AC, name);
+ act->id.flag |= LIB_FAKEUSER;
+ act->id.us++;
+
+ return act;
+}
+
static void make_local_action_channels(bAction *act)
{
bActionChannel *chan;
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index f825a38bd7d..fbd9f5ecdb7 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -73,7 +73,7 @@ static unsigned int screen_view3d_layers(bScreen *screen)
/* generic update flush, reads from context Screen (layers) and scene */
/* this is for compliancy, later it can do all windows etc */
-void ED_anim_dag_flush_update(bContext *C)
+void ED_anim_dag_flush_update(const bContext *C)
{
Scene *scene= CTX_data_scene(C);
bScreen *screen= CTX_wm_screen(C);
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index b8a3b8acb19..8a7a7582ee3 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -17,8 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
+ * The Original Code is Copyright (C) 2008 Blender Foundation
*
* Contributor(s): Joshua Leung
*
@@ -30,6 +29,8 @@
#include <math.h>
#include <float.h>
+#include "MEM_guardedalloc.h"
+
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
new file mode 100644
index 00000000000..57a4d6952c7
--- /dev/null
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -0,0 +1,364 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation
+ * All rights reserved.
+ *
+ * Contributor(s): Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_key_types.h"
+#include "DNA_object_types.h"
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+
+#include "BKE_action.h"
+#include "BKE_ipo.h"
+#include "BKE_key.h"
+#include "BKE_utildefines.h"
+
+#include "ED_anim_api.h"
+#include "ED_keyframing.h"
+#include "ED_keyframes_edit.h"
+
+/* This file contains code for various keyframe-editing tools which are 'destructive'
+ * (i.e. they will modify the order of the keyframes, and change the size of the array).
+ * While some of these tools may eventually be moved out into blenkernel, for now, it is
+ * fine to have these calls here.
+ *
+ * There are also a few tools here which cannot be easily coded for in the other system (yet).
+ * These may also be moved around at some point, but for now, they
+ *
+ * - Joshua Leung, Dec 2008
+ */
+
+/* **************************************************** */
+
+/* Only delete the nominated keyframe from provided ipo-curve.
+ * Not recommended to be used many times successively. For that
+ * there is delete_ipo_keys().
+ */
+void delete_icu_key(IpoCurve *icu, int index, short do_recalc)
+{
+ /* firstly check that index is valid */
+ if (index < 0)
+ index *= -1;
+ if (icu == NULL)
+ return;
+ if (index >= icu->totvert)
+ return;
+
+ /* Delete this key */
+ memmove(&icu->bezt[index], &icu->bezt[index+1], sizeof(BezTriple)*(icu->totvert-index-1));
+ icu->totvert--;
+
+ /* recalc handles - only if it won't cause problems */
+ if (do_recalc)
+ calchandles_ipocurve(icu);
+}
+
+/* Delete selected keyframes in given IPO block */
+void delete_ipo_keys(Ipo *ipo)
+{
+ IpoCurve *icu, *next;
+ int i;
+
+ if (ipo == NULL)
+ return;
+
+ for (icu= ipo->curve.first; icu; icu= next) {
+ /* store pointer to next ipo-curve, as we may delete the current one */
+ next = icu->next;
+
+ /* Delete selected BezTriples */
+ for (i=0; i<icu->totvert; i++) {
+ if (icu->bezt[i].f2 & SELECT) {
+ memmove(&icu->bezt[i], &icu->bezt[i+1], sizeof(BezTriple)*(icu->totvert-i-1));
+ icu->totvert--;
+ i--;
+ }
+ }
+
+ /* Only delete if there isn't an ipo-driver still hanging around on an empty curve */
+ if ((icu->totvert==0) && (icu->driver==NULL)) {
+ BLI_remlink(&ipo->curve, icu);
+ free_ipo_curve(icu);
+ }
+ }
+}
+
+/* ---------------- */
+
+/* duplicate selected keyframes for the given IPO block */
+void duplicate_ipo_keys(Ipo *ipo)
+{
+ IpoCurve *icu;
+ BezTriple *newbezt;
+ int i;
+
+ if (ipo == NULL)
+ return;
+
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (i=0; i<icu->totvert; i++) {
+ /* If a key is selected */
+ if (icu->bezt[i].f2 & SELECT) {
+ /* Expand the list */
+ newbezt = MEM_callocN(sizeof(BezTriple) * (icu->totvert+1), "beztriple");
+
+ memcpy(newbezt, icu->bezt, sizeof(BezTriple) * (i+1));
+ memcpy(newbezt+i+1, icu->bezt+i, sizeof(BezTriple));
+ memcpy(newbezt+i+2, icu->bezt+i+1, sizeof (BezTriple) *(icu->totvert-(i+1)));
+ icu->totvert++;
+
+ /* reassign pointers... (free old, and add new) */
+ MEM_freeN(icu->bezt);
+ icu->bezt=newbezt;
+
+ /* Unselect the current key*/
+ BEZ_DESEL(&icu->bezt[i]);
+ i++;
+
+ /* Select the copied key */
+ BEZ_SEL(&icu->bezt[i]);
+ }
+ }
+ }
+}
+
+/* **************************************************** */
+/* Various Tools */
+
+/* Basic IPO-Curve 'cleanup' function that removes 'double points' and unnecessary keyframes on linear-segments only */
+void clean_ipo_curve(IpoCurve *icu, float thresh)
+{
+ BezTriple *old_bezts, *bezt, *beztn;
+ BezTriple *lastb;
+ int totCount, i;
+
+ /* check if any points */
+ if ((icu == NULL) || (icu->totvert <= 1))
+ return;
+
+ /* make a copy of the old BezTriples, and clear IPO curve */
+ old_bezts = icu->bezt;
+ totCount = icu->totvert;
+ icu->bezt = NULL;
+ icu->totvert = 0;
+
+ /* now insert first keyframe, as it should be ok */
+ bezt = old_bezts;
+ insert_vert_icu(icu, bezt->vec[1][0], bezt->vec[1][1], 0);
+
+ /* Loop through BezTriples, comparing them. Skip any that do
+ * not fit the criteria for "ok" points.
+ */
+ for (i=1; i<totCount; i++) {
+ float prev[2], cur[2], next[2];
+
+ /* get BezTriples and their values */
+ if (i < (totCount - 1)) {
+ beztn = (old_bezts + (i+1));
+ next[0]= beztn->vec[1][0]; next[1]= beztn->vec[1][1];
+ }
+ else {
+ beztn = NULL;
+ next[0] = next[1] = 0.0f;
+ }
+ lastb= (icu->bezt + (icu->totvert - 1));
+ bezt= (old_bezts + i);
+
+ /* get references for quicker access */
+ prev[0] = lastb->vec[1][0]; prev[1] = lastb->vec[1][1];
+ cur[0] = bezt->vec[1][0]; cur[1] = bezt->vec[1][1];
+
+ /* check if current bezt occurs at same time as last ok */
+ if (IS_EQT(cur[0], prev[0], thresh)) {
+ /* If there is a next beztriple, and if occurs at the same time, only insert
+ * if there is a considerable distance between the points, and also if the
+ * current is further away than the next one is to the previous.
+ */
+ if (beztn && (IS_EQT(cur[0], next[0], thresh)) &&
+ (IS_EQT(next[1], prev[1], thresh)==0))
+ {
+ /* only add if current is further away from previous */
+ if (cur[1] > next[1]) {
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
+ }
+ }
+ else {
+ /* only add if values are a considerable distance apart */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
+ }
+ }
+ else {
+ /* checks required are dependent on whether this is last keyframe or not */
+ if (beztn) {
+ /* does current have same value as previous and next? */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe*/
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
+ else if (IS_EQT(cur[1], next[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
+ }
+ else {
+ /* add if value doesn't equal that of previous */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_vert_icu(icu, cur[0], cur[1], 0);
+ }
+ }
+ }
+ }
+
+ /* now free the memory used by the old BezTriples */
+ if (old_bezts)
+ MEM_freeN(old_bezts);
+}
+
+/* ---------------- */
+
+/* temp struct used for smooth_ipo */
+typedef struct tSmooth_Bezt {
+ float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */
+} tSmooth_Bezt;
+
+/* Use a weighted moving-means method to reduce intensity of fluctuations */
+//mode= pupmenu("Smooth IPO%t|Tweak Points%x1|Flatten Handles%x2");
+void smooth_ipo_curve(IpoCurve *icu, short mode)
+{
+ BezTriple *bezt;
+ int i, x, totSel = 0;
+
+ /* first loop through - count how many verts are selected, and fix up handles
+ * this is done for both modes
+ */
+ bezt= icu->bezt;
+ for (i=0; i < icu->totvert; i++, bezt++) {
+ if (BEZSELECTED(bezt)) {
+ /* line point's handles up with point's vertical position */
+ bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
+ if ((bezt->h1==HD_AUTO) || (bezt->h1==HD_VECT)) bezt->h1= HD_ALIGN;
+ if ((bezt->h2==HD_AUTO) || (bezt->h2==HD_VECT)) bezt->h2= HD_ALIGN;
+
+ /* add value to total */
+ totSel++;
+ }
+ }
+
+ /* check if adjust values too... */
+ if (mode == 2) {
+ /* if any points were selected, allocate tSmooth_Bezt points to work on */
+ if (totSel >= 3) {
+ tSmooth_Bezt *tarray, *tsb;
+
+ /* allocate memory in one go */
+ tsb= tarray= MEM_callocN(totSel*sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
+
+ /* populate tarray with data of selected points */
+ bezt= icu->bezt;
+ for (i=0, x=0; (i < icu->totvert) && (x < totSel); i++, bezt++) {
+ if (BEZSELECTED(bezt)) {
+ /* tsb simply needs pointer to vec, and index */
+ tsb->h1 = &bezt->vec[0][1];
+ tsb->h2 = &bezt->vec[1][1];
+ tsb->h3 = &bezt->vec[2][1];
+
+ /* advance to the next tsb to populate */
+ if (x < totSel- 1)
+ tsb++;
+ else
+ break;
+ }
+ }
+
+ /* calculate the new smoothed ipo's with weighted averages:
+ * - this is done with two passes
+ * - uses 5 points for each operation (which stores in the relevant handles)
+ * - previous: w/a ratio = 3:5:2:1:1
+ * - next: w/a ratio = 1:1:2:5:3
+ */
+
+ /* round 1: calculate previous and next */
+ tsb= tarray;
+ for (i=0; i < totSel; i++, tsb++) {
+ /* don't touch end points (otherwise, curves slowly explode) */
+ if (ELEM(i, 0, (totSel-1)) == 0) {
+ const tSmooth_Bezt *tP1 = tsb - 1;
+ const tSmooth_Bezt *tP2 = (i-2 > 0) ? (tsb - 2) : (NULL);
+ const tSmooth_Bezt *tN1 = tsb + 1;
+ const tSmooth_Bezt *tN2 = (i+2 < totSel) ? (tsb + 2) : (NULL);
+
+ const float p1 = *tP1->h2;
+ const float p2 = (tP2) ? (*tP2->h2) : (*tP1->h2);
+ const float c1 = *tsb->h2;
+ const float n1 = *tN1->h2;
+ const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
+
+ /* calculate previous and next */
+ *tsb->h1= (3*p2 + 5*p1 + 2*c1 + n1 + n2) / 12;
+ *tsb->h3= (p2 + p1 + 2*c1 + 5*n1 + 3*n2) / 12;
+ }
+ }
+
+ /* round 2: calculate new values and reset handles */
+ tsb= tarray;
+ for (i=0; i < totSel; i++, tsb++) {
+ /* calculate new position by averaging handles */
+ *tsb->h2 = (*tsb->h1 + *tsb->h3) / 2;
+
+ /* reset handles now */
+ *tsb->h1 = *tsb->h2;
+ *tsb->h3 = *tsb->h2;
+ }
+
+ /* free memory required for tarray */
+ MEM_freeN(tarray);
+ }
+ }
+
+ /* recalculate handles */
+ calchandles_ipocurve(icu);
+}
+
+/* **************************************************** */
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index a86cf3719d3..ac41a63760d 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -55,9 +55,12 @@
#include "DNA_key_types.h"
#include "DNA_lamp_types.h"
#include "DNA_object_types.h"
+#include "DNA_object_fluidsim.h"
+#include "DNA_particle_types.h"
#include "DNA_material_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_userdef_types.h"
@@ -65,10 +68,9 @@
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
-#include "BKE_global.h"
+#include "BKE_context.h"
#include "BKE_utildefines.h"
#include "BKE_blender.h"
-#include "BKE_main.h" // XXX not needed old cruft?
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
@@ -77,31 +79,35 @@
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_material.h"
+#include "BKE_modifier.h"
+#include "ED_anim_api.h"
#include "ED_keyframing.h"
+#include "ED_keyframes_edit.h"
#if 0 // XXX resolve these old dependencies!
-#include "BIF_butspace.h"
-#include "BIF_editaction.h"
-#include "BIF_editkey.h"
-#include "BIF_interface.h"
-#include "BIF_mywindow.h"
-#include "BIF_poseobject.h"
-#include "BIF_screen.h"
-#include "BIF_space.h"
-#include "BIF_toolbox.h"
-#include "BIF_toets.h"
-
-#include "BSE_editipo.h"
-#include "BSE_node.h"
-#include "BSE_time.h"
-#include "BSE_view.h"
-
-#include "blendef.h"
-
-#include "PIL_time.h" /* sleep */
-#include "mydevice.h"
+ #include "BIF_butspace.h"
+ #include "BIF_editaction.h"
+ #include "BIF_editkey.h"
+ #include "BIF_interface.h"
+ #include "BIF_mywindow.h"
+ #include "BIF_poseobject.h"
+ #include "BIF_screen.h"
+ #include "BIF_space.h"
+ #include "BIF_toolbox.h"
+ #include "BIF_toets.h"
+
+ #include "BSE_editipo.h"
+ #include "BSE_node.h"
+ #include "BSE_time.h"
+ #include "BSE_view.h"
+
+ #include "blendef.h"
+
+ #include "PIL_time.h" /* sleep */
+ #include "mydevice.h"
#endif // XXX resolve these old dependencies!
@@ -169,6 +175,284 @@ typedef struct bKeyingContext {
int tot; /* number of keyingsets in */
} bKeyingContext;
+
+/* ************************************************** */
+/* IPO DATA VERIFICATION */
+// XXX these will need to be modified for use with RNA-IPO...
+
+/* depending type, it returns ipo, if needed it creates one */
+/* returns either action ipo or "real" ipo */
+/* arguments define full context;
+ - *from has to be set always, to Object in case of Actions
+ - blocktype defines available channels of Ipo struct (blocktype ID_OB can be in action too)
+ - if actname, use this to locate actionchannel, and optional constname
+ - if bonename, the constname is the ipo to the constraint
+*/
+
+/* note: check header_ipo.c, spaceipo_assign_ipo() too */
+Ipo *verify_ipo(ID *from, short blocktype, char actname[], char constname[], char bonename[], short add)
+{
+ /* lib-linked data is not appropriate here */
+ if ((from==NULL) || (from->lib))
+ return NULL;
+
+ /* first check action ipos */
+ if (actname && actname[0]) {
+ Object *ob= (Object *)from;
+ bActionChannel *achan;
+
+ if (GS(from->name)!=ID_OB) {
+ printf("called ipo system for action with wrong base pointer\n");
+ return NULL;
+ }
+
+ if ((ob->action==NULL) && (add))
+ ob->action= add_empty_action("Action");
+
+ if (add)
+ achan= verify_action_channel(ob->action, actname);
+ else
+ achan= get_action_channel(ob->action, actname);
+
+ if (achan) {
+ /* automatically assign achan to act-group based on pchan's grouping */
+ //if ((blocktype == ID_PO) && (add))
+ // verify_pchan2achan_grouping(ob->action, ob->pose, actname);
+
+ /* constraint exception */
+ if (blocktype==ID_CO) {
+ bConstraintChannel *conchan;
+
+ if (add)
+ conchan= verify_constraint_channel(&achan->constraintChannels, constname);
+ else
+ conchan= get_constraint_channel(&achan->constraintChannels, constname);
+
+ if (conchan) {
+ if ((conchan->ipo==NULL) && (add))
+ conchan->ipo= add_ipo("CoIpo", ID_CO);
+ return conchan->ipo;
+ }
+ }
+ else {
+ if ((achan->ipo==NULL) && (add))
+ achan->ipo= add_ipo("ActIpo", blocktype);
+ return achan->ipo;
+ }
+ }
+ }
+ else {
+ switch (GS(from->name)) {
+ case ID_OB:
+ {
+ Object *ob= (Object *)from;
+
+ /* constraint exception */
+ if (blocktype==ID_CO) {
+ /* check the local constraint ipo */
+ if (bonename && bonename[0] && ob->pose) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, bonename);
+ bConstraint *con;
+
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (strcmp(con->name, constname)==0)
+ break;
+ }
+
+ if (con) {
+ if ((con->ipo==NULL) && (add))
+ con->ipo= add_ipo("CoIpo", ID_CO);
+ return con->ipo;
+ }
+ }
+ else { /* the actionchannel */
+ bConstraintChannel *conchan;
+
+ if (add)
+ conchan= verify_constraint_channel(&ob->constraintChannels, constname);
+ else
+ conchan= get_constraint_channel(&ob->constraintChannels, constname);
+
+ if (conchan) {
+ if ((conchan->ipo==NULL) && (add))
+ conchan->ipo= add_ipo("CoIpo", ID_CO);
+ return conchan->ipo;
+ }
+ }
+ }
+ else if (blocktype==ID_OB) {
+ if ((ob->ipo==NULL) && (add))
+ ob->ipo= add_ipo("ObIpo", ID_OB);
+ return ob->ipo;
+ }
+ else if (blocktype==ID_KE) {
+ Key *key= ob_get_key((Object *)from);
+
+ if (key) {
+ if ((key->ipo==NULL) && (add))
+ key->ipo= add_ipo("KeyIpo", ID_KE);
+ return key->ipo;
+ }
+ return NULL;
+ }
+ else if (blocktype== ID_FLUIDSIM) {
+ Object *ob= (Object *)from;
+
+ FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
+ if(fluidmd) {
+ FluidsimSettings *fss= fluidmd->fss;
+
+ if ((fss->ipo==NULL) && (add))
+ fss->ipo= add_ipo("FluidsimIpo", ID_FLUIDSIM);
+ return fss->ipo;
+ }
+ }
+ else if(blocktype== ID_PA) {
+ Object *ob= (Object *)from;
+ ParticleSystem *psys= psys_get_current(ob);
+
+ if (psys) {
+ if ((psys->part->ipo==NULL) && (add))
+ psys->part->ipo= add_ipo("ParticleIpo", ID_PA);
+ return psys->part->ipo;
+ }
+ return NULL;
+ }
+ }
+ break;
+ case ID_MA:
+ {
+ Material *ma= (Material *)from;
+
+ if ((ma->ipo==NULL) && (add))
+ ma->ipo= add_ipo("MatIpo", ID_MA);
+ return ma->ipo;
+ }
+ break;
+ case ID_TE:
+ {
+ Tex *tex= (Tex *)from;
+
+ if ((tex->ipo==NULL) && (add))
+ tex->ipo= add_ipo("TexIpo", ID_TE);
+ return tex->ipo;
+ }
+ break;
+ case ID_SEQ:
+ {
+ Sequence *seq= (Sequence *)from; /* note, sequence is mimicing Id */
+
+ if ((seq->ipo==NULL) && (add))
+ seq->ipo= add_ipo("SeqIpo", ID_SEQ);
+ //update_seq_ipo_rect(seq); // XXX
+ return seq->ipo;
+ }
+ break;
+ case ID_CU:
+ {
+ Curve *cu= (Curve *)from;
+
+ if ((cu->ipo==NULL) && (add))
+ cu->ipo= add_ipo("CuIpo", ID_CU);
+ return cu->ipo;
+ }
+ break;
+ case ID_WO:
+ {
+ World *wo= (World *)from;
+
+ if ((wo->ipo==NULL) && (add))
+ wo->ipo= add_ipo("WoIpo", ID_WO);
+ return wo->ipo;
+ }
+ break;
+ case ID_LA:
+ {
+ Lamp *la= (Lamp *)from;
+
+ if ((la->ipo==NULL) && (add))
+ la->ipo= add_ipo("LaIpo", ID_LA);
+ return la->ipo;
+ }
+ break;
+ case ID_CA:
+ {
+ Camera *ca= (Camera *)from;
+
+ if ((ca->ipo==NULL) && (add))
+ ca->ipo= add_ipo("CaIpo", ID_CA);
+ return ca->ipo;
+ }
+ break;
+ case ID_SO:
+ {
+#if 0 // depreceated
+ bSound *snd= (bSound *)from;
+
+ if ((snd->ipo==NULL) && (add))
+ snd->ipo= add_ipo("SndIpo", ID_SO);
+ return snd->ipo;
+#endif // depreceated
+ }
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+/* Returns and creates
+ * Make sure functions check for NULL or they will crash!
+ */
+IpoCurve *verify_ipocurve(ID *from, short blocktype, char actname[], char constname[], char bonename[], int adrcode, short add)
+{
+ Ipo *ipo;
+ IpoCurve *icu= NULL;
+
+ /* return 0 if lib */
+ /* creates ipo too (if add) */
+ ipo= verify_ipo(from, blocktype, actname, constname, bonename, add);
+
+ if ((ipo) && (ipo->id.lib==NULL) && (from->lib==NULL)) {
+ /* try to find matching curve */
+ icu= find_ipocurve(ipo, adrcode);
+
+ /* make a new one if none found (and can add) */
+ if ((icu==NULL) && (add)) {
+ icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
+
+ /* set default settings */
+ icu->flag |= (IPO_VISIBLE|IPO_AUTO_HORIZ);
+ if (ipo->curve.first==NULL)
+ icu->flag |= IPO_ACTIVE; /* first one added active */
+
+ icu->blocktype= blocktype;
+ icu->adrcode= adrcode;
+
+ set_icu_vars(icu);
+
+ /* default curve interpolation - from userpref */
+ icu->ipo= U.ipo_new;
+
+ /* add curve to IPO-block */
+ BLI_addtail(&ipo->curve, icu);
+
+ /* special type-dependent stuff */
+ switch (GS(from->name)) {
+ case ID_SEQ: {
+ //Sequence *seq= (Sequence *)from;
+
+ //update_seq_icu_rects(seq); // XXX
+ break;
+ }
+ }
+ }
+ }
+
+ /* return ipo-curve */
+ return icu;
+}
+
/* ************************************************** */
/* KEYFRAME INSERTION */
@@ -382,7 +666,6 @@ void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
}
}
-#if 0 // XXX code to clean up
/* ------------------- Get Data ------------------------ */
@@ -787,11 +1070,11 @@ short insertkey (ID *id, int blocktype, char *actname, char *constname, int adrc
IpoCurve *icu;
/* get ipo-curve */
- //icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode, 1); // XXX this call needs to be in blenkernel
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode, 1);
/* only continue if we have an ipo-curve to add keyframe to */
if (icu) {
- float cfra = frame_to_float(CFRA);
+ float cfra =1.0f;//= frame_to_float(CFRA);
float curval= 0.0f;
/* apply special time tweaking */
@@ -803,10 +1086,10 @@ short insertkey (ID *id, int blocktype, char *actname, char *constname, int adrc
cfra= get_action_frame(ob, cfra);
/* ancient time-offset cruft */
- if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
- /* actually frametofloat calc again! */
- cfra-= give_timeoffset(ob)*G.scene->r.framelen;
- }
+ //if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
+ // /* actually frametofloat calc again! */
+ // cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ //}
}
/* obtain value to give keyframe */
@@ -894,13 +1177,12 @@ short deletekey (ID *id, int blocktype, char *actname, char *constname, int adrc
* Note: here is one of the places where we don't want new ipo + ipo-curve added!
* so 'add' var must be 0
*/
- // XXX funcs here need to be recoded in blenkernel...
- //ipo= verify_ipo(id, blocktype, actname, constname, NULL, 0);
- //icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode, 0);
+ ipo= verify_ipo(id, blocktype, actname, constname, NULL, 0);
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode, 0);
/* only continue if we have an ipo-curve to remove keyframes from */
if (icu) {
- float cfra = frame_to_float(CFRA);
+ float cfra = 1.0f;//frame_to_float(CFRA);
short found = -1;
int i;
@@ -913,10 +1195,10 @@ short deletekey (ID *id, int blocktype, char *actname, char *constname, int adrc
cfra= get_action_frame(ob, cfra);
/* ancient time-offset cruft */
- if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
- /* actually frametofloat calc again! */
- cfra-= give_timeoffset(ob)*G.scene->r.framelen;
- }
+ //if ( (ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)) ) {
+ // /* actually frametofloat calc again! */
+ // cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ //}
}
/* try to find index of beztriple to get rid of */
@@ -1101,7 +1383,8 @@ static short incl_non_del_keys (bKeyingSet *ks, const char mode[])
/* check if include shapekey entry */
static short incl_v3d_ob_shapekey (bKeyingSet *ks, const char mode[])
{
- Object *ob= (G.obedit)? (G.obedit) : (OBACT);
+ //Object *ob= (G.obedit)? (G.obedit) : (OBACT); // XXX
+ Object *ob= NULL;
char *newname= NULL;
if(ob==NULL)
@@ -1366,7 +1649,8 @@ bKeyingSet defks_buts_shading_tex[] =
/* check if include particles entry */
static short incl_buts_ob (bKeyingSet *ks, const char mode[])
{
- Object *ob= OBACT;
+ //Object *ob= OBACT; // xxx
+ Object *ob= NULL;
/* only if object is mesh type */
if(ob==NULL) return 0;
@@ -1396,15 +1680,17 @@ bKeyingSet defks_buts_object[] =
/* check if include internal-renderer entry */
static short incl_buts_cam1 (bKeyingSet *ks, const char mode[])
{
+ Scene *scene= NULL; // FIXME this will cause a crash, but we need an extra arg first!
/* only if renderer is internal renderer */
- return (G.scene->r.renderer==R_INTERN);
+ return (scene->r.renderer==R_INTERN);
}
/* check if include external-renderer entry */
static short incl_buts_cam2 (bKeyingSet *ks, const char mode[])
{
+ Scene *scene= NULL; // FIXME this will cause a crash, but we need an extra arg first!
/* only if renderer is internal renderer */
- return (G.scene->r.renderer!=R_INTERN);
+ return (scene->r.renderer!=R_INTERN);
}
/* array for camera keyingset defines */
@@ -1464,8 +1750,9 @@ typedef enum eKS_Contexts {
/* ---------------- KeyingSet Tools ------------------- */
/* helper for commonkey_context_get() - get keyingsets for 3d-view */
-static void commonkey_context_getv3d (ListBase *sources, bKeyingContext **ksc)
+static void commonkey_context_getv3d (const bContext *C, ListBase *sources, bKeyingContext **ksc)
{
+ Scene *scene= CTX_data_scene(C);
Object *ob;
IpoCurve *icu;
@@ -1475,7 +1762,8 @@ static void commonkey_context_getv3d (ListBase *sources, bKeyingContext **ksc)
/* pose-level */
ob= OBACT;
*ksc= &ks_contexts[KSC_V3D_PCHAN];
- set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
+ // XXX
+ //set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
/* loop through posechannels */
for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
@@ -1497,62 +1785,60 @@ static void commonkey_context_getv3d (ListBase *sources, bKeyingContext **ksc)
}
}
else {
- Base *base;
-
/* object-level */
*ksc= &ks_contexts[KSC_V3D_OBJECT];
/* loop through bases */
- for (base= FIRSTBASE; base; base= base->next) {
- if (TESTBASELIB(base)) {
- bCommonKeySrc *cks;
-
- /* add new keyframing destination */
- cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
- BLI_addtail(sources, cks);
-
- /* set id-block to key to */
- ob= base->object;
- cks->id= (ID *)ob;
-
- /* when ob's keyframes are in an action, default to using 'Object' as achan name */
- if (ob->ipoflag & OB_ACTION_OB)
- cks->actname= "Object";
-
- /* set ipo-flags */
- // TODO: add checks for lib-linked data
- if ((ob->ipo) || (ob->action)) {
- if (ob->ipo) {
- cks->ipo= ob->ipo;
- }
- else {
- bActionChannel *achan;
-
- cks->act= ob->action;
- achan= get_action_channel(ob->action, cks->actname);
-
- if (achan && achan->ipo)
- cks->ipo= achan->ipo;
- }
- /* cks->ipo can be NULL while editing */
- if(cks->ipo) {
- /* deselect all ipo-curves */
- for (icu= cks->ipo->curve.first; icu; icu= icu->next) {
- icu->flag &= ~IPO_SELECT;
- }
+ // XXX but we're only supposed to do this on editable ones!
+ CTX_DATA_BEGIN(C, Base*, base, selected_bases) {
+ bCommonKeySrc *cks;
+
+ /* add new keyframing destination */
+ cks= MEM_callocN(sizeof(bCommonKeySrc), "bCommonKeySrc");
+ BLI_addtail(sources, cks);
+
+ /* set id-block to key to */
+ ob= base->object;
+ cks->id= (ID *)ob;
+
+ /* when ob's keyframes are in an action, default to using 'Object' as achan name */
+ if (ob->ipoflag & OB_ACTION_OB)
+ cks->actname= "Object";
+
+ /* set ipo-flags */
+ // TODO: add checks for lib-linked data
+ if ((ob->ipo) || (ob->action)) {
+ if (ob->ipo) {
+ cks->ipo= ob->ipo;
+ }
+ else {
+ bActionChannel *achan;
+
+ cks->act= ob->action;
+ achan= get_action_channel(ob->action, cks->actname);
+
+ if (achan && achan->ipo)
+ cks->ipo= achan->ipo;
+ }
+ /* cks->ipo can be NULL while editing */
+ if(cks->ipo) {
+ /* deselect all ipo-curves */
+ for (icu= cks->ipo->curve.first; icu; icu= icu->next) {
+ icu->flag &= ~IPO_SELECT;
}
}
}
}
+ CTX_DATA_END;
}
}
/* helper for commonkey_context_get() - get keyingsets for buttons window */
-static void commonkey_context_getsbuts (ListBase *sources, bKeyingContext **ksc)
+static void commonkey_context_getsbuts (const bContext *C, ListBase *sources, bKeyingContext **ksc)
{
- bCommonKeySrc *cks;
-
#if 0 // XXX dunno what's the future of this stuff...
+ bCommonKeySrc *cks;
+
/* check on tab-type */
switch (G.buts->mainb) {
case CONTEXT_SHADING: /* ------------- Shading buttons ---------------- */
@@ -1690,21 +1976,25 @@ static void commonkey_context_getsbuts (ListBase *sources, bKeyingContext **ksc)
/* get keyingsets for appropriate context */
-static void commonkey_context_get (ScrArea *sa, short mode, ListBase *sources, bKeyingContext **ksc)
+static void commonkey_context_get (const bContext *C, ScrArea *sa, short mode, ListBase *sources, bKeyingContext **ksc)
{
+ /* get current view if no view is defined */
+ if (sa == NULL)
+ sa= CTX_wm_area(C);
+
/* check view type */
switch (sa->spacetype) {
/* 3d view - first one tested as most often used */
case SPACE_VIEW3D:
{
- commonkey_context_getv3d(sources, ksc);
+ commonkey_context_getv3d(C, sources, ksc);
}
break;
/* buttons view */
case SPACE_BUTS:
{
- commonkey_context_getsbuts(sources, ksc);
+ commonkey_context_getsbuts(C, sources, ksc);
}
break;
@@ -1721,6 +2011,7 @@ static void commonkey_context_get (ScrArea *sa, short mode, ListBase *sources, b
/* timeline view - keyframe buttons */
case SPACE_TIME:
{
+ bScreen *sc= CTX_wm_screen(C);
ScrArea *sab;
int bigarea= 0;
@@ -1731,12 +2022,12 @@ static void commonkey_context_get (ScrArea *sa, short mode, ListBase *sources, b
//sab= find_biggest_area_of_type(SPACE_VIEW3D);
sab= NULL; // XXX for now...
if (sab) {
- commonkey_context_getv3d(sources, ksc);
+ commonkey_context_getv3d(C, sources, ksc);
return;
}
/* if not found, sab is now NULL, so perform own biggest area test */
- for (sa= G.curscreen->areabase.first; sa; sa= sa->next) { // XXX this has changed!
+ for (sa= sc->areabase.first; sa; sa= sa->next) { // XXX this has changed!
int area= sa->winx * sa->winy;
if (sa->spacetype != SPACE_TIME) {
@@ -1749,15 +2040,18 @@ static void commonkey_context_get (ScrArea *sa, short mode, ListBase *sources, b
/* use whichever largest area was found (it shouldn't be a time window) */
if (sab)
- commonkey_context_get(sab, mode, sources, ksc);
+ commonkey_context_get(C, sab, mode, sources, ksc);
}
break;
}
}
/* flush updates after all operations */
-static void commonkey_context_finish (ListBase *sources)
+static void commonkey_context_finish (const bContext *C, ListBase *sources)
{
+ ScrArea *curarea= CTX_wm_area(C);
+ Scene *scene= CTX_data_scene(C);
+
/* check view type */
switch (curarea->spacetype) {
/* 3d view - first one tested as most often used */
@@ -1765,16 +2059,18 @@ static void commonkey_context_finish (ListBase *sources)
{
/* either pose or object level */
if (OBACT && (OBACT->pose)) {
- Object *ob= OBACT;
+ //Object *ob= OBACT;
/* recalculate ipo handles, etc. */
- if (ob->action)
- remake_action_ipos(ob->action);
+ // XXX this method has been removed!
+ //if (ob->action)
+ // remake_action_ipos(ob->action);
/* recalculate bone-paths on adding new keyframe? */
+ // XXX missing function
// TODO: currently, there is no setting to turn this on/off globally
- if (ob->pose->flag & POSE_RECALCPATHS)
- pose_recalculate_paths(ob);
+ //if (ob->pose->flag & POSE_RECALCPATHS)
+ // pose_recalculate_paths(ob);
}
else {
bCommonKeySrc *cks;
@@ -1793,19 +2089,17 @@ static void commonkey_context_finish (ListBase *sources)
}
/* flush refreshes after undo */
-static void commonkey_context_refresh (void)
+static void commonkey_context_refresh (const bContext *C)
{
+ ScrArea *curarea= CTX_wm_area(C);
+
/* check view type */
switch (curarea->spacetype) {
/* 3d view - first one tested as most often used */
case SPACE_VIEW3D:
{
/* do refreshes */
- DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
-
- //allspace(REMAKEIPO, 0);
- //allqueue(REDRAWVIEW3D, 0);
- //allqueue(REDRAWMARKER, 0);
+ ED_anim_dag_flush_update(C);
}
break;
@@ -1889,8 +2183,7 @@ static bKeyingSet *get_keyingset_fromcontext (bKeyingContext *ksc, short index)
/* ---------------- Keyframe Management API -------------------- */
/* Display a menu for handling the insertion of keyframes based on the active view */
-// TODO: add back an option for repeating last keytype
-void common_modifykey (short mode)
+void common_modifykey (const bContext *C, short mode)
{
ListBase dsources = {NULL, NULL};
bKeyingContext *ksc= NULL;
@@ -1906,7 +2199,7 @@ void common_modifykey (short mode)
/* delegate to other functions or get keyingsets to use
* - if the current area doesn't have its own handling, there will be data returned...
*/
- commonkey_context_get(curarea, mode, &dsources, &ksc);
+ commonkey_context_get(C, NULL, mode, &dsources, &ksc);
/* check that there is data to operate on */
if (ELEM(NULL, dsources.first, ksc)) {
@@ -1919,8 +2212,10 @@ void common_modifykey (short mode)
menustr= build_keyingsets_menu(ksc, "Delete");
else
menustr= build_keyingsets_menu(ksc, "Insert");
- menu_nr= pupmenu(menustr);
- if (menustr) MEM_freeN(menustr);
+ // XXX: this goes to the invoke!
+ //menu_nr= pupmenu(menustr);
+ //if (menustr) MEM_freeN(menustr);
+ menu_nr = -1; // XXX for now
/* no item selected or shapekey entry? */
if (menu_nr < 1) {
@@ -1928,9 +2223,10 @@ void common_modifykey (short mode)
BLI_freelistN(&dsources);
/* check if insert new shapekey */
- if ((menu_nr == 0) && (mode == COMMONKEY_MODE_INSERT))
- insert_shapekey(OBACT);
- else
+ // XXX missing function!
+ //if ((menu_nr == 0) && (mode == COMMONKEY_MODE_INSERT))
+ // insert_shapekey(OBACT);
+ //else
ksc->lastused= NULL;
return;
@@ -2053,7 +2349,7 @@ void common_modifykey (short mode)
}
/* apply post-keying flushes for this data sources */
- commonkey_context_finish(&dsources);
+ commonkey_context_finish(C, &dsources);
ksc->lastused= ks;
/* free temp data */
@@ -2064,27 +2360,26 @@ void common_modifykey (short mode)
BLI_snprintf(buf, 64, "Delete %s Key", ks->name);
else
BLI_snprintf(buf, 64, "Insert %s Key", ks->name);
- BIF_undo_push(buf);
+ //BIF_undo_push(buf);
/* queue updates for contexts */
- commonkey_context_refresh();
+ commonkey_context_refresh(C);
}
/* ---- */
/* used to insert keyframes from any view */
-void common_insertkey (void)
+void common_insertkey (const bContext *C)
{
- common_modifykey(COMMONKEY_MODE_INSERT);
+ common_modifykey(C, COMMONKEY_MODE_INSERT);
}
/* used to insert keyframes from any view */
-void common_deletekey (void)
+void common_deletekey (const bContext *C)
{
- common_modifykey(COMMONKEY_MODE_DELETE);
+ common_modifykey(C, COMMONKEY_MODE_DELETE);
}
-#endif // XXX reenable this file again later...
/* ************************************************** */
/* KEYFRAME DETECTION */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 492e2a22b84..4e55f8c364c 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -285,8 +285,8 @@ void ANIM_nla_mapping_apply(struct Object *ob, struct Ipo *ipo, short restore, s
/* --------- anim_deps.c, animation updates -------- */
/* generic update flush, reads from Context screen (layers) and scene */
-void ED_anim_dag_flush_update(struct bContext *C);
-void ED_update_for_newframe(struct bContext *C, int mute);
+void ED_anim_dag_flush_update(const struct bContext *C);
+void ED_update_for_newframe(const struct bContext *C, int mute);
/* ************************************************* */
/* OPERATORS */
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 3b553320f32..75faaf85d14 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -83,7 +83,7 @@ typedef enum eEditKeyframes_Mirror {
} eEditKeyframes_Mirror;
/* ************************************************ */
-/* Editing API */
+/* Non-Destuctive Editing API (keyframes_edit.c) */
/* --- Generic Properties for Bezier Edit Tools ----- */
@@ -129,9 +129,20 @@ BeztEditFunc ANIM_editkeyframes_ipo(short mode);
void ANIM_editkeyframes_ipocurve_ipotype(struct IpoCurve *icu);
/* ************************************************ */
+/* Destructive Editing API (keyframes_general.c) */
+
+void delete_icu_key(struct IpoCurve *icu, int index, short do_recalc);
+void delete_ipo_keys(struct Ipo *ipo);
+void duplicate_ipo_keys(struct Ipo *ipo);
+
+void clean_ipo_curve(struct IpoCurve *icu, float thresh);
+void smooth_ipo_curve(struct IpoCurve *icu, short mode);
+
+/* ************************************************ */
// XXX all of these funcs should be depreceated or at least renamed!
+/* in keyframes_edit.c */
short is_ipo_key_selected(struct Ipo *ipo);
void set_ipo_key_selection(struct Ipo *ipo, short sel);
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index f4be3f06c6b..9529058b952 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -31,9 +31,16 @@
struct ListBase;
struct ID;
+struct Ipo;
struct IpoCurve;
struct BezTriple;
+/* ************ IPO/IPO-Curve Management ************** */
+// XXX these will need to be updated for RNA-IPO stuff
+
+struct Ipo *verify_ipo(struct ID *from, short blocktype, char actname[], char constname[], char bonename[], short add);
+struct IpoCurve *verify_ipocurve(struct ID *from, short blocktype, char actname[], char constname[], char bonename[], int adrcode, short add);
+
/* ************ Keyframing Management **************** */
/* Lesser Keyframing API call:
@@ -84,8 +91,8 @@ short deletekey(struct ID *id, int blocktype, char *actname, char *constname, in
* These handle keyframes management from various spaces. They will handle the menus
* required for each space.
*/
-void common_insertkey(void);
-void common_deletekey(void);
+void common_insertkey(const struct bContext *C);
+void common_deletekey(const struct bContext *C);
/* ************ Auto-Keyframing ********************** */
/* Notes:
diff --git a/source/blender/editors/space_action/action_edit_keyframes.c b/source/blender/editors/space_action/action_edit_keyframes.c
index 4975a2cd6de..df62de9bd83 100644
--- a/source/blender/editors/space_action/action_edit_keyframes.c
+++ b/source/blender/editors/space_action/action_edit_keyframes.c
@@ -89,18 +89,265 @@
/* GENERAL STUFF */
// TODO:
-// - clean
-// - sample
// - delete
// - insert key
// - copy/paste
+/* ******************** Delete Keyframes Operator ************************* */
+
+static void delete_action_keys (bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ if (ac->datatype == ANIMCONT_GPENCIL)
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
+ else
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and delete selected keys */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ //if (ale->type == ANIMTYPE_GPLAYER)
+ // delete_gplayer_frames((bGPDlayer *)ale->data);
+ //else
+ delete_ipo_keys((Ipo *)ale->key_data);
+ }
+
+ /* free filtered list */
+ BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_delete_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* delete keyframes */
+ delete_action_keys(&ac);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier tha things have changed */
+ ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+
+ return OPERATOR_FINISHED;
+}
+
+void ACT_OT_keyframes_delete (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Delete Keyframes";
+ ot->idname= "ACT_OT_keyframes_delete";
+
+ /* api callbacks */
+ ot->exec= actkeys_delete_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+}
+
+/* ******************** Clean Keyframes Operator ************************* */
+
+static void clean_action_keys (bAnimContext *ac, float thresh)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_ONLYICU);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and clean curves */
+ for (ale= anim_data.first; ale; ale= ale->next)
+ clean_ipo_curve((IpoCurve *)ale->key_data, thresh);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_clean_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ float thresh;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ if (ac.datatype == ANIMCONT_GPENCIL)
+ return OPERATOR_PASS_THROUGH;
+
+ /* get cleaning threshold */
+ thresh= RNA_float_get(op->ptr, "threshold");
+
+ /* clean keyframes */
+ clean_action_keys(&ac, thresh);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier tha things have changed */
+ ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+
+ return OPERATOR_FINISHED;
+}
+
+void ACT_OT_keyframes_clean (wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name= "Clean Keyframes";
+ ot->idname= "ACT_OT_keyframes_clean";
+
+ /* api callbacks */
+ //ot->invoke= // XXX we need that number popup for this!
+ ot->exec= actkeys_clean_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+
+ /* properties */
+ prop= RNA_def_property(ot->srna, "threshold", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_default(prop, 0.001f);
+}
+
+/* ******************** Sample Keyframes Operator *********************** */
+
+/* little cache for values... */
+typedef struct tempFrameValCache {
+ float frame, val;
+} tempFrameValCache;
+
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
+static void sample_action_keys (bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
+ BezTriple *bezt, *start=NULL, *end=NULL;
+ tempFrameValCache *value_cache, *fp;
+ int sfra, range;
+ int i, n;
+
+ /* find selected keyframes... once pair has been found, add keyframes */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* check if selected, and which end this is */
+ if (BEZSELECTED(bezt)) {
+ if (start) {
+ /* set end */
+ end= bezt;
+
+ /* cache values then add keyframes using these values, as adding
+ * keyframes while sampling will affect the outcome...
+ */
+ range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
+ sfra= (int)( floor(start->vec[1][0]) );
+
+ if (range) {
+ value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
+
+ /* sample values */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ fp->frame= (float)(sfra + n);
+ fp->val= eval_icu(icu, fp->frame);
+ }
+
+ /* add keyframes with these */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ insert_vert_icu(icu, fp->frame, fp->val, 1);
+ }
+
+ /* free temp cache */
+ MEM_freeN(value_cache);
+
+ /* as we added keyframes, we need to compensate so that bezt is at the right place */
+ bezt = icu->bezt + i + range - 1;
+ i += (range - 1);
+ }
+
+ /* bezt was selected, so it now marks the start of a whole new chain to search */
+ start= bezt;
+ end= NULL;
+ }
+ else {
+ /* just set start keyframe */
+ start= bezt;
+ end= NULL;
+ }
+ }
+ }
+
+ /* recalculate channel's handles? */
+ calchandles_ipocurve(icu);
+ }
+
+ /* admin and redraws */
+ BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_sample_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ if (ac.datatype == ANIMCONT_GPENCIL)
+ return OPERATOR_PASS_THROUGH;
+
+ /* sample keyframes */
+ sample_action_keys(&ac);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier tha things have changed */
+ ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+
+ return OPERATOR_FINISHED;
+}
+
+void ACT_OT_keyframes_sample (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Sample Keyframes";
+ ot->idname= "ACT_OT_keyframes_sample";
+
+ /* api callbacks */
+ ot->exec= actkeys_sample_exec;
+ ot->poll= ED_operator_areaactive;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+}
+
/* ************************************************************************** */
/* SETTINGS STUFF */
-// TODO:
-// - wkey stuff
-
/* ******************** Set Extrapolation-Type Operator *********************** */
/* defines for set ipo-type for selected keyframes tool */
diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c
index 04958aede0f..d04ffd0935d 100644
--- a/source/blender/editors/space_action/action_header.c
+++ b/source/blender/editors/space_action/action_header.c
@@ -62,14 +62,165 @@
/* ********************************************************* */
/* Menu Defines... */
-// XXX button events
+/* button events */
enum {
B_REDR = 0,
B_ACTCOPYKEYS,
B_ACTPASTEKEYS,
} eActHeader_ButEvents;
-// ---------------- menus
+/* ------------------------------- */
+/* enums declaring constants that are used as menu event codes */
+
+enum {
+ ACTMENU_VIEW_CENTERVIEW= 0,
+ ACTMENU_VIEW_AUTOUPDATE,
+ ACTMENU_VIEW_PLAY3D,
+ ACTMENU_VIEW_PLAYALL,
+ ACTMENU_VIEW_ALL,
+ ACTMENU_VIEW_MAXIMIZE,
+ ACTMENU_VIEW_LOCK,
+ ACTMENU_VIEW_SLIDERS,
+ ACTMENU_VIEW_NEXTMARKER,
+ ACTMENU_VIEW_PREVMARKER,
+ ACTMENU_VIEW_NEXTKEYFRAME,
+ ACTMENU_VIEW_PREVKEYFRAME,
+ ACTMENU_VIEW_TIME,
+ ACTMENU_VIEW_NOHIDE,
+ ACTMENU_VIEW_FRANUM,
+ ACTMENU_VIEW_TRANSDELDUPS,
+ ACTMENU_VIEW_HORIZOPTIMISE,
+ ACTMENU_VIEW_GCOLORS,
+ ACTMENU_VIEW_PREVRANGESET,
+ ACTMENU_VIEW_PREVRANGECLEAR,
+ ACTMENU_VIEW_PREVRANGEAUTO
+};
+
+enum {
+ ACTMENU_SEL_BORDER = 0,
+ ACTMENU_SEL_BORDERC,
+ ACTMENU_SEL_BORDERM,
+ ACTMENU_SEL_ALL_KEYS,
+ ACTMENU_SEL_ALL_CHAN,
+ ACTMENU_SEL_ALL_MARKERS,
+ ACTMENU_SEL_INVERSE_KEYS,
+ ACTMENU_SEL_INVERSE_MARKERS,
+ ACTMENU_SEL_INVERSE_CHANNELS,
+ ACTMENU_SEL_LEFTKEYS,
+ ACTMENU_SEL_RIGHTKEYS
+};
+
+enum {
+ ACTMENU_SEL_COLUMN_KEYS = 1,
+ ACTMENU_SEL_COLUMN_CFRA,
+ ACTMENU_SEL_COLUMN_MARKERSCOLUMN,
+ ACTMENU_SEL_COLUMN_MARKERSBETWEEN
+};
+
+enum {
+ ACTMENU_CHANNELS_OPENLEVELS = 0,
+ ACTMENU_CHANNELS_CLOSELEVELS,
+ ACTMENU_CHANNELS_EXPANDALL,
+ ACTMENU_CHANNELS_SHOWACHANS,
+ ACTMENU_CHANNELS_DELETE
+};
+
+enum {
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_UP = 0,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_DOWN,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_TOP,
+ ACTMENU_CHANNELS_CHANPOS_MOVE_CHANNEL_BOTTOM
+};
+
+enum {
+ ACTMENU_CHANNELS_GROUP_ADD_TOACTIVE = 0,
+ ACTMENU_CHANNELS_GROUP_ADD_TONEW,
+ ACTMENU_CHANNELS_GROUP_REMOVE,
+ ACTMENU_CHANNELS_GROUP_SYNCPOSE
+};
+
+enum {
+ ACTMENU_CHANNELS_SETTINGS_TOGGLE = 0,
+ ACTMENU_CHANNELS_SETTINGS_ENABLE,
+ ACTMENU_CHANNELS_SETTINGS_DISABLE,
+};
+
+enum {
+ ACTMENU_KEY_DUPLICATE = 0,
+ ACTMENU_KEY_DELETE,
+ ACTMENU_KEY_CLEAN,
+ ACTMENU_KEY_SAMPLEKEYS,
+ ACTMENU_KEY_INSERTKEY
+};
+
+enum {
+ ACTMENU_KEY_TRANSFORM_MOVE = 0,
+ ACTMENU_KEY_TRANSFORM_SCALE,
+ ACTMENU_KEY_TRANSFORM_SLIDE,
+ ACTMENU_KEY_TRANSFORM_EXTEND
+};
+
+enum {
+ ACTMENU_KEY_HANDLE_AUTO = 0,
+ ACTMENU_KEY_HANDLE_ALIGN,
+ ACTMENU_KEY_HANDLE_FREE,
+ ACTMENU_KEY_HANDLE_VECTOR
+};
+
+enum {
+ ACTMENU_KEY_INTERP_CONST = 0,
+ ACTMENU_KEY_INTERP_LINEAR,
+ ACTMENU_KEY_INTERP_BEZIER
+};
+
+enum {
+ ACTMENU_KEY_EXTEND_CONST = 0,
+ ACTMENU_KEY_EXTEND_EXTRAPOLATION,
+ ACTMENU_KEY_EXTEND_CYCLIC,
+ ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION
+};
+
+enum {
+ ACTMENU_KEY_SNAP_NEARFRAME = 1,
+ ACTMENU_KEY_SNAP_CURFRAME,
+ ACTMENU_KEY_SNAP_NEARMARK,
+ ACTMENU_KEY_SNAP_NEARTIME,
+ ACTMENU_KEY_SNAP_CFRA2KEY,
+};
+
+enum {
+ ACTMENU_KEY_MIRROR_CURFRAME = 1,
+ ACTMENU_KEY_MIRROR_YAXIS,
+ ACTMENU_KEY_MIRROR_XAXIS,
+ ACTMENU_KEY_MIRROR_MARKER
+};
+
+enum {
+ ACTMENU_MARKERS_ADD = 0,
+ ACTMENU_MARKERS_DUPLICATE,
+ ACTMENU_MARKERS_DELETE,
+ ACTMENU_MARKERS_NAME,
+ ACTMENU_MARKERS_MOVE,
+ ACTMENU_MARKERS_LOCALADD,
+ ACTMENU_MARKERS_LOCALRENAME,
+ ACTMENU_MARKERS_LOCALDELETE,
+ ACTMENU_MARKERS_LOCALMOVE
+};
+
+/* ------------------------------- */
+/* macros for easier state testing (only for use here) */
+
+/* test if active action editor is showing any markers */
+#if 0
+ #define G_SACTION_HASMARKERS \
+ ((G.saction->action && G.saction->action->markers.first) \
+ || (G.scene->markers.first))
+#endif
+
+/* ------------------------------- */
+
+/* *************************************************************** */
+/* menus */
/* Key menu --------------------------- */
@@ -288,7 +439,7 @@ static uiBlock *action_viewmenu(bContext *C, uiMenuBlockHandle *handle, void *ar
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Nothing yet", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- if(curarea->headertype==HEADERTOP) {
+ if (curarea->headertype==HEADERTOP) {
uiBlockSetDirection(block, UI_DOWN);
}
else {
diff --git a/source/blender/editors/space_action/action_intern.h b/source/blender/editors/space_action/action_intern.h
index 6f51ce49888..6f0b5c9899d 100644
--- a/source/blender/editors/space_action/action_intern.h
+++ b/source/blender/editors/space_action/action_intern.h
@@ -73,6 +73,10 @@ enum {
/* ***************************************** */
/* action_edit_keyframes.c */
+void ACT_OT_keyframes_delete(struct wmOperatorType *ot);
+void ACT_OT_keyframes_clean(struct wmOperatorType *ot);
+void ACT_OT_keyframes_sample(struct wmOperatorType *ot);
+
void ACT_OT_keyframes_handletype(struct wmOperatorType *ot);
void ACT_OT_keyframes_ipotype(struct wmOperatorType *ot);
void ACT_OT_keyframes_expotype(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index d6a7fda2704..cd9be252fa8 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -75,6 +75,9 @@ void action_operatortypes(void)
WM_operatortype_append(ACT_OT_keyframes_handletype);
WM_operatortype_append(ACT_OT_keyframes_ipotype);
WM_operatortype_append(ACT_OT_keyframes_expotype);
+ WM_operatortype_append(ACT_OT_keyframes_sample);
+ WM_operatortype_append(ACT_OT_keyframes_clean);
+ WM_operatortype_append(ACT_OT_keyframes_delete);
}
/* ************************** registration - keymaps **********************************/
@@ -114,6 +117,13 @@ static void action_keymap_keyframes (ListBase *keymap)
WM_keymap_add_item(keymap, "ACT_OT_keyframes_handletype", HKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACT_OT_keyframes_ipotype", TKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ACT_OT_keyframes_expotype", EKEY, KM_PRESS, KM_SHIFT, 0); // temp...
+
+ /* destructive */
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_clean", OKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_sample", OKEY, KM_PRESS, KM_SHIFT, 0);
+
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "ACT_OT_keyframes_delete", DELKEY, KM_PRESS, 0, 0);
}
/* --------------- */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 46bf2549087..d356d7a7f42 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -88,31 +88,23 @@
/* ************************************************************************** */
/* GENERAL STUFF */
-#if 0
/* this function finds the channel that mouse is floating over */
-void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
+void *get_nearest_act_channel (bAnimContext *ac, int mval[2], short *ret_type, void **owner)
{
- ListBase act_data = {NULL, NULL};
- bActListElem *ale;
- void *data;
- short datatype;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
int filter;
+ View2D *v2d= &ac->ar->v2d;
int clickmin, clickmax;
- float x,y;
+ float x, y;
+ void *data= NULL;
/* init 'owner' return val */
*owner= NULL;
- /* determine what type of data we are operating on */
- data = get_action_context(&datatype);
- if (data == NULL) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
+ clickmin = (int) ((ACHANNEL_HEIGHT_HALF - y) / (ACHANNEL_STEP));
clickmax = clickmin;
if (clickmax < 0) {
@@ -121,10 +113,10 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
}
/* filter data */
- filter= (ACTFILTER_FORDRAWING | ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
- actdata_filter(&act_data, filter, data, datatype);
+ filter= (ANIMFILTER_FORDRAWING | ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
+ ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
- for (ale= act_data.first; ale; ale= ale->next) {
+ for (ale= anim_data.first; ale; ale= ale->next) {
if (clickmax < 0)
break;
if (clickmin <= 0) {
@@ -133,7 +125,7 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
data= ale->data;
/* if an 'ID' has been set, this takes presidence as owner (for dopesheet) */
- if (datatype == ACTCONT_DOPESHEET) {
+ if (ac->datatype == ANIMCONT_DOPESHEET) {
/* return pointer to ID as owner instead */
if (ale->id)
*owner= ale->id;
@@ -145,7 +137,7 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
*owner= ale->owner;
}
- BLI_freelistN(&act_data);
+ BLI_freelistN(&anim_data);
return data;
}
@@ -154,12 +146,12 @@ void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
}
/* cleanup */
- BLI_freelistN(&act_data);
+ BLI_freelistN(&anim_data);
- *ret_type= ACTTYPE_NONE;
+ *ret_type= ANIMTYPE_NONE;
return NULL;
}
-#endif
+
/* used only by mouse_action. It is used to find the location of the nearest
* keyframe to where the mouse clicked,
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 48c12c527c5..b84e337625a 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -402,7 +402,6 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
/* own keymap */
keymap= WM_keymap_listbase(wm, "Outliner", SPACE_OOPS, 0); /* XXX weak? */
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
-
}
static void outliner_rna_draw(const bContext *C, ARegion *ar)
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 975403c3a5f..4ef2f32c914 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -207,7 +207,7 @@ typedef struct UserDef {
short smooth_viewtx; /* miliseconds to spend spinning the view */
short glreslimit;
short ndof_pan, ndof_rotate;
- short curssize, pad;
+ short curssize, ipo_new;
// char pad[8];
char versemaster[160];
char verseuser[160];