Fix T71908: Animated properties are lost after frame-post handler
The issue was caused by special handling of animation update after manual edits in frame_post handler: to avid loss of manual edits done on top of animated property. This was done as a separate pass for non-animation update after frame_post did modifications. This caused some other side-effect: non-modified animated property was re-setting to the value which is used in the viewport. Idea of this solution is simple: preserve values which came from animation update through copy-on-write process. The actual process of this is a bit involved: need to decode RNA path and do it twice since f-curve might point to a sub-data which pointer will change. Since this is only done for non-active depsgraph (aka depsgraph used for render pipeline) this is probably fine since all this extra overhead is just a fraction of overall render process. Differential Revision: https://developer.blender.org/D6330
This commit is contained in:
parent
c3d6929e4f
commit
befc082736
Notes:
blender-bot
2023-02-14 08:08:56 +01:00
Referenced by issue #73077, Blender exits incorrectly when editing any keyframe Referenced by issue #73029, 2.83: Unable to move, grab, or duplicate keyframes in any editor without a Crash Referenced by issue #73029, 2.83: Unable to move, grab, or duplicate keyframes in any editor without a Crash Referenced by issue #71908, Keyframed parameters are not preserved when frame_change_post handler is used
|
@ -59,6 +59,7 @@ set(SRC
|
|||
intern/eval/deg_eval_copy_on_write.cc
|
||||
intern/eval/deg_eval_flush.cc
|
||||
intern/eval/deg_eval_runtime_backup.cc
|
||||
intern/eval/deg_eval_runtime_backup_animation.cc
|
||||
intern/eval/deg_eval_runtime_backup_modifier.cc
|
||||
intern/eval/deg_eval_runtime_backup_movieclip.cc
|
||||
intern/eval/deg_eval_runtime_backup_object.cc
|
||||
|
@ -108,6 +109,7 @@ set(SRC
|
|||
intern/eval/deg_eval_copy_on_write.h
|
||||
intern/eval/deg_eval_flush.h
|
||||
intern/eval/deg_eval_runtime_backup.h
|
||||
intern/eval/deg_eval_runtime_backup_animation.h
|
||||
intern/eval/deg_eval_runtime_backup_modifier.h
|
||||
intern/eval/deg_eval_runtime_backup_movieclip.h
|
||||
intern/eval/deg_eval_runtime_backup_object.h
|
||||
|
|
|
@ -32,7 +32,8 @@
|
|||
namespace DEG {
|
||||
|
||||
RuntimeBackup::RuntimeBackup(const Depsgraph *depsgraph)
|
||||
: scene_backup(depsgraph),
|
||||
: animation_backup(depsgraph),
|
||||
scene_backup(depsgraph),
|
||||
sound_backup(depsgraph),
|
||||
object_backup(depsgraph),
|
||||
drawdata_ptr(NULL),
|
||||
|
@ -47,6 +48,8 @@ void RuntimeBackup::init_from_id(ID *id)
|
|||
return;
|
||||
}
|
||||
|
||||
animation_backup.init_from_id(id);
|
||||
|
||||
const ID_Type id_type = GS(id->name);
|
||||
switch (id_type) {
|
||||
case ID_OB:
|
||||
|
@ -76,6 +79,8 @@ void RuntimeBackup::init_from_id(ID *id)
|
|||
|
||||
void RuntimeBackup::restore_to_id(ID *id)
|
||||
{
|
||||
animation_backup.restore_to_id(id);
|
||||
|
||||
const ID_Type id_type = GS(id->name);
|
||||
switch (id_type) {
|
||||
case ID_OB:
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_animation.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_movieclip.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_object.h"
|
||||
#include "intern/eval/deg_eval_runtime_backup_scene.h"
|
||||
|
@ -44,6 +45,7 @@ class RuntimeBackup {
|
|||
/* Restore fields to the given ID. */
|
||||
void restore_to_id(ID *id);
|
||||
|
||||
AnimationBackup animation_backup;
|
||||
SceneBackup scene_backup;
|
||||
SoundBackup sound_backup;
|
||||
ObjectRuntimeBackup object_backup;
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#include "intern/eval/deg_eval_runtime_backup_animation.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_types.h"
|
||||
|
||||
#include "intern/depsgraph.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
namespace {
|
||||
|
||||
struct AnimatedPropertyStoreCalbackData {
|
||||
AnimationBackup *backup;
|
||||
|
||||
/* ID which needs to be stored.
|
||||
* Is used to check possibly nested IDs which f-curves are pointing to. */
|
||||
ID *id;
|
||||
|
||||
PointerRNA id_pointer_rna;
|
||||
};
|
||||
|
||||
void animated_property_store_cb(ID *id, FCurve *fcurve, void *data_v)
|
||||
{
|
||||
AnimatedPropertyStoreCalbackData *data = reinterpret_cast<AnimatedPropertyStoreCalbackData *>(
|
||||
data_v);
|
||||
if (fcurve->rna_path == NULL || fcurve->rna_path[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
if (id != data->id) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Resolve path to the property. */
|
||||
PathResolvedRNA resolved_rna;
|
||||
if (!RNA_path_resolve_property_full(&data->id_pointer_rna,
|
||||
fcurve->rna_path,
|
||||
&resolved_rna.ptr,
|
||||
&resolved_rna.prop,
|
||||
&resolved_rna.prop_index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read property value. */
|
||||
float value;
|
||||
if (!BKE_animsys_read_rna_setting(&resolved_rna, &value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
data->backup->values_backup.emplace_back(fcurve->rna_path, value);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AnimationValueBackup::AnimationValueBackup()
|
||||
{
|
||||
}
|
||||
|
||||
AnimationValueBackup::AnimationValueBackup(const string &rna_path, float value)
|
||||
: rna_path(rna_path), value(value)
|
||||
{
|
||||
}
|
||||
|
||||
AnimationValueBackup::~AnimationValueBackup()
|
||||
{
|
||||
}
|
||||
|
||||
AnimationBackup::AnimationBackup(const Depsgraph *depsgraph)
|
||||
{
|
||||
meed_value_backup = !depsgraph->is_active;
|
||||
reset();
|
||||
}
|
||||
|
||||
void AnimationBackup::reset()
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationBackup::init_from_id(ID *id)
|
||||
{
|
||||
AnimatedPropertyStoreCalbackData data;
|
||||
data.backup = this;
|
||||
data.id = id;
|
||||
RNA_id_pointer_create(id, &data.id_pointer_rna);
|
||||
BKE_fcurves_id_cb(id, animated_property_store_cb, &data);
|
||||
}
|
||||
|
||||
void AnimationBackup::restore_to_id(ID *id)
|
||||
{
|
||||
PointerRNA id_pointer_rna;
|
||||
RNA_id_pointer_create(id, &id_pointer_rna);
|
||||
for (const AnimationValueBackup &value_backup : values_backup) {
|
||||
/* Resolve path to the property.
|
||||
*
|
||||
* NOTE: Do it again (after storing), since the sub-data [ointers might be
|
||||
* changed after copy-on-write.
|
||||
*/
|
||||
PathResolvedRNA resolved_rna;
|
||||
if (!RNA_path_resolve_property_full(&id_pointer_rna,
|
||||
value_backup.rna_path.c_str(),
|
||||
&resolved_rna.ptr,
|
||||
&resolved_rna.prop,
|
||||
&resolved_rna.prop_index)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write property value. */
|
||||
if (!BKE_animsys_write_rna_setting(&resolved_rna, value_backup.value)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace DEG
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2019 Blender Foundation.
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup depsgraph
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_modifier.h"
|
||||
|
||||
#include "intern/depsgraph_type.h"
|
||||
|
||||
namespace DEG {
|
||||
|
||||
struct Depsgraph;
|
||||
|
||||
class AnimationValueBackup {
|
||||
public:
|
||||
AnimationValueBackup();
|
||||
AnimationValueBackup(const string &rna_path, float value);
|
||||
~AnimationValueBackup();
|
||||
|
||||
AnimationValueBackup(const AnimationValueBackup &other) = default;
|
||||
AnimationValueBackup(AnimationValueBackup &&other) noexcept = default;
|
||||
|
||||
AnimationValueBackup &operator=(const AnimationValueBackup &other) = default;
|
||||
AnimationValueBackup &operator=(AnimationValueBackup &&other) = default;
|
||||
|
||||
string rna_path;
|
||||
float value;
|
||||
};
|
||||
|
||||
/* Backup of animated properties values. */
|
||||
class AnimationBackup {
|
||||
public:
|
||||
AnimationBackup(const Depsgraph *depsgraph);
|
||||
|
||||
void reset();
|
||||
|
||||
void init_from_id(ID *id);
|
||||
void restore_to_id(ID *id);
|
||||
|
||||
bool meed_value_backup;
|
||||
vector<AnimationValueBackup> values_backup;
|
||||
};
|
||||
|
||||
} // namespace DEG
|
Loading…
Reference in New Issue