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>2007-06-05 16:11:00 +0400
committerJoshua Leung <aligorith@gmail.com>2007-06-05 16:11:00 +0400
commit25935dbdb10dc905b5963951c339447aa181654b (patch)
tree4a2ea7d4946549da23d93fdc238abfd135d5d614
parent6b9fe36e0b86bb6acce5b49d4037cc235eb13121 (diff)
== Action Editor - Major Recode ==
I've just spent two days rewriting the Action Editor to unify its code and bring it under control again (it was 107kb, now it is around 73 kb). * This means that there are no longer separate functions for each tool for Actions and Shapekeys in the Action Editor, and also no more missing tools for either. * Also, I've gotten rid of the need for those complicated, hierarchial loops used for action channels, as they were a pain to keep consistent with each other. * Baking functions have been removed. See user-level-changes for more details. * Reorganised and completely rewrote code in editaction.c, thus the lengthy diff. User Level Changes: * For the meantime, border-selecting Action Channels has been disabled * Baking functions have been removed. As far as I have been able to find out, these were really non-functional anyway. Besides, I don't think they really belonged in editaction.c * Editing Shapekey keyframes now yields the same feature set as for those in Action Channels. * There shouldn't be any major bugs left, but I might have missed something. Further Work: * Do a cleanup like this to the Action Editor drawing code in drawaction.c * Baking??? (harkyman seems to be doing something about this)
-rw-r--r--source/blender/include/BIF_editaction.h85
-rw-r--r--source/blender/include/BSE_editaction_types.h75
-rw-r--r--source/blender/include/BSE_editipo.h1
-rw-r--r--source/blender/src/drawaction.c10
-rw-r--r--source/blender/src/editaction.c4934
-rw-r--r--source/blender/src/editipo_mods.c49
-rw-r--r--source/blender/src/editnla.c3
-rw-r--r--source/blender/src/header_action.c201
8 files changed, 2050 insertions, 3308 deletions
diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h
index 6e180418cd8..838bbb5c34c 100644
--- a/source/blender/include/BIF_editaction.h
+++ b/source/blender/include/BIF_editaction.h
@@ -33,21 +33,11 @@
#ifndef BIF_EDITACTION_H
#define BIF_EDITACTION_H
-#define SET_IPO_POPUP 0
-#define SET_IPO_CONSTANT 1
-#define SET_IPO_LINEAR 2
-#define SET_IPO_BEZIER 3
-
-#define SET_EXTEND_POPUP 0
-#define SET_EXTEND_CONSTANT 1
-#define SET_EXTEND_EXTRAPOLATION 2
-#define SET_EXTEND_CYCLIC 3
-#define SET_EXTEND_CYCLICEXTRAPOLATION 4
-
+/* some interface related sizes*/
#define CHANNELHEIGHT 16
#define CHANNELSKIP 2
-#define NAMEWIDTH 164
-#define SLIDERWIDTH 125
+#define NAMEWIDTH 164
+#define SLIDERWIDTH 125
#define ACTWIDTH (G.saction->actwidth)
/* Some types for easier type-testing */
@@ -57,6 +47,8 @@
#define ACTTYPE_ICU 3
#define ACTTYPE_FILLIPO 4
#define ACTTYPE_FILLCON 5
+#define ACTTYPE_IPO 6
+#define ACTTYPE_SHAPEKEY 7
/* Macros for easier/more consistant state testing */
#define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0)
@@ -72,6 +64,19 @@
#define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
#define SEL_ICU(icu) (icu->flag & IPO_SELECT)
+/* constants for setting ipo-interpolation type */
+#define SET_IPO_POPUP 0
+#define SET_IPO_CONSTANT 1
+#define SET_IPO_LINEAR 2
+#define SET_IPO_BEZIER 3
+
+/* constants for setting ipo-extrapolation type */
+#define SET_EXTEND_POPUP 10
+#define SET_EXTEND_CONSTANT 11
+#define SET_EXTEND_EXTRAPOLATION 12
+#define SET_EXTEND_CYCLIC 13
+#define SET_EXTEND_CYCLICEXTRAPOLATION 14
+
struct bAction;
struct bActionChannel;
struct bPoseChannel;
@@ -82,21 +87,18 @@ struct Key;
struct ListBase;
/* Key operations */
-void delete_meshchannel_keys(struct Key *key);
-void delete_actionchannel_keys(void);
-void duplicate_meshchannel_keys(struct Key *key);
-void duplicate_actionchannel_keys(void);
-void transform_actionchannel_keys(int mode, int dummy);
-void transform_meshchannel_keys(char mode, struct Key *key);
-void snap_keys_to_frame(int snap_mode);
-void mirror_action_keys(short mirror_mode);
-void clean_shapekeys(struct Key *key);
-void clean_actionchannels(struct bAction *act);
+void transform_action_keys(int mode, int dummy);
+void duplicate_action_keys(void);
+void snap_action_keys(short mode);
+void mirror_action_keys(short mode);
void insertkey_action(void);
+void delete_action_keys(void);
+void delete_action_channels(void);
+void clean_action(void);
-/* Marker Operations */
-void column_select_shapekeys(struct Key *key, int mode);
-void column_select_actionkeys(struct bAction *act, int mode);
+/* Column/Channel Key select */
+void column_select_action_keys(int mode);
+void selectall_action_keys(short mval[], short mode, short selectmode);
void markers_selectkeys_between(void);
/* channel/strip operations */
@@ -105,20 +107,15 @@ void down_sel_action(void);
void top_sel_action(void);
void bottom_sel_action(void);
-/* Handles */
-void sethandles_meshchannel_keys(int code, struct Key *key);
-void sethandles_actionchannel_keys(int code);
-
-/* Ipo type */
-void set_ipotype_actionchannels(int ipotype);
-void set_extendtype_actionchannels(int extendtype);
+/* IPO/Handle Types */
+void sethandles_action_keys(int code);
+void action_set_ipo_flags(int mode);
/* Select */
-void borderselect_mesh(struct Key *key);
void borderselect_action(void);
-void deselect_actionchannel_keys(struct bAction *act, int test, int sel);
-void deselect_actionchannels (struct bAction *act, int test);
-void deselect_meshchannel_keys (struct Key *key, int test, int sel);
+void deselect_action_keys(short test, short sel);
+void deselect_action_channels(short test);
+void deselect_actionchannels(struct bAction *act, short test);
int select_channel(struct bAction *act, struct bActionChannel *achan, int selectmode);
void select_actionchannel_by_name (struct bAction *act, char *name, int select);
@@ -128,19 +125,17 @@ int get_nearest_key_num(struct Key *key, short *mval, float *x);
void *get_nearest_act_channel(short mval[], short *ret_type);
/* Action */
-struct bActionChannel* get_hilighted_action_channel(struct bAction* action);
+struct bActionChannel *get_hilighted_action_channel(struct bAction* action);
struct bAction *add_empty_action(char *name);
-
-void winqreadactionspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
-
-/* contextual get action */
struct bAction *ob_get_action(struct Object *ob);
+void actdata_filter(ListBase *act_data, int filter_mode, void *data, short datatype);
+void *get_action_context(short *datatype);
+
void remake_action_ipos(struct bAction *act);
-/* this needs review badly! (ton) */
-struct bAction *bake_action_with_client (struct bAction *act, struct Object *arm, float tolerance);
-void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4]);
+/* event handling */
+void winqreadactionspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
#endif
diff --git a/source/blender/include/BSE_editaction_types.h b/source/blender/include/BSE_editaction_types.h
new file mode 100644
index 00000000000..c4f78710d2d
--- /dev/null
+++ b/source/blender/include/BSE_editaction_types.h
@@ -0,0 +1,75 @@
+/**
+ * $Id: BIF_editaction.h 10519 2007-04-13 11:15:08Z aligorith $
+ *
+ * ***** BEGIN GPL/BL DUAL 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. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * 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) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): 2007, Joshua Leung (major Action Editor recode)
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_EDITACTION_TYPES_H
+#define BIF_EDITACTION_TYPES_H
+
+/******************************************************* */
+/* FILTERED ACTION DATA - TYPES */
+
+/* types of keyframe data in ActListElem */
+#define ALE_NONE 0
+#define ALE_IPO 1
+#define ALE_ICU 2
+
+/* This struct defines a structure used for quick access */
+typedef struct bActListElem {
+ struct bActListElem *next, *prev;
+
+ void *data; /* source data this elem represents */
+ int type; /* one of the ACTTYPE_* values */
+ int flag; /* copy of elem's flags for quick access */
+
+ void *key_data; /* motion data - ipo or ipo-curve */
+ short datatype; /* type of motion data to expect */
+
+ void *owner; /* will either be an action channel or fake ipo-channel (for keys) */
+ short ownertype; /* type of owner */
+} bActListElem;
+
+/******************************************************* */
+/* FILTER ACTION DATA - METHODS/TYPES */
+
+/* filtering flags - under what circumstances should a channel be added */
+#define ACTFILTER_VISIBLE 0x001 /* should channels be visible */
+#define ACTFILTER_SEL 0x002 /* should channels be selected */
+#define ACTFILTER_FOREDIT 0x004 /* does editable status matter */
+#define ACTFILTER_CHANNELS 0x008 /* do we only care that it is a channel */
+#define ACTFILTER_IPOKEYS 0x010 /* only channels referencing ipo's */
+#define ACTFILTER_ONLYICU 0x020 /* only reference ipo-curves */
+
+/* Action Editor - Main Data types */
+#define ACTCONT_NONE 0
+#define ACTCONT_ACTION 1
+#define ACTCONT_SHAPEKEY 2
+
+#endif
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index 01f985018ed..f861a2abd7a 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -107,6 +107,7 @@ void ipo_mirror(short event);
void mouse_select_ipo(void);
void sethandles_ipo(int code);
void select_ipo_bezier_keys(struct Ipo *ipo, int selectmode);
+void select_icu_bezier_keys(struct IpoCurve *icu, int selectmode);
void set_ipotype(void);
void borderselect_ipo(void);
void del_ipo(int need_check);
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index fd6f5f8f0b4..6576dac1d2c 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -110,14 +110,14 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
* correctly *grumble*
*/
mywinset(curarea->win);
- myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
+ myortho2(-0.375, curarea->winx-0.375, G.v2d->cur.ymin, G.v2d->cur.ymax);
sprintf(str, "actionbuttonswin %d", curarea->win);
block= uiNewBlock (&curarea->uiblocks, str,
UI_EMBOSS, UI_HELV, curarea->win);
x = NAMEWIDTH + 1;
- y = key->totkey*(CHANNELHEIGHT+CHANNELSKIP) + CHANNELHEIGHT/2 - G.v2d->cur.ymin;
+ y = CHANNELHEIGHT/2;
/* make the little 'open the sliders' widget */
BIF_ThemeColor(TH_FACE); // this slot was open...
@@ -534,7 +534,7 @@ static void draw_action_mesh_names(Key *key)
KeyBlock *kb;
x = 0.0;
- y= key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+ y= 0.0;
kb= key->block.first;
@@ -846,7 +846,7 @@ static void draw_mesh_strips(SpaceAction *saction, Key *key)
scr_rct.ymax= saction->area->winrct.ymin + saction->v2d.mask.ymax;
di= glaBegin2DDraw(&scr_rct, &G.v2d->cur);
- ybase = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+ ybase = 0;
for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
int frame1_x, channel_y;
@@ -959,7 +959,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
if (G.v2d->cur.ymin < -CHANNELHEIGHT)
G.v2d->cur.ymin = -CHANNELHEIGHT;
- maxymin = key->totkey*(CHANNELHEIGHT+CHANNELSKIP);
+ maxymin = -(key->totkey*(CHANNELHEIGHT+CHANNELSKIP));
if (G.v2d->cur.ymin > maxymin) G.v2d->cur.ymin = maxymin;
}
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 1b0429abda2..2fc0390b7f3 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -25,7 +25,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s): 2007, Joshua Leung (major rewrite of Action Editor)
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -84,6 +84,7 @@
#include "BSE_edit.h"
#include "BSE_drawipo.h"
#include "BSE_headerbuttons.h"
+#include "BSE_editaction_types.h"
#include "BSE_editipo.h"
#include "BSE_time.h"
#include "BSE_trans_types.h"
@@ -95,65 +96,61 @@
#include "blendef.h"
#include "nla.h"
-/* Local Function prototypes, are forward needed */
-static void hilight_channel (bAction *act, bActionChannel *achan, short select);
+/* **************************************************** */
+/* ACTION API */
-/* messy call... */
-static void select_poseelement_by_name (char *name, int select)
+/* this function adds a new Action block */
+bAction *add_empty_action (char *name)
{
- /* Syncs selection of channels with selection of object elements in posemode */
- Object *ob= OBACT;
- bPoseChannel *pchan;
+ bAction *act;
- if (!ob || ob->type!=OB_ARMATURE)
- return;
+ act= alloc_libblock(&G.main->action, ID_AC, name);
+ act->id.flag |= LIB_FAKEUSER;
+ act->id.us++;
- if(select==2) {
- for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
- pchan->bone->flag &= ~(BONE_ACTIVE);
- }
+ return act;
+}
+
+/* generic get current action call, for action window context */
+bAction *ob_get_action (Object *ob)
+{
+ bActionStrip *strip;
- pchan= get_pose_channel(ob->pose, name);
- if(pchan) {
- if(select)
- pchan->bone->flag |= (BONE_SELECTED);
- else
- pchan->bone->flag &= ~(BONE_SELECTED);
- if(select==2)
- pchan->bone->flag |= (BONE_ACTIVE);
+ if(ob->action)
+ return ob->action;
+
+ for (strip=ob->nlastrips.first; strip; strip=strip->next) {
+ if (strip->flag & ACTSTRIP_SELECT)
+ return strip->act;
}
+ return NULL;
}
-/* apparently within active object context */
-/* called extern, like on bone selection */
-void select_actionchannel_by_name (bAction *act, char *name, int select)
+/* used by ipo, outliner, buttons to find the active channel */
+bActionChannel *get_hilighted_action_channel (bAction *action)
{
bActionChannel *achan;
- if (!act)
- return;
+ if (!action)
+ return NULL;
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (!strcmp(achan->name, name)) {
- if (select) {
- achan->flag |= ACHAN_SELECTED;
- hilight_channel(act, achan, 1);
- }
- else {
- achan->flag &= ~ACHAN_SELECTED;
- hilight_channel(act, achan, 0);
- }
- return;
+ for (achan= action->chanbase.first; achan; achan= achan->next) {
+ if(VISIBLE_ACHAN(achan)) {
+ if (SEL_ACHAN(achan) && (achan->flag & ACHAN_HILIGHTED))
+ return achan;
}
}
+
+ return NULL;
}
-/* called on changing action ipos or keys */
-void remake_action_ipos(bAction *act)
+/* ----------------------------------------- */
+
+void remake_action_ipos (bAction *act)
{
bActionChannel *achan;
bConstraintChannel *conchan;
- IpoCurve *icu;
+ IpoCurve *icu;
for (achan= act->chanbase.first; achan; achan= achan->next) {
if (achan->ipo) {
@@ -175,7 +172,7 @@ void remake_action_ipos(bAction *act)
synchronize_action_strips();
}
-static void remake_meshaction_ipos(Ipo *ipo)
+static void remake_meshaction_ipos (Ipo *ipo)
{
/* this puts the bezier triples in proper
* order and makes sure the bezier handles
@@ -189,7 +186,7 @@ static void remake_meshaction_ipos(Ipo *ipo)
}
}
-static void meshkey_do_redraw(Key *key)
+static void meshkey_do_redraw (Key *key)
{
if(key->ipo)
remake_meshaction_ipos(key->ipo);
@@ -203,37 +200,351 @@ static void meshkey_do_redraw(Key *key)
}
-void duplicate_meshchannel_keys(Key *key)
+/* **************************************************** */
+/* FILTER->EDIT STRUCTURES */
+/*
+ * This method involves generating a list of edit structures which enable
+ * tools to naively perform the actions they require without all the boiler-plate
+ * associated with loops within loops and checking for cases to ignore.
+ */
+
+/* this function allocates memory for a new bActListElem struct for the
+ * provided action channel-data.
+ */
+bActListElem *make_new_actlistelem (void *data, short datatype, void *owner, short ownertype)
{
- duplicate_ipo_keys(key->ipo);
- transform_meshchannel_keys('g', key);
+ bActListElem *ale= NULL;
+
+ /* only allocate memory if there is data to convert */
+ if (data) {
+ /* allocate and set generic data */
+ ale= MEM_callocN(sizeof(bActListElem), "bActListElem");
+
+ ale->data= data;
+ ale->type= datatype;
+ ale->owner= owner;
+ ale->ownertype= ownertype;
+
+ /* do specifics */
+ switch (datatype) {
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)data;
+
+ ale->flag= achan->flag;
+
+ if (achan->ipo) {
+ ale->key_data= achan->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)data;
+
+ ale->flag= conchan->flag;
+
+ if (conchan->ipo && conchan->ipo->curve.first) {
+ /* we assume that constraint ipo blocks only have 1 curve:
+ * INFLUENCE, so we pretend that a constraint channel is
+ * really just a Ipo-Curve channel instead.
+ */
+ ale->key_data= conchan->ipo->curve.first;
+ ale->datatype= ALE_ICU;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)data;
+
+ ale->flag= icu->flag;
+ ale->key_data= icu;
+ ale->datatype= ALE_ICU;
+ }
+ break;
+
+ case ACTTYPE_FILLIPO:
+ case ACTTYPE_FILLCON:
+ {
+ bActionChannel *achan= (bActionChannel *)data;
+
+ if (datatype == ACTTYPE_FILLIPO)
+ ale->flag= FILTER_IPO_ACHAN(achan);
+ else
+ ale->flag= FILTER_CON_ACHAN(achan);
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ break;
+ case ACTTYPE_IPO:
+ {
+ ale->flag= 0;
+ ale->key_data= data;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ }
+ }
+
+ /* return created datatype */
+ return ale;
}
-
-void duplicate_actionchannel_keys(void)
+
+/* ----------------------------------------- */
+
+static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_mode)
{
- bAction *act;
+ bActListElem *ale;
bActionChannel *achan;
bConstraintChannel *conchan;
+ IpoCurve *icu;
+
+ /* loop over action channels, performing the necessary checks */
+ for (achan= act->chanbase.first; achan; achan= achan->next) {
+ /* only work with this channel and its subchannels if it is visible */
+ if (!(filter_mode & ACTFILTER_VISIBLE) || VISIBLE_ACHAN(achan)) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_ACHAN(achan)) {
+ /* check if this achan should only be included if it is selected */
+ if (!(filter_mode & ACTFILTER_SEL) || SEL_ACHAN(achan)) {
+ /* are we only interested in the ipo-curves? */
+ if ((filter_mode & ACTFILTER_ONLYICU)==0) {
+ ale= make_new_actlistelem(achan, ACTTYPE_ACHAN, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+
+ /* check if expanded - if not, continue on to next action channel */
+ if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ACTFILTER_ONLYICU)==0)
+ continue;
+
+ /* ipo channels */
+ if (achan->ipo) {
+ /* include ipo-expand widget? */
+ if ((filter_mode & ACTFILTER_CHANNELS) && (filter_mode & ACTFILTER_ONLYICU)==0) {
+ ale= make_new_actlistelem(achan, ACTTYPE_FILLIPO, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+
+ /* add ipo-curve channels? */
+ if (FILTER_IPO_ACHAN(achan) || (filter_mode & ACTFILTER_ONLYICU)) {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
+ ale= make_new_actlistelem(icu, ACTTYPE_ICU, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ }
+
+ /* constraint channels */
+ if (achan->constraintChannels.first) {
+ /* include constraint-expand widget? */
+ if ((filter_mode & ACTFILTER_CHANNELS) && (filter_mode & ACTFILTER_ONLYICU)==0) {
+ ale= make_new_actlistelem(achan, ACTTYPE_FILLCON, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+
+ /* add constaint channels? */
+ if (FILTER_CON_ACHAN(achan)) {
+ /* loop through constraint channels, checking and adding them */
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_CONCHAN(conchan)) {
+ /* check if this conchan should only be included if it is selected */
+ if (!(filter_mode & ACTFILTER_SEL) || SEL_CONCHAN(conchan)) {
+ if ((filter_mode & ACTFILTER_ONLYICU)==0) {
+ ale= make_new_actlistelem(conchan, ACTTYPE_CONCHAN, achan, ACTTYPE_ACHAN);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
- act=G.saction->action;
- if (!act)
- return;
-
- /* Find selected items */
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if(EDITABLE_ACHAN(achan)) {
- duplicate_ipo_keys(achan->ipo);
+static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mode)
+{
+ bActListElem *ale;
+ IpoCurve *icu;
+
+ /* loop over ipo curves if present */
+ if (key->ipo) {
+ if (filter_mode & ACTFILTER_IPOKEYS) {
+ ale= make_new_actlistelem(key->ipo, ACTTYPE_IPO, key, ACTTYPE_SHAPEKEY);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ else {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ ale= make_new_actlistelem(icu, ACTTYPE_ICU, key, ACTTYPE_SHAPEKEY);
+ if (ale) BLI_addtail(act_data, ale);
+ }
+ }
+ }
+}
+
+/* This function filters the active data source to leave only the desired
+ * data types. 'Public' api call.
+ * *act_data: is a pointer to a ListBase, to which the filtered action data
+ * will be placed for use.
+ * filter_mode: how should the data be filtered - bitmapping accessed flags
+ */
+void actdata_filter (ListBase *act_data, int filter_mode, void *data, short datatype)
+{
+ /* only filter data if there's somewhere to put it */
+ if (data && act_data) {
+ bActListElem *ale, *next;
+
+ /* firstly filter the data */
+ switch (datatype) {
+ case ACTCONT_ACTION:
+ actdata_filter_action(act_data, data, filter_mode);
+ break;
+ case ACTCONT_SHAPEKEY:
+ actdata_filter_shapekey(act_data, data, filter_mode);
+ break;
+ }
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- duplicate_ipo_keys(conchan->ipo);
- }
+ /* remove any weedy entries */
+ for (ale= act_data->first; ale; ale= next) {
+ next= ale->next;
+
+ if (ale->type == ACTTYPE_NONE)
+ BLI_freelinkN(act_data, ale);
+
+ if (filter_mode & ACTFILTER_IPOKEYS) {
+ if (ale->datatype != ALE_IPO)
+ BLI_freelinkN(act_data, ale);
+ else if (ale->key_data == NULL)
+ BLI_freelinkN(act_data, ale);
}
}
}
+}
+
+/* **************************************************** */
+/* GENERAL ACTION TOOLS */
+
+
+/* gets the key data from the currently selected
+ * mesh/lattice. If a mesh is not selected, or does not have
+ * key data, then we return NULL (currently only
+ * returns key data for RVK type meshes). If there
+ * is an action that is pinned, return null
+ */
+Key *get_action_mesh_key(void)
+{
+ Object *ob;
+ Key *key;
+
+ ob = OBACT;
+ if (!ob) return NULL;
+
+ if (G.saction->pin) return NULL;
+
+ if (ob->type==OB_MESH ) {
+ key = ((Mesh *)ob->data)->key;
+ }
+ else if (ob->type==OB_LATTICE ) {
+ key = ((Lattice *)ob->data)->key;
+ }
+ else return NULL;
- transform_actionchannel_keys ('g', 0);
+ if (key) {
+ if (key->type == KEY_RELATIVE)
+ return key;
+ }
+
+ return NULL;
+}
+
+/* TODO: kill this! */
+int get_nearest_key_num (Key *key, short *mval, float *x)
+{
+ /* returns the key num that cooresponds to the
+ * y value of the mouse click. Does not check
+ * if this is a valid keynum. Also gives the Ipo
+ * x coordinate.
+ */
+ int num;
+ float ybase, y;
+
+ areamouseco_to_ipoco(G.v2d, mval, x, &y);
+ num = (int) ((CHANNELHEIGHT/2 - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+ return (num + 1);
+}
+
+/* this function is used to get a pointer to an action or shapekey
+ * datablock, thus simplying that process.
+ */
+/* this function is intended for use */
+void *get_nearest_act_channel (short mval[], short *ret_type)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ int clickmin, clickmax;
+ float x,y;
+
+ /* 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));
+ clickmax = clickmin;
+
+ if (clickmax < 0) {
+ *ret_type= ACTTYPE_NONE;
+ return NULL;
+ }
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (clickmax < 0)
+ break;
+ if (clickmin <= 0) {
+ /* found match */
+ *ret_type= ale->type;
+ data= ale->data;
+
+ BLI_freelistN(&act_data);
+
+ return data;
+ }
+ --clickmin;
+ --clickmax;
+ }
+
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
+ *ret_type= ACTTYPE_NONE;
+ return NULL;
}
/* helper for get_nearest_[action,mesh]channel_key */
@@ -295,11 +606,17 @@ static IpoCurve *get_nearest_icu_key (IpoCurve *curve, float *selx, short *sel,
return firsticu;
}
-static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_type, bActionChannel **par)
+/* used only by mouse_action. It is used to find the location of the nearest
+ * keyframe to where the mouse clicked,
+ */
+static void *get_nearest_action_key (float *selx, short *sel, short *ret_type, bActionChannel **par)
{
- bAction *act= G.saction->action;
- bActionChannel *achan;
- bConstraintChannel *conchan;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
IpoCurve *icu;
rctf rectf;
float xmin, xmax, x, y;
@@ -312,7 +629,9 @@ static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_
/* action-channel */
*par= NULL;
- if (act == NULL) {
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) {
*ret_type= ACTTYPE_NONE;
return NULL;
}
@@ -327,7 +646,7 @@ static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
/* if action is mapped in NLA, it returns a correction */
- if (G.saction->pin==0 && OBACT) {
+ if (G.saction->pin==0 && OBACT && datatype==ACTCONT_ACTION) {
xmin= get_action_frame(OBACT, rectf.xmin);
xmax= get_action_frame(OBACT, rectf.xmax);
}
@@ -343,799 +662,149 @@ static void *get_nearest_actionchannel_key (float *selx, short *sel, short *ret_
xrange[0]= xmin;
xrange[1]= xmax;
- /* try in action channels */
- for (achan = act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (clickmax < 0)
- break;
- if ((clickmin <= 0) && (achan->ipo)) {
- /* found level - action channel */
- icu= get_nearest_icu_key(achan->ipo->curve.first, selx, sel, xrange);
-
- *ret_type= ACTTYPE_ACHAN;
- return achan;
- }
- --clickmin;
- --clickmax;
- }
- else
- continue;
-
- if (EXPANDED_ACHAN(achan) == 0)
- continue;
-
- /* try in ipo curves */
- if (achan->ipo) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found level - ipo-curves show/hide */
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
- --clickmin;
- --clickmax;
-
- /* now the ipo-curve channels if they are exposed */
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found level - ipo-curve channel */
- icu= get_nearest_icu_key (icu, selx, sel, xrange);
-
- *ret_type= ACTTYPE_ICU;
- *par= achan;
- return icu;
- }
- --clickmin;
- --clickmax;
- }
- }
- }
-
- /* try in constaint channels */
- if (achan->constraintChannels.first) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - constraints show/hide */
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
- --clickmin;
- --clickmax;
-
- /* now the constraint channels if they are exposed */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0)
- break;
- if ((clickmin <= 0) && (conchan->ipo)) {
- /* found match - constraint channel */
- icu= get_nearest_icu_key(conchan->ipo->curve.first, selx, sel, xrange);
-
- *ret_type= ACTTYPE_CONCHAN;
- *par= achan;
- return conchan;
- }
- --clickmin;
- --clickmax;
- }
- }
- }
- }
-
- *ret_type= ACTTYPE_NONE;
- return NULL;
-}
-
-static IpoCurve *get_nearest_meshchannel_key (float *index, short *sel)
-{
- /* This function tries to find the RVK key that is
- * closest to the user's mouse click
- */
- Key *key;
- IpoCurve *icu;
- IpoCurve *firsticu=NULL;
- int foundsel=0;
- float firstvert=-1, foundx=-1;
- int i;
- short mval[2];
- float ymin, ymax, ybase;
- rctf rectf;
-
- *index=0;
-
- key = get_action_mesh_key();
-
- /* lets get the mouse position and process it so
- * we can start testing selections
- */
- getmouseco_areawin (mval);
- mval[0]-=7;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]+=14;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
- ybase += CHANNELHEIGHT/2;
- *sel=0;
-
- /* lets loop through the IpoCurves trying to find the closest bezier */
- if (!key->ipo) return NULL;
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- /* lets not deal with the "speed" Ipo */
- if (!icu->adrcode) continue;
-
- ymax = ybase - (CHANNELHEIGHT+CHANNELSKIP)*(icu->adrcode-1);
- ymin = ymax - (CHANNELHEIGHT+CHANNELSKIP);
-
- /* Does this curve coorespond to the right
- * strip?
- */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
-
- /* loop through the beziers in the curve */
- for (i=0; i<icu->totvert; i++) {
-
- /* Is this bezier in the right area? */
- if (icu->bezt[i].vec[1][0] > rectf.xmin &&
- icu->bezt[i].vec[1][0] <= rectf.xmax ) {
-
- /* if no other curves have been picked ... */
- if (!firsticu){
- /* mark this curve/bezier as the first selected */
- firsticu=icu;
- firstvert=icu->bezt[i].vec[1][0];
-
- /* sel = (is the bezier is already selected) ? 1 : 0; */
- *sel = icu->bezt[i].f2 & 1;
- }
-
- /* if the bezier is selected ... */
- if (icu->bezt[i].f2 & 1){
- /* if we haven't found a selected one yet ... */
- if (!foundsel){
- /* record the found x value */
- foundsel=1;
- foundx = icu->bezt[i].vec[1][0];
- }
- }
-
- /* if the bezier is unselected and not at the x
- * position of a previous found selected bezier ...
- */
- else if (foundsel && icu->bezt[i].vec[1][0] != foundx){
- /* lets return this found curve/bezier */
- *index=icu->bezt[i].vec[1][0];
- *sel = 0;
- return icu;
- }
- }
- }
- }
- }
- /* return what we've found
- */
- *index=firstvert;
- return firsticu;
-}
-
-/* This function makes a list of the selected keyframes
- * in the ipo curves it has been passed
- */
-static void make_sel_cfra_list(Ipo *ipo, ListBase *elems)
-{
- IpoCurve *icu;
- BezTriple *bezt;
- int a;
-
- for(icu= ipo->curve.first; icu; icu= icu->next) {
-
- bezt= icu->bezt;
- if(bezt) {
- a= icu->totvert;
- while(a--) {
- if(bezt->f2 & 1) {
- add_to_cfra_elem(elems, bezt);
- }
- bezt++;
- }
- }
- }
-}
-
-/* This function selects all key frames in the same column(s) as a already selected key(s)
- * this version only works for Shape Keys, Key should be not NULL
- */
-void column_select_shapekeys(Key *key, int mode)
-{
- if(key && key->ipo) {
- IpoCurve *icu;
- ListBase elems= {NULL, NULL};
- CfraElem *ce;
-
- /* build list of columns */
- switch (mode) {
- case 1:
- /* create a list of all selected keys */
- make_sel_cfra_list(key->ipo, &elems);
- break;
- case 2:
- /* create a list of all selected markers */
- make_marker_cfra_list(&elems, 1);
- break;
- }
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- for(ce= elems.first; ce; ce= ce->next) {
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- BezTriple *bezt= icu->bezt;
- if(bezt) {
- int verts = icu->totvert;
- while(verts--) {
- if( ((int)ce->cfra) == ((int)bezt->vec[1][0]) ) {
- bezt->f2 |= 1;
- }
- bezt++;
- }
- }
- }
- }
-
- BLI_freelistN(&elems);
- }
-}
-
-/* This function selects all key frames in the same column(s) as a already selected key(s)
- * this version only works for on Action. *act should be not NULL
- */
-void column_select_actionkeys(bAction *act, int mode)
-{
- IpoCurve *icu;
- BezTriple *bezt;
- ListBase elems= {NULL, NULL};
- CfraElem *ce;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- if (!act)
- return;
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
- /* build list of columns */
- switch (mode) {
- case 1:
- /* create a list of all selected keys */
- for (achan=act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (achan->ipo)
- make_sel_cfra_list(achan->ipo, &elems);
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (conchan->ipo)
- make_sel_cfra_list(conchan->ipo, &elems);
- }
- }
- }
- }
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (clickmax < 0)
break;
- case 2:
- /* create a list of all selected markers */
- make_marker_cfra_list(&elems, 1);
+ if (clickmin <= 0) {
+ /* found match */
+ *ret_type= ale->type;
- /* apply scaled action correction if needed */
- if (G.saction->pin==0 && OBACT) {
- for (ce= elems.first; ce; ce= ce->next)
- ce->cfra= get_action_frame(OBACT, ce->cfra);
- }
- break;
- }
-
- /* loop through all of the keys and select additional keyframes
- * based on the keys found to be selected above
- */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- if(VISIBLE_ACHAN(achan)) {
- if (achan->ipo) {
- for(ce= elems.first; ce; ce= ce->next) {
- for (icu = achan->ipo->curve.first; icu; icu = icu->next){
- bezt= icu->bezt;
- if(bezt) {
- int verts = icu->totvert;
- while(verts--) {
-
- if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) ) {
- bezt->f2 |= 1;
- }
- bezt++;
- }
- }
+ /* find location of keyframe (if applicable) */
+ if (ale->key_data) {
+ switch (ale->datatype) {
+ case ALE_IPO:
+ {
+ Ipo *ipo= (Ipo *)ale->key_data;
+ icu= get_nearest_icu_key(ipo->curve.first, selx, sel, xrange);
+ }
+ break;
+ case ALE_ICU:
+ {
+ icu= (IpoCurve *)ale->key_data;
+ icu= get_nearest_icu_key(icu, selx, sel, xrange);
}
+ break;
}
}
- if (EXPANDED_ACHAN(achan) == 0 || (FILTER_CON_ACHAN(achan)))
- continue;
+ /* figure out what to return */
+ if (datatype == ACTCONT_ACTION)
+ *par= ale->owner; /* assume that this is an action channel */
+ data = ale->data;
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (conchan->ipo) {
- for(ce= elems.first; ce; ce= ce->next) {
- for (icu = conchan->ipo->curve.first; icu; icu = icu->next){
- bezt= icu->bezt;
- if(bezt) {
- int verts = icu->totvert;
- while(verts--) {
-
- if( ((int)ce->cfra) == ((int)bezt->vec[1][0]) ) {
- bezt->f2 |= 1;
- }
- bezt++;
- }
- }
- }
- }
- }
- }
- }
- }
- BLI_freelistN(&elems);
-}
-
-/* apparently within active object context */
-static void mouse_action(int selectmode)
-{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan= NULL;
- IpoCurve *icu= NULL;
- TimeMarker *marker;
- void *act_channel;
- short sel, act_type;
- float selx;
-
- act=G.saction->action;
- if (!act)
- return;
-
- act_channel= get_nearest_actionchannel_key(&selx, &sel, &act_type, &achan);
- marker=find_nearest_marker(1);
-
- if (act_channel) {
- switch (act_type) {
- case ACTTYPE_ICU:
- icu= (IpoCurve *)act_channel;
- break;
- case ACTTYPE_CONCHAN:
- conchan= (bConstraintChannel *)act_channel;
- break;
- default:
- achan= (bActionChannel *)act_channel;
- }
-
- if (selectmode == SELECT_REPLACE) {
- selectmode = SELECT_ADD;
-
- deselect_actionchannel_keys(act, 0, 0);
- deselect_actionchannels(act, 0);
+ BLI_freelistN(&act_data);
- achan->flag |= ACHAN_SELECTED;
- hilight_channel (act, achan, 1);
- select_poseelement_by_name(achan->name, 2); /* 2 is activate */
- }
-
- if (icu)
- select_icu_key(icu, selx, selectmode);
- else if (conchan)
- select_ipo_key(conchan->ipo, selx, selectmode);
- else
- select_ipo_key(achan->ipo, selx, selectmode);
-
- std_rmouse_transform(transform_actionchannel_keys);
-
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWOOPS, 0);
- allqueue(REDRAWBUTSALL, 0);
- }
- else if (marker) {
- /* not channel, so maybe marker */
- if (selectmode == SELECT_REPLACE) {
- deselect_markers(0, 0);
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_INVERT) {
- if (marker->flag & SELECT)
- marker->flag &= ~SELECT;
- else
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_ADD)
- marker->flag |= SELECT;
- else if (selectmode == SELECT_SUBTRACT)
- marker->flag &= ~SELECT;
-
- std_rmouse_transform(transform_markers);
-
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
-}
-
-static void mouse_mesh_action(int selectmode, Key *key)
-{
- /* Handle a right mouse click selection in an
- * action window displaying RVK data
- */
-
- IpoCurve *icu;
- TimeMarker *marker;
- short sel;
- float selx;
- short mval[2];
-
- /* going to assume that the only reason
- * we got here is because it has been
- * determined that we are a mesh with
- * the right properties (i.e., have key
- * data, etc)
- */
-
- marker= find_nearest_marker(1);
-
- /* get the click location, and the cooresponding
- * ipo curve and selection time value
- */
- getmouseco_areawin (mval);
- icu = get_nearest_meshchannel_key(&selx, &sel);
-
- if (icu) {
- if (selectmode == SELECT_REPLACE) {
- /* if we had planned to replace the
- * selection, then we will first deselect
- * all of the keys, and if the clicked on
- * key had been unselected, we will select
- * it, otherwise, we are done.
- */
- deselect_meshchannel_keys(key, 0, 0);
-
- if (sel == 0)
- selectmode = SELECT_ADD;
- else
- /* the key is selected so we should
- * deselect -- but everything is now deselected
- * so we are done.
- */
- return;
- }
-
- /* select the key using the given mode
- * and redraw as mush stuff as needed.
- */
- select_icu_key(icu, selx, selectmode);
-
- BIF_undo_push("Select Action key");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
-
- }
- else if (marker) {
- /* not channel, so maybe marker */
- if (selectmode == SELECT_REPLACE) {
- deselect_markers(0, 0);
- marker->flag |= SELECT;
- }
- else if (selectmode == SELECT_INVERT) {
- if (marker->flag & SELECT)
- marker->flag &= ~SELECT;
- else
- marker->flag |= SELECT;
+ return data;
}
- else if (selectmode == SELECT_ADD)
- marker->flag |= SELECT;
- else if (selectmode == SELECT_SUBTRACT)
- marker->flag &= ~SELECT;
-
- std_rmouse_transform(transform_markers);
-
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ --clickmin;
+ --clickmax;
}
-}
-
-void borderselect_action(void)
-{
- rcti rect;
- rctf rectf;
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- int val, selectmode;
- int (*select_function)(BezTriple *);
- short mval[2];
- float ymin, ymax;
- act=G.saction->action;
-
- if (!act)
- return;
-
- if ( (val = get_border(&rect, 3)) ) {
- if (val == LEFTMOUSE) {
- selectmode = SELECT_ADD;
- select_function = select_bezier_add;
- }
- else {
- selectmode = SELECT_SUBTRACT;
- select_function = select_bezier_subtract;
- }
-
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- /* if action is mapped in NLA, it returns a correction */
- if (G.saction->pin==0 && OBACT) {
- rectf.xmin= get_action_frame(OBACT, rectf.xmin);
- rectf.xmax= get_action_frame(OBACT, rectf.xmax);
- }
-
- ymax = CHANNELHEIGHT/2;
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- /* Check action channel */
- ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
- ymax=ymin;
-
- if (EXPANDED_ACHAN(achan)) {
- /* check ipo - although the action channel has already been checked,
- * selection may have started below that channel
- */
- if (achan->ipo) {
- /* skip the widget*/
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- ymax= ymin;
-
- if (FILTER_IPO_ACHAN(achan)) {
- /* check ipo-curve channels */
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- borderselect_icu_key(icu, rectf.xmin, rectf.xmax, select_function);
-
- ymax=ymin;
- }
- }
- }
-
- /* Check constraints */
- if (achan->constraintChannels.first) {
- /* skip the widget*/
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- ymax= ymin;
-
- /* check constraint channels */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- ymin= ymax-(CHANNELHEIGHT+CHANNELSKIP);
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax)))
- borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
-
- ymax=ymin;
- }
- }
- }
- }
- }
- }
-
- BIF_undo_push("Border Select Action");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- }
-}
-
-void borderselect_mesh(Key *key)
-{
- rcti rect;
- int val, adrcodemax, adrcodemin;
- short mval[2];
- float xmin, xmax;
- int selectmode;
- int (*select_function)(BezTriple *);
- IpoCurve *icu;
+ /* cleanup */
+ BLI_freelistN(&act_data);
- if ( (val = get_border(&rect, 3)) ){
- /* set the selection function based on what
- * mouse button had been used in the border
- * select
- */
- if (val == LEFTMOUSE) {
- selectmode = SELECT_ADD;
- select_function = select_bezier_add;
- }
- else {
- selectmode = SELECT_SUBTRACT;
- select_function = select_bezier_subtract;
- }
-
- /* get the minimum and maximum adrcode numbers
- * for the IpoCurves (this is the number that
- * relates an IpoCurve to the keyblock it
- * controls).
- */
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- adrcodemax = get_nearest_key_num(key, mval, &xmin);
- adrcodemax = (adrcodemax >= key->totkey) ? key->totkey : adrcodemax;
-
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- adrcodemin = get_nearest_key_num(key, mval, &xmax);
- adrcodemin = (adrcodemin < 1) ? 1 : adrcodemin;
-
- /* Lets loop throug the IpoCurves and do borderselect
- * on the curves with adrcodes in our selected range.
- */
- if(key->ipo) {
- for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
- /* lets not deal with the "speed" Ipo
- */
- if (!icu->adrcode) continue;
- if ( (icu->adrcode >= adrcodemin) &&
- (icu->adrcode <= adrcodemax) ) {
- borderselect_icu_key(icu, xmin, xmax, select_function);
- }
- }
- }
-
- /* redraw stuff */
- BIF_undo_push("Border select Action Key");
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- }
+ *ret_type= ACTTYPE_NONE;
+ return NULL;
}
-/* ******************** action API ***************** */
-
-/* generic get current action call, for action window context */
-bAction *ob_get_action(Object *ob)
+void *get_action_context (short *datatype)
{
- bActionStrip *strip;
+ bAction *act;
+ Key *key;
- if(ob->action)
- return ob->action;
+ /* get pointers to active action/shapekey blocks */
+ act = (G.saction)? G.saction->action: NULL;
+ key = get_action_mesh_key();
- for (strip=ob->nlastrips.first; strip; strip=strip->next){
- if (strip->flag & ACTSTRIP_SELECT)
- return strip->act;
+ if (act) {
+ *datatype= ACTCONT_ACTION;
+ return act;
}
- return NULL;
-}
-
-/* used by ipo, outliner, buttons to find the active channel */
-bActionChannel *get_hilighted_action_channel(bAction *action)
-{
- bActionChannel *achan;
-
- if (!action)
+ else if (key) {
+ *datatype= ACTCONT_SHAPEKEY;
+ return key;
+ }
+ else {
+ *datatype= ACTCONT_NONE;
return NULL;
-
- for (achan= action->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && achan->flag & ACHAN_HILIGHTED)
- return achan;
- }
}
-
- return NULL;
-
}
-bAction *add_empty_action(char *name)
-{
- bAction *act;
- /*
- if(blocktype==ID_OB)
- str= "ObAction";
- else if(blocktype==ID_KE)
- str= "ShapeAction";
- */
- act= alloc_libblock(&G.main->action, ID_AC, name);
- act->id.flag |= LIB_FAKEUSER;
- act->id.us++;
- return act;
-}
+/* **************************************************** */
+/* TRANSFORM TOOLS */
-void transform_actionchannel_keys(int mode, int dummy)
+/* initialise the transform data - create transverts */
+static TransVert *transform_action_init (int *tvtot, float *minx, float *maxx)
{
- bAction *act;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
TransVert *tv;
- Object *ob= OBACT;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- float deltax, startx;
- float minx, maxx, cenf[2];
- float sval[2], cval[2], lastcval[2]={0,0};
- float fac=0.0f;
- int loop=1;
- int tvtot=0;
- int invert=0, firsttime=1;
- int i;
- short cancel=0;
- short mvals[2], mvalc[2], cent[2];
- char str[256];
-
- act=G.saction->action;
- if(act==NULL) return;
-
- /* Ensure that partial selections result in beztriple selections */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- if (EDITABLE_ACHAN(achan)) {
- tvtot+=fullselect_ipo_keys(achan->ipo);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- tvtot+=fullselect_ipo_keys(conchan->ipo);
- }
- }
- }
- }
+ void *data;
+ short datatype;
+ int filter;
+ int count= 0;
+ float min= 0, max= 0;
+ int i;
- /* If nothing is selected, bail out */
- if (!tvtot)
- return;
+ /* initialise the values being passed by reference */
+ *tvtot = *minx = *maxx = 0;
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return NULL;
- /* Build the transvert structure */
- tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
- tvtot=0;
- for (achan=act->chanbase.first; achan; achan= achan->next){
- if(EDITABLE_ACHAN(achan)) {
- tvtot = add_trans_ipo_keys(achan->ipo, tv, tvtot);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- tvtot = add_trans_ipo_keys(conchan->ipo, tv, tvtot);
- }
- }
- }
- }
+ /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
+ for (ale= act_data.first; ale; ale= ale->next)
+ count += fullselect_ipo_keys(ale->key_data);
+
+ /* stop if trying to build list if nothing selected */
+ if (count == 0) return NULL;
+
+ /* Build the transvert structure */
+ tv = MEM_callocN (sizeof(TransVert) * count, "transVert");
+ /* loop 2: build transvert structure */
+ for (ale= act_data.first; ale; ale= ale->next)
+ *tvtot = add_trans_ipo_keys(ale->key_data, tv, *tvtot);
+
/* min max, only every other three */
- minx= maxx= tv[1].loc[0];
- for (i=1; i<tvtot; i+=3){
- if(minx>tv[i].loc[0]) minx= tv[i].loc[0];
- if(maxx<tv[i].loc[0]) maxx= tv[i].loc[0];
+ min= max= tv[1].loc[0];
+ for (i=1; i<count; i+=3){
+ if(min>tv[i].loc[0]) min= tv[i].loc[0];
+ if(max<tv[i].loc[0]) max= tv[i].loc[0];
}
+ *minx= min;
+ *maxx= max;
+
+ /* cleanup temp list */
+ BLI_freelistN(&act_data);
+
+ /* return created transverts */
+ return tv;
+}
+
+/* main transform loop for action editor */
+static short transform_action_loop (TransVert *tv, int tvtot, char mode, short context, float minx, float maxx)
+{
+ Object *ob= OBACT;
+ float deltax, startx;
+ float cenf[2];
+ float sval[2], cval[2], lastcval[2]={0,0};
+ float fac=0.0f;
+ int loop=1, invert=0;
+ int i;
+ short cancel=0, firsttime=1;
+ short mvals[2], mvalc[2], cent[2];
+ char str[256];
/* Do the event loop */
cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
@@ -1156,7 +825,6 @@ void transform_actionchannel_keys(int mode, int dummy)
startx=sval[0];
while (loop) {
-
if(mode=='t' && minx==maxx)
break;
@@ -1251,7 +919,7 @@ void transform_actionchannel_keys(int mode, int dummy)
}
break;
case 'g':
- if (G.saction->pin==0 && OBACT) {
+ if (G.saction->pin==0 && OBACT && context==ACTCONT_ACTION) {
deltax = get_action_frame_inv(OBACT, cval[0]);
deltax -= get_action_frame_inv(OBACT, sval[0]);
@@ -1292,7 +960,7 @@ void transform_actionchannel_keys(int mode, int dummy)
fac*=-1;
}
startx= (G.scene->r.cfra);
- if(G.saction->pin==0 && OBACT)
+ if(G.saction->pin==0 && OBACT && context==ACTCONT_ACTION)
startx= get_action_frame(OBACT, startx);
tv[i].loc[0]-= startx;
@@ -1307,7 +975,7 @@ void transform_actionchannel_keys(int mode, int dummy)
float snapval;
/* convert frame to nla-action time (if needed) */
- if (G.saction->pin==0 && OBACT)
+ if (G.saction->pin==0 && OBACT && context==ACTCONT_ACTION)
snapval= get_action_frame_inv(OBACT, tv[i].loc[0]);
else
snapval= tv[i].loc[0];
@@ -1316,7 +984,7 @@ void transform_actionchannel_keys(int mode, int dummy)
snapval= (float)(floor(snapval+0.5));
/* convert frame out of nla-action time */
- if (G.saction->pin==0 && OBACT)
+ if (G.saction->pin==0 && OBACT && context==ACTCONT_ACTION)
tv[i].loc[0]= get_action_frame(OBACT, snapval);
else
tv[i].loc[0]= snapval;
@@ -1328,7 +996,7 @@ void transform_actionchannel_keys(int mode, int dummy)
headerprint(str);
}
else if (mode=='g') {
- if(G.saction->pin==0 && OBACT) {
+ if(G.saction->pin==0 && OBACT && context==ACTCONT_ACTION) {
/* recalculate the delta based on 'visual' times */
fac = get_action_frame_inv(OBACT, cval[0]);
fac -= get_action_frame_inv(OBACT, sval[0]);
@@ -1347,14 +1015,25 @@ void transform_actionchannel_keys(int mode, int dummy)
}
if (G.saction->lock) {
- if(ob) {
- ob->ctime= -1234567.0f;
- if(ob->pose || ob_get_key(ob))
- DAG_object_flush_update(G.scene, ob, OB_RECALC);
- else
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ if (context == ACTCONT_ACTION) {
+ if(ob) {
+ ob->ctime= -1234567.0f;
+ if(ob->pose || ob_get_key(ob))
+ DAG_object_flush_update(G.scene, ob, OB_RECALC);
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+ force_draw_plus(SPACE_VIEW3D, 0);
+ }
+ else if (context == ACTCONT_SHAPEKEY) {
+ DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWTIME, 0);
+ force_draw_all(0);
}
- force_draw_plus(SPACE_VIEW3D, 0);
}
else {
force_draw(0);
@@ -1367,392 +1046,712 @@ void transform_actionchannel_keys(int mode, int dummy)
firsttime= 0;
}
- /* Update the curve */
- /* Depending on the lock status, draw necessary views */
+ return cancel;
+}
- if(ob) {
- ob->ctime= -1234567.0f;
+/* main call to start transforming keyframes */
+/* NOTE: someday, this should be integrated with the transform system
+ * instead of relying on our own methods
+ */
+void transform_action_keys (int mode, int dummy)
+{
+ Object *ob= OBACT;
+ TransVert *tv;
+ int tvtot= 0;
+ short cancel;
+ float minx, maxx;
+
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* initialise transform */
+ tv= transform_action_init(&tvtot, &minx, &maxx);
+ if (tv == NULL) return;
+
+ /* do transform loop */
+ cancel= transform_action_loop(tv, tvtot, mode, datatype, minx, maxx);
+
+ /* cleanup */
+ if (datatype == ACTCONT_ACTION) {
+ /* Update the curve */
+ /* Depending on the lock status, draw necessary views */
+ if(ob) {
+ ob->ctime= -1234567.0f;
- if(ob->pose || ob_get_key(ob))
- DAG_object_flush_update(G.scene, ob, OB_RECALC);
- else
- DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ if(ob->pose || ob_get_key(ob))
+ DAG_object_flush_update(G.scene, ob, OB_RECALC);
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+
+ remake_action_ipos((bAction *)data);
+
+ G.saction->flag &= ~SACTION_MOVING;
+
+ if (cancel==0) BIF_undo_push("Transform Action"); // does it have to be here?
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWTIME, 0);
+ }
+ else if (datatype == ACTCONT_SHAPEKEY) {
+ /* fix up the Ipocurves and redraw stuff */
+ meshkey_do_redraw((Key *)data);
+ if (cancel==0) BIF_undo_push("Transform Action");
}
- remake_action_ipos(act);
+ MEM_freeN(tv);
+}
+
+/* ----------------------------------------- */
- G.saction->flag &= ~SACTION_MOVING;
+/* duplicate keyframes */
+void duplicate_action_keys (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
- if(cancel==0) BIF_undo_push("Transform Action");
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- allqueue(REDRAWTIME, 0);
- MEM_freeN (tv);
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and duplicate selected keys */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ duplicate_ipo_keys((Ipo *)ale->key_data);
+ }
+
+ /* free filtered list */
+ BLI_freelistN(&act_data);
+
+ /* now, go into transform-grab mode, to move keys */
+ transform_action_keys('g', 0);
}
-void transform_meshchannel_keys(char mode, Key *key)
+/* this function is responsible for snapping keyframes to frame-times */
+void snap_action_keys(short mode)
{
- /* this is the function that determines what happens
- * to those little blocky rvk key things you have selected
- * after you press a 'g' or an 's'. I'd love to say that
- * I have an intimate knowledge of all of what this function
- * is doing, but instead I'm just going to pretend.
- */
- TransVert *tv;
- int /*sel=0,*/ i;
- short mvals[2], mvalc[2], cent[2];
- float sval[2], cval[2], lastcval[2]={0,0};
- short cancel=0;
- float fac=0.0F;
- int loop=1;
- int tvtot=0;
- float deltax, startx;
- float cenf[2];
- int invert=0, firsttime=1;
- char str[256];
-
- /* count all of the selected beziers, and
- * set all 3 control handles to selected
- */
- tvtot=fullselect_ipo_keys(key->ipo);
-
- /* If nothing is selected, bail out */
- if (!tvtot)
- return;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ char str[32];
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* determine mode */
+ switch (mode) {
+ case 1:
+ strcpy(str, "Snap Keys To Nearest Frame");
+ break;
+ case 2:
+ strcpy(str, "Snap Keys To Current Frame");
+ break;
+ case 3:
+ strcpy(str, "Snap Keys To Nearest Marker");
+ break;
+ default:
+ return;
+ }
+
+ /* snap to frame */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ snap_ipo_keys(ale->key_data, mode);
+ }
+ BLI_freelistN(&act_data);
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
- /* Build the transvert structure */
- tv = MEM_callocN (sizeof(TransVert) * tvtot, "transVert");
- tvtot=0;
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- tvtot = add_trans_ipo_keys(key->ipo, tv, tvtot);
+/* this function is responsible for snapping keyframes to frame-times */
+void mirror_action_keys(short mode)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ char str[32];
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
- /* Do the event loop */
- cent[0] = curarea->winx + (G.saction->v2d.hor.xmax)/2;
- cent[1] = curarea->winy + (G.saction->v2d.hor.ymax)/2;
- areamouseco_to_ipoco(G.v2d, cent, &cenf[0], &cenf[1]);
+ /* determine mode */
+ switch (mode) {
+ case 1:
+ strcpy(str, "Mirror Keys Over Current Frame");
+ break;
+ case 2:
+ strcpy(str, "Mirror Keys Over Y-Axis");
+ break;
+ case 3:
+ strcpy(str, "Mirror Keys Over X-Axis");
+ break;
+ case 4:
+ strcpy(str, "Mirror Keys Over Marker");
+ break;
+ default:
+ return;
+ }
+
+ /* mirror */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ mirror_ipo_keys(ale->key_data, mode);
+ }
+ BLI_freelistN(&act_data);
+
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- getmouseco_areawin (mvals);
- areamouseco_to_ipoco(G.v2d, mvals, &sval[0], &sval[1]);
+/* **************************************************** */
+/* ADD/REMOVE KEYFRAMES */
- startx=sval[0];
- while (loop) {
- /* Get the input
- * If we're cancelling, reset transformations
- * Else calc new transformation
- * Perform the transformations
- */
- while (qtest()) {
- short val;
- unsigned short event= extern_qread(&val);
-
- if (val) {
- switch (event) {
- case LEFTMOUSE:
- case SPACEKEY:
- case RETKEY:
- loop=0;
- break;
- case XKEY:
- break;
- case ESCKEY:
- case RIGHTMOUSE:
- cancel=1;
- loop=0;
- break;
- default:
- arrows_move_cursor(event);
- break;
- };
- }
- }
-
- if (cancel) {
- for (i=0; i<tvtot; i++) {
- tv[i].loc[0]=tv[i].oldloc[0];
- tv[i].loc[1]=tv[i].oldloc[1];
- }
- }
- else {
- getmouseco_areawin (mvalc);
- areamouseco_to_ipoco(G.v2d, mvalc, &cval[0], &cval[1]);
-
- if (!firsttime && lastcval[0]==cval[0] && lastcval[1]==cval[1]) {
- PIL_sleep_ms(1);
- }
- else {
- short autosnap= 0;
+/* This function allows the user to insert keyframes on the current
+ * frame from the Action Editor, using the current values of the channels
+ * to be keyframed.
+ */
+void insertkey_action(void)
+{
+ void *data;
+ short datatype;
+
+ Object *ob= OBACT;
+ short mode;
+ float cfra;
+
+ /* get data */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+ cfra = frame_to_float(CFRA);
+
+ if (datatype == ACTCONT_ACTION) {
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+
+ /* ask user what to keyframe */
+ mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2");
+ if (mode == 0) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU );
+ if (mode == 2) filter |= ACTFILTER_SEL;
+
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through ipo curves retrieved */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ /* verify that this is indeed an ipo curve */
+ if (ale->key_data && ale->owner) {
+ bActionChannel *achan= (bActionChannel *)ale->owner;
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
- /* determine mode of keyframe snapping/autosnap */
- if (mode != 't') {
- switch (G.saction->autosnap) {
- case SACTSNAP_OFF:
- if (G.qual == LR_CTRLKEY)
- autosnap= SACTSNAP_STEP;
- else if (G.qual == LR_SHIFTKEY)
- autosnap= SACTSNAP_FRAME;
- else
- autosnap= SACTSNAP_OFF;
- break;
- case SACTSNAP_STEP:
- autosnap= (G.qual==LR_CTRLKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
- break;
- case SACTSNAP_FRAME:
- autosnap= (G.qual==LR_SHIFTKEY)? SACTSNAP_OFF: SACTSNAP_FRAME;
- break;
- }
- }
-
- for (i=0; i<tvtot; i++) {
- tv[i].loc[0]=tv[i].oldloc[0];
-
- switch (mode){
- case 'g':
- deltax = cval[0]-sval[0];
- fac= deltax;
-
- if (autosnap == SACTSNAP_STEP) {
- /* NOTE: this doesn't take into account NLA scaling */
- fac= 1.0f*floor(fac/1.0f + 0.5f);
- }
-
- tv[i].loc[0]+=fac;
- break;
- case 's':
- startx=mvals[0]-(ACTWIDTH/2+(curarea->winrct.xmax
- -curarea->winrct.xmin)/2);
- deltax=mvalc[0]-(ACTWIDTH/2+(curarea->winrct.xmax
- -curarea->winrct.xmin)/2);
- fac= fabs(deltax/startx);
-
- if (autosnap == SACTSNAP_FRAME) {
- /* NOTE: this doesn't take into account NLA scaling */
- fac= 1.0f*floor(fac/1.0f + 0.5f);
- }
+ if (ob)
+ insertkey((ID *)ob, icu->blocktype, achan->name, NULL, icu->adrcode);
+ else
+ insert_vert_ipo(icu, cfra, icu->curval);
+ }
+ }
- if (invert){
- if (i % 03 == 0){
- memcpy (tv[i].loc, tv[i].oldloc,
- sizeof(tv[i+2].oldloc));
- }
- if (i % 03 == 2){
- memcpy (tv[i].loc, tv[i].oldloc,
- sizeof(tv[i-2].oldloc));
- }
-
- fac*=-1;
- }
- startx= (G.scene->r.cfra);
-
- tv[i].loc[0]-= startx;
- tv[i].loc[0]*=fac;
- tv[i].loc[0]+= startx;
+ /* cleanup */
+ BLI_freelistN(&act_data);
+ }
+ else if (datatype == ACTCONT_SHAPEKEY) {
+ Key *key= (Key *)data;
+ IpoCurve *icu;
- break;
- }
-
- /* auto-snap key to nearest frame? */
- if (autosnap == SACTSNAP_FRAME) {
- tv[i].loc[0]= (float)(floor(tv[i].loc[0]+0.5));
- }
- }
- }
- /* Display a message showing the magnitude of
- * the grab/scale we are performing
- */
- if (mode=='s') {
- sprintf(str, "scaleX: %.3f", fac);
- headerprint(str);
- }
- else if (mode=='g') {
- sprintf(str, "deltaX: %.3f", fac);
- headerprint(str);
- }
-
- if (G.saction->lock) {
- /* doubt any of this code ever gets
- * executed, but it might in the
- * future
- */
-
- DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWTIME, 0);
- force_draw_all(0);
- }
- else {
- addqueue (curarea->win, REDRAWALL, 0);
- force_draw(0);
- }
- }
+ /* ask user if they want to insert a keyframe */
+ mode = okee("Insert Keyframe?");
+ if (mode == 0) return;
- lastcval[0]= cval[0];
- lastcval[1]= cval[1];
- firsttime= 0;
- }
+ if (key->ipo) {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ insert_vert_ipo(icu, cfra, icu->curval);
+ }
+ }
+ }
- /* fix up the Ipocurves and redraw stuff */
- meshkey_do_redraw(key);
- BIF_undo_push("Transform Action Keys");
-
- MEM_freeN (tv);
-
- /* did you understand all of that? I pretty much understand
- * what it does, but the specifics seem a little weird and crufty.
- */
+ BIF_undo_push("Insert Key");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-void deselect_actionchannel_keys (bAction *act, int test, int sel)
+/* delete selected keyframes */
+void delete_action_keys (void)
{
- bActionChannel *achan;
- bConstraintChannel *conchan;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and delete selected keys */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ delete_ipo_keys((Ipo *)ale->key_data);
+ }
+
+ /* free filtered list */
+ BLI_freelistN(&act_data);
+
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push("Delete Action Keys");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- if (!act)
- return;
+/* delete selected keyframes */
+void delete_action_channels (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale, *next;
+ bAction *act;
+ void *data;
+ short datatype;
+ int filter;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+ if (datatype != ACTCONT_ACTION) return;
+ act= (bAction *)data;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_CHANNELS | ACTFILTER_SEL);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* remove irrelevant entries */
+ for (ale= act_data.first; ale; ale= next) {
+ next= ale->next;
+
+ if (ale->type != ACTTYPE_ACHAN)
+ BLI_freelinkN(&act_data, ale);
+ }
+
+ /* clean up action channels */
+ for (ale= act_data.first; ale; ale= next) {
+ bActionChannel *achan= (bActionChannel *)ale->data;
+ bConstraintChannel *conchan, *cnext;
+ next= ale->next;
+
+ /* release reference to ipo users */
+ if (achan->ipo)
+ achan->ipo->id.us--;
+
+ for (conchan= achan->constraintChannels.first; conchan; conchan=cnext) {
+ cnext= conchan->next;
+
+ if (conchan->ipo)
+ conchan->ipo->id.us--;
+ }
+
+ /* free memory */
+ BLI_freelistN(&achan->constraintChannels);
+ BLI_freelinkN(&act->chanbase, achan);
+ BLI_freelinkN(&act_data, ale);
+ }
+
+ remake_action_ipos(data);
+
+ BIF_undo_push("Delete Action Channels");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
- /* Determine if this is selection or deselection */
- if (test) {
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- /* Test the channel ipos */
- if (is_ipo_key_selected(achan->ipo)) {
- sel = 0;
- break;
- }
+/* 'Clean' IPO curves - remove any unnecessary keyframes */
+void clean_action (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype, ok;
+
+ /* don't proceed any further if nothing to work on or user refuses */
+ data= get_action_context(&datatype);
+ ok= fbutton(&G.scene->toolsettings->clean_thresh,
+ 0.0000001f, 1.0, 0.001, 0.1,
+ "Clean Threshold");
+ if (!ok) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_SEL | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and clean curves */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ clean_ipo_curve((IpoCurve *)ale->key_data);
+ }
+
+ /* admin and redraws */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Clean Action");
+ allqueue(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+}
- if ((EXPANDED_ACHAN(achan) == 0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* Test the constraint ipos */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
- if (is_ipo_key_selected(conchan->ipo)) {
- sel = 0;
- break;
- }
- }
+/* **************************************************** */
+/* VARIOUS SETTINGS */
- if (sel == 0)
- break;
- }
+/* this function combines several features related to setting
+ * various ipo extrapolation/interpolation
+ */
+void action_set_ipo_flags (int mode)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter, event;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* determine which set of processing we are doing */
+ switch (mode) {
+ case SET_EXTEND_POPUP:
+ {
+ /* present popup menu for ipo extrapolation type */
+ event
+ = pupmenu("Channel Extending Type %t|"
+ "Constant %x11|"
+ "Extrapolation %x12|"
+ "Cyclic %x13|"
+ "Cyclic extrapolation %x14");
+ if(event < 1) return;
}
+ break;
+ case SET_IPO_POPUP:
+ {
+ /* present popup menu for ipo interpolation type */
+ event
+ = pupmenu("Channel Ipo Type %t|"
+ "Constant %x1|"
+ "Linear %x2|"
+ "Bezier %x3");
+ if(event < 1) return;
+ }
+ break;
+
+ default: /* weird, unhandled case */
+ return;
}
- /* Set the flags */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- set_ipo_key_selection(achan->ipo, sel);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
- set_ipo_key_selection(conchan->ipo, sel);
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through setting flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ Ipo *ipo= (Ipo *)ale->key_data;
+
+ /* depending on the mode */
+ switch (mode) {
+ case SET_EXTEND_POPUP: /* extrapolation */
+ {
+ switch (event) {
+ case SET_EXTEND_CONSTANT:
+ setexprap_ipoloop(ipo, IPO_HORIZ);
+ break;
+ case SET_EXTEND_EXTRAPOLATION:
+ setexprap_ipoloop(ipo, IPO_DIR);
+ break;
+ case SET_EXTEND_CYCLIC:
+ setexprap_ipoloop(ipo, IPO_CYCL);
+ break;
+ case SET_EXTEND_CYCLICEXTRAPOLATION:
+ setexprap_ipoloop(ipo, IPO_CYCLX);
+ break;
+ }
+ }
+ break;
+ case SET_IPO_POPUP: /* interpolation */
+ {
+ setipotype_ipo(ipo, event);
}
+ break;
}
}
+
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push("Set Ipo Type");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-void deselect_meshchannel_keys (Key *key, int test, int sel)
+/* this function sets the handles on keyframes
+ */
+void sethandles_action_keys (int code)
{
- /* should deselect the rvk keys */
-
- /* Determine if this is selection or deselection */
- if (test) {
- if (is_ipo_key_selected(key->ipo)) {
- sel = 0;
- }
- }
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ void *data;
+ short datatype;
+ int filter;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through setting flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ sethandles_ipo_keys((Ipo *)ale->key_data, code);
+ }
- /* Set the flags */
- set_ipo_key_selection(key->ipo, sel);
+ /* cleanup */
+ BLI_freelistN(&act_data);
+ if (datatype == ACTCONT_ACTION)
+ remake_action_ipos(data);
+
+ BIF_undo_push("Set Handle Type");
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
}
-/* apparently within active object context */
-void deselect_actionchannels (bAction *act, int test)
+/* ----------------------------------------- */
+
+static void clever_keyblock_names (Key *key, short *mval)
{
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- int sel= 1;
+ KeyBlock *kb;
+ int but=0, i, keynum;
+ char str[64];
+ float x;
+
+ /* get the keynum cooresponding to the y value
+ * of the mouse pointer, return if this is
+ * an invalid key number (and we don't deal
+ * with the speed ipo).
+ */
- if (!act)
- return;
+ keynum = get_nearest_key_num(key, mval, &x);
+ if ( (keynum < 1) || (keynum >= key->totkey) )
+ return;
- /* See if we should be selecting or deselecting */
- if (test) {
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (!sel)
- break;
-
- if (achan->flag & ACHAN_SELECTED) {
- sel= 0;
- break;
- }
- if (sel) {
- if (EXPANDED_ACHAN(achan)) {
- if (FILTER_IPO_ACHAN(achan) && (achan->ipo)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- if (SEL_ICU(icu)) {
- sel= 0;
- break;
- }
- }
+ kb= key->block.first;
+ for (i=0; i<keynum; ++i) kb = kb->next;
- }
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (SEL_CONCHAN(conchan)) {
- sel= 0;
- break;
- }
- }
- }
- }
- }
- }
- }
+ if (kb->name[0] == '\0') {
+ sprintf(str, "Key %d", keynum);
+ }
+ else {
+ strcpy(str, kb->name);
}
- else
- sel= 0;
-
- /* Now set the flags */
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- select_poseelement_by_name(achan->name, sel);
- if (sel)
- achan->flag |= ACHAN_SELECTED;
- else
- achan->flag &= ~ACHAN_SELECTED;
+ if ( (kb->slidermin >= kb->slidermax) ) {
+ kb->slidermin = 0.0;
+ kb->slidermax = 1.0;
+ }
- if (EXPANDED_ACHAN(achan)) {
- if (FILTER_IPO_ACHAN(achan) && (achan->ipo)) {
- for (icu=achan->ipo->curve.first; icu; icu=icu->next) {
- if (sel)
- icu->flag |= IPO_SELECT;
- else
- icu->flag &= ~IPO_SELECT;
- }
- }
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (sel)
- conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
- else
- conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
- }
- }
+ add_numbut(but++, TEX, "KB: ", 0, 24, str,
+ "Does this really need a tool tip?");
+ add_numbut(but++, NUM|FLO, "Slider Min:",
+ -10000, kb->slidermax, &kb->slidermin, 0);
+ add_numbut(but++, NUM|FLO, "Slider Max:",
+ kb->slidermin, 10000, &kb->slidermax, 0);
+
+ if (do_clever_numbuts(str, but, REDRAW)) {
+ strcpy(kb->name, str);
+ allqueue (REDRAWACTION, 0);
+ allspace(REMAKEIPO, 0);
+ allqueue (REDRAWIPO, 0);
+ }
+}
+
+static void clever_achannel_names (short *mval)
+{
+ void *act_channel;
+ bActionChannel *achan= NULL;
+ bConstraintChannel *conchan= NULL;
+ IpoCurve *icu= NULL;
+
+ int but=0;
+ char str[64];
+ short expand, protect, chantype;
+ float slidermin, slidermax;
+
+ /* figure out what is under cursor */
+ act_channel= get_nearest_act_channel(mval, &chantype);
+
+ /* create items for clever-numbut */
+ if (chantype == ACTTYPE_ACHAN) {
+ achan= (bActionChannel *)act_channel;
+
+ strcpy(str, achan->name);
+ protect= (achan->flag & ACHAN_PROTECTED);
+ expand = (achan->flag & ACHAN_EXPANDED);
+
+ add_numbut(but++, TEX, "ActChan: ", 0, 31, str, "Name of Action Channel");
+ add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
+ add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+ }
+ else if (chantype == ACTTYPE_CONCHAN) {
+ conchan= (bConstraintChannel *)act_channel;
+
+ strcpy(str, conchan->name);
+ protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
+
+ add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
+ add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+ }
+ else if (chantype == ACTTYPE_ICU) {
+ icu= (IpoCurve *)act_channel;
+
+ strcpy(str, getname_ipocurve(icu));
+
+ if (IS_EQ(icu->slide_max, icu->slide_min)) {
+ if (IS_EQ(icu->ymax, icu->ymin)) {
+ icu->slide_min= -100.0;
+ icu->slide_max= 100.0;
+ }
+ else {
+ icu->slide_min= icu->ymin;
+ icu->slide_max= icu->ymax;
}
}
+ slidermin= icu->slide_min;
+ slidermax= icu->slide_max;
+
+ //protect= (icu->flag & IPO_PROTECT);
+
+ add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
+ add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
+ //add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
+ }
+ else {
+ /* nothing under-cursor */
+ return;
+ }
+
+ /* draw clever-numbut */
+ if (do_clever_numbuts(str, but, REDRAW)) {
+ /* restore settings based on type */
+ if (icu) {
+ icu->slide_min= slidermin;
+ icu->slide_max= slidermax;
+
+ //if (protect) icu->flag |= IPO_PROTECT;
+ //else icu->flag &= ~IPO_PROTECT;
+ }
+ else if (conchan) {
+ strcpy(conchan->name, str);
+
+ if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
+ else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
+ }
+ else if (achan) {
+ strcpy(achan->name, str);
+
+ if (expand) achan->flag |= ACHAN_EXPANDED;
+ else achan->flag &= ~ACHAN_EXPANDED;
+
+ if (protect) achan->flag |= ACHAN_PROTECTED;
+ else achan->flag &= ~ACHAN_PROTECTED;
+ }
+
+ allqueue (REDRAWACTION, 0);
+ allqueue (REDRAWVIEW3D, 0);
}
+}
+/* this gets called when nkey is pressed (no Transform Properties panel yet) */
+static void numbuts_action (void)
+{
+ /* now called from action window event loop, plus reacts on mouseclick */
+ /* removed Hos grunts for that reason! :) (ton) */
+ void *data;
+ short datatype;
+ short mval[2];
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ getmouseco_areawin(mval);
+
+ if (mval[0] < NAMEWIDTH) {
+ switch (datatype) {
+ case ACTCONT_ACTION:
+ clever_achannel_names(mval);
+ break;
+ case ACTCONT_SHAPEKEY:
+ clever_keyblock_names(data, mval);
+ break;
+ }
+ }
}
-static void hilight_channel (bAction *act, bActionChannel *achan, short select)
+
+/* **************************************************** */
+/* CHANNEL SELECTION */
+
+static void hilight_channel(bAction *act, bActionChannel *achan, short select)
{
bActionChannel *curchan;
@@ -1767,6 +1766,56 @@ static void hilight_channel (bAction *act, bActionChannel *achan, short select)
}
}
+/* messy call... */
+static void select_poseelement_by_name(char *name, int select)
+{
+ /* Syncs selection of channels with selection of object elements in posemode */
+ Object *ob= OBACT;
+ bPoseChannel *pchan;
+
+ if (!ob || ob->type!=OB_ARMATURE)
+ return;
+
+ if(select==2) {
+ for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
+ pchan->bone->flag &= ~(BONE_ACTIVE);
+ }
+
+ pchan= get_pose_channel(ob->pose, name);
+ if(pchan) {
+ if(select)
+ pchan->bone->flag |= (BONE_SELECTED);
+ else
+ pchan->bone->flag &= ~(BONE_SELECTED);
+ if(select==2)
+ pchan->bone->flag |= (BONE_ACTIVE);
+ }
+}
+
+/* apparently within active object context */
+/* called extern, like on bone selection */
+void select_actionchannel_by_name (bAction *act, char *name, int select)
+{
+ bActionChannel *achan;
+
+ if (!act)
+ return;
+
+ for (achan = act->chanbase.first; achan; achan= achan->next) {
+ if (!strcmp(achan->name, name)) {
+ if (select) {
+ achan->flag |= ACHAN_SELECTED;
+ hilight_channel(act, achan, 1);
+ }
+ else {
+ achan->flag &= ~ACHAN_SELECTED;
+ hilight_channel(act, achan, 0);
+ }
+ return;
+ }
+ }
+}
+
/* select_mode = SELECT_REPLACE
* = SELECT_ADD
* = SELECT_SUBTRACT
@@ -1801,7 +1850,8 @@ int select_channel(bAction *act, bActionChannel *achan, int selectmode)
static int select_constraint_channel(bAction *act,
bConstraintChannel *conchan,
- int selectmode) {
+ int selectmode)
+{
/* Select the constraint channel based on the selection mode */
int flag;
@@ -1841,150 +1891,535 @@ int select_icu_channel(bAction *act, IpoCurve *icu, int selectmode)
return flag;
}
-static void borderselect_actionchannels(bAction *act, short *mval,
- short *mvalo, int selectmode)
+/* ----------------------------------------- */
+
+/* deselects action channels in given action */
+void deselect_actionchannels (bAction *act, short test)
{
- /* Select action channels, based on mouse values.
- * If mvalo is NULL we assume it is a one click
- * action, other wise we treat it like it is a
- * border select with mval[0],mval[1] and
- * mvalo[0], mvalo[1] forming the corners of
- * a rectangle.
- */
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
- float click, x,y;
- int clickmin, clickmax;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter, sel=1;
+
+ /* filter data */
+ filter= ACTFILTER_VISIBLE;
+ actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (sel == 0)
+ break;
+
+ switch (ale->type) {
+ case ACTTYPE_ACHAN:
+ if (ale->flag & ACHAN_SELECTED)
+ sel= 0;
+ break;
+ case ACTTYPE_CONCHAN:
+ if (ale->flag & CONSTRAINT_CHANNEL_SELECT)
+ sel=0;
+ break;
+ case ACTTYPE_ICU:
+ if (ale->flag & IPO_SELECT)
+ sel=0;
+ break;
+ }
+ }
+ }
+ else
+ sel= 0;
+
+ /* Now set the flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ switch (ale->type) {
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)ale->data;
+
+ if (sel)
+ achan->flag |= ACHAN_SELECTED;
+ else
+ achan->flag &= ~ACHAN_SELECTED;
+ select_poseelement_by_name(achan->name, sel);
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
+
+ if (sel)
+ conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
+ else
+ conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)ale->data;
+
+ if (sel)
+ icu->flag |= IPO_SELECT;
+ else
+ icu->flag &= ~IPO_SELECT;
+ }
+ break;
+ }
+ }
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+}
- if (!act)
- return;
-
- if (selectmode == SELECT_REPLACE) {
- deselect_actionchannels (act, 0);
- selectmode = SELECT_ADD;
+/* deselects channels in the action editor */
+void deselect_action_channels (short test)
+{
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* based on type */
+ if (datatype == ACTCONT_ACTION)
+ deselect_actionchannels(data, test);
+ // should shapekey channels be allowed to do this?
+}
+
+/* deselects keyframes in the action editor */
+void deselect_action_keys (short test, short sel)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if (is_ipo_key_selected(ale->key_data)) {
+ sel= 0;
+ break;
+ }
+ }
+ }
+
+ /* Now set the flags */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ set_ipo_key_selection(ale->key_data, sel);
}
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+}
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+/* selects all keyframes in the action editor - per channel or time
+ * mode = 0: all in channel; mode = 1: all in frame
+ */
+void selectall_action_keys (short mval[], short mode, short select_mode)
+{
+ void *data;
+ short datatype;
- /* Only one click */
- if (mvalo == NULL) {
- clickmax = clickmin;
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ if (select_mode == SELECT_REPLACE) {
+ deselect_action_keys(0, 0);
+ select_mode = SELECT_ADD;
}
- /* Two click values (i.e., border select */
- else {
- areamouseco_to_ipoco(G.v2d, mvalo, &x, &y);
- click = (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
+
+ /* depending on mode */
+ switch (mode) {
+ case 0: /* all in channel*/
+ {
+ void *act_channel;
+ short chantype;
+
+ /* get channel, and act according to type */
+ act_channel= get_nearest_act_channel(mval, &chantype);
+ switch (chantype) {
+ case ACTTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)act_channel;
+ select_ipo_bezier_keys(achan->ipo, select_mode);
+ }
+ break;
+ case ACTTYPE_CONCHAN:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
+ select_ipo_bezier_keys(conchan->ipo, select_mode);
+ }
+ break;
+ case ACTTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)act_channel;
+ select_icu_bezier_keys(icu, select_mode);
+ }
+ break;
+ }
+ }
+ break;
+ case 1: /* all in frame */
+ {
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ rcti rect;
+ rctf rectf;
+
+ /* use bounding box to find kframe */
+ rect.xmin = rect.xmax = mval[0];
+ rect.ymin = rect.ymax = mval[1];
+
+ mval[0]= rect.xmin;
+ mval[1]= rect.ymin+2;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+ rectf.xmax= rectf.xmin;
+ rectf.ymax= rectf.ymin;
+
+ rectf.xmin = rectf.xmin - 0.5;
+ rectf.xmax = rectf.xmax + 0.5;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* Now set the flags */
+ for (ale= act_data.first; ale; ale= ale->next)
+ borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, select_mode);
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+ }
+ break;
+ }
+
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+}
- if ( ((int) click) < clickmin) {
- clickmax = clickmin;
- clickmin = (int) click;
+void markers_selectkeys_between (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+ float min, max;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* get extreme markers */
+ get_minmax_markers(1, &min, &max);
+ if (min==max) return;
+ min -= 0.5f;
+ max += 0.5f;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* select keys in-between */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ if(G.saction->pin==0 && OBACT && datatype==ACTCONT_ACTION) {
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
+ borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
+ actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
else {
- clickmax = (int) click;
+ borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
}
}
+
+ /* Cleanup */
+ BLI_freelistN(&act_data);
+}
- if (clickmax < 0) {
- return;
- }
+/* ----------------------------------------- */
- /* clickmin and clickmax now coorespond to indices into
- * the collection of channels and constraint channels.
- * What we need to do is apply the selection mode on all
- * channels and constraint channels between these indices.
- * This is done by traversing the channels and constraint
- * channels, for each item decrementing clickmin and clickmax.
- * When clickmin is less than zero we start selecting stuff,
- * until clickmax is less than zero or we run out of channels
- * and constraint channels.
- */
+/* This function makes a list of the selected keyframes
+ * in the ipo curves it has been passed
+ */
+static void make_sel_cfra_list(Ipo *ipo, ListBase *elems)
+{
+ IpoCurve *icu;
+
+ if (ipo == NULL) return;
+
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ BezTriple *bezt;
+ int a= 0;
+
+ for (bezt=icu->bezt; a<icu->totvert; a++, bezt++) {
+ if (bezt && BEZSELECTED(bezt))
+ add_to_cfra_elem(elems, bezt);
+ }
+ }
+}
- /* try in action channels */
- for (achan = act->chanbase.first; achan; achan= achan->next){
- if(VISIBLE_ACHAN(achan)) {
- if (clickmax < 0) break;
+/* This function selects all key frames in the same column(s) as a already selected key(s)
+ * or marker(s), or all the keyframes on a particular frame (triggered by a RMB on x-scrollbar)
+ */
+void column_select_action_keys(int mode)
+{
+ ListBase elems= {NULL, NULL};
+ CfraElem *ce;
+ IpoCurve *icu;
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* build list of columns */
+ switch (mode) {
+ case 1: /* list of selected keys */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
+ actdata_filter(&act_data, filter, data, datatype);
- if (clickmin <= 0) {
- /* Select the channel with the given mode. If the
- * channel is freshly selected then set it to the
- * active channel for the action
- */
- select_channel(act, achan, selectmode);
- /* messy... */
- select_poseelement_by_name(achan->name, 2);
- }
+ for (ale= act_data.first; ale; ale= ale->next)
+ make_sel_cfra_list(ale->key_data, &elems);
+
+ BLI_freelistN(&act_data);
+ break;
+ case 2: /* list of selected markers */
+ make_marker_cfra_list(&elems, 1);
- --clickmin;
- --clickmax;
+ /* apply scaled action correction if needed */
+ if (G.saction->pin==0 && OBACT && datatype==ACTCONT_ACTION) {
+ for (ce= elems.first; ce; ce= ce->next)
+ ce->cfra= get_action_frame(OBACT, ce->cfra);
+ }
+ break;
+ }
+
+ /* loop through all of the keys and select additional keyframes
+ * based on the keys found to be selected above
+ */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ for (ale= act_data.first; ale; ale= ale->next) {
+ for(ce= elems.first; ce; ce= ce->next) {
+ for (icu= ale->key_data; icu; icu= icu->next) {
+ BezTriple *bezt;
+ int verts = 0;
+
+ for (bezt=icu->bezt; verts<icu->totvert; bezt++, verts++) {
+ if (bezt) {
+ if( (int)(ce->cfra) == (int)(bezt->vec[1][0]) )
+ bezt->f2 |= 1;
+ }
+ }
+ }
}
+ }
+
+ BLI_freelistN(&act_data);
+ BLI_freelistN(&elems);
+}
+
+/* borderselect: for keyframes only */
+void borderselect_action (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ rcti rect;
+ rctf rectf;
+ int val, selectmode;
+ int (*select_function)(BezTriple *);
+ short mval[2];
+ float ymin, ymax;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* draw and handle the borderselect stuff (ui) and get the select rect */
+ if ( (val = get_border(&rect, 3)) ) {
+ if (val == LEFTMOUSE) {
+ selectmode = SELECT_ADD;
+ select_function = select_bezier_add;
+ }
+ else {
+ selectmode = SELECT_SUBTRACT;
+ select_function = select_bezier_subtract;
+ }
+
+ mval[0]= rect.xmin;
+ mval[1]= rect.ymin+2;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
+ mval[0]= rect.xmax;
+ mval[1]= rect.ymax-2;
+ areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
- if (EXPANDED_ACHAN(achan) == 0) {
- /* cannot search IPO/constaint channels */
- continue;
+ /* if action is mapped in NLA, it returns a correction */
+ if (G.saction->pin==0 && OBACT && datatype==ACTCONT_ACTION) {
+ rectf.xmin= get_action_frame(OBACT, rectf.xmin);
+ rectf.xmax= get_action_frame(OBACT, rectf.xmax);
}
- if (achan->ipo) {
- /* widget */
- if (clickmax < 0) break;
- --clickmin;
- --clickmax;
-
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (clickmax < 0) break;
-
- if (clickmin <= 0) {
- /* constraint channel */
- select_icu_channel(act, icu, selectmode);
+ ymax = CHANNELHEIGHT/2;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop over data, doing border select */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ ymin=ymax-(CHANNELHEIGHT+CHANNELSKIP);
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ if (ale->key_data) {
+ if (ale->datatype == ALE_IPO)
+ borderselect_ipo_key(ale->key_data, rectf.xmin, rectf.xmax, selectmode);
+ else if (ale->datatype == ALE_ICU)
+ borderselect_icu_key(ale->key_data, rectf.xmin, rectf.xmax, select_function);
}
-
- --clickmin;
- --clickmax;
}
+ ymax=ymin;
}
- if (achan->constraintChannels.first) {
- /* widget */
- if (clickmax < 0) break;
- --clickmin;
- --clickmax;
+ /* cleanup */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Border Select Action");
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ }
+}
+
+/* **************************************************** */
+/* MOUSE-HANDLING */
+
+/* right-hand side - mouse click */
+static void mouse_action (int selectmode)
+{
+ void *data;
+ short datatype;
+ bAction *act;
+ bActionChannel *achan;
+ bConstraintChannel *conchan= NULL;
+ IpoCurve *icu= NULL;
+ TimeMarker *marker;
+ void *act_channel;
+ short sel, act_type;
+ float selx;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
+
+ act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan);
+ marker=find_nearest_marker(1);
+
+ if (act_channel) {
+ switch (act_type) {
+ case ACTTYPE_ICU:
+ icu= (IpoCurve *)act_channel;
+ break;
+ case ACTTYPE_CONCHAN:
+ conchan= (bConstraintChannel *)act_channel;
+ break;
+ default:
+ achan= (bActionChannel *)act_channel;
+ }
+
+ if (selectmode == SELECT_REPLACE) {
+ selectmode = SELECT_ADD;
- /* try in constaint channels */
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0) break;
-
- if (clickmin <= 0) {
- /* constraint channel */
- select_constraint_channel(act, conchan, selectmode);
- }
+ deselect_action_keys(0, 0);
+
+ if (datatype == ACTCONT_ACTION) {
+ deselect_action_channels(0);
- --clickmin;
- --clickmax;
+ achan->flag |= ACHAN_SELECTED;
+ hilight_channel(act, achan, 1);
+ select_poseelement_by_name(achan->name, 2); /* 2 is activate */
}
}
+
+ if (icu)
+ select_icu_key(icu, selx, selectmode);
+ else if (conchan)
+ select_ipo_key(conchan->ipo, selx, selectmode);
+ else
+ select_ipo_key(achan->ipo, selx, selectmode);
+
+ std_rmouse_transform(transform_action_keys);
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWOOPS, 0);
+ allqueue(REDRAWBUTSALL, 0);
+ }
+ else if (marker) {
+ /* not channel, so maybe marker */
+ if (selectmode == SELECT_REPLACE) {
+ deselect_markers(0, 0);
+ marker->flag |= SELECT;
+ }
+ else if (selectmode == SELECT_INVERT) {
+ if (marker->flag & SELECT)
+ marker->flag &= ~SELECT;
+ else
+ marker->flag |= SELECT;
+ }
+ else if (selectmode == SELECT_ADD)
+ marker->flag |= SELECT;
+ else if (selectmode == SELECT_SUBTRACT)
+ marker->flag &= ~SELECT;
+
+ std_rmouse_transform(transform_markers);
+
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWSOUND, 0);
}
-
- allqueue (REDRAWIPO, 0);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWNLA, 0);
- allqueue (REDRAWOOPS, 0);
- allqueue (REDRAWBUTSALL, 0);
}
-/* lefthand side */
+/* lefthand side - mouse-click */
static void mouse_actionchannels (short mval[])
{
bAction *act= G.saction->action;
- void *act_channel;
- short chan_type;
+ void *data, *act_channel;
+ short datatype, chantype;
+
+ /* determine what type of data we are operating on */
+ data = get_action_context(&datatype);
+ if (data == NULL) return;
/* get channel to work on */
- act_channel= get_nearest_act_channel(mval, &chan_type);
+ act_channel= get_nearest_act_channel(mval, &chantype);
/* action to take depends on what channel we've got */
- switch (chan_type) {
+ switch (chantype) {
case ACTTYPE_ACHAN:
{
bActionChannel *achan= (bActionChannel *)act_channel;
@@ -2084,1058 +2519,165 @@ static void mouse_actionchannels (short mval[])
allqueue (REDRAWBUTSALL, 0);
}
-void delete_meshchannel_keys(Key *key)
-{
- delete_ipo_keys(key->ipo);
-
- BIF_undo_push("Delete Action Keys");
- meshkey_do_redraw(key);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
+/* **************************************************** */
+/* ACTION CHANNEL RE-ORDERING */
-void delete_actionchannel_keys(void)
+void top_sel_action()
{
bAction *act;
bActionChannel *achan;
- bConstraintChannel *conchan;
-
+
+ /* Get the selected action, exit if none are selected */
act = G.saction->action;
- if (!act)
- return;
-
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- /* Check action channel keys*/
- delete_ipo_keys(achan->ipo);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- /* Delete constraint channel keys */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- delete_ipo_keys(conchan->ipo);
- }
- }
- }
- }
-
- remake_action_ipos(act);
- BIF_undo_push("Delete Action Keys");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-
-}
-
-static void delete_actionchannels (void)
-{
- bAction *act;
- bActionChannel *achan, *next;
- bConstraintChannel *conchan=NULL, *nextconchan;
- int freechan;
-
- act=G.saction->action;
-
- if (!act)
- return;
-
- for (achan=act->chanbase.first; achan; achan=achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan))
- break;
-
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next){
- if (SEL_CONCHAN(conchan)) {
- achan= act->chanbase.last;
- break;
- }
- }
- }
- }
-
- if (!achan && !conchan)
- return;
+ if (!act) return;
- for (achan= act->chanbase.first; achan; achan= next) {
- freechan = 0;
- next= achan->next;
-
+ for (achan= act->chanbase.first; achan; achan= achan->next){
if (VISIBLE_ACHAN(achan)) {
- /* Remove action channels */
- if (SEL_ACHAN(achan)) {
- if (achan->ipo)
- achan->ipo->id.us--; /* Release the ipo */
- freechan = 1;
-
- /* Remove constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan=nextconchan) {
- nextconchan= conchan->next;
- if (freechan || SEL_CONCHAN(conchan)) {
- if (conchan->ipo)
- conchan->ipo->id.us--;
- BLI_freelinkN(&achan->constraintChannels, conchan);
- }
- }
+ if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
+ /* take it out off the chain keep data */
+ BLI_remlink (&act->chanbase, achan);
+ /* make it first element */
+ BLI_insertlinkbefore(&act->chanbase, act->chanbase.first, achan);
+ achan->flag |= ACHAN_MOVED;
+ /* restart with rest of list */
+ achan= achan->next;
}
-
- if (freechan)
- BLI_freelinkN (&act->chanbase, achan);
}
}
-
- BIF_undo_push("Delete Action channels");
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
-
-}
-
-void clean_shapekeys(Key *key)
-{
- int ok;
-
- /* don't proceed if user refuses */
- if (!key) return;
- ok= fbutton(&G.scene->toolsettings->clean_thresh,
- 0.0000001f, 1.0, 0.001, 0.1,
- "Clean Threshold");
- if (!ok) return;
-
- /* viable option? */
- if (key->ipo) {
- IpoCurve *icu;
-
- for (icu= key->ipo->curve.first; icu; icu=icu->next)
- clean_ipo_curve(icu);
-
- /* admin and redraw stuff */
- BIF_undo_push("Clean Action");
- allqueue(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- }
-}
-
-void clean_actionchannels(bAction *act)
-{
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- Ipo *ipo;
- IpoCurve *icu;
-
- int ok;
-
- /* don't proceed any further if no action or user refuses */
- if (!act) return;
- ok= fbutton(&G.scene->toolsettings->clean_thresh,
- 0.0000001f, 1.0, 0.001, 0.1,
- "Clean Threshold");
- if (!ok) return;
-
- /* clean selected channels only */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if(EDITABLE_ACHAN(achan)) {
- /* clean if action channel if selected */
- if (SEL_ACHAN(achan)) {
- ipo= achan->ipo;
- if (ipo) {
- if (EXPANDED_ACHAN(achan) && FILTER_IPO_ACHAN(achan)) {
- /* only clean selected ipo-curves */
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (SEL_ICU(icu) && EDITABLE_ICU(icu))
- clean_ipo_curve(icu);
- }
- }
- else {
- /* clean all ipo-curves for action channel */
- for (icu= ipo->curve.first; icu; icu= icu->next)
- clean_ipo_curve(icu);
- }
- }
- }
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- /* clean action channel's constraint channels */
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- ipo= conchan->ipo;
- if (ipo) {
- for (icu= ipo->curve.first; icu; icu= icu->next)
- clean_ipo_curve(icu);
- }
- }
- }
- }
- }
+ /* clear temp flags */
+ for (achan= act->chanbase.first; achan; achan= achan->next){
+ achan->flag = achan->flag & ~ACHAN_MOVED;
}
- /* admin and redraws */
- BIF_undo_push("Clean Action");
- allqueue(REMAKEIPO, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void sethandles_meshchannel_keys(int code, Key *key)
-{
-
- sethandles_ipo_keys(key->ipo, code);
-
- BIF_undo_push("Set handles Action keys");
- meshkey_do_redraw(key);
-}
-
-void sethandles_actionchannel_keys(int code)
-{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act)
- return;
-
- /* Loop through the channels and set the beziers
- * of the selected keys based on the integer code
- */
- for (achan = act->chanbase.first; achan; achan= achan->next){
- if (EDITABLE_ACHAN(achan)) {
- sethandles_ipo_keys(achan->ipo, code);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan))
- sethandles_ipo_keys(conchan->ipo, code);
- }
- }
- }
- }
-
/* Clean up and redraw stuff */
- remake_action_ipos(act);
- BIF_undo_push("Set handles Action channel");
+ remake_action_ipos (act);
+ BIF_undo_push("Top Action channel");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
}
-void set_ipotype_actionchannels(int ipotype)
+void up_sel_action()
{
-
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- short event;
-
+ bAction *act;
+ bActionChannel *achan, *prev;
+
/* Get the selected action, exit if none are selected */
act = G.saction->action;
- if (!act)
- return;
-
- if (ipotype == SET_IPO_POPUP) {
- /* Present a popup menu asking the user what type
- * of IPO curve he/she/GreenBTH wants. ;)
- */
- event
- = pupmenu("Channel Ipo Type %t|"
- "Constant %x1|"
- "Linear %x2|"
- "Bezier %x3");
- if(event < 1) return;
- ipotype = event;
- }
+ if (!act) return;
- /* Loop through the channels and for the selected ones set
- * the type for each Ipo curve in the channel Ipo (based on
- * the value from the popup).
- */
- for (achan = act->chanbase.first; achan; achan= achan->next){
- if (EDITABLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan)) {
- if (achan->ipo)
- setipotype_ipo(achan->ipo, ipotype);
- }
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (SEL_CONCHAN(conchan)) {
- if (conchan->ipo)
- setipotype_ipo(conchan->ipo, ipotype);
- }
- }
+ for (achan=act->chanbase.first; achan; achan= achan->next) {
+ if (VISIBLE_ACHAN(achan)) {
+ if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
+ prev = achan->prev;
+ if (prev) {
+ /* take it out off the chain keep data */
+ BLI_remlink (&act->chanbase, achan);
+ /* push it up */
+ BLI_insertlinkbefore(&act->chanbase, prev, achan);
+ achan->flag |= ACHAN_MOVED;
+ /* restart with rest of list */
+ achan= achan->next;
}
}
}
}
-
- /* Clean up and redraw stuff */
- remake_action_ipos(act);
- BIF_undo_push("Set Ipo type Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void set_extendtype_actionchannels(int extendtype)
-{
- bAction *act;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- short event;
-
- /* Get the selected action, exit if none are selected
- */
- act = G.saction->action;
- if (!act)
- return;
-
- if (extendtype == SET_EXTEND_POPUP) {
- /* Present a popup menu asking the user what type
- * of IPO curve he/she/GreenBTH wants. ;)
- */
- event
- = pupmenu("Channel Extending Type %t|"
- "Constant %x1|"
- "Extrapolation %x2|"
- "Cyclic %x3|"
- "Cyclic extrapolation %x4");
- if(event < 1) return;
- extendtype = event;
+ /* clear temp flags */
+ for (achan=act->chanbase.first; achan; achan= achan->next){
+ achan->flag = achan->flag & ~ACHAN_MOVED;
}
- /* Loop through the channels and for the selected ones set
- * the type for each Ipo curve in the channel Ipo (based on
- * the value from the popup).
- */
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan)) {
- if (achan->ipo) {
- switch (extendtype) {
- case SET_EXTEND_CONSTANT:
- setexprap_ipoloop(achan->ipo, IPO_HORIZ);
- break;
- case SET_EXTEND_EXTRAPOLATION:
- setexprap_ipoloop(achan->ipo, IPO_DIR);
- break;
- case SET_EXTEND_CYCLIC:
- setexprap_ipoloop(achan->ipo, IPO_CYCL);
- break;
- case SET_EXTEND_CYCLICEXTRAPOLATION:
- setexprap_ipoloop(achan->ipo, IPO_CYCLX);
- break;
- }
- }
- }
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (SEL_CONCHAN(conchan)) {
- if (conchan->ipo) {
- switch (extendtype) {
- case SET_EXTEND_CONSTANT:
- setexprap_ipoloop(conchan->ipo, IPO_HORIZ);
- break;
- case SET_EXTEND_EXTRAPOLATION:
- setexprap_ipoloop(conchan->ipo, IPO_DIR);
- break;
- case SET_EXTEND_CYCLIC:
- setexprap_ipoloop(conchan->ipo, IPO_CYCL);
- break;
- case SET_EXTEND_CYCLICEXTRAPOLATION:
- setexprap_ipoloop(conchan->ipo, IPO_CYCLX);
- break;
- }
- }
- }
- }
- }
- }
- }
-
/* Clean up and redraw stuff */
- remake_action_ipos(act);
- BIF_undo_push("Set Ipo type Action channel");
+ remake_action_ipos (act);
+ BIF_undo_push("Up Action channel");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
}
-static void set_snap_actionchannels(bAction *act, short snaptype)
-{
- /* snapping function for action channels*/
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- /* Loop through the channels */
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if(EDITABLE_ACHAN(achan)) {
- if (achan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, achan->ipo, 0, 1);
- snap_ipo_keys(achan->ipo, snaptype);
- actstrip_map_ipo_keys(OBACT, achan->ipo, 1, 1);
- }
- else {
- snap_ipo_keys(achan->ipo, snaptype);
- }
- }
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (conchan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 0, 1);
- snap_ipo_keys(conchan->ipo, snaptype);
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 1, 1);
- }
- else {
- snap_ipo_keys(conchan->ipo, snaptype);
- }
- }
- }
- }
- }
- }
-}
-
-static void set_snap_meshchannels(Key *key, short snaptype)
-{
- /* snapping function for mesh channels */
- if(key->ipo) {
- snap_ipo_keys(key->ipo, snaptype);
- }
-}
-
-
-void snap_keys_to_frame(int snap_mode)
+void down_sel_action()
{
- /* This function is the generic entry-point for snapping keyframes
- * to a frame(s). It passes the work off to sub-functions for the
- * different types in the action editor.
- */
-
- SpaceAction *saction;
bAction *act;
- Key *key;
- char str[32];
-
- /* get data */
- saction= curarea->spacedata.first;
- if (!saction) return;
- act = saction->action;
- key = get_action_mesh_key();
-
- /* determine mode */
- switch (snap_mode) {
- case 1:
- strcpy(str, "Snap Keys To Nearest Frame");
- break;
- case 2:
- strcpy(str, "Snap Keys To Current Frame");
- break;
- case 3:
- strcpy(str, "Snap Keys To Nearest Marker");
- break;
- default:
- return;
- }
-
- /* snap to frame */
- if (act) {
- set_snap_actionchannels(act, snap_mode);
- remake_action_ipos (act);
- }
- else if (key) {
- set_snap_meshchannels(key, snap_mode);
- }
- else {
- return;
- }
+ bActionChannel *achan, *next;
- BIF_undo_push(str);
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-static void mirror_actionchannels(bAction *act, short mirror_mode)
-{
- /* mirror function for action channels */
- bActionChannel *achan;
- bConstraintChannel *conchan;
+ /* Get the selected action, exit if none are selected */
+ act = G.saction->action;
+ if (!act) return;
- /* Loop through the channels */
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- if (achan->ipo) {
- if (G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, achan->ipo, 0, 1);
- mirror_ipo_keys(achan->ipo, mirror_mode);
- actstrip_map_ipo_keys(OBACT, achan->ipo, 1, 1);
+ for (achan= act->chanbase.last; achan; achan= achan->prev) {
+ if (VISIBLE_ACHAN(achan)) {
+ if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
+ next = achan->next;
+ if (next) next = next->next;
+ if (next) {
+ /* take it out off the chain keep data */
+ BLI_remlink (&act->chanbase, achan);
+ /* move it down */
+ BLI_insertlinkbefore(&act->chanbase, next, achan);
+ achan->flag |= ACHAN_MOVED;
}
else {
- mirror_ipo_keys(achan->ipo, mirror_mode);
+ /* take it out off the chain keep data */
+ BLI_remlink (&act->chanbase, achan);
+ /* add at end */
+ BLI_addtail(&act->chanbase, achan);
+ achan->flag |= ACHAN_MOVED;
}
}
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* constraint channels */
- for (conchan=achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (conchan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 0, 1);
- mirror_ipo_keys(conchan->ipo, mirror_mode);
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 1, 1);
- }
- else {
- mirror_ipo_keys(conchan->ipo, mirror_mode);
- }
- }
- }
- }
}
}
-}
-
-static void mirror_meshchannels(Key *key, short mirror_mode)
-{
- /* mirror function for mesh channels */
- if(key->ipo) {
- mirror_ipo_keys(key->ipo, mirror_mode);
- }
-}
-
-void mirror_action_keys(short mirror_mode)
-{
- /* This function is the generic entry-point for mirroring keyframes
- * to over a frame. It passes the work off to sub-functions for the
- * different types in the action editor.
- */
-
- SpaceAction *saction;
- bAction *act;
- Key *key;
- char str[32];
-
- /* get data */
- saction= curarea->spacedata.first;
- if (!saction) return;
- act = saction->action;
- key = get_action_mesh_key();
-
- /* determine mode */
- switch (mirror_mode) {
- case 1:
- strcpy(str, "Mirror Keys Over Current Frame");
- break;
- case 2:
- strcpy(str, "Mirror Keys Over Y-Axis");
- break;
- case 3:
- strcpy(str, "Mirror Keys Over X-Axis");
- break;
- case 4:
- strcpy(str, "Mirror Keys Over Marker");
- break;
- default:
- return;
- }
-
- /* mirror */
- if (act) {
- mirror_actionchannels(act, mirror_mode);
- remake_action_ipos (act);
- }
- else if (key) {
- mirror_meshchannels(key, mirror_mode);
- }
- else {
- return;
+ /* clear temp flags */
+ for (achan= act->chanbase.first; achan; achan= achan->next){
+ achan->flag = achan->flag & ~ACHAN_MOVED;
}
- BIF_undo_push(str);
+ /* Clean up and redraw stuff */
+ remake_action_ipos (act);
+ BIF_undo_push("Down Action channel");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
}
-/* This function allows the user to insert keyframes on the current
- * frame from the Action Editor, using the current values of the channels
- * to be keyframed.
- */
-void insertkey_action(void)
+void bottom_sel_action()
{
bAction *act;
- Key *key;
- Object *ob= OBACT;
- IpoCurve *icu;
- short mode;
- float cfra;
+ bActionChannel *achan;
- /* get data */
+ /* Get the selected action, exit if none are selected */
act = G.saction->action;
- key = get_action_mesh_key();
- cfra = frame_to_float(CFRA);
+ if (!act) return;
- if (act) {
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- /* ask user what to keyframe */
- mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2");
- if (mode == 0) return;
-
- for (achan= act->chanbase.first; achan; achan=achan->next) {
- if (EDITABLE_ACHAN(achan)) {
- if (achan->ipo && (SEL_ACHAN(achan) || (mode == 1))) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (ob)
- insertkey((ID *)ob, icu->blocktype, achan->name, NULL, icu->adrcode);
- else
- insert_vert_ipo(icu, cfra, icu->curval);
- }
- }
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (EDITABLE_CONCHAN(conchan)) {
- if (conchan->ipo && (SEL_ACHAN(conchan) || (mode == 1))) {
- for (icu= conchan->ipo->curve.first; icu; icu=icu->next) {
- /* // commented out as this doesn't seem to work right for some reason
- if (ob)
- insertkey((ID *)ob, ID_CO, achan->name, conchan->name, CO_ENFORCE);
- else
- insert_vert_ipo(icu, cfra, icu->curval);
- */
- insert_vert_ipo(icu, cfra, icu->curval);
- }
- }
- }
- }
- }
+ for (achan=act->chanbase.last; achan; achan= achan->prev) {
+ if (VISIBLE_ACHAN(achan)) {
+ if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) {
+ /* take it out off the chain keep data */
+ BLI_remlink (&act->chanbase, achan);
+ /* add at end */
+ BLI_addtail(&act->chanbase, achan);
+ achan->flag |= ACHAN_MOVED;
}
- }
+ }
}
- else if (key) {
- /* ask user if they want to insert a keyframe */
- mode = okee("Insert Keyframe?");
- if (mode == 0) return;
-
- if (key->ipo) {
- for (icu= key->ipo->curve.first; icu; icu=icu->next) {
- insert_vert_ipo(icu, cfra, icu->curval);
- }
- }
+ /* clear temp flags */
+ for (achan=act->chanbase.first; achan; achan= achan->next) {
+ achan->flag = achan->flag & ~ACHAN_MOVED;
}
- BIF_undo_push("Insert Key");
+ /* Clean up and redraw stuff */
+ remake_action_ipos (act);
+ BIF_undo_push("Bottom Action channel");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
}
-static void select_all_keys_frames(bAction *act, short *mval,
- short *mvalo, int selectmode)
-{
-
- /* This function tries to select all action keys in
- * every channel for a given range of keyframes that
- * are within the mouse values mval and mvalo (usually
- * the result of a border select). If mvalo is passed as
- * NULL then the selection is treated as a one-click and
- * the function tries to select all keys within half a
- * frame of the click point.
- */
-
- rcti rect;
- rctf rectf;
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- if (!act)
- return;
-
- if (selectmode == SELECT_REPLACE) {
- deselect_actionchannel_keys(act, 0, 0);
- selectmode = SELECT_ADD;
- }
-
- if (mvalo == NULL) {
- rect.xmin = rect.xmax = mval[0];
- rect.ymin = rect.ymax = mval[1];
- }
- else {
- if (mval[0] < mvalo[0] ) {
- rect.xmin = mval[0];
- rect.xmax = mvalo[0];
- }
- else {
- rect.xmin = mvalo[0];
- rect.xmax = mval[0];
- }
- if (mval[1] < mvalo[1] ) {
- rect.ymin = mval[1];
- rect.ymax = mvalo[1];
- }
- else {
- rect.ymin = mvalo[1];
- rect.ymax = mval[1];
- }
- }
-
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
- mval[0]= rect.xmax;
- mval[1]= rect.ymax-2;
- areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
-
- if (mvalo == NULL) {
- rectf.xmin = rectf.xmin - 0.5;
- rectf.xmax = rectf.xmax + 0.5;
- }
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
-
- if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
- }
- }
- }
- }
-
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
-}
-
-
-static void select_all_keys_channels(bAction *act, short *mval,
- short *mvalo, int selectmode)
-{
- bActionChannel *achan;
- bConstraintChannel *conchan;
- float click, x,y;
- int clickmin, clickmax;
-
- /* This function selects all the action keys that
- * are in the mouse selection range defined by
- * the ordered pairs mval and mvalo (usually
- * these 2 are obtained from a border select).
- * If mvalo is NULL, then the selection is
- * treated like a one-click action, and at most
- * one channel is selected.
- */
-
- /* If the action is null then abort */
- if (!act)
- return;
-
- if (selectmode == SELECT_REPLACE) {
- deselect_actionchannel_keys(act, 0, 0);
- selectmode = SELECT_ADD;
- }
-
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
-
- /* Only one click */
- if (mvalo == NULL) {
- clickmax = clickmin;
- }
- /* Two click values (i.e., border select) */
- else {
- areamouseco_to_ipoco(G.v2d, mvalo, &x, &y);
- click = (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
-
- if ( ((int) click) < clickmin) {
- clickmax = clickmin;
- clickmin = (int) click;
- }
- else {
- clickmax = (int) click;
- }
- }
-
- if (clickmax < 0) {
- return;
- }
-
- for (achan = act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (clickmax < 0) break;
-
- if (clickmin <= 0) {
- /* Select the channel with the given mode. If the
- * channel is freshly selected then set it to the
- * active channel for the action
- */
- select_ipo_bezier_keys(achan->ipo, selectmode);
- }
- --clickmin;
- --clickmax;
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- /* Check for click in a constraint */
- for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0) break;
- if (clickmin <= 0) {
- select_ipo_bezier_keys(achan->ipo, selectmode);
- }
- --clickmin;
- --clickmax;
- }
- }
- }
-
- allqueue (REDRAWIPO, 0);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWNLA, 0);
-}
-
-static void borderselect_function(void (*select_func)(bAction *act,
- short *mval,
- short *mvalo,
- int selectmode))
-{
- /* This function executes an arbitrary selection
- * function as part of a border select. This
- * way the same function that is used for
- * right click selection points can generally
- * be used as the argument to this function
- */
- bAction *act;
- rcti rect;
- short mval[2], mvalo[2];
- int val;
-
- /* Get the selected action, exit if none are selected */
- act=G.saction->action;
- if (!act)
- return;
-
- /* Let the user draw a border (or abort) */
- if ( (val=get_border (&rect, 3)) ) {
- mval[0]= rect.xmin;
- mval[1]= rect.ymin+2;
- mvalo[0]= rect.xmax;
- mvalo[1]= rect.ymax-2;
-
- /* if the left mouse was used, do an additive
- * selection with the user defined selection
- * function.
- */
- if (val == LEFTMOUSE)
- select_func(act, mval, mvalo, SELECT_ADD);
-
- /* if the right mouse was used, do a subtractive
- * selection with the user defined selection
- * function.
- */
- else if (val == RIGHTMOUSE)
- select_func(act, mval, mvalo, SELECT_SUBTRACT);
- }
-
- BIF_undo_push("Border Select Action");
-}
-
-static void clever_keyblock_names(Key *key, short* mval){
- int but=0, i, keynum;
- char str[64];
- float x;
- KeyBlock *kb;
- /* get the keynum cooresponding to the y value
- * of the mouse pointer, return if this is
- * an invalid key number (and we don't deal
- * with the speed ipo).
- */
-
- keynum = get_nearest_key_num(key, mval, &x);
- if ( (keynum < 1) || (keynum >= key->totkey) )
- return;
-
- kb= key->block.first;
- for (i=0; i<keynum; ++i) kb = kb->next;
-
- if (kb->name[0] == '\0') {
- sprintf(str, "Key %d", keynum);
- }
- else {
- strcpy(str, kb->name);
- }
-
- if ( (kb->slidermin >= kb->slidermax) ) {
- kb->slidermin = 0.0;
- kb->slidermax = 1.0;
- }
-
- add_numbut(but++, TEX, "KB: ", 0, 24, str,
- "Does this really need a tool tip?");
- add_numbut(but++, NUM|FLO, "Slider Min:",
- -10000, kb->slidermax, &kb->slidermin, 0);
- add_numbut(but++, NUM|FLO, "Slider Max:",
- kb->slidermin, 10000, &kb->slidermax, 0);
-
- if (do_clever_numbuts(str, but, REDRAW)) {
- strcpy(kb->name, str);
- allqueue (REDRAWACTION, 0);
- allspace(REMAKEIPO, 0);
- allqueue (REDRAWIPO, 0);
- }
-
-
-}
-
-static void clever_achannel_names(short *mval)
-{
- void *act_channel;
- bActionChannel *achan= NULL;
- bConstraintChannel *conchan= NULL;
- IpoCurve *icu= NULL;
-
- int but=0;
- char str[64];
- short expand, protect, chantype;
- float slidermin, slidermax;
-
- /* figure out what is under cursor */
- act_channel= get_nearest_act_channel(mval, &chantype);
-
- /* create items for clever-numbut */
- if (chantype == ACTTYPE_ACHAN) {
- achan= (bActionChannel *)act_channel;
-
- strcpy(str, achan->name);
- protect= (achan->flag & ACHAN_PROTECTED);
- expand = (achan->flag & ACHAN_EXPANDED);
-
- add_numbut(but++, TEX, "ActChan: ", 0, 31, str, "Name of Action Channel");
- add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Channel is Expanded");
- add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_CONCHAN) {
- conchan= (bConstraintChannel *)act_channel;
-
- strcpy(str, conchan->name);
- protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
-
- add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
- add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else if (chantype == ACTTYPE_ICU) {
- icu= (IpoCurve *)act_channel;
-
- strcpy(str, getname_ipocurve(icu));
-
- if (IS_EQ(icu->slide_max, icu->slide_min)) {
- if (IS_EQ(icu->ymax, icu->ymin)) {
- icu->slide_min= -100.0;
- icu->slide_max= 100.0;
- }
- else {
- icu->slide_min= icu->ymin;
- icu->slide_max= icu->ymax;
- }
- }
- slidermin= icu->slide_min;
- slidermax= icu->slide_max;
-
- //protect= (icu->flag & IPO_PROTECT);
-
- add_numbut(but++, NUM|FLO, "Slider Min:", -10000, slidermax, &slidermin, 0);
- add_numbut(but++, NUM|FLO, "Slider Max:", slidermin, 10000, &slidermax, 0);
- //add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
- }
- else {
- /* nothing under-cursor */
- return;
- }
-
-
- /* draw clever-numbut */
- if (do_clever_numbuts(str, but, REDRAW)) {
- /* restore settings based on type */
- if (icu) {
- icu->slide_min= slidermin;
- icu->slide_max= slidermax;
-
- //if (protect) icu->flag |= IPO_PROTECT;
- //else icu->flag &= ~IPO_PROTECT;
- }
- else if (conchan) {
- strcpy(conchan->name, str);
-
- if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
- else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
- }
- else if (achan) {
- strcpy(achan->name, str);
-
- if (expand) achan->flag |= ACHAN_EXPANDED;
- else achan->flag &= ~ACHAN_EXPANDED;
-
- if (protect) achan->flag |= ACHAN_PROTECTED;
- else achan->flag &= ~ACHAN_PROTECTED;
- }
-
- allqueue (REDRAWACTION, 0);
- allqueue (REDRAWVIEW3D, 0);
- }
-}
-
-/* this gets called when nkey is pressed (no Transform Properties panel yet) */
-static void numbuts_action(void)
-{
- /* now called from action window event loop, plus reacts on mouseclick */
- /* removed Hos grunts for that reason! :) (ton) */
- bAction *act;
- Key *key;
- short mval[2];
-
- key = get_action_mesh_key();
- act = G.saction->action;
-
- getmouseco_areawin (mval);
-
- if (mval[0] < NAMEWIDTH) {
- if (act)
- clever_achannel_names(mval);
- else if (key)
- clever_keyblock_names(key, mval);
- }
-}
+/* **************************************************** */
+/* EVENT HANDLING */
void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
@@ -3186,96 +2728,38 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case AKEY:
- if (act) {
- if (mval[0]<NAMEWIDTH) {
- deselect_actionchannels (act, 1);
- allqueue (REDRAWVIEW3D, 0);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (mval[0]>ACTWIDTH) {
- if (G.qual == LR_CTRLKEY) {
- deselect_markers (1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
- else {
- deselect_actionchannel_keys (act, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- }
+ if (mval[0]<NAMEWIDTH) {
+ deselect_action_channels (1);
+ allqueue (REDRAWVIEW3D, 0);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
}
- else if (key) {
- if (mval[0]<ACTWIDTH) {
- /* to do ??? */
+ else if (mval[0]>ACTWIDTH) {
+ if (G.qual == LR_CTRLKEY) {
+ deselect_markers (1, 0);
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWSOUND, 0);
}
else {
- if (G.qual == LR_CTRLKEY) {
- deselect_markers(1, 0);
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
- }
- else {
- deselect_meshchannel_keys(key, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
+ deselect_action_keys (1, 1);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
}
}
break;
case BKEY:
- if (G.qual & LR_CTRLKEY)
+ if (G.qual & LR_CTRLKEY) {
borderselect_markers();
- else if (act) {
- /* If the border select is initiated in the
- * part of the action window where the channel
- * names reside, then select the channels
- */
- if (mval[0]<NAMEWIDTH) {
- borderselect_function(borderselect_actionchannels);
- BIF_undo_push("Select Action");
- }
- else if (mval[0]>ACTWIDTH) {
- /* If the border select is initiated in the
- * vertical scrollbar, then (de)select all keys
- * for the channels in the selection region
- */
- if (IN_2D_VERT_SCROLL(mval)) {
- borderselect_function(select_all_keys_channels);
- }
-
- /* If the border select is initiated in the
- * horizontal scrollbar, then (de)select all keys
- * for the keyframes in the selection region
- */
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- borderselect_function(select_all_keys_frames);
- }
-
- /* Other wise, select the action keys */
- else {
- borderselect_action();
- }
- }
}
- else if (key) {
- if (mval[0]<ACTWIDTH) {
- /* to do?? */
- }
- else {
- borderselect_mesh(key);
- }
+ else {
+ if (mval[0]>ACTWIDTH)
+ borderselect_action();
}
break;
@@ -3288,18 +2772,10 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DKEY:
if (mval[0]>ACTWIDTH) {
- if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
+ if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
duplicate_marker();
- }
- else if (G.qual == LR_SHIFTKEY) {
- if (act) {
- duplicate_actionchannel_keys();
- remake_action_ipos(act);
- }
- else if (key) {
- duplicate_meshchannel_keys(key);
- }
- }
+ else if (G.qual == LR_SHIFTKEY)
+ duplicate_action_keys();
}
break;
@@ -3308,33 +2784,19 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
transform_markers('g', 0);
}
else {
- if (mval[0]>=ACTWIDTH) {
- if (act) {
- transform_actionchannel_keys ('g', 0);
- }
- else if (key) {
- transform_meshchannel_keys('g', key);
- }
- }
+ if (mval[0]>=ACTWIDTH)
+ transform_action_keys('g', 0);
}
break;
case HKEY:
if(G.qual & LR_SHIFTKEY) {
- if(okee("Set Keys to Auto Handle")) {
- if (act)
- sethandles_actionchannel_keys(HD_AUTO);
- else if (key)
- sethandles_meshchannel_keys(HD_AUTO, key);
- }
+ if(okee("Set Keys to Auto Handle"))
+ sethandles_action_keys(HD_AUTO);
}
else {
- if(okee("Toggle Keys Aligned Handle")) {
- if (act)
- sethandles_actionchannel_keys(HD_ALIGN);
- else if (key)
- sethandles_meshchannel_keys(HD_ALIGN, key);
- }
+ if(okee("Toggle Keys Aligned Handle"))
+ sethandles_action_keys(HD_ALIGN);
}
break;
@@ -3344,11 +2806,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
else {
val= (G.qual & LR_SHIFTKEY) ? 2 : 1;
-
- if (act)
- column_select_actionkeys(act, val);
- else if (key)
- column_select_shapekeys(key, val);
+ column_select_action_keys(val);
}
allqueue(REDRAWTIME, 0);
@@ -3392,10 +2850,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case OKEY:
- if(act)
- clean_actionchannels(act);
- else if(key)
- clean_shapekeys(key);
+ clean_action();
break;
case PKEY:
@@ -3415,35 +2870,24 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
if(G.qual & LR_SHIFTKEY) {
if (act || key) {
val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2|Nearest Marker %x3");
- snap_keys_to_frame(val);
+ snap_action_keys(val);
}
}
- else {
- if (act)
- transform_actionchannel_keys ('s', 0);
- else if (key)
- transform_meshchannel_keys('s', key);
- }
+ else
+ transform_action_keys ('s', 0);
}
break;
case TKEY:
- if (act) {
- if(G.qual & LR_SHIFTKEY)
- set_ipotype_actionchannels(SET_IPO_POPUP);
- else
- transform_actionchannel_keys ('t', 0);
- }
- /* else if (key) {} ... todo */
+ if(G.qual & LR_SHIFTKEY)
+ action_set_ipo_flags(SET_IPO_POPUP);
+ else
+ transform_action_keys ('t', 0);
break;
case VKEY:
- if(okee("Set Keys to Vector Handle")) {
- if (act)
- sethandles_actionchannel_keys(HD_VECT);
- else if (key)
- sethandles_meshchannel_keys(HD_VECT, key);
- }
+ if(okee("Set Keys to Vector Handle"))
+ sethandles_action_keys(HD_VECT);
break;
case PAGEUPKEY:
@@ -3478,15 +2922,10 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
case DELKEY:
case XKEY:
if (okee("Erase selected")) {
- if (act) {
- if (mval[0]<NAMEWIDTH)
- delete_actionchannels();
- else
- delete_actionchannel_keys();
- }
- else if (key) {
- delete_meshchannel_keys(key);
- }
+ if (mval[0]<NAMEWIDTH)
+ delete_action_channels();
+ else
+ delete_action_keys();
if (mval[0] >= NAMEWIDTH)
remove_marker();
@@ -3538,45 +2977,26 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
else numbuts_action();
}
else if (mval[0]>ACTWIDTH) {
+ short select_mode= (G.qual & LR_SHIFTKEY)? SELECT_INVERT: SELECT_REPLACE;
+
/* Clicking in the vertical scrollbar selects
* all of the keys for that channel at that height
*/
- if (IN_2D_VERT_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_channels(act, mval, NULL, SELECT_INVERT);
- else
- select_all_keys_channels(act, mval, NULL, SELECT_REPLACE);
- }
+ if (IN_2D_VERT_SCROLL(mval))
+ selectall_action_keys(mval, 0, select_mode);
/* Clicking in the horizontal scrollbar selects
* all of the keys within 0.5 of the nearest integer
* frame
*/
- else if (IN_2D_HORIZ_SCROLL(mval)) {
- if(G.qual & LR_SHIFTKEY)
- select_all_keys_frames(act, mval, NULL, SELECT_INVERT);
- else
- select_all_keys_frames(act, mval, NULL, SELECT_REPLACE);
- BIF_undo_push("Select all Action");
- }
+ else if (IN_2D_HORIZ_SCROLL(mval))
+ selectall_action_keys(mval, 1, select_mode);
/* Clicking in the main area of the action window
* selects keys and markers
*/
- else {
- if (act) {
- if(G.qual & LR_SHIFTKEY)
- mouse_action(SELECT_INVERT);
- else
- mouse_action(SELECT_REPLACE);
- }
- else if (key) {
- if(G.qual & LR_SHIFTKEY)
- mouse_mesh_action(SELECT_INVERT, key);
- else
- mouse_mesh_action(SELECT_REPLACE, key);
- }
- }
+ else
+ mouse_action(select_mode);
}
break;
case PADPLUSKEY:
@@ -3605,634 +3025,4 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
}
-Key *get_action_mesh_key(void)
-{
- /* gets the key data from the currently selected
- * mesh/lattice. If a mesh is not selected, or does not have
- * key data, then we return NULL (currently only
- * returns key data for RVK type meshes). If there
- * is an action that is pinned, return null
- */
- Object *ob;
- Key *key;
-
- ob = OBACT;
- if (!ob) return NULL;
-
- if (G.saction->pin) return NULL;
-
- if (ob->type==OB_MESH ) {
- key = ((Mesh *)ob->data)->key;
- }
- else if (ob->type==OB_LATTICE ) {
- key = ((Lattice *)ob->data)->key;
- }
- else return NULL;
-
- if (key) {
- if (key->type == KEY_RELATIVE)
- return key;
- }
-
- return NULL;
-}
-
-int get_nearest_key_num(Key *key, short *mval, float *x)
-{
- /* returns the key num that cooresponds to the
- * y value of the mouse click. Does not check
- * if this is a valid keynum. Also gives the Ipo
- * x coordinate.
- */
- int num;
- float ybase, y;
-
- areamouseco_to_ipoco(G.v2d, mval, x, &y);
-
- ybase = key->totkey * (CHANNELHEIGHT + CHANNELSKIP);
- num = (int) ((ybase - y + CHANNELHEIGHT/2) / (CHANNELHEIGHT+CHANNELSKIP));
-
- return (num + 1);
-}
-
-void *get_nearest_act_channel(short mval[], short *ret_type)
-{
- /* Returns the 'channel' that is under the mouse cursor.
- * This 'channel' can either be an action channel, or a constraint channel.
- *
- * #ret_type# is used to denote what type of channel was found.
- * It should only be one of the ACTTYPE_* constant values.
- */
-
- bAction *act= G.saction->action;
- bActionChannel *achan;
- bConstraintChannel *conchan;
- IpoCurve *icu;
-
- float x,y;
- int clickmin, clickmax;
-
- if (act == NULL) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
- clickmax = clickmin;
-
- if (clickmax < 0) {
- *ret_type= ACTTYPE_NONE;
- return NULL;
- }
-
- /* try in action channels */
- for (achan = act->chanbase.first; achan; achan=achan->next) {
- if(VISIBLE_ACHAN(achan)) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - action channel */
- *ret_type= ACTTYPE_ACHAN;
- return achan;
- }
- --clickmin;
- --clickmax;
- }
- else
- continue;
-
- if (EXPANDED_ACHAN(achan) == 0)
- continue;
-
- /* try in ipo curves */
- if (achan->ipo) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - ipo-curves show/hide */
- *ret_type= ACTTYPE_FILLIPO;
- return achan; /* pointer to action-channel is returned in this case */
- }
- --clickmin;
- --clickmax;
-
- /* now the ipo-curve channels if they are exposed */
- if (FILTER_IPO_ACHAN(achan)) {
- for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - ipo-curve channel */
- *ret_type= ACTTYPE_ICU;
- return icu;
- }
- --clickmin;
- --clickmax;
- }
- }
- }
-
- /* try in constaint channels */
- if (achan->constraintChannels.first) {
- /* check header first */
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - constraints show/hide */
- *ret_type= ACTTYPE_FILLCON;
- return achan; /* pointer to action-channel is returned in this case */
- }
- --clickmin;
- --clickmax;
-
- /* now the constraint channels if they are exposed */
- if (FILTER_CON_ACHAN(achan)) {
- for (conchan= achan->constraintChannels.first; conchan; conchan=conchan->next) {
- if (clickmax < 0)
- break;
- if (clickmin <= 0) {
- /* found match - constraint channel */
- *ret_type= ACTTYPE_CONCHAN;
- return conchan;
- }
- --clickmin;
- --clickmax;
- }
- }
- }
- }
-
- *ret_type= ACTTYPE_NONE;
- return NULL;
-}
-
-/* ************************************* Action Editor Markers ************************************* */
-
-void markers_selectkeys_between(void)
-{
- bAction *act;
- Key *key;
- float min, max;
-
- /* get extreme markers */
- get_minmax_markers(1, &min, &max);
- if (min==max) return;
- min -= 0.5f;
- max += 0.5f;
-
- /* get keyframe data */
- act = G.saction->action;
- key = get_action_mesh_key();
-
- /* select keys in-between */
- if (act) {
- bActionChannel *achan;
- bConstraintChannel *conchan;
-
- for (achan= act->chanbase.first; achan; achan= achan->next) {
- if (achan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, achan->ipo, 0, 1);
- borderselect_ipo_key(achan->ipo, min, max, SELECT_ADD);
- actstrip_map_ipo_keys(OBACT, achan->ipo, 1, 1);
- }
- else {
- borderselect_ipo_key(achan->ipo, min, max, SELECT_ADD);
- }
- }
-
- if ((EXPANDED_ACHAN(achan)==0) || (FILTER_CON_ACHAN(achan)==0))
- continue;
-
- for (conchan= achan->constraintChannels.first; conchan; conchan= conchan->next) {
- if (conchan->ipo) {
- if(G.saction->pin==0 && OBACT) {
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 0, 1);
- borderselect_ipo_key(conchan->ipo, min, max, SELECT_ADD);
- actstrip_map_ipo_keys(OBACT, conchan->ipo, 1, 1);
- }
- else {
- borderselect_ipo_key(conchan->ipo, min, max, SELECT_ADD);
- }
- }
- }
- }
- }
- else if (key) {
- if (key->ipo)
- borderselect_ipo_key(key->ipo, min, max, SELECT_ADD);
- }
-}
-
-/* ************************************* Action Channel Ordering *********************************** */
-
-void top_sel_action()
-{
- bAction *act;
- bActionChannel *achan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan= act->chanbase.first; achan; achan= achan->next){
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* make it first element */
- BLI_insertlinkbefore(&act->chanbase, act->chanbase.first, achan);
- achan->flag |= ACHAN_MOVED;
- /* restart with rest of list */
- achan= achan->next;
- }
- }
- }
- /* clear temp flags */
- for (achan= act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Top Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void up_sel_action()
-{
- bAction *act;
- bActionChannel *achan, *prev;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- prev = achan->prev;
- if (prev) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* push it up */
- BLI_insertlinkbefore(&act->chanbase, prev, achan);
- achan->flag |= ACHAN_MOVED;
- /* restart with rest of list */
- achan= achan->next;
- }
- }
- }
- }
- /* clear temp flags */
- for (achan=act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Up Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void down_sel_action()
-{
- bAction *act;
- bActionChannel *achan, *next;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan= act->chanbase.last; achan; achan= achan->prev) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)){
- next = achan->next;
- if (next) next = next->next;
- if (next) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* move it down */
- BLI_insertlinkbefore(&act->chanbase, next, achan);
- achan->flag |= ACHAN_MOVED;
- }
- else {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* add at end */
- BLI_addtail(&act->chanbase, achan);
- achan->flag |= ACHAN_MOVED;
- }
- }
- }
- }
- /* clear temp flags */
- for (achan= act->chanbase.first; achan; achan= achan->next){
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Down Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-void bottom_sel_action()
-{
- bAction *act;
- bActionChannel *achan;
-
- /* Get the selected action, exit if none are selected */
- act = G.saction->action;
- if (!act) return;
-
- for (achan=act->chanbase.last; achan; achan= achan->prev) {
- if (VISIBLE_ACHAN(achan)) {
- if (SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED)) {
- /* take it out off the chain keep data */
- BLI_remlink (&act->chanbase, achan);
- /* add at end */
- BLI_addtail(&act->chanbase, achan);
- achan->flag |= ACHAN_MOVED;
- }
- }
- }
- /* clear temp flags */
- for (achan=act->chanbase.first; achan; achan= achan->next) {
- achan->flag = achan->flag & ~ACHAN_MOVED;
- }
-
- /* Clean up and redraw stuff */
- remake_action_ipos (act);
- BIF_undo_push("Bottom Action channel");
- allspace(REMAKEIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWNLA, 0);
-}
-
-/* ********************************* BAKING STUFF ********************************** */
-/* NOTE: these functions should probably be moved to their own file sometime - Aligorith */
-
-void world2bonespace(float boneSpaceMat[][4], float worldSpace[][4], float restPos[][4], float armPos[][4])
-{
- float imatarm[4][4], imatbone[4][4], tmat[4][4], t2mat[4][4];
-
- Mat4Invert(imatarm, armPos);
- Mat4Invert(imatbone, restPos);
- Mat4MulMat4(tmat, imatarm, worldSpace);
- Mat4MulMat4(t2mat, tmat, imatbone);
- Mat4MulMat4(boneSpaceMat, restPos, t2mat);
-}
-
-bAction *bake_action_with_client (bAction *act, Object *armob, float tolerance)
-{
- bArmature *arm;
- bAction *result=NULL;
- bActionChannel *achan;
- bAction *temp;
- bPoseChannel *pchan;
- ID *id;
- float actstart, actend;
- int oldframe;
- int curframe;
- char newname[64];
-
- if (!act)
- return NULL;
-
- arm = get_armature(armob);
-
- if (G.obedit){
- error ("Actions can't be baked in Edit Mode");
- return NULL;
- }
-
- if (!arm || armob->pose==NULL){
- error ("Select an armature before baking");
- return NULL;
- }
-
- /* Get a new action */
- result = add_empty_action("Action");
- id= (ID *)armob;
-
- /* Assign the new action a unique name */
- sprintf (newname, "%s.BAKED", act->id.name+2);
- rename_id(&result->id, newname);
-
- calc_action_range(act, &actstart, &actend, 1);
-
- oldframe = G.scene->r.cfra;
-
- temp = armob->action;
- armob->action = result;
-
- for (curframe=1; curframe<ceil(actend+1.0f); curframe++){
-
- /* Apply the old action */
-
- G.scene->r.cfra = curframe;
-
- /* Apply the object ipo */
- extract_pose_from_action(armob->pose, act, curframe);
-
- where_is_pose(armob);
-
- /* For each channel: set quats and locs if channel is a bone */
- for (pchan=armob->pose->chanbase.first; pchan; pchan=pchan->next){
-
- /* Apply to keys */
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
- insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y);
- insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z);
- }
- }
-
-
- /* Make another pass to ensure all keyframes are set to linear interpolation mode */
- for (achan = result->chanbase.first; achan; achan=achan->next){
- IpoCurve* icu;
- if(achan->ipo) {
- for (icu = achan->ipo->curve.first; icu; icu=icu->next){
- icu->ipo= IPO_LIN;
- }
- }
- }
-
- notice ("Made a new action named \"%s\"", newname);
- G.scene->r.cfra = oldframe;
- armob->action = temp;
-
- /* restore */
- extract_pose_from_action(armob->pose, act, G.scene->r.cfra);
- where_is_pose(armob);
-
- allqueue(REDRAWACTION, 1);
-
- return result;
-}
-
-
-bAction* bake_obIPO_to_action (Object *ob)
-{
- bArmature *arm;
- bAction *result=NULL;
- bAction *temp;
- Bone *bone;
- ID *id;
- ListBase elems;
- int oldframe,testframe;
- char newname[64];
- float quat[4],tmat[4][4],startpos[4][4];
- CfraElem *firstcfra, *lastcfra;
-
- arm = get_armature(ob);
-
- if (arm) {
-
- oldframe = CFRA;
- result = add_empty_action("Action");
- id = (ID *)ob;
-
- sprintf (newname, "TESTOBBAKE");
- rename_id(&result->id, newname);
-
- if(ob!=G.obedit) { // make sure object is not in edit mode
- if(ob->ipo) {
- /* convert the ipo to a list of 'current frame elements' */
-
- temp = ob->action;
- ob->action = result;
-
- elems.first= elems.last= NULL;
- make_cfra_list(ob->ipo, &elems);
- /* set the beginning armature location */
- firstcfra=elems.first;
- lastcfra=elems.last;
- CFRA=firstcfra->cfra;
-
- where_is_object(ob);
- Mat4CpyMat4(startpos,ob->obmat);
-
- /* loop from first key to last, sampling every 10 */
- for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) {
- CFRA=testframe;
- where_is_object(ob);
-
- for (bone = arm->bonebase.first; bone; bone=bone->next) {
- if (!bone->parent) { /* this is a root bone, so give it a key! */
- world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
- Mat4ToQuat(tmat,quat);
- printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);
- }
- }
- }
- BLI_freelistN(&elems);
- }
- }
- CFRA = oldframe;
- }
- return result;
-}
-
-bAction *bake_everything_to_action (Object *ob)
-{
- bArmature *arm;
- bAction *result=NULL;
- bAction *temp;
- Bone *bone;
- ID *id;
- ListBase elems;
- int oldframe,testframe;
- char newname[64];
- float quat[4],tmat[4][4],startpos[4][4];
- CfraElem *firstcfra, *lastcfra;
-
- arm = get_armature(ob);
-
- if (arm) {
- oldframe = CFRA;
- result = add_empty_action("Action");
- id = (ID *)ob;
-
- sprintf (newname, "TESTOBBAKE");
- rename_id(&result->id, newname);
-
- if(ob!=G.obedit) { // make sure object is not in edit mode
- if(ob->ipo) {
- /* convert the ipo to a list of 'current frame elements' */
-
- temp = ob->action;
- ob->action = result;
-
- elems.first= elems.last= NULL;
- make_cfra_list(ob->ipo, &elems);
- /* set the beginning armature location */
- firstcfra=elems.first;
- lastcfra=elems.last;
- CFRA=firstcfra->cfra;
-
- where_is_object(ob);
- Mat4CpyMat4(startpos,ob->obmat);
-
- /* loop from first key to last, sampling every 10 */
- for (testframe = firstcfra->cfra; testframe<=lastcfra->cfra; testframe=testframe+10) {
- CFRA=testframe;
-
- do_all_pose_actions(ob);
- where_is_object(ob);
- for (bone = arm->bonebase.first; bone; bone=bone->next) {
- if (!bone->parent) { /* this is a root bone, so give it a key! */
- world2bonespace(tmat,ob->obmat,bone->arm_mat,startpos);
-
- Mat4ToQuat(tmat,quat);
- printf("Frame: %i %f, %f, %f, %f\n",CFRA,quat[0],quat[1],quat[2],quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_X,tmat[3][0]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Y,tmat[3][1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_LOC_Z,tmat[3][2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_X,quat[1]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Y,quat[2]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_Z,quat[3]);
- insertmatrixkey(id, ID_PO, bone->name, NULL, AC_QUAT_W,quat[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_X,size[0]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Y,size[1]);
- //insertmatrixkey(id, ID_PO, bone->name, NULL, AC_SIZE_Z,size[2]);
- }
- }
- }
- BLI_freelistN(&elems);
- }
- }
- CFRA = oldframe;
- }
- return result;
-}
+/* **************************************************** */
diff --git a/source/blender/src/editipo_mods.c b/source/blender/src/editipo_mods.c
index fe88d2da3c0..b8102aa0704 100644
--- a/source/blender/src/editipo_mods.c
+++ b/source/blender/src/editipo_mods.c
@@ -496,21 +496,40 @@ static int vis_edit_icu_bez(EditIpo *ei)
void select_ipo_bezier_keys(Ipo *ipo, int selectmode)
{
- /* Select all of the beziers in all
- * of the Ipo curves belonging to the
- * Ipo, using the selection mode.
- */
- switch (selectmode) {
- case SELECT_ADD:
- ipo_keys_bezier_loop(ipo, select_bezier_add, NULL);
- break;
- case SELECT_SUBTRACT:
- ipo_keys_bezier_loop(ipo, select_bezier_subtract, NULL);
- break;
- case SELECT_INVERT:
- ipo_keys_bezier_loop(ipo, select_bezier_invert, NULL);
- break;
- }
+ /* Select all of the beziers in all
+ * of the Ipo curves belonging to the
+ * Ipo, using the selection mode.
+ */
+ switch (selectmode) {
+ case SELECT_ADD:
+ ipo_keys_bezier_loop(ipo, select_bezier_add, NULL);
+ break;
+ case SELECT_SUBTRACT:
+ ipo_keys_bezier_loop(ipo, select_bezier_subtract, NULL);
+ break;
+ case SELECT_INVERT:
+ ipo_keys_bezier_loop(ipo, select_bezier_invert, NULL);
+ break;
+ }
+}
+
+void select_icu_bezier_keys(IpoCurve *icu, int selectmode)
+{
+ /* Select all of the beziers in all
+ * of the Ipo curves belonging to the
+ * Ipo, using the selection mode.
+ */
+ switch (selectmode) {
+ case SELECT_ADD:
+ icu_keys_bezier_loop(icu, select_bezier_add, NULL);
+ break;
+ case SELECT_SUBTRACT:
+ icu_keys_bezier_loop(icu, select_bezier_subtract, NULL);
+ break;
+ case SELECT_INVERT:
+ icu_keys_bezier_loop(icu, select_bezier_invert, NULL);
+ break;
+ }
}
void sethandles_ipo_keys(Ipo *ipo, int code)
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 73eea2b5aa4..16952df953c 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -2199,7 +2199,8 @@ void bake_all_to_action(void)
ob = get_object_from_active_strip();
if (ob) {
if (ob->flag&OB_ARMATURE) {
- newAction = bake_obIPO_to_action(ob);
+ //newAction = bake_obIPO_to_action(ob);
+ newAction = NULL;
if (newAction) {
/* unlink the object's IPO */
ipo=ob->ipo;
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index 14a62d67231..340a8008883 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -149,10 +149,7 @@ void do_action_buttons(unsigned short event)
{
Object *ob= OBACT;
- switch(event){
- case B_ACTBAKE:
- bake_action_with_client(G.saction->action, ob, 0.01);
- break;
+ switch(event) {
case B_ACTHOME:
/* Find X extents */
G.v2d->cur.xmin = 0;
@@ -362,6 +359,7 @@ static void do_action_selectmenu_columnmenu(void *arg, int event)
act = saction->action;
key = get_action_mesh_key();
+#if 0 // actionrewite
if (event == ACTMENU_SEL_COLUMN_MARKERSBETWEEN) {
markers_selectkeys_between();
}
@@ -373,6 +371,7 @@ static void do_action_selectmenu_columnmenu(void *arg, int event)
}
else
return;
+#endif // actionrewite
allqueue(REDRAWTIME, 0);
allqueue(REDRAWIPO, 0);
@@ -422,12 +421,7 @@ static void do_action_selectmenu(void *arg, int event)
switch(event)
{
case ACTMENU_SEL_BORDER: /* Border Select */
- if (act) {
- borderselect_action();
- }
- else if (key) {
- borderselect_mesh(key);
- }
+ borderselect_action();
break;
case ACTMENU_SEL_BORDERM: /* Border Select */
@@ -435,22 +429,14 @@ static void do_action_selectmenu(void *arg, int event)
break;
case ACTMENU_SEL_ALL_KEYS: /* Select/Deselect All Keys */
- if (act) {
- deselect_actionchannel_keys (act, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (key) {
- deselect_meshchannel_keys(key, 1, 1);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
+ deselect_action_keys(1, 1);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
break;
case ACTMENU_SEL_ALL_CHAN: /* Select/Deselect All Channels */
- deselect_actionchannels(act, 1);
+ deselect_action_channels(1);
allqueue (REDRAWVIEW3D, 0);
allqueue (REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
@@ -467,18 +453,10 @@ static void do_action_selectmenu(void *arg, int event)
break;
case ACTMENU_SEL_INVERSE_KEYS: /* invert selection status of keys */
- if (act) {
- deselect_actionchannel_keys(act, 0, 2);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
- else if (key) {
- deselect_meshchannel_keys(key, 0, 2);
- allqueue (REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue (REDRAWIPO, 0);
- }
+ deselect_action_keys(0, 2);
+ allqueue (REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue (REDRAWIPO, 0);
break;
case ACTMENU_SEL_INVERSE_MARKERS: /* invert selection of markers */
@@ -558,42 +536,17 @@ static uiBlock *action_selectmenu(void *arg_unused)
}
static void do_action_keymenu_transformmenu(void *arg, int event)
-{
- SpaceAction *saction;
- bAction *act;
- Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- key = get_action_mesh_key();
-
+{
switch (event)
{
case ACTMENU_KEY_TRANSFORM_MOVE:
- if (act) {
- transform_actionchannel_keys ('g', 0);
- }
- else if (key) {
- transform_meshchannel_keys('g', key);
- }
+ transform_action_keys('g', 0);
break;
case ACTMENU_KEY_TRANSFORM_SCALE:
- if (act) {
- transform_actionchannel_keys ('s', 0);
- }
- else if (key) {
- transform_meshchannel_keys('s', key);
- }
+ transform_action_keys ('s', 0);
break;
case ACTMENU_KEY_TRANSFORM_SLIDE:
- if (act) {
- transform_actionchannel_keys ('t', 0);
- }
- else if (key) {
- //transform_meshchannel_keys('t', key);
- }
+ transform_action_keys ('t', 0);
break;
}
@@ -628,24 +581,9 @@ static uiBlock *action_keymenu_transformmenu(void *arg_unused)
static void do_action_keymenu_handlemenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- key = get_action_mesh_key();
-
switch (event) {
case ACTMENU_KEY_HANDLE_AUTO:
- if (act) {
- sethandles_actionchannel_keys(HD_AUTO);
- }
- else if (key) {
- sethandles_meshchannel_keys(HD_AUTO, key);
- }
+ sethandles_action_keys(HD_AUTO);
break;
case ACTMENU_KEY_HANDLE_ALIGN:
@@ -653,21 +591,11 @@ static void do_action_keymenu_handlemenu(void *arg, int event)
/* OK, this is kinda dumb, need to fix the
* toggle crap in sethandles_ipo_keys()
*/
- if (act) {
- sethandles_actionchannel_keys(HD_ALIGN);
- }
- else if (key) {
- sethandles_meshchannel_keys(HD_ALIGN, key);
- }
+ sethandles_action_keys(HD_ALIGN);
break;
case ACTMENU_KEY_HANDLE_VECTOR:
- if (act) {
- sethandles_actionchannel_keys(HD_VECT);
- }
- else if (key) {
- sethandles_meshchannel_keys(HD_VECT, key);
- }
+ sethandles_action_keys(HD_VECT);
break;
}
}
@@ -705,32 +633,16 @@ static uiBlock *action_keymenu_handlemenu(void *arg_unused)
static void do_action_keymenu_intpolmenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- //Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- //key = get_action_mesh_key();
-
switch(event)
{
case ACTMENU_KEY_INTERP_CONST:
- if (act)
- set_ipotype_actionchannels(SET_IPO_CONSTANT);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_IPO_CONSTANT);
break;
case ACTMENU_KEY_INTERP_LINEAR:
- if (act)
- set_ipotype_actionchannels(SET_IPO_LINEAR);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_IPO_LINEAR);
break;
case ACTMENU_KEY_INTERP_BEZIER:
- if (act)
- set_ipotype_actionchannels(SET_IPO_BEZIER);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_IPO_BEZIER);
break;
}
@@ -767,37 +679,19 @@ static uiBlock *action_keymenu_intpolmenu(void *arg_unused)
static void do_action_keymenu_extendmenu(void *arg, int event)
{
- SpaceAction *saction;
- bAction *act;
- //Key *key;
-
- saction = curarea->spacedata.first;
- if (!saction) return;
-
- act = saction->action;
- //key = get_action_mesh_key();
-
switch(event)
{
case ACTMENU_KEY_EXTEND_CONST:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_CONSTANT);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_CONSTANT);
break;
case ACTMENU_KEY_EXTEND_EXTRAPOLATION:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_EXTRAPOLATION);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_EXTRAPOLATION);
break;
case ACTMENU_KEY_EXTEND_CYCLIC:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_CYCLIC);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_CYCLIC);
break;
case ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION:
- if (act)
- set_extendtype_actionchannels(SET_EXTEND_CYCLICEXTRAPOLATION);
- //else if (key) /* todo */
+ action_set_ipo_flags(SET_EXTEND_CYCLICEXTRAPOLATION);
break;
}
@@ -900,7 +794,7 @@ static void do_action_keymenu_snapmenu(void *arg, int event)
case ACTMENU_KEY_SNAP_NEARFRAME:
case ACTMENU_KEY_SNAP_CURFRAME:
case ACTMENU_KEY_SNAP_NEARMARK:
- snap_keys_to_frame(event);
+ snap_action_keys(event);
break;
}
@@ -995,31 +889,13 @@ static void do_action_keymenu(void *arg, int event)
switch(event)
{
case ACTMENU_KEY_DUPLICATE:
- if (act) {
- duplicate_actionchannel_keys();
- remake_action_ipos(act);
- }
- else if (key) {
- duplicate_meshchannel_keys(key);
- }
+ duplicate_action_keys();
break;
-
case ACTMENU_KEY_DELETE:
- if (act) {
- delete_actionchannel_keys ();
- }
- else if (key) {
- delete_meshchannel_keys(key);
- }
- break;
- case ACTMENU_KEY_BAKE:
- bake_action_with_client(G.saction->action, OBACT, 0.01);
+ delete_action_keys ();
break;
case ACTMENU_KEY_CLEAN:
- if (act)
- clean_actionchannels(act);
- else if (key)
- clean_shapekeys(key);
+ clean_action();
break;
}
}
@@ -1062,11 +938,6 @@ static uiBlock *action_keymenu(void *arg_unused)
"Clean Action|O", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_CLEAN, "");
-
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Bake Action to Ipo Keys", 0, yco-=20,
- menuwidth, 19, NULL, 0.0, 0.0, 0,
- ACTMENU_KEY_BAKE, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -1261,16 +1132,6 @@ void action_buttons(void)
from, &(G.saction->actnr), B_ACTALONE,
B_ACTLOCAL, B_ACTIONDELETE, 0, 0);
-
- /* Draw action baker */
- xco+= 8;
-
- uiDefBut(block, BUT, B_ACTBAKE,
- "Bake", xco, 0, 64, YIC, 0, 0, 0, 0, 0,
- "Create an action with the constraint effects "
- "converted into Ipo keys");
- xco+=64;
-
uiClearButLock();
/* draw AUTOSNAP */