Tiny feature, but loadsa code, and big impact for the Blender riggers:
-> Constraint Influence Ipo now can be local, linked to constraint itself You enable this in the IpoWindow header, with the Action icon to the left of the Ipo Type menu. The button tooltips give the clue as well. Tech note: the Ipo now can get directly linked to a constraint, and is being called during regular pose constraint solving. Actions (and drivers in actions) are being calculated *before* pose constraint solving. Result of actions then is written in bones, which then solves the entire pose. This means you can have a driver on both the constraint, as on the action channel for the constraint! Not that I'm going to debug that easily :) Additional fix: Joshua added a copy/paste IpoCurve feature, but he broke the functionality to be able to paste in an empty ipo channel. That now works again
This commit is contained in:
@@ -2083,6 +2083,9 @@ static void where_is_pose_bone(Object *ob, bPoseChannel *pchan, float ctime)
|
||||
if (pchan->constraints.first) {
|
||||
bConstraintOb *cob;
|
||||
|
||||
/* local constraints */
|
||||
do_constraint_channels(&pchan->constraints, NULL, ctime, 0);
|
||||
|
||||
/* make a copy of location of PoseChannel for later */
|
||||
VECCOPY(vec, pchan->pose_mat[3]);
|
||||
|
||||
|
||||
@@ -142,9 +142,11 @@ bConstraintChannel *get_constraint_channel (ListBase *list, const char name[])
|
||||
{
|
||||
bConstraintChannel *chan;
|
||||
|
||||
for (chan = list->first; chan; chan=chan->next) {
|
||||
if (!strcmp(name, chan->name)) {
|
||||
return chan;
|
||||
if(list) {
|
||||
for (chan = list->first; chan; chan=chan->next) {
|
||||
if (!strcmp(name, chan->name)) {
|
||||
return chan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,17 +177,24 @@ bConstraintChannel *verify_constraint_channel (ListBase *list, const char name[]
|
||||
void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime, short onlydrivers)
|
||||
{
|
||||
bConstraint *con;
|
||||
bConstraintChannel *chan;
|
||||
IpoCurve *icu= NULL;
|
||||
|
||||
/* for each Constraint, calculate its Influence from the corresponding ConstraintChannel */
|
||||
for (con=conbase->first; con; con=con->next) {
|
||||
chan = get_constraint_channel(chanbase, con->name);
|
||||
Ipo *ipo= NULL;
|
||||
|
||||
if (chan && chan->ipo) {
|
||||
calc_ipo(chan->ipo, ctime);
|
||||
if(con->flag & CONSTRAINT_OWN_IPO)
|
||||
ipo= con->ipo;
|
||||
else {
|
||||
bConstraintChannel *chan = get_constraint_channel(chanbase, con->name);
|
||||
if(chan) ipo= chan->ipo;
|
||||
}
|
||||
|
||||
if (ipo) {
|
||||
IpoCurve *icu;
|
||||
|
||||
for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
|
||||
calc_ipo(ipo, ctime);
|
||||
|
||||
for (icu=ipo->curve.first; icu; icu=icu->next) {
|
||||
if (!onlydrivers || icu->driver) {
|
||||
switch (icu->adrcode) {
|
||||
case CO_ENFORCE:
|
||||
|
||||
@@ -2180,6 +2180,21 @@ void DAG_pose_sort(Object *ob)
|
||||
ListBase targets = {NULL, NULL};
|
||||
bConstraintTarget *ct;
|
||||
|
||||
if(con->ipo) {
|
||||
IpoCurve *icu;
|
||||
for(icu= con->ipo->curve.first; icu; icu= icu->next) {
|
||||
if(icu->driver && icu->driver->ob==ob) {
|
||||
bPoseChannel *target= get_pose_channel(ob->pose, icu->driver->name);
|
||||
if(target) {
|
||||
node2 = dag_get_node(dag, target);
|
||||
dag_add_relation(dag, node2, node, 0);
|
||||
dag_add_parent_relation(dag, node2, node, 0);
|
||||
cti= NULL; /* trick to get next loop skipped */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cti && cti->get_constraint_targets) {
|
||||
cti->get_constraint_targets(con, &targets);
|
||||
|
||||
|
||||
@@ -1619,7 +1619,9 @@ static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
|
||||
if(con->data==NULL) {
|
||||
con->type= CONSTRAINT_TYPE_NULL;
|
||||
}
|
||||
|
||||
/* own ipo, all constraints have it */
|
||||
con->ipo= newlibadr(fd, id->lib, con->ipo);
|
||||
|
||||
switch (con->type) {
|
||||
case CONSTRAINT_TYPE_PYTHON:
|
||||
{
|
||||
|
||||
@@ -89,8 +89,8 @@ void do_ipo_selectbuttons(void);
|
||||
|
||||
|
||||
/* gets ipo curve, creates if needed */
|
||||
struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, int);
|
||||
struct Ipo *verify_ipo(struct ID *, short, char *, char *);
|
||||
struct IpoCurve *verify_ipocurve(struct ID *, short, char *, char *, char *, int);
|
||||
struct Ipo *verify_ipo(struct ID *, short, char *, char *, char *);
|
||||
int texchannel_to_adrcode(int channel);
|
||||
|
||||
int insert_bezt_icu(struct IpoCurve *icu, struct BezTriple *bezt);
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
#define B_IPO_ACTION_KEY 214
|
||||
#define B_IPOVIEWCENTER 215
|
||||
#define B_IPOVIEWALL 216
|
||||
|
||||
#define B_IPOREDRAW 217
|
||||
|
||||
/* OOPS: 250 */
|
||||
#define B_OOPSHOME 251
|
||||
|
||||
@@ -87,7 +87,6 @@ extern int mod_moveDown(void *ob_v, void *md_v);
|
||||
extern void const_moveUp(void *ob_v, void *con_v);
|
||||
extern void const_moveDown(void *ob_v, void *con_v);
|
||||
extern void del_constr_func (void *ob_v, void *con_v);
|
||||
extern void get_constraint_ipo_context(void *ob_v, char *actname);
|
||||
|
||||
/* editing */
|
||||
extern void editing_panels(void);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
struct Action;
|
||||
struct Text;
|
||||
struct Ipo;
|
||||
|
||||
/* channels reside in Object or Action (ListBase) constraintChannels */
|
||||
typedef struct bConstraintChannel {
|
||||
@@ -66,6 +67,7 @@ typedef struct bConstraint {
|
||||
float enforce; /* Amount of influence exherted by constraint (0.0-1.0) */
|
||||
float headtail; /* Point along subtarget bone where the actual target is. 0=head (default for all), 1=tail*/
|
||||
int pad;
|
||||
struct Ipo *ipo; /* local influence ipo or driver */
|
||||
} bConstraint;
|
||||
|
||||
|
||||
@@ -347,7 +349,9 @@ typedef enum B_CONSTRAINT_FLAG {
|
||||
/* to indicate which Ipo should be shown, maybe for 3d access later too */
|
||||
CONSTRAINT_ACTIVE = (1<<4),
|
||||
/* to indicate that the owner's space should only be changed into ownspace, but not out of it */
|
||||
CONSTRAINT_SPACEONCE = (1<<6)
|
||||
CONSTRAINT_SPACEONCE = (1<<6),
|
||||
/* influence ipo is on constraint itself, not in action channel */
|
||||
CONSTRAINT_OWN_IPO = (1<<7)
|
||||
} B_CONSTRAINT_FLAG;
|
||||
|
||||
/* bConstraint->ownspace/tarspace */
|
||||
|
||||
@@ -94,7 +94,7 @@ typedef struct SpaceIpo {
|
||||
/* the ipo context we need to store */
|
||||
struct Ipo *ipo;
|
||||
struct ID *from;
|
||||
char actname[32], constname[32];
|
||||
char actname[32], constname[32], bonename[32];
|
||||
|
||||
short totipo, pin;
|
||||
short butofs, channel;
|
||||
|
||||
@@ -205,7 +205,7 @@ static void add_constraint_to_active(Object *ob, bConstraint *con)
|
||||
|
||||
/* returns base ID for Ipo, sets actname to channel if appropriate */
|
||||
/* should not make action... */
|
||||
void get_constraint_ipo_context(void *ob_v, char *actname)
|
||||
static void get_constraint_ipo_context(void *ob_v, char *actname)
|
||||
{
|
||||
Object *ob= ob_v;
|
||||
|
||||
@@ -237,8 +237,11 @@ static void enable_constraint_ipo_func (void *ob_v, void *con_v)
|
||||
get_constraint_ipo_context(ob, actname);
|
||||
|
||||
/* adds ipo & channels & curve if needed */
|
||||
verify_ipo((ID *)ob, ID_CO, actname, con->name);
|
||||
|
||||
if(con->flag & CONSTRAINT_OWN_IPO)
|
||||
verify_ipo((ID *)ob, ID_CO, NULL, con->name, actname);
|
||||
else
|
||||
verify_ipo((ID *)ob, ID_CO, actname, con->name, NULL);
|
||||
|
||||
/* make sure ipowin shows it */
|
||||
ob->ipowin= ID_CO;
|
||||
allqueue(REDRAWIPO, ID_CO);
|
||||
@@ -261,8 +264,11 @@ static void add_influence_key_to_constraint_func (void *ob_v, void *con_v)
|
||||
get_constraint_ipo_context(ob, actname);
|
||||
|
||||
/* adds ipo & channels & curve if needed */
|
||||
icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, CO_ENFORCE);
|
||||
|
||||
if(con->flag & CONSTRAINT_OWN_IPO)
|
||||
icu= verify_ipocurve((ID *)ob, ID_CO, NULL, con->name, actname, CO_ENFORCE);
|
||||
else
|
||||
icu= verify_ipocurve((ID *)ob, ID_CO, actname, con->name, NULL, CO_ENFORCE);
|
||||
|
||||
if (!icu) {
|
||||
error("Cannot get a curve from this IPO, may be dealing with linked data");
|
||||
return;
|
||||
|
||||
@@ -1899,7 +1899,7 @@ void do_ipobuts(unsigned short event)
|
||||
ei= get_active_editipo();
|
||||
if(ei) {
|
||||
if(ei->icu==NULL) {
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
|
||||
if (!ei->icu) {
|
||||
error("Could not add a driver to this curve, may be linked data!");
|
||||
break;
|
||||
@@ -1966,7 +1966,7 @@ void do_ipobuts(unsigned short event)
|
||||
}
|
||||
else {
|
||||
if(driver->ob) {
|
||||
if(ob==driver->ob) {
|
||||
if(ob==driver->ob && G.sipo->bonename[0]==0) {
|
||||
error("Cannot assign a Driver to own Object");
|
||||
driver->ob= NULL;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ static int node_buts_group(uiBlock *block, bNodeTree *ntree, bNode *node, rctf *
|
||||
sprintf(str1, "%d", node->id->us);
|
||||
bt= uiDefBut(block, BUT, B_NOP, str1,
|
||||
butr->xmax-19, butr->ymin, 19, 19,
|
||||
NULL, 0, 0, 0, 0, "Displays number of users. Click to make a single-user copy.");
|
||||
NULL, 0, 0, 0, 0, "Displays number of users.");
|
||||
//uiButSetFunc(bt, node_mat_alone_cb, node, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -1013,7 +1013,8 @@ static void make_editipo(void)
|
||||
/* evaluates context in the current UI */
|
||||
/* blocktype is type of ipo */
|
||||
/* from is the base pointer to find data to change (ob in case of action or pose) */
|
||||
static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname, char *constname)
|
||||
/* bonename is for local bone ipos (constraint only now) */
|
||||
static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname, char *constname, char *bonename)
|
||||
{
|
||||
Object *ob= OBACT;
|
||||
|
||||
@@ -1026,25 +1027,37 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
|
||||
bConstraint *con= get_active_constraint(ob);
|
||||
|
||||
if(con) {
|
||||
BLI_strncpy(constname, con->name, 32);
|
||||
|
||||
chan= get_active_constraint_channel(ob);
|
||||
if(chan) {
|
||||
*ipo= chan->ipo;
|
||||
BLI_strncpy(constname, con->name, 32);
|
||||
}
|
||||
|
||||
*from= &ob->id;
|
||||
|
||||
/* set actname if in posemode */
|
||||
if(ob->action) {
|
||||
BLI_strncpy(constname, con->name, 32);
|
||||
|
||||
/* a bit hackish, but we want con->ipo to work */
|
||||
if(con->flag & CONSTRAINT_OWN_IPO) {
|
||||
if(ob->flag & OB_POSEMODE) {
|
||||
bPoseChannel *pchan= get_active_posechannel(ob);
|
||||
if(pchan)
|
||||
BLI_strncpy(actname, pchan->name, 32);
|
||||
if(pchan) {
|
||||
BLI_strncpy(bonename, pchan->name, 32);
|
||||
*ipo= con->ipo;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
chan= get_active_constraint_channel(ob);
|
||||
if(chan) {
|
||||
*ipo= chan->ipo;
|
||||
BLI_strncpy(constname, con->name, 32);
|
||||
}
|
||||
|
||||
/* set actname if in posemode */
|
||||
if(ob->action) {
|
||||
if(ob->flag & OB_POSEMODE) {
|
||||
bPoseChannel *pchan= get_active_posechannel(ob);
|
||||
if(pchan)
|
||||
BLI_strncpy(actname, pchan->name, 32);
|
||||
}
|
||||
else if(ob->ipoflag & OB_ACTION_OB)
|
||||
strcpy(actname, "Object");
|
||||
}
|
||||
else if(ob->ipoflag & OB_ACTION_OB)
|
||||
strcpy(actname, "Object");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1182,9 +1195,9 @@ void test_editipo(int doit)
|
||||
if(G.sipo->pin==0) {
|
||||
Ipo *ipo;
|
||||
ID *from;
|
||||
char actname[32]="", constname[32]="";
|
||||
char actname[32]="", constname[32]="", bonename[32]="";
|
||||
|
||||
get_ipo_context(G.sipo->blocktype, &from, &ipo, actname, constname);
|
||||
get_ipo_context(G.sipo->blocktype, &from, &ipo, actname, constname, bonename);
|
||||
|
||||
if(G.sipo->ipo != ipo) {
|
||||
G.sipo->ipo= ipo;
|
||||
@@ -1203,6 +1216,12 @@ void test_editipo(int doit)
|
||||
BLI_strncpy(G.sipo->constname, constname, 32);
|
||||
doit= 1;
|
||||
}
|
||||
if( strcmp(G.sipo->bonename, bonename)) {
|
||||
BLI_strncpy(G.sipo->bonename, bonename, 32);
|
||||
/* urmf; if bonename, then no action */
|
||||
if(bonename[0]) G.sipo->actname[0]= 0;
|
||||
doit= 1;
|
||||
}
|
||||
|
||||
if(G.sipo->ipo)
|
||||
G.sipo->ipo->cur = G.v2d->cur;
|
||||
@@ -1751,11 +1770,12 @@ void do_ipo_selectbuttons(void)
|
||||
/* arguments define full context;
|
||||
- *from has to be set always, to Object in case of Actions
|
||||
- blocktype defines available channels of Ipo struct (blocktype ID_OB can be in action too)
|
||||
- if actname, use this to locate action, and optional constname to find the channel
|
||||
- if actname, use this to locate actionchannel, and optional constname
|
||||
- if bonename, the constname is the ipo to the constraint
|
||||
*/
|
||||
|
||||
/* note; check header_ipo.c, spaceipo_assign_ipo() too */
|
||||
Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
|
||||
Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname, char *bonename)
|
||||
{
|
||||
|
||||
if(from==NULL || from->lib) return NULL;
|
||||
@@ -1799,13 +1819,30 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
|
||||
case ID_OB:
|
||||
{
|
||||
Object *ob= (Object *)from;
|
||||
|
||||
/* constraint exception */
|
||||
if(blocktype==ID_CO) {
|
||||
bConstraintChannel *conchan= verify_constraint_channel(&ob->constraintChannels, constname);
|
||||
if(conchan->ipo==NULL) {
|
||||
conchan->ipo= add_ipo("CoIpo", ID_CO);
|
||||
/* check the local constraint ipo */
|
||||
if(bonename && bonename[0] && ob->pose) {
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, bonename);
|
||||
bConstraint *con;
|
||||
for(con= pchan->constraints.first; con; con= con->next)
|
||||
if(strcmp(con->name, constname)==0)
|
||||
break;
|
||||
if(con) {
|
||||
if(con->ipo==NULL) {
|
||||
con->ipo= add_ipo("CoIpo", ID_CO);
|
||||
}
|
||||
return con->ipo;
|
||||
}
|
||||
}
|
||||
else { /* the actionchannel */
|
||||
bConstraintChannel *conchan= verify_constraint_channel(&ob->constraintChannels, constname);
|
||||
if(conchan->ipo==NULL) {
|
||||
conchan->ipo= add_ipo("CoIpo", ID_CO);
|
||||
}
|
||||
return conchan->ipo;
|
||||
}
|
||||
return conchan->ipo;
|
||||
}
|
||||
else if(blocktype==ID_OB) {
|
||||
if(ob->ipo==NULL) {
|
||||
@@ -1940,14 +1977,14 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
|
||||
/* returns and creates
|
||||
* Make sure functions check for NULL or they will crash!
|
||||
* */
|
||||
IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constname, int adrcode)
|
||||
IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constname, char *bonename, int adrcode)
|
||||
{
|
||||
Ipo *ipo;
|
||||
IpoCurve *icu= NULL;
|
||||
|
||||
/* return 0 if lib */
|
||||
/* creates ipo too */
|
||||
ipo= verify_ipo(from, blocktype, actname, constname);
|
||||
ipo= verify_ipo(from, blocktype, actname, constname, bonename);
|
||||
|
||||
if(ipo && ipo->id.lib==NULL && from->lib==NULL) {
|
||||
|
||||
@@ -1958,6 +1995,8 @@ IpoCurve *verify_ipocurve(ID *from, short blocktype, char *actname, char *constn
|
||||
icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
|
||||
|
||||
icu->flag |= IPO_VISIBLE|IPO_AUTO_HORIZ;
|
||||
if(ipo->curve.first==NULL) icu->flag |= IPO_ACTIVE; /* first one added active */
|
||||
|
||||
icu->blocktype= blocktype;
|
||||
icu->adrcode= adrcode;
|
||||
|
||||
@@ -2111,7 +2150,7 @@ void add_vert_ipo(void)
|
||||
|
||||
if(ei->icu==NULL) {
|
||||
if(G.sipo->from) {
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
|
||||
if (ei->icu)
|
||||
ei->flag |= ei->icu->flag & IPO_AUTO_HORIZ; /* new curve could have been added, weak... */
|
||||
else
|
||||
@@ -2281,7 +2320,7 @@ static void insertkey_nonrecurs(ID *id, int blocktype, char *actname, char *cons
|
||||
int matset=0;
|
||||
|
||||
if (matset==0) {
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
@@ -2502,7 +2541,7 @@ void insertkey(ID *id, int blocktype, char *actname, char *constname, int adrcod
|
||||
matset=insertmatrixkey(id, blocktype, actname, constname, adrcode);
|
||||
}
|
||||
if (matset==0) {
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
@@ -2544,7 +2583,7 @@ void insertkey_smarter(ID *id, int blocktype, char *actname, char *constname, in
|
||||
int vartype;
|
||||
int insert_mode;
|
||||
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
@@ -2596,7 +2635,7 @@ void insertfloatkey(ID *id, int blocktype, char *actname, char *constname, int a
|
||||
float cfra;
|
||||
int vartype;
|
||||
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, adrcode);
|
||||
icu= verify_ipocurve(id, blocktype, actname, constname, NULL, adrcode);
|
||||
|
||||
if(icu) {
|
||||
|
||||
@@ -4270,7 +4309,7 @@ void paste_editipo(void)
|
||||
int i;
|
||||
|
||||
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
|
||||
if (ei->icu == NULL) return;
|
||||
|
||||
/* Copy selected beztriples from source icu onto this edit-icu,
|
||||
@@ -4307,10 +4346,11 @@ void paste_editipo(void)
|
||||
icu= icu->next;
|
||||
}
|
||||
|
||||
/* otherwise paste entire curve data if selected */
|
||||
else if (ei->flag & IPO_SELECT) {
|
||||
/* otherwise paste entire curve data */
|
||||
else {
|
||||
|
||||
/* make sure an ipo-curve exists (it may not, as this is an editipo) */
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei->adrcode);
|
||||
ei->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei->adrcode);
|
||||
if (ei->icu==NULL) return;
|
||||
|
||||
/* clear exisiting dynamic memory (keyframes, driver) */
|
||||
@@ -5405,7 +5445,7 @@ void ipo_record(void)
|
||||
|
||||
/* make curves ready, start values */
|
||||
if(ei1->icu==NULL)
|
||||
ei1->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei1->adrcode);
|
||||
ei1->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei1->adrcode);
|
||||
if(ei1->icu==NULL) return;
|
||||
|
||||
poin= get_ipo_poin(G.sipo->from, ei1->icu, &type);
|
||||
@@ -5415,7 +5455,7 @@ void ipo_record(void)
|
||||
|
||||
if(ei2) {
|
||||
if(ei2->icu==NULL)
|
||||
ei2->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, ei2->adrcode);
|
||||
ei2->icu= verify_ipocurve(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname, G.sipo->bonename, ei2->adrcode);
|
||||
if(ei2->icu==NULL) return;
|
||||
|
||||
poin= get_ipo_poin(G.sipo->from, ei2->icu, &type);
|
||||
|
||||
@@ -171,9 +171,9 @@ static void rvk_slider_func(void *voidob, void *voidkeynum)
|
||||
|
||||
/* ipo on action or ob? */
|
||||
if(ob->ipoflag & OB_ACTION_KEY)
|
||||
icu = verify_ipocurve(&ob->id, ID_KE, "Shape", NULL, keynum);
|
||||
icu = verify_ipocurve(&ob->id, ID_KE, "Shape", NULL, NULL, keynum);
|
||||
else
|
||||
icu = verify_ipocurve(&ob->id, ID_KE, NULL, NULL, keynum);
|
||||
icu = verify_ipocurve(&ob->id, ID_KE, NULL, NULL, NULL, keynum);
|
||||
|
||||
if (icu) {
|
||||
/* if the ipocurve exists, try to get a bezier
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_key.h"
|
||||
@@ -84,6 +85,7 @@
|
||||
#include "BSE_time.h"
|
||||
|
||||
#include "BIF_editaction.h"
|
||||
#include "BIF_editconstraint.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_mainqueue.h"
|
||||
#include "BIF_resources.h"
|
||||
@@ -139,11 +141,27 @@ void spaceipo_assign_ipo(SpaceIpo *si, Ipo *ipo)
|
||||
Object *ob= (Object *)si->from;
|
||||
/* constraint exception */
|
||||
if(si->blocktype==ID_CO) {
|
||||
bConstraintChannel *conchan= get_constraint_channel(&ob->constraintChannels, si->constname);
|
||||
if(conchan) {
|
||||
if(conchan->ipo)
|
||||
conchan->ipo->id.us--;
|
||||
conchan->ipo= ipo;
|
||||
/* check the local constraint ipo */
|
||||
if(si->bonename && si->bonename[0] && ob->pose) {
|
||||
bPoseChannel *pchan= get_pose_channel(ob->pose, si->bonename);
|
||||
bConstraint *con;
|
||||
|
||||
for(con= pchan->constraints.first; con; con= con->next)
|
||||
if(strcmp(con->name, si->constname)==0)
|
||||
break;
|
||||
if(con) {
|
||||
if(con->ipo)
|
||||
con->ipo->id.us--;
|
||||
con->ipo= ipo;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bConstraintChannel *conchan= get_constraint_channel(&ob->constraintChannels, si->constname);
|
||||
if(conchan) {
|
||||
if(conchan->ipo)
|
||||
conchan->ipo->id.us--;
|
||||
conchan->ipo= ipo;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(si->blocktype==ID_FLUIDSIM) { // NT
|
||||
@@ -1174,6 +1192,11 @@ void do_ipo_buttons(short event)
|
||||
else ei->flag &= ~IPO_VISIBLE;
|
||||
}
|
||||
break;
|
||||
case B_IPOREDRAW:
|
||||
DAG_object_flush_update(G.scene, ob, OB_RECALC);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1270,11 +1293,14 @@ void ipo_buttons(void)
|
||||
}
|
||||
else if(G.sipo->blocktype==ID_CO) {
|
||||
|
||||
if(G.sipo->from && G.sipo->actname[0]==0)
|
||||
if(ob->pose==NULL)
|
||||
uiDefIconButBitS(block, TOG, OB_ACTION_OB, B_IPO_ACTION_OB, ICON_ACTION, xco,0,XIC,YIC, &(ob->ipoflag), 0, 0, 0, 0, "Sets Ipo to be included in an Action or not");
|
||||
else {
|
||||
uiSetButLock(1, "Pose Constraint Ipo cannot be switched");
|
||||
uiDefIconButS(block, TOG, 1, ICON_ACTION, xco,0,XIC,YIC, &fake1, 0, 0, 0, 0, "Ipo is connected to Pose Action");
|
||||
bConstraint *con= get_active_constraint(ob);
|
||||
if(con)
|
||||
uiDefIconButBitS(block, TOGN, CONSTRAINT_OWN_IPO, B_IPOREDRAW, ICON_ACTION, xco,0,XIC,YIC, &con->flag, 0, 0, 0, 0,
|
||||
(con->flag & CONSTRAINT_OWN_IPO)?"Ipo is connected to Constraint itself":"Ipo is connected to Pose Action"
|
||||
);
|
||||
}
|
||||
xco+= XIC;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user