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:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-06-04 16:11:09 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-06-04 16:17:16 +0300
commit07f004620397fd818d2684d08ff67422d76a92cf (patch)
tree5a0db889de90d702a3b6814ede41f497faddfdda /source/blender/depsgraph/intern/eval
parent1dc31f5b982559bbe875d469950ee7404e9a4a3c (diff)
Fix crash when making objects to share same mesh
Make it more reliable and predictable way of getting pointer to an original mesh which came from copy-on-write engine. Related change: made it (hopefully) more clear name for flags.
Diffstat (limited to 'source/blender/depsgraph/intern/eval')
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc48
1 files changed, 31 insertions, 17 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 2789f189f03..858e366b280 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -542,6 +542,7 @@ void update_special_pointers(const Depsgraph *depsgraph,
BLI_assert(object_cow->derivedDeform == NULL);
object_cow->mode = object_orig->mode;
object_cow->sculpt = object_orig->sculpt;
+ object_cow->runtime.mesh_orig = (Mesh *)object_cow->data;
if (object_cow->type == OB_ARMATURE) {
BKE_pose_remap_bone_pointers((bArmature *)object_cow->data,
object_cow->pose);
@@ -724,12 +725,12 @@ static void deg_backup_object_runtime(
Mesh *mesh_eval = object->runtime.mesh_eval;
object_runtime_backup->runtime = object->runtime;
BKE_object_runtime_reset(object);
- /* Currently object update will override actual object->data
- * to an evaluated version. Need to make sure we don't have
- * data set to evaluated one before free anything.
+ /* Object update will override actual object->data to an evaluated version.
+ * Need to make sure we don't have data set to evaluated one before free
+ * anything.
*/
if (mesh_eval != NULL && object->data == mesh_eval) {
- object->data = mesh_eval->id.orig_id;
+ object->data = object->runtime.mesh_orig;
}
/* Store curve cache and make sure we don't free it. */
object_runtime_backup->curve_cache = object->curve_cache;
@@ -742,20 +743,33 @@ static void deg_restore_object_runtime(
Object *object,
const ObjectRuntimeBackup *object_runtime_backup)
{
+ Mesh *mesh_orig = object->runtime.mesh_orig;
object->runtime = object_runtime_backup->runtime;
+ object->runtime.mesh_orig = mesh_orig;
if (object->runtime.mesh_eval != NULL) {
- Mesh *mesh_eval = object->runtime.mesh_eval;
- /* Do same thing as object update: override actual object data
- * pointer with evaluated datablock.
- */
- if (object->type == OB_MESH) {
- object->data = mesh_eval;
- /* Evaluated mesh simply copied edit_btmesh pointer from
- * original mesh during update, need to make sure no dead
- * pointers are left behind.
+ if (object->id.recalc & ID_RECALC_GEOMETRY) {
+ /* If geometry is tagged for update it means, that part of
+ * evaluated mesh are not valid anymore. In this case we can not
+ * have any "persistent" pointers to point to an invalid data.
+ *
+ * We restore object's data datablock to an original copy of
+ * that datablock.
+ */
+ object->data = mesh_orig;
+ }
+ else {
+ Mesh *mesh_eval = object->runtime.mesh_eval;
+ /* Do same thing as object update: override actual object data
+ * pointer with evaluated datablock.
*/
- Mesh *mesh = ((Mesh *)mesh_eval->id.orig_id);
- mesh_eval->edit_btmesh = mesh->edit_btmesh;
+ if (object->type == OB_MESH) {
+ object->data = mesh_eval;
+ /* Evaluated mesh simply copied edit_btmesh pointer from
+ * original mesh during update, need to make sure no dead
+ * pointers are left behind.
+ */
+ mesh_eval->edit_btmesh = mesh_orig->edit_btmesh;
+ }
}
}
if (object_runtime_backup->curve_cache != NULL) {
@@ -995,8 +1009,8 @@ bool deg_validate_copy_on_write_datablock(ID *id_cow)
void deg_tag_copy_on_write_id(ID *id_cow, const ID *id_orig)
{
BLI_assert(id_cow != id_orig);
- BLI_assert((id_orig->tag & LIB_TAG_COPY_ON_WRITE) == 0);
- id_cow->tag |= LIB_TAG_COPY_ON_WRITE;
+ BLI_assert((id_orig->tag & LIB_TAG_COPIED_ON_WRITE) == 0);
+ id_cow->tag |= LIB_TAG_COPIED_ON_WRITE;
id_cow->orig_id = (ID *)id_orig;
}