diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-06-12 20:20:07 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-06-12 20:24:07 +0300 |
commit | 1b8a785d83c85c2b9d605985c377191663ea13fb (patch) | |
tree | e034491af83b51862fcfa0eb294a39c6667f597d /source/blender/blenkernel/intern/action.c | |
parent | 07562a4afb301cf61bdaf9ed4b2b0f37150da6dd (diff) |
Armature: add armature dissolve
Works like mesh dissolve (access from delete or Ctrl+X)
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 7e09ad355a7..1b73978b524 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -717,6 +717,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. */ |