
- border select initiated in the channel names border selects the channels and constraint channels. - right click or border select initiated in the horizontal scroll causes blender to select all keys for the selected frames. - right click or border select in the vertical scroll causes blender to select all keys for the channel or constraint channels that are to the left of the selection.
5627 lines
117 KiB
C
5627 lines
117 KiB
C
/**
|
|
* $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 *****
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#include <unistd.h>
|
|
#else
|
|
#include <io.h>
|
|
#include "BLI_winstuff.h"
|
|
#endif
|
|
#include "MEM_guardedalloc.h"
|
|
#include "PIL_time.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_arithb.h"
|
|
#include "BLI_editVert.h"
|
|
|
|
#include "DNA_constraint_types.h"
|
|
#include "DNA_action_types.h"
|
|
#include "DNA_armature_types.h"
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_lamp_types.h"
|
|
#include "DNA_sequence_types.h"
|
|
#include "DNA_sound_types.h"
|
|
#include "DNA_camera_types.h"
|
|
#include "DNA_material_types.h"
|
|
#include "DNA_key_types.h"
|
|
#include "DNA_screen_types.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_ipo_types.h"
|
|
#include "DNA_curve_types.h"
|
|
#include "DNA_space_types.h"
|
|
#include "DNA_userdef_types.h"
|
|
#include "DNA_view3d_types.h"
|
|
#include "DNA_group_types.h"
|
|
#include "DNA_ika_types.h"
|
|
|
|
#include "BKE_utildefines.h"
|
|
#include "BKE_action.h"
|
|
#include "BKE_anim.h"
|
|
#include "BKE_material.h"
|
|
#include "BKE_ipo.h"
|
|
#include "BKE_key.h"
|
|
#include "BKE_ika.h"
|
|
#include "BKE_displist.h"
|
|
#include "BKE_global.h"
|
|
#include "BKE_group.h"
|
|
|
|
#include "BIF_buttons.h"
|
|
#include "BIF_editkey.h"
|
|
#include "BIF_editseq.h"
|
|
#include "BIF_editview.h"
|
|
#include "BIF_interface.h"
|
|
#include "BIF_mywindow.h"
|
|
#include "BIF_poseobject.h"
|
|
#include "BIF_screen.h"
|
|
#include "BIF_space.h"
|
|
#include "BIF_toolbox.h"
|
|
#include "BIF_poseobject.h"
|
|
|
|
#include "BDR_drawobject.h"
|
|
#include "BDR_editobject.h"
|
|
|
|
#include "BSE_trans_types.h"
|
|
#include "BSE_editipo_types.h"
|
|
#include "BSE_drawipo.h"
|
|
#include "BSE_editipo.h"
|
|
#include "BSE_editaction.h"
|
|
#include "BSE_edit.h"
|
|
#include "BSE_drawview.h"
|
|
#include "BSE_headerbuttons.h"
|
|
|
|
#include "blendef.h"
|
|
#include "mydevice.h"
|
|
#include "interface.h"
|
|
#include "render.h"
|
|
|
|
/* forwards */
|
|
#define BEZSELECTED(bezt) (((bezt)->f1 & 1) || ((bezt)->f2 & 1) || ((bezt)->f3 & 1))
|
|
|
|
#define IPOTHRESH 0.9
|
|
#define ISPOIN(a, b, c) ( (a->b) && (a->c) )
|
|
#define ISPOIN3(a, b, c, d) ( (a->b) && (a->c) && (a->d) )
|
|
#define ISPOIN4(a, b, c, d, e) ( (a->b) && (a->c) && (a->d) && (a->e) )
|
|
|
|
extern int ob_ar[];
|
|
extern int ma_ar[];
|
|
extern int seq_ar[];
|
|
extern int cu_ar[];
|
|
extern int key_ar[];
|
|
extern int wo_ar[];
|
|
extern int la_ar[];
|
|
extern int cam_ar[];
|
|
extern int snd_ar[];
|
|
extern int ac_ar[];
|
|
extern int co_ar[];
|
|
|
|
void getname_ac_ei(int nr, char *str)
|
|
{
|
|
switch(nr) {
|
|
case AC_LOC_X:
|
|
strcpy(str, "LocX"); break;
|
|
case AC_LOC_Y:
|
|
strcpy(str, "LocY"); break;
|
|
case AC_LOC_Z:
|
|
strcpy(str, "LocZ"); break;
|
|
case AC_SIZE_X:
|
|
strcpy(str, "SizeX"); break;
|
|
case AC_SIZE_Y:
|
|
strcpy(str, "SizeY"); break;
|
|
case AC_SIZE_Z:
|
|
strcpy(str, "SizeZ"); break;
|
|
case AC_QUAT_X:
|
|
strcpy(str, "QuatX"); break;
|
|
case AC_QUAT_Y:
|
|
strcpy(str, "QuatY"); break;
|
|
case AC_QUAT_Z:
|
|
strcpy(str, "QuatZ"); break;
|
|
case AC_QUAT_W:
|
|
strcpy(str, "QuatW"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
void getname_co_ei(int nr, char *str)
|
|
{
|
|
switch(nr){
|
|
case CO_ENFORCE:
|
|
strcpy(str, "Inf"); break;
|
|
}
|
|
}
|
|
|
|
void getname_ob_ei(int nr, char *str, int colipo)
|
|
{
|
|
switch(nr) {
|
|
case OB_LOC_X:
|
|
strcpy(str, "LocX"); break;
|
|
case OB_LOC_Y:
|
|
strcpy(str, "LocY"); break;
|
|
case OB_LOC_Z:
|
|
strcpy(str, "LocZ"); break;
|
|
case OB_DLOC_X:
|
|
strcpy(str, "dLocX"); break;
|
|
case OB_DLOC_Y:
|
|
strcpy(str, "dLocY"); break;
|
|
case OB_DLOC_Z:
|
|
strcpy(str, "dLocZ"); break;
|
|
|
|
case OB_ROT_X:
|
|
strcpy(str, "RotX"); break;
|
|
case OB_ROT_Y:
|
|
strcpy(str, "RotY"); break;
|
|
case OB_ROT_Z:
|
|
strcpy(str, "RotZ"); break;
|
|
case OB_DROT_X:
|
|
strcpy(str, "dRotX"); break;
|
|
case OB_DROT_Y:
|
|
strcpy(str, "dRotY"); break;
|
|
case OB_DROT_Z:
|
|
strcpy(str, "dRotZ"); break;
|
|
|
|
case OB_SIZE_X:
|
|
strcpy(str, "SizeX"); break;
|
|
case OB_SIZE_Y:
|
|
strcpy(str, "SizeY"); break;
|
|
case OB_SIZE_Z:
|
|
strcpy(str, "SizeZ"); break;
|
|
case OB_DSIZE_X:
|
|
strcpy(str, "dSizeX"); break;
|
|
case OB_DSIZE_Y:
|
|
strcpy(str, "dSizeY"); break;
|
|
case OB_DSIZE_Z:
|
|
strcpy(str, "dSizeZ"); break;
|
|
|
|
case OB_LAY:
|
|
strcpy(str, "Layer"); break;
|
|
|
|
case OB_TIME:
|
|
strcpy(str, "Time"); break;
|
|
case OB_EFF_X:
|
|
if(colipo) strcpy(str, "ColR");
|
|
else strcpy(str, "EffX");
|
|
break;
|
|
case OB_EFF_Y:
|
|
if(colipo) strcpy(str, "ColG");
|
|
else strcpy(str, "EffY");
|
|
break;
|
|
case OB_EFF_Z:
|
|
if(colipo) strcpy(str, "ColB");
|
|
else strcpy(str, "EffZ");
|
|
break;
|
|
case OB_COL_A:
|
|
strcpy(str, "ColA");
|
|
break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
void getname_tex_ei(int nr, char *str)
|
|
{
|
|
switch(nr) {
|
|
case MAP_OFS_X:
|
|
strcpy(str, "OfsX"); break;
|
|
case MAP_OFS_Y:
|
|
strcpy(str, "OfsY"); break;
|
|
case MAP_OFS_Z:
|
|
strcpy(str, "OfsZ"); break;
|
|
case MAP_SIZE_X:
|
|
strcpy(str, "SizeX"); break;
|
|
case MAP_SIZE_Y:
|
|
strcpy(str, "SizeY"); break;
|
|
case MAP_SIZE_Z:
|
|
strcpy(str, "SizeZ"); break;
|
|
case MAP_R:
|
|
strcpy(str, "texR"); break;
|
|
case MAP_G:
|
|
strcpy(str, "texG"); break;
|
|
case MAP_B:
|
|
strcpy(str, "texB"); break;
|
|
case MAP_DVAR:
|
|
strcpy(str, "DefVar"); break;
|
|
case MAP_COLF:
|
|
strcpy(str, "Col"); break;
|
|
case MAP_NORF:
|
|
strcpy(str, "Nor"); break;
|
|
case MAP_VARF:
|
|
strcpy(str, "Var"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
void getname_mat_ei(int nr, char *str)
|
|
{
|
|
if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str);
|
|
else {
|
|
switch(nr) {
|
|
case MA_COL_R:
|
|
strcpy(str, "R"); break;
|
|
case MA_COL_G:
|
|
strcpy(str, "G"); break;
|
|
case MA_COL_B:
|
|
strcpy(str, "B"); break;
|
|
case MA_SPEC_R:
|
|
strcpy(str, "SpecR"); break;
|
|
case MA_SPEC_G:
|
|
strcpy(str, "SpecG"); break;
|
|
case MA_SPEC_B:
|
|
strcpy(str, "SpecB"); break;
|
|
case MA_MIR_R:
|
|
strcpy(str, "MirR"); break;
|
|
case MA_MIR_G:
|
|
strcpy(str, "MirG"); break;
|
|
case MA_MIR_B:
|
|
strcpy(str, "MirB"); break;
|
|
case MA_REF:
|
|
strcpy(str, "Ref"); break;
|
|
case MA_ALPHA:
|
|
strcpy(str, "Alpha"); break;
|
|
case MA_EMIT:
|
|
strcpy(str, "Emit"); break;
|
|
case MA_AMB:
|
|
strcpy(str, "Amb"); break;
|
|
case MA_SPEC:
|
|
strcpy(str, "Spec"); break;
|
|
case MA_HARD:
|
|
strcpy(str, "Hard"); break;
|
|
case MA_SPTR:
|
|
strcpy(str, "SpTra"); break;
|
|
case MA_ANG:
|
|
strcpy(str, "Ang"); break;
|
|
case MA_MODE:
|
|
strcpy(str, "Mode"); break;
|
|
case MA_HASIZE:
|
|
strcpy(str, "HaSize"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void getname_world_ei(int nr, char *str)
|
|
{
|
|
if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str);
|
|
else {
|
|
switch(nr) {
|
|
case WO_HOR_R:
|
|
strcpy(str, "HorR"); break;
|
|
case WO_HOR_G:
|
|
strcpy(str, "HorG"); break;
|
|
case WO_HOR_B:
|
|
strcpy(str, "HorB"); break;
|
|
case WO_ZEN_R:
|
|
strcpy(str, "ZenR"); break;
|
|
case WO_ZEN_G:
|
|
strcpy(str, "ZenG"); break;
|
|
case WO_ZEN_B:
|
|
strcpy(str, "ZenB"); break;
|
|
|
|
case WO_EXPOS:
|
|
strcpy(str, "Expos"); break;
|
|
|
|
case WO_MISI:
|
|
strcpy(str, "Misi"); break;
|
|
case WO_MISTDI:
|
|
strcpy(str, "MisDi"); break;
|
|
case WO_MISTSTA:
|
|
strcpy(str, "MisSta"); break;
|
|
case WO_MISTHI:
|
|
strcpy(str, "MisHi"); break;
|
|
|
|
case WO_STAR_R:
|
|
strcpy(str, "StarR"); break;
|
|
case WO_STAR_G:
|
|
strcpy(str, "StarB"); break;
|
|
case WO_STAR_B:
|
|
strcpy(str, "StarG"); break;
|
|
|
|
case WO_STARDIST:
|
|
strcpy(str, "StarDi"); break;
|
|
case WO_STARSIZE:
|
|
strcpy(str, "StarSi"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void getname_seq_ei(int nr, char *str)
|
|
{
|
|
switch(nr) {
|
|
case SEQ_FAC1:
|
|
strcpy(str, "Fac"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
void getname_cu_ei(int nr, char *str)
|
|
{
|
|
|
|
switch(nr) {
|
|
case CU_SPEED:
|
|
strcpy(str, "Speed"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
void getname_key_ei(int nr, char *str)
|
|
{
|
|
if(nr==KEY_SPEED) strcpy(str, "Speed");
|
|
else sprintf(str, "Key %d", nr);
|
|
}
|
|
|
|
void getname_la_ei(int nr, char *str)
|
|
{
|
|
if(nr>=MA_MAP1) getname_tex_ei((nr & (MA_MAP1-1)), str);
|
|
else {
|
|
switch(nr) {
|
|
case LA_ENERGY:
|
|
strcpy(str, "Energ"); break;
|
|
case LA_COL_R:
|
|
strcpy(str, "R"); break;
|
|
case LA_COL_G:
|
|
strcpy(str, "G"); break;
|
|
case LA_COL_B:
|
|
strcpy(str, "B"); break;
|
|
case LA_DIST:
|
|
strcpy(str, "Dist"); break;
|
|
case LA_SPOTSI:
|
|
strcpy(str, "SpoSi"); break;
|
|
case LA_SPOTBL:
|
|
strcpy(str, "SpoBl"); break;
|
|
case LA_QUAD1:
|
|
strcpy(str, "Quad1"); break;
|
|
case LA_QUAD2:
|
|
strcpy(str, "Quad2"); break;
|
|
case LA_HALOINT:
|
|
strcpy(str, "HaInt"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void getname_cam_ei(int nr, char *str)
|
|
{
|
|
switch(nr) {
|
|
case CAM_LENS:
|
|
strcpy(str, "Lens"); break;
|
|
case CAM_STA:
|
|
strcpy(str, "ClSta"); break;
|
|
case CAM_END:
|
|
strcpy(str, "ClEnd"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
void getname_snd_ei(int nr, char *str)
|
|
{
|
|
switch(nr) {
|
|
case SND_VOLUME:
|
|
strcpy(str, "Vol"); break;
|
|
case SND_PITCH:
|
|
strcpy(str, "Pitch"); break;
|
|
case SND_PANNING:
|
|
strcpy(str, "Pan"); break;
|
|
case SND_ATTEN:
|
|
strcpy(str, "Atten"); break;
|
|
default:
|
|
str[0]= 0;
|
|
}
|
|
}
|
|
|
|
|
|
IpoCurve *find_ipocurve(Ipo *ipo, int adrcode)
|
|
{
|
|
if(ipo) {
|
|
IpoCurve *icu= ipo->curve.first;
|
|
while(icu) {
|
|
if(icu->adrcode==adrcode) return icu;
|
|
icu= icu->next;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void boundbox_ipocurve(IpoCurve *icu)
|
|
{
|
|
BezTriple *bezt;
|
|
float vec[3]={0.0,0.0,0.0};
|
|
float min[3], max[3];
|
|
int a;
|
|
|
|
if(icu->totvert) {
|
|
INIT_MINMAX(min, max);
|
|
|
|
if(icu->bezt ) {
|
|
a= icu->totvert;
|
|
bezt= icu->bezt;
|
|
while(a--) {
|
|
if(icu->vartype & IPO_BITS) {
|
|
vec[0]= bezt->vec[1][0];
|
|
vec[1]= 0.0;
|
|
DO_MINMAX(vec, min, max);
|
|
|
|
vec[1]= 16.0;
|
|
DO_MINMAX(vec, min, max);
|
|
}
|
|
else {
|
|
if(icu->ipo==IPO_BEZ && a!=icu->totvert-1) {
|
|
DO_MINMAX(bezt->vec[0], min, max);
|
|
}
|
|
DO_MINMAX(bezt->vec[1], min, max);
|
|
if(icu->ipo==IPO_BEZ && a!=0) {
|
|
DO_MINMAX(bezt->vec[2], min, max);
|
|
}
|
|
}
|
|
|
|
bezt++;
|
|
}
|
|
}
|
|
if(min[0]==max[0]) max[0]= (float)(min[0]+1.0);
|
|
if(min[1]==max[1]) max[1]= (float)(min[1]+0.1);
|
|
|
|
icu->totrct.xmin= min[0];
|
|
icu->totrct.ymin= min[1];
|
|
icu->totrct.xmax= max[0];
|
|
icu->totrct.ymax= max[1];
|
|
}
|
|
else {
|
|
icu->totrct.xmin= icu->totrct.ymin= 0.0;
|
|
icu->totrct.xmax= EFRA;
|
|
icu->totrct.ymax= 1.0;
|
|
}
|
|
}
|
|
|
|
void boundbox_ipo(Ipo *ipo, rctf *bb)
|
|
{
|
|
IpoCurve *icu;
|
|
int first= 1;
|
|
|
|
icu= ipo->curve.first;
|
|
while(icu) {
|
|
|
|
boundbox_ipocurve(icu);
|
|
|
|
if(first) {
|
|
*bb= icu->totrct;
|
|
first= 0;
|
|
}
|
|
else BLI_union_rctf(bb, &(icu->totrct));
|
|
|
|
icu= icu->next;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void editipo_changed(SpaceIpo *si, int doredraw)
|
|
{
|
|
EditIpo *ei;
|
|
View2D *v2d;
|
|
Key *key;
|
|
KeyBlock *kb;
|
|
int a, first=1;
|
|
|
|
|
|
ei= si->editipo;
|
|
if(ei==0)
|
|
return;
|
|
|
|
for(a=0; a<si->totipo; a++, ei++) {
|
|
|
|
if(ei->icu) {
|
|
|
|
/* 2 keer i.v.m. ittereren nieuwe autohandle */
|
|
calchandles_ipocurve(ei->icu);
|
|
calchandles_ipocurve(ei->icu);
|
|
|
|
if(ei->flag & IPO_VISIBLE) {
|
|
|
|
boundbox_ipocurve(ei->icu);
|
|
sort_time_ipocurve(ei->icu);
|
|
if(first) {
|
|
si->v2d.tot= ei->icu->totrct;
|
|
first= 0;
|
|
}
|
|
else BLI_union_rctf(&(si->v2d.tot), &(ei->icu->totrct));
|
|
}
|
|
}
|
|
}
|
|
|
|
v2d= &(si->v2d);
|
|
// v2d = &G.v2d;
|
|
|
|
/* keylijnen? */
|
|
if(si->blocktype==ID_KE) {
|
|
key= (Key *)si->from;
|
|
if(key && key->block.first) {
|
|
kb= key->block.first;
|
|
if(kb->pos < v2d->tot.ymin) v2d->tot.ymin= kb->pos;
|
|
kb= key->block.last;
|
|
if(kb->pos > v2d->tot.ymax) v2d->tot.ymax= kb->pos;
|
|
}
|
|
}
|
|
|
|
|
|
/* is er geen curve? */
|
|
if(first) {
|
|
v2d->tot.xmin= 0.0;
|
|
v2d->tot.xmax= EFRA;
|
|
v2d->tot.ymin= (float)-0.1;
|
|
v2d->tot.ymax= (float)1.1;
|
|
|
|
if(si->blocktype==ID_SEQ) {
|
|
v2d->tot.xmin= -5.0;
|
|
v2d->tot.xmax= 105.0;
|
|
v2d->tot.ymin= (float)-0.1;
|
|
v2d->tot.ymax= (float)1.1;
|
|
}
|
|
}
|
|
|
|
si->tot= v2d->tot;
|
|
|
|
if(doredraw) {
|
|
/* als do_ipo altijd wordt aangeroepen: problemen met insertkey, bijvoorbeeld
|
|
* als alleen een 'loc' wordt ge-insert wordt de 'ob->rot' veranderd.
|
|
*/
|
|
|
|
|
|
if(si->blocktype==ID_OB) {
|
|
/* clear delta loc,rot,size (bij ipo vrijgeven/deleten) */
|
|
clear_delta_obipo(si->ipo);
|
|
|
|
}
|
|
|
|
do_ipo(si->ipo);
|
|
|
|
allqueue(REDRAWIPO, 0);
|
|
allqueue (REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWBUTSANIM, 0);
|
|
|
|
if(si->blocktype==ID_OB) {
|
|
Object *ob= (Object *)si->from;
|
|
if(ob && ob->type==OB_IKA) itterate_ika(ob);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
}
|
|
|
|
else if(si->blocktype==ID_MA) allqueue(REDRAWBUTSMAT, 0);
|
|
else if(si->blocktype==ID_WO) allqueue(REDRAWBUTSWORLD, 0);
|
|
else if(si->blocktype==ID_LA) allqueue(REDRAWBUTSLAMP, 0);
|
|
else if(si->blocktype==ID_SO) allqueue(REDRAWBUTSSOUND, 0);
|
|
else if(si->blocktype==ID_CA) {
|
|
allqueue(REDRAWBUTSEDIT, 0);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
else if(si->blocktype==ID_SEQ) clear_last_seq();
|
|
else if(si->blocktype==ID_AC){
|
|
do_all_actions();
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
}
|
|
else if(si->blocktype==ID_KE) {
|
|
do_spec_key((Key *)si->from);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
else if(si->blocktype==ID_CU) {
|
|
calc_curvepath(OBACT);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
}
|
|
|
|
if(si->showkey) make_ipokey();
|
|
}
|
|
|
|
void scale_editipo()
|
|
{
|
|
/* komt uit buttons, scale met G.sipo->tot rect */
|
|
|
|
EditIpo *ei;
|
|
BezTriple *bezt;
|
|
float facx, facy;
|
|
int a, b;
|
|
|
|
facx= (G.sipo->tot.xmax-G.sipo->tot.xmin)/(G.sipo->v2d.tot.xmax-G.sipo->v2d.tot.xmin);
|
|
facy= (G.sipo->tot.ymax-G.sipo->tot.ymin)/(G.sipo->v2d.tot.ymax-G.sipo->v2d.tot.ymin);
|
|
|
|
ei= G.sipo->editipo;
|
|
if(ei==0) return;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
|
|
bezt->vec[0][0]= facx*(bezt->vec[0][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin;
|
|
bezt->vec[1][0]= facx*(bezt->vec[1][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin;
|
|
bezt->vec[2][0]= facx*(bezt->vec[2][0] - G.sipo->v2d.tot.xmin) + G.sipo->tot.xmin;
|
|
|
|
bezt->vec[0][1]= facy*(bezt->vec[0][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin;
|
|
bezt->vec[1][1]= facy*(bezt->vec[1][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin;
|
|
bezt->vec[2][1]= facy*(bezt->vec[2][1] - G.sipo->v2d.tot.ymin) + G.sipo->tot.ymin;
|
|
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
editipo_changed(G.sipo, 1);
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue (REDRAWACTION, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
}
|
|
|
|
|
|
Ipo *get_ipo_to_edit(ID **from)
|
|
{
|
|
Object *ob= OBACT;
|
|
|
|
*from= 0;
|
|
|
|
|
|
if (G.sipo->pin) {
|
|
*from = G.sipo->from;
|
|
return G.sipo->ipo;
|
|
}
|
|
|
|
if(G.sipo->blocktype==ID_SEQ) {
|
|
extern Sequence *last_seq;
|
|
|
|
*from= (ID *)last_seq;
|
|
if(last_seq) return last_seq->ipo;
|
|
}
|
|
else if(G.sipo->blocktype==IPO_CO){
|
|
if (ob && ob->activecon){
|
|
*from= (ID*) ob;
|
|
return ob->activecon->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_AC) {
|
|
bActionChannel *chan;
|
|
if (ob && ob->action){
|
|
*from= (ID *) ob->action;
|
|
chan= get_hilighted_action_channel(ob->action);
|
|
if (chan)
|
|
return chan->ipo;
|
|
else{
|
|
*from = NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(G.sipo->blocktype==ID_WO) {
|
|
World *wo= G.scene->world;
|
|
*from= (ID *)wo;
|
|
if(wo) return wo->ipo;
|
|
}
|
|
else if(G.sipo->blocktype==ID_OB) {
|
|
if(ob) {
|
|
*from= (ID *)ob;
|
|
return ob->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_MA) {
|
|
if(ob) {
|
|
Material *ma= give_current_material(ob, ob->actcol);
|
|
*from= (ID *)ma;
|
|
if(ma) return ma->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_KE) {
|
|
if(ob) {
|
|
Key *key= give_current_key(ob);
|
|
*from= (ID *)key;
|
|
if(key) return key->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_CU) {
|
|
if(ob && ob->type==OB_CURVE) {
|
|
Curve *cu= ob->data;
|
|
*from= (ID *)cu;
|
|
return cu->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_LA) {
|
|
if(ob && ob->type==OB_LAMP) {
|
|
Lamp *la= ob->data;
|
|
*from= (ID *)la;
|
|
return la->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_CA) {
|
|
if(ob && ob->type==OB_CAMERA) {
|
|
Camera *ca= ob->data;
|
|
*from= (ID *)ca;
|
|
if(ca) return ca->ipo;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_SO) {
|
|
|
|
if (G.buts && G.buts->mainb == BUTS_SOUND) {
|
|
|
|
bSound *sound = G.buts->lockpoin;
|
|
|
|
*from= (ID *)sound;
|
|
|
|
if(sound) return sound->ipo;
|
|
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
unsigned int ipo_rainbow(int cur, int tot)
|
|
{
|
|
float dfac, fac, sat;
|
|
|
|
dfac= (float)(1.0/( (float)tot+1.0));
|
|
|
|
/* deze berekening zorgt voor twee verschillende cycles regenboogkleuren */
|
|
if(cur< tot/2) fac= (float)(cur*2.0*dfac);
|
|
else fac= (float)((cur-tot/2)*2.0*dfac +dfac);
|
|
|
|
if(fac>0.5 && fac<0.8) sat= (float)0.4;
|
|
else sat= 0.5;
|
|
|
|
return hsv_to_cpack(fac, sat, 1.0);
|
|
}
|
|
|
|
void make_ob_editipo(Object *ob, SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a, len, colipo=0;
|
|
|
|
if(ob->type==OB_MESH) colipo= 1;
|
|
|
|
ei= si->editipo= MEM_callocN(OB_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= OB_TOTIPO;
|
|
|
|
for(a=0; a<OB_TOTIPO; a++) {
|
|
getname_ob_ei(ob_ar[a], ei->name, colipo);
|
|
ei->adrcode= ob_ar[a];
|
|
|
|
if ELEM6(ei->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z, OB_DROT_X, OB_DROT_Y, OB_DROT_Z) ei->disptype= IPO_DISPDEGR;
|
|
else if(ei->adrcode==OB_LAY) ei->disptype= IPO_DISPBITS;
|
|
else if(ei->adrcode==OB_TIME) ei->disptype= IPO_DISPTIME;
|
|
|
|
ei->col= ipo_rainbow(a, OB_TOTIPO);
|
|
|
|
if(colipo) {
|
|
len= strlen(ei->name);
|
|
if(len) {
|
|
if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF;
|
|
else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50;
|
|
else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050;
|
|
}
|
|
}
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
|
|
void make_seq_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= si->editipo= MEM_callocN(SEQ_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= SEQ_TOTIPO;
|
|
|
|
|
|
for(a=0; a<SEQ_TOTIPO; a++) {
|
|
getname_seq_ei(seq_ar[a], ei->name);
|
|
ei->adrcode= seq_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, SEQ_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
else ei->flag |= IPO_VISIBLE;
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
void make_cu_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= si->editipo= MEM_callocN(CU_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= CU_TOTIPO;
|
|
|
|
|
|
for(a=0; a<CU_TOTIPO; a++) {
|
|
getname_cu_ei(cu_ar[a], ei->name);
|
|
ei->adrcode= cu_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, CU_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
else ei->flag |= IPO_VISIBLE;
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
void make_key_editipo(SpaceIpo *si)
|
|
{
|
|
Key *key;
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= si->editipo= MEM_callocN(KEY_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= KEY_TOTIPO;
|
|
|
|
for(a=0; a<KEY_TOTIPO; a++) {
|
|
getname_key_ei(key_ar[a], ei->name);
|
|
ei->adrcode= key_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, KEY_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
else if(a==0) ei->flag |= IPO_VISIBLE;
|
|
|
|
ei++;
|
|
}
|
|
|
|
ei= si->editipo;
|
|
key= (Key *)G.sipo->from;
|
|
if(key && key->type==KEY_RELATIVE) {
|
|
strcpy(ei->name, "----");
|
|
}
|
|
else {
|
|
ei->flag |= IPO_VISIBLE;
|
|
}
|
|
}
|
|
|
|
int texchannel_to_adrcode(int channel)
|
|
{
|
|
switch(channel) {
|
|
case 0: return MA_MAP1;
|
|
case 1: return MA_MAP2;
|
|
case 2: return MA_MAP3;
|
|
case 3: return MA_MAP4;
|
|
case 4: return MA_MAP5;
|
|
case 5: return MA_MAP6;
|
|
case 6: return MA_MAP7;
|
|
case 7: return MA_MAP8;
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
void make_mat_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a, len;
|
|
|
|
if(si->from==0) return;
|
|
|
|
ei= si->editipo= MEM_callocN(MA_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= MA_TOTIPO;
|
|
|
|
for(a=0; a<MA_TOTIPO; a++) {
|
|
getname_mat_ei(ma_ar[a], ei->name);
|
|
ei->adrcode= ma_ar[a];
|
|
|
|
if(ei->adrcode & MA_MAP1) {
|
|
ei->adrcode-= MA_MAP1;
|
|
ei->adrcode |= texchannel_to_adrcode(si->channel);
|
|
}
|
|
else {
|
|
/* dit was weggecommentaard. Waarom? */
|
|
if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS;
|
|
}
|
|
|
|
ei->col= ipo_rainbow(a, WO_TOTIPO);
|
|
|
|
len= strlen(ei->name);
|
|
if(len) {
|
|
if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF;
|
|
else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50;
|
|
else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050;
|
|
}
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
void make_world_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a, len;
|
|
|
|
if(si->from==0) return;
|
|
|
|
ei= si->editipo= MEM_callocN(WO_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= WO_TOTIPO;
|
|
|
|
for(a=0; a<WO_TOTIPO; a++) {
|
|
getname_world_ei(wo_ar[a], ei->name);
|
|
ei->adrcode= wo_ar[a];
|
|
|
|
if(ei->adrcode & MA_MAP1) {
|
|
ei->adrcode-= MA_MAP1;
|
|
ei->adrcode |= texchannel_to_adrcode(si->channel);
|
|
}
|
|
else {
|
|
if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS;
|
|
}
|
|
|
|
ei->col= ipo_rainbow(a, MA_TOTIPO);
|
|
|
|
len= strlen(ei->name);
|
|
if(len) {
|
|
if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF;
|
|
else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50;
|
|
else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050;
|
|
}
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
void make_lamp_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= si->editipo= MEM_callocN(LA_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= LA_TOTIPO;
|
|
|
|
|
|
for(a=0; a<LA_TOTIPO; a++) {
|
|
getname_la_ei(la_ar[a], ei->name);
|
|
ei->adrcode= la_ar[a];
|
|
|
|
if(ei->adrcode & MA_MAP1) {
|
|
ei->adrcode-= MA_MAP1;
|
|
ei->adrcode |= texchannel_to_adrcode(si->channel);
|
|
}
|
|
|
|
ei->col= ipo_rainbow(a, LA_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
void make_camera_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= si->editipo= MEM_callocN(CAM_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= CAM_TOTIPO;
|
|
|
|
|
|
for(a=0; a<CAM_TOTIPO; a++) {
|
|
getname_cam_ei(cam_ar[a], ei->name);
|
|
ei->adrcode= cam_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, CAM_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
int make_constraint_editipo(Ipo *ipo, EditIpo **si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= *si= MEM_callocN(CO_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
for(a=0; a<CO_TOTIPO; a++) {
|
|
getname_co_ei(co_ar[a], ei->name);
|
|
ei->adrcode= co_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, CO_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
|
|
return CO_TOTIPO;
|
|
}
|
|
int make_action_editipo(Ipo *ipo, EditIpo **si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= *si= MEM_callocN(AC_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
for(a=0; a<AC_TOTIPO; a++) {
|
|
getname_ac_ei(ac_ar[a], ei->name);
|
|
ei->adrcode= ac_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, AC_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
|
|
return AC_TOTIPO;
|
|
}
|
|
|
|
void make_sound_editipo(SpaceIpo *si)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
ei= si->editipo= MEM_callocN(SND_TOTIPO*sizeof(EditIpo), "editipo");
|
|
|
|
si->totipo= SND_TOTIPO;
|
|
|
|
|
|
for(a=0; a<SND_TOTIPO; a++) {
|
|
getname_snd_ei(snd_ar[a], ei->name);
|
|
ei->adrcode= snd_ar[a];
|
|
|
|
ei->col= ipo_rainbow(a, SND_TOTIPO);
|
|
|
|
ei->icu= find_ipocurve(si->ipo, ei->adrcode);
|
|
if(ei->icu) {
|
|
ei->flag= ei->icu->flag;
|
|
}
|
|
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
void make_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
Object *ob;
|
|
ID *from;
|
|
rctf *rf;
|
|
int a;
|
|
|
|
if(G.sipo->editipo)
|
|
MEM_freeN(G.sipo->editipo);
|
|
G.sipo->editipo= 0;
|
|
G.sipo->totipo= 0;
|
|
ob= OBACT;
|
|
|
|
G.sipo->ipo= get_ipo_to_edit(&from);
|
|
G.sipo->from= from;
|
|
|
|
if(G.sipo->ipo) G.sipo->showkey= G.sipo->ipo->showkey;
|
|
|
|
if(G.sipo->blocktype==ID_SEQ) {
|
|
make_seq_editipo(G.sipo);
|
|
}
|
|
else if(G.sipo->blocktype==ID_WO) {
|
|
make_world_editipo(G.sipo);
|
|
}
|
|
else if(G.sipo->blocktype==ID_OB) {
|
|
if (ob) {
|
|
ob->ipowin= ID_OB;
|
|
make_ob_editipo(ob, G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_MA) {
|
|
if (ob) {
|
|
ob->ipowin= ID_MA;
|
|
make_mat_editipo(G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_CU) {
|
|
if (ob) {
|
|
ob->ipowin= ID_CU;
|
|
make_cu_editipo(G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_KE) {
|
|
if (ob) {
|
|
ob->ipowin= ID_KE;
|
|
make_key_editipo(G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_LA) {
|
|
if (ob) {
|
|
ob->ipowin= ID_LA;
|
|
make_lamp_editipo(G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_CA) {
|
|
if (ob) {
|
|
ob->ipowin= ID_CA;
|
|
make_camera_editipo(G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_SO) {
|
|
if (ob) {
|
|
ob->ipowin= ID_SO;
|
|
make_sound_editipo(G.sipo);
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==IPO_CO){
|
|
G.sipo->totipo = make_constraint_editipo(G.sipo->ipo, (EditIpo**)&G.sipo->editipo);
|
|
if (ob) {
|
|
ob->ipowin= IPO_CO;
|
|
}
|
|
}
|
|
else if(G.sipo->blocktype==ID_AC) {
|
|
|
|
G.sipo->totipo = make_action_editipo(G.sipo->ipo, (EditIpo**)&G.sipo->editipo);
|
|
if (ob) {
|
|
ob->ipowin= ID_AC;
|
|
}
|
|
}
|
|
|
|
if(G.sipo->editipo==0) return;
|
|
|
|
/* rowbut voor VISIBLE select */
|
|
G.sipo->rowbut= 0;
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
|
|
if(ei->flag & IPO_VISIBLE) G.sipo->rowbut |= (1<<a);
|
|
|
|
if(ei->icu) ei->icu->flag= ei->flag;
|
|
}
|
|
editipo_changed(G.sipo, 0);
|
|
|
|
if(G.sipo->ipo) {
|
|
|
|
if (G.sipo->pin)
|
|
rf= &(G.sipo->v2d.cur);
|
|
else
|
|
rf= &(G.sipo->ipo->cur);
|
|
|
|
if(rf->xmin<rf->xmax && rf->ymin<rf->ymax) G.v2d->cur= *rf;
|
|
|
|
}
|
|
else {
|
|
if(G.sipo->blocktype==ID_OB) {
|
|
G.v2d->cur.xmin= 0.0;
|
|
G.v2d->cur.xmax= EFRA;
|
|
G.v2d->cur.ymin= -5.0;
|
|
G.v2d->cur.ymax= +5.0;
|
|
}
|
|
else if(G.sipo->blocktype==ID_CA) {
|
|
G.v2d->cur.xmin= 0.0;
|
|
G.v2d->cur.xmax= EFRA;
|
|
G.v2d->cur.ymin= 0.0;
|
|
G.v2d->cur.ymax= 100.0;
|
|
}
|
|
else if ELEM5(G.sipo->blocktype, ID_MA, ID_CU, ID_WO, ID_LA, IPO_CO) {
|
|
G.v2d->cur.xmin= (float)-0.1;
|
|
G.v2d->cur.xmax= EFRA;
|
|
G.v2d->cur.ymin= (float)-0.1;
|
|
G.v2d->cur.ymax= (float)+1.1;
|
|
}
|
|
else if(G.sipo->blocktype==ID_SEQ) {
|
|
G.v2d->cur.xmin= -5.0;
|
|
G.v2d->cur.xmax= 105.0;
|
|
G.v2d->cur.ymin= (float)-0.1;
|
|
G.v2d->cur.ymax= (float)+1.1;
|
|
}
|
|
else if(G.sipo->blocktype==ID_KE) {
|
|
G.v2d->cur.xmin= (float)-0.1;
|
|
G.v2d->cur.xmax= EFRA;
|
|
G.v2d->cur.ymin= (float)-0.1;
|
|
G.v2d->cur.ymax= (float)+2.1;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void test_editipo()
|
|
{
|
|
Ipo *ipo;
|
|
ID *from;
|
|
|
|
if(G.sipo->editipo==0){
|
|
make_editipo();
|
|
}
|
|
else {
|
|
ipo= get_ipo_to_edit(&from);
|
|
|
|
if(G.sipo->ipo != ipo || G.sipo->from!=from)
|
|
make_editipo();
|
|
|
|
}
|
|
|
|
if (G.sipo->pin)
|
|
return;
|
|
|
|
|
|
if(G.sipo->ipo)
|
|
G.sipo->ipo->cur = G.v2d->cur;
|
|
|
|
}
|
|
|
|
/* ****************************************** */
|
|
|
|
int totipo_edit, totipo_sel, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel;
|
|
|
|
void get_status_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
BezTriple *bezt;
|
|
int a, b;
|
|
|
|
totipo_vis= 0;
|
|
totipo_sel= 0;
|
|
totipo_edit= 0;
|
|
totipo_vert= 0;
|
|
totipo_vertsel= 0;
|
|
totipo_key= 0;
|
|
totipo_keysel= 0;
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
if(ei==0) return;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if( ei->flag & IPO_VISIBLE ) {
|
|
totipo_vis++;
|
|
if(ei->flag & IPO_SELECT) totipo_sel++;
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
|
|
|
|
/* als showkey: wel de vertices tellen (voor grab) */
|
|
if(G.sipo->showkey==0) totipo_edit++;
|
|
|
|
if(ei->icu) {
|
|
if(ei->icu->bezt) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(ei->icu->ipo==IPO_BEZ) {
|
|
if(bezt->f1 & 1) totipo_vertsel++;
|
|
if(bezt->f3 & 1) totipo_vertsel++;
|
|
totipo_vert+= 2;
|
|
}
|
|
if(bezt->f2 & 1) totipo_vertsel++;
|
|
|
|
totipo_vert++;
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ei++;
|
|
}
|
|
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
totipo_key++;
|
|
if(ik->flag & 1) totipo_keysel++;
|
|
ik= ik->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void update_editipo_flags()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
unsigned int flag;
|
|
int a;
|
|
|
|
ei= G.sipo->editipo;
|
|
if(ei) {
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
ei->flag &= ~IPO_VISIBLE;
|
|
flag= (1<<a);
|
|
if( G.sipo->rowbut & flag ) ei->flag |= IPO_VISIBLE;
|
|
|
|
if(ei->icu) ei->icu->flag= ei->flag;
|
|
|
|
}
|
|
}
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) {
|
|
if(ik->flag & 1) {
|
|
ik->data[a]->f1 |= 1;
|
|
ik->data[a]->f2 |= 1;
|
|
ik->data[a]->f3 |= 1;
|
|
}
|
|
else {
|
|
ik->data[a]->f1 &= ~1;
|
|
ik->data[a]->f2 &= ~1;
|
|
ik->data[a]->f3 &= ~1;
|
|
}
|
|
}
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
void set_editflag_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
int a; /* , tot= 0, ok= 0; */
|
|
|
|
/* van showkey direkt door naar editen geselecteerde punten */
|
|
if(G.sipo->showkey) {
|
|
G.sipo->showkey= 0;
|
|
if(G.sipo->ipo) G.sipo->ipo->showkey= 0;
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) ei->flag |= IPO_SELECT;
|
|
scrarea_queue_headredraw(curarea);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
|
|
get_status_editipo();
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if(ei->icu) {
|
|
if(ei->flag & IPO_VISIBLE) {
|
|
|
|
if(totipo_edit==0 && (ei->flag & IPO_SELECT)) {
|
|
ei->flag |= IPO_EDIT;
|
|
ei->icu->flag= ei->flag;
|
|
}
|
|
else if(totipo_edit && (ei->flag & IPO_EDIT)) {
|
|
ei->flag -= IPO_EDIT;
|
|
ei->icu->flag= ei->flag;
|
|
}
|
|
else if(totipo_vis==1) {
|
|
if(ei->flag & IPO_EDIT) ei->flag -= IPO_EDIT;
|
|
else ei->flag |= IPO_EDIT;
|
|
ei->icu->flag= ei->flag;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
}
|
|
|
|
void swap_selectall_editipo()
|
|
{
|
|
Object *ob;
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
BezTriple *bezt;
|
|
int a, b; /* , sel=0; */
|
|
|
|
|
|
deselectall_key();
|
|
|
|
get_status_editipo();
|
|
|
|
|
|
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
if(totipo_vertsel) ik->flag &= ~1;
|
|
else ik->flag |= 1;
|
|
ik= ik->next;
|
|
}
|
|
update_editipo_flags();
|
|
|
|
if(G.sipo->showkey && G.sipo->blocktype==ID_OB ) {
|
|
ob= OBACT;
|
|
if(ob && (ob->ipoflag & OB_DRAWKEY)) draw_object_ext(BASACT);
|
|
}
|
|
}
|
|
else if(totipo_edit==0) {
|
|
ei= G.sipo->editipo;
|
|
if (ei){
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if( ei->flag & IPO_VISIBLE ) {
|
|
if(totipo_sel) ei->flag &= ~IPO_SELECT;
|
|
else ei->flag |= IPO_SELECT;
|
|
}
|
|
ei++;
|
|
}
|
|
update_editipo_flags();
|
|
}
|
|
}
|
|
else {
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu ) {
|
|
bezt= ei->icu->bezt;
|
|
if(bezt) {
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(totipo_vertsel) {
|
|
bezt->f1= bezt->f2= bezt->f3= 0;
|
|
}
|
|
else {
|
|
bezt->f1= bezt->f2= bezt->f3= 1;
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
ei++;
|
|
}
|
|
|
|
}
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
void swap_visible_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
Object *ob;
|
|
int a; /* , sel=0; */
|
|
|
|
get_status_editipo();
|
|
|
|
G.sipo->rowbut= 0;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(totipo_vis==0) {
|
|
if(ei->icu) {
|
|
ei->flag |= IPO_VISIBLE;
|
|
G.sipo->rowbut |= (1<<a);
|
|
}
|
|
}
|
|
else ei->flag &= ~IPO_VISIBLE;
|
|
ei++;
|
|
}
|
|
|
|
update_editipo_flags();
|
|
|
|
if(G.sipo->showkey) {
|
|
|
|
make_ipokey();
|
|
|
|
ob= OBACT;
|
|
if(ob && (ob->ipoflag & OB_DRAWKEY)) allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
}
|
|
|
|
void deselectall_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
BezTriple *bezt;
|
|
int a, b; /* , sel=0; */
|
|
|
|
deselectall_key();
|
|
|
|
get_status_editipo();
|
|
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
ik->flag &= ~1;
|
|
ik= ik->next;
|
|
}
|
|
update_editipo_flags();
|
|
|
|
}
|
|
else if(totipo_edit==0) {
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if( ei->flag & IPO_VISIBLE ) {
|
|
ei->flag &= ~IPO_SELECT;
|
|
}
|
|
ei++;
|
|
}
|
|
update_editipo_flags();
|
|
}
|
|
else {
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu ) {
|
|
if(ei->icu->bezt) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
bezt->f1= bezt->f2= bezt->f3= 0;
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
ei++;
|
|
}
|
|
}
|
|
|
|
scrarea_queue_winredraw(curarea);
|
|
}
|
|
|
|
short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt)
|
|
{
|
|
/* selected krijgen een nadeel */
|
|
/* in icu en (bezt of bp) wordt nearest weggeschreven */
|
|
/* return 0 1 2: handlepunt */
|
|
EditIpo *ei;
|
|
BezTriple *bezt1;
|
|
int a, b;
|
|
short dist= 100, temp, mval[2], hpoint=0;
|
|
|
|
*icu= 0;
|
|
*bezt= 0;
|
|
|
|
getmouseco_areawin(mval);
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu) {
|
|
|
|
if(ei->icu->bezt) {
|
|
bezt1= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
|
|
ipoco_to_areaco_noclip(G.v2d, bezt1->vec[0], bezt1->s[0]);
|
|
ipoco_to_areaco_noclip(G.v2d, bezt1->vec[1], bezt1->s[1]);
|
|
ipoco_to_areaco_noclip(G.v2d, bezt1->vec[2], bezt1->s[2]);
|
|
|
|
if(ei->disptype==IPO_DISPBITS) {
|
|
temp= abs(mval[0]- bezt1->s[1][0]);
|
|
}
|
|
else temp= abs(mval[0]- bezt1->s[1][0])+ abs(mval[1]- bezt1->s[1][1]);
|
|
|
|
if( bezt1->f2 & 1) temp+=5;
|
|
if(temp<dist) {
|
|
hpoint= 1;
|
|
*bezt= bezt1;
|
|
dist= temp;
|
|
*icu= ei->icu;
|
|
}
|
|
|
|
if(ei->disptype!=IPO_DISPBITS && ei->icu->ipo==IPO_BEZ) {
|
|
/* middelste punten een klein voordeel */
|
|
temp= -3+abs(mval[0]- bezt1->s[0][0])+ abs(mval[1]- bezt1->s[0][1]);
|
|
if( bezt1->f1 & 1) temp+=5;
|
|
if(temp<dist) {
|
|
hpoint= 0;
|
|
*bezt= bezt1;
|
|
dist= temp;
|
|
*icu= ei->icu;
|
|
}
|
|
|
|
temp= abs(mval[0]- bezt1->s[2][0])+ abs(mval[1]- bezt1->s[2][1]);
|
|
if( bezt1->f3 & 1) temp+=5;
|
|
if(temp<dist) {
|
|
hpoint= 2;
|
|
*bezt=bezt1;
|
|
dist= temp;
|
|
*icu= ei->icu;
|
|
}
|
|
}
|
|
bezt1++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hpoint;
|
|
}
|
|
|
|
|
|
void move_to_frame()
|
|
{
|
|
EditIpo *ei;
|
|
BezTriple *bezt;
|
|
ID *id;
|
|
float cfra;
|
|
int a, b;
|
|
|
|
if(G.sipo->editipo==0) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
|
|
|
|
if(ei->icu->bezt) {
|
|
|
|
b= ei->icu->totvert;
|
|
bezt= ei->icu->bezt;
|
|
while(b--) {
|
|
if(BEZSELECTED(bezt)) {
|
|
|
|
cfra= bezt->vec[1][0]/G.scene->r.framelen;
|
|
|
|
id= G.sipo->from;
|
|
if(id && GS(id->name)==ID_OB ) {
|
|
Object *ob= (Object *)id;
|
|
if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
|
|
cfra+= ob->sf/G.scene->r.framelen;
|
|
}
|
|
}
|
|
CFRA= (short)floor(cfra+0.5);
|
|
|
|
if(CFRA < 1) CFRA= 1;
|
|
update_for_newframe();
|
|
|
|
break;
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* *********************************** */
|
|
|
|
void do_ipowin_buts(short event)
|
|
{
|
|
if((G.qual & LR_SHIFTKEY)==0) {
|
|
G.sipo->rowbut= (1<<event);
|
|
}
|
|
scrarea_queue_winredraw(curarea);
|
|
|
|
update_editipo_flags();
|
|
|
|
if(G.sipo->showkey) {
|
|
make_ipokey();
|
|
if(G.sipo->blocktype==ID_OB) allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
|
|
}
|
|
|
|
void do_ipo_selectbuttons()
|
|
{
|
|
EditIpo *ei, *ei1;
|
|
int a, nr;
|
|
short mval[2];
|
|
|
|
if(G.sipo->showkey) return;
|
|
|
|
/* geen editipo toestaan: editipo's naar selected omzetten */
|
|
get_status_editipo();
|
|
if(totipo_edit) {
|
|
set_editflag_editipo();
|
|
}
|
|
|
|
/* welke */
|
|
getmouseco_areawin(mval);
|
|
|
|
nr= -(mval[1]-curarea->winy+30-G.sipo->butofs-IPOBUTY)/IPOBUTY;
|
|
if(nr>=0 && nr<G.sipo->totipo) {
|
|
ei= G.sipo->editipo;
|
|
ei+= nr;
|
|
|
|
if(ei->icu) {
|
|
if((ei->flag & IPO_VISIBLE)==0) {
|
|
ei->flag |= IPO_VISIBLE;
|
|
G.sipo->rowbut |= (1<<nr);
|
|
}
|
|
|
|
if((G.qual & LR_SHIFTKEY)==0) {
|
|
ei1= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
ei1->flag &= ~IPO_SELECT;
|
|
ei1++;
|
|
}
|
|
}
|
|
|
|
if(ei->flag & IPO_SELECT) {
|
|
ei->flag &= ~IPO_SELECT;
|
|
}
|
|
else {
|
|
ei->flag |= IPO_SELECT;
|
|
}
|
|
|
|
update_editipo_flags();
|
|
scrarea_queue_winredraw(curarea);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ******************************************* */
|
|
|
|
EditIpo *get_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
int a; /* , sel=0; */
|
|
|
|
get_status_editipo();
|
|
|
|
if(totipo_edit>1) {
|
|
error("Too many editipo's");
|
|
return 0;
|
|
}
|
|
if(G.sipo->editipo==0) return 0;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ei->flag & IPO_VISIBLE) {
|
|
if( ei->flag & IPO_EDIT ) return ei;
|
|
else if(totipo_vis==1) return ei;
|
|
|
|
if(ei->flag & IPO_SELECT) {
|
|
if(totipo_sel==1) return ei;
|
|
}
|
|
}
|
|
ei++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static Ipo *get_ipo(ID *from, short type, int make)
|
|
{
|
|
Object *ob;
|
|
Material *ma;
|
|
Curve *cu;
|
|
Sequence *seq;
|
|
Key *key;
|
|
World *wo;
|
|
Lamp *la;
|
|
Camera *ca;
|
|
Ipo *ipo= 0;
|
|
bAction *act;
|
|
|
|
if( type==ID_OB) {
|
|
ob= (Object *)from;
|
|
if(ob->id.lib) return 0;
|
|
|
|
ipo= ob->ipo;
|
|
if(make && ipo==0) ipo= ob->ipo= add_ipo("ObIpo", ID_OB);
|
|
}
|
|
else if( type==IPO_CO){
|
|
ob= (Object *)from;
|
|
if(ob->id.lib) return 0;
|
|
|
|
if (ob->activecon){
|
|
ipo= ob->activecon->ipo;
|
|
if(make && ipo==0) ipo= ob->activecon->ipo= add_ipo("CoIpo", IPO_CO);
|
|
}
|
|
}
|
|
else if( type==ID_AC) {
|
|
act= (bAction *)from;
|
|
if (!act->achan) return 0;
|
|
if (act->id.lib) return 0;
|
|
ipo= act->achan->ipo;
|
|
|
|
/* This should never happen */
|
|
if(make && ipo==0) ipo= act->achan->ipo= add_ipo("AcIpo", ID_AC);
|
|
}
|
|
else if( type==ID_MA) {
|
|
ma= (Material *)from;
|
|
if(ma->id.lib) return 0;
|
|
ipo= ma->ipo;
|
|
|
|
if(make && ipo==0) ipo= ma->ipo= add_ipo("MatIpo", ID_MA);
|
|
}
|
|
|
|
else if( type==ID_SEQ) {
|
|
seq= (Sequence *)from;
|
|
|
|
if(seq->type & SEQ_EFFECT) {
|
|
ipo= seq->ipo;
|
|
if(make && ipo==0) ipo= seq->ipo= add_ipo("SeqIpo", ID_SEQ);
|
|
}
|
|
else return 0;
|
|
}
|
|
else if( type==ID_CU) {
|
|
cu= (Curve *)from;
|
|
if(cu->id.lib) return 0;
|
|
ipo= cu->ipo;
|
|
|
|
if(make && ipo==0) ipo= cu->ipo= add_ipo("CuIpo", ID_CU);
|
|
}
|
|
else if( type==ID_KE) {
|
|
key= (Key *)from;
|
|
if(key->id.lib) return 0;
|
|
ipo= key->ipo;
|
|
|
|
if(make && ipo==0) ipo= key->ipo= add_ipo("KeyIpo", ID_KE);
|
|
}
|
|
else if( type==ID_WO) {
|
|
wo= (World *)from;
|
|
if(wo->id.lib) return 0;
|
|
ipo= wo->ipo;
|
|
|
|
if(make && ipo==0) ipo= wo->ipo= add_ipo("WoIpo", ID_WO);
|
|
}
|
|
else if( type==ID_LA) {
|
|
la= (Lamp *)from;
|
|
if(la->id.lib) return 0;
|
|
ipo= la->ipo;
|
|
|
|
if(make && ipo==0) ipo= la->ipo= add_ipo("LaIpo", ID_LA);
|
|
}
|
|
else if( type==ID_CA) {
|
|
ca= (Camera *)from;
|
|
if(ca->id.lib) return 0;
|
|
ipo= ca->ipo;
|
|
|
|
if(make && ipo==0) ipo= ca->ipo= add_ipo("CaIpo", ID_CA);
|
|
}
|
|
else if( type==ID_SO) {
|
|
bSound *snd= (bSound *)from;
|
|
if(snd->id.lib) return 0;
|
|
ipo= snd->ipo;
|
|
|
|
if(make && ipo==0) ipo= snd->ipo= add_ipo("SndIpo", ID_SO);
|
|
}
|
|
else return 0;
|
|
|
|
return ipo;
|
|
}
|
|
|
|
|
|
// this function should not have the G.sipo in it...
|
|
|
|
IpoCurve *get_ipocurve(ID *from, short type, int adrcode, Ipo *useipo)
|
|
{
|
|
Ipo *ipo= 0;
|
|
IpoCurve *icu=0;
|
|
|
|
/* return 0 als lib */
|
|
/* ook testen of ipo en ipocurve bestaan */
|
|
|
|
if (useipo==NULL) {
|
|
|
|
if (G.sipo==NULL || G.sipo->pin==0){
|
|
ipo= get_ipo(from, type, 1); /* 1= make */
|
|
}
|
|
else
|
|
ipo = G.sipo->ipo;
|
|
|
|
|
|
if(G.sipo) {
|
|
if (G.sipo->pin==0) G.sipo->ipo= ipo;
|
|
}
|
|
}
|
|
else
|
|
ipo= useipo;
|
|
|
|
|
|
if(ipo && ipo->id.lib==0) {
|
|
|
|
icu= ipo->curve.first;
|
|
while(icu) {
|
|
if(icu->adrcode==adrcode) break;
|
|
icu= icu->next;
|
|
}
|
|
if(icu==0) {
|
|
icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
|
|
|
|
icu->flag |= IPO_VISIBLE;
|
|
|
|
if (!useipo && G.sipo && G.sipo->pin)
|
|
icu->blocktype = G.sipo->blocktype;
|
|
else
|
|
icu->blocktype= type;
|
|
icu->adrcode= adrcode;
|
|
|
|
set_icu_vars(icu);
|
|
|
|
BLI_addtail( &(ipo->curve), icu);
|
|
}
|
|
}
|
|
return icu;
|
|
}
|
|
|
|
void insert_vert_ipo(IpoCurve *icu, float x, float y)
|
|
{
|
|
BezTriple *bezt, beztr, *newbezt;
|
|
int a = 0, h1, h2;
|
|
|
|
memset(&beztr, 0, sizeof(BezTriple));
|
|
beztr.vec[1][0]= x;
|
|
beztr.vec[1][1]= y;
|
|
beztr.hide= IPO_BEZ;
|
|
beztr.f1= beztr.f2= beztr.f3= SELECT;
|
|
beztr.h1= beztr.h2= HD_AUTO;
|
|
|
|
bezt= icu->bezt;
|
|
|
|
if(bezt==0) {
|
|
icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple");
|
|
*(icu->bezt)= beztr;
|
|
icu->totvert= 1;
|
|
}
|
|
else {
|
|
/* alle vertices deselect */
|
|
for(a=0; a<icu->totvert; a++, bezt++) {
|
|
bezt->f1= bezt->f2= bezt->f3= 0;
|
|
}
|
|
|
|
bezt= icu->bezt;
|
|
for(a=0; a<=icu->totvert; a++, bezt++) {
|
|
|
|
/* geen dubbele punten */
|
|
if(a<icu->totvert && (bezt->vec[1][0]>x-IPOTHRESH && bezt->vec[1][0]<x+IPOTHRESH)) {
|
|
*(bezt)= beztr;
|
|
break;
|
|
}
|
|
if(a==icu->totvert || bezt->vec[1][0] > x) {
|
|
newbezt= MEM_callocN( (icu->totvert+1)*sizeof(BezTriple), "beztriple");
|
|
|
|
if(a>0) memcpy(newbezt, icu->bezt, a*sizeof(BezTriple));
|
|
|
|
bezt= newbezt+a;
|
|
*(bezt)= beztr;
|
|
|
|
if(a<icu->totvert) memcpy(newbezt+a+1, icu->bezt+a, (icu->totvert-a)*sizeof(BezTriple));
|
|
|
|
MEM_freeN(icu->bezt);
|
|
icu->bezt= newbezt;
|
|
|
|
icu->totvert++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
calchandles_ipocurve(icu);
|
|
|
|
/* handletype goedzetten */
|
|
if(icu->totvert>2) {
|
|
h1= h2= HD_AUTO;
|
|
if(a>0) h1= (bezt-1)->h2;
|
|
if(a<icu->totvert-1) h2= (bezt+1)->h1;
|
|
bezt->h1= h1;
|
|
bezt->h2= h2;
|
|
|
|
calchandles_ipocurve(icu);
|
|
}
|
|
}
|
|
|
|
void add_vert_ipo()
|
|
{
|
|
EditIpo *ei;
|
|
float x, y;
|
|
int val;
|
|
short mval[2];
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
if(G.sipo->showkey) {
|
|
G.sipo->showkey= 0;
|
|
free_ipokey(&G.sipo->ipokey);
|
|
}
|
|
|
|
getmouseco_areawin(mval);
|
|
|
|
if(mval[0]>G.v2d->mask.xmax) return;
|
|
|
|
ei= get_editipo();
|
|
if(ei==0) return;
|
|
|
|
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
|
|
|
|
if(ei->icu==0) {
|
|
if(G.sipo->from)
|
|
ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0);
|
|
}
|
|
if(ei->icu==0) return;
|
|
|
|
if(ei->disptype==IPO_DISPBITS) {
|
|
ei->icu->vartype= IPO_BITS;
|
|
val= (int)floor(y-0.5);
|
|
if(val<0) val= 0;
|
|
y= (float)(1 << val);
|
|
}
|
|
|
|
insert_vert_ipo(ei->icu, x, y);
|
|
|
|
/* voor zekerheid: als icu 0 was, of maar 1 curve visible */
|
|
ei->flag |= IPO_SELECT;
|
|
ei->icu->flag= ei->flag;
|
|
|
|
editipo_changed(G.sipo, 1);
|
|
}
|
|
|
|
void add_duplicate_editipo()
|
|
{
|
|
Object *ob;
|
|
EditIpo *ei;
|
|
IpoCurve *icu;
|
|
BezTriple *bezt, *beztn, *newb;
|
|
int tot, a, b;
|
|
|
|
get_status_editipo();
|
|
if(totipo_vertsel==0) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) {
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
|
|
icu= ei->icu;
|
|
|
|
/* hoeveel punten */
|
|
tot= 0;
|
|
b= icu->totvert;
|
|
bezt= icu->bezt;
|
|
while(b--) {
|
|
if(bezt->f2 & 1) tot++;
|
|
bezt++;
|
|
}
|
|
|
|
if(tot) {
|
|
icu->totvert+= tot;
|
|
newb= beztn= MEM_mallocN(icu->totvert*sizeof(BezTriple), "bezt");
|
|
bezt= icu->bezt;
|
|
b= icu->totvert-tot;
|
|
while(b--) {
|
|
*beztn= *bezt;
|
|
if(bezt->f2 & 1) {
|
|
beztn->f1= beztn->f2= beztn->f3= 0;
|
|
beztn++;
|
|
*beztn= *bezt;
|
|
}
|
|
beztn++;
|
|
bezt++;
|
|
}
|
|
MEM_freeN(icu->bezt);
|
|
icu->bezt= newb;
|
|
|
|
calchandles_ipocurve(icu);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(G.sipo->showkey) {
|
|
make_ipokey();
|
|
if(G.sipo->blocktype==ID_OB) {
|
|
ob= OBACT;
|
|
if(ob && (ob->ipoflag & OB_DRAWKEY)) allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
}
|
|
transform_ipo('g');
|
|
}
|
|
|
|
void remove_doubles_ipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik, *ikn;
|
|
BezTriple *bezt, *newb, *new1;
|
|
float val;
|
|
int mode, a, b;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) {
|
|
|
|
/* OF de curve is selected OF in editmode OF in keymode */
|
|
mode= 0;
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) mode= 1;
|
|
else if(ei->flag & IPO_SELECT) mode= 2;
|
|
|
|
if(mode) {
|
|
bezt= ei->icu->bezt;
|
|
newb= new1= MEM_mallocN(ei->icu->totvert*sizeof(BezTriple), "newbezt");
|
|
*newb= *bezt;
|
|
b= ei->icu->totvert-1;
|
|
bezt++;
|
|
while(b--) {
|
|
|
|
/* mag er verwijderd worden? */
|
|
if(mode==2 || (bezt->f2 & 1)) {
|
|
|
|
/* verschillen de punten? */
|
|
if( fabs( bezt->vec[1][0]-newb->vec[1][0] ) > 0.9 ) {
|
|
newb++;
|
|
*newb= *bezt;
|
|
}
|
|
else {
|
|
/* gemiddelde */
|
|
VecMidf(newb->vec[0], newb->vec[0], bezt->vec[0]);
|
|
VecMidf(newb->vec[1], newb->vec[1], bezt->vec[1]);
|
|
VecMidf(newb->vec[2], newb->vec[2], bezt->vec[2]);
|
|
|
|
newb->h1= newb->h2= HD_FREE;
|
|
|
|
ei->icu->totvert--;
|
|
}
|
|
|
|
}
|
|
else {
|
|
newb++;
|
|
*newb= *bezt;
|
|
}
|
|
bezt++;
|
|
}
|
|
|
|
MEM_freeN(ei->icu->bezt);
|
|
ei->icu->bezt= new1;
|
|
|
|
calchandles_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
}
|
|
|
|
editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */
|
|
|
|
/* dubbele keys weg */
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
ikn= ik->next;
|
|
|
|
while(ik && ikn) {
|
|
if( (ik->flag & 1) && (ikn->flag & 1) ) {
|
|
if( fabs(ik->val-ikn->val) < 0.9 ) {
|
|
val= (float)((ik->val + ikn->val)/2.0);
|
|
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) ik->data[a]->vec[1][0]= val;
|
|
if(ikn->data[a]) ikn->data[a]->vec[1][0]= val;
|
|
}
|
|
}
|
|
}
|
|
ik= ikn;
|
|
ikn= ikn->next;
|
|
|
|
}
|
|
|
|
editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */
|
|
|
|
}
|
|
deselectall_editipo();
|
|
}
|
|
|
|
void join_ipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
IpoCurve *icu;
|
|
BezTriple *bezt, *beztn, *newb;
|
|
float val;
|
|
int mode, tot, a, b;
|
|
|
|
get_status_editipo();
|
|
|
|
mode= pupmenu("Join %t|All Selected %x1|Selected doubles %x2");
|
|
if( mode==2 ) {
|
|
remove_doubles_ipo();
|
|
return;
|
|
}
|
|
else if(mode!=1) return;
|
|
|
|
/* eerst: meerdere geselecteerde verts in 1 curve */
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) {
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
|
|
icu= ei->icu;
|
|
|
|
/* hoeveel punten */
|
|
tot= 0;
|
|
b= icu->totvert;
|
|
bezt= icu->bezt;
|
|
while(b--) {
|
|
if(bezt->f2 & 1) tot++;
|
|
bezt++;
|
|
}
|
|
|
|
if(tot>1) {
|
|
tot--;
|
|
icu->totvert-= tot;
|
|
|
|
newb= MEM_mallocN(icu->totvert*sizeof(BezTriple), "bezt");
|
|
/* het eerste punt wordt het nieuwe punt */
|
|
beztn= newb+1;
|
|
tot= 0;
|
|
|
|
bezt= icu->bezt;
|
|
b= icu->totvert+tot+1;
|
|
while(b--) {
|
|
|
|
if(bezt->f2 & 1) {
|
|
if(tot==0) *newb= *bezt;
|
|
else {
|
|
VecAddf(newb->vec[0], newb->vec[0], bezt->vec[0]);
|
|
VecAddf(newb->vec[1], newb->vec[1], bezt->vec[1]);
|
|
VecAddf(newb->vec[2], newb->vec[2], bezt->vec[2]);
|
|
}
|
|
tot++;
|
|
}
|
|
else {
|
|
*beztn= *bezt;
|
|
beztn++;
|
|
}
|
|
bezt++;
|
|
}
|
|
|
|
VecMulf(newb->vec[0], (float)(1.0/((float)tot)));
|
|
VecMulf(newb->vec[1], (float)(1.0/((float)tot)));
|
|
VecMulf(newb->vec[2], (float)(1.0/((float)tot)));
|
|
|
|
MEM_freeN(icu->bezt);
|
|
icu->bezt= newb;
|
|
|
|
sort_time_ipocurve(icu);
|
|
calchandles_ipocurve(icu);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* dan: in keymode: meerdere geselecteerde keys samenvoegen */
|
|
|
|
editipo_changed(G.sipo, 1); /* maakt ook ipokeys opnieuw! */
|
|
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
val= 0.0;
|
|
tot= 0;
|
|
while(ik) {
|
|
if(ik->flag & 1) {
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) {
|
|
val+= ik->data[a]->vec[1][0];
|
|
break;
|
|
}
|
|
}
|
|
tot++;
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
if(tot>1) {
|
|
val/= (float)tot;
|
|
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
if(ik->flag & 1) {
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) {
|
|
ik->data[a]->vec[1][0]= val;
|
|
}
|
|
}
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
editipo_changed(G.sipo, 0);
|
|
}
|
|
}
|
|
deselectall_editipo();
|
|
}
|
|
|
|
void ipo_snapmenu()
|
|
{
|
|
EditIpo *ei;
|
|
BezTriple *bezt;
|
|
float dx = 0.0;
|
|
int a, b;
|
|
short event, ok, ok2;
|
|
|
|
event= pupmenu("Snap %t|Horizontal %x1|To next %x2|To frame %x3|To current frame%x4");
|
|
if(event < 1) return;
|
|
|
|
get_status_editipo();
|
|
|
|
ei= G.sipo->editipo;
|
|
for(b=0; b<G.sipo->totipo; b++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt) {
|
|
|
|
ok2= 0;
|
|
if(G.sipo->showkey) ok2= 1;
|
|
else if(totipo_vert && (ei->flag & IPO_EDIT)) ok2= 2;
|
|
else if(totipo_vert==0 && (ei->flag & IPO_SELECT)) ok2= 3;
|
|
|
|
if(ok2) {
|
|
bezt= ei->icu->bezt;
|
|
a= ei->icu->totvert;
|
|
while(a--) {
|
|
ok= 0;
|
|
if(totipo_vert) {
|
|
if(bezt->f2 & 1) ok= 1;
|
|
}
|
|
else ok= 1;
|
|
|
|
if(ok) {
|
|
if(event==1) {
|
|
bezt->vec[0][1]= bezt->vec[2][1]= bezt->vec[1][1];
|
|
if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN;
|
|
if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN;
|
|
}
|
|
else if(event==2) {
|
|
if(a) {
|
|
bezt->vec[0][1]= bezt->vec[1][1]= bezt->vec[2][1]= (bezt+1)->vec[1][1];
|
|
if(bezt->h1==HD_AUTO || bezt->h1==HD_VECT) bezt->h1= HD_ALIGN;
|
|
if(bezt->h2==HD_AUTO || bezt->h2==HD_VECT) bezt->h2= HD_ALIGN;
|
|
}
|
|
}
|
|
else if(event==3) {
|
|
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
|
|
}
|
|
else if(event==4) { /* to current frame */
|
|
|
|
if(ok2==1 || ok2==2) {
|
|
|
|
if(G.sipo->blocktype==ID_SEQ) {
|
|
Sequence *seq;
|
|
|
|
seq= (Sequence *)G.sipo->from;
|
|
if(seq) {
|
|
dx= (float)(CFRA-seq->startdisp);
|
|
dx= (float)(100.0*dx/((float)(seq->enddisp-seq->startdisp)));
|
|
|
|
dx-= bezt->vec[1][0];
|
|
}
|
|
}
|
|
else dx= G.scene->r.framelen*CFRA - bezt->vec[1][0];
|
|
|
|
bezt->vec[0][0]+= dx;
|
|
bezt->vec[1][0]+= dx;
|
|
bezt->vec[2][0]+= dx;
|
|
}
|
|
}
|
|
}
|
|
|
|
bezt++;
|
|
}
|
|
calchandles_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
}
|
|
editipo_changed(G.sipo, 1);
|
|
}
|
|
|
|
|
|
|
|
void mouse_select_ipo()
|
|
{
|
|
Object *ob;
|
|
EditIpo *ei, *actei= 0;
|
|
IpoCurve *icu;
|
|
IpoKey *ik, *actik;
|
|
BezTriple *bezt;
|
|
Key *key;
|
|
KeyBlock *kb, *actkb=0;
|
|
float x, y, dist, mindist;
|
|
int a, oldflag = 0, hand, ok;
|
|
short mval[2], xo, yo;
|
|
|
|
if(G.sipo->editipo==0) return;
|
|
|
|
get_status_editipo();
|
|
|
|
if(G.sipo->showkey) {
|
|
getmouseco_areawin(mval);
|
|
|
|
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
|
|
actik= 0;
|
|
mindist= 1000.0;
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
dist= (float)(fabs(ik->val-x));
|
|
if(ik->flag & 1) dist+= 1.0;
|
|
if(dist < mindist) {
|
|
actik= ik;
|
|
mindist= dist;
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
if(actik) {
|
|
oldflag= actik->flag;
|
|
|
|
if(G.qual & LR_SHIFTKEY);
|
|
else deselectall_editipo();
|
|
|
|
if(G.qual & LR_SHIFTKEY) {
|
|
if(oldflag & 1) actik->flag &= ~1;
|
|
else actik->flag |= 1;
|
|
}
|
|
else {
|
|
actik->flag |= 1;
|
|
}
|
|
}
|
|
}
|
|
else if(totipo_edit) {
|
|
|
|
hand= findnearest_ipovert(&icu, &bezt);
|
|
|
|
if(G.qual & LR_SHIFTKEY) {
|
|
if(bezt) {
|
|
if(hand==1) {
|
|
if(BEZSELECTED(bezt)) {
|
|
bezt->f1= bezt->f2= bezt->f3= 0;
|
|
}
|
|
else {
|
|
bezt->f1= bezt->f2= bezt->f3= 1;
|
|
}
|
|
}
|
|
else if(hand==0) {
|
|
if(bezt->f1 & 1) bezt->f1= 0;
|
|
else bezt->f1= 1;
|
|
}
|
|
else {
|
|
if(bezt->f3 & 1) bezt->f3= 0;
|
|
else bezt->f3= 1;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
deselectall_editipo();
|
|
|
|
if(bezt) {
|
|
if(hand==1) {
|
|
bezt->f1|= 1; bezt->f2|= 1; bezt->f3|= 1;
|
|
}
|
|
else if(hand==0) bezt->f1|= 1;
|
|
else bezt->f3|= 1;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
|
|
/* vertex keys ? */
|
|
|
|
if(G.sipo->blocktype==ID_KE && G.sipo->from) {
|
|
key= (Key *)G.sipo->from;
|
|
|
|
ei= G.sipo->editipo;
|
|
if(key->type==KEY_NORMAL || (ei->flag & IPO_VISIBLE)) {
|
|
getmouseco_areawin(mval);
|
|
|
|
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
|
|
/* hoeveel is 20 pixels? */
|
|
mindist= (float)(20.0*(G.v2d->cur.ymax-G.v2d->cur.ymin)/(float)curarea->winy);
|
|
|
|
kb= key->block.first;
|
|
while(kb) {
|
|
dist= (float)(fabs(kb->pos-y));
|
|
if(kb->flag & SELECT) dist+= (float)0.01;
|
|
if(dist < mindist) {
|
|
actkb= kb;
|
|
mindist= dist;
|
|
}
|
|
kb= kb->next;
|
|
}
|
|
if(actkb) {
|
|
ok= TRUE;
|
|
if(G.obedit && (actkb->flag & 1)==0) {
|
|
ok= okee("Copy Key after leaving EditMode");
|
|
}
|
|
if(ok) {
|
|
/* doet ook alle keypos */
|
|
deselectall_editipo();
|
|
|
|
/* oldflag= actkb->flag; */
|
|
|
|
/* if(G.qual & LR_SHIFTKEY); */
|
|
/* else { */
|
|
/* deselectall_key(); */
|
|
/* } */
|
|
|
|
/* if(G.qual & LR_SHIFTKEY) { */
|
|
/* if(oldflag & 1) actkb->flag &= ~1; */
|
|
/* else actkb->flag |= 1; */
|
|
/* } */
|
|
/* else { */
|
|
actkb->flag |= 1;
|
|
/* } */
|
|
|
|
/* bereken keypos */
|
|
showkeypos((Key *)G.sipo->from, actkb);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* select curve */
|
|
if(actkb==0) {
|
|
if(totipo_vis==1) {
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if(ei->icu) {
|
|
if(ei->flag & IPO_VISIBLE) actei= ei;
|
|
}
|
|
}
|
|
}
|
|
else if(totipo_vis>1) {
|
|
actei= select_proj_ipo(0, 0);
|
|
}
|
|
|
|
if(actei) oldflag= actei->flag;
|
|
|
|
if(G.qual & LR_SHIFTKEY);
|
|
else deselectall_editipo();
|
|
|
|
if(actei) {
|
|
if(G.qual & LR_SHIFTKEY) {
|
|
if(oldflag & IPO_SELECT) actei->flag &= ~IPO_SELECT;
|
|
else actei->flag |= IPO_SELECT;
|
|
}
|
|
else {
|
|
actei->flag |= IPO_SELECT;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
update_editipo_flags();
|
|
|
|
force_draw();
|
|
|
|
if(G.sipo->showkey && G.sipo->blocktype==ID_OB) {
|
|
ob= OBACT;
|
|
if(ob && (ob->ipoflag & OB_DRAWKEY)) draw_object_ext(BASACT);
|
|
}
|
|
|
|
getmouseco_areawin(mval);
|
|
xo= mval[0];
|
|
yo= mval[1];
|
|
|
|
while(get_mbut()&R_MOUSE) {
|
|
getmouseco_areawin(mval);
|
|
if(abs(mval[0]-xo)+abs(mval[1]-yo) > 4) {
|
|
|
|
if(actkb) move_keys();
|
|
else transform_ipo('g');
|
|
|
|
return;
|
|
}
|
|
BIF_wait_for_statechange();
|
|
}
|
|
}
|
|
|
|
int icu_keys_bezier_loop(IpoCurve *icu,
|
|
int (*bezier_function)(BezTriple *),
|
|
void (ipocurve_function)(struct IpoCurve *icu))
|
|
{
|
|
/* This loops through the beziers in the Ipocurve, and executes
|
|
* the generic user provided 'bezier_function' on each one.
|
|
* Optionally executes the generic function ipocurve_function on the
|
|
* IPO curve after looping (eg. calchandles_ipocurve)
|
|
*/
|
|
|
|
int b;
|
|
BezTriple *bezt;
|
|
|
|
b = icu->totvert;
|
|
bezt = icu->bezt;
|
|
|
|
/* if bezier_function has been specified
|
|
* then loop through each bezier executing
|
|
* it.
|
|
*/
|
|
|
|
if (bezier_function != NULL) {
|
|
while(b--) {
|
|
/* exit with return code 1 if the bezier function
|
|
* returns 1 (good for when you are only interested
|
|
* in finding the first bezier that
|
|
* satisfies a condition).
|
|
*/
|
|
if (bezier_function(bezt)) return 1;
|
|
bezt++;
|
|
}
|
|
}
|
|
|
|
/* if ipocurve_function has been specified
|
|
* then execute it
|
|
*/
|
|
if (ipocurve_function != NULL)
|
|
ipocurve_function(icu);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int ipo_keys_bezier_loop(Ipo *ipo,
|
|
int (*bezier_function)(BezTriple *),
|
|
void (ipocurve_function)(struct IpoCurve *icu))
|
|
{
|
|
/* This loops through the beziers that are attached to
|
|
* the selected keys on the Ipocurves of the Ipo, and executes
|
|
* the generic user provided 'bezier_function' on each one.
|
|
* Optionally executes the generic function ipocurve_function on a
|
|
* IPO curve after looping (eg. calchandles_ipocurve)
|
|
*/
|
|
|
|
IpoCurve *icu;
|
|
|
|
/* Loop through each curve in the Ipo
|
|
*/
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
if (icu_keys_bezier_loop(icu,bezier_function, ipocurve_function))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int selected_bezier_loop(int (*looptest)(EditIpo *),
|
|
int (*bezier_function)(BezTriple *),
|
|
void (ipocurve_function)(struct IpoCurve *icu))
|
|
{
|
|
/* This loops through the beziers that are attached to
|
|
* selected keys in editmode in the IPO window, and executes
|
|
* the generic user-provided 'bezier_function' on each one
|
|
* that satisfies the 'looptest' function. Optionally executes
|
|
* the generic function ipocurve_function on a IPO curve
|
|
* after looping (eg. calchandles_ipocurve)
|
|
*/
|
|
|
|
EditIpo *ei;
|
|
BezTriple *bezt;
|
|
int a, b;
|
|
|
|
/* Get the first Edit Ipo from the selected Ipos
|
|
*/
|
|
ei= G.sipo->editipo;
|
|
|
|
/* Loop throught all of the selected Ipo's
|
|
*/
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
/* Do a user provided test on the Edit Ipo
|
|
* to determine whether we want to process it
|
|
*/
|
|
if (looptest(ei)) {
|
|
/* Loop through the selected
|
|
* beziers on the Edit Ipo
|
|
*/
|
|
bezt = ei->icu->bezt;
|
|
b = ei->icu->totvert;
|
|
|
|
/* if bezier_function has been specified
|
|
* then loop through each bezier executing
|
|
* it.
|
|
*/
|
|
if (bezier_function != NULL) {
|
|
while(b--) {
|
|
/* exit with return code 1 if the bezier function
|
|
* returns 1 (good for when you are only interested
|
|
* in finding the first bezier that
|
|
* satisfies a condition).
|
|
*/
|
|
if (bezier_function(bezt)) return 1;
|
|
bezt++;
|
|
}
|
|
}
|
|
|
|
/* if ipocurve_function has been specified
|
|
* then execute it
|
|
*/
|
|
if (ipocurve_function != NULL)
|
|
ipocurve_function(ei->icu);
|
|
}
|
|
/* nufte flourdje zim ploopydu <-- random dutch looking comment ;) */
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int select_bezier_add(BezTriple *bezt) {
|
|
/* Select the bezier triple */
|
|
bezt->f1 |= 1;
|
|
bezt->f2 |= 1;
|
|
bezt->f3 |= 1;
|
|
return 0;
|
|
}
|
|
|
|
int select_bezier_subtract(BezTriple *bezt) {
|
|
/* Deselect the bezier triple */
|
|
bezt->f1 &= ~1;
|
|
bezt->f2 &= ~1;
|
|
bezt->f3 &= ~1;
|
|
return 0;
|
|
}
|
|
|
|
int select_bezier_invert(BezTriple *bezt) {
|
|
/* Invert the selection for the bezier triple */
|
|
bezt->f2 ^= 1;
|
|
if ( bezt->f2 & 1 ) {
|
|
bezt->f1 |= 1;
|
|
bezt->f3 |= 1;
|
|
}
|
|
else {
|
|
bezt->f1 &= ~1;
|
|
bezt->f3 &= ~1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int set_bezier_auto(BezTriple *bezt)
|
|
{
|
|
/* Sets the selected bezier handles to type 'auto'
|
|
*/
|
|
|
|
/* is a handle selected? If so
|
|
* set it to type auto
|
|
*/
|
|
if(bezt->f1 || bezt->f3) {
|
|
if(bezt->f1) bezt->h1= 1; /* the secret code for auto */
|
|
if(bezt->f3) bezt->h2= 1;
|
|
|
|
/* if the handles are not of the same type, set them
|
|
* to type free
|
|
*/
|
|
if(bezt->h1!=bezt->h2) {
|
|
if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE;
|
|
if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int set_bezier_vector(BezTriple *bezt)
|
|
{
|
|
/* Sets the selected bezier handles to type 'vector'
|
|
*/
|
|
|
|
/* is a handle selected? If so
|
|
* set it to type vector
|
|
*/
|
|
if(bezt->f1 || bezt->f3) {
|
|
if(bezt->f1) bezt->h1= 2; /* the code for vector */
|
|
if(bezt->f3) bezt->h2= 2;
|
|
|
|
/* if the handles are not of the same type, set them
|
|
* to type free
|
|
*/
|
|
if(bezt->h1!=bezt->h2) {
|
|
if ELEM(bezt->h1, HD_ALIGN, HD_AUTO) bezt->h1= HD_FREE;
|
|
if ELEM(bezt->h2, HD_ALIGN, HD_AUTO) bezt->h2= HD_FREE;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int bezier_isfree(BezTriple *bezt)
|
|
{
|
|
/* queries whether the handle should be set
|
|
* to type 'free' (I think)
|
|
*/
|
|
if(bezt->f1 && bezt->h1) return 1;
|
|
if(bezt->f3 && bezt->h2) return 1;
|
|
return 0;
|
|
}
|
|
|
|
int set_bezier_free(BezTriple *bezt)
|
|
{
|
|
/* Sets selected bezier handles to type 'free'
|
|
*/
|
|
if(bezt->f1) bezt->h1= HD_FREE;
|
|
if(bezt->f3) bezt->h2= HD_FREE;
|
|
return 0;
|
|
}
|
|
|
|
int set_bezier_align(BezTriple *bezt)
|
|
{
|
|
/* Sets selected bezier handles to type 'align'
|
|
*/
|
|
if(bezt->f1) bezt->h1= HD_ALIGN;
|
|
if(bezt->f3) bezt->h2= HD_ALIGN;
|
|
return 0;
|
|
}
|
|
|
|
int vis_edit_icu_bez(EditIpo *ei) {
|
|
/* A 4 part test for an EditIpo :
|
|
* is it a) visible
|
|
* b) in edit mode
|
|
* c) does it contain an Ipo Curve
|
|
* d) does that ipo curve have a bezier
|
|
*
|
|
* (The reason why I don't just use the macro
|
|
* is I need a pointer to a function.)
|
|
*/
|
|
return ISPOIN4(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu, icu->bezt);
|
|
}
|
|
|
|
void select_ipo_bezier_keys(Ipo *ipo, int selectmode)
|
|
{
|
|
/* Select all of the beziers in all
|
|
* of the Ipo curves belonging to the
|
|
* Ipo, using the selection mode.
|
|
*/
|
|
switch (selectmode) {
|
|
case SELECT_ADD:
|
|
ipo_keys_bezier_loop(ipo, select_bezier_add, NULL);
|
|
break;
|
|
case SELECT_SUBTRACT:
|
|
ipo_keys_bezier_loop(ipo, select_bezier_subtract, NULL);
|
|
break;
|
|
case SELECT_INVERT:
|
|
ipo_keys_bezier_loop(ipo, select_bezier_invert, NULL);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sethandles_ipo_keys(Ipo *ipo, int code)
|
|
{
|
|
/* this function lets you set bezier handles all to
|
|
* one type for some Ipo's (e.g. with hotkeys through
|
|
* the action window).
|
|
*/
|
|
|
|
/* code==1: set autohandle */
|
|
/* code==2: set vectorhandle */
|
|
/* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */
|
|
|
|
switch(code) {
|
|
case 1:
|
|
/*** Set to auto ***/
|
|
ipo_keys_bezier_loop(ipo, set_bezier_auto,
|
|
calchandles_ipocurve);
|
|
break;
|
|
case 2:
|
|
/*** Set to vector ***/
|
|
ipo_keys_bezier_loop(ipo, set_bezier_vector,
|
|
calchandles_ipocurve);
|
|
break;
|
|
default:
|
|
if ( ipo_keys_bezier_loop(ipo, bezier_isfree, NULL) ) {
|
|
/*** Set to free ***/
|
|
ipo_keys_bezier_loop(ipo, set_bezier_free,
|
|
calchandles_ipocurve);
|
|
}
|
|
else {
|
|
/*** Set to align ***/
|
|
ipo_keys_bezier_loop(ipo, set_bezier_align,
|
|
calchandles_ipocurve);
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void sethandles_ipo(int code)
|
|
{
|
|
/* this function lets you set bezier handles all to
|
|
* one type for some selected keys in edit mode in the
|
|
* IPO window (e.g. with hotkeys)
|
|
*/
|
|
|
|
/* code==1: set autohandle */
|
|
/* code==2: set vectorhandle */
|
|
/* als code==3 (HD_ALIGN) toggelt het, vectorhandles worden HD_FREE */
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
|
|
switch(code) {
|
|
case 1:
|
|
/*** Set to auto ***/
|
|
selected_bezier_loop(vis_edit_icu_bez, set_bezier_auto,
|
|
calchandles_ipocurve);
|
|
break;
|
|
case 2:
|
|
/*** Set to vector ***/
|
|
selected_bezier_loop(vis_edit_icu_bez, set_bezier_vector,
|
|
calchandles_ipocurve);
|
|
break;
|
|
default:
|
|
if (selected_bezier_loop(vis_edit_icu_bez, bezier_isfree, NULL) ) {
|
|
/*** Set to free ***/
|
|
selected_bezier_loop(vis_edit_icu_bez, set_bezier_free,
|
|
calchandles_ipocurve);
|
|
}
|
|
else {
|
|
/*** Set to align ***/
|
|
selected_bezier_loop(vis_edit_icu_bez, set_bezier_align,
|
|
calchandles_ipocurve);
|
|
}
|
|
break;
|
|
}
|
|
|
|
editipo_changed(G.sipo, 1);
|
|
}
|
|
|
|
|
|
void set_ipocurve_constant(struct IpoCurve *icu) {
|
|
/* Sets the type of the IPO curve to constant
|
|
*/
|
|
icu->ipo= IPO_CONST;
|
|
}
|
|
|
|
void set_ipocurve_linear(struct IpoCurve *icu) {
|
|
/* Sets the type of the IPO curve to linear
|
|
*/
|
|
icu->ipo= IPO_LIN;
|
|
}
|
|
|
|
void set_ipocurve_bezier(struct IpoCurve *icu) {
|
|
/* Sets the type of the IPO curve to bezier
|
|
*/
|
|
icu->ipo= IPO_BEZ;
|
|
}
|
|
|
|
|
|
void setipotype_ipo(Ipo *ipo, int code)
|
|
{
|
|
/* Sets the type of the each ipo curve in the
|
|
* Ipo to a value based on the code
|
|
*/
|
|
switch (code) {
|
|
case 1:
|
|
ipo_keys_bezier_loop(ipo, NULL, set_ipocurve_constant);
|
|
break;
|
|
case 2:
|
|
ipo_keys_bezier_loop(ipo, NULL, set_ipocurve_linear);
|
|
break;
|
|
case 3:
|
|
ipo_keys_bezier_loop(ipo, NULL, set_ipocurve_bezier);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void set_ipotype()
|
|
{
|
|
EditIpo *ei;
|
|
Key *key;
|
|
KeyBlock *kb;
|
|
int a;
|
|
short event;
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
if(G.sipo->showkey) return;
|
|
get_status_editipo();
|
|
|
|
if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) {
|
|
key= (Key *)G.sipo->from;
|
|
if(key==0) return;
|
|
|
|
event= pupmenu("Key Type %t|Linear %x1|Cardinal %x2|B spline %x3");
|
|
if(event < 1) return;
|
|
|
|
kb= key->block.first;
|
|
while(kb) {
|
|
if(kb->flag & SELECT) {
|
|
kb->type= 0;
|
|
if(event==1) kb->type= KEY_LINEAR;
|
|
if(event==2) kb->type= KEY_CARDINAL;
|
|
if(event==3) kb->type= KEY_BSPLINE;
|
|
}
|
|
kb= kb->next;
|
|
}
|
|
}
|
|
else {
|
|
event= pupmenu("Ipo Type %t|Constant %x1|Linear %x2|Bezier %x3");
|
|
if(event < 1) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
|
|
if(event==1) ei->icu->ipo= IPO_CONST;
|
|
else if(event==2) ei->icu->ipo= IPO_LIN;
|
|
else ei->icu->ipo= IPO_BEZ;
|
|
}
|
|
}
|
|
}
|
|
scrarea_queue_winredraw(curarea);
|
|
}
|
|
|
|
void borderselect_ipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
BezTriple *bezt;
|
|
rcti rect;
|
|
rctf rectf;
|
|
int a, b, val;
|
|
short mval[2];
|
|
|
|
get_status_editipo();
|
|
|
|
val= get_border(&rect, 3);
|
|
|
|
if(val) {
|
|
mval[0]= rect.xmin;
|
|
mval[1]= rect.ymin;
|
|
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
|
|
mval[0]= rect.xmax;
|
|
mval[1]= rect.ymax;
|
|
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
|
|
|
|
if(G.sipo->showkey) {
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
if(rectf.xmin<ik->val && rectf.xmax>ik->val) {
|
|
if(val==LEFTMOUSE) ik->flag |= 1;
|
|
else ik->flag &= ~1;
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
update_editipo_flags();
|
|
}
|
|
else if(totipo_edit==0) {
|
|
if(rect.xmin<rect.xmax && rect.ymin<rect.ymax)
|
|
select_proj_ipo(&rectf, val);
|
|
}
|
|
else {
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_EDIT, icu) {
|
|
if(ei->icu->bezt) {
|
|
b= ei->icu->totvert;
|
|
bezt= ei->icu->bezt;
|
|
while(b--) {
|
|
int bit= (val==LEFTMOUSE);
|
|
|
|
if(BLI_in_rctf(&rectf, bezt->vec[0][0], bezt->vec[0][1]))
|
|
bezt->f1 = (bezt->f1&~1) | bit;
|
|
if(BLI_in_rctf(&rectf, bezt->vec[1][0], bezt->vec[1][1]))
|
|
bezt->f2 = (bezt->f2&~1) | bit;
|
|
if(BLI_in_rctf(&rectf, bezt->vec[2][0], bezt->vec[2][1]))
|
|
bezt->f3 = (bezt->f3&~1) | bit;
|
|
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
scrarea_queue_winredraw(curarea);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void del_ipo()
|
|
{
|
|
EditIpo *ei;
|
|
BezTriple *bezt, *bezt1;
|
|
int a, b;
|
|
int del, event;
|
|
|
|
get_status_editipo();
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
|
|
if(totipo_edit==0 && totipo_sel==0 && totipo_vertsel==0) {
|
|
delete_key();
|
|
return;
|
|
}
|
|
|
|
if( okee("Erase selected")==0 ) return;
|
|
|
|
// eerste doorloop, kunnen hele stukken weg?
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
|
|
del= 0;
|
|
|
|
if(G.sipo->showkey==0 && totipo_edit==0) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
|
|
del= 1;
|
|
}
|
|
}
|
|
else {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
|
|
if(ei->icu->bezt) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
if(b) {
|
|
while(b) {
|
|
if( BEZSELECTED(bezt) );
|
|
else break;
|
|
b--;
|
|
bezt++;
|
|
}
|
|
if(b==0) del= 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(del) {
|
|
BLI_remlink( &(G.sipo->ipo->curve), ei->icu);
|
|
if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
|
|
MEM_freeN(ei->icu);
|
|
ei->flag &= ~IPO_SELECT;
|
|
ei->flag &= ~IPO_EDIT;
|
|
ei->icu= 0;
|
|
}
|
|
}
|
|
|
|
// tweede doorloop, kleine stukken weg: alleen curves
|
|
ei= G.sipo->editipo;
|
|
for(b=0; b<G.sipo->totipo; b++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
|
|
|
|
event= 0;
|
|
if(ei->icu->bezt) {
|
|
|
|
bezt= ei->icu->bezt;
|
|
for(a=0; a<ei->icu->totvert; a++) {
|
|
if( BEZSELECTED(bezt) ) {
|
|
memcpy(bezt, bezt+1, (ei->icu->totvert-a-1)*sizeof(BezTriple));
|
|
ei->icu->totvert--;
|
|
a--;
|
|
event= 1;
|
|
}
|
|
else bezt++;
|
|
}
|
|
if(event) {
|
|
bezt1 = (BezTriple*) MEM_mallocN(ei->icu->totvert * sizeof(BezTriple), "delNurb");
|
|
memcpy(bezt1, ei->icu->bezt, (ei->icu->totvert)*sizeof(BezTriple) );
|
|
MEM_freeN(ei->icu->bezt);
|
|
ei->icu->bezt= bezt1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue (REDRAWACTION, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
allspace(REMAKEIPO, 0);
|
|
}
|
|
|
|
ListBase ipocopybuf={0, 0};
|
|
int totipocopybuf=0;
|
|
|
|
void free_ipocopybuf()
|
|
{
|
|
IpoCurve *icu;
|
|
|
|
while( (icu= ipocopybuf.first) ) {
|
|
if(icu->bezt) MEM_freeN(icu->bezt);
|
|
BLI_remlink(&ipocopybuf, icu);
|
|
MEM_freeN(icu);
|
|
}
|
|
totipocopybuf= 0;
|
|
}
|
|
|
|
void copy_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoCurve *icu;
|
|
int a;
|
|
|
|
if(G.sipo->showkey) {
|
|
error("cannot copy\n");
|
|
return;
|
|
}
|
|
|
|
free_ipocopybuf();
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || (ei->flag & IPO_SELECT) ) {
|
|
icu= MEM_callocN(sizeof(IpoCurve), "ipocopybuf");
|
|
*icu= *(ei->icu);
|
|
BLI_addtail(&ipocopybuf, icu);
|
|
if(icu->bezt) {
|
|
icu->bezt= MEM_mallocN(icu->totvert*sizeof(BezTriple), "ipocopybuf");
|
|
memcpy(icu->bezt, ei->icu->bezt, icu->totvert*sizeof(BezTriple));
|
|
}
|
|
totipocopybuf++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(totipocopybuf==0) error("Copybuf is empty");
|
|
}
|
|
|
|
void paste_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoCurve *icu;
|
|
int a, ok;
|
|
|
|
if(G.sipo->showkey) return;
|
|
|
|
if(totipocopybuf==0) return;
|
|
if(G.sipo->ipo==0) return;
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
|
|
get_status_editipo();
|
|
|
|
if(totipo_vis==0) {
|
|
error("No visible splines");
|
|
}
|
|
else if(totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) {
|
|
error("Incompatible paste");
|
|
}
|
|
else {
|
|
/* problemen voorkomen: andere splines visible dan select */
|
|
if(totipo_vis==totipo_sel) totipo_vis= 0;
|
|
|
|
icu= ipocopybuf.first;
|
|
if(icu==0) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if(ei->flag & IPO_VISIBLE) {
|
|
ok= 0;
|
|
if(totipo_vis==totipocopybuf) ok= 1;
|
|
if(totipo_sel==totipocopybuf && (ei->flag & IPO_SELECT)) ok= 1;
|
|
|
|
if(ok) {
|
|
|
|
ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0);
|
|
if(ei->icu==0) return;
|
|
|
|
if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
|
|
ei->icu->bezt= 0;
|
|
|
|
ei->icu->totvert= icu->totvert;
|
|
ei->icu->flag= ei->flag= icu->flag;
|
|
ei->icu->extrap= icu->extrap;
|
|
ei->icu->ipo= icu->ipo;
|
|
|
|
if(icu->bezt) {
|
|
ei->icu->bezt= MEM_mallocN(icu->totvert*sizeof(BezTriple), "ipocopybuf");
|
|
memcpy(ei->icu->bezt, icu->bezt, icu->totvert*sizeof(BezTriple));
|
|
}
|
|
|
|
icu= icu->next;
|
|
|
|
}
|
|
}
|
|
}
|
|
editipo_changed(G.sipo, 1);
|
|
}
|
|
}
|
|
|
|
void set_exprap_ipo(int mode)
|
|
{
|
|
EditIpo *ei;
|
|
int a;
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
/* in geval van keys: altijd ok */
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || (ei->flag & IPO_SELECT) || (G.sipo->showkey) ) {
|
|
ei->icu->extrap= mode;
|
|
}
|
|
}
|
|
}
|
|
editipo_changed(G.sipo, 1);
|
|
}
|
|
|
|
int find_other_handles(EditIpo *eicur, float ctime, BezTriple **beztar)
|
|
{
|
|
EditIpo *ei;
|
|
BezTriple *bezt;
|
|
int a, b, c= 1, totvert;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if(ei!=eicur && ei->icu && (ei->flag & IPO_VISIBLE)) {
|
|
|
|
bezt= ei->icu->bezt;
|
|
totvert= ei->icu->totvert;
|
|
|
|
for(b=0; b<totvert; b++, bezt++) {
|
|
if( bezt->vec[1][0] < ctime+IPOTHRESH && bezt->vec[1][0] > ctime-IPOTHRESH) {
|
|
if(c>2) return 0;
|
|
beztar[c]= bezt;
|
|
c++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(c==3) return 1;
|
|
return 0;
|
|
}
|
|
|
|
void set_speed_editipo(float speed)
|
|
{
|
|
EditIpo *ei;
|
|
BezTriple *bezt, *beztar[3];
|
|
float vec1[3], vec2[3];
|
|
int a, b, totvert, didit=0;
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
|
|
/* uitgaande van 1 visible curve, selected punt, bijhorende punten: lencorr! */
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
bezt= ei->icu->bezt;
|
|
totvert= ei->icu->totvert;
|
|
|
|
for(b=0; b<totvert; b++, bezt++) {
|
|
if(BEZSELECTED(bezt)) {
|
|
|
|
beztar[0]= bezt;
|
|
|
|
if( find_other_handles(ei, bezt->vec[1][0], beztar) ) {
|
|
beztar[0]->h1= beztar[0]->h2= HD_ALIGN;
|
|
beztar[1]->h1= beztar[1]->h2= HD_ALIGN;
|
|
beztar[2]->h1= beztar[2]->h2= HD_ALIGN;
|
|
|
|
vec1[0]= (beztar[0]->vec[1][1] - beztar[0]->vec[0][1]) / (beztar[0]->vec[1][0] - beztar[0]->vec[0][0]) ;
|
|
vec2[0]= (beztar[0]->vec[1][1] - beztar[0]->vec[2][1]) / (beztar[0]->vec[2][0] - beztar[0]->vec[1][0]) ;
|
|
|
|
vec1[1]= (beztar[1]->vec[1][1] - beztar[1]->vec[0][1]) / (beztar[1]->vec[1][0] - beztar[1]->vec[0][0]) ;
|
|
vec2[1]= (beztar[1]->vec[1][1] - beztar[1]->vec[2][1]) / (beztar[1]->vec[2][0] - beztar[1]->vec[1][0]) ;
|
|
|
|
vec1[2]= (beztar[2]->vec[1][1] - beztar[2]->vec[0][1]) / (beztar[2]->vec[1][0] - beztar[2]->vec[0][0]) ;
|
|
vec2[2]= (beztar[2]->vec[1][1] - beztar[2]->vec[2][1]) / (beztar[2]->vec[2][0] - beztar[2]->vec[1][0]) ;
|
|
|
|
Normalise(vec1);
|
|
Normalise(vec2);
|
|
|
|
VecMulf(vec1, speed);
|
|
VecMulf(vec2, speed);
|
|
|
|
beztar[0]->vec[0][1]= beztar[0]->vec[1][1] - vec1[0]*(beztar[0]->vec[1][0] - beztar[0]->vec[0][0]) ;
|
|
beztar[0]->vec[2][1]= beztar[0]->vec[1][1] - vec2[0]*(beztar[0]->vec[2][0] - beztar[0]->vec[1][0]) ;
|
|
|
|
beztar[1]->vec[0][1]= beztar[1]->vec[1][1] - vec1[1]*(beztar[1]->vec[1][0] - beztar[1]->vec[0][0]) ;
|
|
beztar[1]->vec[2][1]= beztar[1]->vec[1][1] - vec2[1]*(beztar[1]->vec[2][0] - beztar[1]->vec[1][0]) ;
|
|
|
|
beztar[2]->vec[0][1]= beztar[2]->vec[1][1] - vec1[2]*(beztar[2]->vec[1][0] - beztar[2]->vec[0][0]) ;
|
|
beztar[2]->vec[2][1]= beztar[2]->vec[1][1] - vec2[2]*(beztar[2]->vec[2][0] - beztar[2]->vec[1][0]) ;
|
|
|
|
didit= 1;
|
|
}
|
|
else {
|
|
error("Cannot set speed");
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(didit==0) error("Did not set speed");
|
|
|
|
editipo_changed(G.sipo, 1);
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue (REDRAWACTION, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
|
|
}
|
|
|
|
|
|
void insertkey(ID *id, int adrcode)
|
|
{
|
|
IpoCurve *icu;
|
|
Ipo *ipo;
|
|
Object *ob;
|
|
void *poin;
|
|
float curval, cfra;
|
|
int type;
|
|
|
|
if(id) {
|
|
|
|
// this call here, otherwise get_ipo_curve gives it from the pinned ipo
|
|
ipo= get_ipo(id, GS(id->name), 1); // 1=make
|
|
|
|
icu= get_ipocurve(id, GS(id->name), adrcode, ipo);
|
|
|
|
if(icu) {
|
|
poin= get_ipo_poin(id, icu, &type);
|
|
if(poin) {
|
|
curval= read_ipo_poin(poin, type);
|
|
|
|
cfra= frame_to_float(CFRA);
|
|
|
|
if( GS(id->name)==ID_OB ) {
|
|
ob= (Object *)id;
|
|
if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
|
|
/* eigenlijk frametofloat overniew berekenen! daarvoor CFRA als float door kunnen geven */
|
|
cfra-= ob->sf*G.scene->r.framelen;
|
|
}
|
|
}
|
|
|
|
insert_vert_ipo(icu, cfra, curval);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void insertkey_editipo()
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
ID *id;
|
|
float *fp, cfra, *insertvals;
|
|
int a, nr, ok, tot;
|
|
short event;
|
|
|
|
if(G.sipo->showkey)
|
|
event= pupmenu("Insert KeyVertices %t|Current frame %x1|Selected Keys %x2");
|
|
else
|
|
event= pupmenu("Insert KeyVertices %t|Current frame %x1");
|
|
|
|
if(event<1) return;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(nr=0; nr<G.sipo->totipo; nr++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
|
|
ok= 0;
|
|
if(G.sipo->showkey) ok= 1;
|
|
else if(ei->flag & IPO_SELECT) ok= 1;
|
|
|
|
if(ok) {
|
|
/* aantal tellen */
|
|
if(event==1) tot= 1;
|
|
else {
|
|
ik= G.sipo->ipokey.first;
|
|
tot= 0;
|
|
while(ik) {
|
|
if(ik->flag & 1) tot++;
|
|
ik= ik->next;
|
|
}
|
|
}
|
|
if(tot) {
|
|
|
|
/* correctie voor ob timeoffs */
|
|
cfra= frame_to_float(CFRA);
|
|
id= G.sipo->from;
|
|
if(id && GS(id->name)==ID_OB ) {
|
|
Object *ob= (Object *)id;
|
|
if(ob->sf!=0.0 && (ob->ipoflag & OB_OFFS_OB) ) {
|
|
cfra-= ob->sf*G.scene->r.framelen;
|
|
}
|
|
}
|
|
else if(id && GS(id->name)==ID_SEQ) {
|
|
extern Sequence *last_seq; /* editsequence.c */
|
|
|
|
if(last_seq) {
|
|
cfra= (float)(100.0*(cfra-last_seq->startdisp)/((float)(last_seq->enddisp-last_seq->startdisp)));
|
|
}
|
|
}
|
|
|
|
insertvals= MEM_mallocN(sizeof(float)*2*tot, "insertkey_editipo");
|
|
/* zeker zijn dat icu->curval klopt */
|
|
calc_ipo(G.sipo->ipo, cfra);
|
|
|
|
if(event==1) {
|
|
insertvals[0]= cfra;
|
|
|
|
insertvals[1]= ei->icu->curval;
|
|
}
|
|
else {
|
|
fp= insertvals;
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
if(ik->flag & 1) {
|
|
calc_ipo(G.sipo->ipo, ik->val);
|
|
|
|
fp[0]= ik->val;
|
|
fp[1]= ei->icu->curval;
|
|
fp+= 2;
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
}
|
|
fp= insertvals;
|
|
for(a=0; a<tot; a++, fp+=2) {
|
|
insert_vert_ipo(ei->icu, fp[0], fp[1]);
|
|
}
|
|
|
|
MEM_freeN(insertvals);
|
|
calc_ipo(G.sipo->ipo, (float)CFRA);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
allqueue (REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
allspace(REMAKEIPO, 0);
|
|
}
|
|
|
|
|
|
void common_insertkey()
|
|
{
|
|
Base *base;
|
|
Object *ob;
|
|
Material *ma;
|
|
ID *id;
|
|
IpoCurve *icu;
|
|
World *wo;
|
|
Lamp *la;
|
|
int tlay, map, event;
|
|
char menustr[256];
|
|
|
|
if(curarea->spacetype==SPACE_IPO) {
|
|
insertkey_editipo();
|
|
}
|
|
else if(curarea->spacetype==SPACE_BUTS) {
|
|
|
|
if(G.buts->mainb==BUTS_MAT) {
|
|
id= G.buts->lockpoin;
|
|
ma= G.buts->lockpoin;
|
|
if(id) {
|
|
event= pupmenu("Insert Key %t|RGB%x0|Alpha%x1|HaSize%x2|Mode %x3|All Color%x10|Ofs%x12|Size%x13|All Mapping%x11");
|
|
if(event== -1) return;
|
|
|
|
map= texchannel_to_adrcode(ma->texact);
|
|
|
|
if(event==0 || event==10) {
|
|
insertkey(id, MA_COL_R);
|
|
insertkey(id, MA_COL_G);
|
|
insertkey(id, MA_COL_B);
|
|
}
|
|
if(event==1 || event==10) {
|
|
insertkey(id, MA_ALPHA);
|
|
}
|
|
if(event==2 || event==10) {
|
|
insertkey(id, MA_HASIZE);
|
|
}
|
|
if(event==3 || event==10) {
|
|
insertkey(id, MA_MODE);
|
|
}
|
|
if(event==10) {
|
|
insertkey(id, MA_SPEC_R);
|
|
insertkey(id, MA_SPEC_G);
|
|
insertkey(id, MA_SPEC_B);
|
|
insertkey(id, MA_REF);
|
|
insertkey(id, MA_EMIT);
|
|
insertkey(id, MA_AMB);
|
|
insertkey(id, MA_SPEC);
|
|
insertkey(id, MA_HARD);
|
|
insertkey(id, MA_MODE);
|
|
}
|
|
if(event==12 || event==11) {
|
|
insertkey(id, map+MAP_OFS_X);
|
|
insertkey(id, map+MAP_OFS_Y);
|
|
insertkey(id, map+MAP_OFS_Z);
|
|
}
|
|
if(event==13 || event==11) {
|
|
insertkey(id, map+MAP_SIZE_X);
|
|
insertkey(id, map+MAP_SIZE_Y);
|
|
insertkey(id, map+MAP_SIZE_Z);
|
|
}
|
|
if(event==11) {
|
|
insertkey(id, map+MAP_R);
|
|
insertkey(id, map+MAP_G);
|
|
insertkey(id, map+MAP_B);
|
|
insertkey(id, map+MAP_DVAR);
|
|
insertkey(id, map+MAP_COLF);
|
|
insertkey(id, map+MAP_NORF);
|
|
insertkey(id, map+MAP_VARF);
|
|
}
|
|
}
|
|
}
|
|
else if(G.buts->mainb==BUTS_WORLD) {
|
|
id= G.buts->lockpoin;
|
|
wo= G.buts->lockpoin;
|
|
if(id) {
|
|
event= pupmenu("Insert Key %t|ZenRGB%x0|HorRGB%x1|Mist%x2|stars %x3|Ofs%x12|Size%x13");
|
|
if(event== -1) return;
|
|
|
|
map= texchannel_to_adrcode(wo->texact);
|
|
|
|
if(event==0) {
|
|
insertkey(id, WO_ZEN_R);
|
|
insertkey(id, WO_ZEN_G);
|
|
insertkey(id, WO_ZEN_B);
|
|
}
|
|
if(event==1) {
|
|
insertkey(id, WO_HOR_R);
|
|
insertkey(id, WO_HOR_G);
|
|
insertkey(id, WO_HOR_B);
|
|
}
|
|
if(event==2) {
|
|
insertkey(id, WO_MISI);
|
|
insertkey(id, WO_MISTDI);
|
|
insertkey(id, WO_MISTSTA);
|
|
insertkey(id, WO_MISTHI);
|
|
}
|
|
if(event==3) {
|
|
insertkey(id, WO_STAR_R);
|
|
insertkey(id, WO_STAR_G);
|
|
insertkey(id, WO_STAR_B);
|
|
insertkey(id, WO_STARDIST);
|
|
insertkey(id, WO_STARSIZE);
|
|
}
|
|
if(event==12) {
|
|
insertkey(id, map+MAP_OFS_X);
|
|
insertkey(id, map+MAP_OFS_Y);
|
|
insertkey(id, map+MAP_OFS_Z);
|
|
}
|
|
if(event==13) {
|
|
insertkey(id, map+MAP_SIZE_X);
|
|
insertkey(id, map+MAP_SIZE_Y);
|
|
insertkey(id, map+MAP_SIZE_Z);
|
|
}
|
|
}
|
|
}
|
|
else if(G.buts->mainb==BUTS_LAMP) {
|
|
id= G.buts->lockpoin;
|
|
la= G.buts->lockpoin;
|
|
if(id) {
|
|
event= pupmenu("Insert Key %t|RGB%x0|Energy%x1|Spotsi%x2|Ofs%x12|Size%x13");
|
|
if(event== -1) return;
|
|
|
|
map= texchannel_to_adrcode(la->texact);
|
|
|
|
if(event==0) {
|
|
insertkey(id, LA_COL_R);
|
|
insertkey(id, LA_COL_G);
|
|
insertkey(id, LA_COL_B);
|
|
}
|
|
if(event==1) {
|
|
insertkey(id, LA_ENERGY);
|
|
}
|
|
if(event==2) {
|
|
insertkey(id, LA_SPOTSI);
|
|
}
|
|
if(event==12) {
|
|
insertkey(id, map+MAP_OFS_X);
|
|
insertkey(id, map+MAP_OFS_Y);
|
|
insertkey(id, map+MAP_OFS_Z);
|
|
}
|
|
if(event==13) {
|
|
insertkey(id, map+MAP_SIZE_X);
|
|
insertkey(id, map+MAP_SIZE_Y);
|
|
insertkey(id, map+MAP_SIZE_Z);
|
|
}
|
|
|
|
}
|
|
}
|
|
else if(G.buts->mainb==BUTS_EDIT) {
|
|
ob= OBACT;
|
|
if(ob && ob->type==OB_CAMERA) {
|
|
id= G.buts->lockpoin;
|
|
if(id) {
|
|
event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1");
|
|
if(event== -1) return;
|
|
|
|
if(event==0) {
|
|
insertkey(id, CAM_LENS);
|
|
}
|
|
if(event==1) {
|
|
insertkey(id, CAM_STA);
|
|
insertkey(id, CAM_END);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if(G.buts->mainb==BUTS_SOUND) {
|
|
if(G.ssound) {
|
|
id= G.buts->lockpoin;
|
|
if(id) {
|
|
event= pupmenu("Insert Key %t|Volume%x0|Pitch%x1|Panning%x2|Attennuation%x3");
|
|
if(event== -1) return;
|
|
|
|
if(event==0) {
|
|
insertkey(id, SND_VOLUME);
|
|
}
|
|
if(event==1) {
|
|
insertkey(id, SND_PITCH);
|
|
}
|
|
if(event==2) {
|
|
insertkey(id, SND_PANNING);
|
|
}
|
|
if(event==3) {
|
|
insertkey(id, SND_ATTEN);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
allspace(REMAKEIPO, 0);
|
|
|
|
}
|
|
else if(curarea->spacetype==SPACE_VIEW3D) {
|
|
|
|
|
|
base= FIRSTBASE;
|
|
while(base) {
|
|
if TESTBASELIB(base) break;
|
|
base= base->next;
|
|
}
|
|
if(base==0) return;
|
|
|
|
if (G.obpose)
|
|
strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Avail%x9");
|
|
else
|
|
strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Size%x2|LocRot%x3|LocRotSize%x4|Layer%x5|Avail%x9");
|
|
|
|
|
|
if( (ob = OBACT)) {
|
|
if(ob->type==OB_MESH) strcat(menustr, "| %x6|Mesh%x7");
|
|
else if(ob->type==OB_LATTICE) strcat(menustr, "| %x6|Lattice%x7");
|
|
else if(ob->type==OB_CURVE) strcat(menustr, "| %x6|Curve%x7");
|
|
else if(ob->type==OB_SURF) strcat(menustr, "| %x6|Surface%x7");
|
|
else if(ob->type==OB_IKA) strcat(menustr, "| %x6|Effector%x8");
|
|
if(ob->flag & OB_FROMGROUP) strcat(menustr, "| %x6|Entire Group%x10");
|
|
}
|
|
|
|
event= pupmenu(menustr);
|
|
if(event== -1) return;
|
|
|
|
if(event==7) {
|
|
if(ob->type==OB_MESH) insert_meshkey(ob->data);
|
|
else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data);
|
|
else if(ob->type==OB_LATTICE) insert_lattkey(ob->data);
|
|
|
|
allqueue(REDRAWIPO, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWBUTSANIM, 0);
|
|
return;
|
|
}
|
|
|
|
if(event==10) {
|
|
Group *group= find_group(ob);
|
|
if(group) {
|
|
add_group_key(group);
|
|
allqueue(REDRAWBUTSANIM, 0);
|
|
}
|
|
}
|
|
|
|
base= FIRSTBASE;
|
|
if (G.obpose){
|
|
bAction *act;
|
|
bPose *pose;
|
|
bPoseChannel *chan;
|
|
bActionChannel *achan;
|
|
|
|
ob = G.obpose;
|
|
|
|
/* Get action & pose from object */
|
|
act=ob->action;
|
|
pose=ob->pose;
|
|
|
|
collect_pose_garbage(ob);
|
|
|
|
if (!act){
|
|
act=G.obpose->action=add_empty_action();
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
}
|
|
if (!pose){
|
|
error ("No pose!"); /* Should never happen */
|
|
}
|
|
|
|
if (act->id.lib)
|
|
{
|
|
error ("Can't key libactions");
|
|
return;
|
|
}
|
|
filter_pose_keys ();
|
|
for (chan=pose->chanbase.first; chan; chan=chan->next)
|
|
{
|
|
if (chan->flag & POSE_KEY){
|
|
// set_action_key(act, chan);
|
|
if(event==0 || event==3 ||event==4) {
|
|
set_action_key(act, chan, AC_LOC_X, 1);
|
|
set_action_key(act, chan, AC_LOC_Y, 1);
|
|
set_action_key(act, chan, AC_LOC_Z, 1);
|
|
}
|
|
if(event==1 || event==3 ||event==4) {
|
|
set_action_key(act, chan, AC_QUAT_X, 1);
|
|
set_action_key(act, chan, AC_QUAT_Y, 1);
|
|
set_action_key(act, chan, AC_QUAT_Z, 1);
|
|
set_action_key(act, chan, AC_QUAT_W, 1);
|
|
}
|
|
if(event==2 || event==4) {
|
|
set_action_key(act, chan, AC_SIZE_X, 1);
|
|
set_action_key(act, chan, AC_SIZE_Y, 1);
|
|
set_action_key(act, chan, AC_SIZE_Z, 1);
|
|
}
|
|
if (event==9){
|
|
for (achan = act->chanbase.first; achan; achan=achan->next){
|
|
if (achan->ipo && !strcmp (achan->name, chan->name)){
|
|
for (icu = achan->ipo->curve.first; icu; icu=icu->next){
|
|
set_action_key(act, chan, icu->adrcode, 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
remake_action_ipos(act);
|
|
}
|
|
allqueue(REDRAWIPO, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
|
|
}
|
|
else
|
|
{
|
|
while(base) {
|
|
if TESTBASELIB(base) {
|
|
id= (ID *)(base->object);
|
|
|
|
/* alle curves in ipo deselect */
|
|
if(base->object->ipo) {
|
|
icu= base->object->ipo->curve.first;
|
|
while(icu) {
|
|
icu->flag &= ~IPO_SELECT;
|
|
if(event==9) insertkey(id, icu->adrcode);
|
|
icu= icu->next;
|
|
}
|
|
}
|
|
|
|
if(event==0 || event==3 ||event==4) {
|
|
insertkey(id, OB_LOC_X);
|
|
insertkey(id, OB_LOC_Y);
|
|
insertkey(id, OB_LOC_Z);
|
|
}
|
|
if(event==1 || event==3 ||event==4) {
|
|
insertkey(id, OB_ROT_X);
|
|
insertkey(id, OB_ROT_Y);
|
|
insertkey(id, OB_ROT_Z);
|
|
}
|
|
if(event==2 || event==4) {
|
|
insertkey(id, OB_SIZE_X);
|
|
insertkey(id, OB_SIZE_Y);
|
|
insertkey(id, OB_SIZE_Z);
|
|
}
|
|
if(event==5) {
|
|
/* localview weghalen */
|
|
tlay= base->object->lay;
|
|
base->object->lay &= 0xFFFFFF;
|
|
insertkey(id, OB_LAY);
|
|
base->object->lay= tlay;
|
|
}
|
|
if(event==8) {
|
|
/* deze patch moet omdat duplicators de positie van effg veranderen */
|
|
Ika *ika= ob->data;
|
|
VecMat4MulVecfl(ika->effg, ob->obmat, ika->effn);
|
|
|
|
insertkey(id, OB_EFF_X);
|
|
insertkey(id, OB_EFF_Y);
|
|
insertkey(id, OB_EFF_Z);
|
|
}
|
|
}
|
|
base= base->next;
|
|
}
|
|
}
|
|
allspace(REMAKEIPO, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWNLA, 0);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/* **************************************************** */
|
|
|
|
/* IPOKEY:
|
|
*
|
|
* er zijn drie manieren om hiermee om te gaan:
|
|
* 1. hieronder: voor tekenen en editen in Ipo window
|
|
* 2. voor tekenen keys in View3D (zie ipo.c en drawobject.c)
|
|
* 3. voor editen keys in View3D (hieronder en editobject.c)
|
|
*
|
|
*/
|
|
|
|
|
|
void free_ipokey(ListBase *lb)
|
|
{
|
|
IpoKey *ik;
|
|
|
|
ik= lb->first;
|
|
while(ik) {
|
|
if(ik->data) MEM_freeN(ik->data);
|
|
ik= ik->next;
|
|
}
|
|
BLI_freelistN(lb);
|
|
}
|
|
|
|
|
|
void add_to_ipokey(ListBase *lb, BezTriple *bezt, int nr, int len)
|
|
{
|
|
IpoKey *ik, *ikn;
|
|
|
|
ik= lb->first;
|
|
while(ik) {
|
|
|
|
if( ik->val==bezt->vec[1][0] ) {
|
|
if(ik->data[nr]==0) { /* dubbele punten! */
|
|
ik->data[nr]= bezt;
|
|
if(bezt->f2 & 1) ik->flag= 1;
|
|
return;
|
|
}
|
|
}
|
|
else if(ik->val > bezt->vec[1][0]) break;
|
|
|
|
ik= ik->next;
|
|
}
|
|
|
|
ikn= MEM_callocN(sizeof(IpoKey), "add_to_ipokey");
|
|
if(ik) BLI_insertlinkbefore(lb, ik, ikn);
|
|
else BLI_addtail(lb, ikn);
|
|
|
|
ikn->data= MEM_callocN(sizeof(float *)*len, "add_to_ipokey");
|
|
ikn->data[nr]= bezt;
|
|
ikn->val= bezt->vec[1][0];
|
|
|
|
if(bezt->f2 & 1) ikn->flag= 1;
|
|
}
|
|
|
|
void make_ipokey(void)
|
|
{
|
|
EditIpo *ei;
|
|
IpoKey *ik;
|
|
ListBase *lb;
|
|
BezTriple *bezt;
|
|
int a, b, sel, desel, totvert;
|
|
|
|
lb= &G.sipo->ipokey;
|
|
free_ipokey(lb);
|
|
|
|
ei= G.sipo->editipo;
|
|
if(ei==0) return;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
bezt= ei->icu->bezt;
|
|
totvert= ei->icu->totvert;
|
|
|
|
for(b=0; b<totvert; b++, bezt++) {
|
|
add_to_ipokey(lb, bezt, a, G.sipo->totipo);
|
|
}
|
|
|
|
ei->flag &= ~IPO_SELECT;
|
|
ei->flag &= ~IPO_EDIT;
|
|
ei->icu->flag= ei->flag;
|
|
}
|
|
}
|
|
|
|
/* selectflags testen */
|
|
ik= lb->first;
|
|
while(ik) {
|
|
sel= desel= 0;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) {
|
|
bezt= ik->data[a];
|
|
if(bezt->f2 & 1) sel++;
|
|
else desel++;
|
|
}
|
|
}
|
|
if(sel && desel) sel= 0;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) {
|
|
bezt= ik->data[a];
|
|
if(sel) {
|
|
bezt->f1 |= 1;
|
|
bezt->f2 |= 1;
|
|
bezt->f3 |= 1;
|
|
}
|
|
else {
|
|
bezt->f1 &= ~1;
|
|
bezt->f2 &= ~1;
|
|
bezt->f3 &= ~1;
|
|
}
|
|
}
|
|
}
|
|
if(sel) ik->flag = 1;
|
|
else ik->flag= 0;
|
|
|
|
ik= ik->next;
|
|
}
|
|
get_status_editipo();
|
|
}
|
|
|
|
void make_ipokey_transform(Object *ob, ListBase *lb, int sel)
|
|
{
|
|
IpoCurve *icu;
|
|
BezTriple *bezt;
|
|
int a, adrcode = 0, ok, dloc=0, drot=0, dsize=0;
|
|
|
|
if(ob->ipo==0) return;
|
|
if(ob->ipo->showkey==0) return;
|
|
|
|
/* testen: zijn er delta curves? */
|
|
icu= ob->ipo->curve.first;
|
|
while(icu) {
|
|
if(icu->flag & IPO_VISIBLE) {
|
|
switch(icu->adrcode) {
|
|
case OB_DLOC_X:
|
|
case OB_DLOC_Y:
|
|
case OB_DLOC_Z:
|
|
dloc= 1;
|
|
break;
|
|
case OB_DROT_X:
|
|
case OB_DROT_Y:
|
|
case OB_DROT_Z:
|
|
drot= 1;
|
|
break;
|
|
case OB_DSIZE_X:
|
|
case OB_DSIZE_Y:
|
|
case OB_DSIZE_Z:
|
|
dsize= 1;
|
|
break;
|
|
}
|
|
}
|
|
icu= icu->next;
|
|
}
|
|
|
|
icu= ob->ipo->curve.first;
|
|
while(icu) {
|
|
if(icu->flag & IPO_VISIBLE) {
|
|
ok= 0;
|
|
|
|
switch(icu->adrcode) {
|
|
case OB_DLOC_X:
|
|
case OB_DLOC_Y:
|
|
case OB_DLOC_Z:
|
|
case OB_DROT_X:
|
|
case OB_DROT_Y:
|
|
case OB_DROT_Z:
|
|
case OB_DSIZE_X:
|
|
case OB_DSIZE_Y:
|
|
case OB_DSIZE_Z:
|
|
ok= 1;
|
|
break;
|
|
|
|
case OB_LOC_X:
|
|
case OB_LOC_Y:
|
|
case OB_LOC_Z:
|
|
if(dloc==0) ok= 1;
|
|
break;
|
|
case OB_ROT_X:
|
|
case OB_ROT_Y:
|
|
case OB_ROT_Z:
|
|
if(drot==0) ok= 1;
|
|
break;
|
|
case OB_SIZE_X:
|
|
case OB_SIZE_Y:
|
|
case OB_SIZE_Z:
|
|
if(dsize==0) ok= 1;
|
|
break;
|
|
}
|
|
if(ok) {
|
|
for(a=0; a<OB_TOTIPO; a++) {
|
|
if(icu->adrcode==ob_ar[a]) {
|
|
adrcode= a;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bezt= icu->bezt;
|
|
a= icu->totvert;
|
|
while(a--) {
|
|
if(sel==0 || (bezt->f2 & 1)) {
|
|
add_to_ipokey(lb, bezt, adrcode, OB_TOTIPO);
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
icu= icu->next;
|
|
}
|
|
}
|
|
|
|
void update_ipokey_val() /* na verplaatsen vertices */
|
|
{
|
|
IpoKey *ik;
|
|
int a;
|
|
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) {
|
|
ik->val= ik->data[a]->vec[1][0];
|
|
break;
|
|
}
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
}
|
|
|
|
void set_tob_old(float *old, float *poin)
|
|
{
|
|
old[0]= *(poin);
|
|
old[3]= *(poin-3);
|
|
old[6]= *(poin+3);
|
|
}
|
|
|
|
void set_ipo_pointers_transob(IpoKey *ik, TransOb *tob)
|
|
{
|
|
BezTriple *bezt;
|
|
int a, delta= 0;
|
|
|
|
tob->locx= tob->locy= tob->locz= 0;
|
|
tob->rotx= tob->roty= tob->rotz= 0;
|
|
tob->sizex= tob->sizey= tob->sizez= 0;
|
|
|
|
for(a=0; a<OB_TOTIPO; a++) {
|
|
if(ik->data[a]) {
|
|
bezt= ik->data[a];
|
|
|
|
switch( ob_ar[a] ) {
|
|
case OB_LOC_X:
|
|
case OB_DLOC_X:
|
|
tob->locx= &(bezt->vec[1][1]); break;
|
|
case OB_LOC_Y:
|
|
case OB_DLOC_Y:
|
|
tob->locy= &(bezt->vec[1][1]); break;
|
|
case OB_LOC_Z:
|
|
case OB_DLOC_Z:
|
|
tob->locz= &(bezt->vec[1][1]); break;
|
|
|
|
case OB_DROT_X:
|
|
delta= 1;
|
|
case OB_ROT_X:
|
|
tob->rotx= &(bezt->vec[1][1]); break;
|
|
case OB_DROT_Y:
|
|
delta= 1;
|
|
case OB_ROT_Y:
|
|
tob->roty= &(bezt->vec[1][1]); break;
|
|
case OB_DROT_Z:
|
|
delta= 1;
|
|
case OB_ROT_Z:
|
|
tob->rotz= &(bezt->vec[1][1]); break;
|
|
|
|
case OB_SIZE_X:
|
|
case OB_DSIZE_X:
|
|
tob->sizex= &(bezt->vec[1][1]); break;
|
|
case OB_SIZE_Y:
|
|
case OB_DSIZE_Y:
|
|
tob->sizey= &(bezt->vec[1][1]); break;
|
|
case OB_SIZE_Z:
|
|
case OB_DSIZE_Z:
|
|
tob->sizez= &(bezt->vec[1][1]); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* oldvals voor o.a. undo */
|
|
if(tob->locx) set_tob_old(tob->oldloc, tob->locx);
|
|
if(tob->locy) set_tob_old(tob->oldloc+1, tob->locy);
|
|
if(tob->locz) set_tob_old(tob->oldloc+2, tob->locz);
|
|
|
|
/* bewaar de eerste oldrot, ivm mapping curves ('1'=10 graden) en correcte berekening */
|
|
if(tob->rotx) set_tob_old(tob->oldrot+3, tob->rotx);
|
|
if(tob->roty) set_tob_old(tob->oldrot+4, tob->roty);
|
|
if(tob->rotz) set_tob_old(tob->oldrot+5, tob->rotz);
|
|
|
|
/* bewaar de eerste oldsize, dit mag niet de dsize zijn! */
|
|
if(tob->sizex) set_tob_old(tob->oldsize+3, tob->sizex);
|
|
if(tob->sizey) set_tob_old(tob->oldsize+4, tob->sizey);
|
|
if(tob->sizez) set_tob_old(tob->oldsize+5, tob->sizez);
|
|
|
|
tob->flag= TOB_IPO;
|
|
if(delta) tob->flag |= TOB_IPODROT;
|
|
}
|
|
|
|
|
|
|
|
void nextkey(ListBase *elems, int dir)
|
|
{
|
|
IpoKey *ik, *previk;
|
|
int totsel;
|
|
|
|
if(dir==1) ik= elems->last;
|
|
else ik= elems->first;
|
|
previk= 0;
|
|
totsel= 0;
|
|
|
|
while(ik) {
|
|
|
|
if(ik->flag) totsel++;
|
|
|
|
if(previk) {
|
|
if(G.qual & LR_SHIFTKEY) {
|
|
if(ik->flag) previk->flag= 1;
|
|
}
|
|
else previk->flag= ik->flag;
|
|
}
|
|
|
|
previk= ik;
|
|
if(dir==1) ik= ik->prev;
|
|
else ik= ik->next;
|
|
|
|
if(G.qual & LR_SHIFTKEY);
|
|
else if(ik==0) previk->flag= 0;
|
|
}
|
|
|
|
/* als geen een key select: */
|
|
if(totsel==0) {
|
|
if(dir==1) ik= elems->first;
|
|
else ik= elems->last;
|
|
|
|
if(ik) ik->flag= 1;
|
|
}
|
|
}
|
|
|
|
static int float_to_frame (float frame)
|
|
{
|
|
int to= (int) frame;
|
|
|
|
if (frame-to>0.5) to++;
|
|
|
|
return to;
|
|
}
|
|
|
|
void movekey_ipo(int dir) /* alleen extern aanroepen vanuit view3d queue */
|
|
{
|
|
IpoKey *ik;
|
|
float toframe = 0.0;
|
|
int a;
|
|
|
|
if(G.sipo->showkey==0) return;
|
|
|
|
ik= G.sipo->ipokey.first;
|
|
if (dir==-1) {
|
|
while (ik && float_to_frame(ik->val)<CFRA) {
|
|
toframe= ik->val;
|
|
ik= ik->next;
|
|
}
|
|
} else {
|
|
while (ik && float_to_frame(ik->val)<=CFRA) {
|
|
ik= ik->next;
|
|
}
|
|
if (ik) toframe= ik->val;
|
|
}
|
|
|
|
a= float_to_frame(toframe);
|
|
|
|
if (a!=CFRA && a>0) {
|
|
CFRA= a;
|
|
|
|
update_for_newframe();
|
|
}
|
|
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
allspace(REMAKEIPO, 0);
|
|
|
|
}
|
|
|
|
void movekey_obipo(int dir) /* alleen extern aanroepen vanuit view3d queue */
|
|
{
|
|
Base *base;
|
|
Object *ob;
|
|
ListBase elems;
|
|
IpoKey *ik;
|
|
int a;
|
|
float toframe= CFRA;
|
|
|
|
base= FIRSTBASE;
|
|
while(base) {
|
|
if TESTBASE(base) {
|
|
ob= base->object;
|
|
if(ob->ipo && ob->ipo->showkey) {
|
|
elems.first= elems.last= 0;
|
|
make_ipokey_transform(ob, &elems, 0);
|
|
|
|
if(elems.first) {
|
|
ik= elems.first;
|
|
if (dir==-1) {
|
|
while (ik && float_to_frame(ik->val)<CFRA) {
|
|
toframe= ik->val;
|
|
ik= ik->next;
|
|
}
|
|
} else {
|
|
while (ik && float_to_frame(ik->val)<=CFRA) {
|
|
ik= ik->next;
|
|
}
|
|
if (ik) toframe= ik->val;
|
|
}
|
|
|
|
free_ipokey(&elems);
|
|
}
|
|
}
|
|
}
|
|
|
|
base= base->next;
|
|
}
|
|
|
|
a= float_to_frame(toframe);
|
|
|
|
if (a!=CFRA && a>0) {
|
|
CFRA= a;
|
|
|
|
update_for_newframe();
|
|
}
|
|
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
allspace(REMAKEIPO, 0);
|
|
|
|
}
|
|
|
|
void nextkey_ipo(int dir) /* aanroepen vanuit ipo queue */
|
|
{
|
|
IpoKey *ik;
|
|
int a;
|
|
|
|
if(G.sipo->showkey==0) return;
|
|
|
|
nextkey(&G.sipo->ipokey, dir);
|
|
|
|
/* kopieeren naar beziers */
|
|
ik= G.sipo->ipokey.first;
|
|
while(ik) {
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ik->data[a]) ik->data[a]->f1= ik->data[a]->f2= ik->data[a]->f3= ik->flag;
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
if(G.sipo->blocktype == ID_OB) allqueue(REDRAWVIEW3D, 0);
|
|
}
|
|
|
|
void nextkey_obipo(int dir) /* alleen extern aanroepen vanuit view3d queue */
|
|
{
|
|
Base *base;
|
|
Object *ob;
|
|
ListBase elems;
|
|
IpoKey *ik;
|
|
int a;
|
|
|
|
/* problem: this doesnt work when you mix dLoc keys with Loc keys */
|
|
|
|
base= FIRSTBASE;
|
|
while(base) {
|
|
if TESTBASE(base) {
|
|
ob= base->object;
|
|
if( (ob->ipoflag & OB_DRAWKEY) && ob->ipo && ob->ipo->showkey) {
|
|
elems.first= elems.last= 0;
|
|
make_ipokey_transform(ob, &elems, 0);
|
|
|
|
if(elems.first) {
|
|
|
|
nextkey(&elems, dir);
|
|
|
|
/* kopieeren naar beziers */
|
|
ik= elems.first;
|
|
while(ik) {
|
|
for(a=0; a<OB_TOTIPO; a++) {
|
|
if(ik->data[a]) ik->data[a]->f1= ik->data[a]->f2= ik->data[a]->f3= ik->flag;
|
|
}
|
|
ik= ik->next;
|
|
}
|
|
|
|
free_ipokey(&elems);
|
|
}
|
|
}
|
|
}
|
|
|
|
base= base->next;
|
|
}
|
|
allqueue(REDRAWNLA, 0);
|
|
allqueue(REDRAWACTION, 0);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allspace(REMAKEIPO, 0);
|
|
allqueue(REDRAWIPO, 0);
|
|
}
|
|
|
|
|
|
/* **************************************************** */
|
|
|
|
|
|
void remake_ipo_transverts(TransVert *transmain, float *dvec, int tot)
|
|
{
|
|
EditIpo *ei;
|
|
TransVert *tv;
|
|
BezTriple *bezt;
|
|
int a, b;
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
|
|
if(ei->icu->bezt) {
|
|
sort_time_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
}
|
|
|
|
ei= G.sipo->editipo;
|
|
tv= transmain;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
|
|
if(ei->icu->bezt) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(ei->icu->ipo==IPO_BEZ) {
|
|
if(bezt->f1 & 1) {
|
|
tv->loc= bezt->vec[0];
|
|
tv++;
|
|
}
|
|
if(bezt->f3 & 1) {
|
|
tv->loc= bezt->vec[2];
|
|
tv++;
|
|
}
|
|
}
|
|
if(bezt->f2 & 1) {
|
|
tv->loc= bezt->vec[1];
|
|
tv++;
|
|
}
|
|
|
|
bezt++;
|
|
}
|
|
testhandles_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(G.sipo->showkey) make_ipokey();
|
|
|
|
if(dvec==0) return;
|
|
|
|
tv= transmain;
|
|
for(a=0; a<tot; a++, tv++) {
|
|
tv->oldloc[0]= tv->loc[0]-dvec[0];
|
|
tv->oldloc[1]= tv->loc[1]-dvec[1];
|
|
}
|
|
}
|
|
|
|
void transform_ipo(int mode)
|
|
{
|
|
EditIpo *ei;
|
|
BezTriple *bezt;
|
|
TransVert *transmain = NULL, *tv;
|
|
float xref=1.0, yref=1.0, dx, dy, dvec[2], min[3], max[3], vec[2], div, cent[2], size[2], sizefac;
|
|
int tot=0, a, b, firsttime=1, afbreek=0, midtog= 0, dosort, proj = 0;
|
|
unsigned short event = 0;
|
|
short mval[2], val, xo, yo, xn, yn, xc, yc;
|
|
char str[32];
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
if(G.sipo->editipo==0) return;
|
|
if(mode=='r') return; /* vanuit gesture */
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
/* welke vertices doen mee */
|
|
get_status_editipo();
|
|
if(totipo_vertsel) {
|
|
tot= totipo_vertsel;
|
|
tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
|
|
|
|
|
|
if(ei->icu->bezt) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(ei->icu->ipo==IPO_BEZ) {
|
|
if(bezt->f1 & 1) {
|
|
tv->loc= bezt->vec[0];
|
|
VECCOPY(tv->oldloc, tv->loc);
|
|
if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
|
|
|
|
/* let op: we nemen middelste vertex */
|
|
DO_MINMAX2(bezt->vec[1], min, max);
|
|
|
|
tv++;
|
|
}
|
|
if(bezt->f3 & 1) {
|
|
tv->loc= bezt->vec[2];
|
|
VECCOPY(tv->oldloc, tv->loc);
|
|
if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
|
|
|
|
/* let op: we nemen middelste vertex */
|
|
DO_MINMAX2(bezt->vec[1], min, max);
|
|
|
|
tv++;
|
|
}
|
|
}
|
|
if(bezt->f2 & 1) {
|
|
tv->loc= bezt->vec[1];
|
|
VECCOPY(tv->oldloc, tv->loc);
|
|
if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
|
|
DO_MINMAX2(bezt->vec[1], min, max);
|
|
tv++;
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(totipo_edit==0 && totipo_sel!=0) {
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
|
|
if(ei->icu->bezt && ei->icu->ipo==IPO_BEZ) tot+= 3*ei->icu->totvert;
|
|
else tot+= ei->icu->totvert;
|
|
}
|
|
}
|
|
if(tot==0) return;
|
|
|
|
tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu) {
|
|
if(ei->icu->bezt) {
|
|
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(ei->icu->ipo==IPO_BEZ) {
|
|
tv->loc= bezt->vec[0];
|
|
VECCOPY(tv->oldloc, tv->loc);
|
|
if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
|
|
tv++;
|
|
|
|
tv->loc= bezt->vec[2];
|
|
VECCOPY(tv->oldloc, tv->loc);
|
|
if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
|
|
tv++;
|
|
}
|
|
tv->loc= bezt->vec[1];
|
|
VECCOPY(tv->oldloc, tv->loc);
|
|
if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
|
|
|
|
DO_MINMAX2(bezt->vec[1], min, max);
|
|
|
|
tv++;
|
|
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if(tot==0) {
|
|
if(totipo_edit==0) move_keys();
|
|
return;
|
|
}
|
|
|
|
cent[0]= (float)((min[0]+max[0])/2.0);
|
|
cent[1]= (float)((min[1]+max[1])/2.0);
|
|
|
|
if(G.sipo->showkey) {
|
|
midtog= 1;
|
|
proj= 1;
|
|
}
|
|
|
|
ipoco_to_areaco(G.v2d, cent, mval);
|
|
xc= mval[0];
|
|
yc= mval[1];
|
|
|
|
getmouseco_areawin(mval);
|
|
xo= xn= mval[0];
|
|
yo= yn= mval[1];
|
|
dvec[0]= dvec[1]= 0.0;
|
|
|
|
sizefac= (float)(sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ));
|
|
if(sizefac<2.0) sizefac= 2.0;
|
|
|
|
while(afbreek==0) {
|
|
getmouseco_areawin(mval);
|
|
if(mval[0]!=xo || mval[1]!=yo || firsttime) {
|
|
|
|
if(mode=='g') {
|
|
|
|
dx= (float)(mval[0]- xo);
|
|
dy= (float)(mval[1]- yo);
|
|
|
|
div= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
|
|
dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
|
|
|
|
div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin);
|
|
dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
|
|
|
|
if(midtog) dvec[proj]= 0.0;
|
|
|
|
/* vec wordt verderop nog gebruikt: remake_ipo_transverts */
|
|
vec[0]= dvec[0];
|
|
vec[1]= dvec[1];
|
|
|
|
apply_keyb_grid(vec, 0.0, (float)1.0, (float)0.1, U.flag & AUTOGRABGRID);
|
|
apply_keyb_grid(vec+1, 0.0, (float)1.0, (float)0.1, 0);
|
|
|
|
tv= transmain;
|
|
for(a=0; a<tot; a++, tv++) {
|
|
tv->loc[0]= tv->oldloc[0]+vec[0];
|
|
|
|
if(tv->flag==0) tv->loc[1]= tv->oldloc[1]+vec[1];
|
|
}
|
|
|
|
sprintf(str, "X: %.3f Y: %.3f ", vec[0], vec[1]);
|
|
headerprint(str);
|
|
}
|
|
else if(mode=='s') {
|
|
|
|
size[0]=size[1]=(float)( (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac);
|
|
|
|
if(midtog) size[proj]= 1.0;
|
|
size[0]*= xref;
|
|
size[1]*= yref;
|
|
|
|
apply_keyb_grid(size, 0.0, (float)0.2, (float)0.1, U.flag & AUTOSIZEGRID);
|
|
apply_keyb_grid(size+1, 0.0, (float)0.2, (float)0.1, U.flag & AUTOSIZEGRID);
|
|
|
|
tv= transmain;
|
|
|
|
for(a=0; a<tot; a++, tv++) {
|
|
tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0];
|
|
if(tv->flag==0) tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1];
|
|
}
|
|
|
|
sprintf(str, "sizeX: %.3f sizeY: %.3f ", size[0], size[1]);
|
|
headerprint(str);
|
|
|
|
}
|
|
|
|
xo= mval[0];
|
|
yo= mval[1];
|
|
|
|
dosort= 0;
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
|
|
/* let op: als de tijd verkeerd is: niet de handles corrigeren */
|
|
if (test_time_ipocurve(ei->icu) ) dosort++;
|
|
else testhandles_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
|
|
if(dosort) {
|
|
if(mode=='g') remake_ipo_transverts(transmain, vec, tot);
|
|
else remake_ipo_transverts(transmain, 0, tot);
|
|
}
|
|
if(G.sipo->showkey) update_ipokey_val();
|
|
|
|
calc_ipo(G.sipo->ipo, (float)CFRA);
|
|
|
|
/* update realtime */
|
|
if(G.sipo->lock) {
|
|
if(G.sipo->blocktype==ID_MA) {
|
|
force_draw_plus(SPACE_BUTS);
|
|
}
|
|
else if(G.sipo->blocktype==ID_KE) {
|
|
do_ob_key(OBACT);
|
|
makeDispList(OBACT);
|
|
force_draw_plus(SPACE_VIEW3D);
|
|
}
|
|
else if(G.sipo->blocktype==ID_AC) {
|
|
do_all_actions();
|
|
force_draw_all();
|
|
}
|
|
else if(G.sipo->blocktype==ID_OB) {
|
|
Base *base= FIRSTBASE;
|
|
|
|
while(base) {
|
|
if(base->object->ipo==G.sipo->ipo) do_ob_ipo(base->object);
|
|
base= base->next;
|
|
}
|
|
force_draw_plus(SPACE_VIEW3D);
|
|
}
|
|
else force_draw();
|
|
}
|
|
else {
|
|
force_draw();
|
|
}
|
|
firsttime= 0;
|
|
}
|
|
else BIF_wait_for_statechange();
|
|
|
|
while(qtest()) {
|
|
event= extern_qread(&val);
|
|
if(val) {
|
|
switch(event) {
|
|
case ESCKEY:
|
|
case LEFTMOUSE:
|
|
case RIGHTMOUSE:
|
|
case SPACEKEY:
|
|
case RETKEY:
|
|
afbreek= 1;
|
|
break;
|
|
case MIDDLEMOUSE:
|
|
if(G.sipo->showkey==0) {
|
|
midtog= ~midtog;
|
|
if(midtog) {
|
|
if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1;
|
|
else proj= 0;
|
|
firsttime= 1;
|
|
}
|
|
}
|
|
break;
|
|
case XKEY:
|
|
case YKEY:
|
|
if(event==XKEY) xref= -xref;
|
|
else if(G.sipo->showkey==0) yref= -yref;
|
|
firsttime= 1;
|
|
break;
|
|
case LEFTCTRLKEY:
|
|
case RIGHTCTRLKEY:
|
|
firsttime= 1;
|
|
break;
|
|
default:
|
|
if(mode=='g') {
|
|
if(G.qual & LR_CTRLKEY) {
|
|
if(event==LEFTARROWKEY) {dvec[0]-= 1.0; firsttime= 1;}
|
|
else if(event==RIGHTARROWKEY) {dvec[0]+= 1.0; firsttime= 1;}
|
|
else if(event==UPARROWKEY) {dvec[1]+= 1.0; firsttime= 1;}
|
|
else if(event==DOWNARROWKEY) {dvec[1]-= 1.0; firsttime= 1;}
|
|
}
|
|
else arrows_move_cursor(event);
|
|
}
|
|
else arrows_move_cursor(event);
|
|
}
|
|
}
|
|
if(afbreek) break;
|
|
}
|
|
}
|
|
|
|
if(event==ESCKEY || event==RIGHTMOUSE) {
|
|
tv= transmain;
|
|
for(a=0; a<tot; a++, tv++) {
|
|
tv->loc[0]= tv->oldloc[0];
|
|
tv->loc[1]= tv->oldloc[1];
|
|
}
|
|
|
|
dosort= 0;
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
|
|
if( test_time_ipocurve(ei->icu)) {
|
|
dosort= 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(dosort) remake_ipo_transverts(transmain, 0, tot);
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
|
|
testhandles_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
}
|
|
calc_ipo(G.sipo->ipo, (float)CFRA);
|
|
}
|
|
|
|
editipo_changed(G.sipo, 1);
|
|
|
|
MEM_freeN(transmain);
|
|
}
|
|
|
|
void clever_numbuts_ipo()
|
|
{
|
|
BezTriple *bezt=0, *bezt1;
|
|
Key *key;
|
|
KeyBlock *kb;
|
|
EditIpo *ei;
|
|
float far, delta[3], old[3];
|
|
int a, b, scale10=0, totbut=2;
|
|
|
|
if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
|
|
if(G.sipo->editipo==0) return;
|
|
|
|
/* welke vertices doen mee */
|
|
get_status_editipo();
|
|
|
|
if(G.qual & LR_SHIFTKEY) totbut= 1;
|
|
|
|
if(G.vd==0) far= 10000.0;
|
|
else far= (float)(MAX2(G.vd->far, 10000.0));
|
|
|
|
if(totipo_vertsel) {
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
|
|
|
|
if(ei->icu->bezt) {
|
|
bezt1= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(BEZSELECTED(bezt1)) {
|
|
bezt= bezt1;
|
|
break;
|
|
}
|
|
bezt1++;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
if(bezt) break;
|
|
}
|
|
|
|
if(bezt==0) return;
|
|
|
|
if(bezt->f2 & 1) {
|
|
|
|
VECCOPY(old, bezt->vec[1]);
|
|
|
|
if(totipo_vis==1 && G.sipo->blocktype==ID_OB) {
|
|
if ELEM4(ei->icu->adrcode, OB_TIME, OB_ROT_X, OB_ROT_Y, OB_ROT_Z) scale10= 1;
|
|
if ELEM3(ei->icu->adrcode, OB_DROT_X, OB_DROT_Y, OB_DROT_Z) scale10= 1;
|
|
}
|
|
if(scale10) bezt->vec[1][1]*= 10.0;
|
|
|
|
add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[1], 0);
|
|
if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[1]+1, 0);
|
|
do_clever_numbuts("Active BezierPoint", totbut, REDRAW);
|
|
|
|
if(scale10) bezt->vec[1][1]/= 10.0;
|
|
|
|
VecSubf(delta, bezt->vec[1], old);
|
|
VECCOPY(bezt->vec[1], old);
|
|
|
|
/* apply */
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
|
|
if(ei->icu->bezt) {
|
|
bezt= ei->icu->bezt;
|
|
b= ei->icu->totvert;
|
|
while(b--) {
|
|
if(bezt->f2 & 1) {
|
|
bezt->vec[0][0]+= delta[0];
|
|
bezt->vec[1][0]+= delta[0];
|
|
bezt->vec[2][0]+= delta[0];
|
|
|
|
bezt->vec[0][1]+= delta[1];
|
|
bezt->vec[1][1]+= delta[1];
|
|
bezt->vec[2][1]+= delta[1];
|
|
}
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++, ei++) {
|
|
if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
|
|
sort_time_ipocurve(ei->icu);
|
|
testhandles_ipocurve(ei->icu);
|
|
}
|
|
}
|
|
|
|
}
|
|
else if(bezt->f1 & 1) {
|
|
add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[0], 0);
|
|
if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[0]+1, 0);
|
|
|
|
do_clever_numbuts("Active HandlePoint", totbut, REDRAW);
|
|
}
|
|
else if(bezt->f3 & 1) {
|
|
add_numbut(0, NUM|FLO, "LocX:", -1000, 10000, bezt->vec[0], 0);
|
|
if(totbut==2) add_numbut(1, NUM|FLO, "LocY:", -far, far, bezt->vec[2]+1, 0);
|
|
|
|
do_clever_numbuts("Active HandlePoint", totbut, REDRAW);
|
|
}
|
|
|
|
editipo_changed(G.sipo, 1);
|
|
}
|
|
else {
|
|
|
|
if(G.sipo->blocktype==ID_KE) {
|
|
key= (Key *)G.sipo->from;
|
|
|
|
if(key==0) return;
|
|
|
|
kb= key->block.first;
|
|
while(kb) {
|
|
if(kb->flag & SELECT) break;
|
|
kb= kb->next;
|
|
}
|
|
if(kb && G.sipo->rowbut&1) {
|
|
add_numbut(0, NUM|FLO, "Pos:", -100, 100, &kb->pos, 0);
|
|
do_clever_numbuts("Active Key", 1, REDRAW);
|
|
sort_keys(key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void filter_sampledata(float *data, int sfra, int efra)
|
|
{
|
|
float *da;
|
|
int a;
|
|
|
|
da= data+1;
|
|
for(a=sfra+1; a<efra; a++, da++) {
|
|
da[0]=(float)( 0.25*da[-1] + 0.5*da[0] + 0.25*da[1]);
|
|
}
|
|
|
|
}
|
|
|
|
void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu)
|
|
{
|
|
BezTriple *bezt;
|
|
float *da;
|
|
int a, tot;
|
|
|
|
filter_sampledata(data, sfra, efra);
|
|
filter_sampledata(data, sfra, efra);
|
|
|
|
icu->ipo= IPO_LIN;
|
|
|
|
if(icu->bezt) MEM_freeN(icu->bezt);
|
|
icu->bezt= 0;
|
|
|
|
tot= 1; /* eerste punt */
|
|
da= data+1;
|
|
for(a=sfra+1; a<efra; a++, da++) {
|
|
if( IS_EQ(da[0], da[1])==0 && IS_EQ(da[1], da[2])==0 ) tot++;
|
|
}
|
|
|
|
icu->totvert= tot;
|
|
bezt= icu->bezt= MEM_callocN(tot*sizeof(BezTriple), "samplebezt");
|
|
bezt->vec[1][0]= (float)sfra;
|
|
bezt->vec[1][1]= data[0];
|
|
bezt++;
|
|
da= data+1;
|
|
for(a=sfra+1; a<efra; a++, da++) {
|
|
if( IS_EQ(da[0], da[1])==0 && IS_EQ(da[1], da[2])==0 ) {
|
|
bezt->vec[1][0]= (float)a;
|
|
bezt->vec[1][1]= da[0];
|
|
bezt++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ipo_record()
|
|
{
|
|
/* 1 of 2 aktieve curves
|
|
* kopie maken (ESC)
|
|
*
|
|
* nulpunt is de huidige stand (of 0)
|
|
* dx (dy identiek) is de hoogteverhouding
|
|
* CTRL start record
|
|
*/
|
|
extern double tottime;
|
|
EditIpo *ei, *ei1=0, *ei2=0;
|
|
ScrArea *sa, *oldarea;
|
|
Ipo *ipo;
|
|
void *poin;
|
|
double swaptime;
|
|
float or1, or2 = 0.0, fac, *data1, *data2;
|
|
int type, a, afbreek=0, firsttime=1, cfrao, cfra, sfra, efra;
|
|
unsigned short event = 0;
|
|
short anim, val, xn, yn, mvalo[2], mval[2];
|
|
char str[128];
|
|
|
|
if(G.sipo->from==0) return;
|
|
if(SFRA>=EFRA) return;
|
|
|
|
anim= pupmenu("Record Mouse %t|Still %x1|Play anim %x2");
|
|
if(anim < 1) return;
|
|
if(anim!=2) anim= 0;
|
|
|
|
ipo= get_ipo(G.sipo->from, G.sipo->blocktype, 1); /* 1= make */
|
|
if(G.sipo) G.sipo->ipo= ipo;
|
|
|
|
/* find the curves... */
|
|
|
|
ei= G.sipo->editipo;
|
|
for(a=0; a<G.sipo->totipo; a++) {
|
|
if(ei->flag & IPO_VISIBLE) {
|
|
|
|
if(ei1==0) ei1= ei;
|
|
else if(ei2==0) ei2= ei;
|
|
else {
|
|
error("Max 2 visible curves");
|
|
return;
|
|
}
|
|
}
|
|
ei++;
|
|
}
|
|
|
|
if(ei1==0) {
|
|
error("Select 1 or 2 channels");
|
|
return;
|
|
}
|
|
|
|
/* curves gereedmaken, startwaardes */
|
|
if(ei1->icu==0) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0);
|
|
if(ei1->icu==0) return;
|
|
poin= get_ipo_poin(G.sipo->from, ei1->icu, &type);
|
|
if(poin) ei1->icu->curval= read_ipo_poin(poin, type);
|
|
or1= ei1->icu->curval;
|
|
ei1->icu->flag |= IPO_LOCK;
|
|
|
|
if(ei2) {
|
|
if(ei2->icu==0) ei2->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei2->adrcode, 0);
|
|
if(ei2->icu==0) return;
|
|
poin= get_ipo_poin(G.sipo->from, ei2->icu, &type);
|
|
if(poin) ei2->icu->curval= read_ipo_poin(poin, type);
|
|
or2= ei2->icu->curval;
|
|
ei2->icu->flag |= IPO_LOCK;
|
|
}
|
|
|
|
fac= G.v2d->cur.ymax - G.v2d->cur.ymin;
|
|
fac/= (float)curarea->winy;
|
|
|
|
/* welke area */
|
|
oldarea= curarea;
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if(sa->win) {
|
|
if(G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_LA) {
|
|
if(sa->spacetype==SPACE_BUTS) break;
|
|
}
|
|
else {
|
|
if(sa->spacetype==SPACE_VIEW3D) break;
|
|
}
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
if(sa) areawinset(sa->win);
|
|
|
|
/* kandie? */
|
|
while(get_mbut()&L_MOUSE) BIF_wait_for_statechange();
|
|
data1= MEM_callocN(sizeof(float)*(EFRA-SFRA+1), "data1");
|
|
data2= MEM_callocN(sizeof(float)*(EFRA-SFRA+1), "data2");
|
|
|
|
getmouseco_areawin(mvalo);
|
|
xn= mvalo[0]; yn= mvalo[1];
|
|
waitcursor(1);
|
|
|
|
tottime= 0.0;
|
|
swaptime= speed_to_swaptime(G.animspeed);
|
|
cfrao= CFRA;
|
|
cfra=efra= SFRA;
|
|
sfra= EFRA;
|
|
|
|
while(afbreek==0) {
|
|
|
|
getmouseco_areawin(mval);
|
|
|
|
if(mval[0]!= mvalo[0] || mval[1]!=mvalo[1] || firsttime || (G.qual & LR_CTRLKEY)) {
|
|
if(anim) CFRA= cfra;
|
|
else firsttime= 0;
|
|
|
|
set_timecursor(cfra);
|
|
|
|
/* ipo doen: eerst alles daarna de specifieke */
|
|
if(anim==2) {
|
|
do_all_ipos();
|
|
do_all_keys();
|
|
}
|
|
|
|
ei1->icu->curval= or1 + fac*(mval[0]-xn);
|
|
if(ei2) ei2->icu->curval= or2 + fac*(mval[1]-yn);
|
|
|
|
do_ipo_nocalc(G.sipo->ipo);
|
|
do_all_visible_ikas();
|
|
|
|
if(G.qual & LR_CTRLKEY) {
|
|
sprintf(str, "Recording... %d\n", cfra);
|
|
data1[ cfra-SFRA ]= ei1->icu->curval;
|
|
if(ei2) data2[ cfra-SFRA ]= ei2->icu->curval;
|
|
|
|
sfra= MIN2(sfra, cfra);
|
|
efra= MAX2(efra, cfra);
|
|
}
|
|
else sprintf(str, "Mouse Recording. Use CTRL to start. LeftMouse or Space to end");
|
|
|
|
do_ob_key(OBACT);
|
|
|
|
headerprint(str);
|
|
|
|
if(sa) scrarea_do_windraw(sa);
|
|
|
|
/* minimaal swaptime laten voorbijgaan */
|
|
tottime -= swaptime;
|
|
while (update_time()) PIL_sleep_ms(1);
|
|
|
|
screen_swapbuffers();
|
|
|
|
tottime= 0.0;
|
|
|
|
mvalo[0]= mval[0];
|
|
mvalo[1]= mval[1];
|
|
|
|
if(anim || (G.qual & LR_CTRLKEY)) {
|
|
cfra++;
|
|
if(cfra>EFRA) cfra= SFRA;
|
|
}
|
|
}
|
|
|
|
while(qtest()) {
|
|
event= extern_qread(&val);
|
|
if(val) {
|
|
switch(event) {
|
|
case LEFTMOUSE: case ESCKEY: case SPACEKEY: case RETKEY:
|
|
afbreek= 1;
|
|
break;
|
|
}
|
|
}
|
|
if(afbreek) break;
|
|
}
|
|
}
|
|
|
|
if(event!=ESCKEY) {
|
|
sampledata_to_ipocurve(data1+sfra-SFRA, sfra, efra, ei1->icu);
|
|
if(ei2) sampledata_to_ipocurve(data2+sfra-SFRA, sfra, efra, ei2->icu);
|
|
|
|
/* vervelend als dat aanstaat */
|
|
if(G.sipo->showkey) {
|
|
G.sipo->showkey= 0;
|
|
free_ipokey(&G.sipo->ipokey);
|
|
}
|
|
}
|
|
else {
|
|
/* undo: startwaardes */
|
|
poin= get_ipo_poin(G.sipo->from, ei1->icu, &type);
|
|
if(poin) write_ipo_poin(poin, type, or1);
|
|
if(ei1->icu->bezt==0) {
|
|
BLI_remlink( &(G.sipo->ipo->curve), ei1->icu);
|
|
MEM_freeN(ei1->icu);
|
|
ei1->icu= 0;
|
|
}
|
|
if(ei2) {
|
|
poin= get_ipo_poin(G.sipo->from, ei2->icu, &type);
|
|
if(poin) write_ipo_poin(poin, type, or2);
|
|
if(ei2->icu->bezt==0) {
|
|
BLI_remlink( &(G.sipo->ipo->curve), ei2->icu);
|
|
MEM_freeN(ei2->icu);
|
|
ei2->icu= 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(ei1->icu) ei1->icu->flag &= ~IPO_LOCK;
|
|
if(ei2 && ei2->icu) ei2->icu->flag &= ~IPO_LOCK;
|
|
|
|
editipo_changed(G.sipo, 0);
|
|
do_ipo(G.sipo->ipo);
|
|
waitcursor(0);
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
if(sa) scrarea_queue_headredraw(sa); /* headerprint */
|
|
scrarea_queue_redraw(oldarea);
|
|
CFRA= cfrao;
|
|
|
|
/* vooropig? */
|
|
update_for_newframe();
|
|
|
|
MEM_freeN(data1);
|
|
MEM_freeN(data2);
|
|
}
|
|
|
|
|
|
|
|
void remake_object_ipos(Object *ob)
|
|
{
|
|
IpoCurve *icu;
|
|
|
|
if (!ob)
|
|
return;
|
|
if (!ob->ipo)
|
|
return;
|
|
|
|
for (icu = ob->ipo->curve.first; icu; icu=icu->next){
|
|
sort_time_ipocurve(icu);
|
|
testhandles_ipocurve(icu);
|
|
}
|
|
}
|
|
|
|
|
|
int is_ipo_key_selected(Ipo *ipo)
|
|
{
|
|
int i;
|
|
IpoCurve *icu;
|
|
|
|
if (!ipo)
|
|
return 0;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (i=0; i<icu->totvert; i++)
|
|
if (BEZSELECTED(&icu->bezt[i]))
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void set_ipo_key_selection(Ipo *ipo, int sel)
|
|
{
|
|
int i;
|
|
IpoCurve *icu;
|
|
|
|
if (!ipo)
|
|
return;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (sel){
|
|
icu->bezt[i].f1|=1;
|
|
icu->bezt[i].f2|=1;
|
|
icu->bezt[i].f3|=1;
|
|
}
|
|
else{
|
|
icu->bezt[i].f1&=~1;
|
|
icu->bezt[i].f2&=~1;
|
|
icu->bezt[i].f3&=~1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void delete_ipo_keys(Ipo *ipo)
|
|
{
|
|
IpoCurve *icu, *next;
|
|
int i;
|
|
|
|
if (!ipo)
|
|
return;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=next){
|
|
next = icu->next;
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (icu->bezt[i].f2 & 1){
|
|
// Delete the item
|
|
memcpy (&icu->bezt[i], &icu->bezt[i+1], sizeof (BezTriple)*(icu->totvert-i-1));
|
|
icu->totvert--;
|
|
i--;
|
|
}
|
|
}
|
|
if (!icu->totvert){
|
|
/* Delete the curve */
|
|
BLI_remlink( &(ipo->curve), icu);
|
|
if(icu->bezt) MEM_freeN(icu->bezt);
|
|
MEM_freeN(icu);
|
|
}
|
|
}
|
|
}
|
|
|
|
int fullselect_ipo_keys(Ipo *ipo)
|
|
{
|
|
int i;
|
|
IpoCurve *icu;
|
|
int tvtot = 0;
|
|
|
|
if (!ipo)
|
|
return tvtot;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (icu->bezt[i].f2 & 1){
|
|
tvtot+=3;
|
|
icu->bezt[i].f1 |= 1;
|
|
icu->bezt[i].f3 |= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return tvtot;
|
|
}
|
|
|
|
int add_trans_ipo_keys(Ipo *ipo, TransVert *tv, int tvtot)
|
|
{
|
|
int i;
|
|
IpoCurve *icu;
|
|
|
|
if (!ipo)
|
|
return tvtot;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (icu->bezt[i].f2 & 1){
|
|
tv[tvtot+0].loc=icu->bezt[i].vec[0];
|
|
tv[tvtot+1].loc=icu->bezt[i].vec[1];
|
|
tv[tvtot+2].loc=icu->bezt[i].vec[2];
|
|
|
|
memcpy (&tv[tvtot+0].oldloc, icu->bezt[i].vec[0], sizeof (float)*3);
|
|
memcpy (&tv[tvtot+1].oldloc, icu->bezt[i].vec[1], sizeof (float)*3);
|
|
memcpy (&tv[tvtot+2].oldloc, icu->bezt[i].vec[2], sizeof (float)*3);
|
|
tvtot+=3;
|
|
}
|
|
}
|
|
}
|
|
|
|
return tvtot;
|
|
}
|
|
|
|
void duplicate_ipo_keys(Ipo *ipo)
|
|
{
|
|
IpoCurve *icu;
|
|
int i;
|
|
BezTriple *newbezt;
|
|
|
|
if (!ipo)
|
|
return;
|
|
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (i=0; i<icu->totvert; i++){
|
|
/* If a key is selected */
|
|
if (icu->bezt[i].f2 & 1){
|
|
/* Expand the list */
|
|
newbezt = MEM_callocN(sizeof(BezTriple) * (icu->totvert+1), "beztriple");
|
|
memcpy (newbezt, icu->bezt, sizeof(BezTriple) * (i+1));
|
|
memcpy (newbezt+i+1, icu->bezt+i, sizeof(BezTriple));
|
|
memcpy (newbezt+i+2, icu->bezt+i+1, sizeof (BezTriple) *(icu->totvert-(i+1)));
|
|
icu->totvert++;
|
|
MEM_freeN (icu->bezt);
|
|
icu->bezt=newbezt;
|
|
/* Unselect the current key*/
|
|
icu->bezt[i].f1 &= ~ 1;
|
|
icu->bezt[i].f2 &= ~ 1;
|
|
icu->bezt[i].f3 &= ~ 1;
|
|
i++;
|
|
/* Select the copied key */
|
|
icu->bezt[i].f1 |= 1;
|
|
icu->bezt[i].f2 |= 1;
|
|
icu->bezt[i].f3 |= 1;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void borderselect_icu_key(IpoCurve *icu, float xmin, float xmax,
|
|
int (*select_function)(BezTriple *))
|
|
{
|
|
/* Selects all bezier triples in the Ipocurve
|
|
* between times xmin and xmax, using the selection
|
|
* function.
|
|
*/
|
|
|
|
int i;
|
|
|
|
/* loop through all of the bezier triples in
|
|
* the Ipocurve -- if the triple occurs between
|
|
* times xmin and xmax then select it using the selection
|
|
* function
|
|
*/
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (icu->bezt[i].vec[1][0] > xmin && icu->bezt[i].vec[1][0] < xmax ){
|
|
select_function(&(icu->bezt[i]));
|
|
}
|
|
}
|
|
}
|
|
|
|
void borderselect_ipo_key(Ipo *ipo, float xmin, float xmax, int selectmode)
|
|
{
|
|
/* Selects all bezier triples in each Ipocurve of the
|
|
* Ipo between times xmin and xmax, using the selection mode.
|
|
*/
|
|
|
|
IpoCurve *icu;
|
|
int (*select_function)(BezTriple *);
|
|
|
|
/* If the ipo is no good then return */
|
|
if (!ipo)
|
|
return;
|
|
|
|
/* Set the selection function based on the
|
|
* selection mode.
|
|
*/
|
|
switch(selectmode) {
|
|
case SELECT_ADD:
|
|
select_function = select_bezier_add;
|
|
break;
|
|
case SELECT_SUBTRACT:
|
|
select_function = select_bezier_subtract;
|
|
break;
|
|
case SELECT_INVERT:
|
|
select_function = select_bezier_invert;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
/* loop through all of the bezier triples in all
|
|
* of the Ipocurves -- if the triple occurs between
|
|
* times xmin and xmax then select it using the selection
|
|
* function
|
|
*/
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
borderselect_icu_key(icu, xmin, xmax, select_function);
|
|
}
|
|
}
|
|
|
|
void select_ipo_key(Ipo *ipo, float selx, int selectmode)
|
|
{
|
|
/* Selects all bezier triples in each Ipocurve of the
|
|
* Ipo at time selx, using the selection mode.
|
|
*/
|
|
int i;
|
|
IpoCurve *icu;
|
|
int (*select_function)(BezTriple *);
|
|
|
|
/* If the ipo is no good then return */
|
|
if (!ipo)
|
|
return;
|
|
|
|
/* Set the selection function based on the
|
|
* selection mode.
|
|
*/
|
|
switch(selectmode) {
|
|
case SELECT_ADD:
|
|
select_function = select_bezier_add;
|
|
break;
|
|
case SELECT_SUBTRACT:
|
|
select_function = select_bezier_subtract;
|
|
break;
|
|
case SELECT_INVERT:
|
|
select_function = select_bezier_invert;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
/* loop through all of the bezier triples in all
|
|
* of the Ipocurves -- if the triple occurs at
|
|
* time selx then select it using the selection
|
|
* function
|
|
*/
|
|
for (icu=ipo->curve.first; icu; icu=icu->next){
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (icu->bezt[i].vec[1][0]==selx){
|
|
select_function(&(icu->bezt[i]));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void select_icu_key(IpoCurve *icu, float selx, int selectmode)
|
|
{
|
|
/* Selects all bezier triples in the Ipocurve
|
|
* at time selx, using the selection mode.
|
|
* This is kind of sloppy the obvious similarities
|
|
* with the above function, forgive me ...
|
|
*/
|
|
int i;
|
|
int (*select_function)(BezTriple *);
|
|
|
|
/* If the icu is no good then return */
|
|
if (!icu)
|
|
return;
|
|
|
|
/* Set the selection function based on the
|
|
* selection mode.
|
|
*/
|
|
switch(selectmode) {
|
|
case SELECT_ADD:
|
|
select_function = select_bezier_add;
|
|
break;
|
|
case SELECT_SUBTRACT:
|
|
select_function = select_bezier_subtract;
|
|
break;
|
|
case SELECT_INVERT:
|
|
select_function = select_bezier_invert;
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
/* loop through all of the bezier triples in
|
|
* the Ipocurve -- if the triple occurs at
|
|
* time selx then select it using the selection
|
|
* function
|
|
*/
|
|
for (i=0; i<icu->totvert; i++){
|
|
if (icu->bezt[i].vec[1][0]==selx){
|
|
select_function(&(icu->bezt[i]));
|
|
}
|
|
}
|
|
|
|
}
|