[Bf-blender-cvs] [fe6a6dee0bd] blender2.8: Motion Paths: only update once when transforming multiple bones or objects.

Brecht Van Lommel noreply at git.blender.org
Fri Sep 14 17:46:19 CEST 2018


Commit: fe6a6dee0bd91c59c774e2feb8886a8a4b4f0806
Author: Brecht Van Lommel
Date:   Fri Sep 14 13:59:58 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBfe6a6dee0bd91c59c774e2feb8886a8a4b4f0806

Motion Paths: only update once when transforming multiple bones or objects.

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

M	source/blender/editors/transform/transform.h
M	source/blender/editors/transform/transform_conversions.c
M	source/blender/editors/transform/transform_generics.c

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

diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 20512a18ae3..3b19618405a 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -730,12 +730,16 @@ bool transdata_check_local_islands(TransInfo *t, short around);
 
 int count_set_pose_transflags(struct Object *ob, const int mode, const short around, bool has_translate_rotate[2]);
 
-/* auto-keying stuff used by special_aftertrans_update */
-void autokeyframe_ob_cb_func(
+/* Auto-keyframe applied after transform, returns true if motion paths need to be updated. */
+void autokeyframe_object(
         struct bContext *C, struct Scene *scene, struct ViewLayer *view_layer, struct Object *ob, int tmode);
-void autokeyframe_pose_cb_func(
+void autokeyframe_pose(
         struct bContext *C, struct Scene *scene, struct Object *ob, int tmode, short targetless_ik);
 
+/* Test if we need to update motion paths for a given object. */
+bool motionpath_need_update_object(struct Scene *scene, struct Object *ob);
+bool motionpath_need_update_pose(struct Scene *scene, struct Object *ob);
+
 /*********************** Constraints *****************************/
 
 void drawConstraint(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 244f6f061af..26c853e8d0a 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -5916,7 +5916,7 @@ static void clear_trans_object_base_flags(TransInfo *t)
  * tmode: should be a transform mode
  */
 // NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases
-void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int tmode)
+void autokeyframe_object(bContext *C, Scene *scene, ViewLayer *view_layer, Object *ob, int tmode)
 {
 	Main *bmain = CTX_data_main(C);
 	ID *id = &ob->id;
@@ -6012,33 +6012,33 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, ViewLayer *view_layer, O
 			ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
 		}
 
-		/* only calculate paths if there are paths to be recalculated,
-		 * assuming that since we've autokeyed the transforms this is
-		 * now safe to apply...
-		 *
-		 * NOTE: only do this when there's context info
-		 */
-		if (C && (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
-			//ED_objects_clear_paths(C); // XXX for now, don't need to clear
-			ED_objects_recalculate_paths(C, scene);
-
-			/* XXX: there's potential here for problems with unkeyed rotations/scale,
-			 *      but for now (until proper data-locality for baking operations),
-			 *      this should be a better fix for T24451 and T37755
-			 */
-		}
-
 		/* free temp info */
 		BLI_freelistN(&dsources);
 	}
 }
 
+/* Return if we need to update motion paths, only if they already exist,
+ * and we will insert a keyframe at the end of transform. */
+bool motionpath_need_update_object(Scene *scene, Object *ob)
+{
+	/* XXX: there's potential here for problems with unkeyed rotations/scale,
+	 *      but for now (until proper data-locality for baking operations),
+	 *      this should be a better fix for T24451 and T37755
+	 */
+
+	if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+		return (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
+	}
+
+	return false;
+}
+
 /* auto-keyframing feature - for poses/pose-channels
  * tmode: should be a transform mode
  * targetless_ik: has targetless ik been done on any channels?
  */
 // NOTE: context may not always be available, so must check before using it as it's a luxury for a few cases
-void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
+void autokeyframe_pose(bContext *C, Scene *scene, Object *ob, int tmode, short targetless_ik)
 {
 	Main *bmain = CTX_data_main(C);
 	ID *id = &ob->id;
@@ -6158,16 +6158,6 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode,
 				BLI_freelistN(&dsources);
 			}
 		}
-
-		/* do the bone paths
-		 *  - only do this when there is context info, since we need that to resolve
-		 *	  how to do the updates and so on...
-		 *	- do not calculate unless there are paths already to update...
-		 */
-		if (C && (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);
-		}
 	}
 	else {
 		/* tag channels that should have unkeyed data */
@@ -6180,6 +6170,17 @@ void autokeyframe_pose_cb_func(bContext *C, Scene *scene, Object *ob, int tmode,
 	}
 }
 
+/* Return if we need to update motion paths, only if they already exist,
+ * and we will insert a keyframe at the end of transform. */
+bool motionpath_need_update_pose(Scene *scene, Object *ob)
+{
+	if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+		return (ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS) != 0;
+	}
+
+	return false;
+}
+
 static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t)
 {
 	SpaceClip *sc = t->sa->spacedata.first;
@@ -6665,6 +6666,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 		}
 	}
 	else if (t->flag & T_POSE) {
+		GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
 
 		FOREACH_TRANS_DATA_CONTAINER (t, tc) {
 
@@ -6704,7 +6706,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 
 			/* automatic inserting of keys and unkeyed tagging - only if transform wasn't canceled (or TFM_DUMMY) */
 			if (!canceled && (t->mode != TFM_DUMMY)) {
-				autokeyframe_pose_cb_func(C, t->scene, ob, t->mode, targetless_ik);
+				autokeyframe_pose(C, t->scene, ob, t->mode, targetless_ik);
+				if (motionpath_need_update_pose(t->scene, ob)) {
+					BLI_gset_insert(motionpath_updates, ob);
+				}
 				DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 			}
 			else if (arm->flag & ARM_DELAYDEFORM) {
@@ -6719,6 +6724,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 				DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
 			}
 		}
+
+		/* Update motion paths once for all transformed bones in an object. */
+		GSetIterator gs_iter;
+		GSET_ITER (gs_iter, motionpath_updates) {
+			ob = BLI_gsetIterator_getKey(&gs_iter);
+			ED_pose_recalculate_paths(C, t->scene, ob);
+		}
 	}
 	else if (t->options & CTX_PAINT_CURVE) {
 		/* pass */
@@ -6734,13 +6746,12 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 		/* do nothing */
 	}
 	else { /* Objects */
-		int i;
-
 		BLI_assert(t->flag & (T_OBJECT | T_TEXTURE));
 
 		TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+		bool motionpath_update = false;
 
-		for (i = 0; i < tc->data_len; i++) {
+		for (int i = 0; i < tc->data_len; i++) {
 			TransData *td = tc->data + i;
 			ListBase pidlist;
 			PTCacheID *pid;
@@ -6772,7 +6783,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 
 			/* Set autokey if necessary */
 			if (!canceled) {
-				autokeyframe_ob_cb_func(C, t->scene, t->view_layer, ob, t->mode);
+				autokeyframe_object(C, t->scene, t->view_layer, ob, t->mode);
+				motionpath_update |= motionpath_need_update_object(t->scene, ob);
 			}
 
 			/* restore rigid body transform */
@@ -6782,6 +6794,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
 					BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle);
 			}
 		}
+
+		if (motionpath_update) {
+			/* Update motion paths once for all transformed objects. */
+			ED_objects_recalculate_paths(C, t->scene);
+		}
 	}
 
 	clear_trans_object_base_flags(t);
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index a2377166dff..925b4e8dd3e 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -937,6 +937,8 @@ static void recalcData_objects(TransInfo *t)
 
 	}
 	else if (t->flag & T_POSE) {
+		GSet *motionpath_updates = BLI_gset_ptr_new("motionpath updates");
+
 		FOREACH_TRANS_DATA_CONTAINER (t, tc) {
 			Object *ob = tc->poseobj;
 			bArmature *arm = ob->data;
@@ -952,7 +954,10 @@ static void recalcData_objects(TransInfo *t)
 				int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
 
 				animrecord_check_state(t->scene, &ob->id, t->animtimer);
-				autokeyframe_pose_cb_func(t->context, t->scene, ob, t->mode, targetless_ik);
+				autokeyframe_pose(t->context, t->scene, ob, t->mode, targetless_ik);
+				if (motionpath_need_update_pose(t->scene, ob)) {
+					BLI_gset_insert(motionpath_updates, ob);
+				}
 			}
 
 			/* old optimize trick... this enforces to bypass the depgraph */
@@ -965,6 +970,13 @@ static void recalcData_objects(TransInfo *t)
 				BKE_pose_where_is(t->depsgraph, t->scene, ob);
 			}
 		}
+
+		/* Update motion paths once for all transformed bones in an object. */
+		GSetIterator gs_iter;
+		GSET_ITER (gs_iter, motionpath_updates) {
+			Object *ob = BLI_gsetIterator_getKey(&gs_iter);
+			ED_pose_recalculate_paths(t->context, t->scene, ob);
+		}
 	}
 	else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
 	         PE_get_current(t->scene, base->object))
@@ -975,7 +987,7 @@ static void recalcData_objects(TransInfo *t)
 		flushTransParticles(t);
 	}
 	else {
-		int i;
+		bool motionpath_update = false;
 
 		if (t->state != TRANS_CANCEL) {
 			applyProject(t);
@@ -984,7 +996,7 @@ static void recalcData_objects(TransInfo *t)
 		FOREACH_TRANS_DATA_CONTAINER (t, tc) {
 			TransData *td = tc->data;
 
-			for (i = 0; i < tc->data_len; i++, td++) {
+			for (int i = 0; i < tc->data_len; i++, td++) {
 				Object *ob = td->ob;
 
 				if (td->flag & TD_NOACTION)
@@ -1000,7 +1012,8 @@ static void recalcData_objects(TransInfo *t)
 				// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
 				if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
 					animrecord_check_state(t->scene, &ob->id, t->animtimer);
-					autokeyframe_ob_cb_fu

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list