This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/armature/pose_utils.c

294 lines
8.9 KiB
C
Raw Normal View History

/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2009, Blender Foundation, Joshua Leung
* This is a new part of Blender
*
* Contributor(s): Joshua Leung
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/editors/armature/pose_utils.c
2011-02-27 20:29:51 +00:00
* \ingroup edarmature
*/
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
#include "BKE_context.h"
#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_armature.h"
#include "ED_keyframing.h"
#include "armature_intern.h"
/* *********************************************** */
/* Contents of this File:
*
* This file contains methods shared between Pose Slide and Pose Lib;
* primarily the functions in question concern Animato <-> Pose
* convenience functions, such as applying/getting pose values
* and/or inserting keyframes for these.
*/
/* *********************************************** */
/* FCurves <-> PoseChannels Links */
/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */
2012-05-08 20:18:33 +00:00
static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *act, bPoseChannel *pchan)
{
ListBase curves = {NULL, NULL};
int transFlags = action_get_item_transforms(act, ob, pchan, &curves);
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
/* check if any transforms found... */
if (transFlags) {
/* make new linkage data */
2012-05-08 20:18:33 +00:00
tPChanFCurveLink *pfl = MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
PointerRNA ptr;
2012-05-08 20:18:33 +00:00
pfl->fcurves = curves;
pfl->pchan = pchan;
/* get the RNA path to this pchan - this needs to be freed! */
RNA_pointer_create((ID *)ob, &RNA_PoseBone, pchan, &ptr);
2012-05-08 20:18:33 +00:00
pfl->pchan_path = RNA_path_from_ID_to_struct(&ptr);
/* add linkage data to operator data */
BLI_addtail(pfLinks, pfl);
/* set pchan's transform flags */
if (transFlags & ACT_TRANS_LOC)
pchan->flag |= POSE_LOC;
if (transFlags & ACT_TRANS_ROT)
pchan->flag |= POSE_ROT;
if (transFlags & ACT_TRANS_SCALE)
pchan->flag |= POSE_SIZE;
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
if (transFlags & ACT_TRANS_BBONE)
pchan->flag |= POSE_BBONE_SHAPE;
/* store current transforms */
copy_v3_v3(pfl->oldloc, pchan->loc);
copy_v3_v3(pfl->oldrot, pchan->eul);
copy_v3_v3(pfl->oldscale, pchan->size);
copy_qt_qt(pfl->oldquat, pchan->quat);
copy_v3_v3(pfl->oldaxis, pchan->rotAxis);
pfl->oldangle = pchan->rotAngle;
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
/* store current bbone values */
pfl->roll1 = pchan->roll1;
pfl->roll2 = pchan->roll2;
pfl->curveInX = pchan->curveInX;
pfl->curveInY = pchan->curveInY;
pfl->curveOutX = pchan->curveOutX;
pfl->curveOutY = pchan->curveOutY;
pfl->scaleIn = pchan->scaleIn;
pfl->scaleOut = pchan->scaleOut;
/* make copy of custom properties */
if (pchan->prop && (transFlags & ACT_TRANS_PROP))
pfl->oldprops = IDP_CopyProperty(pchan->prop);
}
}
/* get sets of F-Curves providing transforms for the bones in the Pose */
void poseAnim_mapping_get(bContext *C, ListBase *pfLinks, Object *ob, bAction *act)
{
/* for each Pose-Channel which gets affected, get the F-Curves for that channel
* and set the relevant transform flags...
*/
2012-05-08 20:18:33 +00:00
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, selected_pose_bones)
{
fcurves_to_pchan_links_get(pfLinks, ob, act, pchan);
}
CTX_DATA_END;
/* if no PoseChannels were found, try a second pass, doing visible ones instead
* i.e. if nothing selected, do whole pose
*/
if (BLI_listbase_is_empty(pfLinks)) {
2012-05-08 20:18:33 +00:00
CTX_DATA_BEGIN (C, bPoseChannel *, pchan, visible_pose_bones)
{
fcurves_to_pchan_links_get(pfLinks, ob, act, pchan);
}
CTX_DATA_END;
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
}
}
/* free F-Curve <-> PoseChannel links */
void poseAnim_mapping_free(ListBase *pfLinks)
{
2012-05-08 20:18:33 +00:00
tPChanFCurveLink *pfl, *pfln = NULL;
/* free the temp pchan links and their data */
2012-05-08 20:18:33 +00:00
for (pfl = pfLinks->first; pfl; pfl = pfln) {
pfln = pfl->next;
/* free custom properties */
if (pfl->oldprops) {
IDP_FreeProperty(pfl->oldprops);
MEM_freeN(pfl->oldprops);
}
/* free list of F-Curve reference links */
BLI_freelistN(&pfl->fcurves);
/* free pchan RNA Path */
MEM_freeN(pfl->pchan_path);
/* free link itself */
BLI_freelinkN(pfLinks, pfl);
}
}
/* ------------------------- */
/* helper for apply() / reset() - refresh the data */
void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob)
{
2012-05-08 20:18:33 +00:00
bArmature *arm = (bArmature *)ob->data;
/* old optimize trick... this enforces to bypass the depgraph
* - note: code copied from transform_generics.c -> recalcData()
*/
2012-07-07 22:51:57 +00:00
/* FIXME: shouldn't this use the builtin stuff? */
2012-05-08 20:18:33 +00:00
if ((arm->flag & ARM_DELAYDEFORM) == 0)
DAG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
else
BKE_pose_where_is(scene, ob);
/* note, notifier might evolve */
2012-05-08 20:18:33 +00:00
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
/* reset changes made to current pose */
void poseAnim_mapping_reset(ListBase *pfLinks)
{
tPChanFCurveLink *pfl;
/* iterate over each pose-channel affected, restoring all channels to their original values */
2012-05-08 20:18:33 +00:00
for (pfl = pfLinks->first; pfl; pfl = pfl->next) {
bPoseChannel *pchan = pfl->pchan;
/* just copy all the values over regardless of whether they changed or not */
copy_v3_v3(pchan->loc, pfl->oldloc);
copy_v3_v3(pchan->eul, pfl->oldrot);
copy_v3_v3(pchan->size, pfl->oldscale);
copy_qt_qt(pchan->quat, pfl->oldquat);
copy_v3_v3(pchan->rotAxis, pfl->oldaxis);
pchan->rotAngle = pfl->oldangle;
Bendy Bones: Advanced B-Bones for Easier + Simple Rigging This commit/patch/branch brings a bunch of powerful new options for B-Bones and for working with B-Bones, making it easier for animators to create their own rigs, using fewer bones (which also means hopefully lighter + faster rigs ;) This functionality was first demoed by Daniel at BConf15 Some highlights from this patch include: * You can now directly control the shape of B-Bones using a series of properties instead of being restricted to trying to indirectly control them through the neighbouring bones. See the "Bendy Bones" panel... * B-Bones can be shaped in EditMode to define a "curved rest pose" for the bone. This is useful for things like eyebrows and mouths/eyelids * You can now make B-Bones use custom bones as their reference bone handles, instead of only using the parent/child bones. To do so, enable the "Use Custom Reference Handles" toggle. If none are specified, then the BBone will only use the Bendy Bone properties. * Constraints Head/Tail option can now slide along the B-Bone shape, instead of just linearly interpolating between the endpoints of the bone. For more details, see: * http://aligorith.blogspot.co.nz/2016/05/bendy-bones-dev-update.html * http://aligorith.blogspot.co.nz/2016/05/an-in-depth-look-at-how-b-bones-work.html -- Credits -- Original Idea: Daniel M Lara (pepeland) Original Patch/Research: Jose Molina Additional Development + Polish: Joshua Leung (aligorith) Testing/Feedback: Daniel M Lara (pepeland), Juan Pablo Bouza (jpbouza)
2016-05-18 03:19:06 +12:00
/* store current bbone values */
pchan->roll1 = pfl->roll1;
pchan->roll2 = pfl->roll2;
pchan->curveInX = pfl->curveInX;
pchan->curveInY = pfl->curveInY;
pchan->curveOutX = pfl->curveOutX;
pchan->curveOutY = pfl->curveOutY;
pchan->scaleIn = pfl->scaleIn;
pchan->scaleOut = pfl->scaleOut;
/* just overwrite values of properties from the stored copies (there should be some) */
if (pfl->oldprops)
IDP_SyncGroupValues(pfl->pchan->prop, pfl->oldprops);
}
}
/* perform autokeyframing after changes were made + confirmed */
void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBase *pfLinks, float cframe)
{
/* insert keyframes as necessary if autokeyframing */
if (autokeyframe_cfra_can_key(scene, &ob->id)) {
KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_WHOLE_CHARACTER_ID);
ListBase dsources = {NULL, NULL};
tPChanFCurveLink *pfl;
/* iterate over each pose-channel affected, tagging bones to be keyed */
/* XXX: here we already have the information about what transforms exist, though
* it might be easier to just overwrite all using normal mechanisms
*/
2012-05-08 20:18:33 +00:00
for (pfl = pfLinks->first; pfl; pfl = pfl->next) {
bPoseChannel *pchan = pfl->pchan;
/* add datasource override for the PoseChannel, to be used later */
== Massive Keying Sets Recode == After a few days of wrong turns and learning the finer points of RNA-type-subclassing the hard way, this commit finally presents a refactored version of the Keying Sets system (now version 2) based on some requirements from Cessen. For a more thorough discussion of this commit, see http://sites.google.com/site/aligorith/keyingsets_2.pdf?attredirects=0&d=1 ------ The main highlight of this refactor is that relative Keying Sets have now been recoded so that Python callbacks are run to generate the Keying Set's list of paths everytime the Keying Set is used (to insert or delete keyframes), allowing complex heuristics to be used to determine whether a property gets keyframed based on the current context. These checks may include checking on selection status of related entities, or transform locks. Built-In KeyingSets have also been recoded, and moved from C and out into Python. These are now coded as Relative Keying Sets, and can to some extent serve as basis for adding new relative Keying Sets. However, these have mostly been coded in a slightly 'modular' way which may be confusing for those not so familiar with Python in general. A usable template will be added soon for more general usage. Keyframing settings (i.e. 'visual', 'needed') can now be specified on a per-path basis now, which is especially useful for Absolute Keying Sets, where control over this is often beneficial. Most of the places where Auto-Keyframing is performed have been tidied up for consistency. I'm sure quite a few issues still exist there, but these I'll clean up over the next few days.
2010-03-16 06:18:49 +00:00
ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
/* clear any unkeyed tags */
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
}
/* insert keyframes for all relevant bones in one go */
ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cframe);
BLI_freelistN(&dsources);
/* do the bone paths
* - only do this if keyframes should have been added
* - do not calculate unless there are paths already to update...
*/
if (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) {
//ED_pose_clear_paths(C, ob); // XXX for now, don't need to clear
ED_pose_recalculate_paths(scene, ob);
}
}
}
/* ------------------------- */
/* find the next F-Curve for a PoseChannel with matching path...
* - path is not just the pfl rna_path, since that path doesn't have property info yet
*/
2012-05-08 20:18:33 +00:00
LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, const char *path)
{
2012-05-08 20:18:33 +00:00
LinkData *first = (prev) ? prev->next : (fcuLinks) ? fcuLinks->first : NULL;
LinkData *ld;
/* check each link to see if the linked F-Curve has a matching path */
2012-05-08 20:18:33 +00:00
for (ld = first; ld; ld = ld->next) {
FCurve *fcu = (FCurve *)ld->data;
/* check if paths match */
if (STREQ(path, fcu->rna_path))
return ld;
}
/* none found */
return NULL;
}
/* *********************************************** */