/* helper call for armature_bone_rename */ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *oldname, const char *newname) { bConstraint *curcon; bConstraintTarget *ct; for (curcon = conlist->first; curcon; curcon = curcon->next) { bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(curcon); ListBase targets = {NULL, NULL}; /* constraint targets */ 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 (STREQ(ct->subtarget, oldname)) { BLI_strncpy(ct->subtarget, newname, MAXBONENAME); } } } if (cti->flush_constraint_targets) cti->flush_constraint_targets(curcon, &targets, 0); } /* action constraints */ if (curcon->type == CONSTRAINT_TYPE_ACTION) { bActionConstraint *actcon = (bActionConstraint *)curcon->data; BKE_action_fix_paths_rename(&ob->id, actcon->act, "pose.bones", oldname, newname, 0, 0, 1); } } }
static int pose_select_constraint_target_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); bArmature *arm = (bArmature *)ob->data; bConstraint *con; int found = 0; CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones) { if (pchan->bone->flag & BONE_SELECTED) { for (con = pchan->constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = BKE_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 == ob) && (ct->subtarget[0])) { bPoseChannel *pchanc = BKE_pose_channel_find_name(ob->pose, ct->subtarget); if ((pchanc) && !(pchanc->bone->flag & BONE_UNSELECTABLE)) { pchanc->bone->flag |= BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL; found = 1; } } } if (cti->flush_constraint_targets) cti->flush_constraint_targets(con, &targets, 1); } } } } CTX_DATA_END; if (!found) return OPERATOR_CANCELLED; /* updates */ WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); if (arm->flag & ARM_HAS_VIZ_DEPS) { /* mask modifier ('armature' mode), etc. */ DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } return OPERATOR_FINISHED; }
/* * Note: When duplicating cross objects, editbones here is the list of bones * from the SOURCE object but ob is the DESTINATION object * */ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Object *src_ob, Object *dst_ob) { /* If an edit bone has been duplicated, lets * update it's constraints if the subtarget * they point to has also been duplicated */ EditBone *oldtarget, *newtarget; bPoseChannel *pchan; bConstraint *curcon; ListBase *conlist; if ((pchan = BKE_pose_channel_verify(dst_ob->pose, dupBone->name))) { if ((conlist = &pchan->constraints)) { for (curcon = conlist->first; curcon; curcon = curcon->next) { /* does this constraint have a subtarget in * this armature? */ bConstraintTypeInfo *cti = BKE_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 == src_ob) && (ct->subtarget[0])) { ct->tar = dst_ob; /* update target */ oldtarget = get_named_editbone(editbones, 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->temp) { newtarget = (EditBone *) oldtarget->temp; BLI_strncpy(ct->subtarget, newtarget->name, sizeof(ct->subtarget)); } } } } if (cti->flush_constraint_targets) cti->flush_constraint_targets(curcon, &targets, 0); } } } } }
/* helper call for armature_bone_rename */ static void constraint_bone_name_fix(Object *ob, ListBase *conlist, const char *oldname, const char *newname) { bConstraint *curcon; bConstraintTarget *ct; for (curcon = conlist->first; curcon; curcon = curcon->next) { bConstraintTypeInfo *cti = BKE_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); } } }
/* Helper function for armature joining - link fixing */ static void joined_armature_fix_links(Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone) { Object *ob; bPose *pose; bPoseChannel *pchant; bConstraint *con; /* let's go through all objects in database */ for (ob = G.main->object.first; ob; ob = ob->id.next) { /* do some object-type specific things */ if (ob->type == OB_ARMATURE) { pose = ob->pose; for (pchant = pose->chanbase.first; pchant; pchant = pchant->next) { for (con = pchant->constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == srcArm) { if (ct->subtarget[0] == '\0') { ct->tar = tarArm; } else if (strcmp(ct->subtarget, pchan->name) == 0) { ct->tar = tarArm; BLI_strncpy(ct->subtarget, curbone->name, sizeof(ct->subtarget)); } } } if (cti->flush_constraint_targets) cti->flush_constraint_targets(con, &targets, 0); } /* action constraint? */ if (con->type == CONSTRAINT_TYPE_ACTION) { bActionConstraint *data = con->data; // XXX old animation system bAction *act; bActionChannel *achan; if (data->act) { act = data->act; for (achan = act->chanbase.first; achan; achan = achan->next) { if (strcmp(achan->name, pchan->name) == 0) BLI_strncpy(achan->name, curbone->name, sizeof(achan->name)); } } } } } } /* fix object-level constraints */ if (ob != srcArm) { for (con = ob->constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); for (ct = targets.first; ct; ct = ct->next) { if (ct->tar == srcArm) { if (ct->subtarget[0] == '\0') { ct->tar = tarArm; } else if (strcmp(ct->subtarget, pchan->name) == 0) { ct->tar = tarArm; BLI_strncpy(ct->subtarget, curbone->name, sizeof(ct->subtarget)); } } } if (cti->flush_constraint_targets) cti->flush_constraint_targets(con, &targets, 0); } } } /* See if an object is parented to this armature */ if (ob->parent && (ob->parent == srcArm)) { /* Is object parented to a bone of this src armature? */ if (ob->partype == PARBONE) { /* bone name in object */ if (!strcmp(ob->parsubstr, pchan->name)) BLI_strncpy(ob->parsubstr, curbone->name, sizeof(ob->parsubstr)); } /* make tar armature be new parent */ ob->parent = tarArm; } } }
/* Helper function for armature separating - link fixing */ static void separated_armature_fix_links(Object *origArm, Object *newArm) { Object *ob; bPoseChannel *pchan; bConstraint *con; ListBase *opchans, *npchans; /* get reference to list of bones in original and new armatures */ opchans = &origArm->pose->chanbase; npchans = &newArm->pose->chanbase; /* let's go through all objects in database */ for (ob = G.main->object.first; ob; ob = ob->id.next) { /* do some object-type specific things */ if (ob->type == OB_ARMATURE) { for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); for (ct = targets.first; ct; ct = ct->next) { /* any targets which point to original armature are redirected to the new one only if: * - the target isn't origArm/newArm itself * - the target is one that can be found in newArm/origArm */ if (ct->subtarget[0] != 0) { if (ct->tar == origArm) { if (BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) { ct->tar = newArm; } } else if (ct->tar == newArm) { if (BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) { ct->tar = origArm; } } } } if (cti->flush_constraint_targets) { cti->flush_constraint_targets(con, &targets, 0); } } } } } /* fix object-level constraints */ if (ob != origArm) { for (con = ob->constraints.first; con; con = con->next) { bConstraintTypeInfo *cti = BKE_constraint_get_typeinfo(con); ListBase targets = {NULL, NULL}; bConstraintTarget *ct; /* constraint targets */ if (cti && cti->get_constraint_targets) { cti->get_constraint_targets(con, &targets); for (ct = targets.first; ct; ct = ct->next) { /* any targets which point to original armature are redirected to the new one only if: * - the target isn't origArm/newArm itself * - the target is one that can be found in newArm/origArm */ if (ct->subtarget[0] != '\0') { if (ct->tar == origArm) { if (BLI_findstring(npchans, ct->subtarget, offsetof(bPoseChannel, name))) { ct->tar = newArm; } } else if (ct->tar == newArm) { if (BLI_findstring(opchans, ct->subtarget, offsetof(bPoseChannel, name))) { ct->tar = origArm; } } } } if (cti->flush_constraint_targets) { cti->flush_constraint_targets(con, &targets, 0); } } } } /* See if an object is parented to this armature */ if (ob->parent && (ob->parent == origArm)) { /* Is object parented to a bone of this src armature? */ if ((ob->partype == PARBONE) && (ob->parsubstr[0] != '\0')) { if (BLI_findstring(npchans, ob->parsubstr, offsetof(bPoseChannel, name))) { ob->parent = newArm; } } } } }