== Constraints Bugfixes ==

* Removed the old get_con_subtarget_name function and fixed the places that used it. This was only suitable for single-target constraints.

* PyConstraints interface drawing should now no longer draw multiple-target fields on top of each other

* Removed double call to BPY_pyconstraint_update when the Update button was clicked. I found this while debugging why PyConstraints didn't seem to be working yet...
This commit is contained in:
Joshua Leung 2007-10-22 10:49:34 +00:00
parent cfd9d390fc
commit e0668e9d22
4 changed files with 78 additions and 84 deletions

@ -56,8 +56,6 @@ void object_test_constraints(struct Object *owner);
void add_constraint(int only_IK);
void ob_clear_constraints(void);
char *get_con_subtarget_name(struct bConstraint *con, struct Object *target);
void rename_constraint(struct Object *ob, struct bConstraint *con, char *newname);

@ -579,19 +579,20 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
/* Draw target parameters */
for (ct=data->targets.first, tarnum=1; ct; ct=ct->next, tarnum++) {
char tarstr[32];
short yoffset= ((tarnum-1) * 38);
/* target label */
sprintf(tarstr, "Target %02d:", tarnum);
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+60, *yco-48, 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
uiDefBut(block, LABEL, B_CONSTRAINT_TEST, tarstr, *xco+60, *yco-(48+yoffset), 55, 18, NULL, 0.0, 0.0, 0.0, 0.0, "");
/* target space-selector - per target */
if (is_armature_target(ct->tar)) {
uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Pose Space %x3|Local with Parent %x4|Local Space %x1",
*xco+60, *yco-66, 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");
*xco+60, *yco-(66+yoffset), 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");
}
else {
uiDefButS(block, MENU, B_CONSTRAINT_TEST, "Target Space %t|World Space %x0|Local (Without Parent) Space %x1",
*xco+60, *yco-66, 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");
*xco+60, *yco-(66+yoffset), 55, 18, &ct->space, 0, 0, 0, 0, "Choose space that target is evaluated in");
}
uiBlockBeginAlign(block);
@ -600,11 +601,11 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
/* subtarget */
if (is_armature_target(ct->tar)) {
but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-66,150,18, &ct->subtarget, 0, 24, 0, 0, "Subtarget Bone");
but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "BO:", *xco+120, *yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Subtarget Bone");
uiButSetCompleteFunc(but, autocomplete_bone, (void *)ct->tar);
}
else if (is_geom_target(ct->tar)) {
but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-66,150,18, &ct->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
but= uiDefBut(block, TEX, B_CONSTRAINT_CHANGETARGET, "VG:", *xco+120, *yco-(66+yoffset),150,18, &ct->subtarget, 0, 24, 0, 0, "Name of Vertex Group defining 'target' points");
uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ct->tar);
}
else {
@ -625,7 +626,6 @@ static void draw_constraint (uiBlock *block, ListBase *list, bConstraint *con, s
uiButSetFunc(but, BPY_pyconstraint_settings, data, NULL);
but=uiDefBut(block, BUT, B_CONSTRAINT_TEST, "Refresh", *xco+((width/2)+10), *yco-(52+theight), (width/2),18, NULL, 0, 24, 0, 0, "Force constraint to refresh it's settings");
uiButSetFunc(but, update_pyconstraint_cb, ob, con);
uiBlockEndAlign(block);
/* constraint space settings */

@ -1074,10 +1074,10 @@ void delete_armature(void)
bConstraint *con;
TEST_EDITARMATURE;
if(okee("Erase selected bone(s)")==0) return;
if (okee("Erase selected bone(s)")==0) return;
/* First erase any associated pose channel */
if (G.obedit->pose){
if (G.obedit->pose) {
bPoseChannel *chan, *next;
for (chan=G.obedit->pose->chanbase.first; chan; chan=next) {
next= chan->next;
@ -1088,14 +1088,28 @@ void delete_armature(void)
BLI_freelinkN (&G.obedit->pose->chanbase, chan);
}
else {
for(con= chan->constraints.first; con; con= con->next) {
char *subtarget = get_con_subtarget_name(con, G.obedit);
if (subtarget) {
curBone = editbone_name_exists (&G.edbo, subtarget);
if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
con->flag |= CONSTRAINT_DISABLE;
subtarget[0]= 0;
for (con= chan->constraints.first; con; con= con->next) {
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
for (ct= targets.first; ct; ct= ct->next) {
if (ct->tar == G.obedit) {
if (ct->subtarget[0]) {
curBone = editbone_name_exists(&G.edbo, ct->subtarget);
if (curBone && (curBone->flag & BONE_SELECTED) && (arm->layer & curBone->layer)) {
con->flag |= CONSTRAINT_DISABLE;
ct->subtarget[0]= 0;
}
}
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
}
}
@ -1103,9 +1117,9 @@ void delete_armature(void)
}
for (curBone=G.edbo.first;curBone;curBone=next){
for (curBone=G.edbo.first;curBone;curBone=next) {
next=curBone->next;
if(arm->layer & curBone->layer)
if (arm->layer & curBone->layer)
if (curBone->flag & BONE_SELECTED)
delete_bone(curBone);
}
@ -1637,28 +1651,43 @@ static void update_dup_subtarget(EditBone *dupBone)
bPoseChannel *chan;
bConstraint *curcon;
ListBase *conlist;
char *subname;
if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) )
if ( (conlist = &chan->constraints) )
if ( (chan = verify_pose_channel(OBACT->pose, dupBone->name)) ) {
if ( (conlist = &chan->constraints) ) {
for (curcon = conlist->first; curcon; curcon=curcon->next) {
/* does this constraint have a subtarget in
* this armature?
*/
subname = get_con_subtarget_name(curcon, G.obedit);
oldtarget = get_named_editbone(subname);
if (oldtarget)
/* was the subtarget bone duplicated too? If
* so, update the constraint to point at the
* duplicate of the old subtarget.
*/
if (oldtarget->flag & BONE_SELECTED){
newtarget = (EditBone*) oldtarget->temp;
strcpy(subname, newtarget->name);
bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(curcon, &targets);
for (ct= targets.first; ct; ct= ct->next) {
if ((ct->tar == G.obedit) && (ct->subtarget[0])) {
oldtarget = get_named_editbone(ct->subtarget);
if (oldtarget) {
/* was the subtarget bone duplicated too? If
* so, update the constraint to point at the
* duplicate of the old subtarget.
*/
if (oldtarget->flag & BONE_SELECTED){
newtarget = (EditBone *) oldtarget->temp;
strcpy(ct->subtarget, newtarget->name);
}
}
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(curcon, &targets, 0);
}
}
}
}
}
@ -2889,13 +2918,25 @@ void unique_bone_name (bArmature *arm, char *name)
static void constraint_bone_name_fix(Object *ob, ListBase *conlist, char *oldname, char *newname)
{
bConstraint *curcon;
char *subtarget;
bConstraintTarget *ct;
for (curcon = conlist->first; curcon; curcon=curcon->next){
subtarget = get_con_subtarget_name(curcon, ob);
if (subtarget)
if (!strcmp(subtarget, oldname) )
BLI_strncpy(subtarget, newname, MAXBONENAME);
for (curcon = conlist->first; curcon; curcon=curcon->next) {
bConstraintTypeInfo *cti= constraint_get_typeinfo(curcon);
ListBase targets = {NULL, NULL};
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(curcon, &targets);
for (ct= targets.first; ct; ct= ct->next) {
if (ct->tar == ob) {
if (!strcmp(ct->subtarget, oldname) )
BLI_strncpy(ct->subtarget, newname, MAXBONENAME);
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(curcon, &targets, 0);
}
}
}

@ -253,51 +253,6 @@ void add_constraint_to_object(bConstraint *con, Object *ob)
}
}
char *get_con_subtarget_name(bConstraint *con, Object *target)
{
bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
static char subtarget[32];
/* If the target for this constraint is target, return a pointer
* to the name for this constraints subtarget ... NULL otherwise
*/
if (target == NULL)
return NULL;
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
for (ct= targets.first; ct; ct= ct->next) {
if (ct->tar == target) {
if (ct->flag & CONSTRAINT_TAR_TEMP) {
/* as temporary targets were created, we can't point to thier subtarget,
* a local copy is made here... this should be ok as long as this function
* is not called twice with expectations that the string will stay the same
*/
strcpy(subtarget, ct->subtarget);
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 1);
return &(subtarget[0]);
}
else {
/* not temporary, so we can return a direct pointer to it */
return &(ct->subtarget[0]);
}
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
return NULL;
}
/* checks validity of object pointers, and NULLs,
* if Bone doesnt exist it sets the CONSTRAINT_DISABLE flag
*/