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:
authorTon Roosendaal <ton@blender.org>2007-11-28 15:11:06 +0300
committerTon Roosendaal <ton@blender.org>2007-11-28 15:11:06 +0300
commit36f7da70466603643ec28b47e4ec0b082fa5226a (patch)
treea93b182bc592a579fa53ee494ded494449aee1a1
parentbb77ea8df5f016399e50bce5ef8b67d2cac89a28 (diff)
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
-rw-r--r--source/blender/blenkernel/intern/armature.c3
-rw-r--r--source/blender/blenkernel/intern/constraint.c27
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c15
-rw-r--r--source/blender/blenloader/intern/readfile.c4
-rw-r--r--source/blender/include/BSE_editipo.h4
-rw-r--r--source/blender/include/blendef.h2
-rw-r--r--source/blender/include/butspace.h1
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h6
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/src/buttons_object.c16
-rw-r--r--source/blender/src/drawipo.c4
-rw-r--r--source/blender/src/drawnode.c2
-rw-r--r--source/blender/src/editipo.c112
-rw-r--r--source/blender/src/editkey.c4
-rw-r--r--source/blender/src/header_ipo.c42
15 files changed, 174 insertions, 70 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 59786afd999..ab15770c3df 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -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]);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 2dc488f8377..3d565c2a5a3 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -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(con->flag & CONSTRAINT_OWN_IPO)
+ ipo= con->ipo;
+ else {
+ bConstraintChannel *chan = get_constraint_channel(chanbase, con->name);
+ if(chan) ipo= chan->ipo;
+ }
- if (chan && chan->ipo) {
- calc_ipo(chan->ipo, ctime);
+ if (ipo) {
+ IpoCurve *icu;
+
+ calc_ipo(ipo, ctime);
- for (icu=chan->ipo->curve.first; icu; icu=icu->next) {
+ for (icu=ipo->curve.first; icu; icu=icu->next) {
if (!onlydrivers || icu->driver) {
switch (icu->adrcode) {
case CO_ENFORCE:
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 924f544285e..1c5ec61a22e 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -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);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6fdf090b163..ae6a2749269 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -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:
{
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index 3dd54d0a5ed..9e95eedc25e 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -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);
diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h
index 4b5506dda30..55fa1fd8840 100644
--- a/source/blender/include/blendef.h
+++ b/source/blender/include/blendef.h
@@ -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
diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h
index 10a31de98e5..eb756fd932e 100644
--- a/source/blender/include/butspace.h
+++ b/source/blender/include/butspace.h
@@ -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);
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index bf512c3faf8..72506b0eb57 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -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 */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 10f488c9f61..2250e6e43ab 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -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;
diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c
index aa30682c9e5..b5733a89a0e 100644
--- a/source/blender/src/buttons_object.c
+++ b/source/blender/src/buttons_object.c
@@ -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;
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index 9b64d350b9f..94832561b86 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -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;
}
diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c
index 4a5dda72b18..52372b51167 100644
--- a/source/blender/src/drawnode.c
+++ b/source/blender/src/drawnode.c
@@ -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);
}
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 5873bb94732..d0442196bb4 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -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);
diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c
index 671889d6431..0d861cda5d0 100644
--- a/source/blender/src/editkey.c
+++ b/source/blender/src/editkey.c
@@ -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
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index 75a438738bb..4f98e966f8c 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -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;
}