Version 1.0 of IpoDrivers.

First note that this is new functionality, unfinished, and only for
testing and feedback purposes. I'll list below what works, and what will
need work still.

This text is also in cms: http://www.blender.org/cms/Ipo_Drivers.680.0.html

An IpoDriver is like an IpoCurve, but instead of a Bezier curve, it allows
to connect a property of other Objects as input for the "channel". For
example, IpoDrivers can be used to have a Shape Key being "driven" by
the rotation of a Bone. Or the RGB colors of a Material get driven by the
XYZ location of an Object.

Editing of Drivers happens in the IpoWindow. Here you can notice that the
channels (right hand window) now have an "active" channel indicator.
To add a Driver, you have to use the "Transform Properties" Panel (Nkey).
Here you can add or remove a Driver to the active channel, and use the
buttons to fill in what kind of relationship you want to establish.

Driver Objects

Note that any Ipo Channel can become driven now, but that only Object
transformation or Pose Bone transformation can be used to become a
Driver now.
At this moment, only the local transformation is taken into account.
For Objects that means the location/rotation/scale value without Parent
transform (as shown in "Transform Properties" Panel for Objects).
For Pose Bones it means that only the Pose transform (changes of rest
position) is Driver information (also as shown in Transform Property
Panel in Pose Mode).

Mapping of Drivers

When an Ipo Channel is "driven", the mapping is by default one-to-one.
It is only restricted by already built-in limits for Channels, like
for Material the "R" value can only range from 0.0 to 1.0.

Also note that when mapping rotations, the actual rotation values
in Ipos are scaled down with a factor 10.0. (180 degrees actually has
in the Ipo system a value of 18.0). This is an ancient year zero
convention in Blender... it is a bit hidden, because the ruler
(vertical as well as horizontal) displays the virtual values correctly.
Only the Properties panel shows the actual value.

When you draw an IpoCurve in a Driven channel, this curve will define
the mapping between the Driver output (horizontal) and Driven input
(vertical, as usual).
A nice new option to use is "Insert one-to-one curve" (press I-key,
or in pulldown menu). This will also zoom the display in exactly to
fill the window, allowing easy edit. If you use this option with
degrees, it will map 180 degree rotation to a range of 1.0 unit.

Live updates

Since the Drivers are integrated in the Ipo system, they will always
be updated whenever an Ipo is evaluated. This happens at least on
frame changes.
For interactive feedback, updates while transforming objects were
added in these cases:

- Driven Object Ipos, by other Objects or Pose Bones
- Driven Shape Key Ipos, by other Objects or Pose Bones

You can also insert Drivers on Action Ipos, but these are only evaluated
on frame change now.

Todo

- Drivers can also get a text button, allowing a 1 line Python script
  to be executed.
- Make UI for it a bit less hidden... maybe with visualization in 3D?
- Allowing global transform coordinates as Driver too.

Issues

- renaming Bones won't rename drivers
- (file) appending the Ipo won't append the linked driver Objects
This commit is contained in:
2005-10-02 20:51:35 +00:00
parent 42fe4c568d
commit 015fe7ea81
18 changed files with 767 additions and 230 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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,6 +1297,7 @@ 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) {
ob->ctime= stime;
@@ -1296,6 +1309,10 @@ 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;

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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 ********************* */

View File

@@ -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

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -45,6 +45,7 @@
#endif
#include "BMF_Api.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
@@ -786,7 +787,19 @@ void drawscroll(int disptype)
scroll_prstr(fac, 3.0+(float)(hor.ymin), fac2, 'h', disptype);
}
}
else {
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);
}
@@ -910,17 +923,18 @@ 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(ei->icu->driver) {
cpack(0x0);
fdrawbox((float)v2d->mask.xmax+11, (float)y+8, (float)v2d->mask.xmax+12.5, (float)y+9.5);
}
}
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->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);
boundbox_ipo_visible(G.sipo); // should not be needed... transform/draw calls should update
/* 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_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,6 +1847,7 @@ static void ipo_panel_properties(short cntrl) // IPO_HANDLER_PROPERTIES
/* SPEED BUTTON */
if(totipo_vertsel) {
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, "");
}

View File

@@ -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) {
if(ei->icu->driver==NULL) {
BLI_remlink( &(G.sipo->ipo->curve), ei->icu);
if(ei->icu->bezt) MEM_freeN(ei->icu->bezt);
MEM_freeN(ei->icu);
free_ipo_curve(ei->icu);
ei->flag &= ~IPO_SELECT;
ei->flag &= ~IPO_EDIT;
ei->icu= 0;
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,15 +3353,24 @@ void del_ipo()
else bezt++;
}
if(event) {
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);
@@ -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,13 +3655,41 @@ 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;
if(event==3) {
IpoDriver *driver= ei->icu->driver;
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;
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) {
@@ -3615,6 +3762,7 @@ void insertkey_editipo()
}
}
}
}
BIF_undo_push("Insert Key Ipo");
allqueue (REDRAWACTION, 0);
allqueue(REDRAWNLA, 0);
@@ -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);
}
}
}

View File

@@ -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;
@@ -4315,6 +4316,20 @@ 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;

View File

@@ -411,9 +411,12 @@ 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, "");
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, "");
@@ -478,6 +481,9 @@ static void do_ipo_viewmenu(void *arg, int event)
case 7: /* Play Back Animation in All */
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:

View File

@@ -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,9 +3750,11 @@ 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);
if(od) {
while (1) {
char ascii;
short val;
@@ -3770,6 +3773,8 @@ static void ui_do_but_tip(uiBut *buttip)
}
ui_end_overdraw(od);
}
uiPanelPop(buttip->block); // panel matrix
/* still the evil global.... */
UIbuttip= NULL;