From d95b1f120b8c8d99060448290756ed4daeecfbac Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 18 Apr 2024 13:52:20 +0200 Subject: [PATCH] Mesh: Store BMEditMesh in shared pointer The main motivation for this is that it's part of a fix for #113377, where I want to propagate the edit mesh pointers through copied meshes in modifiers and geometry nodes, instead of just setting the edit mesh pointer at the end of the modifier stack. That would have two main benefits: 1. We avoid the need to write to the evaluated mesh, after evaluation which means it can be shared directly among evaluated objects. 2. When an object's mesh is completely replaced by the mesh from another object during evaluation (with the object info node), the final edit mesh pointer will not be "wrong", allowing us to skip index-mapped GPU data extraction. Beyond that, using a shared pointer just makes things more automatic. Handling of edit mesh data is already complicated enough, this way some of the worry and complexity can be handled by RAII. One thing to keep in mind is that the edit mesh's BMesh is still freed manually with `EDBM_mesh_free_data` when leaving edit mode. I figured that was a more conservative approach for now. Maybe eventually that could be handled automatically with RAII too. Pull Request: https://projects.blender.org/blender/blender/pulls/120276 --- source/blender/blenkernel/BKE_editmesh.hh | 5 ---- source/blender/blenkernel/BKE_mesh.h | 2 -- source/blender/blenkernel/BKE_mesh_types.hh | 11 +++++--- source/blender/blenkernel/BKE_mesh_wrapper.hh | 4 ++- .../blender/blenkernel/intern/DerivedMesh.cc | 26 +++++++++---------- source/blender/blenkernel/intern/attribute.cc | 10 +++---- .../blender/blenkernel/intern/crazyspace.cc | 3 ++- source/blender/blenkernel/intern/editmesh.cc | 2 +- source/blender/blenkernel/intern/key.cc | 2 +- .../blender/blenkernel/intern/layer_utils.cc | 4 +-- source/blender/blenkernel/intern/mesh.cc | 23 ++-------------- .../blenkernel/intern/mesh_iterators.cc | 8 +++--- .../blender/blenkernel/intern/mesh_runtime.cc | 1 - .../blender/blenkernel/intern/mesh_wrapper.cc | 7 +++-- source/blender/blenkernel/intern/multires.cc | 4 +-- source/blender/blenkernel/intern/object.cc | 11 ++++---- .../blenkernel/intern/object_deform.cc | 5 ++-- .../draw/engines/overlay/overlay_edit_mesh.cc | 2 +- .../draw/engines/overlay/overlay_wireframe.cc | 2 +- .../draw/engines/select/select_draw_utils.cc | 2 +- .../draw_cache_extract_mesh_render_data.cc | 2 +- .../blender/draw/intern/draw_manager_text.cc | 2 +- .../editors/geometry/node_group_operator.cc | 4 +-- .../mesh/editmesh_set_sharpness_by_angle.cc | 2 +- source/blender/editors/mesh/editmesh_tools.cc | 6 ++--- source/blender/editors/mesh/editmesh_undo.cc | 11 +++----- source/blender/editors/mesh/editmesh_utils.cc | 11 ++++---- source/blender/editors/mesh/mesh_data.cc | 18 ++++--------- source/blender/editors/mesh/mesh_mirror.cc | 2 +- source/blender/editors/mesh/meshtools.cc | 4 +-- .../blender/editors/object/object_bake_api.cc | 4 +-- source/blender/editors/object/object_edit.cc | 5 ++-- source/blender/editors/object/object_hook.cc | 4 +-- .../blender/editors/object/object_modifier.cc | 4 +-- .../editors/object/object_relations.cc | 2 +- .../editors/object/object_transform.cc | 2 +- .../blender/editors/object/object_vgroup.cc | 25 +++++++----------- .../editors/sculpt_paint/paint_vertex.cc | 2 +- .../spreadsheet_data_source_geometry.cc | 2 +- .../editors/space_view3d/view3d_buttons.cc | 7 +++-- source/blender/editors/uvedit/uvedit_ops.cc | 4 +-- source/blender/editors/uvedit/uvedit_rip.cc | 2 +- .../blender/geometry/intern/mesh_boolean.cc | 3 ++- source/blender/makesrna/intern/rna_object.cc | 4 +-- source/blender/makesrna/intern/rna_scene.cc | 2 +- .../node_geo_deform_curves_on_surface.cc | 2 +- 46 files changed, 114 insertions(+), 156 deletions(-) diff --git a/source/blender/blenkernel/BKE_editmesh.hh b/source/blender/blenkernel/BKE_editmesh.hh index b476286af63..1ad7e17f455 100644 --- a/source/blender/blenkernel/BKE_editmesh.hh +++ b/source/blender/blenkernel/BKE_editmesh.hh @@ -58,11 +58,6 @@ struct BMEditMesh { /** Temp variables for x-mirror editing (-1 when the layer does not exist). */ int mirror_cdlayer; - /** - * Enable for evaluated copies, causes the edit-mesh to free the memory, not its contents. - */ - char is_shallow_copy; - /** * ID data is older than edit-mode data. * Set #Main.is_memfile_undo_flush_needed when enabling. diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index f2e66c87dc4..2021b13f54e 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -123,8 +123,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src, int corners_num, CustomData_MeshMasks mask); -void BKE_mesh_eval_delete(Mesh *mesh_eval); - /** * Performs copy for use during evaluation, * optional referencing original arrays to reduce memory. diff --git a/source/blender/blenkernel/BKE_mesh_types.hh b/source/blender/blenkernel/BKE_mesh_types.hh index 4914953fcee..d0efa7cee1d 100644 --- a/source/blender/blenkernel/BKE_mesh_types.hh +++ b/source/blender/blenkernel/BKE_mesh_types.hh @@ -111,11 +111,16 @@ struct MeshRuntime { const ImplicitSharingInfo *face_offsets_sharing_info = nullptr; /** - * Storage of the edit mode mesh. If it exists, it generally has the most up-to-date - * information about the mesh. + * Storage of the edit mode BMesh with some extra data for quick access in edit mode. + * - For original (non-evaluated) meshes, when it exists, it generally has the most up-to-date + * information about the mesh. That's because this is only allocated in edit mode. + * - For evaluated meshes, this just references the BMesh from an original object in edit mode. + * Conceptually this is a weak pointer for evaluated meshes. In other words, it doesn't have + * ownership over the BMesh, and using `shared_ptr` is just a convenient way to avoid copying + * the whole struct and making sure the reference is valid. * \note When the object is available, the preferred access method is #BKE_editmesh_from_object. */ - BMEditMesh *edit_mesh = nullptr; + std::shared_ptr edit_mesh; /** * A cache of bounds shared between data-blocks with unchanged positions. When changing positions diff --git a/source/blender/blenkernel/BKE_mesh_wrapper.hh b/source/blender/blenkernel/BKE_mesh_wrapper.hh index f06ebe18d93..eefa751bf25 100644 --- a/source/blender/blenkernel/BKE_mesh_wrapper.hh +++ b/source/blender/blenkernel/BKE_mesh_wrapper.hh @@ -7,6 +7,8 @@ * \ingroup bke */ +#include + #include "BLI_math_vector_types.hh" #include "BLI_span.hh" @@ -14,7 +16,7 @@ struct BMEditMesh; struct CustomData_MeshMasks; struct Mesh; -Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em, +Mesh *BKE_mesh_wrapper_from_editmesh(std::shared_ptr em, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings); void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh); diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 446ce25aad2..64ac98a7ac0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1009,7 +1009,6 @@ static MutableSpan mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh) static void editbmesh_calc_modifiers(Depsgraph *depsgraph, const Scene *scene, Object *ob, - BMEditMesh *em_input, const CustomData_MeshMasks *dataMask, /* return args */ Mesh **r_cage, @@ -1017,6 +1016,8 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph, GeometrySet **r_geometry_set) { Mesh *mesh_input = (Mesh *)ob->data; + BMEditMesh *em_input = mesh_input->runtime->edit_mesh.get(); + Mesh *mesh_cage = nullptr; /* This geometry set contains the non-mesh data that might be generated by modifiers. */ GeometrySet geometry_set_final; @@ -1049,7 +1050,8 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph, CDMaskLink *md_datamask = datamasks; CustomData_MeshMasks append_mask = CD_MASK_BAREMESH; - Mesh *mesh_final = BKE_mesh_wrapper_from_editmesh(em_input, &final_datamask, mesh_input); + Mesh *mesh_final = BKE_mesh_wrapper_from_editmesh( + mesh_input->runtime->edit_mesh, &final_datamask, mesh_input); int cageIndex = BKE_modifiers_get_cage_index(scene, ob, nullptr, true); if (r_cage && cageIndex == -1) { @@ -1094,9 +1096,7 @@ static void editbmesh_calc_modifiers(Depsgraph *depsgraph, * cage mesh isn't modified anymore. */ mesh_final = BKE_mesh_copy_for_eval(mesh_final); if (mesh_cage->runtime->edit_mesh) { - mesh_final->runtime->edit_mesh = static_cast( - MEM_dupallocN(mesh_cage->runtime->edit_mesh)); - mesh_final->runtime->edit_mesh->is_shallow_copy = true; + mesh_final->runtime->edit_mesh = mesh_cage->runtime->edit_mesh; mesh_final->runtime->is_original_bmesh = true; if (mesh_cage->runtime->edit_data) { mesh_final->runtime->edit_data = std::make_unique( @@ -1288,7 +1288,6 @@ static void mesh_build_data(Depsgraph *depsgraph, static void editbmesh_build_data(Depsgraph *depsgraph, const Scene *scene, Object *obedit, - BMEditMesh *em, CustomData_MeshMasks *dataMask) { Mesh *mesh = static_cast(obedit->data); @@ -1297,13 +1296,13 @@ static void editbmesh_build_data(Depsgraph *depsgraph, GeometrySet *non_mesh_components; editbmesh_calc_modifiers( - depsgraph, scene, obedit, em, dataMask, &me_cage, &me_final, &non_mesh_components); + depsgraph, scene, obedit, dataMask, &me_cage, &me_final, &non_mesh_components); /* The modifier stack result is expected to share edit mesh pointer with the input. * This is similar `mesh_calc_finalize()`. */ BKE_mesh_free_editmesh(me_final); BKE_mesh_free_editmesh(me_cage); - me_final->runtime->edit_mesh = me_cage->runtime->edit_mesh = em; + me_final->runtime->edit_mesh = me_cage->runtime->edit_mesh = mesh->runtime->edit_mesh; /* Object has edit_mesh but is not in edit mode (object shares mesh datablock with another object * with is in edit mode). @@ -1407,14 +1406,13 @@ void makeDerivedMesh(Depsgraph *depsgraph, * `edit_mesh` pointer with the input. For example, if the object is first evaluated in the * object mode, and then user in another scene moves object to edit mode. */ Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; bool need_mapping; CustomData_MeshMasks cddata_masks = *dataMask; object_get_datamask(depsgraph, ob, &cddata_masks, &need_mapping); - if (em) { - editbmesh_build_data(depsgraph, scene, ob, em, &cddata_masks); + if (mesh->runtime->edit_mesh) { + editbmesh_build_data(depsgraph, scene, ob, &cddata_masks); } else { mesh_build_data(depsgraph, scene, ob, &cddata_masks, need_mapping); @@ -1428,7 +1426,7 @@ Mesh *mesh_get_eval_deform(Depsgraph *depsgraph, Object *ob, const CustomData_MeshMasks *dataMask) { - BMEditMesh *em = ((Mesh *)ob->data)->runtime->edit_mesh; + BMEditMesh *em = ((Mesh *)ob->data)->runtime->edit_mesh.get(); if (em != nullptr) { /* There is no such a concept as deformed mesh in edit mode. * Explicitly disallow this request so that the evaluated result is not modified with evaluated @@ -1502,7 +1500,7 @@ Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph, Mesh *editbmesh_get_eval_cage(Depsgraph *depsgraph, const Scene *scene, Object *obedit, - BMEditMesh *em, + BMEditMesh * /*em*/, const CustomData_MeshMasks *dataMask) { CustomData_MeshMasks cddata_masks = *dataMask; @@ -1515,7 +1513,7 @@ Mesh *editbmesh_get_eval_cage(Depsgraph *depsgraph, if (!obedit->runtime->editmesh_eval_cage || !CustomData_MeshMasks_are_matching(&(obedit->runtime->last_data_mask), &cddata_masks)) { - editbmesh_build_data(depsgraph, scene, obedit, em, &cddata_masks); + editbmesh_build_data(depsgraph, scene, obedit, &cddata_masks); } return obedit->runtime->editmesh_eval_cage; diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index b42eae462a9..f7987c209b3 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -58,8 +58,7 @@ static void get_domains(const ID *id, DomainInfo info[ATTR_DOMAIN_NUM]) } case ID_ME: { Mesh *mesh = (Mesh *)id; - BMEditMesh *em = mesh->runtime->edit_mesh; - if (em != nullptr) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMesh *bm = em->bm; info[int(AttrDomain::Point)].customdata = &bm->vdata; info[int(AttrDomain::Point)].length = bm->totvert; @@ -326,7 +325,7 @@ CustomDataLayer *BKE_id_attribute_new(ID *id, if (GS(id->name) == ID_ME) { Mesh *mesh = reinterpret_cast(id); - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { if (!mesh_edit_mode_attribute_valid(name, domain, type, reports)) { return nullptr; } @@ -376,9 +375,8 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList if (GS(id->name) == ID_ME) { Mesh *mesh = reinterpret_cast(id); - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (mesh->runtime->edit_mesh) { BLI_assert_unreachable(); - UNUSED_VARS(em); return nullptr; } } @@ -457,7 +455,7 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports) if (GS(id->name) == ID_ME) { Mesh *mesh = reinterpret_cast(id); - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) { if (CustomData *data = info[domain].customdata) { const std::string name_copy = name; diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index e547ececd7c..070ba5090a8 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -273,7 +273,8 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh( cd_mask_extra = datamasks->mask; BLI_linklist_free((LinkNode *)datamasks, nullptr); - mesh = BKE_mesh_wrapper_from_editmesh(em, &cd_mask_extra, me_input); + mesh = BKE_mesh_wrapper_from_editmesh( + std::make_shared(*em), &cd_mask_extra, me_input); deformcos.reinitialize(verts_num); BKE_mesh_wrapper_vert_coords_copy(mesh, deformcos); deformmats.reinitialize(verts_num); diff --git a/source/blender/blenkernel/intern/editmesh.cc b/source/blender/blenkernel/intern/editmesh.cc index eb854c2e565..c2ce09e1db2 100644 --- a/source/blender/blenkernel/intern/editmesh.cc +++ b/source/blender/blenkernel/intern/editmesh.cc @@ -63,7 +63,7 @@ BMEditMesh *BKE_editmesh_copy(BMEditMesh *em) BMEditMesh *BKE_editmesh_from_object(Object *ob) { BLI_assert(ob->type == OB_MESH); - return ((Mesh *)ob->data)->runtime->edit_mesh; + return ((Mesh *)ob->data)->runtime->edit_mesh.get(); } void BKE_editmesh_looptris_calc_ex(BMEditMesh *em, const BMeshCalcTessellation_Params *params) diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 9af15de823e..9c9087290e5 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1285,7 +1285,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac totvert = mesh->verts_num; if (mesh->runtime->edit_mesh && mesh->runtime->edit_mesh->bm->totvert == totvert) { - em = mesh->runtime->edit_mesh; + em = mesh->runtime->edit_mesh.get(); } } else if (ob->type == OB_LATTICE) { diff --git a/source/blender/blenkernel/intern/layer_utils.cc b/source/blender/blenkernel/intern/layer_utils.cc index 204ec9db61a..e0cf87590b1 100644 --- a/source/blender/blenkernel/intern/layer_utils.cc +++ b/source/blender/blenkernel/intern/layer_utils.cc @@ -219,7 +219,7 @@ bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void * /*user_dat { if (ob->type == OB_MESH) { const Mesh *mesh = static_cast(ob->data); - if (const BMEditMesh *em = mesh->runtime->edit_mesh) { + if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) { if (CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) { return true; } @@ -232,7 +232,7 @@ bool BKE_view_layer_filter_edit_mesh_has_edges(const Object *ob, void * /*user_d { if (ob->type == OB_MESH) { const Mesh *mesh = static_cast(ob->data); - if (const BMEditMesh *em = mesh->runtime->edit_mesh) { + if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) { if (em->bm->totedge != 0) { return true; } diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 048b3a9837c..ed3e550999f 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -204,15 +204,7 @@ static void mesh_copy_data(Main *bmain, void BKE_mesh_free_editmesh(Mesh *mesh) { - if (mesh->runtime->edit_mesh == nullptr) { - return; - } - - if (mesh->runtime->edit_mesh->is_shallow_copy == false) { - BKE_editmesh_free_data(mesh->runtime->edit_mesh); - } - MEM_freeN(mesh->runtime->edit_mesh); - mesh->runtime->edit_mesh = nullptr; + mesh->runtime->edit_mesh.reset(); } static void mesh_free_data(ID *id) @@ -848,15 +840,6 @@ Mesh *BKE_mesh_new_nomain_from_template(const Mesh *me_src, me_src, verts_num, edges_num, 0, faces_num, corners_num, CD_MASK_EVERYTHING); } -void BKE_mesh_eval_delete(Mesh *mesh_eval) -{ - /* Evaluated mesh may point to edit mesh, but never owns it. */ - mesh_eval->runtime->edit_mesh = nullptr; - mesh_free_data(&mesh_eval->id); - BKE_libblock_free_data(&mesh_eval->id, false); - MEM_freeN(mesh_eval); -} - Mesh *BKE_mesh_copy_for_eval(const Mesh *source) { return reinterpret_cast( @@ -1155,8 +1138,7 @@ void BKE_mesh_material_remap(Mesh *mesh, const uint *remap, uint remap_len) } \ ((void)0) - if (mesh->runtime->edit_mesh) { - BMEditMesh *em = mesh->runtime->edit_mesh; + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMIter iter; BMFace *efa; @@ -1462,7 +1444,6 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh) * evaluated mesh, and we don't know what parts of the mesh did change. So we simply delete the * evaluated mesh and let objects to re-create it with updated settings. */ if (mesh->runtime->mesh_eval != nullptr) { - mesh->runtime->mesh_eval->runtime->edit_mesh = nullptr; BKE_id_free(nullptr, mesh->runtime->mesh_eval); mesh->runtime->mesh_eval = nullptr; } diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index f824e40dac1..8efd3fb35ee 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -36,7 +36,7 @@ void BKE_mesh_foreach_mapped_vert( MeshForeachFlag flag) { if (mesh->runtime->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) { - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMIter iter; BMVert *eve; @@ -94,7 +94,7 @@ void BKE_mesh_foreach_mapped_edge( void *user_data) { if (mesh->runtime->edit_mesh != nullptr && mesh->runtime->edit_data) { - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMIter iter; BMEdge *eed; @@ -153,7 +153,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, * we want to always access `dm->loopData`, `EditDerivedBMesh` would * return loop data from BMesh itself. */ if (mesh->runtime->edit_mesh != nullptr && mesh->runtime->edit_data) { - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMIter iter; BMFace *efa; @@ -233,7 +233,7 @@ void BKE_mesh_foreach_mapped_face_center( { using namespace blender; if (mesh->runtime->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) { - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMFace *efa; BMIter iter; diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 45ff6ffb824..c66a3cf1625 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -36,7 +36,6 @@ namespace blender::bke { static void free_mesh_eval(MeshRuntime &mesh_runtime) { if (mesh_runtime.mesh_eval != nullptr) { - mesh_runtime.mesh_eval->runtime->edit_mesh = nullptr; BKE_id_free(nullptr, mesh_runtime.mesh_eval); mesh_runtime.mesh_eval = nullptr; } diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 8ccd2d2051f..344e0d8b5f1 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -52,7 +52,7 @@ using blender::float3; using blender::Span; -Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em, +Mesh *BKE_mesh_wrapper_from_editmesh(std::shared_ptr em, const CustomData_MeshMasks *cd_mask_extra, const Mesh *me_settings) { @@ -68,8 +68,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em, /* Use edit-mesh directly where possible. */ mesh->runtime->is_original_bmesh = true; - mesh->runtime->edit_mesh = static_cast(MEM_dupallocN(em)); - mesh->runtime->edit_mesh->is_shallow_copy = true; + mesh->runtime->edit_mesh = std::move(em); /* Make sure we crash if these are ever used. */ #ifndef NDEBUG @@ -110,7 +109,7 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh) BLI_assert(mesh->runtime->edit_mesh != nullptr); BLI_assert(mesh->runtime->edit_data != nullptr); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BM_mesh_bm_to_me_for_eval(*em->bm, *mesh, &mesh->runtime->cd_mask_extra); /* Adding original index layers here assumes that all BMesh Mesh wrappers are created from diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index a4344438af3..59e12b57f5d 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -63,7 +63,7 @@ static void multiresModifier_disp_run( void multires_customdata_delete(Mesh *mesh) { - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { /* CustomData_external_remove is used here only to mark layer * as non-external for further freeing, so zero element count * looks safer than `em->bm->totface`. */ @@ -512,7 +512,7 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o Mesh *mesh = static_cast(ob->data); const MDisps *mdisp; - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { mdisp = static_cast(CustomData_get_layer(&em->bm->ldata, CD_MDISPS)); } else { diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 38ad1c07f6b..842952b1bd7 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1639,7 +1639,7 @@ void BKE_object_free_derived_caches(Object *ob) if (ob->runtime->editmesh_eval_cage && ob->runtime->editmesh_eval_cage != reinterpret_cast(ob->runtime->data_eval)) { - BKE_mesh_eval_delete(ob->runtime->editmesh_eval_cage); + BKE_id_free(nullptr, ob->runtime->editmesh_eval_cage); } ob->runtime->editmesh_eval_cage = nullptr; @@ -1647,7 +1647,7 @@ void BKE_object_free_derived_caches(Object *ob) 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); + BKE_id_free(nullptr, (Mesh *)data_eval); } else { BKE_libblock_free_data(data_eval, false); @@ -1659,7 +1659,7 @@ void BKE_object_free_derived_caches(Object *ob) } if (ob->runtime->mesh_deform_eval != nullptr) { Mesh *mesh_deform_eval = ob->runtime->mesh_deform_eval; - BKE_mesh_eval_delete(mesh_deform_eval); + BKE_id_free(nullptr, mesh_deform_eval); ob->runtime->mesh_deform_eval = nullptr; } @@ -1806,8 +1806,7 @@ char *BKE_object_data_editmode_flush_ptr_get(ID *id) const short type = GS(id->name); switch (type) { case ID_ME: { - BMEditMesh *em = ((Mesh *)id)->runtime->edit_mesh; - if (em != nullptr) { + if (BMEditMesh *em = ((Mesh *)id)->runtime->edit_mesh.get()) { return &em->needs_flush_to_id; } break; @@ -3087,7 +3086,7 @@ static void give_parvert(const Object *par, int nr, float vec[3]) if (par->type == OB_MESH) { const Mesh *mesh = (const Mesh *)par->data; - const BMEditMesh *em = mesh->runtime->edit_mesh; + const BMEditMesh *em = mesh->runtime->edit_mesh.get(); const Mesh *mesh_eval = (em) ? BKE_object_get_editmesh_eval_final(par) : BKE_object_get_evaluated_mesh(par); diff --git a/source/blender/blenkernel/intern/object_deform.cc b/source/blender/blenkernel/intern/object_deform.cc index 2c813efaf87..7667989844e 100644 --- a/source/blender/blenkernel/intern/object_deform.cc +++ b/source/blender/blenkernel/intern/object_deform.cc @@ -149,8 +149,7 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele if (ob->type == OB_MESH) { Mesh *mesh = static_cast(ob->data); - if (mesh->runtime->edit_mesh) { - BMEditMesh *em = mesh->runtime->edit_mesh; + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); if (cd_dvert_offset != -1) { @@ -345,7 +344,7 @@ static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg) /* Else, make sure that any groups with higher indices are adjusted accordingly */ else if (ob->type == OB_MESH) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); BMIter iter; diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.cc b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc index a0c8c4d33f0..e18646b1749 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_mesh.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc @@ -236,7 +236,7 @@ static void overlay_edit_mesh_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob bool has_skin_roots = false; /* TODO: Should be its own function. */ Mesh *mesh = (Mesh *)ob->data; - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob); const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob); diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.cc b/source/blender/draw/engines/overlay/overlay_wireframe.cc index 1ca76962825..fc86ce9e95a 100644 --- a/source/blender/draw/engines/overlay/overlay_wireframe.cc +++ b/source/blender/draw/engines/overlay/overlay_wireframe.cc @@ -178,7 +178,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata, /* TODO: Should be its own function. */ const Mesh *mesh = static_cast(ob->data); if (is_edit_mode) { - BLI_assert(mesh->runtime->edit_mesh); + BLI_assert(mesh->runtime->edit_mesh.get()); const Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob); const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob); has_edit_mesh_cage = editmesh_eval_cage && (editmesh_eval_cage != editmesh_eval_final); diff --git a/source/blender/draw/engines/select/select_draw_utils.cc b/source/blender/draw/engines/select/select_draw_utils.cc index d40b11c4a8f..46c2151f503 100644 --- a/source/blender/draw/engines/select/select_draw_utils.cc +++ b/source/blender/draw/engines/select/select_draw_utils.cc @@ -79,7 +79,7 @@ static void draw_select_id_edit_mesh(SELECTID_StorageList *stl, { using namespace blender::draw; Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE); diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 3dd99983e8a..8a5114eed70 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -597,7 +597,7 @@ MeshRenderData *mesh_render_data_create(Object *object, BLI_assert(editmesh_eval_cage && editmesh_eval_final); mr->bm = mesh->runtime->edit_mesh->bm; - mr->edit_bmesh = mesh->runtime->edit_mesh; + mr->edit_bmesh = mesh->runtime->edit_mesh.get(); mr->mesh = (do_final) ? editmesh_eval_final : editmesh_eval_cage; mr->edit_data = is_mode_active ? mr->mesh->runtime->edit_data.get() : nullptr; diff --git a/source/blender/draw/intern/draw_manager_text.cc b/source/blender/draw/intern/draw_manager_text.cc index dba57103189..42b068e5c68 100644 --- a/source/blender/draw/intern/draw_manager_text.cc +++ b/source/blender/draw/intern/draw_manager_text.cc @@ -259,7 +259,7 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, DRWTextStore *dt = DRW_text_cache_ensure(); const short txt_flag = DRW_TEXT_CACHE_GLOBALSPACE; const Mesh *mesh = BKE_object_get_editmesh_eval_cage(ob); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); float v1[3], v2[3], v3[3], vmid[3], fvec[3]; char numstr[32]; /* Stores the measurement display text here */ size_t numstr_len; diff --git a/source/blender/editors/geometry/node_group_operator.cc b/source/blender/editors/geometry/node_group_operator.cc index 08d682cd4b3..ae2cf46a9bc 100644 --- a/source/blender/editors/geometry/node_group_operator.cc +++ b/source/blender/editors/geometry/node_group_operator.cc @@ -182,7 +182,7 @@ static bke::GeometrySet get_original_geometry_eval_copy(Object &object) } case OB_MESH: { const Mesh *mesh = static_cast(object.data); - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (std::shared_ptr &em = mesh->runtime->edit_mesh) { Mesh *mesh_copy = BKE_mesh_wrapper_from_editmesh(em, nullptr, mesh); BKE_mesh_wrapper_ensure_mdata(mesh_copy); Mesh *final_copy = BKE_mesh_copy_for_eval(mesh_copy); @@ -253,7 +253,7 @@ static void store_result_geometry( BKE_object_material_from_eval_data(&bmain, &object, &new_mesh->id); if (object.mode == OB_MODE_EDIT) { EDBM_mesh_make_from_mesh(&object, new_mesh, scene.toolsettings->selectmode, true); - BKE_editmesh_looptris_and_normals_calc(mesh.runtime->edit_mesh); + BKE_editmesh_looptris_and_normals_calc(mesh.runtime->edit_mesh.get()); BKE_id_free(nullptr, new_mesh); } else { diff --git a/source/blender/editors/mesh/editmesh_set_sharpness_by_angle.cc b/source/blender/editors/mesh/editmesh_set_sharpness_by_angle.cc index 196c6727826..86f63a99000 100644 --- a/source/blender/editors/mesh/editmesh_set_sharpness_by_angle.cc +++ b/source/blender/editors/mesh/editmesh_set_sharpness_by_angle.cc @@ -39,7 +39,7 @@ static int set_sharpness_by_angle_exec(bContext *C, wmOperator *op) for (Object *object : objects) { Mesh &mesh = *static_cast(object->data); - BMEditMesh *em = mesh.runtime->edit_mesh; + BMEditMesh *em = mesh.runtime->edit_mesh.get(); bool changed = false; BMIter iter; diff --git a/source/blender/editors/mesh/editmesh_tools.cc b/source/blender/editors/mesh/editmesh_tools.cc index 4488d62387f..70a5ec3f0a5 100644 --- a/source/blender/editors/mesh/editmesh_tools.cc +++ b/source/blender/editors/mesh/editmesh_tools.cc @@ -3678,7 +3678,7 @@ static int edbm_shape_propagate_to_all_exec(bContext *C, wmOperator *op) scene, view_layer, CTX_wm_view3d(C)); for (Object *obedit : objects) { Mesh *mesh = static_cast(obedit->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); if (em->bm->totvertsel == 0) { continue; @@ -3757,7 +3757,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) Mesh *me_ref = static_cast(obedit_ref->data); Key *key_ref = me_ref->key; KeyBlock *kb_ref = nullptr; - BMEditMesh *em_ref = me_ref->runtime->edit_mesh; + BMEditMesh *em_ref = me_ref->runtime->edit_mesh.get(); BMVert *eve; BMIter iter; const Scene *scene = CTX_data_scene(C); @@ -3793,7 +3793,7 @@ static int edbm_blend_from_shape_exec(bContext *C, wmOperator *op) Mesh *mesh = static_cast(obedit->data); Key *key = mesh->key; KeyBlock *kb = nullptr; - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); int shape; if (em->bm->totvertsel == 0) { diff --git a/source/blender/editors/mesh/editmesh_undo.cc b/source/blender/editors/mesh/editmesh_undo.cc index 81af48ac897..e33f0d4abbe 100644 --- a/source/blender/editors/mesh/editmesh_undo.cc +++ b/source/blender/editors/mesh/editmesh_undo.cc @@ -843,7 +843,7 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em) ob->shapenr = um->shapenr; - MEM_freeN(em_tmp); + MEM_delete(em_tmp); #ifdef USE_ARRAY_STORE um_arraystore_expand_clear(um); @@ -947,11 +947,8 @@ static bool mesh_undosys_step_encode(bContext *C, Main *bmain, UndoStep *us_p) elem->obedit_ref.ptr = ob; Mesh *mesh = static_cast(elem->obedit_ref.ptr->data); - BMEditMesh *em = mesh->runtime->edit_mesh; - undomesh_from_editmesh(&elem->data, - mesh->runtime->edit_mesh, - mesh->key, - um_references ? um_references[i] : nullptr); + BMEditMesh *em = mesh->runtime->edit_mesh.get(); + undomesh_from_editmesh(&elem->data, em, mesh->key, um_references ? um_references[i] : nullptr); em->needs_flush_to_id = 1; us->step.data_size += elem->data.undo_size; elem->data.uv_selectmode = ts->uv_selectmode; @@ -997,7 +994,7 @@ static void mesh_undosys_step_decode( obedit->id.name); continue; } - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); undomesh_to_editmesh(&elem->data, obedit, em); em->needs_flush_to_id = 1; DEG_id_tag_update(&mesh->id, ID_RECALC_GEOMETRY); diff --git a/source/blender/editors/mesh/editmesh_utils.cc b/source/blender/editors/mesh/editmesh_utils.cc index f1f108997e8..36d76465dc3 100644 --- a/source/blender/editors/mesh/editmesh_utils.cc +++ b/source/blender/editors/mesh/editmesh_utils.cc @@ -278,19 +278,20 @@ void EDBM_mesh_make_from_mesh(Object *ob, if (mesh->runtime->edit_mesh) { /* this happens when switching shape keys */ - EDBM_mesh_free_data(mesh->runtime->edit_mesh); - MEM_freeN(mesh->runtime->edit_mesh); + EDBM_mesh_free_data(mesh->runtime->edit_mesh.get()); + mesh->runtime->edit_mesh.reset(); } /* Executing operators re-tessellates, * so we can avoid doing here but at some point it may need to be added back. */ - mesh->runtime->edit_mesh = BKE_editmesh_create(bm); + mesh->runtime->edit_mesh = std::make_shared(); + mesh->runtime->edit_mesh->bm = bm; mesh->runtime->edit_mesh->selectmode = mesh->runtime->edit_mesh->bm->selectmode = select_mode; mesh->runtime->edit_mesh->mat_nr = (ob->actcol > 0) ? ob->actcol - 1 : 0; /* we need to flush selection because the mode may have changed from when last in editmode */ - EDBM_selectmode_flush(mesh->runtime->edit_mesh); + EDBM_selectmode_flush(mesh->runtime->edit_mesh.get()); } void EDBM_mesh_load_ex(Main *bmain, Object *ob, bool free_data) @@ -1653,7 +1654,7 @@ void EDBM_stats_update(BMEditMesh *em) void EDBM_update(Mesh *mesh, const EDBMUpdate_Params *params) { - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); /* Order of calling isn't important. */ DEG_id_tag_update(&mesh->id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, &mesh->id); diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 2e5b767789d..57ad1850404 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -175,9 +175,7 @@ static void mesh_uv_reset_mface(const blender::IndexRange face, float2 *mloopuv) void ED_mesh_uv_loop_reset_ex(Mesh *mesh, const int layernum) { - BMEditMesh *em = mesh->runtime->edit_mesh; - - if (em) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { /* Collect BMesh UVs */ const int cd_loop_uv_offset = CustomData_get_n_offset( &em->bm->ldata, CD_PROP_FLOAT2, layernum); @@ -225,7 +223,6 @@ int ED_mesh_uv_add( { /* NOTE: keep in sync with #ED_mesh_color_add. */ - BMEditMesh *em; int layernum_dst; if (!name) { @@ -235,9 +232,7 @@ int ED_mesh_uv_add( const std::string unique_name = BKE_id_attribute_calc_unique_name(mesh->id, name); bool is_init = false; - if (mesh->runtime->edit_mesh) { - em = mesh->runtime->edit_mesh; - + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2); if (layernum_dst >= MAX_MTFACE) { BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); @@ -366,12 +361,9 @@ bool *ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, const int uv_index) void ED_mesh_uv_ensure(Mesh *mesh, const char *name) { - BMEditMesh *em; int layernum_dst; - if (mesh->runtime->edit_mesh) { - em = mesh->runtime->edit_mesh; - + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2); if (layernum_dst == 0) { ED_mesh_uv_add(mesh, name, true, true, nullptr); @@ -401,7 +393,7 @@ int ED_mesh_color_add( const char *active_name = mesh->active_color_attribute; if (const CustomDataLayer *active_layer = BKE_id_attributes_color_find(&mesh->id, active_name)) { - if (const BMEditMesh *em = mesh->runtime->edit_mesh) { + if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMesh &bm = *em->bm; const int src_i = CustomData_get_named_layer(&bm.ldata, CD_PROP_BYTE_COLOR, active_name); const int dst_i = CustomData_get_named_layer(&bm.ldata, CD_PROP_BYTE_COLOR, layer->name); @@ -754,7 +746,7 @@ static int mesh_customdata_custom_splitnormals_clear_exec(bContext *C, wmOperato { Mesh *mesh = ED_mesh_context(C); - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMesh &bm = *em->bm; if (!CustomData_has_layer(&bm.ldata, CD_CUSTOMLOOPNORMAL)) { return OPERATOR_CANCELLED; diff --git a/source/blender/editors/mesh/mesh_mirror.cc b/source/blender/editors/mesh/mesh_mirror.cc index 89dca4cf2e9..90a2bdd029b 100644 --- a/source/blender/editors/mesh/mesh_mirror.cc +++ b/source/blender/editors/mesh/mesh_mirror.cc @@ -33,7 +33,7 @@ static struct { void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *mesh_eval) { Mesh *mesh = static_cast(ob->data); - const bool use_em = (!mesh_eval && em && mesh->runtime->edit_mesh == em); + const bool use_em = (!mesh_eval && em && mesh->runtime->edit_mesh.get() == em); const int totvert = use_em ? em->bm->totvert : mesh_eval ? mesh_eval->verts_num : mesh->verts_num; diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index b4d750e3c22..a231477a9e2 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -832,7 +832,7 @@ BLI_INLINE void mesh_mirror_topo_table_get_meshes(Object *ob, if (mesh_eval != nullptr) { mesh_mirror = mesh_eval; } - else if (BMEditMesh *em = mesh->runtime->edit_mesh) { + else if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { em_mirror = em; } else { @@ -972,7 +972,7 @@ int ED_mesh_mirror_get_vert(Object *ob, int index) bool use_topology = (mesh->editflag & ME_EDIT_MIRROR_TOPO) != 0; int index_mirr; - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMVert *eve, *eve_mirr; eve = BM_vert_at_index(em->bm, index); eve_mirr = editbmesh_get_x_mirror_vert(ob, em, eve, eve->co, index, use_topology); diff --git a/source/blender/editors/object/object_bake_api.cc b/source/blender/editors/object/object_bake_api.cc index 27edf33d120..0fb3b18ffc5 100644 --- a/source/blender/editors/object/object_bake_api.cc +++ b/source/blender/editors/object/object_bake_api.cc @@ -1217,7 +1217,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) } } - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { /* Copy to bmesh. */ const int active_color_offset = CustomData_get_offset_named( &em->bm->vdata, eCustomDataType(active_color_layer->type), active_color_layer->name); @@ -1252,7 +1252,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) MEM_SAFE_FREE(num_loops_for_vertex); } else if (domain == bke::AttrDomain::Corner) { - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { /* Copy to bmesh. */ const int active_color_offset = CustomData_get_offset_named( &em->bm->ldata, eCustomDataType(active_color_layer->type), active_color_layer->name); diff --git a/source/blender/editors/object/object_edit.cc b/source/blender/editors/object/object_edit.cc index 750ef66bf5f..2df3194b1bc 100644 --- a/source/blender/editors/object/object_edit.cc +++ b/source/blender/editors/object/object_edit.cc @@ -583,9 +583,8 @@ static bool editmode_load_free_ex(Main *bmain, } if (free_data) { - EDBM_mesh_free_data(mesh->runtime->edit_mesh); - MEM_freeN(mesh->runtime->edit_mesh); - mesh->runtime->edit_mesh = nullptr; + EDBM_mesh_free_data(mesh->runtime->edit_mesh.get()); + mesh->runtime->edit_mesh.reset(); } /* will be recalculated as needed. */ { diff --git a/source/blender/editors/object/object_hook.cc b/source/blender/editors/object/object_hook.cc index 34e42ec470e..da73887d45a 100644 --- a/source/blender/editors/object/object_hook.cc +++ b/source/blender/editors/object/object_hook.cc @@ -132,7 +132,7 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, static void select_editbmesh_hook(Object *ob, HookModifierData *hmd) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMVert *eve; BMIter iter; int index = 0, nr = 0; @@ -340,7 +340,7 @@ static bool object_hook_index_array(Main *bmain, DEG_id_tag_update(static_cast(obedit->data), 0); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BKE_editmesh_looptris_and_normals_calc(em); diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index c065190af78..4913261dfa1 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -122,7 +122,7 @@ static void object_force_modifier_update_for_bind(Depsgraph *depsgraph, Object * BKE_object_eval_reset(ob_eval); if (ob->type == OB_MESH) { Mesh *mesh_eval = mesh_create_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_DERIVEDMESH); - BKE_mesh_eval_delete(mesh_eval); + BKE_id_free(nullptr, mesh_eval); } else if (ob->type == OB_LATTICE) { BKE_lattice_modifiers_calc(depsgraph, scene_eval, ob_eval); @@ -2687,7 +2687,7 @@ void OBJECT_OT_multires_rebuild_subdiv(wmOperatorType *ot) static void modifier_skin_customdata_delete(Object *ob) { Mesh *mesh = static_cast(ob->data); - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BM_data_layer_free(em->bm, &em->bm->vdata, CD_MVERT_SKIN); } else { diff --git a/source/blender/editors/object/object_relations.cc b/source/blender/editors/object/object_relations.cc index fd1ed06a5cc..d4ac5f1aeff 100644 --- a/source/blender/editors/object/object_relations.cc +++ b/source/blender/editors/object/object_relations.cc @@ -130,7 +130,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op) DEG_id_tag_update(static_cast(obedit->data), 0); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BKE_editmesh_looptris_and_normals_calc(em); diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index a01db943630..668b7227c1e 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -1316,7 +1316,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if (obedit) { if (obedit->type == OB_MESH) { Mesh *mesh = static_cast(obedit->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMVert *eve; BMIter iter; diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 615f364aa22..ce6fbc9c69c 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -157,7 +157,7 @@ bool vgroup_parray_alloc(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const case ID_ME: { Mesh *mesh = (Mesh *)id; - if (BMEditMesh *em = mesh->runtime->edit_mesh) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMesh *bm = em->bm; const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); BMIter iter; @@ -525,7 +525,7 @@ static void ED_mesh_defvert_mirror_update_em( Object *ob, BMVert *eve, int def_nr, int vidx, const int cd_dvert_offset) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMVert *eve_mirr; bool use_topology = (mesh->editflag & ME_EDIT_MIRROR_TOPO) != 0; @@ -563,7 +563,7 @@ static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx) void vgroup_vert_active_mirror(Object *ob, int def_nr) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); MDeformVert *dvert_act; if (mesh->symmetry & ME_SYMMETRY_X) { @@ -599,7 +599,7 @@ static void vgroup_remove_weight(Object *ob, const int def_nr) static bool vgroup_normalize_active_vertex(Object *ob, eVGroupSelect subset_type) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMVert *eve_act; int v_act; MDeformVert *dvert_act; @@ -638,13 +638,12 @@ static bool vgroup_normalize_active_vertex(Object *ob, eVGroupSelect subset_type static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; MDeformVert *dvert_act; int i, vgroup_tot, subset_count; const bool *vgroup_validmap = BKE_object_defgroup_subset_from_select_type( ob, subset_type, &vgroup_tot, &subset_count); - if (em) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { BMIter iter; BMVert *eve, *eve_act; const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); @@ -935,8 +934,7 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) if (ob->type == OB_MESH) { Mesh *mesh = static_cast(ob->data); - if (mesh->runtime->edit_mesh) { - BMEditMesh *em = mesh->runtime->edit_mesh; + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); /* warning, this lookup is _not_ fast */ @@ -1020,8 +1018,7 @@ static void vgroup_select_verts(Object *ob, int select) if (ob->type == OB_MESH) { Mesh *mesh = static_cast(ob->data); - if (mesh->runtime->edit_mesh) { - BMEditMesh *em = mesh->runtime->edit_mesh; + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); if (cd_dvert_offset != -1) { @@ -2037,9 +2034,8 @@ void vgroup_mirror(Object *ob, /* only the active group */ if (ob->type == OB_MESH) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; - if (em) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); BMIter iter; @@ -2231,7 +2227,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) Mesh *mesh = static_cast(ob->data); if (mesh->runtime->edit_mesh) { - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); int cd_dvert_offset; BMIter iter; @@ -3873,10 +3869,9 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) MDeformVert *dvert_act; Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; int i; - if (em) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); BMIter iter; BMVert *eve, *eve_act; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index b94ca974f22..fa7b0788d8b 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -2142,7 +2142,7 @@ static void fill_mesh_color(Mesh &mesh, const bool use_face_sel, const bool affect_alpha) { - if (BMEditMesh *em = mesh.runtime->edit_mesh) { + if (BMEditMesh *em = mesh.runtime->edit_mesh.get()) { BMesh *bm = em->bm; const std::string name = attribute_name; const CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh.id, name.c_str()); diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 0f36150eef5..04d3598dcf3 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -554,7 +554,7 @@ bke::GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *ss if (object_orig->type == OB_MESH) { const Mesh *mesh = static_cast(object_orig->data); if (object_orig->mode == OB_MODE_EDIT) { - if (const BMEditMesh *em = mesh->runtime->edit_mesh) { + if (const BMEditMesh *em = mesh->runtime->edit_mesh.get()) { Mesh *new_mesh = (Mesh *)BKE_id_new_nomain(ID_ME, nullptr); /* This is a potentially heavy operation to do on every redraw. The best solution here is * to display the data directly from the bmesh without a conversion, which can be diff --git a/source/blender/editors/space_view3d/view3d_buttons.cc b/source/blender/editors/space_view3d/view3d_buttons.cc index d1b11508673..d616dc5de37 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.cc +++ b/source/blender/editors/space_view3d/view3d_buttons.cc @@ -311,7 +311,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (ob->type == OB_MESH) { TransformMedian_Mesh *median = &median_basis.mesh; Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMVert *eve; BMEdge *eed; @@ -900,8 +900,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (ob->type == OB_MESH) { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; - if (em != nullptr) { + if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) { uiBlockInteraction_CallbackData callback_data{}; callback_data.begin_fn = editmesh_partial_update_begin_fn; callback_data.end_fn = editmesh_partial_update_end_fn; @@ -934,7 +933,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float { const TransformMedian_Mesh *median = &median_basis.mesh, *ve_median = &ve_median_basis.mesh; Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMIter iter; BMVert *eve; diff --git a/source/blender/editors/uvedit/uvedit_ops.cc b/source/blender/editors/uvedit/uvedit_ops.cc index 607f4ae1c14..4179386d286 100644 --- a/source/blender/editors/uvedit/uvedit_ops.cc +++ b/source/blender/editors/uvedit/uvedit_ops.cc @@ -1666,7 +1666,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) for (Object *ob : objects) { Mesh *mesh = (Mesh *)ob->data; - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; BMIter iter; @@ -1770,7 +1770,7 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op) for (Object *ob : objects) { Mesh *mesh = (Mesh *)ob->data; - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; if (synced_selection && (bm->totedgesel == 0)) { diff --git a/source/blender/editors/uvedit/uvedit_rip.cc b/source/blender/editors/uvedit/uvedit_rip.cc index 59808f37383..7818af5ca5d 100644 --- a/source/blender/editors/uvedit/uvedit_rip.cc +++ b/source/blender/editors/uvedit/uvedit_rip.cc @@ -741,7 +741,7 @@ static bool uv_rip_pairs_calc_center_and_direction(UVRipPairs *rip, static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const float aspect_y) { Mesh *mesh = (Mesh *)obedit->data; - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); BMesh *bm = em->bm; const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2); BM_uv_map_ensure_vert_select_attr(bm, active_uv_name); diff --git a/source/blender/geometry/intern/mesh_boolean.cc b/source/blender/geometry/intern/mesh_boolean.cc index b8634899c86..b7ec64865d4 100644 --- a/source/blender/geometry/intern/mesh_boolean.cc +++ b/source/blender/geometry/intern/mesh_boolean.cc @@ -6,6 +6,7 @@ #include "BKE_attribute.hh" #include "BKE_customdata.hh" +#include "BKE_lib_id.hh" #include "BKE_mesh.hh" #include "BLI_alloca.h" @@ -1122,7 +1123,7 @@ static Mesh *mesh_boolean_float(Span meshes, if (prev_result_mesh != nullptr) { /* Except in the first iteration, two_meshes[0] holds the intermediate * mesh result from the previous iteration. */ - BKE_mesh_eval_delete(prev_result_mesh); + BKE_id_free(nullptr, prev_result_mesh); } if (i < meshes.size() - 2) { two_meshes[0] = result_i_mesh; diff --git a/source/blender/makesrna/intern/rna_object.cc b/source/blender/makesrna/intern/rna_object.cc index e3faecddd40..dfd92b6432c 100644 --- a/source/blender/makesrna/intern/rna_object.cc +++ b/source/blender/makesrna/intern/rna_object.cc @@ -486,11 +486,11 @@ static void rna_Object_active_shape_update(Main *bmain, Scene * /*scene*/, Point switch (ob->type) { case OB_MESH: { Mesh *mesh = static_cast(ob->data); - BMEditMesh *em = mesh->runtime->edit_mesh; + BMEditMesh *em = mesh->runtime->edit_mesh.get(); int select_mode = em->selectmode; EDBM_mesh_load(bmain, ob); EDBM_mesh_make(ob, select_mode, true); - em = mesh->runtime->edit_mesh; + em = mesh->runtime->edit_mesh.get(); DEG_id_tag_update(&mesh->id, 0); diff --git a/source/blender/makesrna/intern/rna_scene.cc b/source/blender/makesrna/intern/rna_scene.cc index e53bad7e557..d206560fca7 100644 --- a/source/blender/makesrna/intern/rna_scene.cc +++ b/source/blender/makesrna/intern/rna_scene.cc @@ -1987,7 +1987,7 @@ static void rna_Scene_editmesh_select_mode_set(PointerRNA *ptr, const bool *valu Mesh *mesh = BKE_mesh_from_object(object); if (mesh && mesh->runtime->edit_mesh && mesh->runtime->edit_mesh->selectmode != flag) { mesh->runtime->edit_mesh->selectmode = flag; - EDBM_selectmode_set(mesh->runtime->edit_mesh); + EDBM_selectmode_set(mesh->runtime->edit_mesh.get()); } } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index 69461289764..c15ed38b390 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -242,7 +242,7 @@ static void node_geo_exec(GeoNodeExecParams params) Object *surface_ob_orig = DEG_get_original_object(surface_ob_eval); Mesh &surface_object_data = *static_cast(surface_ob_orig->data); - if (BMEditMesh *em = surface_object_data.runtime->edit_mesh) { + if (BMEditMesh *em = surface_object_data.runtime->edit_mesh.get()) { surface_mesh_orig = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, nullptr, &surface_object_data); free_suface_mesh_orig = true; }