Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editipo.c')
-rw-r--r--source/blender/src/editipo.c1475
1 files changed, 1375 insertions, 100 deletions
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 09862636085..cd6aefdb87c 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -97,7 +97,6 @@
#include "BIF_editseq.h"
#include "BIF_editview.h"
#include "BIF_interface.h"
-#include "BIF_keyframing.h"
#include "BIF_mywindow.h"
#include "BIF_poseobject.h"
#include "BIF_screen.h"
@@ -1777,129 +1776,113 @@ void do_ipo_selectbuttons(void)
- if bonename, the constname is the ipo to the constraint
*/
-/* note: check header_ipo.c, spaceipo_assign_ipo() too */
-Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char *bonename, short add)
+/* note; check header_ipo.c, spaceipo_assign_ipo() too */
+Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char *bonename)
{
- /* lib-linked data is not appropriate here */
- if ((from==NULL) || (from->lib))
- return NULL;
+
+ if(from==NULL || from->lib) return NULL;
/* first check action ipos */
- if (actname && actname[0]) {
+ if(actname && actname[0]) {
Object *ob= (Object *)from;
bActionChannel *achan;
- if (GS(from->name)!=ID_OB) {
+ if(GS(from->name)!=ID_OB) {
printf("called ipo system for action with wrong base pointer\n");
return NULL;
}
- if ((ob->action==NULL) && (add))
+ if(ob->action==NULL)
ob->action= add_empty_action("Action");
- if (add)
- achan= verify_action_channel(ob->action, actname);
- else
- achan= get_action_channel(ob->action, actname);
+ achan= verify_action_channel(ob->action, actname);
- if (achan) {
+ if(achan) {
/* automatically assign achan to act-group based on pchan's grouping */
- if ((blocktype == ID_PO) && (add))
+ if (blocktype == ID_PO)
verify_pchan2achan_grouping(ob->action, ob->pose, actname);
/* constraint exception */
- if (blocktype==ID_CO) {
- bConstraintChannel *conchan;
-
- if (add)
- conchan= verify_constraint_channel(&achan->constraintChannels, constname);
- else
- conchan= get_constraint_channel(&achan->constraintChannels, constname);
-
- if (conchan) {
- if ((conchan->ipo==NULL) && (add))
- conchan->ipo= add_ipo("CoIpo", ID_CO);
- return conchan->ipo;
+ if(blocktype==ID_CO) {
+ bConstraintChannel *conchan= verify_constraint_channel(&achan->constraintChannels, constname);
+ if(conchan->ipo==NULL) {
+ conchan->ipo= add_ipo("CoIpo", ID_CO);
}
+ return conchan->ipo;
}
else {
- if ((achan->ipo==NULL) && (add))
+ if(achan->ipo==NULL) {
achan->ipo= add_ipo("ActIpo", blocktype);
+ }
+
return achan->ipo;
}
}
}
else {
- switch (GS(from->name)) {
+
+ switch(GS(from->name)) {
case ID_OB:
{
Object *ob= (Object *)from;
/* constraint exception */
- if (blocktype==ID_CO) {
+ if(blocktype==ID_CO) {
/* check the local constraint ipo */
- if (bonename && bonename[0] && ob->pose) {
+ if(bonename && bonename[0] && ob->pose) {
bPoseChannel *pchan= get_pose_channel(ob->pose, bonename);
bConstraint *con;
-
- for (con= pchan->constraints.first; con; con= con->next) {
- if (strcmp(con->name, constname)==0)
+ for(con= pchan->constraints.first; con; con= con->next)
+ if(strcmp(con->name, constname)==0)
break;
- }
-
- if (con) {
- if ((con->ipo==NULL) && (add))
+ if(con) {
+ if(con->ipo==NULL) {
con->ipo= add_ipo("CoIpo", ID_CO);
+ }
return con->ipo;
}
}
else { /* the actionchannel */
- bConstraintChannel *conchan;
-
- if (add)
- conchan= verify_constraint_channel(&ob->constraintChannels, constname);
- else
- conchan= get_constraint_channel(&ob->constraintChannels, constname);
-
- if (conchan) {
- if ((conchan->ipo==NULL) && (add))
- conchan->ipo= add_ipo("CoIpo", ID_CO);
- return conchan->ipo;
+ bConstraintChannel *conchan= verify_constraint_channel(&ob->constraintChannels, constname);
+ if(conchan->ipo==NULL) {
+ conchan->ipo= add_ipo("CoIpo", ID_CO);
}
+ return conchan->ipo;
}
}
- else if (blocktype==ID_OB) {
- if ((ob->ipo==NULL) && (add))
+ else if(blocktype==ID_OB) {
+ if(ob->ipo==NULL) {
ob->ipo= add_ipo("ObIpo", ID_OB);
+ }
return ob->ipo;
}
- else if (blocktype==ID_KE) {
+ else if(blocktype==ID_KE) {
Key *key= ob_get_key((Object *)from);
- if (key) {
- if ((key->ipo==NULL) && (add))
+ if(key) {
+ if(key->ipo==NULL) {
key->ipo= add_ipo("KeyIpo", ID_KE);
+ }
return key->ipo;
}
return NULL;
}
- else if (blocktype== ID_FLUIDSIM) {
+ else if(blocktype== ID_FLUIDSIM) {
Object *ob= (Object *)from;
-
- if (ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
+ if(ob->fluidsimFlag & OB_FLUIDSIM_ENABLE) {
FluidsimSettings *fss= ob->fluidsimSettings;
-
- if ((fss->ipo==NULL) && (add))
+ if(fss->ipo==NULL) {
fss->ipo= add_ipo("FluidsimIpo", ID_FLUIDSIM);
+ //fprintf(stderr,"FSIPO NEW!\n");
+ }
return fss->ipo;
}
}
- else if(blocktype== ID_PA) {
+ else if(blocktype== ID_PA){
Object *ob= (Object *)from;
ParticleSystem *psys= psys_get_current(ob);
-
- if (psys) {
- if ((psys->part->ipo==NULL) && (add))
+ if(psys){
+ if(psys->part->ipo==0)
psys->part->ipo= add_ipo("ParticleIpo", ID_PA);
return psys->part->ipo;
}
@@ -1910,27 +1893,30 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
case ID_MA:
{
Material *ma= (Material *)from;
-
- if ((ma->ipo==NULL) && (add))
+
+ if(ma->ipo==NULL) {
ma->ipo= add_ipo("MatIpo", ID_MA);
+ }
return ma->ipo;
}
break;
case ID_TE:
{
Tex *tex= (Tex *)from;
-
- if ((tex->ipo==NULL) && (add))
+
+ if(tex->ipo==NULL) {
tex->ipo= add_ipo("TexIpo", ID_TE);
+ }
return tex->ipo;
}
break;
case ID_SEQ:
{
Sequence *seq= (Sequence *)from; /* note, sequence is mimicing Id */
-
- if ((seq->ipo==NULL) && (add))
+
+ if(seq->ipo==NULL) {
seq->ipo= add_ipo("SeqIpo", ID_SEQ);
+ }
update_seq_ipo_rect(seq);
return seq->ipo;
}
@@ -1939,17 +1925,19 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
{
Curve *cu= (Curve *)from;
- if ((cu->ipo==NULL) && (add))
+ if(cu->ipo==NULL) {
cu->ipo= add_ipo("CuIpo", ID_CU);
+ }
return cu->ipo;
}
break;
case ID_WO:
{
World *wo= (World *)from;
-
- if ((wo->ipo==NULL) && (add))
+
+ if(wo->ipo==NULL) {
wo->ipo= add_ipo("WoIpo", ID_WO);
+ }
return wo->ipo;
}
break;
@@ -1957,26 +1945,29 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
{
Lamp *la= (Lamp *)from;
- if ((la->ipo==NULL) && (add))
+ if(la->ipo==NULL) {
la->ipo= add_ipo("LaIpo", ID_LA);
+ }
return la->ipo;
}
break;
case ID_CA:
{
Camera *ca= (Camera *)from;
-
- if ((ca->ipo==NULL) && (add))
+
+ if(ca->ipo==NULL) {
ca->ipo= add_ipo("CaIpo", ID_CA);
+ }
return ca->ipo;
}
break;
case ID_SO:
{
bSound *snd= (bSound *)from;
-
- if ((snd->ipo==NULL) && (add))
+
+ if(snd->ipo==NULL) {
snd->ipo= add_ipo("SndIpo", ID_SO);
+ }
return snd->ipo;
}
}
@@ -1988,36 +1979,32 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char
/* returns and creates
* Make sure functions check for NULL or they will crash!
* */
-IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constname, char *bonename, int adrcode, short add)
+IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constname, char *bonename, int adrcode)
{
Ipo *ipo;
IpoCurve *icu= NULL;
/* return 0 if lib */
- /* creates ipo too (if add) */
- ipo= verify_ipo(from, blocktype, actname, constname, bonename, add);
+ /* creates ipo too */
+ ipo= verify_ipo(from, blocktype, actname, constname, bonename);
- if (ipo && ipo->id.lib==NULL && from->lib==NULL) {
- /* try to find matching curve */
- for (icu= ipo->curve.first; icu; icu= icu->next) {
- if (icu->adrcode==adrcode)
- break;
- }
+ if(ipo && ipo->id.lib==NULL && from->lib==NULL) {
- /* make a new one if none found (and can add) */
- if ((icu==NULL) && (add)) {
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->adrcode==adrcode) break;
+ }
+ if(icu==NULL) {
icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
- icu->flag |= (IPO_VISIBLE|IPO_AUTO_HORIZ);
- if (ipo->curve.first==NULL)
- icu->flag |= IPO_ACTIVE; /* first one added active */
+ icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ;
+ if(ipo->curve.first==NULL) icu->flag |= IPO_ACTIVE; /* first one added active */
icu->blocktype= blocktype;
icu->adrcode= adrcode;
set_icu_vars(icu);
- BLI_addtail(&ipo->curve, icu);
+ BLI_addtail( &(ipo->curve), icu);
switch (GS(from->name)) {
case ID_SEQ: {
@@ -2029,12 +2016,190 @@ IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constn
}
}
}
-
- /* return ipo-curve */
+
return icu;
}
+/* threshold for inserting keyframes - threshold here should be good enough for now, but should become userpref */
+#define BEZT_INSERT_THRESH 0.00001
+
+/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
+ * Returns the index to insert at (data already at that index will be offset if replace is 0)
+ */
+static int binarysearch_bezt_index (BezTriple array[], BezTriple *item, int arraylen, short *replace)
+{
+ int start=0, end=arraylen;
+ int loopbreaker= 0, maxloop= arraylen * 2;
+ const float frame= (item)? item->vec[1][0] : 0.0f;
+
+ /* initialise replace-flag first */
+ *replace= 0;
+
+ /* sneaky optimisations (don't go through searching process if...):
+ * - keyframe to be added is to be added out of current bounds
+ * - keyframe to be added would replace one of the existing ones on bounds
+ */
+ if ((arraylen <= 0) || ELEM(NULL, array, item)) {
+ printf("Warning: binarysearch_bezt_index encountered invalid array \n");
+ return 0;
+ }
+ else {
+ /* check whether to add before/after/on */
+ float framenum;
+
+ /* 'First' Keyframe (when only one keyframe, this case is used) */
+ framenum= array[0].vec[1][0];
+ if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
+ *replace = 1;
+ return 0;
+ }
+ else if (frame < framenum)
+ return 0;
+
+ /* 'Last' Keyframe */
+ framenum= array[(arraylen-1)].vec[1][0];
+ if (IS_EQT(frame, framenum, BEZT_INSERT_THRESH)) {
+ *replace= 1;
+ return (arraylen - 1);
+ }
+ else if (frame > framenum)
+ return arraylen;
+ }
+
+
+ /* most of the time, this loop is just to find where to put it
+ * 'loopbreaker' is just here to prevent infinite loops
+ */
+ for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
+ /* compute and get midpoint */
+ int mid = (start + end) / 2;
+ float midfra= array[mid].vec[1][0];
+
+ /* check if exactly equal to midpoint */
+ if (IS_EQT(frame, midfra, BEZT_INSERT_THRESH)) {
+ *replace = 1;
+ return mid;
+ }
+
+ /* repeat in upper/lower half */
+ if (frame > midfra)
+ start= mid + 1;
+ else if (frame < midfra)
+ end= mid - 1;
+ }
+
+ /* print error if loop-limit exceeded */
+ if (loopbreaker == (maxloop-1)) {
+ printf("Error: binarysearch_bezt_index was taking too long \n");
+
+ // include debug info
+ printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
+ }
+
+ /* not found, so return where to place it */
+ return start;
+}
+
+/* This function adds a given BezTriple to an IPO-Curve. It will allocate
+ * memory for the array if needed, and will insert the BezTriple into a
+ * suitable place in chronological order.
+ *
+ * NOTE: any recalculate of the IPO-Curve that needs to be done will need to
+ * be done by the caller.
+ */
+int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
+{
+ BezTriple *newb;
+ int i= 0;
+
+ if (icu->bezt == NULL) {
+ icu->bezt= MEM_callocN(sizeof(BezTriple), "beztriple");
+ *(icu->bezt)= *bezt;
+ icu->totvert= 1;
+ }
+ else {
+ short replace = -1;
+ i = binarysearch_bezt_index(icu->bezt, bezt, icu->totvert, &replace);
+
+ if (replace) {
+ /* sanity check: 'i' may in rare cases exceed arraylen */
+ if ((i >= 0) && (i < icu->totvert))
+ *(icu->bezt + i) = *bezt;
+ }
+ else {
+ /* add new */
+ newb= MEM_callocN((icu->totvert+1)*sizeof(BezTriple), "beztriple");
+
+ /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
+ if (i > 0)
+ memcpy(newb, icu->bezt, i*sizeof(BezTriple));
+
+ /* add beztriple to paste at index i */
+ *(newb + i)= *bezt;
+
+ /* add the beztriples that occur after the beztriple to be pasted (originally in icu) */
+ if (i < icu->totvert)
+ memcpy(newb+i+1, icu->bezt+i, (icu->totvert-i)*sizeof(BezTriple));
+
+ /* replace (+ free) old with new */
+ MEM_freeN(icu->bezt);
+ icu->bezt= newb;
+
+ icu->totvert++;
+ }
+ }
+
+ /* we need to return the index, so that some tools which do post-processing can
+ * detect where we added the BezTriple in the array
+ */
+ return i;
+}
+
+/* This function is a wrapper for insert_bezt_icu, and should be used when
+ * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
+ * else yet.
+ *
+ * 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
+ */
+void insert_vert_icu (IpoCurve *icu, float x, float y, short fast)
+{
+ BezTriple beztr;
+ int a, h1, h2;
+
+ /* set all three points, for nicer start position */
+ memset(&beztr, 0, sizeof(BezTriple));
+ beztr.vec[0][0]= x;
+ beztr.vec[0][1]= y;
+ beztr.vec[1][0]= x;
+ beztr.vec[1][1]= y;
+ beztr.vec[2][0]= x;
+ beztr.vec[2][1]= y;
+ beztr.hide= IPO_BEZ;
+ beztr.f1= beztr.f2= beztr.f3= SELECT;
+ beztr.h1= beztr.h2= HD_AUTO;
+
+ /* add temp beztriple to keyframes */
+ a= insert_bezt_icu(icu, &beztr);
+ if (!fast) calchandles_ipocurve(icu);
+
+ /* set handletype */
+ if (icu->totvert > 2) {
+ BezTriple *bezt;
+
+ h1= h2= HD_AUTO;
+ bezt= (icu->bezt + a);
+
+ if (a > 0) h1= (bezt-1)->h2;
+ if (a < icu->totvert-1) h2= (bezt+1)->h1;
+
+ bezt->h1= h1;
+ bezt->h2= h2;
+
+ if (!fast) calchandles_ipocurve(icu);
+ }
+}
+
void add_vert_ipo(void)
{
EditIpo *ei;
@@ -2068,7 +2233,7 @@ void add_vert_ipo(void)
if(ei->icu==NULL) {
if(G.sipo->from) {
- ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode, 1);
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
if (ei->icu)
ei->flag |= ei->icu->flag & IPO_AUTO_HORIZ; /* new curve could have been added, weak... */
else
@@ -2094,6 +2259,525 @@ void add_vert_ipo(void)
BIF_undo_push("Add Ipo vertex");
}
+static void *get_context_ipo_poin(ID *id, int blocktype, char *actname, char *constname, IpoCurve *icu, int *vartype)
+{
+ if (blocktype==ID_PO) {
+ if (GS(id->name)==ID_OB) {
+ Object *ob= (Object *)id;
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+
+ if (pchan) {
+ *vartype= IPO_FLOAT;
+ return get_pchan_ipo_poin(pchan, icu->adrcode);
+ }
+ else
+ return NULL;
+ }
+ return NULL;
+ }
+ else if (blocktype==ID_CO) {
+ if ((GS(id->name)==ID_OB) && (constname && constname[0])) {
+ Object *ob= (Object *)id;
+ bConstraint *con;
+
+ /* assume that we only want the influence (as only used for Constraint Channels) */
+ if ((ob->ipoflag & OB_ACTION_OB) && !strcmp(actname, "Object")) {
+ for (con= ob->constraints.first; con; con= con->next) {
+ if (strcmp(constname, con->name)==0) {
+ *vartype= IPO_FLOAT;
+ return &con->enforce;
+ }
+ }
+ }
+ else if (ob->pose) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+
+ if (pchan) {
+ for (con= pchan->constraints.first; con; con= con->next) {
+ if (strcmp(constname, con->name)==0) {
+ *vartype= IPO_FLOAT;
+ return &con->enforce;
+ }
+ }
+ }
+ }
+ }
+ return NULL;
+ }
+ else
+ return get_ipo_poin(id, icu, vartype);
+
+}
+
+#define KEYNEEDED_DONTADD 0
+#define KEYNEEDED_JUSTADD 1
+#define KEYNEEDED_DELPREV 2
+#define KEYNEEDED_DELNEXT 3
+
+static int new_key_needed(IpoCurve *icu, float cFrame, float nValue)
+{
+ /* This function determines whether a new keyframe is needed */
+ /* Cases where keyframes should not be added:
+ * 1. Keyframe to be added bewteen two keyframes with similar values
+ * 2. Keyframe to be added on frame where two keyframes are already situated
+ * 3. Keyframe lies at point that intersects the linear line between two keyframes
+ */
+
+ BezTriple *bezt=NULL, *prev=NULL;
+ int totCount, i;
+ float valA = 0.0f, valB = 0.0f;
+
+ /* safety checking */
+ if (!icu) return KEYNEEDED_JUSTADD;
+ totCount= icu->totvert;
+ if (totCount==0) return KEYNEEDED_JUSTADD;
+
+ /* loop through checking if any are the same */
+ bezt= icu->bezt;
+ for (i=0; i<totCount; i++) {
+ float prevPosi=0.0f, prevVal=0.0f;
+ float beztPosi=0.0f, beztVal=0.0f;
+
+ /* get current time+value */
+ beztPosi= bezt->vec[1][0];
+ beztVal= bezt->vec[1][1];
+
+ if (prev) {
+ /* there is a keyframe before the one currently being examined */
+
+ /* get previous time+value */
+ prevPosi= prev->vec[1][0];
+ prevVal= prev->vec[1][1];
+
+ /* keyframe to be added at point where there are already two similar points? */
+ if (IS_EQ(prevPosi, cFrame) && IS_EQ(beztPosi, cFrame) && IS_EQ(beztPosi, prevPosi)) {
+ return KEYNEEDED_DONTADD;
+ }
+
+ /* keyframe between prev+current points ? */
+ if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
+ /* is the value of keyframe to be added the same as keyframes on either side ? */
+ if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal)) {
+ return KEYNEEDED_DONTADD;
+ }
+ else {
+ float realVal;
+
+ /* get real value of curve at that point */
+ realVal= eval_icu(icu, cFrame);
+
+ /* compare whether it's the same as proposed */
+ if (IS_EQ(realVal, nValue))
+ return KEYNEEDED_DONTADD;
+ else
+ return KEYNEEDED_JUSTADD;
+ }
+ }
+
+ /* new keyframe before prev beztriple? */
+ if (cFrame < prevPosi) {
+ /* A new keyframe will be added. However, whether the previous beztriple
+ * stays around or not depends on whether the values of previous/current
+ * beztriples and new keyframe are the same.
+ */
+ if (IS_EQ(prevVal, nValue) && IS_EQ(beztVal, nValue) && IS_EQ(prevVal, beztVal))
+ return KEYNEEDED_DELNEXT;
+ else
+ return KEYNEEDED_JUSTADD;
+ }
+ }
+ else {
+ /* just add a keyframe if there's only one keyframe
+ * and the new one occurs before the exisiting one does.
+ */
+ if ((cFrame < beztPosi) && (totCount==1))
+ return KEYNEEDED_JUSTADD;
+ }
+
+ /* continue. frame to do not yet passed (or other conditions not met) */
+ if (i < (totCount-1)) {
+ prev= bezt;
+ bezt++;
+ }
+ else
+ break;
+ }
+
+ /* Frame in which to add a new-keyframe occurs after all other keys
+ * -> If there are at least two existing keyframes, then if the values of the
+ * last two keyframes and the new-keyframe match, the last existing keyframe
+ * gets deleted as it is no longer required.
+ * -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
+ * keyframe is not equal to last keyframe.
+ */
+ bezt= (icu->bezt + (icu->totvert - 1));
+ valA= bezt->vec[1][1];
+
+ if (prev)
+ valB= prev->vec[1][1];
+ else
+ valB= bezt->vec[1][1] + 1.0f;
+
+ if (IS_EQ(valA, nValue) && IS_EQ(valA, valB))
+ return KEYNEEDED_DELPREV;
+ else
+ return KEYNEEDED_JUSTADD;
+}
+
+/* a duplicate of insertkey that does not check for routing to insertmatrixkey
+ to avoid recursion problems */
+static void insertkey_nonrecurs(ID *id, int blocktype, char *actname, char *constname, int adrcode)
+{
+ IpoCurve *icu;
+ Object *ob;
+ void *poin= NULL;
+ float curval, cfra;
+ int vartype;
+ int matset=0;
+
+ if (matset==0) {
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
+
+ if(icu) {
+
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
+
+ if(poin) {
+ curval= read_ipo_poin(poin, vartype);
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ /* actually frametofloat calc again! */
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ }
+ }
+
+ insert_vert_icu(icu, cfra, curval, 0);
+ }
+ }
+ }
+}
+
+int insertmatrixkey(ID *id, int blocktype, char *actname, char *constname, int adrcode)
+{
+ int matindex=0;
+ /* branch on adrcode and blocktype, generating the proper matrix-based
+ values to send to insertfloatkey */
+ if (GS(id->name)==ID_OB) {
+ Object *ob= (Object *)id;
+
+ if ( blocktype==ID_OB ){ //working with an object
+ if ((ob)&&!(ob->parent)) {
+ if ((adrcode==OB_ROT_X)||(adrcode==OB_ROT_Y)||(adrcode==OB_ROT_Z)) { //get a rotation
+ float eul[3];
+ switch (adrcode) {
+ case OB_ROT_X:
+ matindex=0;
+ break;
+ case OB_ROT_Y:
+ matindex=1;
+ break;
+ case OB_ROT_Z:
+ matindex=2;
+ break;
+ }
+ Mat4ToEul(ob->obmat, eul);
+ insertfloatkey(id, ID_OB, actname, NULL, adrcode, eul[matindex]*(5.72958));
+ return 1;
+ } else if ((adrcode==OB_LOC_X)||(adrcode==OB_LOC_Y)||(adrcode==OB_LOC_Z)) {//get a translation
+ switch (adrcode) {
+ case OB_LOC_X:
+ matindex=0;
+ break;
+ case OB_LOC_Y:
+ matindex=1;
+ break;
+ case OB_LOC_Z:
+ matindex=2;
+ break;
+ }
+ insertfloatkey(id, ID_OB, actname, NULL, adrcode, ob->obmat[3][matindex]);
+ return 1;
+ }
+ }
+ } else if ( blocktype==ID_PO) { //working with a pose channel
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+ if (pchan) {
+ if ((adrcode==AC_LOC_X)||(adrcode==AC_LOC_Y)||(adrcode==AC_LOC_Z)) {
+ switch (adrcode) {
+ case AC_LOC_X:
+ matindex=0;
+ break;
+ case AC_LOC_Y:
+ matindex=1;
+ break;
+ case AC_LOC_Z:
+ matindex=2;
+ break;
+ }
+ if (!(pchan->bone->parent)||((pchan->bone->parent)&&!(pchan->bone->flag&BONE_CONNECTED))) { /* don't use for non-connected child bones */
+ float delta_mat[4][4];
+ armature_mat_pose_to_delta(delta_mat, pchan->pose_mat, pchan->bone->arm_mat);
+ insertfloatkey(id, ID_PO, pchan->name, NULL, adrcode, delta_mat[3][matindex]);
+ return 1;
+ }
+ } else if ((adrcode==AC_QUAT_W)||(adrcode==AC_QUAT_X)||(adrcode==AC_QUAT_Y)||(adrcode==AC_QUAT_Z)) {
+ float tmat[4][4], trimat[3][3], localQuat[4];
+
+ switch (adrcode) {
+ case AC_QUAT_W:
+ matindex=0;
+ break;
+ case AC_QUAT_X:
+ matindex=1;
+ break;
+ case AC_QUAT_Y:
+ matindex=2;
+ break;
+ case AC_QUAT_Z:
+ matindex=3;
+ break;
+ }
+
+ /* it should be reasonable to assume that we are keyframing on the active object, although it is not
+ * strictly required for this particular space conversion, arg1 must not be null for this to work
+ */
+ Mat4CpyMat4(tmat, pchan->pose_mat);
+ constraint_mat_convertspace(OBACT, pchan, tmat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+
+ Mat3CpyMat4(trimat, tmat);
+ Mat3ToQuat_is_ok(trimat, localQuat);
+ insertfloatkey(id, ID_PO, pchan->name, NULL, adrcode, localQuat[matindex]);
+
+ return 1;
+ }
+ }
+ }
+ }
+ /* failed to set a matrix key -- use traditional, but the non-recursing version */
+ insertkey_nonrecurs(id,blocktype,actname,constname,adrcode);
+ return 0;
+}
+
+static int match_adr_constraint(ID * id, int blocktype, char *actname, int adrcode)
+{ /* This function matches constraint blocks with adrcodes to see if the
+ visual keying method should be used. For example, an object looking to key
+ location and having a CopyLoc constraint would return true. */
+
+ Object *ob=NULL;
+ int foundmatch=0;
+ int searchtype=0;
+ bConstraint *conref=NULL, *con=NULL;
+
+ /*Retrieve constraint list*/
+ if( GS(id->name)==ID_OB )
+ ob= (Object *)id;
+ if (ob) {
+ if (blocktype==ID_PO) {
+ bPoseChannel *pchan= get_pose_channel(ob->pose, actname);
+ conref=pchan->constraints.first;
+ } else if (blocktype==ID_OB) {
+ conref=ob->constraints.first;
+ }
+
+ if (conref) {
+ /*Set search type: 1 is for translation contraints, 2 is for rotation*/
+ if ((adrcode==OB_LOC_X)||(adrcode==OB_LOC_Y)||(adrcode==OB_LOC_Z)||(adrcode==AC_LOC_X)||(adrcode==AC_LOC_Y)||(adrcode==AC_LOC_Z)) {
+ searchtype=1;
+ } else if ((adrcode==OB_ROT_X)||(adrcode==OB_ROT_Y)||(adrcode==OB_ROT_Z)||(adrcode==AC_QUAT_W)||(adrcode==AC_QUAT_X)||(adrcode==AC_QUAT_Y)||(adrcode==AC_QUAT_Z)) {
+ searchtype=2;
+ }
+
+ if (searchtype>0) {
+ for (con=conref; (con)&&(foundmatch==0); con=con->next) {
+ switch (con->type) {
+ /* match constraint types to which kinds of keying they would affect */
+ case CONSTRAINT_TYPE_CHILDOF:
+ foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_TRACKTO:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ if (searchtype==2) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_MINMAX:
+ if (searchtype==1) foundmatch=1;
+ break;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ foundmatch=1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return foundmatch;
+
+}
+
+void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, short fast)
+{
+ IpoCurve *icu;
+ Object *ob;
+ void *poin= NULL;
+ float curval, cfra;
+ int vartype;
+ int matset=0;
+
+ if ((IS_AUTOKEY_FLAG(AUTOMATKEY))&&(match_adr_constraint(id, blocktype, actname, adrcode))) {
+ matset=insertmatrixkey(id, blocktype, actname, constname, adrcode);
+ }
+ if (matset==0) {
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
+
+ if(icu) {
+
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
+
+ if(poin) {
+ curval= read_ipo_poin(poin, vartype);
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ /* actually frametofloat calc again! */
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ }
+ }
+
+ insert_vert_icu(icu, cfra, curval, fast);
+ }
+ }
+ }
+}
+
+
+
+/* This function is a 'smarter' version of the insert key code.
+ * It uses an auxilliary function to check whether a keyframe is really needed */
+void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, int adrcode)
+{
+ IpoCurve *icu;
+ Object *ob;
+ void *poin= NULL;
+ float curval, cfra;
+ int vartype;
+ int insert_mode;
+
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
+
+ if(icu) {
+
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
+
+ if(poin) {
+ curval= read_ipo_poin(poin, vartype);
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ /* actually frametofloat calc again! */
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ }
+ }
+
+ /* check whether this curve really needs a new keyframe */
+ insert_mode= new_key_needed(icu, cfra, curval);
+
+ /* insert new keyframe at current frame */
+ if (insert_mode)
+ insert_vert_icu(icu, cfra, curval, 0);
+
+ /* delete keyframe immediately before/after newly added */
+ switch (insert_mode) {
+ case KEYNEEDED_DELPREV:
+ delete_icu_key(icu, icu->totvert-2, 1);
+ break;
+ case KEYNEEDED_DELNEXT:
+ delete_icu_key(icu, 1, 1);
+ break;
+ }
+ }
+ }
+}
+
+/* For inserting keys based on an arbitrary float value */
+void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int adrcode, float floatkey)
+{
+ IpoCurve *icu;
+ Object *ob;
+ void *poin= NULL;
+ float cfra;
+ int vartype;
+
+ icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
+
+ if(icu) {
+
+ poin= get_context_ipo_poin(id, blocktype, actname, constname, icu, &vartype);
+
+ if(poin) {
+
+ cfra= frame_to_float(CFRA);
+
+ /* if action is mapped in NLA, it returns a correction */
+ if(actname && actname[0] && GS(id->name)==ID_OB)
+ cfra= get_action_frame((Object *)id, cfra);
+
+ if( GS(id->name)==ID_OB ) {
+ ob= (Object *)id;
+ if((ob->ipoflag & OB_OFFS_OB) && (give_timeoffset(ob)!=0.0) ) {
+ /* actually frametofloat calc again! */
+ cfra-= give_timeoffset(ob)*G.scene->r.framelen;
+ }
+ }
+
+ /* insert new keyframe at current frame */
+ insert_vert_icu(icu, cfra, floatkey, 0);
+ }
+ }
+}
void insertkey_editipo(void)
{
@@ -2225,6 +2909,598 @@ void insertkey_editipo(void)
}
+void common_insertkey(void)
+{
+ Base *base;
+ Object *ob;
+ Material *ma;
+ ID *id;
+ IpoCurve *icu;
+ World *wo;
+ Lamp *la;
+ Tex *te;
+ int tlay, map, event;
+ char menustr[256];
+
+ if(curarea->spacetype==SPACE_IPO) {
+ insertkey_editipo();
+ }
+ else if(curarea->spacetype==SPACE_ACTION) {
+ insertkey_action();
+ }
+ else if(curarea->spacetype==SPACE_BUTS) {
+ if(G.buts->mainb==CONTEXT_SHADING) {
+ int tab= G.buts->tab[CONTEXT_SHADING];
+
+ if(tab==TAB_SHADING_MAT) {
+ ma = G.buts->lockpoin;
+ ma = editnode_get_active_material(ma);
+ id = (ID *)ma;
+
+ if(id) {
+ event= pupmenu("Insert Key %t|RGB%x0|Alpha%x1|Halo Size%x2|Mode %x3|All Color%x10|All Mirror%x14|Ofs%x12|Size%x13|All Mapping%x11");
+ if(event== -1) return;
+
+ map= texchannel_to_adrcode(ma->texact);
+
+ if(event==0 || event==10) {
+ insertkey(id, ID_MA, NULL, NULL, MA_COL_R, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_COL_G, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_COL_B, 0);
+ }
+ if(event==1 || event==10) {
+ insertkey(id, ID_MA, NULL, NULL, MA_ALPHA, 0);
+ }
+ if(event==2 || event==10) {
+ insertkey(id, ID_MA, NULL, NULL, MA_HASIZE, 0);
+ }
+ if(event==3 || event==10) {
+ insertkey(id, ID_MA, NULL, NULL, MA_MODE, 0);
+ }
+ if(event==10) {
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC_R, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC_G, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC_B, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_REF, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_EMIT, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_AMB, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_SPEC, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_HARD, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_MODE, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_TRANSLU, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_ADD, 0);
+ }
+ if(event==14) {
+ insertkey(id, ID_MA, NULL, NULL, MA_RAYM, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESMIR, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESMIRI, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESTRA, 0);
+ insertkey(id, ID_MA, NULL, NULL, MA_FRESTRAI, 0);
+ }
+ if(event==12 || event==11) {
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_OFS_Z, 0);
+ }
+ if(event==13 || event==11) {
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_SIZE_Z, 0);
+ }
+ if(event==11) {
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_R, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_G, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_B, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_DVAR, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_COLF, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_NORF, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_VARF, 0);
+ insertkey(id, ID_MA, NULL, NULL, map+MAP_DISP, 0);
+ }
+ }
+ }
+ else if(tab==TAB_SHADING_WORLD) {
+ id= G.buts->lockpoin;
+ wo= G.buts->lockpoin;
+ if(id) {
+ event= pupmenu("Insert Key %t|Zenith RGB%x0|Horizon RGB%x1|Mist%x2|Stars %x3|Offset%x12|Size%x13");
+ if(event== -1) return;
+
+ map= texchannel_to_adrcode(wo->texact);
+
+ if(event==0) {
+ insertkey(id, ID_WO, NULL, NULL, WO_ZEN_R, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_ZEN_G, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_ZEN_B, 0);
+ }
+ if(event==1) {
+ insertkey(id, ID_WO, NULL, NULL, WO_HOR_R, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_HOR_G, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_HOR_B, 0);
+ }
+ if(event==2) {
+ insertkey(id, ID_WO, NULL, NULL, WO_MISI, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISTDI, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISTSTA, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_MISTHI, 0);
+ }
+ if(event==3) {
+ insertkey(id, ID_WO, NULL, NULL, WO_STAR_R, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STAR_G, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STAR_B, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STARDIST, 0);
+ insertkey(id, ID_WO, NULL, NULL, WO_STARSIZE, 0);
+ }
+ if(event==12) {
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_OFS_Z, 0);
+ }
+ if(event==13) {
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey(id, ID_WO, NULL, NULL, map+MAP_SIZE_Z, 0);
+ }
+ }
+ }
+ else if(tab==TAB_SHADING_LAMP) {
+ id= G.buts->lockpoin;
+ la= G.buts->lockpoin;
+ if(id) {
+ event= pupmenu("Insert Key %t|RGB%x0|Energy%x1|Spot Size%x2|Offset%x12|Size%x13");
+ if(event== -1) return;
+
+ map= texchannel_to_adrcode(la->texact);
+
+ if(event==0) {
+ insertkey(id, ID_LA, NULL, NULL, LA_COL_R, 0);
+ insertkey(id, ID_LA, NULL, NULL, LA_COL_G, 0);
+ insertkey(id, ID_LA, NULL, NULL, LA_COL_B, 0);
+ }
+ if(event==1) {
+ insertkey(id, ID_LA, NULL, NULL, LA_ENERGY, 0);
+ }
+ if(event==2) {
+ insertkey(id, ID_LA, NULL, NULL, LA_SPOTSI, 0);
+ }
+ if(event==12) {
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_X, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Y, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_OFS_Z, 0);
+ }
+ if(event==13) {
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_X, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Y, 0);
+ insertkey(id, ID_LA, NULL, NULL, map+MAP_SIZE_Z, 0);
+ }
+
+ }
+ }
+ else if(tab==TAB_SHADING_TEX) {
+ id= G.buts->lockpoin;
+ te= G.buts->lockpoin;
+ if(id) {
+ event= pupmenu("Insert Key %t|Clouds%x0|Marble%x1|Stucci%x2|Wood%x3|Magic%x4|Blend%x5|Musgrave%x6|Voronoi%x7|DistortedNoise%x8|ColorFilter%x9");
+ if(event== -1) return;
+
+ if(event==0) {
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
+ }
+ if(event==1) {
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2, 0);
+ }
+ if(event==2) {
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
+ }
+ if(event==3) {
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NTYPE, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS1, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_N_BAS2, 0);
+ }
+ if(event==4) {
+ insertkey(id, ID_TE, NULL, NULL, TE_NDEPTH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_TURB, 0);
+ }
+ if(event==5) {
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ }
+ if(event==6) {
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_TYP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MGH, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_LAC, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN, 0);
+ }
+ if(event==7) {
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW1, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW2, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW3, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNW4, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VNMEXP, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VN_DISTM, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_VN_COLT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_ISCA, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_NSIZE, 0);
+ }
+ if(event==8) {
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OCT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_OFF, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_MG_GAIN, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_DISTA, 0);
+ }
+ if(event==9) {
+ insertkey(id, ID_TE, NULL, NULL, TE_COL_R, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_COL_G, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_COL_B, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_BRIGHT, 0);
+ insertkey(id, ID_TE, NULL, NULL, TE_CONTRA, 0);
+ }
+ }
+ }
+ }
+ else if(G.buts->mainb==CONTEXT_OBJECT) {
+ ob= OBACT;
+ if(ob) {
+ id= (ID *) (ob);
+ if(id) {
+ if(ob->type==OB_MESH)
+ event= pupmenu("Insert Key %t|Surface Damping%x0|Random Damping%x1|Permeability%x2|Force Strength%x3|Force Falloff%x4");
+ else
+ event= pupmenu("Insert Key %t|Force Strength%x3|Force Falloff%x4");
+ if(event == -1) return;
+
+ if(event==0) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_SDAMP, 0);
+ }
+ if(event==1) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_RDAMP, 0);
+ }
+ if(event==2) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_PERM, 0);
+ }
+ if(event==3) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_FSTR, 0);
+ }
+ if(event==4) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_FFALL, 0);
+ }
+ if(event==5) {
+ insertkey(id, ID_OB, NULL, NULL, OB_PD_FMAXD, 0);
+ }
+ }
+ }
+ }
+ else if(G.buts->mainb==CONTEXT_EDITING) {
+ ob= OBACT;
+ if(ob && ob->type==OB_CAMERA) {
+ id= G.buts->lockpoin;
+ if(id) {
+ /* yafray: insert key extended with aperture and focal distance */
+ /* qdn: FocalDistance now enabled for Blender as wel, for use with defocus node */
+ if (G.scene->r.renderer==R_INTERN)
+ event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1|FocalDistance%x3|Viewplane Shift%x4");
+ else
+ event= pupmenu("Insert Key %t|Lens%x0|Clipping%x1|Aperture%x2|FocalDistance%x3");
+ if(event== -1) return;
+
+ if(event==0) {
+ insertkey(id, ID_CA, NULL, NULL, CAM_LENS, 0);
+ }
+ else if(event==1) {
+ insertkey(id, ID_CA, NULL, NULL, CAM_STA, 0);
+ insertkey(id, ID_CA, NULL, NULL, CAM_END, 0);
+ }
+ else if(event==2) {
+ insertkey(id, ID_CA, NULL, NULL, CAM_YF_APERT, 0);
+ }
+ else if(event==3) {
+ insertkey(id, ID_CA, NULL, NULL, CAM_YF_FDIST, 0);
+ }
+ else if(event==4) {
+ insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_X, 0);
+ insertkey(id, ID_CA, NULL, NULL, CAM_SHIFT_Y, 0);
+ }
+ }
+ }
+ }
+ else if(FALSE /* && 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, ID_SO, NULL, NULL, SND_VOLUME, 0);
+ }
+ if(event==1) {
+ insertkey(id, ID_SO, NULL, NULL, SND_PITCH, 0);
+ }
+ if(event==2) {
+ insertkey(id, ID_SO, NULL, NULL, SND_PANNING, 0);
+ }
+ if(event==3) {
+ insertkey(id, ID_SO, NULL, NULL, SND_ATTEN, 0);
+ }
+ }
+ }
+ }
+
+ BIF_undo_push("Insert Key Buttons");
+
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWIPO, 0);
+ allspace(REMAKEIPO, 0);
+
+ }
+ else if(curarea->spacetype==SPACE_VIEW3D) {
+ ob= OBACT;
+
+ if (ob && (ob->flag & OB_POSEMODE)) {
+ bPoseChannel *pchan;
+
+ set_pose_keys(ob); /* sets pchan->flag to POSE_KEY if bone selected, and clears if not */
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next)
+ if (pchan->flag & POSE_KEY)
+ break;
+ if(pchan==NULL) return;
+ strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Scale%x2|LocRot%x3|LocRotScale%x4|Avail%x9|Needed%x15|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13");
+ }
+ else {
+ base= FIRSTBASE;
+ while(base) {
+ if (TESTBASELIB(base)) break;
+ base= base->next;
+ }
+ if(base==NULL) return;
+ strcpy(menustr, "Insert Key%t|Loc%x0|Rot%x1|Scale%x2|LocRot%x3|LocRotScale%x4|Layer%x5|Avail%x9|Needed%x15|VisualLoc%x11|VisualRot%x12|VisualLocRot%x13");
+ }
+
+ if(ob) {
+ 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");
+ }
+
+ event= pupmenu(menustr);
+ if(event== -1) return;
+
+ if(event==7) { // ob != NULL
+ insert_shapekey(ob);
+ return;
+ }
+
+ if (ob && (ob->flag & OB_POSEMODE)){
+ bPoseChannel *pchan;
+ short recalc_bonepaths= 0;
+
+ if (ob->action && ob->action->id.lib) {
+ error ("Can't key libactions");
+ return;
+ }
+
+ id= &ob->id;
+ for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+ if (pchan->flag & POSE_KEY) {
+ /* insert relevant keyframes */
+ if(event==0 || event==3 ||event==4) {
+ insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
+ }
+ if(event==1 || event==3 || event==4) {
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
+ }
+ if(event==2 || event==4) {
+ insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_X, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Y, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_SIZE_Z, 0);
+ }
+ if (event==9 && ob->action) {
+ bActionChannel *achan;
+
+ for (achan = ob->action->chanbase.first; achan; achan=achan->next){
+ if (achan->ipo && !strcmp (achan->name, pchan->name)){
+ for (icu = achan->ipo->curve.first; icu; icu=icu->next){
+ insertkey(id, ID_PO, achan->name, NULL, icu->adrcode, 0);
+ }
+ break;
+ }
+ }
+ }
+ if(event==11 || event==13) {
+ int matok=0;
+ /* check one to make sure we're not trying to set visual loc keys on
+ bones inside of a chain, which only leads to tears. */
+ matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_X);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z);
+
+ if (matok == 0) {
+ insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_X, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Y, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_LOC_Z, 0);
+ }
+ }
+ if(event==12 || event==13) {
+ int matok=0;
+ /* check one to make sure we're not trying to set visual rot keys on
+ bones inside of a chain, which only leads to tears. */
+ matok= insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y);
+ insertmatrixkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z);
+
+ if (matok == 0) {
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_W, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_X, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Y, 0);
+ insertkey(id, ID_PO, pchan->name, NULL, AC_QUAT_Z, 0);
+ }
+ }
+ if (event==15 && ob->action) {
+ bActionChannel *achan;
+
+ for (achan = ob->action->chanbase.first; achan; achan=achan->next){
+ if (achan->ipo && !strcmp (achan->name, pchan->name)){
+ for (icu = achan->ipo->curve.first; icu; icu=icu->next){
+ insertkey_smarter(id, ID_PO, achan->name, NULL, icu->adrcode);
+ }
+ break;
+ }
+ }
+ }
+
+ /* clear unkeyed flag (it doesn't matter if it's set or not) */
+ if (pchan->bone)
+ pchan->bone->flag &= ~BONE_UNKEYED;
+
+ /* check if bone has a path */
+ if (pchan->path)
+ recalc_bonepaths = 1;
+ }
+ }
+
+ /* recalculate ipo handles, etc. */
+ if(ob->action)
+ remake_action_ipos(ob->action);
+
+ /* recalculate bone-paths on adding new keyframe? */
+ // TODO: currently, there is no setting to turn this on/off globally
+ if (recalc_bonepaths)
+ pose_recalculate_paths(ob);
+
+
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ }
+ else {
+ base= FIRSTBASE;
+ while(base) {
+ if (TESTBASELIB(base)) {
+ char *actname= NULL;
+
+ id= (ID *)(base->object);
+
+ if(base->object->ipoflag & OB_ACTION_OB)
+ actname= "Object";
+
+ /* all curves in ipo deselect */
+ if(base->object->ipo || base->object->action) {
+ if (base->object->ipo) {
+ icu= base->object->ipo->curve.first;
+ }
+ else {
+ bActionChannel *achan;
+ achan= get_action_channel(base->object->action, actname);
+
+ if (achan && achan->ipo)
+ icu= achan->ipo->curve.first;
+ else
+ icu= NULL;
+ }
+
+ while(icu) {
+ icu->flag &= ~IPO_SELECT;
+
+ switch (event) {
+ case 9:
+ insertkey(id, ID_OB, actname, NULL, icu->adrcode, 0);
+ break;
+ case 15:
+ insertkey_smarter(id, ID_OB, actname, NULL, icu->adrcode);
+ break;
+ }
+ icu= icu->next;
+ }
+ }
+
+ if(event==0 || event==3 ||event==4) {
+ insertkey(id, ID_OB, actname, NULL, OB_LOC_X, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_LOC_Y, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_LOC_Z, 0);
+ }
+ if(event==1 || event==3 ||event==4) {
+ insertkey(id, ID_OB, actname, NULL, OB_ROT_X, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_ROT_Y, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_ROT_Z, 0);
+ }
+ if(event==2 || event==4) {
+ insertkey(id, ID_OB, actname, NULL, OB_SIZE_X, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_SIZE_Y, 0);
+ insertkey(id, ID_OB, actname, NULL, OB_SIZE_Z, 0);
+ }
+ if(event==5) {
+ /* remove localview */
+ tlay= base->object->lay;
+ base->object->lay &= 0xFFFFFF;
+ insertkey(id, ID_OB, actname, NULL, OB_LAY, 0);
+ base->object->lay= tlay;
+ }
+ if(event==11 || event==13) {
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_X);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Y);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_LOC_Z);
+ }
+ if(event==12 || event==13) {
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_X);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Y);
+ insertmatrixkey(id, ID_OB, actname, NULL, OB_ROT_Z);
+ }
+ base->object->recalc |= OB_RECALC_OB;
+ }
+ base= base->next;
+ }
+ }
+
+ if(event==0) BIF_undo_push("Insert Loc Key");
+ else if(event==1) BIF_undo_push("Insert Rot Key");
+ else if(event==2) BIF_undo_push("Insert Scale Key");
+ else if(event==3) BIF_undo_push("Insert LocRot Key");
+ else if(event==4) BIF_undo_push("Insert LocRotScale Key");
+ else if(event==5) BIF_undo_push("Insert Layer Key");
+ else if(event==7) BIF_undo_push("Insert Vertex Key");
+ else if(event==9) BIF_undo_push("Insert Avail Key");
+ else if(event==11) BIF_undo_push("Insert VisualLoc Key");
+ else if(event==12) BIF_undo_push("Insert VisualRot Key");
+ else if(event==13) BIF_undo_push("Insert VisualLocRot Key");
+ else if(event==15) BIF_undo_push("Insert Needed Key");
+
+ DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
+
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ }
+
+}
+
/* ****************************************************************************** */
void add_duplicate_editipo(void)
@@ -2375,7 +3651,6 @@ void remove_doubles_ipo(void)
}
deselectall_editipo();
- BIF_undo_push("Remove Doubles (IPO)");
}
@@ -3198,7 +4473,7 @@ void paste_editipo(void)
int i;
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
- ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode, 1);
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
if (ei->icu == NULL) return;
/* Copy selected beztriples from source icu onto this edit-icu,
@@ -3239,7 +4514,7 @@ void paste_editipo(void)
else {
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
- ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode, 1);
+ ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
if (ei->icu==NULL) return;
/* clear exisiting dynamic memory (keyframes, driver) */
@@ -4354,7 +5629,7 @@ void ipo_record(void)
/* make curves ready, start values */
if(ei1->icu==NULL)
- ei1->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei1->adrcode, 1);
+ ei1->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei1->adrcode);
if(ei1->icu==NULL) return;
poin= get_ipo_poin(G.sipo->from, ei1->icu, &type);
@@ -4364,7 +5639,7 @@ void ipo_record(void)
if(ei2) {
if(ei2->icu==NULL)
- ei2->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei2->adrcode, 1);
+ ei2->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei2->adrcode);
if(ei2->icu==NULL) return;
poin= get_ipo_poin(G.sipo->from, ei2->icu, &type);