From 318112379d6d251334b8f3d2a20b935210446b4f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 27 Feb 2020 11:23:15 +0100 Subject: 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. This previously caused a bug in T74283, that should be fixed now. Differential Revision: https://developer.blender.org/D6695 --- source/blender/alembic/intern/abc_writer_curves.cc | 6 +- source/blender/alembic/intern/abc_writer_mball.cc | 6 +- source/blender/blenkernel/BKE_object.h | 4 +- source/blender/blenkernel/intern/DerivedMesh.c | 73 ++++++--------- source/blender/blenkernel/intern/constraint.c | 6 +- source/blender/blenkernel/intern/crazyspace.c | 4 +- source/blender/blenkernel/intern/displist.c | 16 ++-- source/blender/blenkernel/intern/effect.c | 6 +- source/blender/blenkernel/intern/mesh_convert.c | 32 +++---- source/blender/blenkernel/intern/modifier.c | 2 +- source/blender/blenkernel/intern/object.c | 101 +++++++++++++-------- source/blender/blenkernel/intern/object_dupli.c | 4 +- source/blender/blenkernel/intern/object_update.c | 4 +- source/blender/blenkernel/intern/paint.c | 2 +- source/blender/blenkernel/intern/rigidbody.c | 8 +- .../intern/eval/deg_eval_copy_on_write.cc | 4 +- .../intern/eval/deg_eval_runtime_backup_object.cc | 24 ++--- source/blender/draw/intern/draw_cache.c | 48 +++++----- source/blender/editors/mesh/editface.c | 7 +- .../blender/editors/mesh/editmesh_knife_project.c | 5 +- source/blender/editors/physics/particle_edit.c | 3 +- source/blender/editors/sculpt_paint/paint_vertex.c | 2 +- source/blender/editors/space_info/info_stats.c | 5 +- source/blender/editors/space_view3d/drawobject.c | 9 +- .../editors/transform/transform_snap_object.c | 10 +- source/blender/makesdna/DNA_object_types.h | 16 ++-- source/blender/makesrna/intern/rna_object_api.c | 27 +++--- source/blender/usd/intern/usd_writer_mesh.cc | 2 +- 28 files changed, 220 insertions(+), 216 deletions(-) diff --git a/source/blender/alembic/intern/abc_writer_curves.cc b/source/blender/alembic/intern/abc_writer_curves.cc index bb9109dc025..3ab9b365a72 100644 --- a/source/blender/alembic/intern/abc_writer_curves.cc +++ b/source/blender/alembic/intern/abc_writer_curves.cc @@ -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; diff --git a/source/blender/alembic/intern/abc_writer_mball.cc b/source/blender/alembic/intern/abc_writer_mball.cc index aa08146c6e2..cc0775bd537 100644 --- a/source/blender/alembic/intern/abc_writer_mball.cc +++ b/source/blender/alembic/intern/abc_writer_mball.cc @@ -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; 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 */ 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 edb02ee331f..95521ee9e47 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 @@ -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; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc index df7338e1076..855dd4821ce 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc @@ -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 = 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; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 8057d167e2f..f37e5b14d83 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -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: diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 5c9fb866df7..5f948595a22 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -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; diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index 8d5c1469694..21de89d33dd 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -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); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 92e76ab31fa..49b6acc9003 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -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)); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 7372ea6d44a..6971182e5b8 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -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); diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index 225ca72a7d0..d00083d343b 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -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; } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 0daa5aa53ae..00f61a4d0aa 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -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; } } diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c index 2ad3de1528f..ecd267d6f2a 100644 --- a/source/blender/editors/transform/transform_snap_object.c +++ b/source/blender/editors/transform/transform_snap_object.c @@ -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, diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index b142939eaeb..bfa7400f926 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -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. diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 5552de00be8..cbeb8f17991 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -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; } diff --git a/source/blender/usd/intern/usd_writer_mesh.cc b/source/blender/usd/intern/usd_writer_mesh.cc index bc3bc06f8a6..74005afaf31 100644 --- a/source/blender/usd/intern/usd_writer_mesh.cc +++ b/source/blender/usd/intern/usd_writer_mesh.cc @@ -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 -- cgit v1.2.3