Armature: add armature dissolve

Works like mesh dissolve (access from delete or Ctrl+X)
This commit is contained in:
Campbell Barton
2015-06-13 03:20:07 +10:00
parent 07562a4afb
commit 1b8a785d83
7 changed files with 260 additions and 48 deletions

View File

@@ -140,6 +140,10 @@ void BKE_pose_channels_free_ex(struct bPose *pose, bool do_id_us
void BKE_pose_channels_hash_make(struct bPose *pose);
void BKE_pose_channels_hash_free(struct bPose *pose);
void BKE_pose_channels_remove(
struct Object *ob,
bool (*filter_fn)(const char *bone_name, void *user_data), void *user_data);
void BKE_pose_free(struct bPose *pose);
void BKE_pose_free_ex(struct bPose *pose, bool do_id_user);
void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints);

View File

@@ -716,6 +716,57 @@ void BKE_pose_channels_hash_free(bPose *pose)
}
}
/**
* Selectively remove pose channels.
*/
void BKE_pose_channels_remove(
Object *ob,
bool (*filter_fn)(const char *bone_name, void *user_data), void *user_data)
{
/* First erase any associated pose channel */
if (ob->pose) {
bPoseChannel *pchan, *pchan_next;
bConstraint *con;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan_next) {
pchan_next = pchan->next;
if (filter_fn(pchan->name, user_data)) {
BKE_pose_channel_free(pchan);
if (ob->pose->chanhash) {
BLI_ghash_remove(ob->pose->chanhash, pchan->name, NULL, NULL);
}
BLI_freelinkN(&ob->pose->chanbase, pchan);
}
else {
for (con = pchan->constraints.first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(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) {
if (ct->subtarget[0]) {
if (filter_fn(ct->subtarget, user_data)) {
con->flag |= CONSTRAINT_DISABLE;
ct->subtarget[0] = 0;
}
}
}
}
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
}
}
}
}
}
/**
* Deallocates a pose channel.
* Does not free the pose channel itself.