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
path: root/source
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2021-03-29 11:14:53 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-03-29 12:00:32 +0300
commit3681a619ded1a6b225befc31ef87259081fb61e5 (patch)
tree35f841fc7287689e25c95da5aa89842b75a9fd7b /source
parent8034b276ba6c5369a356a1b8f5e858305f8b47b9 (diff)
Fix T78650: Lattice evaluation writes to shared data
Fix the data management bug where evaluation of lattice objects would write back to the CoW copy of the Lattice ID, even when that copy was shared between objects. Each lattice object evaluation now stores its own evaluated data copy via `BKE_object_eval_assign_data()`. Reviewed By: sergey Maniphest Tasks: T78650 Differential Revision: https://developer.blender.org/D10790
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_object.h6
-rw-r--r--source/blender/blenkernel/intern/lattice.c61
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c6
-rw-r--r--source/blender/blenkernel/intern/lattice_deform_test.cc1
-rw-r--r--source/blender/blenkernel/intern/object.c31
5 files changed, 60 insertions, 45 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 12c40e891c9..0c2c6313dde 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -336,6 +336,12 @@ struct Mesh *BKE_object_get_evaluated_mesh(struct Object *object);
struct Mesh *BKE_object_get_pre_modified_mesh(struct Object *object);
struct Mesh *BKE_object_get_original_mesh(struct Object *object);
+/* Lattice accessors.
+ * These functions return either the regular lattice, or the edit-mode lattice,
+ * whichever is currently in use. */
+struct Lattice *BKE_object_get_lattice(const struct Object *object);
+struct Lattice *BKE_object_get_evaluated_lattice(const struct Object *object);
+
int BKE_object_insert_ptcache(struct Object *ob);
void BKE_object_delete_ptcache(struct Object *ob, int index);
struct KeyBlock *BKE_object_shapekey_insert(struct Main *bmain,
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 7c451051727..48104e72825 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -540,10 +540,12 @@ void BKE_lattice_vert_coords_apply(Lattice *lt, const float (*vert_coords)[3])
void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
{
+ BKE_object_free_derived_caches(ob);
+ if (ob->runtime.curve_cache == NULL) {
+ ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice");
+ }
+
Lattice *lt = ob->data;
- /* Get vertex coordinates from the original copy;
- * otherwise we get already-modified coordinates. */
- Object *ob_orig = DEG_get_original_object(ob);
VirtualModifierData virtualModifierData;
ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData);
float(*vert_coords)[3] = NULL;
@@ -551,13 +553,6 @@ void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Objec
const bool is_editmode = (lt->editlatt != NULL);
const ModifierEvalContext mectx = {depsgraph, ob, 0};
- if (ob->runtime.curve_cache) {
- BKE_displist_free(&ob->runtime.curve_cache->disp);
- }
- else {
- ob->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice");
- }
-
for (; md; md = md->next) {
const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type);
@@ -577,49 +572,33 @@ void BKE_lattice_modifiers_calc(struct Depsgraph *depsgraph, Scene *scene, Objec
continue;
}
- if (!vert_coords) {
- Lattice *lt_orig = ob_orig->data;
- if (lt_orig->editlatt) {
- lt_orig = lt_orig->editlatt->latt;
- }
- vert_coords = BKE_lattice_vert_coords_alloc(lt_orig, &numVerts);
+ if (vert_coords == NULL) {
+ /* Get either the edit-mode or regular lattice, whichever is in use now. */
+ const Lattice *effective_lattice = BKE_object_get_lattice(ob);
+ vert_coords = BKE_lattice_vert_coords_alloc(effective_lattice, &numVerts);
}
+
mti->deformVerts(md, &mectx, NULL, vert_coords, numVerts);
}
- if (ob->id.tag & LIB_TAG_COPIED_ON_WRITE) {
- if (vert_coords) {
- BKE_lattice_vert_coords_apply(ob->data, vert_coords);
- MEM_freeN(vert_coords);
- }
+ if (vert_coords == NULL) {
+ return;
}
- else {
- /* Displist won't do anything; this is just for posterity's sake until we remove it. */
- if (!vert_coords) {
- Lattice *lt_orig = ob_orig->data;
- if (lt_orig->editlatt) {
- lt_orig = lt_orig->editlatt->latt;
- }
- vert_coords = BKE_lattice_vert_coords_alloc(lt_orig, &numVerts);
- }
-
- DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
- dl->type = DL_VERTS;
- dl->parts = 1;
- dl->nr = numVerts;
- dl->verts = (float *)vert_coords;
- BLI_addtail(&ob->runtime.curve_cache->disp, dl);
+ Lattice *lt_eval = BKE_object_get_evaluated_lattice(ob);
+ if (lt_eval == NULL) {
+ BKE_id_copy_ex(NULL, &lt->id, (ID **)&lt_eval, LIB_ID_COPY_LOCALIZE);
+ BKE_object_eval_assign_data(ob, &lt_eval->id, true);
}
+
+ BKE_lattice_vert_coords_apply(lt_eval, vert_coords);
+ MEM_freeN(vert_coords);
}
struct MDeformVert *BKE_lattice_deform_verts_get(const struct Object *oblatt)
{
- Lattice *lt = (Lattice *)oblatt->data;
BLI_assert(oblatt->type == OB_LATTICE);
- if (lt->editlatt) {
- lt = lt->editlatt->latt;
- }
+ Lattice *lt = BKE_object_get_lattice(oblatt);
return lt->dvert;
}
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 2651042939f..4a926ee3d96 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -47,6 +47,7 @@
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_modifier.h"
+#include "BKE_object.h"
#include "BKE_deform.h"
@@ -69,7 +70,7 @@ typedef struct LatticeDeformData {
LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Object *ob)
{
/* we make an array with all differences */
- Lattice *lt = oblatt->data;
+ Lattice *lt = BKE_object_get_lattice(oblatt);
BPoint *bp;
DispList *dl = oblatt->runtime.curve_cache ?
BKE_displist_find(&oblatt->runtime.curve_cache->disp, DL_VERTS) :
@@ -83,9 +84,6 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
float latmat[4][4];
LatticeDeformData *lattice_deform_data;
- if (lt->editlatt) {
- lt = lt->editlatt->latt;
- }
bp = lt->def;
const int32_t num_points = lt->pntsu * lt->pntsv * lt->pntsw;
diff --git a/source/blender/blenkernel/intern/lattice_deform_test.cc b/source/blender/blenkernel/intern/lattice_deform_test.cc
index f08d0349598..a7cd5c36ec2 100644
--- a/source/blender/blenkernel/intern/lattice_deform_test.cc
+++ b/source/blender/blenkernel/intern/lattice_deform_test.cc
@@ -51,6 +51,7 @@ static void test_lattice_deform_init(LatticeDeformTestContext *ctx,
ctx->coords[index][2] = (rng->get_float() - 0.5f) * 10;
}
IDType_ID_LT.init_data(&ctx->lattice.id);
+ strcpy(ctx->lattice.id.name, "LTLattice");
IDType_ID_OB.init_data(&ctx->ob_lattice.id);
ctx->ob_lattice.type = OB_LATTICE;
ctx->ob_lattice.data = &ctx->lattice;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index b07c4b22c39..a8224094919 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -4474,6 +4474,37 @@ Mesh *BKE_object_get_original_mesh(Object *object)
return result;
}
+Lattice *BKE_object_get_lattice(const Object *object)
+{
+ ID *data = object->data;
+ if (data == NULL || GS(data->name) != ID_LT) {
+ return NULL;
+ }
+
+ Lattice *lt = (Lattice *)data;
+ if (lt->editlatt) {
+ return lt->editlatt->latt;
+ }
+
+ return lt;
+}
+
+Lattice *BKE_object_get_evaluated_lattice(const Object *object)
+{
+ ID *data_eval = object->runtime.data_eval;
+
+ if (data_eval == NULL || GS(data_eval->name) != ID_LT) {
+ return NULL;
+ }
+
+ Lattice *lt_eval = (Lattice *)data_eval;
+ if (lt_eval->editlatt) {
+ return lt_eval->editlatt->latt;
+ }
+
+ return lt_eval;
+}
+
static int pc_cmp(const void *a, const void *b)
{
const LinkData *ad = a, *bd = b;