Files
test2/source/blender/src/editaction.c

5245 lines
133 KiB
C
Raw Normal View History

2002-10-12 11:37:38 +00:00
/**
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
2002-10-12 11:37:38 +00:00
*
* 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.
2002-10-12 11:37:38 +00:00
*
* 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 rewrite of Action Editor)
2002-10-12 11:37:38 +00:00
*
* ***** END GPL LICENSE BLOCK *****
2002-10-12 11:37:38 +00:00
*/
#include <string.h>
#include <stddef.h>
2002-10-12 11:37:38 +00:00
#include <math.h>
#include "MEM_guardedalloc.h"
#include "PIL_time.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "DNA_action_types.h"
#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
2002-10-12 11:37:38 +00:00
#include "DNA_userdef_types.h"
#include "DNA_constraint_types.h"
#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_nla_types.h"
#include "DNA_lattice_types.h"
#include "DNA_gpencil_types.h"
2002-10-12 11:37:38 +00:00
Biiig commit! Thanks to 2-3 weeks of cvs freeze... Render: - New; support for dual CPU render (SDL thread) Currently only works with alternating scanlines, but gives excellent performance. For both normal render as unified implemented. Note the "mutex" locks on z-transp buffer render and imbuf loads. - This has been made possible by major cleanups in render code, especially getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct OSA or using Materials or Texture data to write to. - Made normal render fully 4x32 floats too, and removed all old optimizes with chars or shorts. - Made normal render and unified render use same code for sky and halo render, giving equal (and better) results for halo render. Old render now also uses PostProcess options (brightness, mul, gamma) - Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer after render. Using PostProcess menu you will note an immediate re- display of image too (32 bits RGBA) - Added "Hue" and "Saturation" sliders to PostProcess options - Render module is still not having a "nice" API, but amount of dependencies went down a lot. Next todo: remove abusive "previewrender" code. The last main global in Render (struct Render) now can be re-used for fully controlling a render, to allow multiple "instances" of render to open. - Renderwindow now displays a smal bar on top with the stats, and keeps the stats after render too. Including "spare" page support. Not only easier visible that way, but also to remove the awkward code that was drawing stats in the Info header (extreme slow on some ATIs too) - Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping defines. - I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
#include "BKE_action.h"
2002-10-12 11:37:38 +00:00
#include "BKE_armature.h"
#include "BKE_constraint.h"
#include "BKE_curve.h"
Result of 2 weeks of quiet coding work in Greece :) Aim was to get a total refresh of the animation system. This is needed because; - we need to upgrade it with 21st century features - current code is spaghetti/hack combo, and hides good design - it should become lag-free with using dependency graphs A full log, with complete code API/structure/design explanation will follow, that's a load of work... so here below the list with hot changes; - The entire object update system (matrices, geometry) is now centralized. Calls to where_is_object and makeDispList are forbidden, instead we tag objects 'changed' and let the depgraph code sort it out - Removed all old "Ika" code - Depgraph is aware of all relationships, including meta balls, constraints, bevelcurve, and so on. - Made depgraph aware of relation types and layers, to do smart flushing of 'changed' events. Nothing gets calculated too often! - Transform uses depgraph to detect changes - On frame-advance, depgraph flushes animated changes Armatures; Almost all armature related code has been fully built from scratch. It now reveils the original design much better, with a very clean implementation, lag free without even calculating each Bone more than once. Result is quite a speedup yes! Important to note is; 1) Armature is data containing the 'rest position' 2) Pose is the changes of rest position, and always on object level. That way more Objects can use same Pose. Also constraints are in Pose 3) Actions only contain the Ipos to change values in Poses. - Bones draw unrotated now - Drawing bones speedup enormously (10-20 times) - Bone selecting in EditMode, selection state is saved for PoseMode, and vice-versa - Undo in editmode - Bone renaming does vertexgroups, constraints, posechannels, actions, for all users of Armature in entire file - Added Bone renaming in NKey panel - Nkey PoseMode shows eulers now - EditMode and PoseMode now have 'active' bone too (last clicked) - Parenting in EditMode' CTRL+P, ALT+P, with nice options! - Pose is added in Outliner now, with showing that constraints are in the Pose, not Armature - Disconnected IK solving from constraints. It's a separate phase now, on top of the full Pose calculations - Pose itself has a dependency graph too, so evaluation order is lag free. TODO NOW; - Rotating in Posemode has incorrect inverse transform (Martin will fix) - Python Bone/Armature/Pose API disabled... needs full recode too (wait for my doc!) - Game engine will need upgrade too - Depgraph code needs revision, cleanup, can be much faster! (But, compliments for Jean-Luc, it works like a charm!) - IK changed, it now doesnt use previous position to advance to next position anymore. That system looks nice (no flips) but is not well suited for NLA and background render. TODO LATER; We now can do loadsa new nifty features as well; like: - Kill PoseMode (can be option for armatures itself) - Make B-Bones (Bezier, Bspline, like for spines) - Move all silly button level edit to 3d window (like CTRL+I = add IK) - Much better & informative drawing - Fix action/nla editors - Put all ipos in Actions (object, mesh key, lamp color) - Add hooks - Null bones - Much more advanced constraints... Bugfixes; - OGL render (view3d header) had wrong first frame on anim render - Ipo 'recording' mode had wrong playback speed - Vertex-key mode now sticks to show 'active key', until frame change -Ton-
2005-07-03 17:35:38 +00:00
#include "BKE_depsgraph.h"
2002-10-12 11:37:38 +00:00
#include "BKE_global.h"
Biiig commit! Thanks to 2-3 weeks of cvs freeze... Render: - New; support for dual CPU render (SDL thread) Currently only works with alternating scanlines, but gives excellent performance. For both normal render as unified implemented. Note the "mutex" locks on z-transp buffer render and imbuf loads. - This has been made possible by major cleanups in render code, especially getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct OSA or using Materials or Texture data to write to. - Made normal render fully 4x32 floats too, and removed all old optimizes with chars or shorts. - Made normal render and unified render use same code for sky and halo render, giving equal (and better) results for halo render. Old render now also uses PostProcess options (brightness, mul, gamma) - Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer after render. Using PostProcess menu you will note an immediate re- display of image too (32 bits RGBA) - Added "Hue" and "Saturation" sliders to PostProcess options - Render module is still not having a "nice" API, but amount of dependencies went down a lot. Next todo: remove abusive "previewrender" code. The last main global in Render (struct Render) now can be re-used for fully controlling a render, to allow multiple "instances" of render to open. - Renderwindow now displays a smal bar on top with the stats, and keeps the stats after render too. Including "spare" page support. Not only easier visible that way, but also to remove the awkward code that was drawing stats in the Info header (extreme slow on some ATIs too) - Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping defines. - I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
#include "BKE_ipo.h"
#include "BKE_key.h"
2002-10-12 11:37:38 +00:00
#include "BKE_library.h"
#include "BKE_main.h"
Biiig commit! Thanks to 2-3 weeks of cvs freeze... Render: - New; support for dual CPU render (SDL thread) Currently only works with alternating scanlines, but gives excellent performance. For both normal render as unified implemented. Note the "mutex" locks on z-transp buffer render and imbuf loads. - This has been made possible by major cleanups in render code, especially getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct OSA or using Materials or Texture data to write to. - Made normal render fully 4x32 floats too, and removed all old optimizes with chars or shorts. - Made normal render and unified render use same code for sky and halo render, giving equal (and better) results for halo render. Old render now also uses PostProcess options (brightness, mul, gamma) - Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer after render. Using PostProcess menu you will note an immediate re- display of image too (32 bits RGBA) - Added "Hue" and "Saturation" sliders to PostProcess options - Render module is still not having a "nice" API, but amount of dependencies went down a lot. Next todo: remove abusive "previewrender" code. The last main global in Render (struct Render) now can be re-used for fully controlling a render, to allow multiple "instances" of render to open. - Renderwindow now displays a smal bar on top with the stats, and keeps the stats after render too. Including "spare" page support. Not only easier visible that way, but also to remove the awkward code that was drawing stats in the Info header (extreme slow on some ATIs too) - Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping defines. - I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
#include "BKE_utildefines.h"
#include "BKE_object.h" /* for where_is_object in obanim -> action baking */
2002-10-12 11:37:38 +00:00
#include "BIF_butspace.h"
#include "BIF_editaction.h"
#include "BIF_editarmature.h"
#include "BIF_editnla.h"
#include "BIF_editview.h"
2002-10-12 11:37:38 +00:00
#include "BIF_gl.h"
#include "BIF_interface.h"
#include "BIF_keyframing.h"
2002-10-12 11:37:38 +00:00
#include "BIF_mywindow.h"
#include "BIF_poseobject.h"
2002-10-12 11:37:38 +00:00
#include "BIF_screen.h"
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BIF_transform.h"
2002-10-12 11:37:38 +00:00
#include "BSE_edit.h"
#include "BSE_drawipo.h"
#include "BSE_headerbuttons.h"
#include "BSE_editaction_types.h"
2002-10-12 11:37:38 +00:00
#include "BSE_editipo.h"
#include "BSE_time.h"
2002-10-12 11:37:38 +00:00
#include "BSE_trans_types.h"
#include "BDR_drawaction.h"
2002-10-12 11:37:38 +00:00
#include "BDR_editobject.h"
#include "BDR_gpencil.h"
2002-10-12 11:37:38 +00:00
#include "mydevice.h"
#include "blendef.h"
#include "nla.h"
/* **************************************************** */
/* ACTION API */
/* this function adds a new Action block */
bAction *add_empty_action (char *name)
2002-10-12 11:37:38 +00:00
{
bAction *act;
act= alloc_libblock(&G.main->action, ID_AC, name);
act->id.flag |= LIB_FAKEUSER;
act->id.us++;
return act;
}
/* generic get current action call, for action window context */
bAction *ob_get_action (Object *ob)
{
bActionStrip *strip;
if(ob->action)
return ob->action;
for (strip=ob->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT)
return strip->act;
2002-10-12 11:37:38 +00:00
}
return NULL;
2002-10-12 11:37:38 +00:00
}
/* used by ipo, outliner, buttons to find the active channel */
bActionChannel *get_hilighted_action_channel (bAction *action)
2002-10-12 11:37:38 +00:00
{
bActionChannel *achan;
2002-10-12 11:37:38 +00:00
if (!action)
return NULL;
2002-10-12 11:37:38 +00:00
for (achan= action->chanbase.first; achan; achan= achan->next) {
if (VISIBLE_ACHAN(achan)) {
if (SEL_ACHAN(achan) && (achan->flag & ACHAN_HILIGHTED))
return achan;
2002-10-12 11:37:38 +00:00
}
}
return NULL;
2002-10-12 11:37:38 +00:00
}
/* ----------------------------------------- */
void remake_action_ipos (bAction *act)
2002-10-12 11:37:38 +00:00
{
bActionChannel *achan;
2002-10-12 11:37:38 +00:00
bConstraintChannel *conchan;
IpoCurve *icu;
2002-10-12 11:37:38 +00:00
for (achan= act->chanbase.first; achan; achan= achan->next) {
if (achan->ipo) {
for (icu = achan->ipo->curve.first; icu; icu=icu->next) {
2002-10-12 11:37:38 +00:00
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
}
}
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (conchan->ipo) {
for (icu = conchan->ipo->curve.first; icu; icu=icu->next) {
2002-10-12 11:37:38 +00:00
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
}
}
}
}
synchronize_action_strips();
2002-10-12 11:37:38 +00:00
}
/* **************************************************** */
/* 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)
{
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;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
if ((owner) && (ownertype == ACTTYPE_ACHAN)) {
bActionChannel *ochan= (bActionChannel *)owner;
ale->grp= ochan->grp;
}
else
ale->grp= NULL;
/* do specifics */
switch (datatype) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
case ACTTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)data;
ale->flag= agrp->flag;
ale->key_data= NULL;
ale->datatype= ALE_GROUP;
}
break;
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:
case ACTTYPE_CONCHAN2:
{
bConstraintChannel *conchan= (bConstraintChannel *)data;
ale->flag= conchan->flag;
if (datatype == ACTTYPE_CONCHAN2) {
/* CONCHAN2 is a hack so that constraint-channels keyframes can be edited */
if (conchan->ipo) {
ale->key_data= conchan->ipo;
ale->datatype= ALE_IPO;
}
else {
ale->key_data= NULL;
ale->datatype= ALE_NONE;
}
}
else {
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;
case ACTTYPE_GPLAYER:
{
bGPDlayer *gpl= (bGPDlayer *)data;
ale->flag= gpl->flag;
ale->key_data= NULL;
ale->datatype= ALE_GPFRAME;
}
break;
}
}
/* return created datatype */
return ale;
}
/* ----------------------------------------- */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
static void actdata_filter_actionchannel (ListBase *act_data, bActionChannel *achan, int filter_mode)
2002-10-12 11:37:38 +00:00
{
bActListElem *ale;
2002-10-12 11:37:38 +00:00
bConstraintChannel *conchan;
IpoCurve *icu;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* 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);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
else {
/* for insert key... this check could be improved */
return;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* check if expanded - if not, continue on to next action channel */
if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ACTFILTER_ONLYICU)==0) {
/* only exit if we don't need to include constraint channels for group-channel keyframes */
if ( !(filter_mode & ACTFILTER_IPOKEYS) || (achan->grp == NULL) || (EXPANDED_AGRP(achan->grp)==0) )
return;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* ipo channels */
if ((achan->ipo) && (filter_mode & ACTFILTER_IPOKEYS)==0) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* 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);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* 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);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
}
/* constraint channels */
if (achan->constraintChannels.first) {
/* include constraint-expand widget? */
if ( (filter_mode & ACTFILTER_CHANNELS) && !(filter_mode & ACTFILTER_ONLYICU)
&& !(filter_mode & ACTFILTER_IPOKEYS) )
{
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
ale= make_new_actlistelem(achan, ACTTYPE_FILLCON, achan, ACTTYPE_ACHAN);
if (ale) BLI_addtail(act_data, ale);
}
/* add constraint channels? */
if (FILTER_CON_ACHAN(achan) || (filter_mode & ACTFILTER_IPOKEYS) || (filter_mode & ACTFILTER_ONLYICU)) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* 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_IPOKEYS) {
ale= make_new_actlistelem(conchan, ACTTYPE_CONCHAN2, achan, ACTTYPE_ACHAN);
if (ale) BLI_addtail(act_data, ale);
}
else {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
ale= make_new_actlistelem(conchan, ACTTYPE_CONCHAN, achan, ACTTYPE_ACHAN);
if (ale) BLI_addtail(act_data, ale);
}
}
}
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
}
}
}
static void actdata_filter_action (ListBase *act_data, bAction *act, int filter_mode)
{
bActListElem *ale=NULL;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionGroup *agrp;
bActionChannel *achan, *lastchan=NULL;
/* loop over groups */
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
/* add this group as a channel first */
if (!(filter_mode & ACTFILTER_ONLYICU) && !(filter_mode & ACTFILTER_IPOKEYS)) {
/* check if filtering by selection */
if ( !(filter_mode & ACTFILTER_SEL) || SEL_AGRP(agrp) ) {
ale= make_new_actlistelem(agrp, ACTTYPE_GROUP, NULL, ACTTYPE_NONE);
if (ale) BLI_addtail(act_data, ale);
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* store reference to last channel of group */
if (agrp->channels.last)
lastchan= agrp->channels.last;
/* there are some situations, where only the channels of the active group should get considered */
if (!(filter_mode & ACTFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
/* filters here are a bit convoulted...
* - groups show a "summary" of keyframes beside their name which must accessable for tools which handle keyframes
* - groups can be collapsed (and those tools which are only interested in channels rely on knowing that group is closed)
*
* cases when we should include action-channels and so-forth inside group:
* - we don't care about visibility
* - group is expanded
* - we're interested in keyframes, but not if they appear in selected channels
*/
if ( (!(filter_mode & ACTFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) ||
( ((filter_mode & ACTFILTER_IPOKEYS) || (filter_mode & ACTFILTER_ONLYICU)) &&
(!(filter_mode & ACTFILTER_SEL) || (SEL_AGRP(agrp))) ) )
{
if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
actdata_filter_actionchannel(act_data, achan, filter_mode);
}
/* remove group from filtered list if last element is group
* (i.e. only if group had channels, which were all hidden)
*/
if ( (ale) && (act_data->last == ale) &&
(ale->data == agrp) && (agrp->channels.first) )
{
BLI_freelinkN(act_data, ale);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
}
}
}
/* loop over un-grouped action channels (only if we're not only considering those channels in the active group) */
if (!(filter_mode & ACTFILTER_ACTGROUPED)) {
for (achan=(lastchan)?lastchan->next:act->chanbase.first; achan; achan=achan->next) {
actdata_filter_actionchannel(act_data, achan, filter_mode);
}
}
}
2002-10-12 11:37:38 +00:00
static void actdata_filter_shapekey (ListBase *act_data, Key *key, int filter_mode)
{
bActListElem *ale;
KeyBlock *kb;
IpoCurve *icu;
int i;
/* are we filtering for display or editing */
if (filter_mode & ACTFILTER_FORDRAWING) {
/* for display - loop over shapekeys, adding ipo-curve references where needed */
kb= key->block.first;
/* loop through possible shapekeys, manually creating entries */
for (i= 1; i < key->totkey; i++) {
ale= MEM_callocN(sizeof(bActListElem), "bActListElem");
kb = kb->next;
ale->data= kb;
ale->type= ACTTYPE_SHAPEKEY; /* 'abused' usage of this type */
ale->owner= key;
ale->ownertype= ACTTYPE_SHAPEKEY;
ale->datatype= ALE_NONE;
ale->index = i;
if (key->ipo) {
for (icu= key->ipo->curve.first; icu; icu=icu->next) {
if (icu->adrcode == i) {
ale->key_data= icu;
ale->datatype= ALE_ICU;
break;
}
}
}
BLI_addtail(act_data, ale);
}
}
else {
/* loop over ipo curves if present - for editing */
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);
}
}
}
}
}
static void actdata_filter_gpencil (ListBase *act_data, bScreen *sc, int filter_mode)
{
bActListElem *ale;
ScrArea *sa;
bGPdata *gpd;
bGPDlayer *gpl;
/* check if filtering types are appropriate */
if ( !(filter_mode & (ACTFILTER_IPOKEYS|ACTFILTER_ONLYICU|ACTFILTER_ACTGROUPED)) )
{
/* special hack for fullscreen area (which must be this one then):
* - we use the curarea->full as screen to get spaces from, since the
* old (pre-fullscreen) screen was stored there...
* - this is needed as all data would otherwise disappear
*/
if ((curarea->full) && (curarea->spacetype==SPACE_ACTION))
sc= curarea->full;
/* loop over spaces in current screen, finding gpd blocks (could be slow!) */
for (sa= sc->areabase.first; sa; sa= sa->next) {
/* try to get gp data */
gpd= gpencil_data_getactive(sa);
if (gpd == NULL) continue;
/* add gpd as channel too (if for drawing, and it has layers) */
if ((filter_mode & ACTFILTER_FORDRAWING) && (gpd->layers.first)) {
/* add to list */
ale= make_new_actlistelem(gpd, ACTTYPE_GPDATABLOCK, sa, ACTTYPE_SPECIALDATA);
if (ale) BLI_addtail(act_data, ale);
}
/* only add layers if they will be visible (if drawing channels) */
if ( !(filter_mode & ACTFILTER_VISIBLE) || (EXPANDED_GPD(gpd)) ) {
/* loop over layers as the conditions are acceptable */
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
/* only if selected */
if (!(filter_mode & ACTFILTER_SEL) || SEL_GPL(gpl)) {
/* only if editable */
if (!(filter_mode & ACTFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
/* add to list */
ale= make_new_actlistelem(gpl, ACTTYPE_GPLAYER, gpd, ACTTYPE_GPDATABLOCK);
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;
case ACTCONT_GPENCIL:
actdata_filter_gpencil(act_data, data, filter_mode);
break;
}
/* 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);
}
}
2002-10-12 11:37:38 +00:00
}
}
/* **************************************************** */
/* 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
*/
/* Note: there's a similar function in key.c (ob_get_key) */
Key *get_action_mesh_key(void)
{
Object *ob;
Key *key;
ob = OBACT;
if (ob == NULL)
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 if (ELEM(ob->type, OB_CURVE, OB_SURF))
key= ((Curve *)ob->data)->key;
else
return NULL;
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 y;
areamouseco_to_ipoco(G.v2d, mval, x, &y);
num = (int) ((CHANNELHEIGHT/2 - y) / (CHANNELHEIGHT+CHANNELSKIP));
return (num + 1);
}
2002-10-12 11:37:38 +00:00
/* this function finds the channel that mouse is floating over */
void *get_nearest_act_channel (short mval[], short *ret_type, void **owner)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
void *data;
short datatype;
int filter;
int clickmin, clickmax;
float x,y;
/* init 'owner' return val */
*owner= NULL;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) {
*ret_type= ACTTYPE_NONE;
return NULL;
}
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
clickmax = clickmin;
if (clickmax < 0) {
*ret_type= ACTTYPE_NONE;
return NULL;
}
/* filter data */
filter= (ACTFILTER_FORDRAWING | 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;
*owner= ale->owner;
BLI_freelistN(&act_data);
return data;
}
--clickmin;
--clickmax;
}
/* cleanup */
BLI_freelistN(&act_data);
*ret_type= ACTTYPE_NONE;
return NULL;
2002-10-12 11:37:38 +00:00
}
/* 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)
{
ListBase act_data = {NULL, NULL};
ListBase act_keys = {NULL, NULL};
bActListElem *ale;
ActKeyColumn *ak;
void *data;
short datatype;
int filter;
rctf rectf;
float xmin, xmax, x, y;
int clickmin, clickmax;
2002-10-12 11:37:38 +00:00
short mval[2];
short found = 0;
getmouseco_areawin (mval);
2002-10-12 11:37:38 +00:00
/* action-channel */
*par= NULL;
2002-10-12 11:37:38 +00:00
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) {
*ret_type= ACTTYPE_NONE;
return NULL;
}
2002-10-12 11:37:38 +00:00
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
clickmin = (int) (((CHANNELHEIGHT/2) - y) / (CHANNELHEIGHT+CHANNELSKIP));
clickmax = clickmin;
2002-10-12 11:37:38 +00:00
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);
/* if action is mapped in NLA, it returns a correction */
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
xmin= get_action_frame(OBACT, rectf.xmin);
xmax= get_action_frame(OBACT, rectf.xmax);
}
else {
xmin= rectf.xmin;
xmax= rectf.xmax;
}
if (clickmax < 0) {
*ret_type= ACTTYPE_NONE;
return NULL;
}
/* filter data */
filter= (ACTFILTER_FORDRAWING | 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 */
/* make list of keyframes */
if (ale->key_data) {
switch (ale->datatype) {
case ALE_IPO:
{
Ipo *ipo= (Ipo *)ale->key_data;
ipo_to_keylist(ipo, &act_keys, NULL, NULL);
}
break;
case ALE_ICU:
{
IpoCurve *icu= (IpoCurve *)ale->key_data;
icu_to_keylist(icu, &act_keys, NULL, NULL);
2002-10-12 11:37:38 +00:00
}
break;
2002-10-12 11:37:38 +00:00
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (ale->type == ACTTYPE_GROUP) {
bActionGroup *agrp= (bActionGroup *)ale->data;
agroup_to_keylist(agrp, &act_keys, NULL, NULL);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
else if (ale->type == ACTTYPE_GPDATABLOCK) {
/* cleanup */
BLI_freelistN(&act_data);
/* this channel currently doens't have any keyframes... must ignore! */
*ret_type= ACTTYPE_NONE;
return NULL;
}
else if (ale->type == ACTTYPE_GPLAYER) {
bGPDlayer *gpl= (bGPDlayer *)ale->data;
gpl_to_keylist(gpl, &act_keys, NULL, NULL);
}
/* loop through keyframes, finding one that was clicked on */
for (ak= act_keys.first; ak; ak= ak->next) {
if (IN_RANGE(ak->cfra, xmin, xmax)) {
*selx= ak->cfra;
found= 1;
break;
}
}
/* no matching keyframe found - set to mean frame value so it doesn't actually select anything */
if (found == 0)
*selx= ((xmax+xmin) / 2);
/* figure out what to return */
if (datatype == ACTCONT_ACTION) {
*par= ale->owner; /* assume that this is an action channel */
*ret_type= ale->type;
data = ale->data;
}
else if (datatype == ACTCONT_SHAPEKEY) {
data = ale->key_data;
*ret_type= ACTTYPE_ICU;
}
else if (datatype == ACTCONT_GPENCIL) {
data = ale->data;
*ret_type= ACTTYPE_GPLAYER;
}
/* cleanup tempolary lists */
BLI_freelistN(&act_keys);
act_keys.first = act_keys.last = NULL;
BLI_freelistN(&act_data);
return data;
2002-10-12 11:37:38 +00:00
}
--clickmin;
--clickmax;
}
2002-10-12 11:37:38 +00:00
/* cleanup */
BLI_freelistN(&act_data);
*ret_type= ACTTYPE_NONE;
return NULL;
2002-10-12 11:37:38 +00:00
}
void *get_action_context (short *datatype)
{
bAction *act;
Key *key;
/* get pointers to active action/shapekey blocks */
act = (G.saction)? G.saction->action: NULL;
key = get_action_mesh_key();
/* check mode selector */
if (G.saction) {
switch (G.saction->mode) {
case SACTCONT_ACTION:
*datatype= ACTCONT_ACTION;
return act;
case SACTCONT_SHAPEKEY:
*datatype= ACTCONT_SHAPEKEY;
return key;
case SACTCONT_GPENCIL:
*datatype= ACTCONT_GPENCIL;
return G.curscreen; // FIXME: add that dopesheet type thing here!
default: /* includes SACTCONT_DOPESHEET for now */
*datatype= ACTCONT_NONE;
return NULL;
}
}
else {
/* resort to guessing based on what is available */
if (act) {
*datatype= ACTCONT_ACTION;
return act;
}
else if (key) {
*datatype= ACTCONT_SHAPEKEY;
return key;
}
else {
*datatype= ACTCONT_NONE;
return NULL;
}
}
}
/* Quick-tool for preview-range functionality in Action Editor for setting Preview-Range
* bounds to extents of Action, when Ctrl-Alt-P is used. Only available for actions.
*/
void action_previewrange_set (bAction *act)
{
float start, end;
/* sanity check */
if (act == NULL)
return;
/* calculate range + make sure it is adjusted for nla-scaling */
calc_action_range(act, &start, &end, 0);
if (NLA_ACTION_SCALED) {
start= get_action_frame_inv(OBACT, start);
end= get_action_frame_inv(OBACT, end);
}
/* set preview range */
G.scene->r.psfra= (int)start;
G.scene->r.pefra= (int)end;
BIF_undo_push("Set anim-preview range");
allqueue(REDRAWTIME, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWBUTSALL, 0);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* **************************************************** */
/* ACTION CHANNEL GROUPS */
/* Get the active action-group for an Action */
bActionGroup *get_active_actiongroup (bAction *act)
{
bActionGroup *agrp= NULL;
if (act && act->groups.first) {
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
if (agrp->flag & AGRP_ACTIVE)
break;
}
}
return agrp;
}
/* Make the given Action-Group the active one */
void set_active_actiongroup (bAction *act, bActionGroup *agrp, short select)
{
bActionGroup *grp;
/* sanity checks */
if (act == NULL)
return;
/* Deactive all others */
for (grp= act->groups.first; grp; grp= grp->next) {
if ((grp==agrp) && (select))
grp->flag |= AGRP_ACTIVE;
else
grp->flag &= ~AGRP_ACTIVE;
}
}
/* Add given channel into (active) group
* - assumes that channel is not linked to anything anymore
* - always adds at the end of the group
*/
static void action_groups_addachan (bAction *act, bActionGroup *agrp, bActionChannel *achan)
{
bActionChannel *chan;
short done=0;
/* sanity checks */
if (ELEM3(NULL, act, agrp, achan))
return;
/* if no channels, just add to two lists at the same time */
if (act->chanbase.first == NULL) {
achan->next = achan->prev = NULL;
agrp->channels.first = agrp->channels.last = achan;
act->chanbase.first = act->chanbase.last = achan;
achan->grp= agrp;
return;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* try to find a channel to slot this in before/after */
for (chan= act->chanbase.first; chan; chan= chan->next) {
/* if channel has no group, then we have ungrouped channels, which should always occur after groups */
if (chan->grp == NULL) {
BLI_insertlinkbefore(&act->chanbase, chan, achan);
if (agrp->channels.first == NULL)
agrp->channels.first= achan;
agrp->channels.last= achan;
done= 1;
break;
}
/* if channel has group after current, we can now insert (otherwise we have gone too far) */
else if (chan->grp == agrp->next) {
BLI_insertlinkbefore(&act->chanbase, chan, achan);
if (agrp->channels.first == NULL)
agrp->channels.first= achan;
agrp->channels.last= achan;
done= 1;
break;
}
/* if channel has group we're targeting, check whether it is the last one of these */
else if (chan->grp == agrp) {
if ((chan->next) && (chan->next->grp != agrp)) {
BLI_insertlinkafter(&act->chanbase, chan, achan);
agrp->channels.last= achan;
done= 1;
break;
}
else if (chan->next == NULL) {
BLI_addtail(&act->chanbase, achan);
agrp->channels.last= achan;
done= 1;
break;
}
}
/* if channel has group before target, check whether the next one is something after target */
else if (chan->grp == agrp->prev) {
if (chan->next) {
if ((chan->next->grp != chan->grp) && (chan->next->grp != agrp)) {
BLI_insertlinkafter(&act->chanbase, chan, achan);
agrp->channels.first= achan;
agrp->channels.last= achan;
done= 1;
break;
}
}
else {
BLI_insertlinkafter(&act->chanbase, chan, achan);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
agrp->channels.first= achan;
agrp->channels.last= achan;
done= 1;
break;
}
}
}
/* only if added, set channel as belonging to this group */
if (done) {
achan->grp= agrp;
}
else
printf("Error: ActionChannel: '%s' couldn't be added to Group: '%s' \n", achan->name, agrp->name);
}
/* Remove the given channel from all groups */
static void action_groups_removeachan (bAction *act, bActionChannel *achan)
{
/* sanity checks */
if (ELEM(NULL, act, achan))
return;
/* check if any group used this directly */
if (achan->grp) {
bActionGroup *agrp= achan->grp;
if (agrp->channels.first == agrp->channels.last) {
if (agrp->channels.first == achan) {
agrp->channels.first= NULL;
agrp->channels.last= NULL;
}
}
else if (agrp->channels.first == achan) {
if ((achan->next) && (achan->next->grp==agrp))
agrp->channels.first= achan->next;
else
agrp->channels.first= NULL;
}
else if (agrp->channels.last == achan) {
if ((achan->prev) && (achan->prev->grp==agrp))
agrp->channels.last= achan->prev;
else
agrp->channels.last= NULL;
}
achan->grp= NULL;
}
/* now just remove from list */
BLI_remlink(&act->chanbase, achan);
}
/* Add a new Action-Group or add channels to active one */
void action_groups_group (short add_group)
{
bAction *act;
bActionChannel *achan, *anext;
bActionGroup *agrp;
void *data;
short datatype;
/* validate type of data we are working on */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype != ACTCONT_ACTION) return;
act= (bAction *)data;
/* get active group */
if ((act->groups.first==NULL) || (add_group)) {
/* Add a new group, and make it active */
agrp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
agrp->flag |= (AGRP_ACTIVE|AGRP_SELECTED|AGRP_EXPANDED);
sprintf(agrp->name, "Group");
BLI_addtail(&act->groups, agrp);
BLI_uniquename(&act->groups, agrp, "Group", offsetof(bActionGroup, name), 32);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
set_active_actiongroup(act, agrp, 1);
add_group= 1;
}
else {
agrp= get_active_actiongroup(act);
if (agrp == NULL) {
error("No Active Action Group");
return;
}
}
/* loop through action-channels, finding those that are selected + visible to move */
// FIXME: this should be done with action api instead
for (achan= act->chanbase.first; achan; achan= anext) {
anext= achan->next;
/* make sure not already in new-group */
if (achan->grp != agrp) {
if ((achan->grp==NULL) || (EXPANDED_AGRP(achan->grp))) {
if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
/* unlink from everything else */
action_groups_removeachan(act, achan);
/* add to end of group's channels */
action_groups_addachan(act, agrp, achan);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
}
}
/* updates and undo */
if (add_group)
BIF_undo_push("Add Action Group");
else
BIF_undo_push("Add to Action Group");
allqueue(REDRAWACTION, 0);
}
/* Remove selected channels from their groups */
void action_groups_ungroup (void)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
bAction *act;
void *data;
short datatype;
short filter;
/* validate type of data we are working on */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype != ACTCONT_ACTION) return;
act= (bAction *)data;
/* filter data */
filter= (ACTFILTER_VISIBLE|ACTFILTER_SEL);
actdata_filter(&act_data, filter, act, ACTCONT_ACTION);
/* Only ungroup selected action-channels */
for (ale= act_data.first; ale; ale= ale->next) {
if (ale->type == ACTTYPE_ACHAN) {
action_groups_removeachan(act, ale->data);
BLI_addtail(&act->chanbase, ale->data);
}
}
BLI_freelistN(&act_data);
/* updates and undo */
BIF_undo_push("Remove From Action Groups");
allqueue(REDRAWACTION, 0);
}
/* Copy colors from a specified theme's color set to an Action/Bone Group */
void actionbone_group_copycolors (bActionGroup *grp, short init_new)
{
/* error checking */
if (grp == NULL)
return;
/* only do color copying if using a custom color */
if (grp->customCol) {
if (grp->customCol > 0) {
/* copy theme colors on-to group's custom color in case user tries to edit color */
bTheme *btheme= U.themes.first;
ThemeWireColor *col_set= &btheme->tarm[(grp->customCol - 1)];
memcpy(&grp->cs, col_set, sizeof(ThemeWireColor));
}
else if (init_new) {
/* init custom colors with a generic multi-color rgb set, if not initialised already (and allowed to do so) */
if (grp->cs.solid[0] == 0) {
/* define for setting colors in theme below */
#define SETCOL(col, r, g, b, a) col[0]=r; col[1]=g; col[2]= b; col[3]= a;
SETCOL(grp->cs.solid, 0xff, 0x00, 0x00, 255);
SETCOL(grp->cs.select, 0x81, 0xe6, 0x14, 255);
SETCOL(grp->cs.active, 0x18, 0xb6, 0xe0, 255);
#undef SETCOL
}
}
}
}
/* This function is used when inserting keyframes for pose-channels. It assigns the
* action-channel with the nominated name to a group with the same name as that of
* the pose-channel with the nominated name.
*
* Note: this function calls validate_action_channel if action channel doesn't exist
*/
void verify_pchan2achan_grouping (bAction *act, bPose *pose, char name[])
{
bActionChannel *achan;
bPoseChannel *pchan;
/* sanity checks */
if (ELEM3(NULL, act, pose, name))
return;
if (name[0] == 0)
return;
/* try to get the channels */
pchan= get_pose_channel(pose, name);
if (pchan == NULL) return;
achan= verify_action_channel(act, name);
/* check if pchan has a group */
if ((pchan->agrp_index > 0) && (achan->grp == NULL)) {
bActionGroup *agrp, *grp=NULL;
/* get group to try to be like */
agrp= (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
if (agrp == NULL) {
error("PoseChannel has invalid group!");
return;
}
/* try to find a group which is similar to the one we want (or add one) */
for (grp= act->groups.first; grp; grp= grp->next) {
if (!strcmp(grp->name, agrp->name))
break;
}
if (grp == NULL) {
grp= MEM_callocN(sizeof(bActionGroup), "bActionGroup");
grp->flag |= (AGRP_ACTIVE|AGRP_SELECTED|AGRP_EXPANDED);
/* copy name */
sprintf(grp->name, agrp->name);
/* deal with group-color copying (grp is destination, agrp is source) */
memcpy(grp, agrp, sizeof(bActionGroup));
actionbone_group_copycolors(grp, 1);
BLI_addtail(&act->groups, grp);
}
/* make sure this channel is definitely not connected to anything before adding to group */
action_groups_removeachan(act, achan);
action_groups_addachan(act, grp, achan);
}
}
/* This function is used when the user specifically requests to sync changes of pchans + bone groups
* to achans + action groups. All achans are detached from their groups, and all groups are destroyed.
* They are then recreated when the achans are reassigned to groups.
*
* Note: This doesn't preserve hand-created groups, and will operate on ALL action-channels regardless of
* whether they were selected or active. More specific filtering can be added later.
*/
void sync_pchan2achan_grouping ()
{
void *data;
short datatype;
bAction *act;
bActionChannel *achan, *next, *last;
bPose *pose;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if ((datatype != ACTCONT_ACTION) || (data==NULL)) return;
if ((G.saction->pin) || (OBACT==NULL) || (OBACT->type != OB_ARMATURE)) {
error("Action doesn't belong to active armature");
return;
}
/* get data */
act= (bAction *)data;
pose= OBACT->pose;
/* remove achan->group links, then delete all groups */
for (achan= act->chanbase.first; achan; achan= achan->next)
achan->grp = NULL;
BLI_freelistN(&act->groups);
/* loop through all achans, reassigning them to groups (colors are resyncronised) */
last= act->chanbase.last;
for (achan= act->chanbase.first; achan && achan!=last; achan= next) {
next= achan->next;
verify_pchan2achan_grouping(act, pose, achan->name);
}
/* undo and redraw */
BIF_undo_push("Sync Armature-Data and Action");
allqueue(REDRAWACTION, 0);
}
/* **************************************************** */
/* TRANSFORM TOOLS */
/* main call to start transforming keyframes */
void transform_action_keys (int mode, int dummy)
2002-10-12 11:37:38 +00:00
{
void *data;
short datatype;
short context = (U.flag & USER_DRAGIMMEDIATE)?CTX_TWEAK:CTX_NONE;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
switch (mode) {
case 'g':
{
initTransform(TFM_TIME_TRANSLATE, context);
Transform();
2002-10-12 11:37:38 +00:00
}
break;
case 's':
{
initTransform(TFM_TIME_SCALE, context);
Transform();
}
break;
case 't':
{
initTransform(TFM_TIME_SLIDE, context);
Transform();
}
break;
case 'e':
{
initTransform(TFM_TIME_EXTEND, context);
Transform();
}
break;
}
}
2002-10-12 11:37:38 +00:00
/* ----------------------------------------- */
/* duplicate keyframes */
void duplicate_action_keys (void)
{
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 */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
else
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) {
if (ale->type == ACTTYPE_GPLAYER)
duplicate_gplayer_frames(ale->data);
else
duplicate_ipo_keys((Ipo *)ale->key_data);
}
/* free filtered list */
BLI_freelistN(&act_data);
/* now, go into transform-grab mode, to move keys */
BIF_TransformSetUndo("Add Duplicate");
transform_action_keys('g', 0);
}
/* this function is responsible for snapping the current frame to selected data */
void snap_cfra_action()
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
/* get data */
data= get_action_context(&datatype);
if (data == NULL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* snap current frame to selected data */
snap_cfra_ipo_keys(NULL, -1);
for (ale= act_data.first; ale; ale= ale->next) {
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
snap_cfra_ipo_keys(ale->key_data, 0);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
else
snap_cfra_ipo_keys(ale->key_data, 0);
}
BLI_freelistN(&act_data);
snap_cfra_ipo_keys(NULL, 1);
BIF_undo_push("Snap Current Frame to Keys");
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
}
/* this function is responsible for snapping keyframes to frame-times */
void snap_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;
/* determine mode */
switch (mode) {
case 1:
strcpy(str, "Snap Keys To Nearest Frame");
break;
case 2:
if (G.saction->flag & SACTION_DRAWTIME)
strcpy(str, "Snap Keys To Current Time");
else
strcpy(str, "Snap Keys To Current Frame");
break;
case 3:
strcpy(str, "Snap Keys To Nearest Marker");
break;
case 4:
strcpy(str, "Snap Keys To Nearest Second");
break;
default:
return;
}
/* filter data */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
else
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* snap to frame */
for (ale= act_data.first; ale; ale= ale->next) {
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
snap_ipo_keys(ale->key_data, mode);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
else if (ale->type == ACTTYPE_GPLAYER)
snap_gplayer_frames(ale->data, mode);
else
snap_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);
allqueue(REDRAWVIEW3D, 0);
}
/* 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;
/* 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;
}
/* filter data */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
else
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* mirror */
for (ale= act_data.first; ale; ale= ale->next) {
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
mirror_ipo_keys(ale->key_data, mode);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
else if (ale->type == ACTTYPE_GPLAYER)
mirror_gplayer_frames(ale->data, mode);
else
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);
}
/* **************************************************** */
/* ADD/REMOVE KEYFRAMES */
2002-10-12 11:37:38 +00:00
/* 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|In Active Group%x3");
if (mode <= 0) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU );
if (mode == 2) filter |= ACTFILTER_SEL;
else if (mode == 3) filter |= ACTFILTER_ACTGROUPED;
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;
bConstraintChannel *conchan= (ale->type==ACTTYPE_CONCHAN) ? ale->data : NULL;
IpoCurve *icu= (IpoCurve *)ale->key_data;
if (ob)
insertkey((ID *)ob, icu->blocktype, achan->name, ((conchan)?(conchan->name):(NULL)), icu->adrcode, 0);
else
insert_vert_icu(icu, cfra, icu->curval, 0);
2002-10-12 11:37:38 +00:00
}
}
/* cleanup */
BLI_freelistN(&act_data);
2002-10-12 11:37:38 +00:00
}
else if (datatype == ACTCONT_SHAPEKEY) {
Key *key= (Key *)data;
IpoCurve *icu;
/* 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_icu(icu, cfra, icu->curval, 0);
}
}
}
else {
/* this tool is not supported in this mode */
return;
}
BIF_undo_push("Insert Key");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
2008-03-20 14:54:57 +00:00
allqueue(REDRAWBUTSOBJECT, 0);
}
/* delete selected keyframes */
void delete_action_keys (void)
{
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 */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT);
else
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) {
if (ale->type == ACTTYPE_GPLAYER)
delete_gplayer_frames((bGPDlayer *)ale->data);
else
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);
}
/* delete selected action-channels (only achans and conchans are considered) */
void delete_action_channels (void)
2002-10-12 11:37:38 +00:00
{
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;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* deal with groups first */
if (act->groups.first) {
bActionGroup *agrp, *grp;
bActionChannel *chan, *nchan;
/* unlink achan's that belonged to this group (and make sure they're not selected if they weren't visible) */
for (agrp= act->groups.first; agrp; agrp= grp) {
grp= agrp->next;
/* remove if group is selected */
if (SEL_AGRP(agrp)) {
for (chan= agrp->channels.first; chan && chan->grp==agrp; chan= nchan) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
nchan= chan->next;
action_groups_removeachan(act, chan);
BLI_addtail(&act->chanbase, chan);
if (EXPANDED_AGRP(agrp) == 0)
chan->flag &= ~(ACHAN_SELECTED|ACHAN_HILIGHTED);
}
BLI_freelinkN(&act->groups, agrp);
}
}
}
/* 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 references 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--;
}
/* remove action-channel from group(s) */
if (achan->grp)
action_groups_removeachan(act, achan);
/* free memory */
BLI_freelistN(&achan->constraintChannels);
BLI_freelinkN(&act->chanbase, achan);
BLI_freelinkN(&act_data, ale);
2002-10-12 11:37:38 +00:00
}
remake_action_ipos(data);
BIF_undo_push("Delete Action Channels");
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
2002-10-12 11:37:38 +00:00
}
/* '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.0f, 0.001f, 0.1f,
"Clean Threshold");
if (!ok) return;
if (datatype == ACTCONT_GPENCIL) 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);
2002-10-12 11:37:38 +00:00
}
/* little cache for values... */
typedef struct tempFrameValCache {
float frame, val;
} tempFrameValCache;
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
void sample_action_keys (void)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
/* sanity checks */
data= get_action_context(&datatype);
if (data == NULL) return;
if (datatype == ACTCONT_GPENCIL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
actdata_filter(&act_data, filter, data, datatype);
/* loop through filtered data and add keys between selected keyframes on every frame */
for (ale= act_data.first; ale; ale= ale->next) {
IpoCurve *icu= (IpoCurve *)ale->key_data;
BezTriple *bezt, *start=NULL, *end=NULL;
tempFrameValCache *value_cache, *fp;
int sfra, range;
int i, n;
/* find selected keyframes... once pair has been found, add keyframes */
for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
/* check if selected, and which end this is */
if (BEZSELECTED(bezt)) {
if (start) {
/* set end */
end= bezt;
/* cache values then add keyframes using these values, as adding
* keyframes while sampling will affect the outcome...
*/
range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
sfra= (int)( floor(start->vec[1][0]) );
if (range) {
value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
/* sample values */
for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
fp->frame= (float)(sfra + n);
fp->val= eval_icu(icu, fp->frame);
}
/* add keyframes with these */
for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
insert_vert_icu(icu, fp->frame, fp->val, 1);
}
/* free temp cache */
MEM_freeN(value_cache);
/* as we added keyframes, we need to compensate so that bezt is at the right place */
bezt = icu->bezt + i + range - 1;
i += (range - 1);
}
/* bezt was selected, so it now marks the start of a whole new chain to search */
start= bezt;
end= NULL;
}
else {
/* just set start keyframe */
start= bezt;
end= NULL;
}
}
}
/* recalculate channel's handles? */
calchandles_ipocurve(icu);
}
/* admin and redraws */
BLI_freelistN(&act_data);
BIF_undo_push("Sample Action Keys");
allqueue(REMAKEIPO, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
}
/* **************************************************** */
/* COPY/PASTE FOR ACTIONS */
/* - The copy/paste buffer currently stores a set of Action Channels, with temporary
* IPO-blocks, and also temporary IpoCurves which only contain the selected keyframes.
* - Only pastes between compatable data is possible (i.e. same achan->name, ipo-curve type, etc.)
* Unless there is only one element in the buffer, names are also tested to check for compatability.
* - All pasted frames are offset by the same amount. This is calculated as the difference in the times of
* the current frame and the 'first keyframe' (i.e. the earliest one in all channels).
* - The earliest frame is calculated per copy operation.
*/
/* globals for copy/paste data (like for other copy/paste buffers) */
ListBase actcopybuf = {NULL, NULL};
static float actcopy_firstframe= 999999999.0f;
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void free_actcopybuf ()
{
bActionChannel *achan, *anext;
bConstraintChannel *conchan, *cnext;
for (achan= actcopybuf.first; achan; achan= anext) {
anext= achan->next;
if (achan->ipo) {
free_ipo(achan->ipo);
MEM_freeN(achan->ipo);
}
for (conchan=achan->constraintChannels.first; conchan; conchan=cnext) {
cnext= conchan->next;
if (conchan->ipo) {
free_ipo(conchan->ipo);
MEM_freeN(conchan->ipo);
}
BLI_freelinkN(&achan->constraintChannels, conchan);
}
BLI_freelinkN(&actcopybuf, achan);
}
actcopybuf.first= actcopybuf.last= NULL;
actcopy_firstframe= 999999999.0f;
}
/* This function adds data to the copy/paste buffer, freeing existing data first
* Only the selected action channels gets their selected keyframes copied.
*/
void copy_actdata ()
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
/* clear buffer first */
free_actcopybuf();
/* get data */
data= get_action_context(&datatype);
if (data == NULL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* assume that each of these is an ipo-block */
for (ale= act_data.first; ale; ale= ale->next) {
bActionChannel *achan;
Ipo *ipo= ale->key_data;
Ipo *ipn;
IpoCurve *icu, *icn;
BezTriple *bezt;
int i;
/* coerce an action-channel out of owner */
if (ale->ownertype == ACTTYPE_ACHAN) {
bActionChannel *achanO= ale->owner;
achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
strcpy(achan->name, achanO->name);
}
else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
strcpy(achan->name, "#ACP_ShapeKey");
}
else
continue;
BLI_addtail(&actcopybuf, achan);
/* add constraint channel if needed, then add new ipo-block */
if (ale->type == ACTTYPE_CONCHAN) {
bConstraintChannel *conchanO= ale->data;
bConstraintChannel *conchan;
conchan= MEM_callocN(sizeof(bConstraintChannel), "ActCopyPasteConchan");
strcpy(conchan->name, conchanO->name);
BLI_addtail(&achan->constraintChannels, conchan);
conchan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
}
else {
achan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
}
ipn->blocktype = ipo->blocktype;
/* now loop through curves, and only copy selected keyframes */
for (icu= ipo->curve.first; icu; icu= icu->next) {
/* allocate a new curve */
icn= MEM_callocN(sizeof(IpoCurve), "ActCopyPasteIcu");
icn->blocktype = icu->blocktype;
icn->adrcode = icu->adrcode;
BLI_addtail(&ipn->curve, icn);
/* find selected BezTriples to add to the buffer (and set first frame) */
for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
if (BEZSELECTED(bezt)) {
/* add to buffer ipo-curve */
insert_bezt_icu(icn, bezt);
/* check if this is the earliest frame encountered so far */
if (bezt->vec[1][0] < actcopy_firstframe)
actcopy_firstframe= bezt->vec[1][0];
}
}
}
}
/* check if anything ended up in the buffer */
if (ELEM(NULL, actcopybuf.first, actcopybuf.last))
error("Nothing copied to buffer");
/* free temp memory */
BLI_freelistN(&act_data);
}
void paste_actdata ()
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
Object *ob= OBACT;
const float offset = (float)(CFRA - actcopy_firstframe);
char *actname = NULL, *conname = NULL;
short no_name= 0;
/* check if buffer is empty */
if (ELEM(NULL, actcopybuf.first, actcopybuf.last)) {
error("No data in buffer to paste");
return;
}
/* check if single channel in buffer (disregard names if so) */
if (actcopybuf.first == actcopybuf.last)
no_name= 1;
/* get data */
data= get_action_context(&datatype);
if (data == NULL) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* from selected channels */
for (ale= act_data.first; ale; ale= ale->next) {
Ipo *ipo_src = NULL;
bActionChannel *achan;
IpoCurve *ico, *icu;
BezTriple *bezt;
int i;
/* find suitable IPO-block from buffer to paste from */
for (achan= actcopybuf.first; achan; achan= achan->next) {
/* try to match data */
if (ale->ownertype == ACTTYPE_ACHAN) {
bActionChannel *achant= ale->owner;
/* check if we have a corresponding action channel */
if ((no_name) || (strcmp(achan->name, achant->name)==0)) {
actname= achant->name;
/* check if this is a constraint channel */
if (ale->type == ACTTYPE_CONCHAN) {
bConstraintChannel *conchant= ale->data;
bConstraintChannel *conchan;
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (strcmp(conchan->name, conchant->name)==0) {
conname= conchant->name;
ipo_src= conchan->ipo;
break;
}
}
if (ipo_src) break;
}
else {
ipo_src= achan->ipo;
break;
}
}
}
else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
/* check if this action channel is "#ACP_ShapeKey" */
if ((no_name) || (strcmp(achan->name, "#ACP_ShapeKey")==0)) {
actname= NULL;
ipo_src= achan->ipo;
break;
}
}
}
/* this shouldn't happen, but it might */
if (ipo_src == NULL)
continue;
/* loop over curves, pasting keyframes */
for (ico= ipo_src->curve.first; ico; ico= ico->next) {
/* get IPO-curve to paste to (IPO-curve might not exist for destination, so gets created) */
icu= verify_ipocurve((ID *)ob, ico->blocktype, actname, conname, NULL, ico->adrcode, 1);
if (icu) {
/* just start pasting, with the the first keyframe on the current frame, and so on */
for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) {
/* temporarily apply offset to src beztriple while copying */
bezt->vec[0][0] += offset;
bezt->vec[1][0] += offset;
bezt->vec[2][0] += offset;
/* insert the keyframe */
insert_bezt_icu(icu, bezt);
/* un-apply offset from src beztriple after copying */
bezt->vec[0][0] -= offset;
bezt->vec[1][0] -= offset;
bezt->vec[2][0] -= offset;
}
/* recalculate channel's handles? */
calchandles_ipocurve(icu);
}
}
}
/* free temp memory */
BLI_freelistN(&act_data);
/* do depsgraph updates (for 3d-view)? */
if ((ob) && (G.saction->pin==0)) {
if (ob->type == OB_ARMATURE)
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
else
DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
}
/* undo and redraw stuff */
allqueue(REDRAWVIEW3D, 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
BIF_undo_push("Paste Action Keyframes");
}
/* **************************************************** */
/* VARIOUS SETTINGS */
/* This function combines several features related to setting
* various ipo extrapolation/interpolation
*/
void action_set_ipo_flags (short mode, short event)
{
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;
if (datatype == ACTCONT_GPENCIL) 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;
case SET_IPO_MENU: /* called from menus */
case SET_EXTEND_MENU:
break;
default: /* weird, unhandled case */
return;
2002-10-12 11:37:38 +00:00
}
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
2002-10-12 11:37:38 +00:00
/* 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 */
case SET_EXTEND_MENU:
{
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 */
case SET_IPO_MENU:
{
setipotype_ipo(ipo, event);
}
break;
}
2002-10-12 11:37:38 +00:00
}
/* 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);
}
2002-10-12 11:37:38 +00:00
/* this function sets the handles on keyframes */
void sethandles_action_keys (int code)
{
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;
if (datatype == ACTCONT_GPENCIL) 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);
}
/* 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);
}
2002-10-12 11:37:38 +00:00
/* ----------------------------------------- */
2002-10-12 11:37:38 +00:00
/* this gets called when nkey is pressed (no Transform Properties panel yet) */
static void numbuts_action ()
{
void *data;
short datatype;
void *act_channel, *channel_owner;
short chantype;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionGroup *agrp= NULL;
bActionChannel *achan= NULL;
bConstraintChannel *conchan= NULL;
IpoCurve *icu= NULL;
KeyBlock *kb= NULL;
bGPdata *gpd= NULL;
bGPDlayer *gpl= NULL;
short mval[2];
int but=0;
char str[128];
short expand, protect, mute;
float slidermin, slidermax;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
/* figure out what is under cursor */
getmouseco_areawin(mval);
if (mval[0] > NAMEWIDTH)
return;
act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner);
/* create items for clever-numbut */
if (chantype == ACTTYPE_ACHAN) {
/* Action Channel */
achan= (bActionChannel *)act_channel;
strcpy(str, achan->name);
protect= (achan->flag & ACHAN_PROTECTED);
expand = (achan->flag & ACHAN_EXPANDED);
mute = (achan->ipo)? (achan->ipo->muteipo): 0;
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, "Muted", 0, 24, &mute, "Channel is Muted");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
else if (chantype == ACTTYPE_CONCHAN) {
/* Constraint Channel */
conchan= (bConstraintChannel *)act_channel;
strcpy(str, conchan->name);
protect= (conchan->flag & CONSTRAINT_CHANNEL_PROTECTED);
mute = (conchan->ipo)? (conchan->ipo->muteipo): 0;
add_numbut(but++, TEX, "ConChan: ", 0, 29, str, "Name of Constraint Channel");
add_numbut(but++, TOG|SHO, "Muted", 0, 24, &mute, "Channel is Muted");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
else if (chantype == ACTTYPE_ICU) {
/* IPO Curve */
icu= (IpoCurve *)act_channel;
if (G.saction->pin)
sprintf(str, getname_ipocurve(icu, NULL));
else
sprintf(str, getname_ipocurve(icu, OBACT));
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;
}
2002-10-12 11:37:38 +00:00
}
slidermin= icu->slide_min;
slidermax= icu->slide_max;
//protect= (icu->flag & IPO_PROTECT);
mute = (icu->flag & IPO_MUTE);
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, "Muted", 0, 24, &mute, "Channel is Muted");
//add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Channel is Protected");
}
else if (chantype == ACTTYPE_SHAPEKEY) {
/* Shape Key */
kb= (KeyBlock *)act_channel;
if (kb->name[0] == '\0') {
Key *key= (Key *)data;
int keynum= BLI_findindex(&key->block, kb);
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);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (chantype == ACTTYPE_GROUP) {
/* Action Group */
agrp= (bActionGroup *)act_channel;
strcpy(str, agrp->name);
protect= (agrp->flag & AGRP_PROTECTED);
expand = (agrp->flag & AGRP_EXPANDED);
add_numbut(but++, TEX, "ActGroup: ", 0, 31, str, "Name of Action Group");
add_numbut(but++, TOG|SHO, "Expanded", 0, 24, &expand, "Action Group is Expanded");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Group is Protected");
}
else if (chantype == ACTTYPE_GPLAYER) {
/* Grease-Pencil Layer */
gpd= (bGPdata *)channel_owner;
gpl= (bGPDlayer *)act_channel;
strcpy(str, gpl->info);
protect= (gpl->flag & GP_LAYER_LOCKED);
mute = (gpl->flag & GP_LAYER_HIDE);
add_numbut(but++, TEX, "GP-Layer: ", 0, 128, str, "Name of Grease Pencil Layer");
add_numbut(but++, TOG|SHO, "Hide", 0, 24, &mute, "Grease Pencil Layer is Visible");
add_numbut(but++, TOG|SHO, "Protected", 0, 24, &protect, "Grease Pencil Layer is Protected");
}
else {
/* nothing under-cursor */
return;
2002-10-12 11:37:38 +00:00
}
/* 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;
if (mute) icu->flag |= IPO_MUTE;
else icu->flag &= ~IPO_MUTE;
}
else if (conchan) {
strcpy(conchan->name, str);
if (protect) conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
else conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
if (conchan->ipo)
conchan->ipo->muteipo = mute;
}
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;
if (achan->ipo)
achan->ipo->muteipo = mute;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (agrp) {
strcpy(agrp->name, str);
BLI_uniquename(&( ((bAction *)data)->groups ), agrp, "Group", offsetof(bActionGroup, name), 32);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
if (expand) agrp->flag |= AGRP_EXPANDED;
else agrp->flag &= ~AGRP_EXPANDED;
if (protect) agrp->flag |= AGRP_PROTECTED;
else agrp->flag &= ~AGRP_PROTECTED;
}
else if (gpl) {
strcpy(gpl->info, str);
BLI_uniquename(&gpd->layers, gpl, "GP_Layer", offsetof(bGPDlayer, info), 128);
if (mute) gpl->flag |= GP_LAYER_HIDE;
else gpl->flag &= ~GP_LAYER_HIDE;;
if (protect) gpl->flag |= GP_LAYER_LOCKED;
else gpl->flag &= ~GP_LAYER_LOCKED;
}
allqueue(REDRAWACTION, 0);
allspace(REMAKEIPO, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWVIEW3D, 0);
2002-10-12 11:37:38 +00:00
}
}
/* Set/clear a particular flag (setting) for all selected + visible channels
* mode: 0 = toggle, 1 = turn on, 2 = turn off
*/
void setflag_action_channels (short mode)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
char str[32];
short val;
/* get data */
data= get_action_context(&datatype);
if (data == NULL) return;
/* get setting to affect */
if (mode == 2) {
val= pupmenu("Disable Setting%t|Protect %x1|Mute%x2");
sprintf(str, "Disable Action Setting");
}
else if (mode == 1) {
val= pupmenu("Enable Setting%t|Protect %x1|Mute%x2");
sprintf(str, "Enable Action Setting");
}
else {
val= pupmenu("Toggle Setting%t|Protect %x1|Mute%x2");
sprintf(str, "Toggle Action Setting");
}
if (val <= 0) return;
/* filter data */
filter= (ACTFILTER_VISIBLE | ACTFILTER_CHANNELS | ACTFILTER_SEL);
actdata_filter(&act_data, filter, data, datatype);
/* affect selected channels */
for (ale= act_data.first; ale; ale= ale->next) {
switch (ale->type) {
case ACTTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)ale->data;
/* only 'protect' is available */
if (val == 1) {
if (mode == 2)
agrp->flag &= ~AGRP_PROTECTED;
else if (mode == 1)
agrp->flag |= AGRP_PROTECTED;
else
agrp->flag ^= AGRP_PROTECTED;
}
}
break;
case ACTTYPE_ACHAN:
{
bActionChannel *achan= (bActionChannel *)ale->data;
/* 'protect' and 'mute' */
if ((val == 2) && (achan->ipo)) {
Ipo *ipo= achan->ipo;
/* mute */
if (mode == 2)
ipo->muteipo= 0;
else if (mode == 1)
ipo->muteipo= 1;
else
ipo->muteipo= (ipo->muteipo) ? 0 : 1;
}
else if (val == 1) {
/* protected */
if (mode == 2)
achan->flag &= ~ACHAN_PROTECTED;
else if (mode == 1)
achan->flag |= ACHAN_PROTECTED;
else
achan->flag ^= ACHAN_PROTECTED;
}
}
break;
case ACTTYPE_CONCHAN:
{
bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
/* 'protect' and 'mute' */
if ((val == 2) && (conchan->ipo)) {
Ipo *ipo= conchan->ipo;
/* mute */
if (mode == 2)
ipo->muteipo= 0;
else if (mode == 1)
ipo->muteipo= 1;
else
ipo->muteipo= (ipo->muteipo) ? 0 : 1;
}
else if (val == 1) {
/* protect */
if (mode == 2)
conchan->flag &= ~CONSTRAINT_CHANNEL_PROTECTED;
else if (mode == 1)
conchan->flag |= CONSTRAINT_CHANNEL_PROTECTED;
else
conchan->flag ^= CONSTRAINT_CHANNEL_PROTECTED;
}
}
break;
case ACTTYPE_ICU:
{
IpoCurve *icu= (IpoCurve *)ale->data;
/* mute */
if (val == 2) {
if (mode == 2)
icu->flag &= ~IPO_MUTE;
else if (mode == 1)
icu->flag |= IPO_MUTE;
else
icu->flag ^= IPO_MUTE;
}
}
break;
case ACTTYPE_GPLAYER:
{
bGPDlayer *gpl= (bGPDlayer *)ale->data;
/* 'protect' and 'mute' */
if (val == 2) {
/* mute */
if (mode == 2)
gpl->flag &= ~GP_LAYER_HIDE;
else if (mode == 1)
gpl->flag |= GP_LAYER_HIDE;
else
gpl->flag ^= GP_LAYER_HIDE;
}
else if (val == 1) {
/* protected */
if (mode == 2)
gpl->flag &= ~GP_LAYER_LOCKED;
else if (mode == 1)
gpl->flag |= GP_LAYER_LOCKED;
else
gpl->flag ^= GP_LAYER_LOCKED;
}
}
break;
}
}
BLI_freelistN(&act_data);
BIF_undo_push(str);
allspace(REMAKEIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWNLA, 0);
}
/* **************************************************** */
/* CHANNEL SELECTION */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* select_mode = SELECT_REPLACE
* = SELECT_ADD
* = SELECT_SUBTRACT
* = SELECT_INVERT
*/
static void select_action_group (bAction *act, bActionGroup *agrp, int selectmode)
{
/* Select the channel based on the selection mode */
short select;
switch (selectmode) {
case SELECT_ADD:
agrp->flag |= AGRP_SELECTED;
break;
case SELECT_SUBTRACT:
agrp->flag &= ~AGRP_SELECTED;
break;
case SELECT_INVERT:
agrp->flag ^= AGRP_SELECTED;
break;
}
select = (agrp->flag & AGRP_SELECTED) ? 1 : 0;
set_active_actiongroup(act, agrp, select);
}
static void hilight_channel (bAction *act, bActionChannel *achan, short select)
2002-10-12 11:37:38 +00:00
{
bActionChannel *curchan;
2002-10-12 11:37:38 +00:00
if (!act)
return;
for (curchan=act->chanbase.first; curchan; curchan=curchan->next) {
if (curchan==achan && select)
curchan->flag |= ACHAN_HILIGHTED;
else
curchan->flag &= ~ACHAN_HILIGHTED;
}
}
/* Syncs selection of channels with selection of object elements in posemode */
/* messy call... */
static void select_poseelement_by_name (char *name, int select)
{
Object *ob= OBACT;
bPoseChannel *pchan;
if ((ob==NULL) || (ob->type!=OB_ARMATURE))
return;
if (abs(select) == 2) {
for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next)
pchan->bone->flag &= ~(BONE_ACTIVE);
2002-10-12 11:37:38 +00:00
}
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);
2002-10-12 11:37:38 +00:00
}
}
/* apparently within active object context */
/* called extern, like on bone selection */
void select_actionchannel_by_name (bAction *act, char *name, int select)
2002-10-12 11:37:38 +00:00
{
bActionChannel *achan;
2002-10-12 11:37:38 +00:00
if (act == NULL)
2002-10-12 11:37:38 +00:00
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;
}
2002-10-12 11:37:38 +00:00
}
}
/* select_mode = SELECT_REPLACE
* = SELECT_ADD
* = SELECT_SUBTRACT
* = SELECT_INVERT
*/
Version 1.0 of the new Outliner The outliner is a hierarchical diagram displaying a list of data in Blender and its dependencies. The 'databrowse' doesn't really show it, and Oops is too chaotic still. And most of all, the former two don't offer much tools. After discussions on irc, Matt came with this design proposal; http://mke3.net/blender/interface/layout/outliner/ Which is closely followed for the implementation. The current version only shows all 'library data' in Blender (objects, meshes, ipos, etc) and not the 'direct data' such as vertex groups or NLA. I decided to make it inside the Oopw window, as an option. You can find the option in the "View" pulldown, or directly invoke it with ALT+SHIFT+F9 Here's a quick overview of the Outliner GUI: - Header pulldown has options what it can show (Visible = in current layers) - click on triangle arrow to open/close - press AKEY to open/close all - Leftmouse click on an item activates; and does based on type a couple of extra things: - activates a scene - selects/activates the Object - enters editmode (if clicked on Mesh, Curve, etc) - shows the appropriate Shading buttons (Lamp, Material, Texture) - sets the IpoWindow to the current IPO - activates the Ipo-channel in an Action - Selected and Active objects are drawn in its Theme selection color - SHIFT+click on Object does extend-select - Press DOTkey to get the current active data in center of view TODO; - rightmouse selection; for indicating operations like delete or duplicate - showing more data types - icon (re)design... - lotsof options as described in Matts paper still...
2004-10-06 18:55:00 +00:00
/* exported for outliner (ton) */
/* apparently within active object context */
int select_channel (bAction *act, bActionChannel *achan, int selectmode)
{
/* Select the channel based on the selection mode */
int flag;
switch (selectmode) {
case SELECT_ADD:
achan->flag |= ACHAN_SELECTED;
break;
case SELECT_SUBTRACT:
achan->flag &= ~ACHAN_SELECTED;
break;
case SELECT_INVERT:
achan->flag ^= ACHAN_SELECTED;
break;
}
flag = (achan->flag & ACHAN_SELECTED) ? 1 : 0;
hilight_channel(act, achan, flag);
select_poseelement_by_name(achan->name, flag);
return flag;
}
static int select_constraint_channel (bAction *act,
bConstraintChannel *conchan,
int selectmode)
{
/* Select the constraint channel based on the selection mode */
int flag;
switch (selectmode) {
case SELECT_ADD:
conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
break;
case SELECT_SUBTRACT:
conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
break;
case SELECT_INVERT:
conchan->flag ^= CONSTRAINT_CHANNEL_SELECT;
break;
}
flag = (conchan->flag & CONSTRAINT_CHANNEL_SELECT) ? 1 : 0;
return flag;
}
int select_icu_channel (bAction *act, IpoCurve *icu, int selectmode)
{
/* Select the channel based on the selection mode */
int flag;
switch (selectmode) {
case SELECT_ADD:
icu->flag |= IPO_SELECT;
break;
case SELECT_SUBTRACT:
icu->flag &= ~IPO_SELECT;
break;
case SELECT_INVERT:
icu->flag ^= IPO_SELECT;
break;
}
flag = (icu->flag & IPO_SELECT) ? 1 : 0;
return flag;
}
int select_gplayer_channel (bGPdata *gpd, bGPDlayer *gpl, int selectmode)
{
/* Select the channel based on the selection mode */
int flag;
switch (selectmode) {
case SELECT_ADD:
gpl->flag |= GP_LAYER_SELECT;
break;
case SELECT_SUBTRACT:
gpl->flag &= ~GP_LAYER_SELECT;
break;
case SELECT_INVERT:
gpl->flag ^= GP_LAYER_SELECT;
break;
}
flag = (gpl->flag & GP_LAYER_SELECT) ? 1 : 0;
if (flag)
gpencil_layer_setactive(gpd, gpl);
return flag;
}
/* select only the active action-group's action channels */
void select_action_group_channels (bAction *act, bActionGroup *agrp)
{
bActionChannel *achan;
/* error checking */
if (ELEM(NULL, act, agrp))
return;
/* deselect all other channels */
deselect_actionchannels(act, 0);
/* only select channels in group */
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
select_channel(act, achan, SELECT_ADD);
/* messy... set active bone */
select_poseelement_by_name(achan->name, 1);
}
}
/* ----------------------------------------- */
2002-10-12 11:37:38 +00:00
/* De-selects or inverts the selection of Channels in a given Action
* mode: 0 = default behaviour (select all), 1 = test if (de)select all, 2 = invert all
*/
void deselect_actionchannels (bAction *act, short mode)
{
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 (mode == 1) {
for (ale= act_data.first; ale; ale= ale->next) {
if (sel == 0)
break;
switch (ale->type) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
case ACTTYPE_GROUP:
if (ale->flag & AGRP_SELECTED)
sel= 0;
break;
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;
This commit adds two of my recent animation editing related patches: #5061 - Ipo/Action 'Cleaning' #5071 - 'Only Needed' Keyframing Option ==================== * IPO/Action 'Cleaning': It removes un-necessary keyframes from individual ipo curves. - In both editors, the hotkey is currently the OKEY. Also accesable from menus of each editor. - There is currently a 'threshold' popup. This sets the value that the cleaner uses to determine if two keys have same time/value There are a few improvements that could still be made, such as: - There are a few cases that it still doesn't handle yet, such as when un-needed keyframes lie on a linear line (and similiar cases). This shall be improved soon. - Also, for some reason, after running cleaning while in ipo editor editmode, all but the active curve are hidden. ==================== * 'Only Needed' Keyframing Option: This patch adds a new keyframing option for objects and bones. It only adds keyframes where they are needed, judging from the surrounding points on that curve. Notes about this keyframing option: - Works like the existing 'Avail' option, except it checks if the keyframe is needed. - Currently uses hardcoded threshold for determining if same value. [quote] /* Cases where keyframes should not be added: * 1. Keyframe to be added bewteen two keyframes with similar values * 2. Keyframe to be added between two keyframes with similar times * 3. Keyframe lies at point that intersects the linear line between two keyframes */ [/unquote]
2006-11-09 08:43:27 +00:00
}
}
}
else
sel= 0;
/* Now set the flags */
for (ale= act_data.first; ale; ale= ale->next) {
switch (ale->type) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
case ACTTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)ale->data;
if (mode == 2)
agrp->flag ^= AGRP_SELECTED;
else if (sel)
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
agrp->flag |= AGRP_SELECTED;
else
agrp->flag &= ~AGRP_SELECTED;
agrp->flag &= ~AGRP_ACTIVE;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
break;
case ACTTYPE_ACHAN:
{
bActionChannel *achan= (bActionChannel *)ale->data;
if (mode == 2)
achan->flag ^= AGRP_SELECTED;
else if (sel)
achan->flag |= ACHAN_SELECTED;
else
achan->flag &= ~ACHAN_SELECTED;
select_poseelement_by_name(achan->name, sel);
achan->flag &= ~ACHAN_HILIGHTED;
}
break;
case ACTTYPE_CONCHAN:
{
bConstraintChannel *conchan= (bConstraintChannel *)ale->data;
if (mode == 2)
conchan->flag ^= CONSTRAINT_CHANNEL_SELECT;
else if (sel)
conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
else
conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
}
break;
case ACTTYPE_ICU:
{
IpoCurve *icu= (IpoCurve *)ale->data;
if (mode == 2)
icu->flag ^= IPO_SELECT;
else if (sel)
icu->flag |= IPO_SELECT;
else
icu->flag &= ~IPO_SELECT;
icu->flag &= ~IPO_ACTIVE;
}
break;
2002-10-12 11:37:38 +00:00
}
}
/* Cleanup */
BLI_freelistN(&act_data);
2002-10-12 11:37:38 +00:00
}
/* deselects channels in the action editor */
void deselect_action_channels (short mode)
{
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, mode);
else if (datatype == ACTCONT_GPENCIL)
deselect_gpencil_layers(data, mode);
// 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;
/* determine type-based settings */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE);
else
filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
/* filter data */
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 (ale->type == ACTTYPE_GPLAYER) {
if (is_gplayer_frame_selected(ale->data)) {
sel= 0;
break;
}
}
else {
if (is_ipo_key_selected(ale->key_data)) {
sel= 0;
break;
}
}
}
}
/* Now set the flags */
for (ale= act_data.first; ale; ale= ale->next) {
if (ale->type == ACTTYPE_GPLAYER)
set_gplayer_frame_selection(ale->data, sel);
else
set_ipo_key_selection(ale->key_data, sel);
}
/* Cleanup */
BLI_freelistN(&act_data);
}
/* 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;
/* 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;
}
/* depending on mode */
switch (mode) {
case 0: /* all in channel*/
{
void *act_channel, *channel_owner;
short chantype;
/* get channel, and act according to type */
act_channel= get_nearest_act_channel(mval, &chantype, &channel_owner);
switch (chantype) {
case ACTTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)act_channel;
bActionChannel *achan;
bConstraintChannel *conchan;
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
select_ipo_bezier_keys(achan->ipo, select_mode);
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
select_ipo_bezier_keys(conchan->ipo, select_mode);
}
}
break;
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;
case ACTTYPE_GPLAYER:
{
bGPDlayer *gpl= (bGPDlayer *)act_channel;
select_gpencil_frames(gpl, 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.5f;
rectf.xmax = rectf.xmax + 0.5f;
/* filter data */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE);
else
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);
}
/* Selects all visible keyframes between the specified markers */
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(NLA_ACTION_SCALED && 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 {
borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
}
}
/* Cleanup */
BLI_freelistN(&act_data);
}
/* Selects all the keyframes on either side of the current frame (depends on which side the mouse is on) */
void selectkeys_leftright (short leftright, short select_mode)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
float min, max;
if (select_mode==SELECT_REPLACE) {
select_mode=SELECT_ADD;
deselect_action_keys(0, 0);
}
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
if (leftright == 1) {
min = -MAXFRAMEF;
max = (float)(CFRA + 0.1f);
}
else {
min = (float)(CFRA - 0.1f);
max = MAXFRAMEF;
}
/* filter data */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE);
else
filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* select keys on the side where most data occurs */
for (ale= act_data.first; ale; ale= ale->next) {
if (NLA_ACTION_SCALED && 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 if (ale->type == ACTTYPE_GPLAYER)
borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD);
else
borderselect_ipo_key(ale->key_data, min, max, SELECT_ADD);
}
/* Cleanup */
BLI_freelistN(&act_data);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWIPO, 0);
}
/* ----------------------------------------- */
/* Jumps to the frame where the next/previous keyframe (that is visible) occurs
* dir: indicates direction
*/
void nextprev_action_keyframe (short dir)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
ListBase elems= {NULL, NULL};
CfraElem *ce, *nearest=NULL;
float dist, min_dist= 1000000;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
/* abort if no direction */
if (dir == 0)
return;
/* get list of keyframes that can be used (in global-time) */
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE);
else
filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
for (ale= act_data.first; ale; ale= ale->next) {
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
make_cfra_list(ale->key_data, &elems);
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
}
else if (ale->type == ACTTYPE_GPLAYER)
gplayer_make_cfra_list(ale->key_data, &elems, 0);
else
make_cfra_list(ale->key_data, &elems);
}
BLI_freelistN(&act_data);
/* find nearest keyframe to current frame */
for (ce= elems.first; ce; ce= ce->next) {
dist= ABS(ce->cfra - CFRA);
if (dist < min_dist) {
min_dist= dist;
nearest= ce;
}
}
/* if a nearest keyframe was found, use the one either side */
if (nearest) {
short changed= 0;
if ((dir > 0) && (nearest->next)) {
CFRA= (int)nearest->next->cfra;
changed= 1;
}
else if ((dir < 0) && (nearest->prev)) {
CFRA= (int)nearest->prev->cfra;
changed= 1;
}
if (changed) {
update_for_newframe();
allqueue(REDRAWALL, 0);
}
}
/* free temp data */
BLI_freelistN(&elems);
}
/* ----------------------------------------- */
/* 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);
}
}
}
/* 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 */
if (datatype == ACTCONT_GPENCIL) {
filter= (ACTFILTER_VISIBLE);
actdata_filter(&act_data, filter, data, datatype);
for (ale= act_data.first; ale; ale= ale->next)
gplayer_make_cfra_list(ale->data, &elems, 1);
}
else {
filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
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);
/* apply scaled action correction if needed */
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
for (ce= elems.first; ce; ce= ce->next)
ce->cfra= get_action_frame(OBACT, ce->cfra);
}
break;
case 3: /* current frame */
/* make a single CfraElem */
ce= MEM_callocN(sizeof(CfraElem), "cfraElem");
BLI_addtail(&elems, ce);
/* apply scaled action correction if needed */
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION)
ce->cfra= (float)get_action_frame(OBACT, (float)CFRA);
else
ce->cfra= (float)CFRA;
}
/* loop through all of the keys and select additional keyframes
* based on the keys found to be selected above
*/
if (datatype == ACTCONT_GPENCIL)
filter= (ACTFILTER_VISIBLE);
else
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) {
/* select elements with frame number matching cfraelem */
if (ale->type == ACTTYPE_GPLAYER) {
bGPDlayer *gpl= (bGPDlayer *)ale->data;
bGPDframe *gpf;
for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
if ( (int)ce->cfra == gpf->framenum )
gpf->flag |= GP_FRAME_SELECT;
}
}
else {
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 action-channels */
void borderselect_actionchannels (void)
{
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
void *data;
short datatype;
rcti rect;
rctf rectf;
int val, selectmode;
short mval[2];
float ymin, ymax;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
if (ELEM(datatype, ACTCONT_ACTION, ACTCONT_GPENCIL)==0) return;
/* draw and handle the borderselect stuff (ui) and get the select rect */
if ( (val = get_border(&rect, 3)) ) {
selectmode= ((val==LEFTMOUSE) ? SELECT_ADD : SELECT_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);
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 channel is within border-select region, alter it */
if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
/* only the following types can be selected */
switch (ale->type) {
case ACTTYPE_GROUP: /* action group */
{
bActionGroup *agrp= (bActionGroup *)ale->data;
if (selectmode == SELECT_ADD)
agrp->flag |= AGRP_SELECTED;
else
agrp->flag &= ~AGRP_SELECTED;
}
break;
case ACTTYPE_ACHAN: /* action channel */
case ACTTYPE_FILLIPO: /* expand ipo curves = action channel */
case ACTTYPE_FILLCON: /* expand constraint channels = action channel */
{
bActionChannel *achan= (bActionChannel *)ale->data;
if (selectmode == SELECT_ADD)
achan->flag |= ACHAN_SELECTED;
else
achan->flag &= ~ACHAN_SELECTED;
/* messy... set active bone */
select_poseelement_by_name(achan->name, selectmode);
}
break;
case ACTTYPE_CONCHAN: /* constraint channel */
{
bConstraintChannel *conchan = (bConstraintChannel *)ale->data;
if (selectmode == SELECT_ADD)
conchan->flag |= CONSTRAINT_CHANNEL_SELECT;
else
conchan->flag &= ~CONSTRAINT_CHANNEL_SELECT;
}
break;
case ACTTYPE_ICU: /* ipo-curve channel */
{
IpoCurve *icu = (IpoCurve *)ale->data;
if (selectmode == SELECT_ADD)
icu->flag |= IPO_SELECT;
else
icu->flag &= ~IPO_SELECT;
}
break;
case ACTTYPE_GPLAYER: /* grease-pencil layer */
{
bGPDlayer *gpl = (bGPDlayer *)ale->data;
if (selectmode == SELECT_ADD)
gpl->flag |= GP_LAYER_SELECT;
else
gpl->flag &= ~GP_LAYER_SELECT;
}
break;
}
/* select action-channel 'owner' */
if ((ale->owner) && (ale->ownertype == ACTTYPE_ACHAN)) {
bActionChannel *achano= (bActionChannel *)ale->owner;
/* messy... set active bone */
select_poseelement_by_name(achano->name, selectmode);
}
}
ymax=ymin;
}
/* cleanup */
BLI_freelistN(&act_data);
BIF_undo_push("Border Select Action");
allqueue(REDRAWIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWVIEW3D, 0);
}
}
/* some quick defines for borderselect modes */
enum {
ACTEDIT_BORDERSEL_ALL = 0,
ACTEDIT_BORDERSEL_FRA,
ACTEDIT_BORDERSEL_CHA
};
/* 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, mode;
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;
/* what should be selected (based on the starting location of cursor) */
getmouseco_areawin(mval);
if (IN_2D_VERT_SCROLL(mval))
mode = ACTEDIT_BORDERSEL_CHA;
else if (IN_2D_HORIZ_SCROLL(mval))
mode = ACTEDIT_BORDERSEL_FRA;
else
mode = ACTEDIT_BORDERSEL_ALL;
/* 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 action is mapped in NLA, it returns a correction */
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
rectf.xmin= get_action_frame(OBACT, rectf.xmin);
rectf.xmax= get_action_frame(OBACT, rectf.xmax);
}
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);
/* what gets selected depends on the mode (based on initial position of cursor) */
switch (mode) {
case ACTEDIT_BORDERSEL_FRA: /* all in frame(s) */
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);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (ale->type == ACTTYPE_GROUP) {
bActionGroup *agrp= ale->data;
bActionChannel *achan;
bConstraintChannel *conchan;
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
}
}
else if (ale->type == ACTTYPE_GPLAYER) {
borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode);
}
break;
case ACTEDIT_BORDERSEL_CHA: /* all in channel(s) */
if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
if (ale->key_data) {
if (ale->datatype == ALE_IPO)
select_ipo_bezier_keys(ale->key_data, selectmode);
else if (ale->datatype == ALE_ICU)
select_icu_bezier_keys(ale->key_data, selectmode);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (ale->type == ACTTYPE_GROUP) {
bActionGroup *agrp= ale->data;
bActionChannel *achan;
bConstraintChannel *conchan;
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
select_ipo_bezier_keys(achan->ipo, selectmode);
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
select_ipo_bezier_keys(conchan->ipo, selectmode);
}
}
else if (ale->type == ACTTYPE_GPLAYER) {
select_gpencil_frames(ale->data, selectmode);
}
}
break;
default: /* any keyframe inside region defined by region */
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);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (ale->type == ACTTYPE_GROUP) {
bActionGroup *agrp= ale->data;
bActionChannel *achan;
bConstraintChannel *conchan;
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
borderselect_ipo_key(achan->ipo, rectf.xmin, rectf.xmax, selectmode);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
borderselect_ipo_key(conchan->ipo, rectf.xmin, rectf.xmax, selectmode);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
}
else if (ale->type == ACTTYPE_GPLAYER) {
borderselect_gplayer_frames(ale->data, rectf.xmin, rectf.xmax, selectmode);
}
}
}
ymax=ymin;
}
/* 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= NULL;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionGroup *agrp= NULL;
bActionChannel *achan= NULL;
bConstraintChannel *conchan= NULL;
IpoCurve *icu= NULL;
bGPdata *gpd = NULL;
bGPDlayer *gpl = NULL;
TimeMarker *marker, *pmarker;
void *act_channel;
2008-02-03 18:50:03 +00:00
short sel, act_type = 0;
float selx = 0.0;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype == ACTCONT_ACTION) act= (bAction *)data;
if (datatype == ACTCONT_GPENCIL) gpd= (bGPdata *)data;
act_channel= get_nearest_action_key(&selx, &sel, &act_type, &achan);
marker= find_nearest_marker(SCE_MARKERS, 1);
pmarker= (act) ? find_nearest_marker(&act->markers, 1) : NULL;
if (marker) {
/* what about scene's markers? */
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(REDRAWMARKER, 0);
}
else if (pmarker) {
/* action's markers are drawn behind scene markers */
if (selectmode == SELECT_REPLACE) {
action_set_activemarker(act, pmarker, 1);
pmarker->flag |= SELECT;
}
else if (selectmode == SELECT_INVERT) {
if (pmarker->flag & SELECT) {
pmarker->flag &= ~SELECT;
action_set_activemarker(act, NULL, 0);
}
else {
pmarker->flag |= SELECT;
action_set_activemarker(act, pmarker, 0);
}
}
else if (selectmode == SELECT_ADD) {
pmarker->flag |= SELECT;
action_set_activemarker(act, pmarker, 0);
}
else if (selectmode == SELECT_SUBTRACT) {
pmarker->flag &= ~SELECT;
action_set_activemarker(act, NULL, 0);
}
// TODO: local-markers cannot be moved atm...
//std_rmouse_transform(transform_markers);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
else if (act_channel) {
/* must have been a channel */
switch (act_type) {
case ACTTYPE_ICU:
icu= (IpoCurve *)act_channel;
break;
case ACTTYPE_CONCHAN:
conchan= (bConstraintChannel *)act_channel;
break;
case ACTTYPE_ACHAN:
achan= (bActionChannel *)act_channel;
break;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
case ACTTYPE_GROUP:
agrp= (bActionGroup *)act_channel;
break;
case ACTTYPE_GPLAYER:
gpl= (bGPDlayer *)act_channel;
break;
default:
return;
}
if (selectmode == SELECT_REPLACE) {
selectmode = SELECT_ADD;
deselect_action_keys(0, 0);
if (datatype == ACTCONT_ACTION) {
deselect_action_channels(0);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* Highlight either an Action-Channel or Action-Group */
if (achan) {
achan->flag |= ACHAN_SELECTED;
hilight_channel(act, achan, 1);
select_poseelement_by_name(achan->name, 2); /* 2 is activate */
}
else if (agrp) {
agrp->flag |= AGRP_SELECTED;
set_active_actiongroup(act, agrp, 1);
}
}
else if (datatype == ACTCONT_GPENCIL) {
deselect_action_channels(0);
/* Highlight gpencil layer */
gpl->flag |= GP_LAYER_SELECT;
gpencil_layer_setactive(gpd, gpl);
}
}
if (icu)
select_icu_key(icu, selx, selectmode);
else if (conchan)
select_ipo_key(conchan->ipo, selx, selectmode);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (achan)
select_ipo_key(achan->ipo, selx, selectmode);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else if (agrp) {
for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
select_ipo_key(achan->ipo, selx, selectmode);
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next)
select_ipo_key(conchan->ipo, selx, selectmode);
}
}
else if (gpl)
select_gpencil_frame(gpl, (int)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);
}
}
/* lefthand side - mouse-click */
static void mouse_actionchannels (short mval[])
{
bAction *act= G.saction->action;
void *data, *act_channel, *channel_owner;
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, &chantype, &channel_owner);
/* action to take depends on what channel we've got */
switch (chantype) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
case ACTTYPE_GROUP:
{
bActionGroup *agrp= (bActionGroup *)act_channel;
if ((mval[0] < 16) && (agrp->channels.first)) {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* toggle expand */
agrp->flag ^= AGRP_EXPANDED;
}
else if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle protection/locking */
agrp->flag ^= AGRP_PROTECTED;
}
else {
/* select/deselect group */
if (G.qual == LR_SHIFTKEY) {
/* inverse selection status of group */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
select_action_group(act, agrp, SELECT_INVERT);
}
else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY)) {
/* select all in group (and deselect everthing else) */
select_action_group_channels(act, agrp);
select_action_group(act, agrp, SELECT_ADD);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
else {
/* select group by itself */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
deselect_actionchannels(act, 0);
select_action_group(act, agrp, SELECT_ADD);
}
}
}
break;
case ACTTYPE_ACHAN:
{
bActionChannel *achan= (bActionChannel *)act_channel;
if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle protect */
achan->flag ^= ACHAN_PROTECTED;
}
else if ((mval[0] >= (NAMEWIDTH-32)) && (achan->ipo)) {
/* toggle mute */
achan->ipo->muteipo = (achan->ipo->muteipo)? 0: 1;
}
else if (mval[0] <= 17) {
/* toggle expand */
achan->flag ^= ACHAN_EXPANDED;
}
else {
/* select/deselect achan */
if (G.qual & LR_SHIFTKEY) {
select_channel(act, achan, SELECT_INVERT);
}
else {
deselect_actionchannels(act, 0);
select_channel(act, achan, SELECT_ADD);
}
/* messy... set active bone */
select_poseelement_by_name(achan->name, 2);
}
}
break;
case ACTTYPE_FILLIPO:
{
bActionChannel *achan= (bActionChannel *)act_channel;
achan->flag ^= ACHAN_SHOWIPO;
if ((mval[0] > 24) && (achan->flag & ACHAN_SHOWIPO)) {
/* select+make active achan */
deselect_actionchannels(act, 0);
select_channel(act, achan, SELECT_ADD);
/* messy... set active bone */
select_poseelement_by_name(achan->name, 2);
}
}
break;
case ACTTYPE_FILLCON:
{
bActionChannel *achan= (bActionChannel *)act_channel;
achan->flag ^= ACHAN_SHOWCONS;
if ((mval[0] > 24) && (achan->flag & ACHAN_SHOWCONS)) {
/* select+make active achan */
deselect_actionchannels(act, 0);
select_channel(act, achan, SELECT_ADD);
/* messy... set active bone */
select_poseelement_by_name(achan->name, 2);
}
}
break;
case ACTTYPE_ICU:
{
IpoCurve *icu= (IpoCurve *)act_channel;
#if 0 /* disabled until all ipo tools support this -------> */
if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle protection */
icu->flag ^= IPO_PROTECT;
}
#endif /* <------- end of disabled code */
if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle mute */
icu->flag ^= IPO_MUTE;
}
else {
/* select/deselect */
select_icu_channel(act, icu, SELECT_INVERT);
}
allspace(REMAKEIPO, 0);
}
break;
case ACTTYPE_CONCHAN:
{
bConstraintChannel *conchan= (bConstraintChannel *)act_channel;
if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle protection */
conchan->flag ^= CONSTRAINT_CHANNEL_PROTECTED;
}
else if ((mval[0] >= (NAMEWIDTH-32)) && (conchan->ipo)) {
/* toggle mute */
conchan->ipo->muteipo = (conchan->ipo->muteipo)? 0: 1;
}
else {
/* select/deselect */
select_constraint_channel(act, conchan, SELECT_INVERT);
}
}
break;
case ACTTYPE_GPDATABLOCK:
{
bGPdata *gpd= (bGPdata *)act_channel;
/* toggle expand */
gpd->flag ^= GP_DATA_EXPAND;
}
break;
case ACTTYPE_GPLAYER:
{
bGPdata *gpd= (bGPdata *)channel_owner;
bGPDlayer *gpl= (bGPDlayer *)act_channel;
if (mval[0] >= (NAMEWIDTH-16)) {
/* toggle lock */
gpl->flag ^= GP_LAYER_LOCKED;
}
else if (mval[0] >= (NAMEWIDTH-32)) {
/* toggle hide */
gpl->flag ^= GP_LAYER_HIDE;
}
else {
/* select/deselect */
if (G.qual & LR_SHIFTKEY) {
select_gplayer_channel(gpd, gpl, SELECT_INVERT);
}
else {
deselect_gpencil_layers(data, 0);
select_gplayer_channel(gpd, gpl, SELECT_INVERT);
}
}
}
break;
default:
return;
}
allqueue(REDRAWIPO, 0);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWTIME, 0);
allqueue(REDRAWOOPS, 0);
allqueue(REDRAWBUTSALL, 0);
}
/* **************************************************** */
/* ACTION CHANNEL RE-ORDERING */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* make sure all action-channels belong to a group (and clear action's list) */
static void split_groups_action_temp (bAction *act, bActionGroup *tgrp)
{
bActionChannel *achan;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionGroup *agrp;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* Separate action-channels into lists per group */
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
if (agrp->channels.first) {
achan= agrp->channels.last;
act->chanbase.first= achan->next;
achan= agrp->channels.first;
achan->prev= NULL;
achan= agrp->channels.last;
achan->next= NULL;
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* Initialise memory for temp-group */
memset(tgrp, 0, sizeof(bActionGroup));
tgrp->flag |= (AGRP_EXPANDED|AGRP_TEMP);
strcpy(tgrp->name, "#TempGroup");
/* Move any action-channels not already moved, to the temp group */
if (act->chanbase.first) {
/* start of list */
achan= act->chanbase.first;
achan->prev= NULL;
tgrp->channels.first= achan;
act->chanbase.first= NULL;
/* end of list */
achan= act->chanbase.last;
achan->next= NULL;
tgrp->channels.last= achan;
act->chanbase.last= NULL;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* Add temp-group to list */
BLI_addtail(&act->groups, tgrp);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* link lists of channels that groups have */
static void join_groups_action_temp (bAction *act)
{
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionGroup *agrp;
bActionChannel *achan;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
ListBase tempGroup;
/* add list of channels to action's channels */
tempGroup= agrp->channels;
addlisttolist(&act->chanbase, &agrp->channels);
agrp->channels= tempGroup;
/* clear moved flag */
agrp->flag &= ~AGRP_MOVED;
/* if temp-group... remove from list (but don't free as it's on the stack!) */
if (agrp->flag & AGRP_TEMP) {
BLI_remlink(&act->groups, agrp);
break;
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* clear "moved" flag from all achans */
for (achan= act->chanbase.first; achan; achan= achan->next)
achan->flag &= ~ACHAN_MOVED;
}
static short rearrange_actchannel_is_ok (Link *channel, short type)
{
if (type == ACTTYPE_GROUP) {
bActionGroup *agrp= (bActionGroup *)channel;
if (SEL_AGRP(agrp) && !(agrp->flag & AGRP_MOVED))
return 1;
}
else if (type == ACTTYPE_ACHAN) {
bActionChannel *achan= (bActionChannel *)channel;
if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan) && !(achan->flag & ACHAN_MOVED))
return 1;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
return 0;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
static short rearrange_actchannel_after_ok (Link *channel, short type)
{
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
if (type == ACTTYPE_GROUP) {
bActionGroup *agrp= (bActionGroup *)channel;
if (agrp->flag & AGRP_TEMP)
return 0;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
return 1;
}
static short rearrange_actchannel_top (ListBase *list, Link *channel, short type)
{
if (rearrange_actchannel_is_ok(channel, type)) {
/* take it out off the chain keep data */
BLI_remlink(list, channel);
/* make it first element */
BLI_insertlinkbefore(list, list->first, channel);
return 1;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
return 0;
}
static short rearrange_actchannel_up (ListBase *list, Link *channel, short type)
{
if (rearrange_actchannel_is_ok(channel, type)) {
Link *prev= channel->prev;
if (prev) {
/* take it out off the chain keep data */
BLI_remlink(list, channel);
/* push it up */
BLI_insertlinkbefore(list, prev, channel);
return 1;
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
return 0;
}
static short rearrange_actchannel_down (ListBase *list, Link *channel, short type)
{
if (rearrange_actchannel_is_ok(channel, type)) {
Link *next = (channel->next) ? channel->next->next : NULL;
if (next) {
/* take it out off the chain keep data */
BLI_remlink(list, channel);
/* move it down */
BLI_insertlinkbefore(list, next, channel);
return 1;
}
else if (rearrange_actchannel_after_ok(list->last, type)) {
/* take it out off the chain keep data */
BLI_remlink(list, channel);
/* add at end */
BLI_addtail(list, channel);
return 1;
}
else {
/* take it out off the chain keep data */
BLI_remlink(list, channel);
/* add just before end */
BLI_insertlinkbefore(list, list->last, channel);
return 1;
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
return 0;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
static short rearrange_actchannel_bottom (ListBase *list, Link *channel, short type)
{
if (rearrange_actchannel_is_ok(channel, type)) {
if (rearrange_actchannel_after_ok(list->last, type)) {
/* take it out off the chain keep data */
BLI_remlink(list, channel);
/* add at end */
BLI_addtail(list, channel);
return 1;
}
}
return 0;
}
/* Change the order of action-channels
* mode: REARRANGE_ACTCHAN_*
*/
void rearrange_action_channels (short mode)
{
bAction *act;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionChannel *achan, *chan;
bActionGroup *agrp, *grp;
bActionGroup tgrp;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
void *data;
short datatype;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
short (*rearrange_func)(ListBase *, Link *, short);
short do_channels = 1;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
char undostr[60];
/* Get the active action, exit if none are selected */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype != ACTCONT_ACTION) return;
act= (bAction *)data;
/* exit if invalid mode */
switch (mode) {
case REARRANGE_ACTCHAN_TOP:
strcpy(undostr, "Channel(s) to Top");
rearrange_func= rearrange_actchannel_top;
break;
case REARRANGE_ACTCHAN_UP:
strcpy(undostr, "Channel(s) Move Up");
rearrange_func= rearrange_actchannel_up;
break;
case REARRANGE_ACTCHAN_DOWN:
strcpy(undostr, "Channel(s) Move Down");
rearrange_func= rearrange_actchannel_down;
break;
case REARRANGE_ACTCHAN_BOTTOM:
strcpy(undostr, "Channel(s) to Bottom");
rearrange_func= rearrange_actchannel_bottom;
break;
default:
return;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* make sure we're only operating with groups */
split_groups_action_temp(act, &tgrp);
/* rearrange groups first (and then, only consider channels if the groups weren't moved) */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
#define GET_FIRST(list) ((mode > 0) ? (list.first) : (list.last))
#define GET_NEXT(item) ((mode > 0) ? (item->next) : (item->prev))
for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
/* Get next group to consider */
grp= GET_NEXT(agrp);
/* try to do group first */
if (rearrange_func(&act->groups, (Link *)agrp, ACTTYPE_GROUP)) {
do_channels= 0;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
agrp->flag |= AGRP_MOVED;
}
}
if (do_channels) {
for (agrp= GET_FIRST(act->groups); agrp; agrp= grp) {
/* Get next group to consider */
grp= GET_NEXT(agrp);
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* only consider action-channels if they're visible (group expanded) */
if (EXPANDED_AGRP(agrp)) {
for (achan= GET_FIRST(agrp->channels); achan; achan= chan) {
/* Get next channel to consider */
chan= GET_NEXT(achan);
/* Try to do channel */
if (rearrange_func(&agrp->channels, (Link *)achan, ACTTYPE_ACHAN))
achan->flag |= ACHAN_MOVED;
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
}
}
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
#undef GET_FIRST
#undef GET_NEXT
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* assemble lists into one list (and clear moved tags) */
join_groups_action_temp(act);
/* Undo + redraw */
BIF_undo_push(undostr);
allqueue(REDRAWACTION, 0);
}
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* ******************************************************************* */
/* CHANNEL VISIBILITY/FOLDING */
/* Expand all channels to show full hierachy */
void expand_all_action (void)
{
void *data;
short datatype;
bAction *act;
bActionChannel *achan;
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
bActionGroup *agrp;
short mode= 1;
/* Get the selected action, exit if none are selected */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype != ACTCONT_ACTION) return;
act= (bAction *)data;
/* check if expand all, or close all */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
if (EXPANDED_AGRP(agrp)) {
mode= 0;
break;
}
}
if (mode == 0) {
for (achan= act->chanbase.first; achan; achan= achan->next) {
if (VISIBLE_ACHAN(achan)) {
if (EXPANDED_ACHAN(achan)) {
mode= 0;
break;
}
}
}
}
/* expand/collapse depending on mode */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
if (mode == 1)
agrp->flag |= AGRP_EXPANDED;
else
agrp->flag &= ~AGRP_EXPANDED;
}
for (achan=act->chanbase.first; achan; achan= achan->next) {
if (VISIBLE_ACHAN(achan)) {
if (mode == 1)
achan->flag |= (ACHAN_EXPANDED|ACHAN_SHOWIPO|ACHAN_SHOWCONS);
else
achan->flag &= ~(ACHAN_EXPANDED|ACHAN_SHOWIPO|ACHAN_SHOWCONS);
}
}
/* Cleanup and do redraws */
BIF_undo_push("Expand Action Hierachy");
allqueue(REDRAWACTION, 0);
}
/* Expands those groups which are hiding a selected actionchannel */
void expand_obscuregroups_action (void)
{
void *data;
short datatype;
bAction *act;
bActionChannel *achan;
/* Get the selected action, exit if none are selected */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype != ACTCONT_ACTION) return;
act= (bAction *)data;
/* check if expand all, or close all */
for (achan= act->chanbase.first; achan; achan= achan->next) {
if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
if (achan->grp)
achan->grp->flag |= AGRP_EXPANDED;
}
}
/* Cleanup and do redraws */
BIF_undo_push("Show Group-Hidden Channels");
allqueue(REDRAWACTION, 0);
}
/* For visible channels, expand/collapse one level */
void openclose_level_action (short mode)
{
void *data;
short datatype;
bAction *act;
bActionChannel *achan;
bActionGroup *agrp;
/* Get the selected action, exit if none are selected */
data = get_action_context(&datatype);
if (data == NULL) return;
if (datatype != ACTCONT_ACTION) return;
act= (bAction *)data;
/* Abort if no operation required */
if (mode == 0) return;
/* Only affect selected channels */
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
for (achan= act->chanbase.first; achan; achan= achan->next) {
/* make sure if there is a group, it isn't about to be collapsed and is open */
if ( (achan->grp==NULL) || (EXPANDED_AGRP(achan->grp) && SEL_AGRP(achan->grp)==0) ) {
if (VISIBLE_ACHAN(achan) && SEL_ACHAN(achan)) {
if (EXPANDED_ACHAN(achan)) {
if (FILTER_IPO_ACHAN(achan) || FILTER_CON_ACHAN(achan)) {
if (mode < 0)
achan->flag &= ~(ACHAN_SHOWIPO|ACHAN_SHOWCONS);
}
else {
if (mode > 0)
achan->flag |= (ACHAN_SHOWIPO|ACHAN_SHOWCONS);
else
achan->flag &= ~ACHAN_EXPANDED;
}
}
else {
if (mode > 0)
achan->flag |= ACHAN_EXPANDED;
}
}
}
}
/* Expand/collapse selected groups */
for (agrp= act->groups.first; agrp; agrp= agrp->next) {
if (SEL_AGRP(agrp)) {
if (mode < 0)
agrp->flag &= ~AGRP_EXPANDED;
else
agrp->flag |= AGRP_EXPANDED;
}
}
/* Cleanup and do redraws */
BIF_undo_push("Expand/Collapse Action Level");
allqueue(REDRAWACTION, 0);
}
/* **************************************************** */
/* ACTION MARKERS (PoseLib features) */
/* NOTE: yes, these duplicate code from edittime.c a bit, but these do a bit more...
* These could get merged with those someday if need be... (Aligorith, 20071230)
*/
/* Makes the given marker the active one
* - deselect indicates whether unactive ones should be deselected too
*/
void action_set_activemarker (bAction *act, TimeMarker *active, short deselect)
{
TimeMarker *marker;
int index= 0;
/* sanity checks */
if (act == NULL)
return;
act->active_marker= 0;
/* set appropriate flags for all markers */
for (marker=act->markers.first; marker; marker=marker->next, index++) {
/* only active may be active */
if (marker == active) {
act->active_marker= index + 1;
marker->flag |= (SELECT|ACTIVE);
}
else {
if (deselect)
marker->flag &= ~(SELECT|ACTIVE);
else
marker->flag &= ~ACTIVE;
}
}
}
/* Adds a local marker to the active action */
void action_add_localmarker (bAction *act, int frame)
{
TimeMarker *marker;
char name[64];
/* sanity checks */
if (act == NULL)
return;
/* get name of marker */
sprintf(name, "Pose");
if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
return;
/* add marker to action - replaces any existing marker there */
for (marker= act->markers.first; marker; marker= marker->next) {
if (marker->frame == frame) {
BLI_strncpy(marker->name, name, sizeof(marker->name));
break;
}
}
if (marker == NULL) {
marker= MEM_callocN(sizeof(TimeMarker), "ActionMarker");
BLI_strncpy(marker->name, name, sizeof(marker->name));
marker->frame= frame;
BLI_addtail(&act->markers, marker);
}
/* validate the name */
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
/* sets the newly added marker as the active one */
action_set_activemarker(act, marker, 1);
BIF_undo_push("Action Add Marker");
allqueue(REDRAWACTION, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
/* Renames the active local marker to the active action */
void action_rename_localmarker (bAction *act)
{
TimeMarker *marker;
char name[64];
int val;
/* sanity checks */
if (act == NULL)
return;
/* get active marker to rename */
if (act->active_marker == 0)
return;
else
val= act->active_marker;
if (val <= 0) return;
marker= BLI_findlink(&act->markers, val-1);
if (marker == NULL) return;
/* get name of marker */
sprintf(name, marker->name);
if (sbutton(name, 0, sizeof(name)-1, "Name: ") == 0)
return;
/* copy then validate name */
BLI_strncpy(marker->name, name, sizeof(marker->name));
BLI_uniquename(&act->markers, marker, "Pose", offsetof(TimeMarker, name), 64);
/* undo and update */
BIF_undo_push("Action Rename Marker");
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWACTION, 0);
}
/* Deletes all selected markers, and adjusts things as appropriate */
void action_remove_localmarkers (bAction *act)
{
TimeMarker *marker, *next;
/* sanity checks */
if (act == NULL)
return;
/* remove selected markers */
for (marker= act->markers.first; marker; marker= next) {
next= marker->next;
if (marker->flag & SELECT)
BLI_freelinkN(&act->markers, marker);
}
/* clear active just in case */
act->active_marker= 0;
/* undo and update */
BIF_undo_push("Action Remove Marker(s)");
allqueue(REDRAWBUTSEDIT, 0);
allqueue(REDRAWACTION, 0);
}
/* **************************************************** */
/* EVENT HANDLING */
void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
{
extern void do_actionbuts(unsigned short event); // drawaction.c
SpaceAction *saction;
void *data;
short datatype;
float dx, dy;
int doredraw= 0;
int cfra;
short mval[2];
unsigned short event= evt->event;
short val= evt->val;
short mousebut = L_MOUSE;
if (curarea->win==0) return;
saction= curarea->spacedata.first;
if (!saction)
return;
data= get_action_context(&datatype);
if (val) {
if ( uiDoBlocks(&curarea->uiblocks, event, 1)!=UI_NOTHING ) event= 0;
/* swap mouse buttons based on user preference */
if (U.flag & USER_LMOUSESELECT) {
if (event == LEFTMOUSE) {
event = RIGHTMOUSE;
mousebut = L_MOUSE;
}
else if (event == RIGHTMOUSE) {
event = LEFTMOUSE;
mousebut = R_MOUSE;
}
}
getmouseco_areawin(mval);
switch(event) {
case UI_BUT_EVENT:
do_actionbuts(val); /* window itself */
break;
/* LEFTMOUSE and RIGHTMOUSE event codes can be swapped above,
* based on user preference USER_LMOUSESELECT
*/
case LEFTMOUSE:
if (view2dmove(LEFTMOUSE)) /* only checks for sliders */
break;
else if ((G.v2d->mask.xmin==0) || (mval[0] > ACTWIDTH)) {
/* moving time-marker / current frame */
do {
getmouseco_areawin(mval);
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
cfra= (int)(dx+0.5f);
if (cfra < 1) cfra= 1;
if (cfra != CFRA) {
CFRA= cfra;
update_for_newframe();
force_draw_all(0);
}
else
PIL_sleep_ms(30);
}
while(get_mbut() & mousebut);
break;
}
/* passed on as selection */
case RIGHTMOUSE:
/* Clicking in the channel area */
if ((G.v2d->mask.xmin) && (mval[0] < NAMEWIDTH)) {
if (ELEM(datatype, ACTCONT_ACTION, ACTCONT_GPENCIL)) {
/* mouse is over action channels */
if (G.qual == LR_CTRLKEY)
numbuts_action();
else
mouse_actionchannels(mval);
}
else
numbuts_action();
}
else {
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))
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))
selectall_action_keys(mval, 1, select_mode);
/* Clicking in the main area of the action window
* selects keys and markers
*/
else if (G.qual & LR_ALTKEY) {
areamouseco_to_ipoco(G.v2d, mval, &dx, &dy);
/* sends a 1 for left and 0 for right */
selectkeys_leftright((dx < (float)CFRA), select_mode);
}
else
mouse_action(select_mode);
}
break;
case MIDDLEMOUSE:
case WHEELUPMOUSE:
case WHEELDOWNMOUSE:
view2dmove(event); /* in drawipo.c */
break;
case AKEY:
if (mval[0] < NAMEWIDTH) {
deselect_action_channels(1);
BIF_undo_push("(De)Select Action Channels");
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);
BIF_undo_push("(De)Select Markers");
allqueue(REDRAWTIME, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWSOUND, 0);
}
else {
deselect_action_keys(1, 1);
BIF_undo_push("(De)Select Keys");
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
}
}
break;
case BKEY:
if (G.qual & LR_CTRLKEY) {
borderselect_markers();
}
else {
if (mval[0] <= ACTWIDTH)
borderselect_actionchannels();
else
borderselect_action();
}
break;
case CKEY:
/* scroll the window so the current
* frame is in the center.
*/
center_currframe();
break;
case DKEY:
if (mval[0] > ACTWIDTH) {
if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
duplicate_marker();
else if (G.qual == LR_SHIFTKEY)
duplicate_action_keys();
}
break;
case EKEY:
if (mval[0] >= ACTWIDTH)
transform_action_keys('e', 0);
break;
case GKEY:
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* Action Channel Groups */
if (G.qual == LR_SHIFTKEY)
action_groups_group(0);
else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
action_groups_group(1);
else if (G.qual == LR_ALTKEY)
action_groups_ungroup();
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
/* Transforms */
else {
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
if (mval[0] >= ACTWIDTH) {
if (G.qual == LR_CTRLKEY)
transform_markers('g', 0);
else
transform_action_keys('g', 0);
}
}
break;
case HKEY:
if (G.qual & LR_SHIFTKEY) {
if (okee("Set Keys to Auto Handle"))
sethandles_action_keys(HD_AUTO);
}
else {
if (okee("Toggle Keys Aligned Handle"))
sethandles_action_keys(HD_ALIGN);
}
break;
case IKEY:
if (G.qual & LR_CTRLKEY) {
if (mval[0] < ACTWIDTH) {
deselect_action_channels(2);
BIF_undo_push("Inverse Action Channels");
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
}
else if (G.qual & LR_SHIFTKEY) {
deselect_markers(0, 2);
BIF_undo_push("Inverse Markers");
allqueue(REDRAWMARKER, 0);
}
else {
deselect_action_keys(0, 2);
BIF_undo_push("Inverse Keys");
allqueue(REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
allqueue(REDRAWIPO, 0);
}
}
break;
case KKEY:
if (G.qual == LR_ALTKEY)
markers_selectkeys_between();
else if (G.qual == LR_SHIFTKEY)
column_select_action_keys(2);
else if (G.qual == LR_CTRLKEY)
column_select_action_keys(3);
else
column_select_action_keys(1);
allqueue(REDRAWMARKER, 0);
break;
case LKEY:
/* poselib manipulation - only for actions */
if (datatype == ACTCONT_ACTION) {
if (G.qual == LR_SHIFTKEY)
action_add_localmarker(data, CFRA);
else if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
action_rename_localmarker(data);
else if (G.qual == LR_ALTKEY)
action_remove_localmarkers(data);
else if (G.qual == LR_CTRLKEY) {
G.saction->flag |= SACTION_POSEMARKERS_MOVE;
transform_markers('g', 0);
G.saction->flag &= ~SACTION_POSEMARKERS_MOVE;
}
}
break;
case MKEY:
if (G.qual & LR_SHIFTKEY) {
/* mirror keyframes */
if (data) {
if (G.saction->flag & SACTION_DRAWTIME)
val = pupmenu("Mirror Keys Over%t|Current Time%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
else
val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2|Horizontal Axis %x3|Selected Marker %x4");
mirror_action_keys(val);
}
}
else {
/* marker operations */
if (G.qual == 0)
add_marker(CFRA);
else if (G.qual == LR_CTRLKEY)
rename_marker();
else
break;
allqueue(REDRAWMARKER, 0);
}
break;
case NKEY:
if (G.qual==0) {
/* panel will not always show useful info! */
if (mval[0] > ACTWIDTH) {
add_blockhandler(curarea, ACTION_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
scrarea_queue_winredraw(curarea);
}
else
numbuts_action();
}
break;
case OKEY:
if (G.qual & LR_ALTKEY)
sample_action_keys();
else
clean_action();
break;
case PKEY:
if (G.qual == (LR_CTRLKEY|LR_ALTKEY)) /* set preview range to range of action */
action_previewrange_set(G.saction->action);
else if (G.qual & LR_CTRLKEY) /* set preview range */
anim_previewrange_set();
else if (G.qual & LR_ALTKEY) /* clear preview range */
anim_previewrange_clear();
allqueue(REDRAWMARKER, 0);
allqueue(REDRAWBUTSALL, 0);
break;
case SKEY:
if (mval[0]>=ACTWIDTH) {
if (G.qual == (LR_SHIFTKEY|LR_CTRLKEY)) {
if (data) {
snap_cfra_action();
}
}
else if (G.qual & LR_SHIFTKEY) {
if (data) {
if (G.saction->flag & SACTION_DRAWTIME)
val = pupmenu("Snap Keys To%t|Nearest Second%x4|Current Time%x2|Nearest Marker %x3");
else
val = pupmenu("Snap Keys To%t|Nearest Frame%x1|Current Frame%x2|Nearest Marker %x3");
snap_action_keys(val);
}
}
else {
transform_action_keys('s', 0);
}
}
break;
case TKEY:
if (G.qual & LR_SHIFTKEY)
action_set_ipo_flags(SET_IPO_POPUP, 0);
else if (G.qual & LR_CTRLKEY) {
val= pupmenu("Time value%t|Frames %x1|Seconds%x2");
if (val > 0) {
if (val == 2) saction->flag |= SACTION_DRAWTIME;
else saction->flag &= ~SACTION_DRAWTIME;
doredraw= 1;
}
}
else
transform_action_keys ('t', 0);
break;
case VKEY:
if (okee("Set Keys to Vector Handle"))
sethandles_action_keys(HD_VECT);
break;
case WKEY:
/* toggle/turn-on\off-based-on-setting */
if (G.qual) {
if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
val= 1;
else if (G.qual == LR_ALTKEY)
val= 2;
else
val= 0;
setflag_action_channels(val);
}
break;
case PAGEUPKEY:
if (datatype == ACTCONT_ACTION) {
if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
rearrange_action_channels(REARRANGE_ACTCHAN_TOP);
else if (G.qual == LR_SHIFTKEY)
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
rearrange_action_channels(REARRANGE_ACTCHAN_UP);
else if (G.qual == LR_CTRLKEY)
nextprev_action_keyframe(1);
else
nextprev_marker(1);
}
else if (datatype == ACTCONT_SHAPEKEY) {
/* only jump to markers possible (key channels can't be moved yet) */
if (G.qual == LR_CTRLKEY)
nextprev_action_keyframe(1);
else
nextprev_marker(1);
}
break;
case PAGEDOWNKEY:
if (datatype == ACTCONT_ACTION) {
if (G.qual == (LR_CTRLKEY|LR_SHIFTKEY))
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
rearrange_action_channels(REARRANGE_ACTCHAN_BOTTOM);
else if (G.qual == LR_SHIFTKEY)
== Action Editor - Groups for Action Channels (Peach Request) == Now, you can assign Action Channels to named (folder-like) groups, which help to organise the channels (important for more complex rigs). These are collapsible, can be "protected", and show a "summary" of the keyframes in the channels the Group contains. They are drawn as bright-green (active) or a darker shade of green (not active) channels. * Each Action has its own set of Groups. * An Action-Channel can only occur in one Group at a time. It can also not occur in any group. * Action-Channels can be moved between Groups * Groups + grouped-channels always occur BEFORE un-grouped channels Important Hotkeys: * Shift-G : Adds the selected Action-Channels to the Active Group. This will create a new group if need be * Ctrl-Shift-G : Always adds a new group, and adds the selected Action-Channels to it * Alt-G : Removes selected Action-Channels from their groups * Ctrl-Shift-Alt-G : (Note: this will be removed soon) This is a simple debugging-hotkey I added, which just prints a list of the groups, channels, and their addresses... * NKey / Ctrl-LMB: While hovering over the name of a group, this shows a popup like for other channels, which allows the editing of the channel's name, etc. Assorted Notes: * Some tools may not work yet with this (Ctrl Numpad+/- for example) * Fixed some bugs in various places in Action Editor code * Added theme colours for group channels * The nomenclature of these tools may change in future when a better alternative is found * The ability to auto-assign action-channels to groups when they are keyframed will be coming up shortly
2008-01-17 23:02:11 +00:00
rearrange_action_channels(REARRANGE_ACTCHAN_DOWN);
else if (G.qual == LR_CTRLKEY)
nextprev_action_keyframe(-1);
else
nextprev_marker(-1);
}
else if (datatype == ACTCONT_SHAPEKEY) {
/* only jump to markers possible (key channels can't be moved yet) */
if (G.qual == LR_CTRLKEY)
nextprev_action_keyframe(-1);
else
nextprev_marker(-1);
}
break;
case DELKEY:
case XKEY:
/* markers are incorported under shift-modifier (it does go against conventions, but oh well :/) */
if (G.qual == LR_SHIFTKEY) {
if (okee("Erase selected marker(s)?")) {
if (mval[0] >= NAMEWIDTH)
remove_marker();
}
}
else {
if (okee("Erase selected?")) {
if (mval[0] < NAMEWIDTH) {
if (datatype == ACTCONT_ACTION)
delete_action_channels();
else if (datatype == ACTCONT_GPENCIL)
delete_gpencil_layers();
}
else
delete_action_keys();
}
}
allqueue(REDRAWMARKER, 0);
break;
case ACCENTGRAVEKEY:
if (datatype == ACTCONT_ACTION) {
if (G.qual == LR_SHIFTKEY)
expand_obscuregroups_action();
else
expand_all_action();
}
break;
case PADPLUSKEY:
if (G.qual == LR_CTRLKEY) {
if (datatype == ACTCONT_ACTION)
openclose_level_action(1);
}
else {
view2d_zoom(G.v2d, 0.1154f, sa->winx, sa->winy);
test_view2d(G.v2d, sa->winx, sa->winy);
view2d_do_locks(curarea, V2D_LOCK_COPY);
doredraw= 1;
}
break;
case PADMINUS:
if (G.qual == LR_CTRLKEY) {
if (datatype == ACTCONT_ACTION)
openclose_level_action(-1);
}
else {
view2d_zoom(G.v2d, -0.15f, sa->winx, sa->winy);
test_view2d(G.v2d, sa->winx, sa->winy);
view2d_do_locks(curarea, V2D_LOCK_COPY);
doredraw= 1;
}
break;
case HOMEKEY:
do_action_buttons(B_ACTHOME); /* header */
break;
}
}
if (doredraw) addqueue(curarea->win, REDRAW, 1);
}
/* **************************************************** */