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 *>(
HooglyBoogly marked this conversation as resolved Outdated

The comment is out-of-date?

The comment is out-of-date?
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);
HooglyBoogly marked this conversation as resolved Outdated

This seems to be a wrong usage of usage of shared pointers. There are now code-paths which will get bare pointer from the mesh->runtime->edit_mesh.get(), pass it to the BKE_mesh_wrapper_from_editmesh, and here a new shared pointer is created.
From my understanding it defeats the original intent of an evaluated state sharing the same em pointer as the input.

This seems to be a wrong usage of usage of shared pointers. There are now code-paths which will get bare pointer from the `mesh->runtime->edit_mesh.get()`, pass it to the `BKE_mesh_wrapper_from_editmesh`, and here a new shared pointer is created. From my understanding it defeats the original intent of an evaluated state sharing the same `em` pointer as the input.

Indeed, thanks. It isn't harmful to correctness in this PR, but it might have messed with my future plans here (comparing edit mesh pointer equality to decide whether to use mapped GPU data extraction). I'll change this function to take a shared pointer argument. That should reduce memory usage too.

Indeed, thanks. It isn't harmful to correctness in this PR, but it might have messed with my future plans here (comparing edit mesh pointer equality to decide whether to use mapped GPU data extraction). I'll change this function to take a shared pointer argument. That should reduce memory usage too.
/* 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;
}