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:
-rw-r--r--source/blender/blenkernel/BKE_ipo.h6
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c39
-rw-r--r--source/blender/blenkernel/intern/ipo.c164
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/object.c39
-rw-r--r--source/blender/blenloader/intern/readfile.c7
-rw-r--r--source/blender/blenloader/intern/writefile.c1
-rw-r--r--source/blender/include/BSE_editipo.h2
-rw-r--r--source/blender/makesdna/DNA_curve_types.h8
-rw-r--r--source/blender/makesdna/DNA_ipo_types.h1
-rw-r--r--source/blender/render/intern/source/renderPreAndPost.c6
-rw-r--r--source/blender/src/buttons_shading.c2
-rw-r--r--source/blender/src/drawipo.c213
-rw-r--r--source/blender/src/editipo.c429
-rw-r--r--source/blender/src/editobject.c17
-rw-r--r--source/blender/src/header_ipo.c22
-rw-r--r--source/blender/src/interface.c35
18 files changed, 766 insertions, 229 deletions
diff --git a/source/blender/blenkernel/BKE_ipo.h b/source/blender/blenkernel/BKE_ipo.h
index c0a5be27bcf..6acbceb8e3f 100644
--- a/source/blender/blenkernel/BKE_ipo.h
+++ b/source/blender/blenkernel/BKE_ipo.h
@@ -52,7 +52,10 @@ struct ID;
/* struct IPO_Channel; */
float frame_to_float(int cfra);
+
+void free_ipo_curve(struct IpoCurve *icu);
void free_ipo(struct Ipo *ipo);
+
struct Ipo *add_ipo(char *name, int idcode);
struct Ipo *copy_ipo(struct Ipo *ipo);
void make_local_obipo(struct Ipo *ipo);
@@ -79,11 +82,14 @@ void *give_mtex_poin(struct MTex *mtex, int adrcode );
void *get_ipo_poin(struct ID *id, struct IpoCurve *icu, int *type);
void set_icu_vars(struct IpoCurve *icu);
void execute_ipo(struct ID *id, struct Ipo *ipo);
+
void do_ipo_nocalc(struct Ipo *ipo);
void do_ipo(struct Ipo *ipo);
void do_mat_ipo(struct Material *ma);
void do_ob_ipo(struct Object *ob);
void do_seq_ipo(struct Sequence *seq);
+void do_ob_ipodrivers(struct Object *ob, struct Ipo *ipo);
+
int has_ipo_code(struct Ipo *ipo, int code);
void do_all_data_ipos(void);
int calc_ipo_spec(struct Ipo *ipo, int adrcode, float *ctime);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 9c06c2d015d..6fd3cbcfd8b 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -756,7 +756,7 @@ short get_constraint_target_matrix (bConstraint *con, short ownertype, void* own
if(data->subtarget[0]) {
pchan = get_pose_channel(data->tar->pose, data->subtarget);
if (pchan) {
- float arm_mat[3][3], pose_mat[3][3];
+ float arm_mat[3][3], pose_mat[3][3]; /* arm mat should be bone mat! bug... */
Mat3CpyMat4(arm_mat, pchan->bone->arm_mat);
Mat3CpyMat4(pose_mat, pchan->pose_mat);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 61a0ea20a2e..45c9d0b874e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -47,6 +47,7 @@
#include "DNA_ID.h"
#include "DNA_effect_types.h"
#include "DNA_lattice_types.h"
+#include "DNA_key_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
@@ -289,6 +290,23 @@ DagForest * dag_init()
return forest;
}
+static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int isdata)
+{
+ IpoCurve *icu;
+ DagNode *node1;
+
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver && icu->driver->ob) {
+ node1 = dag_get_node(dag, icu->driver->ob);
+ if(icu->driver->blocktype==ID_AR)
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_DATA_DATA:DAG_RL_DATA_OB);
+ else
+ dag_add_relation(dag, node1, node, isdata?DAG_RL_OB_DATA:DAG_RL_OB_OB);
+ }
+ }
+}
+
+
struct DagForest *build_dag(struct Scene *sce, short mask)
{
Base *base;
@@ -300,6 +318,7 @@ struct DagForest *build_dag(struct Scene *sce, short mask)
DagNode * scenenode;
DagForest *dag;
DagAdjList *itA;
+ Key *key;
dag = sce->theDag;
sce->dagisvalid=1;
@@ -324,9 +343,8 @@ struct DagForest *build_dag(struct Scene *sce, short mask)
dag_add_relation(dag,node,node2,DAG_RL_DATA);
node2->first_ancestor = ob;
node2->ancestor_count += 1;
-
-
}
+
if (ob->type == OB_ARMATURE) {
if (ob->pose){
bPoseChannel *pchan;
@@ -354,6 +372,23 @@ struct DagForest *build_dag(struct Scene *sce, short mask)
}
}
}
+
+ /* driver dependencies */
+ if(ob->ipo)
+ dag_add_driver_relation(ob->ipo, dag, node, 0);
+
+ key= ob_get_key(ob);
+ if(key && key->ipo)
+ dag_add_driver_relation(key->ipo, dag, node, 1);
+
+ if(ob->action) {
+ bActionChannel *chan;
+ for (chan = ob->action->chanbase.first; chan; chan=chan->next){
+ if(chan->ipo)
+ dag_add_driver_relation(chan->ipo, dag, node, 1);
+ }
+ }
+
if (ob->modifiers.first) {
ModifierData *md;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index ece3e39ae1e..36f461feaf2 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_action_types.h"
+#include "DNA_armature_types.h"
#include "DNA_curve_types.h"
#include "DNA_camera_types.h"
#include "DNA_lamp_types.h"
@@ -184,17 +185,24 @@ float frame_to_float(int cfra) /* see also bsystem_time in object.c */
return ctime;
}
+/* includes ipo curve itself */
+void free_ipo_curve(IpoCurve *icu)
+{
+ if(icu->bezt) MEM_freeN(icu->bezt);
+ if(icu->bp) MEM_freeN(icu->bp);
+ if(icu->driver) MEM_freeN(icu->driver);
+ MEM_freeN(icu);
+}
+
/* do not free ipo itself */
void free_ipo(Ipo *ipo)
{
IpoCurve *icu;
- icu= ipo->curve.first;
- while(icu) {
- if(icu->bezt) MEM_freeN(icu->bezt);
- icu= icu->next;
+ while( (icu= ipo->curve.first) ) {
+ BLI_remlink(&ipo->curve, icu);
+ free_ipo_curve(icu);
}
- BLI_freelistN(&ipo->curve);
}
Ipo *add_ipo(char *name, int idcode)
@@ -212,7 +220,7 @@ Ipo *copy_ipo(Ipo *ipo)
Ipo *ipon;
IpoCurve *icu;
- if(ipo==0) return 0;
+ if(ipo==NULL) return 0;
ipon= copy_libblock(ipo);
@@ -221,6 +229,7 @@ Ipo *copy_ipo(Ipo *ipo)
icu= ipon->curve.first;
while(icu) {
icu->bezt= MEM_dupallocN(icu->bezt);
+ if(icu->driver) icu->driver= MEM_dupallocN(icu->driver);
icu= icu->next;
}
@@ -247,7 +256,7 @@ void make_local_obipo(Ipo *ipo)
ob= ob->id.next;
}
- if(local && lib==0) {
+ if(local && lib==NULL) {
ipo->id.lib= 0;
ipo->id.flag= LIB_LOCAL;
new_id(0, (ID *)ipo, 0);
@@ -260,7 +269,7 @@ void make_local_obipo(Ipo *ipo)
while(ob) {
if(ob->ipo==ipo) {
- if(ob->id.lib==0) {
+ if(ob->id.lib==NULL) {
ob->ipo= ipon;
ipon->id.us++;
ipo->id.us--;
@@ -291,7 +300,7 @@ void make_local_matipo(Ipo *ipo)
ma= ma->id.next;
}
- if(local && lib==0) {
+ if(local && lib==NULL) {
ipo->id.lib= 0;
ipo->id.flag= LIB_LOCAL;
new_id(0, (ID *)ipo, 0);
@@ -304,7 +313,7 @@ void make_local_matipo(Ipo *ipo)
while(ma) {
if(ma->ipo==ipo) {
- if(ma->id.lib==0) {
+ if(ma->id.lib==NULL) {
ma->ipo= ipon;
ipon->id.us++;
ipo->id.us--;
@@ -335,7 +344,7 @@ void make_local_keyipo(Ipo *ipo)
key= key->id.next;
}
- if(local && lib==0) {
+ if(local && lib==NULL) {
ipo->id.lib= 0;
ipo->id.flag= LIB_LOCAL;
new_id(0, (ID *)ipo, 0);
@@ -348,7 +357,7 @@ void make_local_keyipo(Ipo *ipo)
while(key) {
if(key->ipo==ipo) {
- if(key->id.lib==0) {
+ if(key->id.lib==NULL) {
key->ipo= ipon;
ipon->id.us++;
ipo->id.us--;
@@ -363,7 +372,7 @@ void make_local_keyipo(Ipo *ipo)
void make_local_ipo(Ipo *ipo)
{
- if(ipo->id.lib==0) return;
+ if(ipo->id.lib==NULL) return;
if(ipo->id.us==1) {
ipo->id.lib= 0;
ipo->id.flag= LIB_LOCAL;
@@ -443,7 +452,7 @@ void testhandles_ipocurve(IpoCurve *icu)
int flag, a;
bezt= icu->bezt;
- if(bezt==0) return;
+ if(bezt==NULL) return;
a= icu->totvert;
while(a--) {
@@ -675,6 +684,86 @@ void berekenx(float *f, float *o, int b)
}
}
+static float eval_driver(IpoDriver *driver)
+{
+ Object *ob= driver->ob;
+
+ if(ob==NULL) return 0.0f;
+
+ if(driver->blocktype==ID_OB) {
+ switch(driver->adrcode) {
+ case OB_LOC_X:
+ return ob->loc[0];
+ case OB_LOC_Y:
+ return ob->loc[1];
+ case OB_LOC_Z:
+ return ob->loc[2];
+ case OB_ROT_X:
+ return ob->rot[0]/(M_PI_2/9.0);
+ case OB_ROT_Y:
+ return ob->rot[1]/(M_PI_2/9.0);
+ case OB_ROT_Z:
+ return ob->rot[2]/(M_PI_2/9.0);
+ case OB_SIZE_X:
+ return ob->size[0];
+ case OB_SIZE_Y:
+ return ob->size[1];
+ case OB_SIZE_Z:
+ return ob->size[2];
+ }
+ }
+ else { /* ID_AR */
+ bPoseChannel *pchan= get_pose_channel(ob->pose, driver->name);
+ if(pchan && pchan->bone) {
+ float pose_mat[3][3];
+ float diff_mat[3][3], par_mat[3][3], ipar_mat[3][3];
+ float eul[3], size[3];
+
+ /* we need the local transform = current transform - (parent transform + bone transform) */
+
+ Mat3CpyMat4(pose_mat, pchan->pose_mat);
+
+ if (pchan->parent) {
+ Mat3CpyMat4(par_mat, pchan->parent->pose_mat);
+ Mat3MulMat3(diff_mat, par_mat, pchan->bone->bone_mat);
+
+ Mat3Inv(ipar_mat, diff_mat);
+ }
+ else {
+ Mat3Inv(ipar_mat, pchan->bone->bone_mat);
+ }
+
+ Mat3MulMat3(diff_mat, ipar_mat, pose_mat);
+
+ Mat3ToEul(diff_mat, eul);
+ Mat3ToSize(diff_mat, size);
+
+ switch(driver->adrcode) {
+ case OB_LOC_X:
+ return pchan->loc[0];
+ case OB_LOC_Y:
+ return pchan->loc[1];
+ case OB_LOC_Z:
+ return pchan->loc[2];
+ case OB_ROT_X:
+ return eul[0]/(M_PI_2/9.0);
+ case OB_ROT_Y:
+ return eul[1]/(M_PI_2/9.0);
+ case OB_ROT_Z:
+ return eul[2]/(M_PI_2/9.0);
+ case OB_SIZE_X:
+ return size[0];
+ case OB_SIZE_Y:
+ return size[1];
+ case OB_SIZE_Z:
+ return size[2];
+ }
+ }
+ }
+
+ return 0.0f;
+}
+
float eval_icu(IpoCurve *icu, float ipotime)
{
BezTriple *bezt, *prevbezt;
@@ -684,6 +773,10 @@ float eval_icu(IpoCurve *icu, float ipotime)
cycyofs= 0.0;
+ if(icu->driver) {
+ /* ipotime now serves as input for the curve */
+ ipotime= cvalue= eval_driver(icu->driver);
+ }
if(icu->bezt) {
prevbezt= icu->bezt;
bezt= prevbezt+1;
@@ -814,10 +907,12 @@ void calc_ipo(Ipo *ipo, float ctime)
{
IpoCurve *icu;
+ if(ipo==NULL) return;
+
icu= ipo->curve.first;
while(icu) {
- if( (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime);
+ if(icu->driver || (icu->flag & IPO_LOCK)==0) calc_icu(icu, ctime);
icu= icu->next;
}
@@ -1186,7 +1281,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
poin= &(ma->add); break;
}
- if(poin==0) {
+ if(poin==NULL) {
mtex= 0;
if(icu->adrcode & MA_MAP1) mtex= ma->mtex[0];
else if(icu->adrcode & MA_MAP2) mtex= ma->mtex[1];
@@ -1270,7 +1365,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
poin= &(wo->starsize); break;
}
- if(poin==0) {
+ if(poin==NULL) {
mtex= 0;
if(icu->adrcode & MA_MAP1) mtex= wo->mtex[0];
else if(icu->adrcode & MA_MAP2) mtex= wo->mtex[1];
@@ -1315,7 +1410,7 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
poin= &(la->haint); break;
}
- if(poin==0) {
+ if(poin==NULL) {
mtex= 0;
if(icu->adrcode & MA_MAP1) mtex= la->mtex[0];
else if(icu->adrcode & MA_MAP2) mtex= la->mtex[1];
@@ -1650,7 +1745,7 @@ void execute_ipo(ID *id, Ipo *ipo)
void *poin;
int type;
- if(ipo==0) return;
+ if(ipo==NULL) return;
icu= ipo->curve.first;
while(icu) {
@@ -1673,7 +1768,7 @@ void do_ipo_nocalc(Ipo *ipo)
Camera *ca;
bSound *snd;
- if(ipo==0) return;
+ if(ipo==NULL) return;
switch(ipo->blocktype) {
case ID_OB:
@@ -1747,7 +1842,7 @@ void do_mat_ipo(Material *ma)
{
float ctime;
- if(ma==0 || ma->ipo==0) return;
+ if(ma==NULL || ma->ipo==NULL) return;
ctime= frame_to_float(G.scene->r.cfra);
/* if(ob->ipoflag & OB_OFFS_OB) ctime-= ob->sf; */
@@ -1762,7 +1857,7 @@ void do_ob_ipo(Object *ob)
float ctime;
unsigned int lay;
- if(ob->ipo==0) return;
+ if(ob->ipo==NULL) return;
/* do not set ob->ctime here: for example when parent in invisible layer */
@@ -1785,6 +1880,21 @@ void do_ob_ipo(Object *ob)
}
}
+void do_ob_ipodrivers(Object *ob, Ipo *ipo)
+{
+ IpoCurve *icu;
+ void *poin;
+ int type;
+
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver) {
+ icu->curval= eval_icu(icu, 0.0f);
+ poin= get_ipo_poin((ID *)ob, icu, &type);
+ if(poin) write_ipo_poin(poin, type, icu->curval);
+ }
+ }
+}
+
void do_seq_ipo(Sequence *seq)
{
float ctime, div;
@@ -1794,7 +1904,7 @@ void do_seq_ipo(Sequence *seq)
if(seq->ipo) {
ctime= frame_to_float(G.scene->r.cfra - seq->startdisp);
div= (seq->enddisp - seq->startdisp)/100.0f;
- if(div==0) return;
+ if(div==0.0) return;
/* 2nd field */
calc_ipo(seq->ipo, (ctime+0.5f)/div);
@@ -1813,7 +1923,7 @@ int has_ipo_code(Ipo *ipo, int code)
{
IpoCurve *icu;
- if(ipo==0) return 0;
+ if(ipo==NULL) return 0;
icu= ipo->curve.first;
while(icu) {
@@ -1924,7 +2034,7 @@ int calc_ipo_spec(Ipo *ipo, int adrcode, float *ctime)
{
IpoCurve *icu;
- if(ipo==0) return 0;
+ if(ipo==NULL) return 0;
icu= ipo->curve.first;
while(icu) {
@@ -1948,11 +2058,11 @@ void clear_delta_obipo(Ipo *ipo)
{
Object *ob;
- if(ipo==0) return;
+ if(ipo==NULL) return;
ob= G.main->object.first;
while(ob) {
- if(ob->id.lib==0) {
+ if(ob->id.lib==NULL) {
if(ob->ipo==ipo) {
memset(&ob->dloc, 0, 12);
memset(&ob->drot, 0, 12);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index c32874f69c5..d0c0b1f9927 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -935,6 +935,8 @@ static int do_mesh_key(Mesh *me)
else {
ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0);
+ calc_ipo(me->key->ipo, ctime); /* also all relative key positions */
+
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 29bfff8bc66..aa8efe61565 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -237,6 +237,7 @@ void unlink_object(Object *ob)
Scene *sce;
Curve *cu;
Tex *tex;
+ Ipo *ipo;
Group *group;
bConstraint *con;
int a;
@@ -308,7 +309,7 @@ void unlink_object(Object *ob)
for(a=0; a<MAX_MTEX; a++) {
if(mat->mtex[a] && ob==mat->mtex[a]->object) {
/* actually, test for lib here... to do */
- mat->mtex[a]->object= 0;
+ mat->mtex[a]->object= NULL;
}
}
@@ -319,7 +320,7 @@ void unlink_object(Object *ob)
tex= G.main->tex.first;
while(tex) {
if(tex->env) {
- if(tex->env->object == ob) tex->env->object= 0;
+ if(tex->env->object == ob) tex->env->object= NULL;
}
tex= tex->id.next;
}
@@ -333,10 +334,10 @@ void unlink_object(Object *ob)
/* worlds */
wrld= G.main->world.first;
while(wrld) {
- if(wrld->id.lib==0) {
+ if(wrld->id.lib==NULL) {
for(a=0; a<MAX_MTEX; a++) {
if(wrld->mtex[a] && ob==wrld->mtex[a]->object)
- wrld->mtex[a]->object =0;
+ wrld->mtex[a]->object= NULL;
}
}
@@ -346,12 +347,23 @@ void unlink_object(Object *ob)
/* scenes */
sce= G.main->scene.first;
while(sce) {
- if(sce->id.lib==0) {
- if(sce->camera==ob) sce->camera= 0;
+ if(sce->id.lib==NULL) {
+ if(sce->camera==ob) sce->camera= NULL;
}
sce= sce->id.next;
}
- /* keys */
+ /* ipos */
+ ipo= G.main->ipo.first;
+ while(ipo) {
+ if(ipo->id.lib==NULL) {
+ IpoCurve *icu;
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver && icu->driver->ob==ob)
+ icu->driver->ob= NULL;
+ }
+ }
+ ipo= ipo->id.next;
+ }
/* screens */
sc= G.main->screen.first;
@@ -365,11 +377,11 @@ void unlink_object(Object *ob)
View3D *v3d= (View3D*) sl;
if(v3d->camera==ob) {
- v3d->camera= 0;
+ v3d->camera= NULL;
if(v3d->persp>1) v3d->persp= 1;
}
if(v3d->localvd && v3d->localvd->camera==ob ) {
- v3d->localvd->camera= 0;
+ v3d->localvd->camera= NULL;
if(v3d->localvd->persp>1) v3d->localvd->persp= 1;
}
}
@@ -1285,8 +1297,9 @@ void where_is_object_time(Object *ob, float ctime)
if(ob==NULL) return;
+ /* this is needed to be able to grab objects with ipos, otherwise it always freezes them */
stime= bsystem_time(ob, 0, ctime, 0.0);
- if( stime != ob->ctime) {
+ if(stime != ob->ctime) {
ob->ctime= stime;
if(ob->ipo) {
@@ -1296,7 +1309,11 @@ void where_is_object_time(Object *ob, float ctime)
/* do constraint ipos ... */
do_constraint_channels(&ob->constraints, &ob->constraintChannels, ctime);
}
-
+ else {
+ /* but, the drivers have to be done */
+ if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo);
+ }
+
if(ob->parent) {
par= ob->parent;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index da342c2f656..54b4e494169 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1707,7 +1707,11 @@ static void lib_link_ipo(FileData *fd, Main *main)
ipo= main->ipo.first;
while(ipo) {
if(ipo->id.flag & LIB_NEEDLINK) {
-
+ IpoCurve *icu;
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver)
+ icu->driver->ob= newlibadr(fd, ipo->id.lib, icu->driver->ob);
+ }
ipo->id.flag -= LIB_NEEDLINK;
}
ipo= ipo->id.next;
@@ -1723,6 +1727,7 @@ static void direct_link_ipo(FileData *fd, Ipo *ipo)
while(icu) {
icu->bezt= newdataadr(fd, icu->bezt);
icu->bp= newdataadr(fd, icu->bp);
+ icu->driver= newdataadr(fd, icu->driver);
icu= icu->next;
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index bce6dceb384..f941b5f77d2 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -770,6 +770,7 @@ static void write_ipos(WriteData *wd, ListBase *idbase)
while(icu) {
if(icu->bezt) writestruct(wd, DATA, "BezTriple", icu->totvert, icu->bezt);
if(icu->bp) writestruct(wd, DATA, "BPoint", icu->totvert, icu->bp);
+ if(icu->driver) writestruct(wd, DATA, "IpoDriver", 1, icu->driver);
icu= icu->next;
}
}
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index d96565f95b4..e0036de5eac 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -59,6 +59,8 @@ char *getname_la_ei(int nr);
char *getname_cam_ei(int nr);
char *getname_snd_ei(int nr);
+struct EditIpo *get_active_editipo(void);
+
void boundbox_ipocurve(struct IpoCurve *icu);
void boundbox_ipo(struct Ipo *ipo, struct rctf *bb);
void editipo_changed(struct SpaceIpo *si, int doredraw);
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index 5c99671dd54..2078875215f 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -171,6 +171,12 @@ typedef struct Curve {
struct CharInfo curinfo;
} Curve;
+typedef struct IpoDriver {
+ struct Object *ob;
+ short blocktype, adrcode, type, flag;
+ char name[32]; /* bone or constraint(?) name, later we can add python expression here */
+} IpoDriver;
+
typedef struct IpoCurve {
struct IpoCurve *next, *prev;
@@ -188,6 +194,8 @@ typedef struct IpoCurve {
float curval;
+ IpoDriver *driver;
+
} IpoCurve;
/* **************** CURVE ********************* */
diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h
index c658d40db79..b3cb0c81148 100644
--- a/source/blender/makesdna/DNA_ipo_types.h
+++ b/source/blender/makesdna/DNA_ipo_types.h
@@ -359,6 +359,7 @@ typedef short IPO_Channel;
#define IPO_EDIT 4
#define IPO_LOCK 8
#define IPO_AUTO_HORIZ 16
+#define IPO_ACTIVE 32
#endif
diff --git a/source/blender/render/intern/source/renderPreAndPost.c b/source/blender/render/intern/source/renderPreAndPost.c
index 0f7a98843ce..defb6b97ff6 100644
--- a/source/blender/render/intern/source/renderPreAndPost.c
+++ b/source/blender/render/intern/source/renderPreAndPost.c
@@ -70,12 +70,12 @@ void prepareScene()
/* RADIO */
if(R.r.mode & R_RADIO) do_radio_render();
- /* ENVIRONMENT MAPS */
- make_envmaps();
-
/* octree */
if(R.r.mode & R_RAYTRACE) makeoctree();
+ /* ENVIRONMENT MAPS */
+ make_envmaps();
+
}
}
diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c
index 1047c46f787..93addb8e20d 100644
--- a/source/blender/src/buttons_shading.c
+++ b/source/blender/src/buttons_shading.c
@@ -2544,7 +2544,7 @@ void do_matbuts(unsigned short event)
/* same for 'xtreme alpha' which is 'only shadow' */
ma= G.buts->lockpoin;
if((ma->mode & MA_HALO)==0) {
- ma->mode &= ~(MA_STAR|MA_HALO_XALPHA);
+ ma->mode &= ~(MA_STAR|MA_HALO_XALPHA|MA_ZINV);
}
BIF_preview_changed(G.buts);
allqueue(REDRAWBUTSSHADING, 0);
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index c18d9aba1c1..f2546d20d39 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -45,6 +45,7 @@
#endif
#include "BMF_Api.h"
+#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -786,8 +787,20 @@ void drawscroll(int disptype)
scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype);
}
}
- else {
- scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
+ else { /* space ipo */
+ EditIpo *ei= get_active_editipo();
+
+ if(ei && ei->icu && ei->icu->driver) {
+ int adrcode= ei->icu->driver->adrcode;
+
+ if(adrcode==OB_ROT_X || adrcode==OB_ROT_Y || adrcode==OB_ROT_Z) {
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'v', IPO_DISPDEGR);
+ }
+ else
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
+ }
+ else
+ scroll_prstr(fac, 3.0+(float)(hor.ymin), val, 'h', disptype);
}
fac+= dfac;
@@ -910,16 +923,17 @@ static void draw_ipobuts(SpaceIpo *sipo)
sel= ei->flag & (IPO_SELECT + IPO_EDIT);
uiEmboss((float)(v2d->mask.xmax+8), (float)(y+2), (float)(v2d->mask.xmax+15), (float)(y+IPOBUTY-2), sel);
- }
-
- if(sipo->blocktype==ID_KE) {
- Key *key= (Key *)sipo->from;
- if(key==NULL || key->type==KEY_NORMAL) break;
- if(a==ob->shapenr-1) {
+
+ if(ei->icu->driver) {
cpack(0x0);
- fdrawbox(v2d->mask.xmax+7, y+1, v2d->mask.xmax+16, y+IPOBUTY-1);
+ fdrawbox((float)v2d->mask.xmax+11, (float)y+8, (float)v2d->mask.xmax+12.5, (float)y+9.5);
}
}
+
+ if(ei->flag & IPO_ACTIVE) {
+ cpack(0x0);
+ fdrawbox(v2d->mask.xmax+7, y+1, v2d->mask.xmax+16, y+IPOBUTY-1);
+ }
}
uiDrawBlock(block);
}
@@ -1247,7 +1261,9 @@ static void draw_ipocurves(int sel)
glVertex2fv(v1);
}
else {
- resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]);
+ /* resol not depending on horizontal resolution anymore, drivers for example... */
+ if(icu->driver) resol= 32;
+ else resol= 3.0*sqrt(bezt->vec[1][0] - prevbezt->vec[1][0]);
if(resol<2) {
v1[0]= prevbezt->vec[1][0]+cycxofs;
@@ -1439,11 +1455,13 @@ static void draw_key(SpaceIpo *sipo, int visible)
#define B_MUL_IPO 3402
#define B_TRANS_IPO 3403
#define B_IPO_NONE 3404
+#define B_IPO_DRIVER 3405
+#define B_IPO_REDR 3406
+#define B_IPO_DEPCHANGE 3407
static float hspeed= 0;
-
-static void boundbox_ipo_visible(SpaceIpo *si)
+static void boundbox_ipo_curves(SpaceIpo *si)
{
EditIpo *ei;
Key *key;
@@ -1550,20 +1568,21 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m
VECCOPY(si->median, median);
+ uiBlockBeginAlign(block);
if(tot==1) {
if(iskey)
uiDefButF(block, NUM, B_TRANS_IPO, "Key Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 10, 0, "");
else {
- uiDefButF(block, NUM, B_TRANS_IPO, "Vertex X:", 10, 100, 300, 19, &(si->median[0]), min, max, 100, 0, "");
- uiDefButF(block, NUM, B_TRANS_IPO, "Vertex Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 100, 0, "");
+ uiDefButF(block, NUM, B_TRANS_IPO, "Vertex X:", 10, 100, 150, 19, &(si->median[0]), min, max, 100, 0, "");
+ uiDefButF(block, NUM, B_TRANS_IPO, "Vertex Y:", 160, 100, 150, 19, &(si->median[1]), min, max, 100, 0, "");
}
}
else {
if(iskey)
uiDefButF(block, NUM, B_TRANS_IPO, "Median Key Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 10, 0, "");
else {
- uiDefButF(block, NUM, B_TRANS_IPO, "Median X:", 10, 100, 300, 19, &(si->median[0]), min, max, 100, 0, "");
- uiDefButF(block, NUM, B_TRANS_IPO, "Median Y:", 10, 80, 300, 19, &(si->median[1]), min, max, 100, 0, "");
+ uiDefButF(block, NUM, B_TRANS_IPO, "Median X:", 10, 100, 150, 19, &(si->median[0]), min, max, 100, 0, "");
+ uiDefButF(block, NUM, B_TRANS_IPO, "Median Y:", 160, 100, 150, 19, &(si->median[1]), min, max, 100, 0, "");
}
}
}
@@ -1624,8 +1643,22 @@ static void ipo_editvertex_buts(uiBlock *block, SpaceIpo *si, float min, float m
void do_ipobuts(unsigned short event)
{
Object *ob= OBACT;
+ EditIpo *ei;
switch(event) {
+ case B_IPO_REDR:
+ ei= get_active_editipo();
+ if(ei) {
+ if(ei->icu->driver) {
+ if(G.sipo->blocktype==ID_KE || G.sipo->blocktype==ID_AC)
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+ }
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWVIEW3D, 0);
+ break;
case B_SETSPEED:
set_speed_editipo(hspeed);
break;
@@ -1645,28 +1678,167 @@ void do_ipobuts(unsigned short event)
allqueue(REDRAWIPO, 0);
allqueue(REDRAWBUTSEDIT, 0);
break;
+ case B_IPO_DRIVER:
+ ei= get_active_editipo();
+ if(ei) {
+ if(ei->icu==NULL) {
+ ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0);
+ ei->flag |= IPO_SELECT;
+ ei->icu->flag= ei->flag;
+ }
+ if(ei->icu->driver) {
+ MEM_freeN(ei->icu->driver);
+ ei->icu->driver= NULL;
+ if(ei->icu->bezt==NULL) {
+ BLI_remlink( &(G.sipo->ipo->curve), ei->icu);
+ free_ipo_curve(ei->icu);
+ ei->icu= NULL;
+ }
+ }
+ else {
+ ei->icu->driver= MEM_callocN(sizeof(IpoDriver), "ipo driver");
+ ei->icu->driver->blocktype= ID_OB;
+ ei->icu->driver->adrcode= OB_LOC_X;
+ }
+
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ DAG_scene_sort(G.scene);
+
+ BIF_undo_push("Add/Remove Ipo driver");
+ }
+ break;
+ case B_IPO_DEPCHANGE:
+ ei= get_active_editipo();
+ if(ei) {
+ if(ei->icu->driver) {
+ IpoDriver *driver= ei->icu->driver;
+
+ /* check if type is still OK */
+ if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR);
+ else driver->blocktype= ID_OB;
+
+ DAG_scene_sort(G.scene);
+
+ if(G.sipo->blocktype==ID_KE || G.sipo->blocktype==ID_AC)
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ else
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);
+ }
+ }
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ break;
+ }
+}
+
+static char *ipodriver_modeselect_pup(Object *ob)
+{
+ static char string[265];
+ char tmpstr[64];
+ char formatstring[64];
+
+ strcpy(string, "Driver type: %t");
+
+ strcpy(formatstring, "|%s %%x%d %%i%d");
+
+ if(ob) {
+ sprintf(tmpstr,formatstring,"Object",ID_OB, ICON_OBJECT);
+ strcat(string,tmpstr);
}
+ if(ob && ob->type==OB_ARMATURE) {
+ sprintf(tmpstr,formatstring,"Pose",ID_AR, ICON_POSE_DEHLT);
+ strcat(string,tmpstr);
+ }
+
+ return (string);
}
+static char *ipodriver_channelselect_pup(void)
+{
+ static char string[1024];
+ char *tmp;
+
+ strcpy(string, "Driver channel: %t");
+ tmp= string+strlen(string);
+
+ tmp+= sprintf(tmp, "|Loc X %%x%d", OB_LOC_X);
+ tmp+= sprintf(tmp, "|Loc Y %%x%d", OB_LOC_Y);
+ tmp+= sprintf(tmp, "|Loc Z %%x%d", OB_LOC_Z);
+ tmp+= sprintf(tmp, "|Rot X %%x%d", OB_ROT_X);
+ tmp+= sprintf(tmp, "|Rot Y %%x%d", OB_ROT_Y);
+ tmp+= sprintf(tmp, "|Rot Z %%x%d", OB_ROT_Z);
+ tmp+= sprintf(tmp, "|Size X %%x%d", OB_SIZE_X);
+ tmp+= sprintf(tmp, "|Size Y %%x%d", OB_SIZE_Y);
+ tmp+= sprintf(tmp, "|Size Z %%x%d", OB_SIZE_Z);
+
+ return (string);
+}
static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
{
- extern int totipo_vis; // editipo.c
+ extern int totipo_curve; // editipo.c
uiBlock *block;
+ EditIpo *ei;
+ char name[48];
block= uiNewBlock(&curarea->uiblocks, "ipo_panel_properties", UI_EMBOSS, UI_HELV, curarea->win);
uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
uiSetPanelHandler(IPO_HANDLER_PROPERTIES); // for close and esc
if(uiNewPanel(curarea, block, "Transform Properties", "Ipo", 10, 230, 318, 204)==0) return;
+ /* this is new panel height, newpanel doesnt force new size on existing panels */
+ uiNewPanelHeight(block, 204);
+
+ /* driver buttons first */
+ ei= get_active_editipo();
+ if(ei) {
+
+ sprintf(name, "Driven Channel: %s", ei->name);
+ uiDefBut(block, LABEL, 0, name, 10, 265, 200, 19, NULL, 1.0, 0.0, 0, 0, "");
+
+ if(ei->icu && ei->icu->driver) {
+ IpoDriver *driver= ei->icu->driver;
+
+ uiDefBut(block, BUT, B_IPO_DRIVER, "Remove", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Remove Driver for this Ipo Channel");
+
+ uiBlockBeginAlign(block);
+ uiDefIDPoinBut(block, test_obpoin_but, B_IPO_DEPCHANGE, "OB:", 10, 240, 150, 20, &(driver->ob), "Driver Object");
+ if(driver->ob) {
+ int icon=ICON_OBJECT;
+
+ if(driver->ob->type==OB_ARMATURE && driver->blocktype==ID_AR) {
+ icon = ICON_POSE_DEHLT;
+ uiDefBut(block, TEX, B_IPO_REDR, "BO:", 10,220,150,20, driver->name, 0, 31, 0, 0, "Bone name");
+ }
+ else driver->blocktype= ID_OB; /* safety when switching object button */
+
+ uiBlockBeginAlign(block);
+ uiDefIconTextButS(block, MENU, B_IPO_DEPCHANGE, icon,
+ ipodriver_modeselect_pup(driver->ob), 165,240,145,20, &(driver->blocktype), 0, 0, 0, 0, "Driver type");
+
+ uiDefButS(block, MENU, B_IPO_REDR,
+ ipodriver_channelselect_pup(), 165,220,145,20, &(driver->adrcode), 0, 0, 0, 0, "Driver channel");
+ }
+ uiBlockEndAlign(block);
+ }
+ else {
+ uiDefBut(block, BUT, B_IPO_DRIVER, "Add Driver", 210,265,100,19, NULL, 0.0f, 0.0f, 0, 0, "Create a Driver for this Ipo Channel");
+ }
+ }
+ else
+ uiDefBut(block, LABEL, 0, " ", 10, 265, 150, 19, NULL, 1.0, 0.0, 0, 0, "");
- boundbox_ipo_visible(G.sipo); // should not be needed... transform/draw calls should update
+ boundbox_ipo_curves(G.sipo); // should not be needed... transform/draw calls should update
/* note ranges for buttons below are idiot... we need 2 ranges, one for sliding scale, one for real clip */
- if(G.sipo->ipo && G.sipo->ipo->curve.first && totipo_vis) {
+ if(G.sipo->ipo && G.sipo->ipo->curve.first && totipo_curve) {
extern int totipo_vertsel; // editipo.c
uiDefBut(block, LABEL, 0, "Visible curves", 10, 200, 150, 19, NULL, 1.0, 0.0, 0, 0, "");
+ uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_MUL_IPO, "Xmin:", 10, 180, 150, 19, &G.sipo->tot.xmin, G.sipo->tot.xmin-1000.0, MAXFRAMEF, 100, 0, "");
uiDefButF(block, NUM, B_MUL_IPO, "Xmax:", 160, 180, 150, 19, &G.sipo->tot.xmax, G.sipo->tot.ymin-1000.0, MAXFRAMEF, 100, 0, "");
@@ -1675,7 +1847,8 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
/* SPEED BUTTON */
if(totipo_vertsel) {
- uiDefButF(block, NUM, B_IPO_NONE, "Speed:", 10,130,150,19, &hspeed, 0.0, 180.0, 1, 0, "");
+ uiBlockBeginAlign(block);
+ uiDefButF(block, NUM, B_IPO_NONE, "Speed:", 10,130,150,19, &hspeed, 0.0, 180.0, 1, 0, "");
uiDefBut(block, BUT, B_SETSPEED,"SET", 160,130,50,19, 0, 0, 0, 0, 0, "");
}
}
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 05974e251d0..a3f579db4c5 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -288,6 +288,86 @@ char *getname_snd_ei(int nr)
return ic_name_empty[0];
}
+/* tests if only one editipo is active */
+static void check_active_editipo(void)
+{
+ EditIpo *ei, *actei;
+ int a;
+
+ actei= G.sipo->editipo;
+ if(actei) {
+ for(a=0; a<G.sipo->totipo; a++, actei++) {
+ if(actei->flag & IPO_ACTIVE)
+ break;
+ }
+ if(actei==NULL) {
+ /* set visible active */
+ for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
+ if(ei->flag & IPO_VISIBLE)
+ break;
+ }
+ if(ei==NULL) ei=G.sipo->editipo;
+ ei->flag |= IPO_ACTIVE;
+ if(ei->icu) ei->icu->flag |= IPO_ACTIVE;
+ }
+ else {
+ /* make sure no others are active */
+ for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
+ if(ei!=actei) {
+ ei->flag &= ~IPO_ACTIVE;
+ if(ei->icu) ei->icu->flag &= ~IPO_ACTIVE;
+ }
+ }
+ }
+ }
+}
+
+/* sets this ei channel active */
+static void set_active_editipo(EditIpo *actei)
+{
+ EditIpo *ei;
+ int a;
+
+ for(a=0, ei=G.sipo->editipo; a<G.sipo->totipo; a++, ei++) {
+ ei->flag &= ~IPO_ACTIVE;
+ if(ei->icu) ei->icu->flag &= ~IPO_ACTIVE;
+ }
+ actei->flag |= IPO_ACTIVE;
+ if(actei->icu) actei->icu->flag |= IPO_ACTIVE;
+}
+
+EditIpo *get_active_editipo(void)
+{
+ EditIpo *ei= G.sipo->editipo;
+ int a;
+
+ for(a=0; a<G.sipo->totipo; a++, ei++)
+ if(ei->flag & IPO_ACTIVE)
+ return ei;
+
+ return NULL;
+}
+
+static void set_active_key(int index)
+{
+ if(G.sipo->blocktype==ID_KE && G.sipo->from) {
+ Key *key= (Key *)G.sipo->from;
+ KeyBlock *curkb;
+ Object *ob= OBACT;
+
+ curkb= BLI_findlink(&key->block, index-1);
+ if(curkb) {
+ ob->shapenr= index;
+ ob->shapeflag |= OB_SHAPE_TEMPLOCK;
+
+ /* calc keypos */
+ DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+ allqueue(REDRAWVIEW3D, 0);
+ allqueue(REDRAWBUTSEDIT, 0);
+ }
+ }
+}
+
void boundbox_ipocurve(IpoCurve *icu)
{
BezTriple *bezt;
@@ -484,7 +564,7 @@ void editipo_changed(SpaceIpo *si, int doredraw)
if(si->showkey) make_ipokey();
}
-void scale_editipo()
+void scale_editipo(void)
{
/* comes from buttons, scale with G.sipo->tot rect */
@@ -786,6 +866,13 @@ void make_key_editipo(SpaceIpo *si)
else if(a==0)
if(key && key->type==KEY_NORMAL)
ei->flag |= IPO_VISIBLE;
+
+ /* active ipo is tied to active shape */
+ {
+ Object *ob= OBACT;
+ if(a==ob->shapenr-1)
+ set_active_editipo(ei);
+ }
}
ei= si->editipo;
@@ -1066,7 +1153,7 @@ void make_sound_editipo(SpaceIpo *si)
}
}
-void make_editipo()
+void make_editipo(void)
{
EditIpo *ei;
Object *ob;
@@ -1213,12 +1300,12 @@ void make_editipo()
}
-void test_editipo()
+void test_editipo(void)
{
Ipo *ipo;
ID *from;
- if(G.sipo->editipo==0){
+ if(G.sipo->editipo==NULL){
make_editipo();
}
else {
@@ -1240,9 +1327,9 @@ void test_editipo()
/* ****************************************** */
-int totipo_edit, totipo_sel, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel;
+int totipo_edit, totipo_sel, totipo_curve, totipo_vis, totipo_vert, totipo_vertsel, totipo_key, totipo_keysel;
-void get_status_editipo()
+void get_status_editipo(void)
{
EditIpo *ei;
IpoKey *ik;
@@ -1250,6 +1337,7 @@ void get_status_editipo()
int a, b;
totipo_vis= 0;
+ totipo_curve= 0;
totipo_sel= 0;
totipo_edit= 0;
totipo_vert= 0;
@@ -1265,6 +1353,7 @@ void get_status_editipo()
if( ei->flag & IPO_VISIBLE ) {
totipo_vis++;
if(ei->flag & IPO_SELECT) totipo_sel++;
+ if(ei->icu && ei->icu->totvert) totipo_curve++;
if(G.sipo->showkey || (ei->flag & IPO_EDIT)) {
/* if showkey: do count the vertices (for grab) */
@@ -1302,7 +1391,8 @@ void get_status_editipo()
}
}
-void update_editipo_flags()
+/* synchronize editipo flag with icu flag and ipokey flags */
+void update_editipo_flags(void)
{
EditIpo *ei;
IpoKey *ik;
@@ -1336,7 +1426,7 @@ void update_editipo_flags()
}
}
-void set_editflag_editipo()
+void set_editflag_editipo(void)
{
EditIpo *ei;
int a; /* , tot= 0, ok= 0; */
@@ -1380,7 +1470,8 @@ void set_editflag_editipo()
scrarea_queue_winredraw(curarea);
}
-void ipo_toggle_showkey(void) {
+void ipo_toggle_showkey(void)
+{
if(G.sipo->showkey) {
G.sipo->showkey= 0;
swap_selectall_editipo(); /* sel all */
@@ -1392,7 +1483,7 @@ void ipo_toggle_showkey(void) {
BIF_undo_push("Toggle show key Ipo");
}
-void swap_selectall_editipo()
+void swap_selectall_editipo(void)
{
Object *ob;
EditIpo *ei;
@@ -1458,7 +1549,7 @@ void swap_selectall_editipo()
}
-void swap_visible_editipo()
+void swap_visible_editipo(void)
{
EditIpo *ei;
Object *ob;
@@ -1493,7 +1584,7 @@ void swap_visible_editipo()
BIF_undo_push("Swap Visible Ipo");
}
-void deselectall_editipo()
+void deselectall_editipo(void)
{
EditIpo *ei;
IpoKey *ik;
@@ -1614,7 +1705,7 @@ short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt)
}
-void move_to_frame()
+void move_to_frame(void)
{
EditIpo *ei;
BezTriple *bezt;
@@ -1667,7 +1758,7 @@ void move_to_frame()
/* handling of right-hand channel/curve buttons in ipo window */
void do_ipowin_buts(short event)
{
- EditIpo *ei = 0;
+ EditIpo *ei = NULL;
int a;
/* without shift, all other channels are made invisible */
@@ -1680,9 +1771,17 @@ void do_ipowin_buts(short event)
ei++;
}
}
+
+ /* set active */
+ if(event>=0 && event<G.sipo->totipo) {
+ ei= G.sipo->editipo; // void pointer...
+ set_active_editipo(ei+event);
+ set_active_key(event+1); // only if there's a key, of course
+ }
scrarea_queue_winredraw(curarea);
update_editipo_flags();
+ get_status_editipo();
if(G.sipo->showkey) {
make_ipokey();
@@ -1692,7 +1791,7 @@ void do_ipowin_buts(short event)
}
/* the fake buttons to the left of channel names, for select/deselect curves */
-void do_ipo_selectbuttons()
+void do_ipo_selectbuttons(void)
{
EditIpo *ei, *ei1;
int a, nr;
@@ -1714,6 +1813,9 @@ void do_ipo_selectbuttons()
ei= G.sipo->editipo;
ei+= nr;
+ set_active_editipo(ei);
+ set_active_key(nr+1);
+
if(ei->icu) {
if((ei->flag & IPO_VISIBLE)==0) {
ei->flag |= IPO_VISIBLE|IPO_SELECT;
@@ -1743,7 +1845,7 @@ void do_ipo_selectbuttons()
/* ******************************************* */
-EditIpo *get_editipo()
+EditIpo *get_editipo(void)
{
EditIpo *ei;
int a; /* , sel=0; */
@@ -1889,8 +1991,8 @@ Ipo *get_ipo(ID *from, short type, int make)
IpoCurve *get_ipocurve(ID *from, short type, int adrcode, Ipo *useipo)
{
- Ipo *ipo= 0;
- IpoCurve *icu=0;
+ Ipo *ipo= NULL;
+ IpoCurve *icu=NULL;
/* return 0 if lib */
/* also test if ipo and ipocurve exist */
@@ -1956,7 +2058,7 @@ void insert_vert_ipo(IpoCurve *icu, float x, float y)
bezt= icu->bezt;
- if(bezt==0) {
+ if(bezt==NULL) {
icu->bezt= MEM_callocN( sizeof(BezTriple), "beztriple");
*(icu->bezt)= beztr;
icu->totvert= 1;
@@ -2009,7 +2111,7 @@ void insert_vert_ipo(IpoCurve *icu, float x, float y)
}
}
-void add_vert_ipo()
+void add_vert_ipo(void)
{
EditIpo *ei;
float x, y;
@@ -2034,11 +2136,11 @@ void add_vert_ipo()
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
- if(ei->icu==0) {
+ if(ei->icu==NULL) {
if(G.sipo->from)
ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0);
}
- if(ei->icu==0) return;
+ if(ei->icu==NULL) return;
if(ei->disptype==IPO_DISPBITS) {
ei->icu->vartype= IPO_BITS;
@@ -2057,7 +2159,7 @@ void add_vert_ipo()
BIF_undo_push("Add Ipo vertex");
}
-void add_duplicate_editipo()
+void add_duplicate_editipo(void)
{
Object *ob;
EditIpo *ei;
@@ -2118,7 +2220,7 @@ void add_duplicate_editipo()
transform_ipo('g');
}
-void remove_doubles_ipo()
+void remove_doubles_ipo(void)
{
EditIpo *ei;
IpoKey *ik, *ikn;
@@ -2436,7 +2538,7 @@ void ipo_snap(short event)
-void mouse_select_ipo()
+void mouse_select_ipo(void)
{
Object *ob;
Key *key;
@@ -2555,14 +2657,8 @@ void mouse_select_ipo()
if(ok) {
/* also does all keypos */
deselectall_editipo();
-
- ob->shapenr= index;
- ob->shapeflag |= OB_SHAPE_TEMPLOCK;
-
- /* calc keypos */
- DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
- allqueue(REDRAWVIEW3D, 0);
- allqueue(REDRAWBUTSEDIT, 0);
+ set_active_key(index);
+ set_active_editipo(ei+index-1);
}
}
}
@@ -2595,6 +2691,7 @@ void mouse_select_ipo()
else {
actei->flag |= IPO_SELECT;
}
+ set_active_editipo(actei);
}
}
}
@@ -2754,7 +2851,8 @@ static int selected_bezier_loop(int (*looptest)(EditIpo *),
return 0;
}
-int select_bezier_add(BezTriple *bezt) {
+int select_bezier_add(BezTriple *bezt)
+{
/* Select the bezier triple */
bezt->f1 |= 1;
bezt->f2 |= 1;
@@ -2762,7 +2860,8 @@ int select_bezier_add(BezTriple *bezt) {
return 0;
}
-int select_bezier_subtract(BezTriple *bezt) {
+int select_bezier_subtract(BezTriple *bezt)
+{
/* Deselect the bezier triple */
bezt->f1 &= ~1;
bezt->f2 &= ~1;
@@ -2770,7 +2869,8 @@ int select_bezier_subtract(BezTriple *bezt) {
return 0;
}
-int select_bezier_invert(BezTriple *bezt) {
+int select_bezier_invert(BezTriple *bezt)
+{
/* Invert the selection for the bezier triple */
bezt->f2 ^= 1;
if ( bezt->f2 & 1 ) {
@@ -2858,7 +2958,8 @@ static int set_bezier_align(BezTriple *bezt)
return 0;
}
-static int vis_edit_icu_bez(EditIpo *ei) {
+static int vis_edit_icu_bez(EditIpo *ei)
+{
/* A 4 part test for an EditIpo :
* is it a) visible
* b) in edit mode
@@ -3035,7 +3136,7 @@ void setipotype_ipo(Ipo *ipo, int code)
}
}
-void set_ipotype()
+void set_ipotype(void)
{
EditIpo *ei;
int a;
@@ -3078,7 +3179,7 @@ void set_ipotype()
scrarea_queue_winredraw(curarea);
}
-void borderselect_ipo()
+void borderselect_ipo(void)
{
EditIpo *ei;
IpoKey *ik;
@@ -3164,7 +3265,7 @@ void del_ipoCurve ( IpoCurve * icu )
}
}
-void del_ipo()
+void del_ipo(void)
{
EditIpo *ei;
BezTriple *bezt, *bezt1;
@@ -3214,12 +3315,21 @@ void del_ipo()
}
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;
+ if(ei->icu->driver==NULL) {
+ BLI_remlink( &(G.sipo->ipo->curve), ei->icu);
+
+ free_ipo_curve(ei->icu);
+
+ ei->flag &= ~IPO_SELECT;
+ ei->flag &= ~IPO_EDIT;
+ ei->icu= NULL;
+ }
+ else {
+ if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
+ ei->icu->bezt= NULL;
+ ei->icu->totvert= 0;
+ ei->flag &= ~IPO_EDIT;
+ }
}
}
@@ -3243,16 +3353,25 @@ void del_ipo()
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;
+ if(ei->icu->totvert) {
+ 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;
+ }
+ else {
+ MEM_freeN(ei->icu->bezt);
+ ei->icu->bezt= NULL;
+ }
}
}
}
}
}
+ get_status_editipo(); /* count again */
+ check_active_editipo();
+
BIF_undo_push("Delete Ipo");
allqueue(REDRAWNLA, 0);
allqueue (REDRAWACTION, 0);
@@ -3263,19 +3382,18 @@ void del_ipo()
ListBase ipocopybuf={0, 0};
int totipocopybuf=0;
-void free_ipocopybuf()
+void free_ipocopybuf(void)
{
IpoCurve *icu;
while( (icu= ipocopybuf.first) ) {
- if(icu->bezt) MEM_freeN(icu->bezt);
BLI_remlink(&ipocopybuf, icu);
- MEM_freeN(icu);
+ free_ipo_curve(icu);
}
totipocopybuf= 0;
}
-void copy_editipo()
+void copy_editipo(void)
{
EditIpo *ei;
IpoCurve *icu;
@@ -3295,10 +3413,9 @@ void copy_editipo()
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));
- }
+ icu->bezt= MEM_dupallocN(icu->bezt);
+ icu->driver= MEM_dupallocN(icu->driver);
+
totipocopybuf++;
}
}
@@ -3307,7 +3424,7 @@ void copy_editipo()
if(totipocopybuf==0) error("Copy buffer is empty");
}
-void paste_editipo()
+void paste_editipo(void)
{
EditIpo *ei;
IpoCurve *icu;
@@ -3322,7 +3439,7 @@ void paste_editipo()
get_status_editipo();
if(totipo_vis==0) {
- error("No visible splines");
+ error("No visible channels");
}
else if(totipo_vis!=totipocopybuf && totipo_sel!=totipocopybuf) {
error("Incompatible paste");
@@ -3344,20 +3461,22 @@ void paste_editipo()
if(ok) {
ei->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei->adrcode, 0);
- if(ei->icu==0) return;
+ if(ei->icu==NULL) return;
if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
- ei->icu->bezt= 0;
+ ei->icu->bezt= NULL;
+ if(ei->icu->driver) MEM_freeN(ei->icu->driver);
+ ei->icu->driver= NULL;
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));
- }
+ if(icu->bezt)
+ ei->icu->bezt= MEM_dupallocN(icu->bezt);
+ if(icu->driver)
+ ei->icu->driver= MEM_dupallocN(icu->driver);
icu= icu->next;
@@ -3501,7 +3620,7 @@ void insertkey(ID *id, int adrcode)
if(id) {
- // this call here, otherwise get_ipo_curve gives it from the pinned ipo
+ // this call here, otherwise get_ipocurve 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);
@@ -3527,7 +3646,7 @@ void insertkey(ID *id, int adrcode)
}
}
-void insertkey_editipo()
+void insertkey_editipo(void)
{
EditIpo *ei;
IpoKey *ik;
@@ -3536,81 +3655,110 @@ void insertkey_editipo()
int a, nr, ok, tot;
short event;
- if(G.sipo->showkey)
+ ei= get_active_editipo();
+ if(ei && ei->icu && ei->icu->driver)
+ event= pupmenu("Insert Curve %t|Default one-to-one mapping %x3");
+ else if(G.sipo->showkey)
event= pupmenu("Insert Key Vertices %t|Current Frame %x1|Selected Keys %x2");
else
event= pupmenu("Insert Key Vertices %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) {
+ if(event==3) {
+ IpoDriver *driver= ei->icu->driver;
- ok= 0;
- if(G.sipo->showkey) ok= 1;
- else if(ei->flag & IPO_SELECT) ok= 1;
+ if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
+ ei->icu->totvert= 0;
+ ei->icu->bezt= NULL;
+
+ insert_vert_ipo(ei->icu, 0.0f, 0.0f);
+
+ if(ELEM3(driver->adrcode, OB_ROT_X, OB_ROT_Y, OB_ROT_Z)) {
+ if(ei->disptype==IPO_DISPDEGR)
+ insert_vert_ipo(ei->icu, 18.0f, 18.0f);
+ else
+ insert_vert_ipo(ei->icu, 18.0f, 1.0f);
+ }
+ else
+ insert_vert_ipo(ei->icu, 1.0f, 1.0f);
+
+ ei->flag |= IPO_SELECT|IPO_VISIBLE;
+ ei->icu->flag= ei->flag;
+ ei->icu->extrap= IPO_DIR;
- if(ok) {
- /* count amount */
- 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) {
-
- /* correction for 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)));
- }
- }
+ do_ipo_buttons(B_IPOHOME);
+ }
+ else {
+ ei= G.sipo->editipo;
+ for(nr=0; nr<G.sipo->totipo; nr++, ei++) {
+ if ISPOIN(ei, flag & IPO_VISIBLE, icu) {
- insertvals= MEM_mallocN(sizeof(float)*2*tot, "insertkey_editipo");
- /* make sure icu->curval is correct */
- calc_ipo(G.sipo->ipo, cfra);
-
- if(event==1) {
- insertvals[0]= cfra;
-
- insertvals[1]= ei->icu->curval;
- }
+ ok= 0;
+ if(G.sipo->showkey) ok= 1;
+ else if(ei->flag & IPO_SELECT) ok= 1;
+
+ if(ok) {
+ /* count amount */
+ if(event==1) tot= 1;
else {
- fp= insertvals;
ik= G.sipo->ipokey.first;
+ tot= 0;
while(ik) {
- if(ik->flag & 1) {
- calc_ipo(G.sipo->ipo, ik->val);
-
- fp[0]= ik->val;
- fp[1]= ei->icu->curval;
- fp+= 2;
- }
+ if(ik->flag & 1) tot++;
ik= ik->next;
}
}
- fp= insertvals;
- for(a=0; a<tot; a++, fp+=2) {
- insert_vert_ipo(ei->icu, fp[0], fp[1]);
- }
+ if(tot) {
- MEM_freeN(insertvals);
- calc_ipo(G.sipo->ipo, (float)CFRA);
+ /* correction for 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");
+ /* make sure icu->curval is correct */
+ 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);
+ }
}
}
}
@@ -3623,7 +3771,7 @@ void insertkey_editipo()
}
-void common_insertkey()
+void common_insertkey(void)
{
Base *base;
Object *ob;
@@ -4250,7 +4398,7 @@ void make_ipokey_transform(Object *ob, ListBase *lb, int sel)
}
}
-void update_ipokey_val() /* after moving vertices */
+void update_ipokey_val(void) /* after moving vertices */
{
IpoKey *ik;
int a;
@@ -4992,7 +5140,7 @@ void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu)
icu->ipo= IPO_LIN;
if(icu->bezt) MEM_freeN(icu->bezt);
- icu->bezt= 0;
+ icu->bezt= NULL;
tot= 1; /* first point */
da= data+1;
@@ -5015,7 +5163,7 @@ void sampledata_to_ipocurve(float *data, int sfra, int efra, IpoCurve *icu)
}
}
-void ipo_record()
+void ipo_record(void)
{
/* only 1 or 2 active curves
* make a copy (ESC)
@@ -5070,16 +5218,16 @@ void ipo_record()
}
/* make curves ready, start values */
- if(ei1->icu==0) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0);
- if(ei1->icu==0) return;
+ if(ei1->icu==NULL) ei1->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei1->adrcode, 0);
+ if(ei1->icu==NULL) 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;
+ if(ei2->icu==NULL) ei2->icu= get_ipocurve(G.sipo->from, G.sipo->blocktype, ei2->adrcode, 0);
+ if(ei2->icu==NULL) 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;
@@ -5203,18 +5351,18 @@ void ipo_record()
/* undo: start values */
poin= get_ipo_poin(G.sipo->from, ei1->icu, &type);
if(poin) write_ipo_poin(poin, type, or1);
- if(ei1->icu->bezt==0) {
+ if(ei1->icu->bezt==NULL) {
BLI_remlink( &(G.sipo->ipo->curve), ei1->icu);
MEM_freeN(ei1->icu);
- ei1->icu= 0;
+ ei1->icu= NULL;
}
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) {
+ if(ei2->icu->bezt==NULL) {
BLI_remlink( &(G.sipo->ipo->curve), ei2->icu);
MEM_freeN(ei2->icu);
- ei2->icu= 0;
+ ei2->icu= NULL;
}
}
}
@@ -5320,8 +5468,7 @@ void delete_ipo_keys(Ipo *ipo)
if (!icu->totvert){
/* Delete the curve */
BLI_remlink( &(ipo->curve), icu);
- if(icu->bezt) MEM_freeN(icu->bezt);
- MEM_freeN(icu);
+ free_ipo_curve(icu);
}
}
}
diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c
index f7368c58013..c7f4de25c7e 100644
--- a/source/blender/src/editobject.c
+++ b/source/blender/src/editobject.c
@@ -4114,6 +4114,7 @@ void adduplicate(int noTrans)
Object *ob, *obn;
Material ***matarar, *ma, *mao;
ID *id;
+ Ipo *ipo;
bConstraintChannel *chan;
int a, didit, dupflag;
@@ -4314,7 +4315,21 @@ void adduplicate(int noTrans)
}
base= base->next;
}
-
+
+ /* ipos */
+ ipo= G.main->ipo.first;
+ while(ipo) {
+ if(ipo->id.lib==NULL) {
+ IpoCurve *icu;
+ for(icu= ipo->curve.first; icu; icu= icu->next) {
+ if(icu->driver) {
+ ID_NEW(icu->driver->ob);
+ }
+ }
+ }
+ ipo= ipo->id.next;
+ }
+
/* materials */
if( dupflag & USER_DUP_MAT) {
mao= G.main->mat.first;
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index fce45d7ab39..06e7e418224 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -411,10 +411,13 @@ static uiBlock *ipo_editmenu(void *arg_unused)
else
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_DEHLT, "Edit Selected|TAB", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 6, "");
- ei = G.sipo->editipo;
+ ei = get_active_editipo();
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert Keyframe...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+ if(ei->icu && ei->icu->driver)
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert 1:1 Curve...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
+ else
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Insert Keyframe...|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 3, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
@@ -473,11 +476,14 @@ static void do_ipo_viewmenu(void *arg, int event)
mainqenter(PADMINUS,1);
break;
case 6: /* Play Back Animation */
- play_anim(0);
- break;
+ play_anim(0);
+ break;
case 7: /* Play Back Animation in All */
- play_anim(1);
- break;
+ play_anim(1);
+ break;
+ case 8:
+ add_blockhandler(curarea, IPO_HANDLER_PROPERTIES, UI_PNL_UNSTOW);
+ break;
}
}
@@ -492,6 +498,8 @@ static uiBlock *ipo_viewmenu(void *arg_unused)
block= uiNewBlock(&curarea->uiblocks, "ipo_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
uiBlockSetButmFunc(block, do_ipo_viewmenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL, "Channel Properties|N", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
if (G.sipo->showkey)
uiDefIconTextBut(block, BUTM, 1, ICON_CHECKBOX_HLT, "Show Keys|K", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
else
@@ -692,6 +700,8 @@ void do_ipo_buttons(short event)
v2d->cur.ymax= v2d->tot.ymax+ dy;
test_view2d(G.v2d, curarea->winx, curarea->winy);
+ if(G.sipo->ipo) G.sipo->ipo->cur = G.v2d->cur;
+
scrarea_queue_winredraw(curarea);
break;
case B_IPOBORDER:
diff --git a/source/blender/src/interface.c b/source/blender/src/interface.c
index 78b94c42564..f7429c3bc57 100644
--- a/source/blender/src/interface.c
+++ b/source/blender/src/interface.c
@@ -1225,7 +1225,8 @@ static int ui_do_but_MENU(uiBut *but)
uibut_do_func(but);
- return event;
+ if(event == UI_NOTHING) return 0;
+ else return but->retval;
}
@@ -3749,27 +3750,31 @@ static void ui_do_but_tip(uiBut *buttip)
* as long as the mouse remains on top
* of the button that owns it.
*/
+ Mat4CpyMat4(UIwinmat, buttip->block->winmat); // get rid of uiwinmat once...
uiPanelPush(buttip->block); // panel matrix
od= ui_draw_but_tip(buttip);
- while (1) {
- char ascii;
- short val;
- unsigned short evt= extern_qread_ext(&val, &ascii);
-
- if (evt==MOUSEX || evt==MOUSEY) {
- short mouse[2];
- uiGetMouse(od->oldwin, mouse);
-
- if (!uibut_contains_pt(buttip, mouse))
+ if(od) {
+ while (1) {
+ char ascii;
+ short val;
+ unsigned short evt= extern_qread_ext(&val, &ascii);
+
+ if (evt==MOUSEX || evt==MOUSEY) {
+ short mouse[2];
+ uiGetMouse(od->oldwin, mouse);
+
+ if (!uibut_contains_pt(buttip, mouse))
+ break;
+ } else {
+ mainqpushback(evt, val, ascii);
break;
- } else {
- mainqpushback(evt, val, ascii);
- break;
+ }
}
+
+ ui_end_overdraw(od);
}
- ui_end_overdraw(od);
uiPanelPop(buttip->block); // panel matrix
/* still the evil global.... */
UIbuttip= NULL;