2002-10-12 11:37:38 +00:00
/**
* $ Id $
*
* * * * * * BEGIN GPL / BL DUAL LICENSE BLOCK * * * * *
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version . The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License . See http : //www.blender.org/BL/ for information
* about this .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* The Original Code is Copyright ( C ) 2001 - 2002 by NaN Holding BV .
* All rights reserved .
*
* The Original Code is : all of this file .
*
* Contributor ( s ) : none yet .
*
* * * * * * END GPL / BL DUAL LICENSE BLOCK * * * * *
* This file is a horrible mess : An attmept to cram some
* final functionality into blender before it is too late .
*
* Hopefully it can be tidied up at a later date . . .
*/
# include <stdlib.h>
# include <string.h>
# include <math.h>
# include "PIL_time.h"
# include "BKE_global.h"
# include "BKE_main.h"
# include "BKE_library.h"
# include "BKE_nla.h"
# include "BKE_action.h"
# include "BIF_screen.h"
# include "BIF_interface.h"
# include "BIF_buttons.h"
# include "BIF_space.h"
# include "BIF_mywindow.h"
# include "BIF_editview.h"
# include "BIF_toolbox.h"
# include "MEM_guardedalloc.h"
# include "BLI_blenlib.h"
# include "DNA_screen_types.h"
# include "DNA_space_types.h"
# include "DNA_scene_types.h"
# include "DNA_ipo_types.h"
# include "DNA_curve_types.h"
# include "DNA_object_types.h"
# include "DNA_userdef_types.h"
# include "DNA_action_types.h"
# include "DNA_nla_types.h"
# include "DNA_constraint_types.h"
# include "BSE_editipo.h"
# include "BSE_editnla_types.h"
# include "BSE_headerbuttons.h"
# include "BSE_drawipo.h"
# include "BSE_trans_types.h"
# include "BSE_edit.h"
# include "BDR_editobject.h"
# include "interface.h"
# include "blendef.h"
# include "mydevice.h"
# include "blendertimer.h"
# include "license_key.h"
# include "keyed_functions.h"
/* Note: A lot of these pretty much duplicate the behaviour of the
action windows . The functions should be shared , not copy - pasted */
typedef struct NlaParam {
SpaceNla * snla ;
unsigned short event ;
short val ;
} NlaParam ;
static void deselect_nlachannel_keys ( int test ) ;
static void deselect_nlachannels ( int test ) ;
static void transform_nlachannel_keys ( char mode ) ;
static void delete_nlachannel_keys ( void ) ;
static void delete_nlachannels ( void ) ;
static void duplicate_nlachannel_keys ( void ) ;
static void borderselect_nla ( void ) ;
static void mouse_nla ( void ) ;
static Base * get_nearest_nlachannel_ob_key ( float * index , short * sel ) ;
static bAction * get_nearest_nlachannel_ac_key ( float * index , short * sel ) ;
static Base * get_nearest_nlastrip ( bActionStrip * * rstrip , short * sel ) ;
static void mouse_nlachannels ( short mval [ 2 ] ) ;
static void add_nlablock ( short mval [ 2 ] ) ;
static bActionStrip * get_active_nlastrip ( void ) ;
static void convert_nla ( short mval [ 2 ] ) ;
extern int count_nla_levels ( void ) ; /* From drawnla.c */
extern int nla_filter ( Base * base , int flags ) ; /* From drawnla.c */
/* ******************** SPACE: NLA ********************** */
/* Protected creator function */
int calc_memleak ( void * ptr ) {
int doredraw = 0 ;
short mval [ 2 ] ;
float dx , dy ;
int cfra ;
SpaceNla * snla ;
NlaParam * params = ( NlaParam * ) ptr ;
unsigned short event ;
short val ;
if ( ! ptr )
return - 1 ;
snla = params - > snla ;
event = params - > event ;
val = params - > val ;
if ( LICENSE_KEY_VALID ) {
if ( curarea - > win = = 0 ) return 0 ;
if ( ! snla )
return 0 ;
if ( val ) {
if ( uiDoBlocks ( & curarea - > uiblocks , event ) ! = UI_NOTHING ) event = 0 ;
getmouseco_areawin ( mval ) ;
switch ( event ) {
case UI_BUT_EVENT :
do_blenderbuttons ( val ) ;
break ;
case HOMEKEY :
do_nla_buttons ( B_NLAHOME ) ;
break ;
case DKEY :
if ( G . qual & LR_SHIFTKEY & & mval [ 0 ] > = NLAWIDTH ) {
duplicate_nlachannel_keys ( ) ;
update_for_newframe ( ) ;
}
break ;
case DELKEY :
case XKEY :
if ( mval [ 0 ] > = NLAWIDTH )
delete_nlachannel_keys ( ) ;
else
delete_nlachannels ( ) ;
update_for_newframe ( ) ;
break ;
case GKEY :
if ( mval [ 0 ] > = NLAWIDTH )
transform_nlachannel_keys ( ' g ' ) ;
update_for_newframe ( ) ;
break ;
case SKEY :
if ( mval [ 0 ] > = NLAWIDTH )
transform_nlachannel_keys ( ' s ' ) ;
update_for_newframe ( ) ;
break ;
case BKEY :
borderselect_nla ( ) ;
break ;
case CKEY :
convert_nla ( mval ) ;
break ;
case AKEY :
if ( G . qual & LR_SHIFTKEY ) {
add_nlablock ( mval ) ;
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
}
else {
if ( mval [ 0 ] > = NLAWIDTH )
deselect_nlachannel_keys ( 1 ) ;
else {
deselect_nlachannels ( 1 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
}
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWIPO , 0 ) ;
}
break ;
case RIGHTMOUSE :
if ( mval [ 0 ] > = NLAWIDTH )
mouse_nla ( ) ;
else
mouse_nlachannels ( mval ) ;
break ;
case LEFTMOUSE :
if ( mval [ 0 ] > NLAWIDTH ) {
do {
getmouseco_areawin ( mval ) ;
areamouseco_to_ipoco ( G . v2d , mval , & dx , & dy ) ;
cfra = ( int ) dx ;
if ( cfra < 1 ) cfra = 1 ;
if ( cfra ! = CFRA ) {
CFRA = cfra ;
update_for_newframe ( ) ;
force_draw_plus ( SPACE_VIEW3D ) ;
force_draw_plus ( SPACE_IPO ) ;
}
} while ( get_mbut ( ) & L_MOUSE ) ;
}
break ;
case MIDDLEMOUSE :
view2dmove ( ) ; /* in drawipo.c */
break ;
}
}
if ( doredraw ) scrarea_queue_winredraw ( curarea ) ;
}
return 0 ;
}
void winqreadnlaspace ( unsigned short event , short val , char ascii )
{
NlaParam param ;
Base * base ;
bActionStrip * strip , * next ;
short mval [ 2 ] ;
float dx , dy ;
int cfra ;
param . event = event ;
param . val = val ;
param . snla = curarea - > spacedata . first ;
/* Call the protected (&obfuscated) eventloop function */
if ( KEY_NLA_EVENT ) {
KEY_NLA_EVENT ( & param ) ;
}
else {
getmouseco_areawin ( mval ) ;
switch ( event ) {
case GKEY :
case SKEY :
case AKEY :
case CKEY :
case NKEY :
case RIGHTMOUSE :
notice ( " NLA window editing only available in Blender Publisher " ) ;
break ;
case LEFTMOUSE :
if ( mval [ 0 ] > NLAWIDTH ) {
do {
getmouseco_areawin ( mval ) ;
areamouseco_to_ipoco ( G . v2d , mval , & dx , & dy ) ;
cfra = ( int ) dx ;
if ( cfra < 1 ) cfra = 1 ;
if ( cfra ! = CFRA ) {
CFRA = cfra ;
update_for_newframe ( ) ;
force_draw_plus ( SPACE_VIEW3D ) ;
force_draw_plus ( SPACE_IPO ) ;
}
} while ( get_mbut ( ) & L_MOUSE ) ;
}
break ;
case MIDDLEMOUSE :
view2dmove ( ) ; /* in drawipo.c */
break ;
case DELKEY :
case XKEY :
if ( okee ( " This will remove all NLA information from all objects! " ) ) {
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = next ) {
next = strip - > next ;
free_actionstrip ( strip ) ;
BLI_freelinkN ( & base - > object - > nlastrips , strip ) ;
}
}
update_for_newframe ( ) ;
}
break ;
default :
break ;
}
}
}
static void convert_nla ( short mval [ 2 ] )
{
short event ;
float ymax , ymin ;
Base * base ;
float x , y ;
int sel = 0 ;
bActionStrip * strip , * nstrip ;
if ( LICENSE_KEY_VALID ) {
/* Find out what strip we're over */
ymax = count_nla_levels ( ) * ( NLACHANNELSKIP + NLACHANNELHEIGHT ) ;
areamouseco_to_ipoco ( G . v2d , mval , & x , & y ) ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
if ( nla_filter ( base , 0 ) ) {
/* Check object ipo */
ymin = ymax - ( NLACHANNELSKIP + NLACHANNELHEIGHT ) ;
if ( y > = ymin & & y < = ymax )
break ;
ymax = ymin ;
if ( base - > object - > type = = OB_ARMATURE ) {
/* Check action ipo */
ymin = ymax - ( NLACHANNELSKIP + NLACHANNELHEIGHT ) ;
if ( y > = ymin & & y < = ymax )
break ;
ymax = ymin ;
/* Check nlastrips */
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
ymin = ymax - ( NLACHANNELSKIP + NLACHANNELHEIGHT ) ;
if ( y > = ymin & & y < = ymax ) {
sel = 1 ;
break ;
}
ymax = ymin ;
}
if ( sel )
break ;
}
}
}
if ( ! base )
return ;
if ( base - > object - > type = = OB_ARMATURE ) {
event = pupmenu ( " Convert%t|Action to NLAstrip%x1 " ) ;
switch ( event ) {
case 1 :
if ( base - > object - > action ) {
/* Make new actionstrip */
nstrip = MEM_callocN ( sizeof ( bActionStrip ) , " bActionStrip " ) ;
deselect_nlachannel_keys ( 0 ) ;
/* Link the action to the nstrip */
nstrip - > act = base - > object - > action ;
nstrip - > actstart = calc_action_start ( base - > object - > action ) ; /* MAKE THIS THE FIRST FRAME OF THE ACTION */
nstrip - > actend = calc_action_end ( base - > object - > action ) ;
nstrip - > start = nstrip - > actstart ;
nstrip - > end = nstrip - > actend ;
nstrip - > flag = ACTSTRIP_SELECT ;
nstrip - > repeat = 1.0 ;
BLI_addtail ( & base - > object - > nlastrips , nstrip ) ;
/* Unlink action */
base - > object - > action = NULL ;
allqueue ( REDRAWNLA , 0 ) ;
}
break ;
default :
break ;
}
}
}
}
static void add_nlablock ( short mval [ 2 ] )
{
/* Make sure we are over an armature */
Base * base ;
bAction * act = NULL ;
bActionStrip * strip ;
float ymin , ymax ;
float x , y ;
rctf rectf ;
short event ;
char * str ;
short nr ;
int cur ;
if ( LICENSE_KEY_VALID ) {
areamouseco_to_ipoco ( G . v2d , mval , & x , & y ) ;
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 ) ;
ymax = count_nla_levels ( ) ;
ymax * = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Handle object ipo selection */
if ( nla_filter ( base , 0 ) ) {
/* STUPID STUPID STUPID */
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
/* Handle object ipos */
if ( base - > object - > type = = OB_ARMATURE ) {
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) )
break ;
}
ymax = ymin ;
/* Handle action ipos & Action strips */
if ( base - > object - > type = = OB_ARMATURE ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) * ( BLI_countlist ( & base - > object - > nlastrips ) + 1 ) ;
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) )
break ;
ymax = ymin ;
}
}
}
/* Make sure we have an armature */
if ( ! base ) {
error ( " Not an armature! " ) ;
return ;
}
/* Popup action menu */
IDnames_to_pupstring ( & str , " Add action " , NULL , & G . main - > action , ( ID * ) G . scene , & nr ) ;
event = pupmenu ( str ) ;
if ( event ! = - 1 ) {
for ( cur = 1 , act = G . main - > action . first ; act ; act = act - > id . next , cur + + ) {
if ( cur = = event ) {
break ;
}
}
}
MEM_freeN ( str ) ;
/* Bail out if no action was chosen */
if ( ! act ) {
return ;
}
/* Initialize the new action block */
strip = MEM_callocN ( sizeof ( bActionStrip ) , " bActionStrip " ) ;
deselect_nlachannel_keys ( 0 ) ;
/* Link the action to the strip */
strip - > act = act ;
strip - > actstart = 1.0 ;
strip - > actend = calc_action_end ( act ) ;
strip - > start = G . scene - > r . cfra ; /* Should be mval[0] */
strip - > end = strip - > start + ( strip - > actend - strip - > actstart ) ;
strip - > flag = ACTSTRIP_SELECT ;
strip - > repeat = 1.0 ;
act - > id . us + + ;
BLI_addtail ( & base - > object - > nlastrips , strip ) ;
}
}
static void mouse_nlachannels ( short mval [ 2 ] )
{
/* Find which strip has been clicked */
// bActionChannel *chan;
bConstraintChannel * conchan = NULL ;
bActionStrip * strip ;
float click ;
int wsize ;
int sel ;
Base * base ;
wsize = ( count_nla_levels ( ) * ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ) ;
click = ( wsize - ( mval [ 1 ] + G . v2d - > cur . ymin ) ) ;
click + = NLACHANNELHEIGHT / 2 ;
click / = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( click < 0 )
return ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
if ( nla_filter ( base , 0 ) ) {
/* See if this is a base selected */
if ( ( int ) click = = 0 )
break ;
click - - ;
/* Check for click in a constraint */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
if ( ( int ) click = = 0 ) {
base = G . scene - > base . last ;
break ;
}
click - - ;
}
/* See if this is an action */
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
if ( ( int ) click = = 0 ) {
break ;
}
click - - ;
}
/* See if this is an nla strip */
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( ( int ) click = = 0 ) {
base = G . scene - > base . last ;
break ;
}
click - - ;
}
}
}
if ( ! base & & ! conchan )
return ;
/* Handle constraint strip selection */
if ( conchan ) {
if ( conchan - > flag & CONSTRAINT_CHANNEL_SELECT )
sel = 0 ;
else
sel = 1 ;
/* Channel names clicking */
if ( G . qual & LR_SHIFTKEY ) {
// select_poseelement_by_name(chan->name, !(chan->flag & ACHAN_SELECTED));
if ( conchan - > flag & CONSTRAINT_CHANNEL_SELECT ) {
conchan - > flag & = ~ CONSTRAINT_CHANNEL_SELECT ;
// hilight_channel(act, chan, 0);
}
else {
conchan - > flag | = CONSTRAINT_CHANNEL_SELECT ;
// hilight_channel(act, chan, 1);
}
}
else {
deselect_nlachannels ( 0 ) ; // Auto clear
conchan - > flag | = CONSTRAINT_CHANNEL_SELECT ;
// hilight_channel(act, chan, 1);
// act->achan = chan;
// select_poseelement_by_name(chan->name, 1);
}
}
/* Handle object strip selection */
else if ( base )
{
/* Choose the mode */
if ( base - > flag & SELECT )
sel = 0 ;
else
sel = 1 ;
/* Channel names clicking */
if ( G . qual & LR_SHIFTKEY ) {
// select_poseelement_by_name(chan->name, !(chan->flag & ACHAN_SELECTED));
if ( base - > flag & SELECT ) {
base - > flag & = ~ SELECT ;
// hilight_channel(act, chan, 0);
}
else {
base - > flag | = SELECT ;
// hilight_channel(act, chan, 1);
}
}
else {
deselect_nlachannels ( 0 ) ; // Auto clear
base - > flag | = SELECT ;
// hilight_channel(act, chan, 1);
// act->achan = chan;
// select_poseelement_by_name(chan->name, 1);
}
}
allqueue ( REDRAWIPO , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
allqueue ( REDRAWACTION , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
}
void init_nlaspace ( ScrArea * sa )
{
SpaceNla * snla ;
snla = MEM_callocN ( sizeof ( SpaceNla ) , " initnlaspace " ) ;
BLI_addhead ( & sa - > spacedata , snla ) ;
snla - > spacetype = SPACE_NLA ;
snla - > v2d . tot . xmin = 1.0 ;
snla - > v2d . tot . ymin = 0.0 ;
snla - > v2d . tot . xmax = 1000.0 ;
snla - > v2d . tot . ymax = 1000.0 ;
snla - > v2d . cur . xmin = - 5.0 ;
snla - > v2d . cur . ymin = 0.0 ;
snla - > v2d . cur . xmax = 65.0 ;
snla - > v2d . cur . ymax = 1000.0 ;
snla - > v2d . min [ 0 ] = 0.0 ;
snla - > v2d . min [ 1 ] = 0.0 ;
snla - > v2d . max [ 0 ] = 1000.0 ;
snla - > v2d . max [ 1 ] = 1000.0 ;
snla - > v2d . minzoom = 0.1F ;
snla - > v2d . maxzoom = 10 ;
snla - > v2d . scroll = R_SCROLL + B_SCROLL ;
snla - > v2d . keepaspect = 0 ;
snla - > v2d . keepzoom = V2D_LOCKZOOM_Y ;
snla - > v2d . keeptot = 0 ;
snla - > lock = 0 ;
} ;
static void deselect_nlachannel_keys ( int test )
{
Base * base ;
int sel = 1 ;
bActionChannel * chan ;
bActionStrip * strip ;
bConstraintChannel * conchan ;
/* Determine if this is selection or deselection */
if ( LICENSE_KEY_VALID ) {
if ( test ) {
for ( base = G . scene - > base . first ; base & & sel ; base = base - > next ) {
/* Test object ipos */
if ( is_ipo_key_selected ( base - > object - > ipo ) ) {
sel = 0 ;
break ;
}
/* Test object constraint ipos */
if ( sel ) {
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
if ( is_ipo_key_selected ( conchan - > ipo ) ) {
sel = 0 ;
break ;
}
}
}
/* Test action ipos */
if ( sel ) {
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
if ( is_ipo_key_selected ( chan - > ipo ) ) {
sel = 0 ;
break ;
}
/* Test action constraints */
if ( sel ) {
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
if ( is_ipo_key_selected ( conchan - > ipo ) ) {
sel = 0 ;
break ;
}
}
}
}
}
}
/* Test NLA strips */
if ( sel ) {
if ( base - > object - > type = = OB_ARMATURE ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( strip - > flag & ACTSTRIP_SELECT ) {
sel = 0 ;
break ;
}
}
}
}
}
}
else
sel = 0 ;
/* Set the flags */
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Set the object ipos */
set_ipo_key_selection ( base - > object - > ipo , sel ) ;
/* Set the object constraint ipos */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
set_ipo_key_selection ( conchan - > ipo , sel ) ;
}
/* Set the action ipos */
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
set_ipo_key_selection ( chan - > ipo , sel ) ;
/* Set the action constraint ipos */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
set_ipo_key_selection ( conchan - > ipo , sel ) ;
}
}
/* Set the nlastrips */
if ( base - > object - > type = = OB_ARMATURE ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( sel )
strip - > flag | = ACTSTRIP_SELECT ;
else
strip - > flag & = ~ ACTSTRIP_SELECT ;
}
}
}
}
}
static void transform_nlachannel_keys ( char mode )
{
Base * base ;
TransVert * tv ;
int /*sel=0,*/ i ;
short mvals [ 2 ] , mvalc [ 2 ] ;
// short cent[2];
float sval [ 2 ] , cval [ 2 ] , lastcval [ 2 ] ;
short cancel = 0 ;
float fac = 0.0F ;
int loop = 1 ;
int tvtot = 0 ;
float deltax , startx ;
// float cenf[2];
int invert = 0 , firsttime = 1 ;
char str [ 256 ] ;
bActionChannel * chan ;
bActionStrip * strip ;
bConstraintChannel * conchan ;
if ( LICENSE_KEY_VALID ) {
/* Ensure that partial selections result in beztriple selections */
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Check object ipos */
tvtot + = fullselect_ipo_keys ( base - > object - > ipo ) ;
/* Check object constraint ipos */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next )
tvtot + = fullselect_ipo_keys ( conchan - > ipo ) ;
/* Check action ipos */
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
tvtot + = fullselect_ipo_keys ( chan - > ipo ) ;
/* Check action constraint ipos */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
tvtot + = fullselect_ipo_keys ( conchan - > ipo ) ;
}
}
/* Check nlastrips */
if ( base - > object - > type = = OB_ARMATURE ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( strip - > flag & ACTSTRIP_SELECT )
tvtot + = 2 ;
}
}
}
/* If nothing is selected, bail out */
if ( ! tvtot )
return ;
/* Build the transvert structure */
tv = MEM_callocN ( sizeof ( TransVert ) * tvtot , " transVert " ) ;
tvtot = 0 ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Manipulate object ipos */
tvtot = add_trans_ipo_keys ( base - > object - > ipo , tv , tvtot ) ;
/* Manipulate object constraint ipos */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next )
tvtot = add_trans_ipo_keys ( conchan - > ipo , tv , tvtot ) ;
/* Manipulate action ipos */
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
tvtot = add_trans_ipo_keys ( chan - > ipo , tv , tvtot ) ;
/* Manipulate action constraint ipos */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
tvtot = add_trans_ipo_keys ( conchan - > ipo , tv , tvtot ) ;
}
}
/* Manipulate nlastrips */
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( strip - > flag & ACTSTRIP_SELECT ) {
tv [ tvtot + 0 ] . val = & strip - > start ;
tv [ tvtot + 1 ] . val = & strip - > end ;
tv [ tvtot + 0 ] . oldval = strip - > start ;
tv [ tvtot + 1 ] . oldval = strip - > end ;
tvtot + = 2 ;
}
}
}
/* Do the event loop */
// cent[0] = curarea->winx + (G.snla->v2d.hor.xmax)/2;
// cent[1] = curarea->winy + (G.snla->v2d.hor.ymax)/2;
// areamouseco_to_ipoco(cent, &cenf[0], &cenf[1]);
getmouseco_areawin ( mvals ) ;
areamouseco_to_ipoco ( G . v2d , mvals , & sval [ 0 ] , & sval [ 1 ] ) ;
startx = sval [ 0 ] ;
while ( loop ) {
/* Get the input */
/* If we're cancelling, reset transformations */
/* Else calc new transformation */
/* Perform the transformations */
while ( qtest ( ) ) {
short val ;
unsigned short event = extern_qread ( & val ) ;
if ( val ) {
switch ( event ) {
case LEFTMOUSE :
case SPACEKEY :
case RETKEY :
loop = 0 ;
break ;
case XKEY :
break ;
case ESCKEY :
case RIGHTMOUSE :
cancel = 1 ;
loop = 0 ;
break ;
default :
arrows_move_cursor ( event ) ;
break ;
} ;
}
}
if ( cancel ) {
for ( i = 0 ; i < tvtot ; i + + ) {
if ( tv [ i ] . loc ) {
tv [ i ] . loc [ 0 ] = tv [ i ] . oldloc [ 0 ] ;
tv [ i ] . loc [ 1 ] = tv [ i ] . oldloc [ 1 ] ;
}
if ( tv [ i ] . val )
tv [ i ] . val [ 0 ] = tv [ i ] . oldval ;
}
}
else {
getmouseco_areawin ( mvalc ) ;
areamouseco_to_ipoco ( G . v2d , mvalc , & cval [ 0 ] , & cval [ 1 ] ) ;
if ( ! firsttime & & lastcval [ 0 ] = = cval [ 0 ] & & lastcval [ 1 ] = = cval [ 1 ] ) {
PIL_sleep_ms ( 1 ) ;
}
else {
for ( i = 0 ; i < tvtot ; i + + ) {
if ( tv [ i ] . loc )
tv [ i ] . loc [ 0 ] = tv [ i ] . oldloc [ 0 ] ;
if ( tv [ i ] . val )
tv [ i ] . val [ 0 ] = tv [ i ] . oldval ;
switch ( mode ) {
case ' g ' :
deltax = cval [ 0 ] - sval [ 0 ] ;
fac = deltax ;
apply_keyb_grid ( & fac , 0.0F , 1.0F , 0.1F , U . flag & AUTOGRABGRID ) ;
if ( tv [ i ] . loc )
tv [ i ] . loc [ 0 ] + = fac ;
if ( tv [ i ] . val )
tv [ i ] . val [ 0 ] + = fac ;
break ;
case ' s ' :
startx = mvals [ 0 ] - ( NLAWIDTH / 2 + ( curarea - > winrct . xmax - curarea - > winrct . xmin ) / 2 ) ;
deltax = mvalc [ 0 ] - ( NLAWIDTH / 2 + ( curarea - > winrct . xmax - curarea - > winrct . xmin ) / 2 ) ;
fac = ( float ) fabs ( deltax / startx ) ;
apply_keyb_grid ( & fac , 0.0F , 0.2F , 0.1F , U . flag & AUTOSIZEGRID ) ;
if ( invert ) {
if ( i % 03 = = 0 ) {
memcpy ( tv [ i ] . loc , tv [ i ] . oldloc , sizeof ( tv [ i + 2 ] . oldloc ) ) ;
}
if ( i % 03 = = 2 ) {
memcpy ( tv [ i ] . loc , tv [ i ] . oldloc , sizeof ( tv [ i - 2 ] . oldloc ) ) ;
}
fac * = - 1 ;
}
startx = ( G . scene - > r . cfra ) ;
if ( tv [ i ] . loc ) {
tv [ i ] . loc [ 0 ] - = startx ;
tv [ i ] . loc [ 0 ] * = fac ;
tv [ i ] . loc [ 0 ] + = startx ;
}
if ( tv [ i ] . val ) {
tv [ i ] . val [ 0 ] - = startx ;
tv [ i ] . val [ 0 ] * = fac ;
tv [ i ] . val [ 0 ] + = startx ;
}
break ;
}
}
}
if ( mode = = ' s ' ) {
sprintf ( str , " sizeX: %.3f " , fac ) ;
headerprint ( str ) ;
}
else if ( mode = = ' g ' ) {
sprintf ( str , " deltaX: %.3f " , fac ) ;
headerprint ( str ) ;
}
if ( G . snla - > lock ) {
allqueue ( REDRAWVIEW3D , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWIPO , 0 ) ;
force_draw_all ( ) ;
}
else {
addqueue ( curarea - > win , REDRAWALL , 0 ) ;
force_draw ( ) ;
}
}
lastcval [ 0 ] = cval [ 0 ] ;
lastcval [ 1 ] = cval [ 1 ] ;
firsttime = 0 ;
}
allspace ( REMAKEALLIPO , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWIPO , 0 ) ;
MEM_freeN ( tv ) ;
}
}
static void delete_nlachannel_keys ( void )
{
Base * base ;
bActionChannel * chan ;
bConstraintChannel * conchan ;
bActionStrip * strip , * nextstrip ;
if ( LICENSE_KEY_VALID ) {
if ( ! okee ( " Erase selected keys " ) )
return ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Delete object ipos */
delete_ipo_keys ( base - > object - > ipo ) ;
/* Delete object constraint keys */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next )
delete_ipo_keys ( conchan - > ipo ) ;
/* Delete NLA strips */
if ( base - > object - > type = = OB_ARMATURE ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = nextstrip ) {
nextstrip = strip - > next ;
if ( strip - > flag & ACTSTRIP_SELECT ) {
free_actionstrip ( strip ) ;
BLI_remlink ( & base - > object - > nlastrips , strip ) ;
MEM_freeN ( strip ) ;
}
}
}
/* Delete action ipos */
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
delete_ipo_keys ( chan - > ipo ) ;
/* Delete action constraint keys */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
delete_ipo_keys ( conchan - > ipo ) ;
}
}
}
allspace ( REMAKEALLIPO , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWIPO , 0 ) ;
}
}
static void duplicate_nlachannel_keys ( void )
{
Base * base ;
bActionChannel * chan ;
bConstraintChannel * conchan ;
bActionStrip * strip , * laststrip ;
if ( LICENSE_KEY_VALID ) {
/* Find selected items */
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Duplicate object keys */
duplicate_ipo_keys ( base - > object - > ipo ) ;
/* Duplicate object constraint keys */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next )
duplicate_ipo_keys ( conchan - > ipo ) ;
/* Duplicate nla strips */
if ( base - > object - > type = = OB_ARMATURE ) {
laststrip = base - > object - > nlastrips . last ;
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( strip - > flag & ACTSTRIP_SELECT ) {
bActionStrip * newstrip ;
copy_actionstrip ( & newstrip , & strip ) ;
BLI_addtail ( & base - > object - > nlastrips , newstrip ) ;
strip - > flag & = ~ ACTSTRIP_SELECT ;
newstrip - > flag | = ACTSTRIP_SELECT ;
}
if ( strip = = laststrip )
break ;
}
}
/* Duplicate actionchannel keys */
if ( base - > object - > type = = OB_ARMATURE & & base - > object - > action ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
duplicate_ipo_keys ( chan - > ipo ) ;
/* Duplicate action constraint keys */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
duplicate_ipo_keys ( conchan - > ipo ) ;
}
}
}
transform_nlachannel_keys ( ' g ' ) ;
}
}
static void borderselect_nla ( void )
{
Base * base ;
rcti rect ;
rctf rectf ;
int val ;
short mval [ 2 ] ;
float ymin , ymax ;
bActionStrip * strip ;
bConstraintChannel * conchan ;
if ( LICENSE_KEY_VALID ) {
val = get_border ( & rect , 3 ) ;
if ( val ) {
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 = count_nla_levels ( ) ;
ymax * = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Check object ipos */
if ( nla_filter ( base , 0 ) ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( base - > object - > ipo ) {
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) )
borderselect_ipo_key ( base - > object - > ipo , rectf . xmin , rectf . xmax , val ) ;
}
ymax = ymin ;
/* Check object constraint ipos */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) )
borderselect_ipo_key ( conchan - > ipo , rectf . xmin , rectf . xmax , val ) ;
ymax = ymin ;
}
/* Check action ipos */
if ( ACTIVE_ARMATURE ( base ) ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( base - > object - > action ) {
bActionChannel * chan ;
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
borderselect_ipo_key ( chan - > ipo , rectf . xmin , rectf . xmax , val ) ;
/* Check action constraint ipos */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
borderselect_ipo_key ( conchan - > ipo , rectf . xmin , rectf . xmax , val ) ;
}
}
}
ymax = ymin ;
} /* End of if armature */
/* Skip nlastrips */
if ( base - > object - > type = = OB_ARMATURE ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
//
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
if ( ! ( ( rectf . xmax < strip - > start ) | | ( rectf . xmin > strip - > end ) ) ) {
if ( val = = 1 )
strip - > flag | = ACTSTRIP_SELECT ;
else
strip - > flag & = ~ ACTSTRIP_SELECT ;
}
}
ymax = ymin ;
}
}
} /* End of object filter */
}
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWACTION , 0 ) ;
allqueue ( REDRAWIPO , 0 ) ;
}
}
}
static void mouse_nla ( void )
{
short sel ;
float selx ;
short mval [ 2 ] ;
Base * base ;
bAction * act ;
bActionChannel * chan ;
bActionStrip * rstrip ;
bConstraintChannel * conchan ;
if ( LICENSE_KEY_VALID ) {
getmouseco_areawin ( mval ) ;
/* Try object ipo selection */
base = get_nearest_nlachannel_ob_key ( & selx , & sel ) ;
if ( base ) {
if ( ! ( G . qual & LR_SHIFTKEY ) ) {
deselect_nlachannel_keys ( 0 ) ;
sel = 0 ;
}
select_ipo_key ( base - > object - > ipo , selx , sel ) ;
/* Try object constraint selection */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next )
select_ipo_key ( conchan - > ipo , selx , sel ) ;
allqueue ( REDRAWIPO , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
return ;
}
/* Try action ipo selection */
act = get_nearest_nlachannel_ac_key ( & selx , & sel ) ;
if ( act ) {
if ( ! ( G . qual & LR_SHIFTKEY ) ) {
deselect_nlachannel_keys ( 0 ) ;
sel = 0 ;
}
for ( chan = act - > chanbase . first ; chan ; chan = chan - > next ) {
select_ipo_key ( chan - > ipo , selx , sel ) ;
/* Try action constraint selection */
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next )
select_ipo_key ( conchan - > ipo , selx , sel ) ;
}
allqueue ( REDRAWIPO , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
return ;
}
/* Try nla strip selection */
base = get_nearest_nlastrip ( & rstrip , & sel ) ;
if ( base ) {
if ( ! ( G . qual & LR_SHIFTKEY ) ) {
deselect_nlachannel_keys ( 0 ) ;
sel = 0 ;
}
if ( sel )
rstrip - > flag & = ~ ACTSTRIP_SELECT ;
else
rstrip - > flag | = ACTSTRIP_SELECT ;
allqueue ( REDRAWIPO , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
allqueue ( REDRAWNLA , 0 ) ;
return ;
}
}
}
static Base * get_nearest_nlastrip ( bActionStrip * * rstrip , short * sel )
/* This function is currently more complicated than it seems like it should be.
* However , this will be needed once the nla strip timeline is more complex */
{
Base * base , * firstbase = NULL ;
short mval [ 2 ] ;
short foundsel = 0 ;
rctf rectf ;
float ymin , ymax ;
bActionStrip * strip , * firststrip , * foundstrip ;
if ( LICENSE_KEY_VALID ) {
getmouseco_areawin ( mval ) ;
mval [ 0 ] - = 7 ;
areamouseco_to_ipoco ( G . v2d , mval , & rectf . xmin , & rectf . ymin ) ;
mval [ 0 ] + = 14 ;
areamouseco_to_ipoco ( G . v2d , mval , & rectf . xmax , & rectf . ymax ) ;
ymax = count_nla_levels ( ) ;
ymax * = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
if ( nla_filter ( base , 0 ) ) {
/* Skip object ipos */
// if (base->object->ipo)
ymax - = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( base - > object - > type = = OB_ARMATURE ) {
/* Skip action ipos */
if ( base - > object - > action )
ymax - = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
/* Do Ytest */
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
/* Do XTest */
if ( ! ( ( rectf . xmax < strip - > start ) | | ( rectf . xmin > strip - > end ) ) ) {
if ( ! firstbase ) {
firstbase = base ;
firststrip = strip ;
* sel = strip - > flag & ACTSTRIP_SELECT ;
}
if ( strip - > flag & ACTSTRIP_SELECT ) {
if ( ! foundsel ) {
foundsel = 1 ;
foundstrip = strip ;
}
}
else if ( foundsel & & strip ! = foundstrip ) {
* rstrip = strip ;
* sel = 0 ;
return base ;
}
}
}
ymax = ymin ;
}
}
}
}
* rstrip = firststrip ;
return firstbase ;
}
else
return NULL ;
}
static Base * get_nearest_nlachannel_ob_key ( float * index , short * sel )
{
Base * base ;
IpoCurve * icu ;
Base * firstbase = NULL ;
bConstraintChannel * conchan ;
int foundsel = 0 ;
float firstvert = - 1 , foundx = - 1 ;
int i ;
short mval [ 2 ] ;
float ymin , ymax ;
rctf rectf ;
if ( LICENSE_KEY_VALID ) {
* index = 0 ;
getmouseco_areawin ( mval ) ;
mval [ 0 ] - = 7 ;
areamouseco_to_ipoco ( G . v2d , mval , & rectf . xmin , & rectf . ymin ) ;
mval [ 0 ] + = 14 ;
areamouseco_to_ipoco ( G . v2d , mval , & rectf . xmax , & rectf . ymax ) ;
ymax = count_nla_levels ( ) ;
ymax * = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
* sel = 0 ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Handle object ipo selection */
if ( nla_filter ( base , 0 ) ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( base - > object - > ipo ) {
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
for ( icu = base - > object - > ipo - > curve . first ; icu ; icu = icu - > next ) {
for ( i = 0 ; i < icu - > totvert ; i + + ) {
if ( icu - > bezt [ i ] . vec [ 1 ] [ 0 ] > rectf . xmin & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] < = rectf . xmax ) {
if ( ! firstbase ) {
firstbase = base ;
firstvert = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = icu - > bezt [ i ] . f2 & 1 ;
}
if ( icu - > bezt [ i ] . f2 & 1 ) {
if ( ! foundsel ) {
foundsel = 1 ;
foundx = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
}
}
else if ( foundsel & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ! = foundx ) {
* index = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = 0 ;
return base ;
}
}
}
}
}
}
ymax = ymin ;
/* Handle object constraint ipos */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
for ( icu = conchan - > ipo - > curve . first ; icu ; icu = icu - > next ) {
for ( i = 0 ; i < icu - > totvert ; i + + ) {
if ( icu - > bezt [ i ] . vec [ 1 ] [ 0 ] > rectf . xmin & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] < = rectf . xmax ) {
if ( ! firstbase ) {
firstbase = base ;
firstvert = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = icu - > bezt [ i ] . f2 & 1 ;
}
if ( icu - > bezt [ i ] . f2 & 1 ) {
if ( ! foundsel ) {
foundsel = 1 ;
foundx = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
}
}
else if ( foundsel & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ! = foundx ) {
* index = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = 0 ;
return base ;
}
}
}
}
}
ymax = ymin ;
}
/* Skip action ipos */
if ( ACTIVE_ARMATURE ( base ) ) {
ymax - = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
}
/* Skip nlastrips */
if ( base - > object - > type = = OB_ARMATURE ) {
ymax - = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) * BLI_countlist ( & base - > object - > nlastrips ) ;
}
}
}
* index = firstvert ;
return firstbase ;
}
else
return NULL ;
}
static bAction * get_nearest_nlachannel_ac_key ( float * index , short * sel )
{
Base * base ;
IpoCurve * icu ;
bAction * firstact = NULL ;
int foundsel = 0 ;
float firstvert = - 1 , foundx = - 1 ;
int i ;
short mval [ 2 ] ;
float ymin , ymax ;
rctf rectf ;
bActionChannel * chan ;
bConstraintChannel * conchan ;
if ( LICENSE_KEY_VALID ) {
* index = 0 ;
getmouseco_areawin ( mval ) ;
mval [ 0 ] - = 7 ;
areamouseco_to_ipoco ( G . v2d , mval , & rectf . xmin , & rectf . ymin ) ;
mval [ 0 ] + = 14 ;
areamouseco_to_ipoco ( G . v2d , mval , & rectf . xmax , & rectf . ymax ) ;
ymax = count_nla_levels ( ) ;
ymax * = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
* sel = 0 ;
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Handle object ipo selection */
if ( nla_filter ( base , 0 ) ) {
/* Skip object ipo */
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
ymax = ymin ;
/* Handle action ipos */
if ( ACTIVE_ARMATURE ( base ) ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
for ( chan = base - > object - > action - > chanbase . first ; chan ; chan = chan - > next ) {
for ( icu = chan - > ipo - > curve . first ; icu ; icu = icu - > next ) {
for ( i = 0 ; i < icu - > totvert ; i + + ) {
if ( icu - > bezt [ i ] . vec [ 1 ] [ 0 ] > rectf . xmin & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] < = rectf . xmax ) {
if ( ! firstact ) {
firstact = base - > object - > action ;
firstvert = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = icu - > bezt [ i ] . f2 & 1 ;
}
if ( icu - > bezt [ i ] . f2 & 1 ) {
if ( ! foundsel ) {
foundsel = 1 ;
foundx = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
}
}
else if ( foundsel & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ! = foundx ) {
* index = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = 0 ;
return base - > object - > action ;
}
}
}
}
for ( conchan = chan - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
ymin = ymax - ( NLACHANNELHEIGHT + NLACHANNELSKIP ) ;
if ( ! ( ( ymax < rectf . ymin ) | | ( ymin > rectf . ymax ) ) ) {
for ( icu = conchan - > ipo - > curve . first ; icu ; icu = icu - > next ) {
for ( i = 0 ; i < icu - > totvert ; i + + ) {
if ( icu - > bezt [ i ] . vec [ 1 ] [ 0 ] > rectf . xmin & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] < = rectf . xmax ) {
if ( ! firstact ) {
firstact = base - > object - > action ;
firstvert = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = icu - > bezt [ i ] . f2 & 1 ;
}
if ( icu - > bezt [ i ] . f2 & 1 ) {
if ( ! foundsel ) {
foundsel = 1 ;
foundx = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
}
}
else if ( foundsel & & icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ! = foundx ) {
* index = icu - > bezt [ i ] . vec [ 1 ] [ 0 ] ;
* sel = 0 ;
return base - > object - > action ;
}
}
}
}
}
ymax = ymin ;
}
}
}
ymax = ymin ;
}
/* Skip nlastrips */
if ( base - > object - > type = = OB_ARMATURE ) {
ymax - = ( NLACHANNELHEIGHT + NLACHANNELSKIP ) * BLI_countlist ( & base - > object - > nlastrips ) ;
}
}
}
* index = firstvert ;
return firstact ;
}
else
return NULL ;
}
static bActionStrip * get_active_nlastrip ( void )
/* For now just returns the first selected strip */
{
Base * base ;
bActionStrip * strip ;
if ( LICENSE_KEY_VALID ) {
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
if ( nla_filter ( base , 0 ) & & base - > object - > type = = OB_ARMATURE ) {
for ( strip = base - > object - > nlastrips . first ; strip ; strip = strip - > next ) {
if ( strip - > flag & ACTSTRIP_SELECT )
return strip ;
}
}
}
return NULL ;
}
else
return NULL ;
}
void clever_numbuts_nla ( void ) {
bActionStrip * strip ;
int but = 0 ;
if ( LICENSE_KEY_VALID ) {
/* Determine if an nla strip has been selected */
strip = get_active_nlastrip ( ) ;
if ( ! strip )
return ;
add_numbut ( but + + , LABEL , " Timeline Range: " , 1.0 , 18000.0 , 0 , 0 ) ;
add_numbut ( but + + , NUM | FLO , " Strip Start: " , 1.0 , 18000.0 , & strip - > start , " First frame in the timeline " ) ;
add_numbut ( but + + , NUM | FLO , " Strip End: " , 1.0 , 18000.0 , & strip - > end , " Last frame in the timeline " ) ;
add_numbut ( but + + , LABEL , " Action Range: " , 1.0 , 18000.0 , 0 , 0 ) ;
add_numbut ( but + + , NUM | FLO , " Action Start: " , 1.0 , 18000.0 , & strip - > actstart , " First frame of the action to map to the playrange " ) ;
add_numbut ( but + + , NUM | FLO , " Action End: " , 1.0 , 18000.0 , & strip - > actend , " Last frame of the action to map to the playrange " ) ;
add_numbut ( but + + , LABEL , " Blending: " , 1.0 , 18000.0 , 0 , 0 ) ;
add_numbut ( but + + , NUM | FLO , " Blendin: " , 0.0 , 18000.0 , & strip - > blendin , " Number of frames of ease-in " ) ;
add_numbut ( but + + , NUM | FLO , " Blendout: " , 0.0 , 18000.0 , & strip - > blendout , " Number of frames of ease-out " ) ;
add_numbut ( but + + , LABEL , " Options: " , 1.0 , 18000.0 , 0 , 0 ) ;
add_numbut ( but + + , NUM | FLO , " Repeat: " , 0.0001 , 18000.0 , & strip - > repeat , " Number of times the action should repeat " ) ;
add_numbut ( but + + , NUM | FLO , " Stride: " , 0.0001 , 1000.0 , & strip - > stridelen , " Distance covered by one complete cycle of the action specified in the Action Range " ) ;
{
/* STUPID HACK BECAUSE NUMBUTS ARE BROKEN WITH MULTIPLE TOGGLES */
short hold = ( strip - > flag & ACTSTRIP_HOLDLASTFRAME ) ? 1 : 0 ;
short frompath = ( strip - > flag & ACTSTRIP_USESTRIDE ) ? 1 : 0 ;
add_numbut ( but + + , TOG | SHO , " Use Path " , 0 , 0 , & frompath , " Plays action based on position on path & stride length. Only valid for armatures that are parented to a path " ) ;
add_numbut ( but + + , TOG | SHO , " Hold " , 0 , 0 , & hold , " Toggles whether or not to continue displaying the last frame past the end of the strip " ) ;
add_numbut ( but + + , TOG | SHO , " Add " , 0 , 0 , & strip - > mode , " Toggles additive blending mode " ) ;
do_clever_numbuts ( " Action " , but , REDRAW ) ;
/* STUPID HACK BECAUSE NUMBUTS ARE BROKEN WITH MULTIPLE TOGGLES */
if ( hold ) strip - > flag | = ACTSTRIP_HOLDLASTFRAME ;
else strip - > flag & = ~ ACTSTRIP_HOLDLASTFRAME ;
if ( frompath ) strip - > flag | = ACTSTRIP_USESTRIDE ;
else strip - > flag & = ~ ACTSTRIP_USESTRIDE ;
}
if ( strip - > end < strip - > start )
strip - > end = strip - > start ;
if ( strip - > blendin > ( strip - > end - strip - > start ) )
strip - > blendin = strip - > end - strip - > start ;
if ( strip - > blendout > ( strip - > end - strip - > start ) )
strip - > blendout = strip - > end - strip - > start ;
if ( strip - > blendin > ( strip - > end - strip - > start - strip - > blendout ) )
strip - > blendin = ( strip - > end - strip - > start - strip - > blendout ) ;
if ( strip - > blendout > ( strip - > end - strip - > start - strip - > blendin ) )
strip - > blendout = ( strip - > end - strip - > start - strip - > blendin ) ;
update_for_newframe ( ) ;
allqueue ( REDRAWNLA , 0 ) ;
allqueue ( REDRAWVIEW3D , 0 ) ;
}
}
static void deselect_nlachannels ( int test ) {
int sel = 1 ;
Base * base ;
bConstraintChannel * conchan ;
if ( test ) {
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
/* Check base flags for previous selection */
if ( base - > flag & SELECT ) {
sel = 0 ;
break ;
}
/* Check constraint flags for previous selection */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
if ( conchan - > flag & CONSTRAINT_CHANNEL_SELECT ) {
sel = 0 ;
base = G . scene - > base . last ;
break ;
}
}
}
}
else
sel = 0 ;
/* Select objects */
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
if ( sel ) {
if ( nla_filter ( base , 0 ) )
base - > flag | = SELECT ;
}
else
base - > flag & = ~ SELECT ;
/* Select constraint channels */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
if ( sel ) {
if ( nla_filter ( base , 0 ) )
conchan - > flag | = CONSTRAINT_CHANNEL_SELECT ;
}
else
conchan - > flag & = ~ CONSTRAINT_CHANNEL_SELECT ;
}
}
}
static void delete_nlachannels ( void ) {
Base * base ;
bConstraintChannel * conchan , * nextchan ;
int sel = 0 ;
/* See if there is anything selected */
for ( base = G . scene - > base . first ; base & & ( ! sel ) ; base = base - > next ) {
/* Check constraints */
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = conchan - > next ) {
if ( conchan - > flag & CONSTRAINT_CHANNEL_SELECT ) {
sel = 1 ;
break ;
}
}
}
if ( ! sel )
return ;
if ( okee ( " Delete selected channels " ) ) {
for ( base = G . scene - > base . first ; base ; base = base - > next ) {
for ( conchan = base - > object - > constraintChannels . first ; conchan ; conchan = nextchan ) {
nextchan = conchan - > next ;
if ( conchan - > flag & CONSTRAINT_CHANNEL_SELECT ) {
/* If we're the active constraint, unlink us */
if ( conchan = = base - > object - > activecon )
base - > object - > activecon = NULL ;
if ( conchan - > ipo )
conchan - > ipo - > id . us - - ;
BLI_freelinkN ( & base - > object - > constraintChannels , conchan ) ;
}
}
}
}
2002-10-30 00:27:48 +00:00
}