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:
authorBrecht Van Lommel <brecht>2020-02-27 13:23:15 +0300
committerBrecht Van Lommel <brecht@blender.org>2020-02-27 17:25:35 +0300
commitf2b95b9eae2ee913c99cff7595527b18d8b49d0a (patch)
tree4bbd1a009cd5ace8bd9bb3efe8e5882a459b5f98 /source/blender/blenkernel
parent57b7833d1eff5e11bbdec654ff09fb24263cc055 (diff)
Objects: make evaluated data runtime storage usable for types other than mesh
This is in preparation of new object types. This only changes mesh_eval, we may do the same for mesh_deform_eval and other areas in the future if there is a need for it. Differential Revision: https://developer.blender.org/D6695
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c73
-rw-r--r--source/blender/blenkernel/intern/constraint.c6
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c4
-rw-r--r--source/blender/blenkernel/intern/displist.c16
-rw-r--r--source/blender/blenkernel/intern/effect.c6
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c32
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/object.c101
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c4
-rw-r--r--source/blender/blenkernel/intern/object_update.c4
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c8
13 files changed, 130 insertions, 132 deletions
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 9f436db97ee..8963f241ca8 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -287,6 +287,7 @@ void BKE_object_eval_uber_transform(struct Depsgraph *depsgraph, struct Object *
void BKE_object_eval_uber_data(struct Depsgraph *depsgraph,
struct Scene *scene,
struct Object *ob);
+void BKE_object_eval_assign_data(struct Object *object, struct ID *data, bool is_owned);
void BKE_object_eval_boundbox(struct Depsgraph *depsgraph, struct Object *object);
void BKE_object_synchronize_to_original(struct Depsgraph *depsgraph, struct Object *object);
@@ -326,8 +327,7 @@ int BKE_object_obdata_texspace_get(struct Object *ob,
float **r_loc,
float **r_size);
-struct Mesh *BKE_object_get_evaluated_mesh(const struct Depsgraph *depsgraph, struct Object *ob);
-struct Mesh *BKE_object_get_final_mesh(struct Object *object);
+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);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 3006ab76032..148c7a6b6c0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1719,43 +1719,12 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
}
}
-static void assign_object_mesh_eval(Object *object)
-{
- BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
-
- Mesh *mesh = (Mesh *)object->data;
- Mesh *mesh_eval = object->runtime.mesh_eval;
-
- /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
- * is not guaranteed to be owned by object.
- *
- * Check ownership now, since later on we can not go to a mesh owned by someone else via object's
- * runtime: this could cause access freed data on depsgraph destruction (mesh who owns the final
- * result might be freed prior to object). */
- if (mesh_eval == mesh->runtime.mesh_eval) {
- object->runtime.is_mesh_eval_owned = false;
- }
- else {
- mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- object->runtime.is_mesh_eval_owned = true;
- }
-
- /* NOTE: We are not supposed to invoke evaluation for original object, but some areas are still
- * under process of being ported, so we play safe here. */
- if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
- object->data = mesh_eval;
- }
- else {
- /* evaluated will be available via: 'object->runtime.mesh_eval' */
- }
-}
-
-static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob)
+static void mesh_build_extra_data(struct Depsgraph *depsgraph, Object *ob, Mesh *mesh_eval)
{
uint32_t eval_flags = DEG_get_eval_flags_for_id(depsgraph, &ob->id);
if (eval_flags & DAG_EVAL_NEED_SHRINKWRAP_BOUNDARY) {
- BKE_shrinkwrap_compute_boundary_data(ob->runtime.mesh_eval);
+ BKE_shrinkwrap_compute_boundary_data(mesh_eval);
}
}
@@ -1793,6 +1762,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
}
#endif
+ Mesh *mesh_eval = NULL, *mesh_deform_eval = NULL;
mesh_calc_modifiers(depsgraph,
scene,
ob,
@@ -1802,26 +1772,35 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
-1,
true,
true,
- &ob->runtime.mesh_deform_eval,
- &ob->runtime.mesh_eval);
-
- BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
-
- assign_object_mesh_eval(ob);
+ &mesh_deform_eval,
+ &mesh_eval);
+ /* The modifier stack evaluation is storing result in mesh->runtime.mesh_eval, but this result
+ * is not guaranteed to be owned by object.
+ *
+ * Check ownership now, since later on we can not go to a mesh owned by someone else via
+ * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns
+ * the final result might be freed prior to object). */
+ Mesh *mesh = ob->data;
+ const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval);
+ BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned);
+
+ ob->runtime.mesh_deform_eval = mesh_deform_eval;
ob->runtime.last_data_mask = *dataMask;
ob->runtime.last_need_mapping = need_mapping;
+ BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
+
if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
if (DEG_is_active(depsgraph)) {
BKE_sculpt_update_object_after_eval(depsgraph, ob);
}
}
- if (ob->runtime.mesh_eval != NULL) {
- mesh_runtime_check_normals_valid(ob->runtime.mesh_eval);
+ if (mesh_eval != NULL) {
+ mesh_runtime_check_normals_valid(mesh_eval);
}
- mesh_build_extra_data(depsgraph, ob);
+ mesh_build_extra_data(depsgraph, ob, mesh_eval);
}
static void editbmesh_build_data(struct Depsgraph *depsgraph,
@@ -1942,18 +1921,20 @@ Mesh *mesh_get_eval_final(struct Depsgraph *depsgraph,
CustomData_MeshMasks cddata_masks = *dataMask;
object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping);
- if (!ob->runtime.mesh_eval ||
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if ((mesh_eval == NULL) ||
!CustomData_MeshMasks_are_matching(&(ob->runtime.last_data_mask), &cddata_masks) ||
(need_mapping && !ob->runtime.last_need_mapping)) {
CustomData_MeshMasks_update(&cddata_masks, &ob->runtime.last_data_mask);
mesh_build_data(
depsgraph, scene, ob, &cddata_masks, need_mapping || ob->runtime.last_need_mapping);
+ mesh_eval = BKE_object_get_evaluated_mesh(ob);
}
- if (ob->runtime.mesh_eval) {
- BLI_assert(!(ob->runtime.mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL));
+ if (mesh_eval != NULL) {
+ BLI_assert(!(mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL));
}
- return ob->runtime.mesh_eval;
+ return mesh_eval;
}
Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 26dea11624b..3df1a84a0c9 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -368,7 +368,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* when not in EditMode, use the 'final' evaluated mesh, depsgraph
* ensures we build with CD_MDEFORMVERT layer
*/
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
BMEditMesh *em = BKE_editmesh_from_object(ob);
float plane[3];
float imat[3][3], tmat[3][3];
@@ -3968,7 +3968,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *UNUSED(depsgraph),
float track_no[3] = {0.0f, 0.0f, 0.0f};
SpaceTransform transform;
- Mesh *target_eval = ct->tar->runtime.mesh_eval;
+ Mesh *target_eval = BKE_object_get_evaluated_mesh(ct->tar);
copy_m4_m4(ct->matrix, cob->matrix);
@@ -4736,7 +4736,7 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
if (data->depth_ob) {
Object *depth_ob = data->depth_ob;
- Mesh *target_eval = depth_ob->runtime.mesh_eval;
+ Mesh *target_eval = BKE_object_get_evaluated_mesh(depth_ob);
if (target_eval) {
BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
BVHTreeRayHit hit;
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index e0abe836bf8..bdca888efcc 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -338,8 +338,8 @@ static void crazyspace_init_object_for_eval(struct Depsgraph *depsgraph,
{
Object *object_eval = DEG_get_evaluated_object(depsgraph, object);
*object_crazy = *object_eval;
- if (object_crazy->runtime.mesh_orig != NULL) {
- object_crazy->data = object_crazy->runtime.mesh_orig;
+ if (object_crazy->runtime.data_orig != NULL) {
+ object_crazy->data = object_crazy->runtime.data_orig;
}
}
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 6d7d42b2293..6963f629798 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1772,7 +1772,7 @@ static void do_makeDispListCurveTypes(Depsgraph *depsgraph,
curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render);
}
- if (cu->flag & CU_DEFORM_FILL && !ob->runtime.mesh_eval) {
+ if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) {
curve_to_filledpoly(cu, &nubase, dispbase);
}
@@ -1800,12 +1800,11 @@ void BKE_displist_make_curveTypes(
dispbase = &(ob->runtime.curve_cache->disp);
- do_makeDispListCurveTypes(
- depsgraph, scene, ob, dispbase, for_render, for_orco, &ob->runtime.mesh_eval);
+ Mesh *mesh_eval = NULL;
+ do_makeDispListCurveTypes(depsgraph, scene, ob, dispbase, for_render, for_orco, &mesh_eval);
- if (ob->runtime.mesh_eval != NULL) {
- ob->runtime.mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- ob->runtime.is_mesh_eval_owned = true;
+ if (mesh_eval != NULL) {
+ BKE_object_eval_assign_data(ob, &mesh_eval->id, true);
}
boundbox_displist_object(ob);
@@ -1861,8 +1860,9 @@ static void boundbox_displist_object(Object *ob)
ob->runtime.bb = MEM_callocN(sizeof(BoundBox), "boundbox");
}
- if (ob->runtime.mesh_eval) {
- BKE_object_boundbox_calc_from_mesh(ob, ob->runtime.mesh_eval);
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+ if (mesh_eval) {
+ BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
}
else {
float min[3], max[3];
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 8971021329a..4a9efc7cac4 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -315,7 +315,7 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph,
else if (weights->weight[ob->pd->forcefield] == 0.0f) {
continue;
}
- else if (ob->pd->shape == PFIELD_SHAPE_POINTS && ob->runtime.mesh_eval == NULL) {
+ else if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) {
continue;
}
@@ -656,7 +656,7 @@ int get_effector_data(EffectorCache *eff,
efd->size = 0.0f;
}
else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
- Mesh *me_eval = eff->ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
if (me_eval != NULL) {
copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
normal_short_to_float_v3(efd->nor, me_eval->mvert[*efd->index].no);
@@ -769,7 +769,7 @@ static void get_effector_tot(
efd->index = p;
if (eff->pd->shape == PFIELD_SHAPE_POINTS) {
- Mesh *me_eval = eff->ob->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
*tot = me_eval != NULL ? me_eval->totvert : 1;
if (*tot && eff->pd->forcefield == PFIELD_HARMONIC && point->index >= 0) {
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 014ccdb913e..f0bab4c0aa2 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -582,7 +582,7 @@ void BKE_mesh_from_nurbs_displist(
Main *bmain, Object *ob, ListBase *dispbase, const char *obdata_name, bool temporary)
{
Object *ob1;
- Mesh *me_eval = ob->runtime.mesh_eval;
+ Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
Mesh *me;
Curve *cu;
MVert *allvert = NULL;
@@ -644,7 +644,7 @@ void BKE_mesh_from_nurbs_displist(
me = BKE_id_new_nomain(ID_ME, obdata_name);
}
- ob->runtime.mesh_eval = NULL;
+ ob->runtime.data_eval = NULL;
BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
}
@@ -929,11 +929,9 @@ static Object *object_for_curve_to_mesh_create(Object *object)
BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp);
}
/* Constructive modifiers will use mesh to store result. */
- if (object->runtime.mesh_eval != NULL) {
- BKE_id_copy_ex(NULL,
- &object->runtime.mesh_eval->id,
- (ID **)&temp_object->runtime.mesh_eval,
- LIB_ID_COPY_LOCALIZE);
+ if (object->runtime.data_eval != NULL) {
+ BKE_id_copy_ex(
+ NULL, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
}
/* Need to create copy of curve itself as well, it will be freed by underlying conversion
@@ -994,19 +992,15 @@ static void curve_to_mesh_eval_ensure(Object *object)
* bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also
* Mesh From Curve operator.
* Brecht says hold off with that. */
- BKE_displist_make_curveTypes_forRender(NULL,
- NULL,
- &remapped_object,
- &remapped_object.runtime.curve_cache->disp,
- &remapped_object.runtime.mesh_eval,
- false);
+ Mesh *mesh_eval = NULL;
+ BKE_displist_make_curveTypes_forRender(
+ NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval, false);
/* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a
* real issue currently, code here is broken in more than one way, fix(es) will be done
* separately. */
- if (remapped_object.runtime.mesh_eval != NULL) {
- remapped_object.runtime.mesh_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- remapped_object.runtime.is_mesh_eval_owned = true;
+ if (mesh_eval != NULL) {
+ BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true);
}
BKE_object_free_curve_cache(&bevel_object);
@@ -1104,8 +1098,8 @@ static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object
}
Object object_for_eval = *object;
- if (object_for_eval.runtime.mesh_orig != NULL) {
- object_for_eval.data = object_for_eval.runtime.mesh_orig;
+ if (object_for_eval.runtime.data_orig != NULL) {
+ object_for_eval.data = object_for_eval.runtime.data_orig;
}
Scene *scene = DEG_get_evaluated_scene(depsgraph);
@@ -1306,7 +1300,7 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
ModifierData *md_eval,
int build_shapekey_layers)
{
- Mesh *me = ob_eval->runtime.mesh_orig ? ob_eval->runtime.mesh_orig : ob_eval->data;
+ Mesh *me = ob_eval->runtime.data_orig ? ob_eval->runtime.data_orig : ob_eval->data;
const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type);
Mesh *result;
KeyBlock *kb;
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 51c70406692..381e43241ea 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -1019,7 +1019,7 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval,
if (me == NULL) {
me = (get_cage_mesh && ob_eval->runtime.mesh_deform_eval != NULL) ?
ob_eval->runtime.mesh_deform_eval :
- ob_eval->runtime.mesh_eval;
+ BKE_object_get_evaluated_mesh(ob_eval);
}
return me;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 51d397a44bc..4d7d5861a09 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -363,11 +363,11 @@ static void object_update_from_subsurf_ccg(Object *object)
* (happens on dependency graph free where order of CoW-ed IDs free is undefined).
*
* Good news is: such mesh does not have modifiers applied, so no need to worry about CCG. */
- if (!object->runtime.is_mesh_eval_owned) {
+ if (!object->runtime.is_data_eval_owned) {
return;
}
/* Object was never evaluated, so can not have CCG subdivision surface. */
- Mesh *mesh_eval = object->runtime.mesh_eval;
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(object);
if (mesh_eval == NULL) {
return;
}
@@ -410,13 +410,13 @@ static void object_update_from_subsurf_ccg(Object *object)
/* TODO(sergey): Solve this somehow, to be fully stable for threaded
* evaluation environment.
*/
- /* NOTE: runtime.mesh_orig is what was before assigning mesh_eval,
+ /* NOTE: runtime.data_orig is what was before assigning mesh_eval,
* it is orig as in what was in object_eval->data before evaluating
* modifier stack.
*
* mesh_cow is a copy-on-written version od object_orig->data.
*/
- Mesh *mesh_cow = object->runtime.mesh_orig;
+ Mesh *mesh_cow = (Mesh *)object->runtime.data_orig;
copy_ccg_data(mesh_cow, mesh_orig, CD_MDISPS);
copy_ccg_data(mesh_cow, mesh_orig, CD_GRID_PAINT_MASK);
/* Everything is now up-to-date. */
@@ -424,6 +424,33 @@ static void object_update_from_subsurf_ccg(Object *object)
subdiv_ccg->dirty.hidden = false;
}
+/* Assign data after modifier stack evaluation. */
+void BKE_object_eval_assign_data(Object *object_eval, ID *data_eval, bool is_owned)
+{
+ BLI_assert(object_eval->id.tag & LIB_TAG_COPIED_ON_WRITE);
+ BLI_assert(object_eval->runtime.data_eval == NULL);
+ BLI_assert(data_eval->tag & LIB_TAG_NO_MAIN);
+
+ if (is_owned) {
+ /* Set flag for debugging. */
+ data_eval->tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
+ }
+
+ /* Assigned evaluated data. */
+ object_eval->runtime.data_eval = data_eval;
+ object_eval->runtime.is_data_eval_owned = is_owned;
+
+ /* Overwrite data of evaluated object, if the datablock types match. */
+ ID *data = object_eval->data;
+ if (GS(data->name) == GS(data_eval->name)) {
+ /* NOTE: we are not supposed to invoke evaluation for original objects,
+ * but some areas are still being ported, so we play safe here. */
+ if (object_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) {
+ object_eval->data = data_eval;
+ }
+ }
+}
+
/* free data derived from mesh, called when mesh changes or is freed */
void BKE_object_free_derived_caches(Object *ob)
{
@@ -431,17 +458,18 @@ void BKE_object_free_derived_caches(Object *ob)
object_update_from_subsurf_ccg(ob);
- /* Restore initial pointer. */
- if (ob->runtime.mesh_orig != NULL) {
- ob->data = ob->runtime.mesh_orig;
- }
-
- if (ob->runtime.mesh_eval != NULL) {
- if (ob->runtime.is_mesh_eval_owned) {
- Mesh *mesh_eval = ob->runtime.mesh_eval;
- BKE_mesh_eval_delete(mesh_eval);
+ if (ob->runtime.data_eval != NULL) {
+ if (ob->runtime.is_data_eval_owned) {
+ ID *data_eval = ob->runtime.data_eval;
+ if (GS(data_eval->name) == ID_ME) {
+ BKE_mesh_eval_delete((Mesh *)data_eval);
+ }
+ else {
+ BKE_libblock_free_datablock(data_eval, 0);
+ MEM_freeN(data_eval);
+ }
}
- ob->runtime.mesh_eval = NULL;
+ ob->runtime.data_eval = NULL;
}
if (ob->runtime.mesh_deform_eval != NULL) {
Mesh *mesh_deform_eval = ob->runtime.mesh_deform_eval;
@@ -449,6 +477,12 @@ void BKE_object_free_derived_caches(Object *ob)
ob->runtime.mesh_deform_eval = NULL;
}
+ /* Restore initial pointer for copy-on-write datablocks, object->data
+ * might be pointing to an evaluated datablock data was just freed above. */
+ if (ob->runtime.data_orig != NULL) {
+ ob->data = ob->runtime.data_orig;
+ }
+
BKE_object_to_mesh_clear(ob);
BKE_object_free_curve_cache(ob);
@@ -2308,7 +2342,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
if (par->type == OB_MESH) {
Mesh *me = par->data;
BMEditMesh *em = me->edit_mesh;
- Mesh *me_eval = (em) ? em->mesh_eval_final : par->runtime.mesh_eval;
+ Mesh *me_eval = (em) ? em->mesh_eval_final : BKE_object_get_evaluated_mesh(par);
if (me_eval) {
int count = 0;
@@ -3067,12 +3101,12 @@ void BKE_object_foreach_display_point(Object *ob,
void (*func_cb)(const float[3], void *),
void *user_data)
{
+ Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
float co[3];
- if (ob->runtime.mesh_eval) {
- const Mesh *me = ob->runtime.mesh_eval;
- const MVert *mv = me->mvert;
- const int totvert = me->totvert;
+ if (mesh_eval != NULL) {
+ const MVert *mv = mesh_eval->mvert;
+ const int totvert = mesh_eval->totvert;
for (int i = 0; i < totvert; i++, mv++) {
mul_v3_m4v3(co, obmat, mv->co);
func_cb(co, user_data);
@@ -3342,24 +3376,11 @@ int BKE_object_obdata_texspace_get(Object *ob, short **r_texflag, float **r_loc,
return 1;
}
-/** Get evaluated mesh for given (main, original) object and depsgraph. */
-Mesh *BKE_object_get_evaluated_mesh(const Depsgraph *depsgraph, Object *ob)
+/** Get evaluated mesh for given object. */
+Mesh *BKE_object_get_evaluated_mesh(Object *object)
{
- Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- return ob_eval->runtime.mesh_eval;
-}
-
-/* Get object's mesh with all modifiers applied. */
-Mesh *BKE_object_get_final_mesh(Object *object)
-{
- if (object->runtime.mesh_eval != NULL) {
- BLI_assert((object->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
- BLI_assert(object->runtime.mesh_eval == object->data);
- BLI_assert((object->runtime.mesh_eval->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) != 0);
- return object->runtime.mesh_eval;
- }
- /* Wasn't evaluated yet. */
- return object->data;
+ ID *data_eval = object->runtime.data_eval;
+ return (data_eval && GS(data_eval->name) == ID_ME) ? (Mesh *)data_eval : NULL;
}
/* Get mesh which is not affected by modifiers:
@@ -3370,11 +3391,11 @@ Mesh *BKE_object_get_final_mesh(Object *object)
*/
Mesh *BKE_object_get_pre_modified_mesh(Object *object)
{
- if (object->runtime.mesh_orig != NULL) {
+ if (object->type == OB_MESH && object->runtime.data_orig != NULL) {
BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
BLI_assert(object->id.orig_id != NULL);
- BLI_assert(object->runtime.mesh_orig->id.orig_id == ((Object *)object->id.orig_id)->data);
- Mesh *result = object->runtime.mesh_orig;
+ BLI_assert(object->runtime.data_orig->orig_id == ((Object *)object->id.orig_id)->data);
+ Mesh *result = (Mesh *)object->runtime.data_orig;
BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE) != 0);
BLI_assert((result->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
return result;
@@ -3925,7 +3946,7 @@ void BKE_object_runtime_reset(Object *object)
void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag))
{
Object_Runtime *runtime = &object->runtime;
- runtime->mesh_eval = NULL;
+ runtime->data_eval = NULL;
runtime->mesh_deform_eval = NULL;
runtime->curve_cache = NULL;
runtime->gpencil_cache = NULL;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index c10ab3cddab..28b6e0d4e02 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -426,7 +426,7 @@ static void make_duplis_verts(const DupliContext *ctx)
vdd.me_eval = vdd.edit_mesh->mesh_eval_cage;
}
else {
- vdd.me_eval = parent->runtime.mesh_eval;
+ vdd.me_eval = BKE_object_get_evaluated_mesh(parent);
}
if (vdd.me_eval == NULL) {
@@ -702,7 +702,7 @@ static void make_duplis_faces(const DupliContext *ctx)
fdd.me_eval = em->mesh_eval_cage;
}
else {
- fdd.me_eval = parent->runtime.mesh_eval;
+ fdd.me_eval = BKE_object_get_evaluated_mesh(parent);
}
if (fdd.me_eval == NULL) {
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 366fd0950fa..c647afdd00a 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -398,8 +398,8 @@ void BKE_object_data_select_update(Depsgraph *depsgraph, ID *object_data)
void BKE_object_select_update(Depsgraph *depsgraph, Object *object)
{
DEG_debug_print_eval(depsgraph, __func__, object->id.name, object);
- if (object->type == OB_MESH && !object->runtime.is_mesh_eval_owned) {
- Mesh *mesh_input = object->runtime.mesh_orig;
+ if (object->type == OB_MESH && !object->runtime.is_data_eval_owned) {
+ Mesh *mesh_input = (Mesh *)object->runtime.data_orig;
Mesh_Runtime *mesh_runtime = &mesh_input->runtime;
BLI_mutex_lock(mesh_runtime->eval_mutex);
BKE_object_data_select_update(depsgraph, object->data);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 2cc1681d436..4da7d8d007a 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -1351,7 +1351,7 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval)
/* Update after mesh evaluation in the dependency graph, to rebuild PBVH or
* other data when modifiers change the mesh. */
Object *ob_orig = DEG_get_original_object(ob_eval);
- Mesh *me_eval = ob_eval->runtime.mesh_eval;
+ Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
BLI_assert(me_eval != NULL);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index c2180e50b74..494c5e21613 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -332,22 +332,24 @@ void BKE_rigidbody_object_copy(Main *bmain, Object *ob_dst, const Object *ob_src
/* get the appropriate evaluated mesh based on rigid body mesh source */
static Mesh *rigidbody_get_mesh(Object *ob)
{
+ BLI_assert(ob->type == OB_MESH);
+
switch (ob->rigidbody_object->mesh_source) {
case RBO_MESH_DEFORM:
return ob->runtime.mesh_deform_eval;
case RBO_MESH_FINAL:
- return ob->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(ob);
case RBO_MESH_BASE:
/* This mesh may be used for computing looptris, which should be done
* on the original; otherwise every time the CoW is recreated it will
* have to be recomputed. */
BLI_assert(ob->rigidbody_object->mesh_source == RBO_MESH_BASE);
- return ob->runtime.mesh_orig;
+ return (Mesh *)ob->runtime.data_orig;
}
/* Just return something sensible so that at least Blender won't crash. */
BLI_assert(!"Unknown mesh source");
- return ob->runtime.mesh_eval;
+ return BKE_object_get_evaluated_mesh(ob);
}
/* create collision shape of mesh - convex hull */