Mesh: Store BMEditMesh in shared pointer #120276

Merged
Hans Goudey merged 5 commits from HooglyBoogly/blender:mesh-edit-mesh-shared-ptr into main 2024-04-18 13:52:32 +02:00
46 changed files with 114 additions and 156 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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<BMEditMesh> edit_mesh;
/**
* A cache of bounds shared between data-blocks with unchanged positions. When changing positions

View File

@ -7,6 +7,8 @@
* \ingroup bke
*/
#include <memory>
#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<BMEditMesh> em,
const CustomData_MeshMasks *cd_mask_extra,
const Mesh *me_settings);
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh);

View File

@ -1009,7 +1009,6 @@ static MutableSpan<float3> 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<BMEditMesh *>(
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<blender::bke::EditMeshData>(
@ -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<Mesh *>(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<Mesh *>(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;

View File

@ -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<Mesh *>(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<Mesh *>(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<Mesh *>(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;

View File

@ -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<BMEditMesh>(*em), &cd_mask_extra, me_input);
deformcos.reinitialize(verts_num);
BKE_mesh_wrapper_vert_coords_copy(mesh, deformcos);
deformmats.reinitialize(verts_num);

View File

@ -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)

View File

@ -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) {

View File

@ -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<const Mesh *>(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<const Mesh *>(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;
}

View File

@ -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<Mesh *>(
Review

Good point. It reminded me that this function is unnecessary now. I've replaced it with BKE_id_free

Good point. It reminded me that this function is unnecessary now. I've replaced it with `BKE_id_free`
@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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<BMEditMesh> 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<BMEditMesh *>(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

View File

@ -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<Mesh *>(ob->data);
const MDisps *mdisp;
if (BMEditMesh *em = mesh->runtime->edit_mesh) {
if (BMEditMesh *em = mesh->runtime->edit_mesh.get()) {
mdisp = static_cast<const MDisps *>(CustomData_get_layer(&em->bm->ldata, CD_MDISPS));
}
else {

View File

@ -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<Mesh *>(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);

View File

@ -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<Mesh *>(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<Mesh *>(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;

View File

@ -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);

View File

@ -178,7 +178,7 @@ void OVERLAY_wireframe_cache_populate(OVERLAY_Data *vedata,
/* TODO: Should be its own function. */
const Mesh *mesh = static_cast<const Mesh *>(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);

View File

@ -79,7 +79,7 @@ static void draw_select_id_edit_mesh(SELECTID_StorageList *stl,
{
using namespace blender::draw;
Mesh *mesh = static_cast<Mesh *>(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);

View File

@ -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;

View File

@ -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;

View File

@ -182,7 +182,7 @@ static bke::GeometrySet get_original_geometry_eval_copy(Object &object)
}
case OB_MESH: {
const Mesh *mesh = static_cast<const Mesh *>(object.data);
if (BMEditMesh *em = mesh->runtime->edit_mesh) {
if (std::shared_ptr<BMEditMesh> &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 {

View File

@ -39,7 +39,7 @@ static int set_sharpness_by_angle_exec(bContext *C, wmOperator *op)
for (Object *object : objects) {
Mesh &mesh = *static_cast<Mesh *>(object->data);
BMEditMesh *em = mesh.runtime->edit_mesh;
BMEditMesh *em = mesh.runtime->edit_mesh.get();
bool changed = false;
BMIter iter;

View File

@ -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<Mesh *>(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<Mesh *>(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<Mesh *>(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) {

View File

@ -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<Mesh *>(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);

View File

@ -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<BMEditMesh>();
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);

View File

@ -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;

View File

@ -33,7 +33,7 @@ static struct {
void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *mesh_eval)
{
Mesh *mesh = static_cast<Mesh *>(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;

View File

@ -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);

View File

@ -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);

View File

@ -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. */
{

View File

@ -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<Mesh *>(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<ID *>(obedit->data), 0);
BMEditMesh *em = mesh->runtime->edit_mesh;
BMEditMesh *em = mesh->runtime->edit_mesh.get();
BKE_editmesh_looptris_and_normals_calc(em);

View File

@ -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);
@ -2689,7 +2689,7 @@ void OBJECT_OT_multires_rebuild_subdiv(wmOperatorType *ot)
static void modifier_skin_customdata_delete(Object *ob)
{
Mesh *mesh = static_cast<Mesh *>(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 {

View File

@ -130,7 +130,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(static_cast<ID *>(obedit->data), 0);
BMEditMesh *em = mesh->runtime->edit_mesh;
BMEditMesh *em = mesh->runtime->edit_mesh.get();
BKE_editmesh_looptris_and_normals_calc(em);

View File

@ -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<Mesh *>(obedit->data);
BMEditMesh *em = mesh->runtime->edit_mesh;
BMEditMesh *em = mesh->runtime->edit_mesh.get();
BMVert *eve;
BMIter iter;

View File

@ -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<Mesh *>(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<Mesh *>(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<Mesh *>(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<Mesh *>(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<Mesh *>(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<Mesh *>(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<Mesh *>(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<Mesh *>(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<Mesh *>(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;

View File

@ -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());

View File

@ -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<const Mesh *>(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

View File

@ -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<Mesh *>(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<Mesh *>(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<Mesh *>(ob->data);
BMEditMesh *em = mesh->runtime->edit_mesh;
BMEditMesh *em = mesh->runtime->edit_mesh.get();
BMesh *bm = em->bm;
BMIter iter;
BMVert *eve;

View File

@ -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)) {

View File

@ -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);

View File

@ -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<const Mesh *> 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;

View File

@ -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<Mesh *>(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);

View File

@ -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());
}
}
}

View File

@ -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<Mesh *>(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;
}