[Bf-blender-cvs] [3c61efcf206] blender2.8: Multi-Objects: pose slide operators

Dalai Felinto noreply at git.blender.org
Sat Oct 20 02:20:44 CEST 2018


Commit: 3c61efcf206dcce904570baef1d5e209415d0ea9
Author: Dalai Felinto
Date:   Fri Oct 19 19:08:12 2018 -0300
Branches: blender2.8
https://developer.blender.org/rB3c61efcf206dcce904570baef1d5e209415d0ea9

Multi-Objects: pose slide operators

* POSE_OT_breakdown
* POSE_OT_relax
* POSE_OT_push
* POSE_OT_propagate

Note: I could not test relax because of T57313.

Note 2: I believe those are the last armature related operators to be
ported - \o/

===================================================================

M	source/blender/editors/armature/armature_intern.h
M	source/blender/editors/armature/pose_slide.c
M	source/blender/editors/armature/pose_utils.c

===================================================================

diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index e5efb3315d0..da24787fc18 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -147,6 +147,8 @@ void POSE_OT_bone_layers(struct wmOperatorType *ot);
 typedef struct tPChanFCurveLink {
 	struct tPChanFCurveLink *next, *prev;
 
+	struct Object *ob;              /* Object this Pose Channel belongs to. */
+
 	ListBase fcurves;               /* F-Curves for this PoseChannel (wrapped with LinkData) */
 	struct bPoseChannel *pchan;     /* Pose Channel which data is attached to */
 
@@ -170,12 +172,13 @@ typedef struct tPChanFCurveLink {
 
 /* ----------- */
 
-void poseAnim_mapping_get(struct bContext *C, ListBase *pfLinks, struct Object *ob, struct bAction *act);
+struct Object *poseAnim_object_get(struct Object *ob_);
+void poseAnim_mapping_get(struct bContext *C, ListBase *pfLinks);
 void poseAnim_mapping_free(ListBase *pfLinks);
 
 void poseAnim_mapping_refresh(struct bContext *C, struct Scene *scene, struct Object *ob);
 void poseAnim_mapping_reset(ListBase *pfLinks);
-void poseAnim_mapping_autoKeyframe(struct bContext *C, struct Scene *scene, struct Object *ob, ListBase *pfLinks, float cframe);
+void poseAnim_mapping_autoKeyframe(struct bContext *C, struct Scene *scene, ListBase *pfLinks, float cframe);
 
 LinkData *poseAnim_mapping_getNextFCurve(ListBase *fcuLinks, LinkData *prev, const char *path);
 
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 3cd0897a326..909ae834ac2 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -42,6 +42,7 @@
 #include "BKE_nla.h"
 
 #include "BKE_context.h"
+#include "BKE_layer.h"
 #include "BKE_object.h"
 #include "BKE_report.h"
 #include "BKE_unit.h"
@@ -89,10 +90,9 @@ typedef struct tPoseSlideOp {
 	Scene *scene;       /* current scene */
 	ScrArea *sa;        /* area that we're operating in (needed for modal()) */
 	ARegion *ar;        /* region that we're operating in (needed for modal()) */
-	Object *ob;         /* active object that Pose Info comes from */
-	bArmature *arm;     /* armature for pose */
+	uint objects_len;   /* len of the PoseSlideObject array. */
 
-	ListBase pfLinks;   /* links between posechannels and f-curves  */
+	ListBase pfLinks;   /* links between posechannels and f-curves for all the pose objects. */
 	DLRBT_Tree keys;    /* binary tree for quicker searching for keyframes (when applicable) */
 
 	int cframe;         /* current frame number - global time */
@@ -100,9 +100,6 @@ typedef struct tPoseSlideOp {
 	int prevFrame;      /* frame before current frame (blend-from) - global time */
 	int nextFrame;      /* frame after current frame (blend-to)    - global time */
 
-	float prevFrameF;   /* prevFrame, but in local action time (for F-Curve lookups to work) */
-	float nextFrameF;   /* nextFrame, but in local action time (for F-Curve lookups to work) */
-
 	short mode;         /* sliding mode (ePoseSlide_Modes) */
 	short flag;         /* unused for now, but can later get used for storing runtime settings.... */
 
@@ -112,8 +109,17 @@ typedef struct tPoseSlideOp {
 	float percentage;   /* 0-1 value for determining the influence of whatever is relevant */
 
 	NumInput num;       /* numeric input */
+
+	struct tPoseSlideObject *ob_data_array;
 } tPoseSlideOp;
 
+typedef struct tPoseSlideObject {
+	Object *ob;         /* active object that Pose Info comes from */
+	float prevFrameF;   /* prevFrame, but in local action time (for F-Curve lookups to work) */
+	float nextFrameF;   /* nextFrame, but in local action time (for F-Curve lookups to work) */
+	bool valid;
+} tPoseSlideObject;
+
 /* Pose Sliding Modes */
 typedef enum ePoseSlide_Modes {
 	POSESLIDE_PUSH  = 0,        /* exaggerate the pose... */
@@ -167,18 +173,15 @@ static const EnumPropertyItem prop_axis_lock_types[] = {
 /* ------------------------------------ */
 
 /* operator init */
-static int pose_slide_init(bContext *C, wmOperator *op, short mode)
+static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
 {
 	tPoseSlideOp *pso;
-	bAction *act = NULL;
 
 	/* init slide-op data */
 	pso = op->customdata = MEM_callocN(sizeof(tPoseSlideOp), "tPoseSlideOp");
 
 	/* get info from context */
 	pso->scene = CTX_data_scene(C);
-	pso->ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
-	pso->arm = (pso->ob) ? pso->ob->data : NULL;
 	pso->sa = CTX_wm_area(C); /* only really needed when doing modal() */
 	pso->ar = CTX_wm_region(C); /* only really needed when doing modal() */
 
@@ -194,25 +197,38 @@ static int pose_slide_init(bContext *C, wmOperator *op, short mode)
 	pso->channels = RNA_enum_get(op->ptr, "channels");
 	pso->axislock = RNA_enum_get(op->ptr, "axis_lock");
 
-	/* ensure validity of the settings from the context */
-	if (ELEM(NULL, pso->ob, pso->arm, pso->ob->adt, pso->ob->adt->action))
-		return 0;
+	/* for each Pose-Channel which gets affected, get the F-Curves for that channel
+	* and set the relevant transform flags...
+	*/
+	poseAnim_mapping_get(C, &pso->pfLinks);
 
-	act = pso->ob->adt->action;
+	Object **objects = BKE_view_layer_array_from_objects_in_mode_unique_data(CTX_data_view_layer(C),
+	                                                                         &pso->objects_len,
+	                                                                         OB_MODE_POSE);
+	pso->ob_data_array = MEM_callocN(pso->objects_len * sizeof(tPoseSlideObject), "pose slide objects data");
 
-	/* apply NLA mapping corrections so the frame lookups work */
-	pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
-	pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
+	for (uint ob_index = 0; ob_index < pso->objects_len; ob_index++) {
+		tPoseSlideObject *ob_data = &pso->ob_data_array[ob_index];
+		Object *ob_iter = poseAnim_object_get(objects[ob_index]);
 
-	/* for each Pose-Channel which gets affected, get the F-Curves for that channel
-	 * and set the relevant transform flags...
-	 */
-	poseAnim_mapping_get(C, &pso->pfLinks, pso->ob, act);
+		/* Ensure validity of the settings from the context. */
+		if (ob_iter == NULL) {
+			continue;
+		}
+
+		ob_data->ob = ob_iter;
+		ob_data->valid = true;
 
-	/* set depsgraph flags */
-	/* make sure the lock is set OK, unlock can be accidentally saved? */
-	pso->ob->pose->flag |= POSE_LOCKED;
-	pso->ob->pose->flag &= ~POSE_DO_UNLOCK;
+		/* apply NLA mapping corrections so the frame lookups work */
+		ob_data->prevFrameF = BKE_nla_tweakedit_remap(ob_data->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
+		ob_data->nextFrameF = BKE_nla_tweakedit_remap(ob_data->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
+
+		/* set depsgraph flags */
+		/* make sure the lock is set OK, unlock can be accidentally saved? */
+		ob_data->ob->pose->flag |= POSE_LOCKED;
+		ob_data->ob->pose->flag &= ~POSE_DO_UNLOCK;
+	}
+	MEM_freeN(objects);
 
 	/* do basic initialize of RB-BST used for finding keyframes, but leave the filling of it up
 	 * to the caller of this (usually only invoke() will do it, to make things more efficient).
@@ -242,6 +258,10 @@ static void pose_slide_exit(wmOperator *op)
 		/* free RB-BST for keyframes (if it contained data) */
 		BLI_dlrbTree_free(&pso->keys);
 
+		if (pso->ob_data_array != NULL) {
+			MEM_freeN(pso->ob_data_array);
+		}
+
 		/* free data itself */
 		MEM_freeN(pso);
 	}
@@ -256,21 +276,50 @@ static void pose_slide_exit(wmOperator *op)
 static void pose_slide_refresh(bContext *C, tPoseSlideOp *pso)
 {
 	/* wrapper around the generic version, allowing us to add some custom stuff later still */
-	poseAnim_mapping_refresh(C, pso->scene, pso->ob);
+	for (uint ob_index = 0; ob_index < pso->objects_len; ob_index++) {
+		tPoseSlideObject *ob_data = &pso->ob_data_array[ob_index];
+		if (ob_data->valid) {
+			poseAnim_mapping_refresh(C, pso->scene, ob_data->ob);
+		}
+	}
+}
+
+/** Although this lookup is not ideal, we won't be dealing with a lot of objects at a given time.
+  * But if it comes to that we can instead store prev/next frme in the tPChanFCurveLink. */
+static bool pose_frame_range_from_object_get(tPoseSlideOp *pso, Object *ob, float *prevFrameF, float *nextFrameF)
+{
+	for (uint ob_index = 0; ob_index < pso->objects_len; ob_index++) {
+		tPoseSlideObject *ob_data = &pso->ob_data_array[ob_index];
+		Object *ob_iter = ob_data->ob;
+
+		if (ob_iter == ob) {
+			*prevFrameF = ob_data->prevFrameF;
+			*nextFrameF = ob_data->nextFrameF;
+			return true;
+		}
+	}
+	return false;
 }
 
 /* helper for apply() - perform sliding for some value */
-static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val)
+static void pose_slide_apply_val(
+        tPoseSlideOp *pso,
+        FCurve *fcu,
+        Object *ob,
+        float *val)
 {
+	float prevFrameF, nextFrameF;
 	float cframe = (float)pso->cframe;
 	float sVal, eVal;
 	float w1, w2;
 
+	pose_frame_range_from_object_get(pso, ob, &prevFrameF, &nextFrameF);
+
 	/* get keyframe values for endpoint poses to blend with */
 	/* previous/start */
-	sVal = evaluate_fcurve(fcu, pso->prevFrameF);
+	sVal = evaluate_fcurve(fcu, prevFrameF);
 	/* next/end */
-	eVal = evaluate_fcurve(fcu, pso->nextFrameF);
+	eVal = evaluate_fcurve(fcu, nextFrameF);
 
 	/* if both values are equal, don't do anything */
 	if (IS_EQF(sVal, eVal)) {
@@ -364,7 +413,7 @@ static void pose_slide_apply_vec3(tPoseSlideOp *pso, tPChanFCurveLink *pfl, floa
 		    ((lock & PS_LOCK_Z) && (idx == 2)))
 		{
 			/* just work on these channels one by one... there's no interaction between values */
-			pose_slide_apply_val(pso, fcu, &vec[fcu->array_index]);
+			pose_slide_apply_val(pso, fcu, pfl->ob, &vec[fcu->array_index]);
 		}
 	}
 
@@ -413,14 +462,14 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, tPChanFCurveLink *pfl, con
 					case PROP_FLOAT:
 					{
 						float tval = RNA_property_float_get(&ptr, prop);
-						pose_slide_apply_val(pso, fcu, &tval);
+						pose_slide_apply_val(pso, fcu, pfl->ob, &tval);
 						RNA_prop

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list