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:
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py7
-rw-r--r--source/blender/editors/armature/poseSlide.c54
-rw-r--r--source/blender/editors/armature/poseUtils.c12
-rw-r--r--source/blender/editors/space_action/action_select.c2
-rw-r--r--source/blender/editors/space_graph/graph_select.c2
5 files changed, 68 insertions, 9 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index f026a26c984..13270a8c6fd 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -1258,9 +1258,16 @@ class VIEW3D_MT_pose_propagate(bpy.types.Menu):
layout = self.layout
layout.operator("pose.propagate")
+
+ layout.separator()
+
layout.operator("pose.propagate", text="To Next Keyframe").mode = 'NEXT_KEY'
layout.operator("pose.propagate", text="To Last Keyframe (Make Cyclic)").mode = 'LAST_KEY'
+ layout.separator()
+
+ layout.operator("pose.propagate", text="On Selected Markers").mode = 'SELECTED_MARKERS'
+
class VIEW3D_MT_pose_library(bpy.types.Menu):
bl_label = "Pose Library"
diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c
index 31fcf0a1253..203d76086b3 100644
--- a/source/blender/editors/armature/poseSlide.c
+++ b/source/blender/editors/armature/poseSlide.c
@@ -63,6 +63,7 @@
#include "ED_armature.h"
#include "ED_keyframes_draw.h"
+#include "ED_markers.h"
#include "ED_screen.h"
#include "armature_intern.h"
@@ -871,9 +872,21 @@ typedef enum ePosePropagate_Termination {
/* stop after the specified frame */
POSE_PROPAGATE_BEFORE_FRAME,
/* stop when we run out of keyframes */
- POSE_PROPAGATE_BEFORE_END
+ POSE_PROPAGATE_BEFORE_END,
+
+ /* only do on the frames where markers are selected */
+ POSE_PROPAGATE_SELECTED_MARKERS
} ePosePropagate_Termination;
+/* termination data needed for some modes - assumes only one of these entries will be needed at a time */
+typedef union tPosePropagate_ModeData {
+ /* smart holds + before frame: frame number to stop on */
+ float end_frame;
+
+ /* selected markers: listbase for CfraElem's marking these frames */
+ ListBase sel_markers;
+} tPosePropagate_ModeData;
+
/* --------------------------------- */
/* get frame on which the "hold" for the bone ends
@@ -1030,7 +1043,8 @@ static float pose_propagate_get_refVal (Object *ob, FCurve *fcu)
}
/* propagate just works along each F-Curve in turn */
-static void pose_propagate_fcurve (wmOperator *op, Object *ob, tPChanFCurveLink *UNUSED(pfl), FCurve *fcu, float startFrame, float endFrame)
+static void pose_propagate_fcurve (wmOperator *op, Object *ob, FCurve *fcu,
+ float startFrame, tPosePropagate_ModeData modeData)
{
const int mode = RNA_enum_get(op->ptr, "mode");
@@ -1067,7 +1081,7 @@ static void pose_propagate_fcurve (wmOperator *op, Object *ob, tPChanFCurveLink
/* additional termination conditions based on the operator 'mode' property go here... */
if (ELEM(mode, POSE_PROPAGATE_BEFORE_FRAME, POSE_PROPAGATE_SMART_HOLDS)) {
/* stop if keyframe is outside the accepted range */
- if (bezt->vec[1][0] > endFrame)
+ if (bezt->vec[1][0] > modeData.end_frame)
break;
}
else if (mode == POSE_PROPAGATE_NEXT_KEY) {
@@ -1080,6 +1094,20 @@ static void pose_propagate_fcurve (wmOperator *op, Object *ob, tPChanFCurveLink
if (i != (fcu->totvert-1))
continue;
}
+ else if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
+ /* only allow if there's a marker on this frame */
+ CfraElem *ce = NULL;
+
+ /* stop on matching marker if there is one */
+ for (ce = modeData.sel_markers.first; ce; ce = ce->next) {
+ if (ce->cfra == (int)(floor(bezt->vec[1][0] + 0.5f)))
+ break;
+ }
+
+ /* skip this keyframe if no marker */
+ if (ce == NULL)
+ continue;
+ }
/* just flatten handles, since values will now be the same either side... */
// TODO: perhaps a fade-out modulation of the value is required here (optional once again)?
@@ -1102,7 +1130,7 @@ static int pose_propagate_exec (bContext *C, wmOperator *op)
ListBase pflinks = {NULL, NULL};
tPChanFCurveLink *pfl;
- float endFrame = RNA_float_get(op->ptr, "end_frame");
+ tPosePropagate_ModeData modeData;
const int mode = RNA_enum_get(op->ptr, "mode");
/* sanity checks */
@@ -1118,6 +1146,16 @@ static int pose_propagate_exec (bContext *C, wmOperator *op)
/* isolate F-Curves related to the selected bones */
poseAnim_mapping_get(C, &pflinks, ob, act);
+ /* mode-specific data preprocessing (requiring no access to curves) */
+ if (mode == POSE_PROPAGATE_SELECTED_MARKERS) {
+ /* get a list of selected markers */
+ ED_markers_make_cfra_list(&scene->markers, &modeData.sel_markers, SELECT);
+ }
+ else {
+ /* assume everything else wants endFrame */
+ modeData.end_frame = RNA_float_get(op->ptr, "end_frame");
+ }
+
/* for each bone, perform the copying required */
for (pfl = pflinks.first; pfl; pfl = pfl->next) {
LinkData *ld;
@@ -1127,17 +1165,20 @@ static int pose_propagate_exec (bContext *C, wmOperator *op)
/* we store in endFrame the end frame of the "long keyframe" (i.e. a held value) starting
* from the keyframe that occurs after the current frame
*/
- endFrame = pose_propagate_get_boneHoldEndFrame(ob, pfl, (float)CFRA);
+ modeData.end_frame = pose_propagate_get_boneHoldEndFrame(ob, pfl, (float)CFRA);
}
/* go through propagating pose to keyframes, curve by curve */
for (ld = pfl->fcurves.first; ld; ld= ld->next)
- pose_propagate_fcurve(op, ob, pfl, (FCurve *)ld->data, (float)CFRA, endFrame);
+ pose_propagate_fcurve(op, ob, (FCurve *)ld->data, (float)CFRA, modeData);
}
/* free temp data */
poseAnim_mapping_free(&pflinks);
+ if (mode == POSE_PROPAGATE_SELECTED_MARKERS)
+ BLI_freelistN(&modeData.sel_markers);
+
/* updates + notifiers */
poseAnim_mapping_refresh(C, scene, ob);
@@ -1154,6 +1195,7 @@ void POSE_OT_propagate (wmOperatorType *ot)
{POSE_PROPAGATE_LAST_KEY, "LAST_KEY", 0, "To Last Keyframe", "Propagate pose to the last keyframe only (i.e. making action cyclic)"},
{POSE_PROPAGATE_BEFORE_FRAME, "BEFORE_FRAME", 0, "Before Frame", "Propagate pose to all keyframes between current frame and 'Frame' property"},
{POSE_PROPAGATE_BEFORE_END, "BEFORE_END", 0, "Before Last Keyframe", "Propagate pose to all keyframes from current frame until no more are found"},
+ {POSE_PROPAGATE_SELECTED_MARKERS, "SELECTED_MARKERS", 0, "On Selected Markers", "Propagate pose to all keyframes occurring on frames with Scene Markers after the current frame"},
{0, NULL, 0, NULL, NULL}};
/* identifiers */
diff --git a/source/blender/editors/armature/poseUtils.c b/source/blender/editors/armature/poseUtils.c
index 16e84db0ba7..7ade93076e5 100644
--- a/source/blender/editors/armature/poseUtils.c
+++ b/source/blender/editors/armature/poseUtils.c
@@ -128,7 +128,6 @@ static void fcurves_to_pchan_links_get (ListBase *pfLinks, Object *ob, bAction *
/* get sets of F-Curves providing transforms for the bones in the Pose */
-// TODO: separate the inner workings out to another helper func, since we need option of whether to take selected or visible bones...
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
@@ -139,6 +138,17 @@ void poseAnim_mapping_get (bContext *C, ListBase *pfLinks, Object *ob, bAction *
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 (pfLinks->first == NULL) {
+ CTX_DATA_BEGIN(C, bPoseChannel*, pchan, visible_pose_bones)
+ {
+ fcurves_to_pchan_links_get(pfLinks, ob, act, pchan);
+ }
+ CTX_DATA_END;
+ }
}
/* free F-Curve <-> PoseChannel links */
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index f9687e99c87..bee872dbe60 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -455,7 +455,7 @@ static void columnselect_action_keys (bAnimContext *ac, short mode)
break;
case ACTKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
- ED_markers_make_cfra_list(ac->markers, &ked.list, 1);
+ ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
break;
default: /* invalid option */
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 8bec0803c5e..920f477e7eb 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -459,7 +459,7 @@ static void columnselect_graph_keys (bAnimContext *ac, short mode)
break;
case GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
- ED_markers_make_cfra_list(ac->markers, &ked.list, 1);
+ ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
break;
default: /* invalid option */