Objects: make evaluated data runtime storage usable for types other than mesh
authorBrecht Van Lommel <brecht>
Thu, 27 Feb 2020 10:23:15 +0000 (11:23 +0100)
committerBrecht Van Lommel <brecht@blender.org>
Thu, 27 Feb 2020 14:25:35 +0000 (15:25 +0100)
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

28 files changed:
source/blender/alembic/intern/abc_writer_curves.cc
source/blender/alembic/intern/abc_writer_mball.cc
source/blender/blenkernel/BKE_object.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/crazyspace.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/mesh_convert.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/object_dupli.c
source/blender/blenkernel/intern/object_update.c
source/blender/blenkernel/intern/paint.c
source/blender/blenkernel/intern/rigidbody.c
source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
source/blender/draw/intern/draw_cache.c
source/blender/editors/mesh/editface.c
source/blender/editors/mesh/editmesh_knife_project.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_info/info_stats.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/transform/transform_snap_object.c
source/blender/makesdna/DNA_object_types.h
source/blender/makesrna/intern/rna_object_api.c
source/blender/usd/intern/usd_writer_mesh.cc

index bb9109dc025684bcf5c4dd83f265c4143d4184b6..3ab9b365a72be6c003ea5b6d20aeb7a69d8eb7e2 100644 (file)
@@ -31,6 +31,7 @@ extern "C" {
 
 #include "BKE_curve.h"
 #include "BKE_mesh.h"
+#include "BKE_object.h"
 }
 
 using Alembic::AbcGeom::OCompoundProperty;
@@ -176,10 +177,11 @@ Mesh *AbcCurveMeshWriter::getEvaluatedMesh(Scene * /*scene_eval*/,
                                            Object *ob_eval,
                                            bool &r_needsfree)
 {
-  if (ob_eval->runtime.mesh_eval != NULL) {
+  Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+  if (mesh_eval != NULL) {
     /* Mesh_eval only exists when generative modifiers are in use. */
     r_needsfree = false;
-    return ob_eval->runtime.mesh_eval;
+    return mesh_eval;
   }
 
   r_needsfree = true;
index aa08146c6e2f08fab20ca95f2386ffd3630153db..cc0775bd537dfac3e41363ca1cdd47430504619e 100644 (file)
@@ -30,6 +30,7 @@ extern "C" {
 #include "BKE_lib_id.h"
 #include "BKE_mball.h"
 #include "BKE_mesh.h"
+#include "BKE_object.h"
 
 #include "BLI_utildefines.h"
 }
@@ -55,10 +56,11 @@ bool AbcMBallWriter::isAnimated() const
 
 Mesh *AbcMBallWriter::getEvaluatedMesh(Scene * /*scene_eval*/, Object *ob_eval, bool &r_needsfree)
 {
-  if (ob_eval->runtime.mesh_eval != NULL) {
+  Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob_eval);
+  if (mesh_eval != NULL) {
     /* Mesh_eval only exists when generative modifiers are in use. */
     r_needsfree = false;
-    return ob_eval->runtime.mesh_eval;
+    return mesh_eval;
   }
   r_needsfree = true;
 
index 9f436db97ee25b17c176b9c39dc4f8b96e6b8b6d..8963f241ca89cb42ce2f8a6b9f33b51283d6545d 100644 (file)
@@ -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);
 
index 3006ab76032bca9a1fdc4da28e2623ebba05c0c0..148c7a6b6c0d68b94c61b032a74e07d31dc02dec 100644 (file)
@@ -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,
index 26dea11624ba90e884792f3cfda71b29761f7e5e..3df1a84a0c9928970a3dd4e7787ab988c5289caf 100644 (file)
@@ -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;
index e0abe836bf82c4ced83d3b75a91b0cb0f8a62601..bdca888efcc6293e77accd099480e697432732b6 100644 (file)
@@ -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;
   }
 }
 
index 6d7d42b2293aeca52dbc5c7fdd7804b93bcdf73c..6963f629798b0748d754fafb88e44667d72249c6 100644 (file)
@@ -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];
index 8971021329ae2285acda8eef454d335fe8be73d0..4a9efc7cac436497af9e5af2523e5d1927b58061 100644 (file)
@@ -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) {
index 014ccdb913e460183108af6598d0b31e171e19c8..f0bab4c0aa24f023b1319a2ac545d85f0313891c 100644 (file)
@@ -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;
index 51c70406692fdc59444629a06666eefa86f948e8..381e43241ea04b13dc5bbd594a84d0a748ca2fff 100644 (file)
@@ -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;
index 51d397a44bcb74d72ec1584ce3ebfa57458fad93..4d7d5861a0963775043c7e40030b613d1895cb73 100644 (file)
@@ -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;
index c10ab3cddabd6489a1c920c3958bf6dcd5943672..28b6e0d4e02425a31dd007ddb370c00abd580be6 100644 (file)
@@ -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) {
index 366fd0950fa755d3c3a5a49e39fc18261e168272..c647afdd00a65a9734d4a2efaba7106a727a68e0 100644 (file)
@@ -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);
index 2cc1681d436d3bde06d74d8b2b7ddce96c5469da..4da7d8d007a6b3cf593ce31f507af5f8a5113e73 100644 (file)
@@ -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);
 
index c2180e50b744501545f1a65e0110f3d80043c74e..494c5e2161305a9448fb760c8e81845a3629ccf0 100644 (file)
@@ -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 */
index edb02ee331f57a9dd489e43d441a22c613b4d7ea..95521ee9e479d313fe64ad8aa5a188f651a36904 100644 (file)
@@ -781,9 +781,7 @@ void update_id_after_copy(const Depsgraph *depsgraph,
       const Object *object_orig = (const Object *)id_orig;
       object_cow->mode = object_orig->mode;
       object_cow->sculpt = object_orig->sculpt;
-      if (object_cow->type == OB_MESH) {
-        object_cow->runtime.mesh_orig = (Mesh *)object_cow->data;
-      }
+      object_cow->runtime.data_orig = (ID *)object_cow->data;
       if (object_cow->type == OB_ARMATURE) {
         const bArmature *armature_orig = (bArmature *)object_orig->data;
         bArmature *armature_cow = (bArmature *)object_cow->data;
index df7338e1076ef0392eee64f19cb0f7902dbbf425..acbcd4d551dff4388d8b9fc6ddd25ded6b2fd49f 100644 (file)
@@ -44,7 +44,6 @@ ObjectRuntimeBackup::ObjectRuntimeBackup(const Depsgraph * /*depsgraph*/)
 void ObjectRuntimeBackup::init_from_object(Object *object)
 {
   /* Store evaluated mesh and curve_cache, and make sure we don't free it. */
-  Mesh *mesh_eval = object->runtime.mesh_eval;
   runtime = object->runtime;
   BKE_object_runtime_reset(object);
   /* Keep bbox (for now at least). */
@@ -52,9 +51,7 @@ void ObjectRuntimeBackup::init_from_object(Object *object)
   /* 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 != nullptr && object->data == mesh_eval) {
-    object->data = runtime.mesh_orig;
-  }
+  object->data = runtime.data_orig;
   /* Make a backup of base flags. */
   base_flag = object->base_flag;
   base_local_view_bits = object->base_local_view_bits;
@@ -98,12 +95,13 @@ void ObjectRuntimeBackup::backup_pose_channel_runtime_data(Object *object)
 
 void ObjectRuntimeBackup::restore_to_object(Object *object)
 {
-  Mesh *mesh_orig = object->runtime.mesh_orig;
+  ID *data_orig = object->runtime.data_orig;
+  ID *data_eval = object->runtime.data_eval;
   BoundBox *bb = object->runtime.bb;
   object->runtime = runtime;
-  object->runtime.mesh_orig = mesh_orig;
+  object->runtime.data_orig = data_orig;
   object->runtime.bb = bb;
-  if (object->type == OB_MESH && object->runtime.mesh_eval != nullptr) {
+  if (object->type == OB_MESH && data_eval != nullptr) {
     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
@@ -111,20 +109,24 @@ void ObjectRuntimeBackup::restore_to_object(Object *object)
        *
        * We restore object's data datablock to an original copy of
        * that datablock. */
-      object->data = mesh_orig;
+      object->data = data_orig;
 
       /* After that, immediately free the invalidated caches. */
       BKE_object_free_derived_caches(object);
     }
     else {
-      Mesh *mesh_eval = object->runtime.mesh_eval;
       /* Do same thing as object update: override actual object data
        * pointer with evaluated datablock. */
-      object->data = mesh_eval;
+      object->data = data_eval;
+
       /* Evaluated mesh simply copied edit_mesh pointer from
        * original mesh during update, need to make sure no dead
        * pointers are left behind. */
-      mesh_eval->edit_mesh = mesh_orig->edit_mesh;
+      if (object->type == OB_MESH) {
+        Mesh *mesh_eval = (Mesh *)data_eval;
+        Mesh *mesh_orig = (Mesh *)data_orig;
+        mesh_eval->edit_mesh = mesh_orig->edit_mesh;
+      }
     }
   }
   object->base_flag = base_flag;
index 8057d167e2f3328d389a2ffc3f170339e8219c33..f37e5b14d83100f98da90e7206792fd45b4e12fe 100644 (file)
@@ -836,12 +836,12 @@ GPUBatch *DRW_cache_object_surface_get(Object *ob)
 
 int DRW_cache_object_material_count_get(struct Object *ob)
 {
-  Mesh *me = (ob->runtime.mesh_eval != NULL) ? ob->runtime.mesh_eval : (Mesh *)ob->data;
-  short type = (ob->runtime.mesh_eval != NULL) ? OB_MESH : ob->type;
+  Mesh *me = BKE_object_get_evaluated_mesh(ob);
+  short type = (me != NULL) ? OB_MESH : ob->type;
 
   switch (type) {
     case OB_MESH:
-      return DRW_mesh_material_count_get(me);
+      return DRW_mesh_material_count_get((me != NULL) ? me : ob->data);
     case OB_CURVE:
     case OB_SURF:
     case OB_FONT:
@@ -2807,7 +2807,7 @@ GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
   BLI_assert(ob->type == OB_CURVE);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
   }
@@ -2845,7 +2845,7 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
   BLI_assert(ob->type == OB_CURVE);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_surface(mesh_eval);
   }
@@ -2859,7 +2859,7 @@ GPUBatch *DRW_cache_curve_loose_edges_get(Object *ob)
   BLI_assert(ob->type == OB_CURVE);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
   }
@@ -2875,7 +2875,7 @@ GPUBatch *DRW_cache_curve_face_wireframe_get(Object *ob)
   BLI_assert(ob->type == OB_CURVE);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
   }
@@ -2888,7 +2888,7 @@ GPUBatch *DRW_cache_curve_edge_detection_get(Object *ob, bool *r_is_manifold)
 {
   BLI_assert(ob->type == OB_CURVE);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
   }
@@ -2905,7 +2905,7 @@ GPUBatch **DRW_cache_curve_surface_shaded_get(Object *ob,
   BLI_assert(ob->type == OB_CURVE);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
   }
@@ -2957,7 +2957,7 @@ GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
 {
   BLI_assert(ob->type == OB_FONT);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   const bool has_surface = (cu->flag & (CU_FRONT | CU_BACK)) || cu->ext1 != 0.0f ||
                            cu->ext2 != 0.0f;
   if (!has_surface) {
@@ -2975,7 +2975,7 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
 {
   BLI_assert(ob->type == OB_FONT);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (cu->editfont && (cu->flag & CU_FAST)) {
     return NULL;
   }
@@ -2991,7 +2991,7 @@ GPUBatch *DRW_cache_text_edge_detection_get(Object *ob, bool *r_is_manifold)
 {
   BLI_assert(ob->type == OB_FONT);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (cu->editfont && (cu->flag & CU_FAST)) {
     return NULL;
   }
@@ -3007,7 +3007,7 @@ GPUBatch *DRW_cache_text_loose_edges_get(Object *ob)
 {
   BLI_assert(ob->type == OB_FONT);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (cu->editfont && (cu->flag & CU_FAST)) {
     return NULL;
   }
@@ -3024,7 +3024,7 @@ GPUBatch *DRW_cache_text_face_wireframe_get(Object *ob)
 {
   BLI_assert(ob->type == OB_FONT);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (cu->editfont && (cu->flag & CU_FAST)) {
     return NULL;
   }
@@ -3042,7 +3042,7 @@ GPUBatch **DRW_cache_text_surface_shaded_get(Object *ob,
 {
   BLI_assert(ob->type == OB_FONT);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (cu->editfont && (cu->flag & CU_FAST)) {
     return NULL;
   }
@@ -3065,7 +3065,7 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
   BLI_assert(ob->type == OB_SURF);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_surface(mesh_eval);
   }
@@ -3079,7 +3079,7 @@ GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
   BLI_assert(ob->type == OB_SURF);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
   }
@@ -3093,7 +3093,7 @@ GPUBatch *DRW_cache_surf_face_wireframe_get(Object *ob)
   BLI_assert(ob->type == OB_SURF);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_wireframes_face(mesh_eval);
   }
@@ -3106,7 +3106,7 @@ GPUBatch *DRW_cache_surf_edge_detection_get(Object *ob, bool *r_is_manifold)
 {
   BLI_assert(ob->type == OB_SURF);
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_edge_detection(mesh_eval, r_is_manifold);
   }
@@ -3120,7 +3120,7 @@ GPUBatch *DRW_cache_surf_loose_edges_get(Object *ob)
   BLI_assert(ob->type == OB_SURF);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_loose_edges(mesh_eval);
   }
@@ -3139,7 +3139,7 @@ GPUBatch **DRW_cache_surf_surface_shaded_get(Object *ob,
   BLI_assert(ob->type == OB_SURF);
 
   struct Curve *cu = ob->data;
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   if (mesh_eval != NULL) {
     return DRW_mesh_batch_cache_get_surface_shaded(mesh_eval, gpumat_array, gpumat_array_len);
   }
@@ -3398,7 +3398,7 @@ GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
 
 void drw_batch_cache_validate(Object *ob)
 {
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   switch (ob->type) {
     case OB_MESH:
       DRW_mesh_batch_cache_validate((Mesh *)ob->data);
@@ -3436,7 +3436,7 @@ void drw_batch_cache_generate_requested(Object *ob)
                            DRW_object_use_hide_faces(ob)) ||
                           ((mode == CTX_MODE_EDIT_MESH) && DRW_object_is_in_edit_mode(ob))));
 
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
   switch (ob->type) {
     case OB_MESH:
       DRW_mesh_batch_cache_create_requested(ob, (Mesh *)ob->data, scene, is_paint_mode, use_hide);
@@ -3457,7 +3457,7 @@ void drw_batch_cache_generate_requested(Object *ob)
 
 void DRW_batch_cache_free_old(Object *ob, int ctime)
 {
-  struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+  struct Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
 
   switch (ob->type) {
     case OB_MESH:
index 5c9fb866df7bc25ca679239d128d6058299d0c9e..5f948595a225723dedf4001f9328e486dbae8449 100644 (file)
@@ -35,6 +35,7 @@
 #include "BKE_customdata.h"
 #include "BKE_global.h"
 #include "BKE_mesh.h"
+#include "BKE_object.h"
 
 #include "ED_mesh.h"
 #include "ED_screen.h"
@@ -80,8 +81,8 @@ void paintface_flush_flags(struct bContext *C, Object *ob, short flag)
     return;
   }
 
-  Mesh *me_orig = ob_eval->runtime.mesh_orig;
-  Mesh *me_eval = ob_eval->runtime.mesh_eval;
+  Mesh *me_orig = (Mesh *)ob_eval->runtime.data_orig;
+  Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval;
   bool updated = false;
 
   if (me_orig != NULL && me_eval != NULL && me_orig->totpoly == me->totpoly) {
@@ -443,7 +444,7 @@ bool paintface_mouse_select(
 void paintvert_flush_flags(Object *ob)
 {
   Mesh *me = BKE_mesh_from_object(ob);
-  Mesh *me_eval = ob->runtime.mesh_eval;
+  Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
   MVert *mvert_eval, *mv;
   const int *index_array = NULL;
   int totvert;
index 8d5c146969405d86fb824d24f02079460e23b8aa..21de89d33dd17e9aa26d92fe46bd36cd8f2cd481 100644 (file)
@@ -33,6 +33,7 @@
 #include "BKE_curve.h"
 #include "BKE_editmesh.h"
 #include "BKE_mesh_runtime.h"
+#include "BKE_object.h"
 #include "BKE_report.h"
 
 #include "DEG_depsgraph.h"
@@ -61,9 +62,9 @@ static LinkNode *knifeproject_poly_from_object(const bContext *C,
   struct Mesh *me_eval;
   bool me_eval_needs_free;
 
-  if (ob->type == OB_MESH || ob->runtime.mesh_eval) {
+  if (ob->type == OB_MESH || ob->runtime.data_eval) {
     Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
-    me_eval = ob_eval->runtime.mesh_eval;
+    me_eval = BKE_object_get_evaluated_mesh(ob_eval);
     if (me_eval == NULL) {
       Scene *scene_eval = (Scene *)DEG_get_evaluated_id(depsgraph, &scene->id);
       me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
index 92e76ab31fa0342818421ee60f5c48910c58290c..49b6acc9003b600db391e5b02d0a13c5f7617437 100644 (file)
@@ -488,7 +488,8 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
 
 static bool PE_create_shape_tree(PEData *data, Object *shapeob)
 {
-  Mesh *mesh = BKE_object_get_evaluated_mesh(data->depsgraph, shapeob);
+  Object *shapeob_eval = DEG_get_evaluated_object(data->depsgraph, shapeob);
+  Mesh *mesh = BKE_object_get_evaluated_mesh(shapeob_eval);
 
   memset(&data->shape_bvh, 0, sizeof(data->shape_bvh));
 
index 7372ea6d44a36aacacbc8b1edce63871d1d37ec9..6971182e5b874a28860813aeafb48dfeb36c6cb6 100644 (file)
@@ -181,7 +181,7 @@ static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev,
  * (without evaluating modifiers) */
 static bool vertex_paint_use_fast_update_check(Object *ob)
 {
-  Mesh *me_eval = ob->runtime.mesh_eval;
+  Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
 
   if (me_eval != NULL) {
     Mesh *me = BKE_mesh_from_object(ob);
index 225ca72a7d0649226faee532e31b96a782faf2fb..d00083d343b2648beef673a265f7391c764715af 100644 (file)
@@ -137,7 +137,7 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
   switch (ob->type) {
     case OB_MESH: {
       /* we assume evaluated mesh is already built, this strictly does stats now. */
-      Mesh *me_eval = ob->runtime.mesh_eval;
+      Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
       if (!BLI_gset_add(objects_gset, me_eval)) {
         break;
       }
@@ -153,8 +153,7 @@ static void stats_object(Object *ob, SceneStats *stats, GSet *objects_gset)
     case OB_SURF:
     case OB_CURVE:
     case OB_FONT: {
-      Mesh *me_eval = ob->runtime.mesh_eval;
-
+      Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
       if ((me_eval != NULL) && !BLI_gset_add(objects_gset, me_eval)) {
         break;
       }
index 0daa5aa53ae9669269e3123741c18ed3345b7970..00f61a4d0aaa50218b1cf971c869816de966e5a8 100644 (file)
@@ -28,9 +28,9 @@
 #include "BLI_math.h"
 
 #include "BKE_DerivedMesh.h"
-#include "BKE_global.h"
-
 #include "BKE_editmesh.h"
+#include "BKE_global.h"
+#include "BKE_object.h"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
@@ -120,8 +120,9 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
   Mesh *me = ob->data;
   {
     Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
-    if (ob_eval->runtime.mesh_eval) {
-      me = ob_eval->runtime.mesh_eval;
+    Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
+    if (me_eval != NULL) {
+      me = me_eval;
     }
   }
 
index 2ad3de1528f1c524cd7133fdc49c9331ffd3aea3..ecd267d6f2a4c9c773a92c2ae20f3ec50d4a1627 100644 (file)
@@ -936,12 +936,13 @@ static bool raycastObj(SnapObjectContext *sctx,
     case OB_CURVE:
     case OB_SURF:
     case OB_FONT: {
-      if (ob->runtime.mesh_eval) {
+      Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+      if (mesh_eval) {
         retval = raycastMesh(sctx,
                              ray_start,
                              ray_dir,
                              ob,
-                             ob->runtime.mesh_eval,
+                             mesh_eval,
                              obmat,
                              ob_index,
                              false,
@@ -2654,11 +2655,12 @@ static short snapObject(SnapObjectContext *sctx,
       break; /* Use ATTR_FALLTHROUGH if we want to snap to the generated mesh. */
     case OB_SURF:
     case OB_FONT: {
-      if (ob->runtime.mesh_eval) {
+      Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+      if (mesh_eval) {
         retval |= snapMesh(sctx,
                            snapdata,
                            ob,
-                           ob->runtime.mesh_eval,
+                           mesh_eval,
                            obmat,
                            use_backface_culling,
                            dist_px,
index b142939eaebea51204a90b39eeddf44667cb7fbc..bfa7400f9263973907b66f055d5225297e00e91b 100644 (file)
@@ -124,7 +124,7 @@ struct CustomData_MeshMasks;
 typedef struct Object_Runtime {
   /**
    * The custom data layer mask that was last used
-   * to calculate mesh_eval and mesh_deform_eval.
+   * to calculate data_eval and mesh_deform_eval.
    */
   CustomData_MeshMasks last_data_mask;
 
@@ -141,25 +141,25 @@ typedef struct Object_Runtime {
   char _pad1[3];
 
   /**
-   * Denotes whether the evaluated mesh is owned by this object or is referenced and owned by
+   * Denotes whether the evaluated data is owned by this object or is referenced and owned by
    * somebody else.
    */
-  char is_mesh_eval_owned;
+  char is_data_eval_owned;
 
   /** Axis aligned boundbox (in localspace). */
   struct BoundBox *bb;
 
   /**
-   * Original mesh pointer, before object->data was changed to point
-   * to mesh_eval.
+   * Original data pointer, before object->data was changed to point
+   * to data_eval.
    * Is assigned by dependency graph's copy-on-write evaluation.
    */
-  struct Mesh *mesh_orig;
+  struct ID *data_orig;
   /**
-   * Mesh structure created during object evaluation.
+   * Object data structure created during object evaluation.
    * It has all modifiers applied.
    */
-  struct Mesh *mesh_eval;
+  struct ID *data_eval;
   /**
    * Mesh structure created during object evaluation.
    * It has deformation only modifiers applied on it.
index 5552de00be8499094b2422c24df4f39a963bd910..cbeb8f1799144708a9e759da2447da13f8fa2dea 100644 (file)
@@ -487,7 +487,7 @@ static Object *eval_object_ensure(Object *ob,
                                   ReportList *reports,
                                   PointerRNA *rnaptr_depsgraph)
 {
-  if (ob->runtime.mesh_eval == NULL) {
+  if (ob->runtime.data_eval == NULL) {
     Object *ob_orig = ob;
     Depsgraph *depsgraph = rnaptr_depsgraph != NULL ? rnaptr_depsgraph->data : NULL;
     if (depsgraph == NULL) {
@@ -496,7 +496,7 @@ static Object *eval_object_ensure(Object *ob,
     if (depsgraph != NULL) {
       ob = DEG_get_evaluated_object(depsgraph, ob);
     }
-    if (ob == NULL || ob->runtime.mesh_eval == NULL) {
+    if (ob == NULL || BKE_object_get_evaluated_mesh(ob) == NULL) {
       BKE_reportf(
           reports, RPT_ERROR, "Object '%s' has no evaluated mesh data", ob_orig->id.name + 2);
       return NULL;
@@ -521,8 +521,7 @@ static void rna_Object_ray_cast(Object *ob,
 
   /* TODO(sergey): This isn't very reliable check. It is possible to have non-NULL pointer
    * but which is out of date, and possibly dangling one. */
-  if (ob->runtime.mesh_eval == NULL &&
-      (ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
+  if ((ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
     return;
   }
 
@@ -538,7 +537,8 @@ static void rna_Object_ray_cast(Object *ob,
 
     /* No need to managing allocation or freeing of the BVH data.
      * This is generated and freed as needed. */
-    BKE_bvhtree_from_mesh_get(&treeData, ob->runtime.mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
+    Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+    BKE_bvhtree_from_mesh_get(&treeData, mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
 
     /* may fail if the mesh has no faces, in that case the ray-cast misses */
     if (treeData.tree != NULL) {
@@ -559,8 +559,7 @@ static void rna_Object_ray_cast(Object *ob,
 
           copy_v3_v3(r_location, hit.co);
           copy_v3_v3(r_normal, hit.no);
-          *r_index = mesh_looptri_to_poly_index(ob->runtime.mesh_eval,
-                                                &treeData.looptri[hit.index]);
+          *r_index = mesh_looptri_to_poly_index(mesh_eval, &treeData.looptri[hit.index]);
         }
       }
 
@@ -589,14 +588,14 @@ static void rna_Object_closest_point_on_mesh(Object *ob,
 {
   BVHTreeFromMesh treeData = {NULL};
 
-  if (ob->runtime.mesh_eval == NULL &&
-      (ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
+  if ((ob = eval_object_ensure(ob, C, reports, rnaptr_depsgraph)) == NULL) {
     return;
   }
 
   /* No need to managing allocation or freeing of the BVH data.
    * this is generated and freed as needed. */
-  BKE_bvhtree_from_mesh_get(&treeData, ob->runtime.mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
+  Mesh *mesh_eval = BKE_object_get_evaluated_mesh(ob);
+  BKE_bvhtree_from_mesh_get(&treeData, mesh_eval, BVHTREE_FROM_LOOPTRI, 4);
 
   if (treeData.tree == NULL) {
     BKE_reportf(reports,
@@ -617,8 +616,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob,
 
       copy_v3_v3(r_location, nearest.co);
       copy_v3_v3(r_normal, nearest.no);
-      *r_index = mesh_looptri_to_poly_index(ob->runtime.mesh_eval,
-                                            &treeData.looptri[nearest.index]);
+      *r_index = mesh_looptri_to_poly_index(mesh_eval, &treeData.looptri[nearest.index]);
 
       goto finally;
     }
@@ -659,8 +657,7 @@ void rna_Object_me_eval_info(
   switch (type) {
     case 1:
     case 2:
-      if (ob->runtime.mesh_eval == NULL &&
-          (ob = eval_object_ensure(ob, C, NULL, rnaptr_depsgraph)) == NULL) {
+      if ((ob = eval_object_ensure(ob, C, NULL, rnaptr_depsgraph)) == NULL) {
         return;
       }
   }
@@ -675,7 +672,7 @@ void rna_Object_me_eval_info(
       me_eval = ob->runtime.mesh_deform_eval;
       break;
     case 2:
-      me_eval = ob->runtime.mesh_eval;
+      me_eval = BKE_object_get_evaluated_mesh(ob);
       break;
   }
 
index bc3bc06f8a667ca5447faf6e655293edfdb7e4fd..74005afaf31607d3444b9e2ca6eb23bff59b8b9f 100644 (file)
@@ -483,7 +483,7 @@ USDMeshWriter::USDMeshWriter(const USDExporterContext &ctx) : USDGenericMeshWrit
 
 Mesh *USDMeshWriter::get_export_mesh(Object *object_eval, bool & /*r_needsfree*/)
 {
-  return object_eval->runtime.mesh_eval;
+  return BKE_object_get_evaluated_mesh(object_eval);
 }
 
 }  // namespace USD