[Bf-blender-cvs] [5feb03c3ae3] blender2.8: Motion Paths: interactively update current frame location while dragging.

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


Commit: 5feb03c3ae3353f1a616412f7384511f693ebc33
Author: Brecht Van Lommel
Date:   Fri Sep 14 14:03:31 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB5feb03c3ae3353f1a616412f7384511f693ebc33

Motion Paths: interactively update current frame location while dragging.

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

M	source/blender/blenkernel/BKE_anim.h
M	source/blender/blenkernel/intern/anim.c
M	source/blender/editors/armature/pose_edit.c
M	source/blender/editors/armature/pose_transform.c
M	source/blender/editors/armature/pose_utils.c
M	source/blender/editors/include/ED_armature.h
M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/transform/transform_conversions.c
M	source/blender/editors/transform/transform_generics.c

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

diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 91f936c6eca..0d8a50c5325 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -61,7 +61,8 @@ void animviz_calc_motionpaths(struct Depsgraph *depsgraph,
                               struct Main *bmain,
                               struct Scene *scene,
                               ListBase *targets,
-                              bool restore);
+                              bool restore,
+                              bool current_frame_only);
 
 /* ---------------------------------------------------- */
 /* Curve Paths */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 02f871e6ccf..deafe631290 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -347,7 +347,6 @@ static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
 	/* for each target, check if it can be baked on the current frame */
 	for (mpt = targets->first; mpt; mpt = mpt->next) {
 		bMotionPath *mpath = mpt->mpath;
-		bMotionPathVert *mpv;
 
 		/* current frame must be within the range the cache works for
 		 *	- is inclusive of the first frame, but not the last otherwise we get buffer overruns
@@ -357,7 +356,7 @@ static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
 		}
 
 		/* get the relevant cache vert to write to */
-		mpv = mpath->points + (cframe - mpath->start_frame);
+		bMotionPathVert *mpv = mpath->points + (cframe - mpath->start_frame);
 
 		Object *ob_eval = mpt->ob_eval;
 
@@ -392,6 +391,25 @@ static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
 		if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) {
 			mpv->flag |= MOTIONPATH_VERT_KEY;
 		}
+
+		/* Incremental update on evaluated object if possible, for fast updating
+		 * while dragging in transform. */
+		bMotionPath *mpath_eval = NULL;
+		if (mpt->pchan) {
+			mpath_eval = (pchan_eval) ? pchan_eval->mpath : NULL;
+		}
+		else {
+			mpath_eval = ob_eval->mpath;
+		}
+
+		if (mpath_eval && mpath_eval->length == mpath->length) {
+			bMotionPathVert *mpv_eval = mpath_eval->points + (cframe - mpath_eval->start_frame);
+			*mpv_eval = *mpv;
+
+			GPU_VERTBUF_DISCARD_SAFE(mpath_eval->points_vbo);
+			GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_line);
+			GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_points);
+		}
 	}
 }
 
@@ -405,36 +423,45 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
                               Main *bmain,
                               Scene *scene,
                               ListBase *targets,
-                              bool restore)
+                              bool restore,
+                              bool current_frame_only)
 {
-	MPathTarget *mpt;
-	int sfra, efra;
-	int cfra;
-
 	/* sanity check */
 	if (ELEM(NULL, targets, targets->first))
 		return;
 
-	/* set frame values */
-	cfra = CFRA;
-	sfra = efra = cfra;
-
-	/* TODO: this method could be improved...
+	/* Compute frame range to bake within.
+	 * TODO: this method could be improved...
 	 * 1) max range for standard baking
 	 * 2) minimum range for recalc baking (i.e. between keyframes, but how?) */
-	for (mpt = targets->first; mpt; mpt = mpt->next) {
+	int sfra = INT_MAX;
+	int efra = INT_MIN;
+
+	for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
 		/* try to increase area to do (only as much as needed) */
 		sfra = MIN2(sfra, mpt->mpath->start_frame);
 		efra = MAX2(efra, mpt->mpath->end_frame);
 	}
-	if (efra <= sfra) return;
 
+	if (efra <= sfra) {
+		return;
+	}
+
+	/* Limit frame range if we are updating just the current frame. */
+	/* set frame values */
+	int cfra = CFRA;
+	if (current_frame_only) {
+		if (cfra < sfra || cfra > efra) {
+			return;
+		}
+		sfra = efra = cfra;
+	}
 
 	/* get copies of objects/bones to get the calculated results from
 	 * (for copy-on-write evaluation), so that we actually get some results
 	 */
 	// TODO: Create a copy of background depsgraph that only contain these entities, and only evaluates them..
-	for (mpt = targets->first; mpt; mpt = mpt->next) {
+	for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
 		mpt->ob_eval = DEG_get_evaluated_object(depsgraph, mpt->ob);
 
 		AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id);
@@ -472,8 +499,14 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
 	/* calculate path over requested range */
 	printf("Calculating MotionPaths between frames %d - %d (%d frames)\n", sfra, efra, efra - sfra + 1);
 	for (CFRA = sfra; CFRA <= efra; CFRA++) {
-		/* update relevant data for new frame */
-		motionpaths_calc_update_scene(bmain, depsgraph);
+		if (current_frame_only) {
+			/* For current frame, only update tagged. */
+			BKE_scene_graph_update_tagged(depsgraph, bmain);
+		}
+		else {
+			/* Update relevant data for new frame. */
+			motionpaths_calc_update_scene(bmain, depsgraph);
+		}
 
 		/* perform baking for targets */
 		motionpaths_calc_bake_targets(targets, CFRA);
@@ -484,12 +517,12 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
 	 * may be a temporary one that works on a subset of the data. We always have
 	 * to resoture the current frame though. */
 	CFRA = cfra;
-	if (restore) {
+	if (!current_frame_only && restore) {
 		motionpaths_calc_update_scene(bmain, depsgraph);
 	}
 
 	/* clear recalc flags from targets */
-	for (mpt = targets->first; mpt; mpt = mpt->next) {
+	for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
 		bAnimVizSettings *avs;
 		bMotionPath *mpath = mpt->mpath;
 
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index d0ca809f196..15b8c3eb8de 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -193,15 +193,20 @@ static bool pose_has_protected_selected(Object *ob, short warn)
  *
  * To be called from various tools that do incremental updates
  */
-void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
+void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob, bool current_frame_only)
 {
-	struct Main *bmain = CTX_data_main(C);
+	/* Transform doesn't always have context avaialble to do update. */
+	if (C == NULL) {
+		return;
+	}
+
+	Main *bmain = CTX_data_main(C);
 	Depsgraph *depsgraph = CTX_data_depsgraph(C);
 	ListBase targets = {NULL, NULL};
 	bool free_depsgraph = false;
 
 	/* Override depsgraph with a filtered, simpler copy */
-	if (G.debug_value != -1) {
+	if (!current_frame_only && G.debug_value != -1) {
 		TIMEIT_START(filter_pose_depsgraph);
 		DEG_FilterQuery query = {0};
 
@@ -226,13 +231,16 @@ void ED_pose_recalculate_paths(bContext *C, Scene *scene, Object *ob)
 
 	/* recalculate paths, then free */
 	TIMEIT_START(pose_path_calc);
-	animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, false);
+	animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, !free_depsgraph, current_frame_only);
 	TIMEIT_END(pose_path_calc);
 
 	BLI_freelistN(&targets);
 
-	/* tag armature object for copy on write - so paths will draw/redraw */
-	DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
+	if (!current_frame_only) {
+		/* Tag armature object for copy on write - so paths will draw/redraw.
+		 * For currently frame only we update evaluated object directly. */
+		DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
+	}
 
 	/* Free temporary depsgraph instance */
 	if (free_depsgraph) {
@@ -303,7 +311,7 @@ static int pose_calculate_paths_exec(bContext *C, wmOperator *op)
 
 	/* calculate the bones that now have motionpaths... */
 	/* TODO: only make for the selected bones? */
-	ED_pose_recalculate_paths(C, scene, ob);
+	ED_pose_recalculate_paths(C, scene, ob, false);
 
 #ifdef DEBUG_TIME
 	TIMEIT_END(recalc_pose_paths);
@@ -364,7 +372,7 @@ static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
 
 	/* calculate the bones that now have motionpaths... */
 	/* TODO: only make for the selected bones? */
-	ED_pose_recalculate_paths(C, scene, ob);
+	ED_pose_recalculate_paths(C, scene, ob, false);
 
 	/* notifiers for updates */
 	WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
diff --git a/source/blender/editors/armature/pose_transform.c b/source/blender/editors/armature/pose_transform.c
index 22c710dcda5..b492cfacddb 100644
--- a/source/blender/editors/armature/pose_transform.c
+++ b/source/blender/editors/armature/pose_transform.c
@@ -584,7 +584,7 @@ static int pose_paste_exec(bContext *C, wmOperator *op)
 
 	/* Recalculate paths if any of the bones have paths... */
 	if ((ob->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
-		ED_pose_recalculate_paths(C, scene, ob);
+		ED_pose_recalculate_paths(C, scene, ob, false);
 	}
 
 	/* Notifiers for updates, */
@@ -827,7 +827,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op,
 
 				/* now recalculate paths */
 				if ((ob_iter->pose->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)) {
-					ED_pose_recalculate_paths(C, scene, ob_iter);
+					ED_pose_recalculate_paths(C, scene, ob_iter, false);
 				}
 
 				BLI_freelistN(&dsources);
diff --git a/source/blender/editors/armature/pose_utils.c b/source/blender/editors/armature/pose_utils.c
index e280284a9ce..8b0a60c0f97 100644
--- a/source/blender/editors/armature/pose_utils.c
+++ b/source/blender/editors/armature/pose_utils.c
@@ -269,7 +269,7 @@ void poseAnim_mapping_autoKeyframe(bContext *C, Scene *scene, Object *ob, ListBa
 		 */
 		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);
+			ED_pose_recalculate_paths(C, scene, ob, false);
 		}
 	}
 }
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 5c193392052..3044543795c 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -225,7 +225,7 @@ bool ED_pose_deselect_all(struct Object *ob, int select_mode, const bool ignore_
 void ED_pose_deselect_all_multi(struct Object **objects, uint obj

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list