Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/armature/pose_utils.c')
-rw-r--r--source/blender/editors/armature/pose_utils.c498
1 files changed, 246 insertions, 252 deletions
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index 25ddcee52cf..d8793bc2a1e 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -63,64 +63,67 @@
/* FCurves <-> PoseChannels Links */
/* helper for poseAnim_mapping_get() -> get the relevant F-Curves per PoseChannel */
-static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *act, bPoseChannel *pchan)
+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);
-
- pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
-
- /* check if any transforms found... */
- if (transFlags) {
- /* make new linkage data */
- tPChanFCurveLink *pfl = MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
- PointerRNA ptr;
-
- pfl->ob = ob;
- 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);
- 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;
- 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;
-
- /* 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->ease1 = pchan->ease1;
- pfl->ease2 = pchan->ease2;
- 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);
- }
+ ListBase curves = {NULL, NULL};
+ int transFlags = action_get_item_transforms(act, ob, pchan, &curves);
+
+ pchan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE | POSE_BBONE_SHAPE);
+
+ /* check if any transforms found... */
+ if (transFlags) {
+ /* make new linkage data */
+ tPChanFCurveLink *pfl = MEM_callocN(sizeof(tPChanFCurveLink), "tPChanFCurveLink");
+ PointerRNA ptr;
+
+ pfl->ob = ob;
+ 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);
+ 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;
+ 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;
+
+ /* 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->ease1 = pchan->ease1;
+ pfl->ease2 = pchan->ease2;
+ 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);
+ }
}
/**
@@ -128,96 +131,85 @@ static void fcurves_to_pchan_links_get(ListBase *pfLinks, Object *ob, bAction *a
*/
Object *poseAnim_object_get(Object *ob_)
{
- Object *ob = BKE_object_pose_armature_get(ob_);
- if (!ELEM(NULL,
- ob,
- ob->data,
- ob->adt,
- ob->adt->action))
- {
- return ob;
- }
- return NULL;
+ Object *ob = BKE_object_pose_armature_get(ob_);
+ if (!ELEM(NULL, ob, ob->data, ob->adt, ob->adt->action)) {
+ return ob;
+ }
+ return NULL;
}
/* get sets of F-Curves providing transforms for the bones in the Pose */
void poseAnim_mapping_get(bContext *C, ListBase *pfLinks)
{
- /* for each Pose-Channel which gets affected, get the F-Curves for that channel
- * and set the relevant transform flags...
- */
- Object *prev_ob, *ob_pose_armature;
-
- prev_ob = NULL;
- ob_pose_armature = NULL;
- CTX_DATA_BEGIN_WITH_ID (C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob)
- {
- if (ob != prev_ob) {
- prev_ob = ob;
- ob_pose_armature = poseAnim_object_get(ob);
- }
-
- if (ob_pose_armature == NULL) {
- continue;
- }
-
- fcurves_to_pchan_links_get(pfLinks,
- ob_pose_armature,
- ob_pose_armature->adt->action,
- 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)) {
- prev_ob = NULL;
- ob_pose_armature = NULL;
- CTX_DATA_BEGIN_WITH_ID(C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob)
- {
- if (ob != prev_ob) {
- prev_ob = ob;
- ob_pose_armature = poseAnim_object_get(ob);
- }
-
- if (ob_pose_armature == NULL) {
- continue;
- }
-
- fcurves_to_pchan_links_get(pfLinks,
- ob_pose_armature,
- ob_pose_armature->adt->action,
- pchan);
- }
- CTX_DATA_END;
- }
+ /* for each Pose-Channel which gets affected, get the F-Curves for that channel
+ * and set the relevant transform flags...
+ */
+ Object *prev_ob, *ob_pose_armature;
+
+ prev_ob = NULL;
+ ob_pose_armature = NULL;
+ CTX_DATA_BEGIN_WITH_ID(C, bPoseChannel *, pchan, selected_pose_bones, Object *, ob)
+ {
+ if (ob != prev_ob) {
+ prev_ob = ob;
+ ob_pose_armature = poseAnim_object_get(ob);
+ }
+
+ if (ob_pose_armature == NULL) {
+ continue;
+ }
+
+ fcurves_to_pchan_links_get(pfLinks, ob_pose_armature, ob_pose_armature->adt->action, 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)) {
+ prev_ob = NULL;
+ ob_pose_armature = NULL;
+ CTX_DATA_BEGIN_WITH_ID(C, bPoseChannel *, pchan, visible_pose_bones, Object *, ob)
+ {
+ if (ob != prev_ob) {
+ prev_ob = ob;
+ ob_pose_armature = poseAnim_object_get(ob);
+ }
+
+ if (ob_pose_armature == NULL) {
+ continue;
+ }
+
+ fcurves_to_pchan_links_get(pfLinks, ob_pose_armature, ob_pose_armature->adt->action, pchan);
+ }
+ CTX_DATA_END;
+ }
}
/* free F-Curve <-> PoseChannel links */
void poseAnim_mapping_free(ListBase *pfLinks)
{
- tPChanFCurveLink *pfl, *pfln = NULL;
+ tPChanFCurveLink *pfl, *pfln = NULL;
- /* free the temp pchan links and their data */
- for (pfl = pfLinks->first; pfl; pfl = pfln) {
- pfln = pfl->next;
+ /* free the temp pchan links and their data */
+ 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 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 list of F-Curve reference links */
+ BLI_freelistN(&pfl->fcurves);
- /* free pchan RNA Path */
- MEM_freeN(pfl->pchan_path);
+ /* free pchan RNA Path */
+ MEM_freeN(pfl->pchan_path);
- /* free link itself */
- BLI_freelinkN(pfLinks, pfl);
- }
+ /* free link itself */
+ BLI_freelinkN(pfLinks, pfl);
+ }
}
/* ------------------------- */
@@ -225,125 +217,127 @@ void poseAnim_mapping_free(ListBase *pfLinks)
/* helper for apply() / reset() - refresh the data */
void poseAnim_mapping_refresh(bContext *C, Scene *scene, Object *ob)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- bArmature *arm = (bArmature *)ob->data;
-
- /* old optimize trick... this enforces to bypass the depgraph
- * - note: code copied from transform_generics.c -> recalcData()
- */
- /* FIXME: shouldn't this use the builtin stuff? */
- if ((arm->flag & ARM_DELAYDEFORM) == 0)
- DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); /* sets recalc flags */
- else
- BKE_pose_where_is(depsgraph, scene, ob);
-
- /* otherwise animation doesn't get updated */
- DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ bArmature *arm = (bArmature *)ob->data;
+
+ /* old optimize trick... this enforces to bypass the depgraph
+ * - note: code copied from transform_generics.c -> recalcData()
+ */
+ /* FIXME: shouldn't this use the builtin stuff? */
+ if ((arm->flag & ARM_DELAYDEFORM) == 0)
+ DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); /* sets recalc flags */
+ else
+ BKE_pose_where_is(depsgraph, scene, ob);
+
+ /* otherwise animation doesn't get updated */
+ DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE);
+ 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 */
- 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;
-
- /* 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->ease1 = pfl->ease1;
- pchan->ease2 = pfl->ease2;
- 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);
- }
+ tPChanFCurveLink *pfl;
+
+ /* iterate over each pose-channel affected, restoring all channels to their original values */
+ 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;
+
+ /* 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->ease1 = pfl->ease1;
+ pchan->ease2 = pfl->ease2;
+ 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 auto-key-framing after changes were made + confirmed */
void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks, float cframe)
{
- ViewLayer *view_layer = CTX_data_view_layer(C);
- View3D *v3d = CTX_wm_view3d(C);
- bool skip = true;
-
- FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
- ob->id.tag &= ~LIB_TAG_DOIT;
- ob = poseAnim_object_get(ob);
-
- /* Ensure validity of the settings from the context. */
- if (ob == NULL) {
- continue;
- }
-
- if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- ob->id.tag |= LIB_TAG_DOIT;
- skip = false;
- }
- } FOREACH_OBJECT_IN_MODE_END;
-
- if (skip) {
- return;
- }
-
- /* Insert keyframes as necessary if auto-key-framing. */
- 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
- */
- for (pfl = pfLinks->first; pfl; pfl = pfl->next) {
- bPoseChannel *pchan = pfl->pchan;
-
- if ((pfl->ob->id.tag & LIB_TAG_DOIT) == 0) {
- continue;
- }
-
- /* add datasource override for the PoseChannel, to be used later */
- ANIM_relative_keyingset_add_source(&dsources, &pfl->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...
- */
- FOREACH_OBJECT_IN_MODE_BEGIN(view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
- if (ob->id.tag & LIB_TAG_DOIT) {
- 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(C, scene, ob, false);
- }
- }
- } FOREACH_OBJECT_IN_MODE_END;
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ bool skip = true;
+
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ ob->id.tag &= ~LIB_TAG_DOIT;
+ ob = poseAnim_object_get(ob);
+
+ /* Ensure validity of the settings from the context. */
+ if (ob == NULL) {
+ continue;
+ }
+
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+ ob->id.tag |= LIB_TAG_DOIT;
+ skip = false;
+ }
+ }
+ FOREACH_OBJECT_IN_MODE_END;
+
+ if (skip) {
+ return;
+ }
+
+ /* Insert keyframes as necessary if auto-key-framing. */
+ 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
+ */
+ for (pfl = pfLinks->first; pfl; pfl = pfl->next) {
+ bPoseChannel *pchan = pfl->pchan;
+
+ if ((pfl->ob->id.tag & LIB_TAG_DOIT) == 0) {
+ continue;
+ }
+
+ /* add datasource override for the PoseChannel, to be used later */
+ ANIM_relative_keyingset_add_source(&dsources, &pfl->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...
+ */
+ FOREACH_OBJECT_IN_MODE_BEGIN (view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) {
+ if (ob->id.tag & LIB_TAG_DOIT) {
+ 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(C, scene, ob, false);
+ }
+ }
+ }
+ FOREACH_OBJECT_IN_MODE_END;
}
/* ------------------------- */
@@ -353,20 +347,20 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, ListBase *pfLinks,
*/
LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, const char *path)
{
- LinkData *first = (prev) ? prev->next : (fcuLinks) ? fcuLinks->first : NULL;
- LinkData *ld;
+ 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 */
- for (ld = first; ld; ld = ld->next) {
- FCurve *fcu = (FCurve *)ld->data;
+ /* check each link to see if the linked F-Curve has a matching path */
+ for (ld = first; ld; ld = ld->next) {
+ FCurve *fcu = (FCurve *)ld->data;
- /* check if paths match */
- if (STREQ(path, fcu->rna_path))
- return ld;
- }
+ /* check if paths match */
+ if (STREQ(path, fcu->rna_path))
+ return ld;
+ }
- /* none found */
- return NULL;
+ /* none found */
+ return NULL;
}
/* *********************************************** */