2008-12-27 11:44:00 +00:00
|
|
|
/**
|
2009-06-23 00:09:26 +00:00
|
|
|
* $Id$
|
2008-12-27 11:44:00 +00:00
|
|
|
*
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2008-12-27 11:44:00 +00:00
|
|
|
*
|
|
|
|
* 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): Joshua Leung
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
2009-05-08 10:50:32 +00:00
|
|
|
#include "RNA_enum_types.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
#include "BKE_action.h"
|
|
|
|
#include "BKE_depsgraph.h"
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
#include "BKE_fcurve.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
#include "BKE_key.h"
|
|
|
|
#include "BKE_material.h"
|
2009-06-23 13:25:31 +00:00
|
|
|
#include "BKE_nla.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
#include "BKE_object.h"
|
|
|
|
#include "BKE_context.h"
|
2009-02-24 11:23:04 +00:00
|
|
|
#include "BKE_report.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
|
|
|
|
#include "UI_view2d.h"
|
|
|
|
|
|
|
|
#include "ED_anim_api.h"
|
|
|
|
#include "ED_keyframing.h"
|
|
|
|
#include "ED_keyframes_edit.h"
|
|
|
|
#include "ED_screen.h"
|
2009-07-08 16:17:47 +00:00
|
|
|
#include "ED_transform.h"
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
2009-10-01 23:32:57 +00:00
|
|
|
#include "UI_interface.h"
|
|
|
|
|
2008-12-27 11:44:00 +00:00
|
|
|
#include "action_intern.h"
|
|
|
|
|
2.5 - Assorted Animation UI/Editing Tweaks
Main Feature:
* It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.)
* Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying.
* Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region.
--> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen...
--> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors...
Other tweaks:
* Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon
* Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though.
* Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too.
* Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
2009-09-27 04:22:04 +00:00
|
|
|
/* ************************************************************************** */
|
|
|
|
/* ACTION MANAGEMENT */
|
|
|
|
|
|
|
|
/* ******************** New Action Operator *********************** */
|
|
|
|
|
|
|
|
static int act_new_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAction *action;
|
2009-10-01 23:32:57 +00:00
|
|
|
PointerRNA ptr, idptr;
|
|
|
|
PropertyRNA *prop;
|
2.5 - Assorted Animation UI/Editing Tweaks
Main Feature:
* It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.)
* Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying.
* Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region.
--> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen...
--> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors...
Other tweaks:
* Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon
* Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though.
* Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too.
* Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
2009-09-27 04:22:04 +00:00
|
|
|
|
|
|
|
// XXX need to restore behaviour to copy old actions...
|
|
|
|
action= add_empty_action("Action");
|
|
|
|
|
2009-10-01 23:32:57 +00:00
|
|
|
/* hook into UI */
|
|
|
|
uiIDContextProperty(C, &ptr, &prop);
|
|
|
|
|
|
|
|
if(prop) {
|
|
|
|
/* when creating new ID blocks, use is already 1, but RNA
|
|
|
|
* pointer se also increases user, so this compensates it */
|
|
|
|
action->id.us--;
|
|
|
|
|
|
|
|
RNA_id_pointer_create(&action->id, &idptr);
|
|
|
|
RNA_property_pointer_set(&ptr, prop, idptr);
|
|
|
|
RNA_property_update(C, &ptr, prop);
|
|
|
|
}
|
|
|
|
|
2.5 - Assorted Animation UI/Editing Tweaks
Main Feature:
* It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.)
* Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying.
* Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region.
--> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen...
--> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors...
Other tweaks:
* Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon
* Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though.
* Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too.
* Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
2009-09-27 04:22:04 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2.5 - Assorted Animation UI/Editing Tweaks
Main Feature:
* It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.)
* Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying.
* Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region.
--> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen...
--> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors...
Other tweaks:
* Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon
* Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though.
* Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too.
* Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
2009-09-27 04:22:04 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_new (wmOperatorType *ot)
|
2.5 - Assorted Animation UI/Editing Tweaks
Main Feature:
* It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.)
* Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying.
* Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region.
--> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen...
--> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors...
Other tweaks:
* Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon
* Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though.
* Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too.
* Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
2009-09-27 04:22:04 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "New";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_new";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Create new action";
|
2.5 - Assorted Animation UI/Editing Tweaks
Main Feature:
* It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.)
* Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying.
* Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region.
--> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen...
--> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors...
Other tweaks:
* Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon
* Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though.
* Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too.
* Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
2009-09-27 04:22:04 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= act_new_exec;
|
|
|
|
// NOTE: this is used in the NLA too...
|
|
|
|
//ot->poll= ED_operator_action_active;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
}
|
|
|
|
|
2009-01-01 01:47:36 +00:00
|
|
|
/* ************************************************************************** */
|
|
|
|
/* KEYFRAME-RANGE STUFF */
|
|
|
|
|
|
|
|
/* *************************** Calculate Range ************************** */
|
|
|
|
|
|
|
|
/* Get the min/max keyframes*/
|
|
|
|
static void get_keyframe_extents (bAnimContext *ac, float *min, float *max)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* get data to filter, from Action or Dopesheet */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
/* set large values to try to override */
|
|
|
|
*min= 999999999.0f;
|
|
|
|
*max= -999999999.0f;
|
|
|
|
|
|
|
|
/* check if any channels to set range with */
|
|
|
|
if (anim_data.first) {
|
2009-01-03 06:01:11 +00:00
|
|
|
/* go through channels, finding max extents */
|
2009-01-01 01:47:36 +00:00
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-01-20 11:56:45 +00:00
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
2009-01-01 01:47:36 +00:00
|
|
|
float tmin, tmax;
|
|
|
|
|
|
|
|
/* get range and apply necessary scaling before */
|
2009-01-20 11:56:45 +00:00
|
|
|
calc_fcurve_range(fcu, &tmin, &tmax);
|
2009-01-01 01:47:36 +00:00
|
|
|
|
2009-06-23 13:25:31 +00:00
|
|
|
if (adt) {
|
2009-06-28 07:32:00 +00:00
|
|
|
tmin= BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);
|
|
|
|
tmax= BKE_nla_tweakedit_remap(adt, tmax, NLATIME_CONVERT_MAP);
|
2009-01-01 01:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* try to set cur using these values, if they're more extreme than previously set values */
|
|
|
|
*min= MIN2(*min, tmin);
|
|
|
|
*max= MAX2(*max, tmax);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free memory */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* set default range */
|
|
|
|
if (ac->scene) {
|
|
|
|
*min= (float)ac->scene->r.sfra;
|
|
|
|
*max= (float)ac->scene->r.efra;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
*min= -5;
|
|
|
|
*max= 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ****************** Automatic Preview-Range Operator ****************** */
|
|
|
|
|
|
|
|
static int actkeys_previewrange_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
Scene *scene;
|
|
|
|
float min, max;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.scene == NULL)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
else
|
|
|
|
scene= ac.scene;
|
|
|
|
|
|
|
|
/* set the range directly */
|
|
|
|
get_keyframe_extents(&ac, &min, &max);
|
2010-01-19 20:30:04 +00:00
|
|
|
scene->r.flag |= SCER_PRV_RANGE;
|
2009-01-01 01:47:36 +00:00
|
|
|
scene->r.psfra= (int)floor(min + 0.5f);
|
|
|
|
scene->r.pefra= (int)floor(max + 0.5f);
|
|
|
|
|
2009-01-05 09:54:39 +00:00
|
|
|
/* set notifier that things have changed */
|
|
|
|
// XXX err... there's nothing for frame ranges yet, but this should do fine too
|
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, ac.scene);
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_previewrange_set (wmOperatorType *ot)
|
2009-01-01 01:47:36 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Auto-Set Preview Range";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_previewrange_set";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Set Preview Range based on extents of selected Keyframes";
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= actkeys_previewrange_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-01 01:47:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ****************** View-All Operator ****************** */
|
|
|
|
|
|
|
|
static int actkeys_viewall_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
View2D *v2d;
|
|
|
|
float extra;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
v2d= &ac.ar->v2d;
|
|
|
|
|
|
|
|
/* set the horizontal range, with an extra offset so that the extreme keys will be in view */
|
|
|
|
get_keyframe_extents(&ac, &v2d->cur.xmin, &v2d->cur.xmax);
|
|
|
|
|
2009-02-09 04:47:34 +00:00
|
|
|
extra= 0.1f * (v2d->cur.xmax - v2d->cur.xmin);
|
2009-01-01 01:47:36 +00:00
|
|
|
v2d->cur.xmin -= extra;
|
|
|
|
v2d->cur.xmax += extra;
|
|
|
|
|
|
|
|
/* set vertical range */
|
|
|
|
v2d->cur.ymax= 0.0f;
|
2009-01-02 06:03:53 +00:00
|
|
|
v2d->cur.ymin= (float)-(v2d->mask.ymax - v2d->mask.ymin);
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
/* do View2D syncing */
|
|
|
|
UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* just redraw this view */
|
2009-01-05 09:54:39 +00:00
|
|
|
ED_area_tag_redraw(CTX_wm_area(C));
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_view_all (wmOperatorType *ot)
|
2009-01-01 01:47:36 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "View All";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_view_all";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Reset viewable area to show full keyframe range";
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= actkeys_viewall_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2009-01-01 01:47:36 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2009-01-01 01:47:36 +00:00
|
|
|
}
|
|
|
|
|
2008-12-27 11:44:00 +00:00
|
|
|
/* ************************************************************************** */
|
|
|
|
/* GENERAL STUFF */
|
|
|
|
|
2008-12-29 11:04:55 +00:00
|
|
|
/* ******************** Copy/Paste Keyframes Operator ************************* */
|
2009-02-24 11:18:24 +00:00
|
|
|
/* NOTE: the backend code for this is shared with the graph editor */
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
static short copy_action_keys (bAnimContext *ac)
|
2009-01-22 10:53:22 +00:00
|
|
|
{
|
2008-12-29 11:04:55 +00:00
|
|
|
ListBase anim_data = {NULL, NULL};
|
2009-02-24 11:18:24 +00:00
|
|
|
int filter, ok=0;
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* clear buffer first */
|
2009-02-24 11:18:24 +00:00
|
|
|
free_anim_copybuf();
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-29 11:04:55 +00:00
|
|
|
|
2009-02-24 11:18:24 +00:00
|
|
|
/* copy keyframes */
|
|
|
|
ok= copy_animedit_keys(ac, &anim_data);
|
2008-12-29 11:04:55 +00:00
|
|
|
|
2009-02-24 11:18:24 +00:00
|
|
|
/* clean up */
|
2008-12-29 11:04:55 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
2009-02-24 16:51:55 +00:00
|
|
|
|
|
|
|
return ok;
|
2008-12-29 11:04:55 +00:00
|
|
|
}
|
|
|
|
|
2009-02-24 11:18:24 +00:00
|
|
|
|
2008-12-29 11:04:55 +00:00
|
|
|
static short paste_action_keys (bAnimContext *ac)
|
2009-02-24 11:18:24 +00:00
|
|
|
{
|
2008-12-29 11:04:55 +00:00
|
|
|
ListBase anim_data = {NULL, NULL};
|
2009-02-24 11:18:24 +00:00
|
|
|
int filter, ok=0;
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-29 11:04:55 +00:00
|
|
|
|
2009-02-24 11:18:24 +00:00
|
|
|
/* paste keyframes */
|
|
|
|
ok= paste_animedit_keys(ac, &anim_data);
|
2008-12-29 11:04:55 +00:00
|
|
|
|
2009-02-24 11:18:24 +00:00
|
|
|
/* clean up */
|
2008-12-29 11:04:55 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
2009-02-24 16:51:55 +00:00
|
|
|
|
|
|
|
return ok;
|
2008-12-29 11:04:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_copy_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* copy keyframes */
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL) {
|
|
|
|
// FIXME...
|
|
|
|
}
|
|
|
|
else {
|
2008-12-30 10:10:44 +00:00
|
|
|
if (copy_action_keys(&ac)) {
|
2009-02-24 11:23:04 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "No keyframes copied to keyframes copy/paste buffer");
|
|
|
|
return OPERATOR_CANCELLED;
|
2008-12-29 11:04:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_copy (wmOperatorType *ot)
|
2008-12-29 11:04:55 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Copy Keyframes";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_copy";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Copy selected keyframes to the copy/paste buffer";
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= actkeys_copy_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-29 11:04:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int actkeys_paste_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* paste keyframes */
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL) {
|
|
|
|
// FIXME...
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (paste_action_keys(&ac)) {
|
2009-02-24 11:23:04 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "No keyframes to paste");
|
|
|
|
return OPERATOR_CANCELLED;
|
2008-12-29 11:04:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_paste (wmOperatorType *ot)
|
2008-12-29 11:04:55 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Paste Keyframes";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_paste";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Paste keyframes from copy/paste buffer for the selected channels, starting on the current frame";
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= actkeys_paste_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-29 11:04:55 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-29 11:04:55 +00:00
|
|
|
}
|
2008-12-28 11:51:41 +00:00
|
|
|
|
2009-02-21 05:04:12 +00:00
|
|
|
/* ******************** Insert Keyframes Operator ************************* */
|
|
|
|
|
|
|
|
/* defines for insert keyframes tool */
|
|
|
|
EnumPropertyItem prop_actkeys_insertkey_types[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{1, "ALL", 0, "All Channels", ""},
|
|
|
|
{2, "SEL", 0, "Only Selected Channels", ""},
|
|
|
|
{3, "GROUP", 0, "In Active Group", ""}, // xxx not in all cases
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2009-02-21 05:04:12 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* this function is responsible for snapping keyframes to frame-times */
|
|
|
|
static void insert_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
Scene *scene= ac->scene;
|
|
|
|
float cfra= (float)CFRA;
|
|
|
|
short flag = 0;
|
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-02-21 05:04:12 +00:00
|
|
|
if (mode == 2) filter |= ANIMFILTER_SEL;
|
|
|
|
else if (mode == 3) filter |= ANIMFILTER_ACTGROUPED;
|
|
|
|
|
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* init keyframing flag */
|
2009-12-14 12:09:20 +00:00
|
|
|
flag = ANIM_get_keyframing_flags(scene, 1);
|
2009-02-21 05:04:12 +00:00
|
|
|
|
|
|
|
/* insert keyframes */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-02-21 05:04:12 +00:00
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
|
|
|
|
|
|
|
/* adjust current frame for NLA-scaling */
|
2009-06-23 13:25:31 +00:00
|
|
|
if (adt)
|
2009-06-28 07:32:00 +00:00
|
|
|
cfra= BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
|
2009-06-23 13:25:31 +00:00
|
|
|
else
|
|
|
|
cfra= (float)CFRA;
|
2009-02-21 05:04:12 +00:00
|
|
|
|
|
|
|
/* if there's an id */
|
|
|
|
if (ale->id)
|
2009-04-15 01:10:36 +00:00
|
|
|
insert_keyframe(ale->id, NULL, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
|
2009-02-21 05:04:12 +00:00
|
|
|
else
|
|
|
|
insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_insertkey_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
2009-06-29 03:02:41 +00:00
|
|
|
/* what channels to affect? */
|
2009-02-21 05:04:12 +00:00
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
2009-06-29 03:02:41 +00:00
|
|
|
/* insert keyframes */
|
2009-02-21 05:04:12 +00:00
|
|
|
insert_action_keys(&ac, mode);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2009-02-21 05:04:12 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-12-31 23:56:45 +00:00
|
|
|
void ACTION_OT_keyframe_insert (wmOperatorType *ot)
|
2009-02-21 05:04:12 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Insert Keyframes";
|
2009-12-31 23:56:45 +00:00
|
|
|
ot->idname= "ACTION_OT_keyframe_insert";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Insert keyframes for the specified channels";
|
2009-02-21 05:04:12 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_insertkey_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2009-02-21 05:04:12 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* id-props */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", prop_actkeys_insertkey_types, 0, "Type", "");
|
2009-02-21 05:04:12 +00:00
|
|
|
}
|
|
|
|
|
2009-02-20 11:17:33 +00:00
|
|
|
/* ******************** Duplicate Keyframes Operator ************************* */
|
|
|
|
|
|
|
|
static void duplicate_action_keys (bAnimContext *ac)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
if (ac->datatype == ANIMCONT_GPENCIL)
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
|
2009-02-20 11:17:33 +00:00
|
|
|
else
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-02-20 11:17:33 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* loop through filtered data and delete selected keys */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
//if (ale->type == ANIMTYPE_GPLAYER)
|
|
|
|
// delete_gplayer_frames((bGPDlayer *)ale->data);
|
|
|
|
//else
|
|
|
|
duplicate_fcurve_keys((FCurve *)ale->key_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free filtered list */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_duplicate_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* duplicate keyframes */
|
|
|
|
duplicate_action_keys(&ac);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2009-02-20 11:17:33 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED; // xxx - start transform
|
|
|
|
}
|
|
|
|
|
|
|
|
static int actkeys_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
|
|
|
actkeys_duplicate_exec(C, op);
|
|
|
|
|
|
|
|
RNA_int_set(op->ptr, "mode", TFM_TIME_TRANSLATE);
|
2009-12-10 10:36:32 +00:00
|
|
|
WM_operator_name_call(C, "TRANSFORM_OT_transform", WM_OP_INVOKE_REGION_WIN, op->ptr);
|
2009-02-20 11:17:33 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_duplicate (wmOperatorType *ot)
|
2009-02-20 11:17:33 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Duplicate Keyframes";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_duplicate";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Make a copy of all selected keyframes";
|
2009-02-20 11:17:33 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= actkeys_duplicate_invoke;
|
|
|
|
ot->exec= actkeys_duplicate_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2009-02-20 11:17:33 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* to give to transform */
|
|
|
|
RNA_def_int(ot->srna, "mode", TFM_TIME_TRANSLATE, 0, INT_MAX, "Mode", "", 0, INT_MAX);
|
|
|
|
}
|
|
|
|
|
2008-12-29 01:19:25 +00:00
|
|
|
/* ******************** Delete Keyframes Operator ************************* */
|
|
|
|
|
|
|
|
static void delete_action_keys (bAnimContext *ac)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
if (ac->datatype == ANIMCONT_GPENCIL)
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
|
2008-12-29 01:19:25 +00:00
|
|
|
else
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* loop through filtered data and delete selected keys */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-12-04 03:51:52 +00:00
|
|
|
if (ale->type != ANIMTYPE_GPLAYER) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
|
|
|
AnimData *adt= ale->adt;
|
|
|
|
|
|
|
|
/* delete selected keyframes only */
|
|
|
|
delete_fcurve_keys(fcu);
|
|
|
|
|
|
|
|
/* Only delete curve too if it won't be doing anything anymore */
|
|
|
|
if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
|
2009-12-06 09:37:31 +00:00
|
|
|
ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
|
2009-12-04 03:51:52 +00:00
|
|
|
}
|
2008-12-29 01:19:25 +00:00
|
|
|
//else
|
2009-12-04 03:51:52 +00:00
|
|
|
// delete_gplayer_frames((bGPDlayer *)ale->data);
|
2008-12-29 01:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* free filtered list */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_delete_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* delete keyframes */
|
|
|
|
delete_action_keys(&ac);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_delete (wmOperatorType *ot)
|
2008-12-29 01:19:25 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Delete Keyframes";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_delete";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Remove all selected keyframes";
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2009-01-28 09:55:36 +00:00
|
|
|
ot->invoke= WM_operator_confirm;
|
2008-12-29 01:19:25 +00:00
|
|
|
ot->exec= actkeys_delete_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-29 01:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Clean Keyframes Operator ************************* */
|
|
|
|
|
|
|
|
static void clean_action_keys (bAnimContext *ac, float thresh)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* loop through filtered data and clean curves */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next)
|
2.5: Blender "Animato" - New Animation System
Finally, here is the basic (functional) prototype of the new animation system which will allow for the infamous "everything is animatable", and which also addresses several of the more serious shortcomings of the old system. Unfortunately, this will break old animation files (especially right now, as I haven't written the version patching code yet), however, this is for the future.
Highlights of the new system:
* Scrapped IPO-Curves/IPO/(Action+Constraint-Channels)/Action system, and replaced it with F-Curve/Action.
- F-Curves (animators from other packages will feel at home with this name) replace IPO-Curves.
- The 'new' Actions, act as the containers for F-Curves, so that they can be reused. They are therefore more akin to the old 'IPO' blocks, except they do not have the blocktype restriction, so you can store materials/texture/geometry F-Curves in the same Action as Object transforms, etc.
* F-Curves use RNA-paths for Data Access, hence allowing "every" (where sensible/editable that is) user-accessible setting from RNA to be animated.
* Drivers are no longer mixed with Animation Data, so rigs will not be that easily broken and several dependency problems can be eliminated. (NOTE: drivers haven't been hooked up yet, but the code is in place)
* F-Curve modifier system allows useful 'large-scale' manipulation of F-Curve values, including (I've only included implemented ones here): envelope deform (similar to lattices to allow broad-scale reshaping of curves), curve generator (polynomial or py-expression), cycles (replacing the old cyclic extrapolation modes, giving more control over this). (NOTE: currently this cannot be tested, as there's not access to them, but the code is all in place)
* NLA system with 'tracks' (i.e. layers), and multiple strips per track. (NOTE: NLA system is not yet functional, as it's only partially coded still)
There are more nice things that I will be preparing some nice docs for soon, but for now, check for more details:
http://lists.blender.org/pipermail/bf-taskforce25/2009-January/000260.html
So, what currently works:
* I've implemented two basic operators for the 3D-view only to Insert and Delete Keyframes. These are tempolary ones only that will be replaced in due course with 'proper' code.
* Object Loc/Rot/Scale can be keyframed. Also, the colour of the 'active' material (Note: this should really be for nth material instead, but that doesn't work yet in RNA) can also be keyframed into the same datablock.
* Standard animation refresh (i.e. animation resulting from NLA and Action evaluation) is now done completely separate from drivers before anything else is done after a frame change. Drivers are handled after this in a separate pass, as dictated by depsgraph flags, etc.
Notes:
* Drivers haven't been hooked up yet
* Only objects and data directly linked to objects can be animated.
* Depsgraph will need further tweaks. Currently, I've only made sure that it will update some things in the most basic cases (i.e. frame change).
* Animation Editors are currently broken (in terms of editing stuff). This will be my next target (priority to get Dopesheet working first, then F-Curve editor - i.e. old IPO Editor)
* I've had to put in large chunks of XXX sandboxing for old animation system code all around the place. This will be cleaned up in due course, as some places need special review.
In particular, the particles and sequencer code have far too many manual calls to calculate + flush animation info, which is really bad (this is a 'please explain yourselves' call to Physics coders!).
2009-01-17 03:12:50 +00:00
|
|
|
clean_fcurve((FCurve *)ale->key_data, thresh);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* free temp data */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_clean_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
float thresh;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* get cleaning threshold */
|
|
|
|
thresh= RNA_float_get(op->ptr, "threshold");
|
|
|
|
|
|
|
|
/* clean keyframes */
|
|
|
|
clean_action_keys(&ac, thresh);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_clean (wmOperatorType *ot)
|
2008-12-29 01:19:25 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Clean Keyframes";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_clean";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Simplify F-Curves by removing closely spaced keyframes";
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
//ot->invoke= // XXX we need that number popup for this!
|
|
|
|
ot->exec= actkeys_clean_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* properties */
|
2010-02-07 23:39:44 +00:00
|
|
|
ot->prop= RNA_def_float(ot->srna, "threshold", 0.001f, 0.0f, FLT_MAX, "Threshold", "", 0.0f, 1000.0f);
|
2008-12-29 01:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Sample Keyframes Operator *********************** */
|
|
|
|
|
|
|
|
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
|
|
|
|
static void sample_action_keys (bAnimContext *ac)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* loop through filtered data and add keys between selected keyframes on every frame */
|
2009-09-04 04:27:06 +00:00
|
|
|
for (ale= anim_data.first; ale; ale= ale->next)
|
|
|
|
sample_fcurve((FCurve *)ale->key_data);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* admin and redraws */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_sample_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* sample keyframes */
|
|
|
|
sample_action_keys(&ac);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_sample (wmOperatorType *ot)
|
2008-12-29 01:19:25 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Sample Keyframes";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_sample";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Add keyframes on every frame between the selected keyframes";
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= actkeys_sample_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-29 01:19:25 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-29 01:19:25 +00:00
|
|
|
}
|
|
|
|
|
2008-12-27 11:44:00 +00:00
|
|
|
/* ************************************************************************** */
|
|
|
|
/* SETTINGS STUFF */
|
|
|
|
|
2008-12-28 11:51:41 +00:00
|
|
|
/* ******************** Set Extrapolation-Type Operator *********************** */
|
|
|
|
|
2009-01-02 11:06:27 +00:00
|
|
|
/* defines for set extrapolation-type for selected keyframes tool */
|
2008-12-28 11:51:41 +00:00
|
|
|
EnumPropertyItem prop_actkeys_expo_types[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""},
|
|
|
|
{FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2008-12-28 11:51:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* this function is responsible for setting extrapolation mode for keyframes */
|
|
|
|
static void setexpo_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-28 11:51:41 +00:00
|
|
|
|
2009-01-20 11:07:42 +00:00
|
|
|
/* loop through setting mode per F-Curve */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->data;
|
|
|
|
fcu->extend= mode;
|
|
|
|
}
|
2008-12-28 11:51:41 +00:00
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_expo_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* get handle setting mode */
|
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* set handle type */
|
|
|
|
setexpo_action_keys(&ac, mode);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframe properties have changed */
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
|
2008-12-28 11:51:41 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_extrapolation_type (wmOperatorType *ot)
|
2008-12-28 11:51:41 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Set Keyframe Extrapolation";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_extrapolation_type";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Set extrapolation mode for selected F-Curves";
|
2008-12-28 11:51:41 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_expo_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-28 11:51:41 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-28 11:51:41 +00:00
|
|
|
|
|
|
|
/* id-props */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", prop_actkeys_expo_types, 0, "Type", "");
|
2008-12-28 11:51:41 +00:00
|
|
|
}
|
|
|
|
|
2008-12-28 08:15:29 +00:00
|
|
|
/* ******************** Set Interpolation-Type Operator *********************** */
|
|
|
|
|
|
|
|
/* this function is responsible for setting interpolation mode for keyframes */
|
|
|
|
static void setipo_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc set_cb= ANIM_editkeyframes_ipo(mode);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
2008-12-28 11:51:41 +00:00
|
|
|
/* loop through setting BezTriple interpolation
|
2010-04-02 12:02:39 +00:00
|
|
|
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
|
2008-12-28 08:15:29 +00:00
|
|
|
*/
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next)
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, calchandles_fcurve);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_ipo_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* get handle setting mode */
|
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* set handle type */
|
|
|
|
setipo_action_keys(&ac, mode);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframe properties have changed */
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_interpolation_type (wmOperatorType *ot)
|
2008-12-28 08:15:29 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Set Keyframe Interpolation";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_interpolation_type";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Set interpolation mode for the F-Curve segments starting from the selected keyframes";
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_ipo_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* id-props */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", beztriple_interpolation_mode_items, 0, "Type", "");
|
2008-12-28 08:15:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Set Handle-Type Operator *********************** */
|
|
|
|
|
2010-02-01 11:45:24 +00:00
|
|
|
EnumPropertyItem actkeys_handle_type_items[] = {
|
|
|
|
{HD_FREE, "FREE", 0, "Free", ""},
|
|
|
|
{HD_VECT, "VECTOR", 0, "Vector", ""},
|
|
|
|
{HD_ALIGN, "ALIGNED", 0, "Aligned", ""},
|
2010-02-02 21:16:28 +00:00
|
|
|
{0, "", 0, "", ""},
|
|
|
|
{HD_AUTO, "AUTO", 0, "Auto", "Handles that are automatically adjusted upon moving the keyframe"},
|
|
|
|
{HD_AUTO_ANIM, "ANIM_CLAMPED", 0, "Auto Clamped", "Auto handles clamped to not overshoot"},
|
2010-02-01 11:45:24 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}};
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
2008-12-28 08:15:29 +00:00
|
|
|
/* this function is responsible for setting handle-type of selected keyframes */
|
|
|
|
static void sethandles_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
2010-02-02 21:16:28 +00:00
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc edit_cb= ANIM_editkeyframes_handles(mode);
|
|
|
|
KeyframeEditFunc sel_cb= ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* loop through setting flags for handles
|
2010-04-02 12:02:39 +00:00
|
|
|
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
|
2008-12-28 08:15:29 +00:00
|
|
|
*/
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2010-02-02 21:16:28 +00:00
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
2010-02-01 11:45:24 +00:00
|
|
|
|
2010-02-02 21:16:28 +00:00
|
|
|
/* any selected keyframes for editing? */
|
2010-04-02 12:02:39 +00:00
|
|
|
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL)) {
|
2010-02-02 21:16:28 +00:00
|
|
|
/* for auto/auto-clamped, toggle the auto-handles flag on the F-Curve */
|
|
|
|
if (mode == HD_AUTO_ANIM)
|
|
|
|
fcu->flag |= FCURVE_AUTO_HANDLES;
|
|
|
|
else if (mode == HD_AUTO)
|
|
|
|
fcu->flag &= ~FCURVE_AUTO_HANDLES;
|
2008-12-28 08:15:29 +00:00
|
|
|
|
2010-02-02 21:16:28 +00:00
|
|
|
/* change type of selected handles */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, edit_cb, calchandles_fcurve);
|
2010-02-02 21:16:28 +00:00
|
|
|
}
|
2008-12-28 08:15:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_handletype_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* get handle setting mode */
|
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* set handle type */
|
2010-02-02 21:16:28 +00:00
|
|
|
sethandles_action_keys(&ac, mode);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframe properties have changed */
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_handle_type (wmOperatorType *ot)
|
2008-12-28 08:15:29 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Set Keyframe Handle Type";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_handle_type";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Set type of handle for selected keyframes";
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_handletype_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-28 08:15:29 +00:00
|
|
|
|
|
|
|
/* id-props */
|
2010-02-01 11:45:24 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", actkeys_handle_type_items, 0, "Type", "");
|
2008-12-28 08:15:29 +00:00
|
|
|
}
|
|
|
|
|
2009-09-04 02:44:56 +00:00
|
|
|
/* ******************** Set Keyframe-Type Operator *********************** */
|
|
|
|
|
|
|
|
/* this function is responsible for setting interpolation mode for keyframes */
|
|
|
|
static void setkeytype_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc set_cb= ANIM_editkeyframes_keytype(mode);
|
2009-09-04 02:44:56 +00:00
|
|
|
|
|
|
|
/* filter data */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-09-04 02:44:56 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* loop through setting BezTriple interpolation
|
2010-04-02 12:02:39 +00:00
|
|
|
* Note: we do not supply KeyframeEditData to the looper yet. Currently that's not necessary here...
|
2009-09-04 02:44:56 +00:00
|
|
|
*/
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next)
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(NULL, ale->key_data, NULL, set_cb, NULL);
|
2009-09-04 02:44:56 +00:00
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_keytype_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
if (ac.datatype == ANIMCONT_GPENCIL)
|
|
|
|
return OPERATOR_PASS_THROUGH;
|
|
|
|
|
|
|
|
/* get handle setting mode */
|
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* set handle type */
|
|
|
|
setkeytype_action_keys(&ac, mode);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
|
|
|
/* set notifier that keyframe properties have changed */
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_keyframe_type (wmOperatorType *ot)
|
2009-09-04 02:44:56 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Set Keyframe Type";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_keyframe_type";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Set type of keyframe for the seleced keyframes";
|
2009-09-04 02:44:56 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_keytype_exec;
|
|
|
|
ot->poll= ED_operator_action_active;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* id-props */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", beztriple_keyframe_type_items, 0, "Type", "");
|
2009-09-04 02:44:56 +00:00
|
|
|
}
|
|
|
|
|
2008-12-27 11:44:00 +00:00
|
|
|
/* ************************************************************************** */
|
|
|
|
/* TRANSFORM STUFF */
|
|
|
|
|
2009-06-22 03:26:36 +00:00
|
|
|
/* ***************** Jump to Selected Frames Operator *********************** */
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* snap current-frame indicator to 'average time' of selected keyframe */
|
2009-06-22 03:26:36 +00:00
|
|
|
static int actkeys_framejump_exec(bContext *C, wmOperator *op)
|
2008-12-27 11:44:00 +00:00
|
|
|
{
|
|
|
|
bAnimContext ac;
|
2008-12-28 04:13:18 +00:00
|
|
|
ListBase anim_data= {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditData ked;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
2008-12-28 04:13:18 +00:00
|
|
|
/* init edit data */
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
2008-12-28 04:13:18 +00:00
|
|
|
|
|
|
|
/* loop over action data, averaging values */
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
2008-12-28 04:13:18 +00:00
|
|
|
|
2009-06-23 13:25:31 +00:00
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
AnimData *adt= ANIM_nla_mapping_get(&ac, ale);
|
|
|
|
if (adt) {
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
|
2009-06-23 13:25:31 +00:00
|
|
|
}
|
|
|
|
else
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_calc_average, NULL);
|
2009-06-23 13:25:31 +00:00
|
|
|
}
|
2008-12-28 04:13:18 +00:00
|
|
|
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
|
|
|
|
/* set the new current frame value, based on the average time */
|
2010-04-02 12:02:39 +00:00
|
|
|
if (ked.i1) {
|
2008-12-28 04:13:18 +00:00
|
|
|
Scene *scene= ac.scene;
|
2010-04-02 12:02:39 +00:00
|
|
|
CFRA= (int)floor((ked.f1 / ked.i1) + 0.5f);
|
2008-12-28 04:13:18 +00:00
|
|
|
}
|
2008-12-27 11:44:00 +00:00
|
|
|
|
2009-04-10 03:34:20 +00:00
|
|
|
/* set notifier that things have changed */
|
2008-12-28 04:13:18 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, ac.scene);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_frame_jump (wmOperatorType *ot)
|
2008-12-27 11:44:00 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
2009-06-22 03:26:36 +00:00
|
|
|
ot->name= "Jump to Frame";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_frame_jump";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Set the current frame to the average frame of the selected keyframes";
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2009-06-22 03:26:36 +00:00
|
|
|
ot->exec= actkeys_framejump_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Snap Keyframes Operator *********************** */
|
|
|
|
|
|
|
|
/* defines for snap keyframes tool */
|
|
|
|
EnumPropertyItem prop_actkeys_snap_types[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", ""},
|
|
|
|
{ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry?
|
|
|
|
{ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry?
|
|
|
|
{ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2008-12-27 11:44:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* this function is responsible for snapping keyframes to frame-times */
|
|
|
|
static void snap_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditData ked;
|
|
|
|
KeyframeEditFunc edit_cb;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
if (ac->datatype == ANIMCONT_GPENCIL)
|
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
|
|
|
|
else
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* get beztriple editing callbacks */
|
|
|
|
edit_cb= ANIM_editkeyframes_snap(mode);
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
|
|
|
ked.scene= ac->scene;
|
2009-05-09 02:37:12 +00:00
|
|
|
if (mode == ACTKEYS_SNAP_NEAREST_MARKER) {
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.list.first= (ac->markers) ? ac->markers->first : NULL;
|
|
|
|
ked.list.last= (ac->markers) ? ac->markers->last : NULL;
|
2009-05-09 02:37:12 +00:00
|
|
|
}
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* snap keyframes */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
2009-06-23 13:25:31 +00:00
|
|
|
if (adt) {
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
|
|
|
//else if (ale->type == ACTTYPE_GPLAYER)
|
|
|
|
// snap_gplayer_frames(ale->data, mode);
|
|
|
|
else
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
2010-01-26 03:16:14 +00:00
|
|
|
|
2008-12-27 11:44:00 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_snap_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* get snapping mode */
|
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* snap keyframes */
|
|
|
|
snap_action_keys(&ac, mode);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_snap (wmOperatorType *ot)
|
2008-12-27 11:44:00 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Snap Keys";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_snap";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Snap selected keyframes to the times specified";
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_snap_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* id-props */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", prop_actkeys_snap_types, 0, "Type", "");
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Mirror Keyframes Operator *********************** */
|
|
|
|
|
2008-12-28 08:15:29 +00:00
|
|
|
/* defines for mirror keyframes tool */
|
2008-12-27 11:44:00 +00:00
|
|
|
EnumPropertyItem prop_actkeys_mirror_types[] = {
|
2009-07-01 01:17:58 +00:00
|
|
|
{ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", ""},
|
|
|
|
{ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""},
|
|
|
|
{ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""},
|
2009-06-16 00:52:21 +00:00
|
|
|
{0, NULL, 0, NULL, NULL}
|
2008-12-27 11:44:00 +00:00
|
|
|
};
|
|
|
|
|
2008-12-28 08:15:29 +00:00
|
|
|
/* this function is responsible for mirroring keyframes */
|
2008-12-27 11:44:00 +00:00
|
|
|
static void mirror_action_keys(bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditData ked;
|
|
|
|
KeyframeEditFunc edit_cb;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* get beztriple editing callbacks */
|
|
|
|
edit_cb= ANIM_editkeyframes_mirror(mode);
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
|
|
|
ked.scene= ac->scene;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* for 'first selected marker' mode, need to find first selected marker first! */
|
|
|
|
// XXX should this be made into a helper func in the API?
|
|
|
|
if (mode == ACTKEYS_MIRROR_MARKER) {
|
|
|
|
TimeMarker *marker= NULL;
|
|
|
|
|
|
|
|
/* find first selected marker */
|
2009-05-09 02:37:12 +00:00
|
|
|
if (ac->markers) {
|
|
|
|
for (marker= ac->markers->first; marker; marker=marker->next) {
|
|
|
|
if (marker->flag & SELECT) {
|
|
|
|
break;
|
|
|
|
}
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* store marker's time (if available) */
|
|
|
|
if (marker)
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.f1= (float)marker->frame;
|
2008-12-27 11:44:00 +00:00
|
|
|
else
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
if (ac->datatype == ANIMCONT_GPENCIL)
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
|
2008-12-27 11:44:00 +00:00
|
|
|
else
|
2010-05-20 05:18:27 +00:00
|
|
|
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY | ANIMFILTER_NODUPLIS);
|
2009-01-26 04:13:38 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* mirror keyframes */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
2009-06-23 13:25:31 +00:00
|
|
|
if (adt) {
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
|
|
|
//else if (ale->type == ACTTYPE_GPLAYER)
|
|
|
|
// snap_gplayer_frames(ale->data, mode);
|
|
|
|
else
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, edit_cb, calchandles_fcurve);
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
2010-01-26 03:16:14 +00:00
|
|
|
|
2008-12-27 11:44:00 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int actkeys_mirror_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
2008-12-28 08:15:29 +00:00
|
|
|
/* get mirroring mode */
|
2008-12-27 11:44:00 +00:00
|
|
|
mode= RNA_enum_get(op->ptr, "type");
|
|
|
|
|
|
|
|
/* mirror keyframes */
|
|
|
|
mirror_action_keys(&ac, mode);
|
|
|
|
|
|
|
|
/* validate keyframes after editing */
|
|
|
|
ANIM_editkeyframes_refresh(&ac);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframes have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_EDITED, NULL);
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-11-28 14:37:21 +00:00
|
|
|
void ACTION_OT_mirror (wmOperatorType *ot)
|
2008-12-27 11:44:00 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Mirror Keys";
|
2009-11-28 14:37:21 +00:00
|
|
|
ot->idname= "ACTION_OT_mirror";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Flip selected keyframes over the selected mirror line";
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_menu_invoke;
|
|
|
|
ot->exec= actkeys_mirror_exec;
|
2009-06-21 03:02:40 +00:00
|
|
|
ot->poll= ED_operator_action_active;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* flags */
|
2009-01-31 19:40:40 +00:00
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
2008-12-27 11:44:00 +00:00
|
|
|
|
|
|
|
/* id-props */
|
2010-01-15 22:40:33 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", "");
|
2008-12-27 11:44:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|