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--source/blender/blenkernel/BKE_anim.h3
-rw-r--r--source/blender/blenkernel/intern/anim.c71
-rw-r--r--source/blender/editors/armature/pose_edit.c24
-rw-r--r--source/blender/editors/armature/pose_transform.c4
-rw-r--r--source/blender/editors/armature/pose_utils.c2
-rw-r--r--source/blender/editors/include/ED_armature.h2
-rw-r--r--source/blender/editors/include/ED_object.h2
-rw-r--r--source/blender/editors/object/object_edit.c30
-rw-r--r--source/blender/editors/transform/transform_conversions.c17
-rw-r--r--source/blender/editors/transform/transform_generics.c15
10 files changed, 114 insertions, 56 deletions
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 objects_len, int select_mode, const bool ignore_visibility);
void ED_pose_bone_select_tag_update(struct Object *ob);
void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select);
-void ED_pose_recalculate_paths(struct bContext *C, struct Scene *scene, struct Object *ob);
+void ED_pose_recalculate_paths(struct bContext *C, struct Scene *scene, struct Object *ob, bool current_frame_only);
struct Object *ED_pose_object_from_context(struct bContext *C);
/* meshlaplacian.c */
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 3fd520810ea..1f58a6508b2 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -196,7 +196,7 @@ void ED_object_single_user(struct Main *bmain, struct Scene *scene, struct Objec
/* object motion paths */
void ED_objects_clear_paths(struct bContext *C, bool only_selected);
-void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene);
+void ED_objects_recalculate_paths(struct bContext *C, struct Scene *scene, bool current_frame_only);
/* constraints */
struct ListBase *get_active_constraints(struct Object *ob);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index cd572c9e93f..43d287590e6 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1223,9 +1223,14 @@ void OBJECT_OT_forcefield_toggle(wmOperatorType *ot)
*
* To be called from various tools that do incremental updates
*/
-void ED_objects_recalculate_paths(bContext *C, Scene *scene)
+void ED_objects_recalculate_paths(bContext *C, Scene *scene, 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};
@@ -1239,17 +1244,20 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
CTX_DATA_END;
/* recalculate paths, then free */
- animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, true);
+ animviz_calc_motionpaths(depsgraph, bmain, scene, &targets, true, current_frame_only);
BLI_freelistN(&targets);
- /* tag objects for copy on write - so paths will draw/redraw */
- CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
- {
- if (ob->mpath) {
- DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
+ if (!current_frame_only) {
+ /* Tag objects for copy on write - so paths will draw/redraw
+ * For currently frame only we update evaluated object directly. */
+ CTX_DATA_BEGIN(C, Object *, ob, selected_editable_objects)
+ {
+ if (ob->mpath) {
+ DEG_id_tag_update(&ob->id, DEG_TAG_COPY_ON_WRITE);
+ }
}
+ CTX_DATA_END;
}
- CTX_DATA_END;
}
@@ -1296,7 +1304,7 @@ static int object_calculate_paths_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* calculate the paths for objects that have them (and are tagged to get refreshed) */
- ED_objects_recalculate_paths(C, scene);
+ ED_objects_recalculate_paths(C, scene, false);
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
@@ -1346,7 +1354,7 @@ static int object_update_paths_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
/* calculate the paths for objects that have them (and are tagged to get refreshed) */
- ED_objects_recalculate_paths(C, scene);
+ ED_objects_recalculate_paths(C, scene, false);
/* notifiers for updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 26c853e8d0a..ae3ad145c31 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -6707,9 +6707,6 @@ 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(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) {
@@ -6723,14 +6720,20 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
else {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
+
+ if (t->mode != TFM_DUMMY && motionpath_need_update_pose(t->scene, ob)) {
+ BLI_gset_insert(motionpath_updates, ob);
+ }
}
/* Update motion paths once for all transformed bones in an object. */
GSetIterator gs_iter;
GSET_ITER (gs_iter, motionpath_updates) {
+ bool current_frame_only = canceled;
ob = BLI_gsetIterator_getKey(&gs_iter);
- ED_pose_recalculate_paths(C, t->scene, ob);
+ ED_pose_recalculate_paths(C, t->scene, ob, current_frame_only);
}
+ BLI_gset_free(motionpath_updates, NULL);
}
else if (t->options & CTX_PAINT_CURVE) {
/* pass */
@@ -6784,9 +6787,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
/* Set autokey if necessary */
if (!canceled) {
autokeyframe_object(C, t->scene, t->view_layer, ob, t->mode);
- motionpath_update |= motionpath_need_update_object(t->scene, ob);
}
+ motionpath_update |= motionpath_need_update_object(t->scene, ob);
+
/* restore rigid body transform */
if (ob->rigidbody_object && canceled) {
float ctime = BKE_scene_frame_get(t->scene);
@@ -6797,7 +6801,8 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (motionpath_update) {
/* Update motion paths once for all transformed objects. */
- ED_objects_recalculate_paths(C, t->scene);
+ bool current_frame_only = canceled;
+ ED_objects_recalculate_paths(C, t->scene, current_frame_only);
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 925b4e8dd3e..87ce40546aa 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -955,9 +955,10 @@ static void recalcData_objects(TransInfo *t)
animrecord_check_state(t->scene, &ob->id, t->animtimer);
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);
- }
+ }
+
+ if (motionpath_need_update_pose(t->scene, ob)) {
+ BLI_gset_insert(motionpath_updates, ob);
}
/* old optimize trick... this enforces to bypass the depgraph */
@@ -975,8 +976,9 @@ static void recalcData_objects(TransInfo *t)
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);
+ ED_pose_recalculate_paths(t->context, t->scene, ob, true);
}
+ BLI_gset_free(motionpath_updates, NULL);
}
else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
PE_get_current(t->scene, base->object))
@@ -1013,9 +1015,10 @@ static void recalcData_objects(TransInfo *t)
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
animrecord_check_state(t->scene, &ob->id, t->animtimer);
autokeyframe_object(t->context, t->scene, t->view_layer, ob, t->mode);
- motionpath_update |= motionpath_need_update_object(t->scene, ob);
}
+ motionpath_update |= motionpath_need_update_object(t->scene, ob);
+
/* sets recalc flags fully, instead of flushing existing ones
* otherwise proxies don't function correctly
*/
@@ -1028,7 +1031,7 @@ static void recalcData_objects(TransInfo *t)
if (motionpath_update) {
/* Update motion paths once for all transformed objects. */
- ED_objects_recalculate_paths(t->context, t->scene);
+ ED_objects_recalculate_paths(t->context, t->scene, true);
}
}
}