From c34c6d3e25f2f4d96d124cb5ec43c4392e7de4dc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 12 Oct 2022 20:55:26 -0500 Subject: Mesh: Move runtime data out of DNA This commit replaces the `Mesh_Runtime` struct embedded in `Mesh` with `blender::bke::MeshRuntime`. This has quite a few benefits: - It's possible to use C++ types like `std::mutex`, `Array`, `BitVector`, etc. more easily - Meshes saved in files are slightly smaller - Copying and writing meshes is a bit more obvious without clearing of runtime data, etc. The first is by far the most important. It will allows us to avoid a bunch of manual memory management boilerplate that is error-prone and annoying. It should also simplify future CoW improvements for runtime data. This patch doesn't change anything besides changing `mesh.runtime.data` to `mesh.runtime->data`. The cleanups above will happen separately. Differential Revision: https://developer.blender.org/D16180 --- source/blender/blenkernel/BKE_editmesh_cache.h | 20 ++- source/blender/blenkernel/BKE_mesh_runtime.h | 19 +-- source/blender/blenkernel/BKE_mesh_types.h | 144 ++++++++++++++++ source/blender/blenkernel/intern/DerivedMesh.cc | 32 ++-- source/blender/blenkernel/intern/bvhutils.cc | 4 +- source/blender/blenkernel/intern/cloth.c | 2 +- source/blender/blenkernel/intern/editmesh.cc | 6 +- .../blender/blenkernel/intern/mball_tessellate.cc | 2 +- source/blender/blenkernel/intern/mesh.cc | 38 +++-- source/blender/blenkernel/intern/mesh_convert.cc | 2 +- source/blender/blenkernel/intern/mesh_debug.cc | 4 +- source/blender/blenkernel/intern/mesh_iterators.cc | 32 ++-- source/blender/blenkernel/intern/mesh_normals.cc | 68 ++++---- source/blender/blenkernel/intern/mesh_remap.c | 2 +- source/blender/blenkernel/intern/mesh_runtime.cc | 186 +++++++++------------ source/blender/blenkernel/intern/mesh_tangent.cc | 6 +- source/blender/blenkernel/intern/mesh_wrapper.cc | 66 ++++---- source/blender/blenkernel/intern/modifier.cc | 6 +- source/blender/blenkernel/intern/multires.cc | 2 +- source/blender/blenkernel/intern/object.cc | 10 +- source/blender/blenkernel/intern/object_dupli.cc | 4 +- source/blender/blenkernel/intern/object_update.cc | 2 +- source/blender/blenkernel/intern/paint.cc | 8 +- source/blender/blenkernel/intern/particle.c | 5 +- .../blenkernel/intern/particle_distribute.c | 3 +- source/blender/blenkernel/intern/particle_system.c | 3 +- source/blender/blenkernel/intern/rigidbody.c | 6 +- source/blender/blenkernel/intern/shrinkwrap.cc | 8 +- source/blender/blenkernel/intern/subdiv_ccg.cc | 2 +- source/blender/blenkernel/intern/subdiv_mesh.cc | 10 +- .../blender/blenkernel/intern/subdiv_modifier.cc | 3 +- source/blender/bmesh/intern/bmesh_mesh_convert.cc | 2 +- .../draw/engines/workbench/workbench_engine.c | 5 +- .../blender/draw/intern/draw_cache_extract_mesh.cc | 2 +- .../intern/draw_cache_extract_mesh_render_data.cc | 6 +- source/blender/draw/intern/draw_cache_impl_mesh.cc | 32 ++-- .../draw/intern/draw_cache_impl_subdivision.cc | 2 +- source/blender/draw/intern/draw_manager_data.cc | 2 +- source/blender/draw/intern/draw_manager_text.cc | 9 +- .../draw/intern/mesh_extractors/extract_mesh.hh | 10 +- .../mesh_extractors/extract_mesh_ibo_edituv.cc | 2 +- .../mesh_extractors/extract_mesh_ibo_fdots.cc | 2 +- .../mesh_extractors/extract_mesh_vbo_fdots_pos.cc | 2 +- .../mesh_extractors/extract_mesh_vbo_fdots_uv.cc | 2 +- source/blender/editors/mesh/editmesh_select.cc | 6 +- source/blender/editors/mesh/editmesh_undo.cc | 5 + source/blender/editors/physics/particle_edit.c | 6 +- source/blender/editors/physics/particle_object.c | 2 +- .../editors/sculpt_paint/paint_image_proj.c | 2 +- source/blender/editors/sculpt_paint/paint_utils.c | 2 +- source/blender/editors/space_info/info_stats.cc | 5 +- source/blender/editors/space_view3d/drawobject.c | 5 +- .../space_view3d/view3d_gizmo_preselect_type.cc | 6 +- .../editors/space_view3d/view3d_iterators.cc | 2 +- .../editors/transform/transform_snap_object.cc | 22 +-- .../gpencil_modifiers/intern/lineart/lineart_cpu.c | 4 +- source/blender/makesdna/DNA_mesh_types.h | 143 ++-------------- source/blender/makesrna/intern/rna_mesh.c | 46 ++++- source/blender/modifiers/intern/MOD_cast.c | 3 +- .../blender/modifiers/intern/MOD_datatransfer.cc | 2 +- source/blender/modifiers/intern/MOD_multires.cc | 4 +- source/blender/modifiers/intern/MOD_normal_edit.cc | 2 +- .../blender/modifiers/intern/MOD_particlesystem.cc | 2 +- source/blender/modifiers/intern/MOD_remesh.c | 5 +- source/blender/modifiers/intern/MOD_subsurf.cc | 2 +- source/blender/modifiers/intern/MOD_util.cc | 4 +- source/blender/modifiers/intern/MOD_uvproject.cc | 2 +- source/blender/modifiers/intern/MOD_uvwarp.cc | 2 +- source/blender/modifiers/intern/MOD_wave.cc | 3 +- .../modifiers/intern/MOD_weighted_normal.cc | 2 +- .../blender/modifiers/intern/MOD_weightvgedit.cc | 2 +- source/blender/modifiers/intern/MOD_weightvgmix.cc | 2 +- .../modifiers/intern/MOD_weightvgproximity.cc | 2 +- source/blender/render/intern/bake.c | 2 +- 74 files changed, 575 insertions(+), 505 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_editmesh_cache.h b/source/blender/blenkernel/BKE_editmesh_cache.h index 2640356ccf6..454a07be4e3 100644 --- a/source/blender/blenkernel/BKE_editmesh_cache.h +++ b/source/blender/blenkernel/BKE_editmesh_cache.h @@ -11,15 +11,25 @@ extern "C" { #endif struct BMEditMesh; -struct EditMeshData; -void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, struct EditMeshData *emd); -void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, struct EditMeshData *emd); +typedef struct EditMeshData { + /** when set, \a vertexNos, polyNos are lazy initialized */ + const float (*vertexCos)[3]; -void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, struct EditMeshData *emd); + /** lazy initialize (when \a vertexCos is set) */ + float const (*vertexNos)[3]; + float const (*polyNos)[3]; + /** also lazy init but don't depend on \a vertexCos */ + const float (*polyCos)[3]; +} EditMeshData; + +void BKE_editmesh_cache_ensure_poly_normals(struct BMEditMesh *em, EditMeshData *emd); +void BKE_editmesh_cache_ensure_vert_normals(struct BMEditMesh *em, EditMeshData *emd); + +void BKE_editmesh_cache_ensure_poly_centers(struct BMEditMesh *em, EditMeshData *emd); bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em, - struct EditMeshData *emd, + EditMeshData *emd, float min[3], float max[3]); diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h index dfefe125a51..27e04c1a4de 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.h +++ b/source/blender/blenkernel/BKE_mesh_runtime.h @@ -9,6 +9,7 @@ */ //#include "BKE_customdata.h" /* for eCustomDataMask */ +#include "BKE_mesh_types.h" #ifdef __cplusplus extern "C" { @@ -25,22 +26,11 @@ struct Mesh; struct Object; struct Scene; -/** - * \brief Initialize the runtime of the given mesh. - * - * Function expects that the runtime is already cleared. - */ -void BKE_mesh_runtime_init_data(struct Mesh *mesh); /** * \brief Free all data (and mutexes) inside the runtime of the given mesh. */ void BKE_mesh_runtime_free_data(struct Mesh *mesh); -/** - * Clear all pointers which we don't want to be shared on copying the datablock. - * However, keep all the flags which defines what the mesh is (for example, that - * it's deformed only, or that its custom data layers are out of date.) - */ -void BKE_mesh_runtime_reset_on_copy(struct Mesh *mesh, int flag); + int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh); void BKE_mesh_runtime_looptri_recalc(struct Mesh *mesh); /** @@ -66,6 +56,11 @@ void BKE_mesh_runtime_verttri_from_looptri(struct MVertTri *r_verttri, const struct MLoopTri *looptri, int looptri_num); +/** \note Only used for access in C. */ +bool BKE_mesh_is_deformed_only(const struct Mesh *mesh); +/** \note Only used for access in C. */ +eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh); + /* NOTE: the functions below are defined in DerivedMesh.cc, and are intended to be moved * to a more suitable location when that file is removed. * They should also be renamed to use conventions from BKE, not old DerivedMesh.cc. diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index 0b879c1dfe9..8f3fee70c7f 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -1,11 +1,33 @@ /* SPDX-License-Identifier: GPL-2.0-or-later * Copyright 2020 Blender Foundation. All rights reserved. */ + #pragma once /** \file * \ingroup bke */ +#ifdef __cplusplus + +# include "BLI_span.hh" + +# include "DNA_customdata_types.h" + +# include "MEM_guardedalloc.h" + +struct BVHCache; +struct EditMeshData; +struct MLoopTri; +struct ShrinkwrapBoundaryData; +struct SubdivCCG; +struct SubsurfRuntimeData; + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + typedef enum eMeshBatchDirtyMode { BKE_MESH_BATCH_DIRTY_ALL = 0, BKE_MESH_BATCH_DIRTY_SELECT, @@ -14,3 +36,125 @@ typedef enum eMeshBatchDirtyMode { BKE_MESH_BATCH_DIRTY_UVEDIT_ALL, BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT, } eMeshBatchDirtyMode; + +/** #MeshRuntime.wrapper_type */ +typedef enum eMeshWrapperType { + /** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */ + ME_WRAPPER_TYPE_MDATA = 0, + /** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */ + ME_WRAPPER_TYPE_BMESH = 1, + /** Use subdivision mesh data (#MeshRuntime.mesh_eval). */ + ME_WRAPPER_TYPE_SUBD = 2, +} eMeshWrapperType; + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +namespace blender::bke { + +/** + * \warning Typical access is done via #Mesh::looptris(). + */ +struct MLoopTri_Store { + /* WARNING! swapping between array (ready-to-be-used data) and array_wip + * (where data is actually computed) + * shall always be protected by same lock as one used for looptris computing. */ + MLoopTri *array = nullptr; + MLoopTri *array_wip = nullptr; + int len = 0; + int len_alloc = 0; +}; + +struct MeshRuntime { + /* Evaluated mesh for objects which do not have effective modifiers. + * This mesh is used as a result of modifier stack evaluation. + * Since modifier stack evaluation is threaded on object level we need some synchronization. */ + Mesh *mesh_eval = nullptr; + void *eval_mutex = nullptr; + + /* A separate mutex is needed for normal calculation, because sometimes + * the normals are needed while #eval_mutex is already locked. */ + void *normals_mutex = nullptr; + + /** Needed to ensure some thread-safety during render data pre-processing. */ + void *render_mutex = nullptr; + + /** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */ + EditMeshData *edit_data = nullptr; + + /** + * Data used to efficiently draw the mesh in the viewport, especially useful when + * the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`. + */ + void *batch_cache = nullptr; + + /** Cache for derived triangulation of the mesh. */ + MLoopTri_Store looptris; + + /** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */ + BVHCache *bvh_cache = nullptr; + + /** Cache of non-manifold boundary data for Shrinkwrap Target Project. */ + ShrinkwrapBoundaryData *shrinkwrap_data = nullptr; + + /** Needed in case we need to lazily initialize the mesh. */ + CustomData_MeshMasks cd_mask_extra = {}; + + SubdivCCG *subdiv_ccg = nullptr; + int subdiv_ccg_tot_level = 0; + + /** Set by modifier stack if only deformed from original. */ + bool deformed_only = false; + /** + * Copied from edit-mesh (hint, draw with edit-mesh data when true). + * + * Modifiers that edit the mesh data in-place must set this to false + * (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh + * data will be used for drawing, missing changes from modifiers. See T79517. + */ + bool is_original_bmesh = false; + + /** #eMeshWrapperType and others. */ + eMeshWrapperType wrapper_type = ME_WRAPPER_TYPE_MDATA; + /** + * A type mask from wrapper_type, + * in case there are differences in finalizing logic between types. + */ + eMeshWrapperType wrapper_type_finalize = ME_WRAPPER_TYPE_MDATA; + + /** + * Settings for lazily evaluating the subdivision on the CPU if needed. These are + * set in the modifier when GPU subdivision can be performed, and owned by the by + * the modifier in the object. + */ + SubsurfRuntimeData *subsurf_runtime_data = nullptr; + + /** + * Caches for lazily computed vertex and polygon normals. These are stored here rather than in + * #CustomData because they can be calculated on a const mesh, and adding custom data layers on a + * const mesh is not thread-safe. + */ + bool vert_normals_dirty = false; + bool poly_normals_dirty = false; + float (*vert_normals)[3] = nullptr; + float (*poly_normals)[3] = nullptr; + + /** + * A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the + * subdivision surface modifier and used by drawing code instead of polygon center face dots. + */ + uint32_t *subsurf_face_dot_tags = nullptr; + + MeshRuntime(); + /** \warning This does not free all data currently. See #BKE_mesh_runtime_free_data. */ + ~MeshRuntime(); + + MEM_CXX_CLASS_ALLOC_FUNCS("MeshRuntime") +}; + +} // namespace blender::bke + +#endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 742f20fa65f..9930e5f23fa 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -35,6 +35,7 @@ #include "BKE_colorband.h" #include "BKE_deform.h" #include "BKE_editmesh.h" +#include "BKE_editmesh_cache.h" #include "BKE_geometry_set.hh" #include "BKE_geometry_set_instances.hh" #include "BKE_key.h" @@ -537,7 +538,7 @@ static void mesh_calc_modifier_final_normals(const Mesh *mesh_input, (final_datamask->lmask & CD_MASK_NORMAL) != 0); /* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */ - SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data; + SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data; if (subsurf_runtime_data) { subsurf_runtime_data->calc_loop_normals = calc_loop_normals; } @@ -585,11 +586,12 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval) void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval, const CustomData_MeshMasks *cd_mask_finalize) { - if (me_eval->runtime.wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) { + if (me_eval->runtime->wrapper_type_finalize & (1 << ME_WRAPPER_TYPE_BMESH)) { editbmesh_calc_modifier_final_normals(me_eval, cd_mask_finalize); - me_eval->runtime.wrapper_type_finalize &= ~(1 << ME_WRAPPER_TYPE_BMESH); + me_eval->runtime->wrapper_type_finalize = eMeshWrapperType( + me_eval->runtime->wrapper_type_finalize & ~(1 << ME_WRAPPER_TYPE_BMESH)); } - BLI_assert(me_eval->runtime.wrapper_type_finalize == 0); + BLI_assert(me_eval->runtime->wrapper_type_finalize == 0); } /** @@ -1052,7 +1054,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, append_mask.lmask |= CD_MASK_PREVIEW_MLOOPCOL; } - mesh_final->runtime.deformed_only = false; + mesh_final->runtime->deformed_only = false; } isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); @@ -1119,7 +1121,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, mesh_calc_finalize(mesh_input, mesh_final); } else { - Mesh_Runtime *runtime = &mesh_input->runtime; + blender::bke::MeshRuntime *runtime = mesh_input->runtime; if (runtime->mesh_eval == nullptr) { BLI_assert(runtime->eval_mutex != nullptr); BLI_mutex_lock((ThreadMutex *)runtime->eval_mutex); @@ -1207,7 +1209,7 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final, const bool calc_loop_normals = ((mesh_final->flag & ME_AUTOSMOOTH) != 0 || (final_datamask->lmask & CD_MASK_NORMAL) != 0); - SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime.subsurf_runtime_data; + SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->subsurf_runtime_data; if (subsurf_runtime_data) { subsurf_runtime_data->calc_loop_normals = calc_loop_normals; } @@ -1234,9 +1236,10 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final, static void editbmesh_calc_modifier_final_normals_or_defer( Mesh *mesh_final, const CustomData_MeshMasks *final_datamask) { - if (mesh_final->runtime.wrapper_type != ME_WRAPPER_TYPE_MDATA) { + if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) { /* Generated at draw time. */ - mesh_final->runtime.wrapper_type_finalize = (1 << mesh_final->runtime.wrapper_type); + mesh_final->runtime->wrapper_type_finalize = eMeshWrapperType( + 1 << mesh_final->runtime->wrapper_type); return; } @@ -1450,7 +1453,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, deformed_verts = nullptr; } } - mesh_final->runtime.deformed_only = false; + mesh_final->runtime->deformed_only = false; } if (r_cage && i == cageIndex) { @@ -1469,7 +1472,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, if (!BKE_mesh_runtime_ensure_edit_data(me_orig)) { BKE_mesh_runtime_reset_edit_data(me_orig); } - me_orig->runtime.edit_data->vertexCos = (const float(*)[3])MEM_dupallocN(deformed_verts); + me_orig->runtime->edit_data->vertexCos = (const float(*)[3])MEM_dupallocN( + deformed_verts); } mesh_cage = BKE_mesh_wrapper_from_editmesh_with_coords( em_input, @@ -1583,7 +1587,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph, * object's runtime: this could cause access freed data on depsgraph destruction (mesh who owns * the final result might be freed prior to object). */ Mesh *mesh = (Mesh *)ob->data; - const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime.mesh_eval); + const bool is_mesh_eval_owned = (mesh_eval != mesh->runtime->mesh_eval); BKE_object_eval_assign_data(ob, &mesh_eval->id, is_mesh_eval_owned); /* Add the final mesh as a non-owning component to the geometry set. */ @@ -1643,7 +1647,7 @@ static void editbmesh_build_data(struct Depsgraph *depsgraph, } } - const bool is_mesh_eval_owned = (me_final != mesh->runtime.mesh_eval); + const bool is_mesh_eval_owned = (me_final != mesh->runtime->mesh_eval); BKE_object_eval_assign_data(obedit, &me_final->id, is_mesh_eval_owned); obedit->runtime.editmesh_eval_cage = me_cage; @@ -1914,7 +1918,7 @@ static void make_vertexcos__mapFunc(void *userData, void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int totcos) { - if (me_eval->runtime.deformed_only == false) { + if (me_eval->runtime->deformed_only == false) { MappedUserData userData; memset(r_cos, 0, sizeof(*r_cos) * totcos); userData.vertexcos = r_cos; diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index 58b377eecdb..184356615d4 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -1222,8 +1222,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, const BVHCacheType bvh_cache_type, const int tree_type) { - BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime.bvh_cache; - ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex; + BVHCache **bvh_cache_p = (BVHCache **)&mesh->runtime->bvh_cache; + ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime->eval_mutex; const MLoopTri *looptri = nullptr; int looptri_len = 0; diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 7ee6b4cdfc0..89983eb8f62 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -826,7 +826,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes const MLoop *mloop = BKE_mesh_loops(mesh); const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh); const uint mvert_num = mesh->totvert; - const uint looptri_num = mesh->runtime.looptris.len; + const uint looptri_num = BKE_mesh_runtime_looptri_len(mesh); /* Allocate our vertices. */ clmd->clothObject->mvert_num = mvert_num; diff --git a/source/blender/blenkernel/intern/editmesh.cc b/source/blender/blenkernel/intern/editmesh.cc index 2ed5ec7469f..b586b4110f2 100644 --- a/source/blender/blenkernel/intern/editmesh.cc +++ b/source/blender/blenkernel/intern/editmesh.cc @@ -240,12 +240,12 @@ const float (*BKE_editmesh_vert_coords_when_deformed(Depsgraph *depsgraph, Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(object_eval); - if ((me->runtime.edit_data != nullptr) && (me->runtime.edit_data->vertexCos != nullptr)) { + if ((me->runtime->edit_data != nullptr) && (me->runtime->edit_data->vertexCos != nullptr)) { /* Deformed, and we have deformed coords already. */ - coords = me->runtime.edit_data->vertexCos; + coords = me->runtime->edit_data->vertexCos; } else if ((editmesh_eval_final != nullptr) && - (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) { + (editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) { /* If this is an edit-mesh type, leave nullptr as we can use the vertex coords. */ } else { diff --git a/source/blender/blenkernel/intern/mball_tessellate.cc b/source/blender/blenkernel/intern/mball_tessellate.cc index 5e8d2bc6d76..bb3713e770a 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.cc +++ b/source/blender/blenkernel/intern/mball_tessellate.cc @@ -1498,7 +1498,7 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) for (int i = 0; i < mesh->totvert; i++) { normalize_v3(process.no[i]); } - mesh->runtime.vert_normals = process.no; + mesh->runtime->vert_normals = process.no; BKE_mesh_vertex_normals_clear_dirty(mesh); mesh->totloop = loop_offset; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 9e7821428d1..0018c217964 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -89,7 +89,7 @@ static void mesh_init_data(ID *id) CustomData_reset(&mesh->pdata); CustomData_reset(&mesh->ldata); - BKE_mesh_runtime_init_data(mesh); + mesh->runtime = new blender::bke::MeshRuntime(); /* A newly created mesh does not have normals, so tag them dirty. This will be cleared * by #BKE_mesh_vertex_normals_clear_dirty or #BKE_mesh_poly_normals_ensure. */ @@ -103,14 +103,19 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int Mesh *mesh_dst = (Mesh *)id_dst; const Mesh *mesh_src = (const Mesh *)id_src; - BKE_mesh_runtime_reset_on_copy(mesh_dst, flag); + mesh_dst->runtime = new blender::bke::MeshRuntime(); + mesh_dst->runtime->deformed_only = mesh_src->runtime->deformed_only; + mesh_dst->runtime->wrapper_type = mesh_src->runtime->wrapper_type; + mesh_dst->runtime->wrapper_type_finalize = mesh_src->runtime->wrapper_type_finalize; + mesh_dst->runtime->subsurf_runtime_data = mesh_src->runtime->subsurf_runtime_data; + mesh_dst->runtime->cd_mask_extra = mesh_src->runtime->cd_mask_extra; /* Copy face dot tags, since meshes may be duplicated after a subsurf modifier * or node, but we still need to be able to draw face center vertices. */ - mesh_dst->runtime.subsurf_face_dot_tags = static_cast( - MEM_dupallocN(mesh_src->runtime.subsurf_face_dot_tags)); + mesh_dst->runtime->subsurf_face_dot_tags = static_cast( + MEM_dupallocN(mesh_src->runtime->subsurf_face_dot_tags)); if ((mesh_src->id.tag & LIB_TAG_NO_MAIN) == 0) { /* This is a direct copy of a main mesh, so for now it has the same topology. */ - mesh_dst->runtime.deformed_only = true; + mesh_dst->runtime->deformed_only = true; } /* This option is set for run-time meshes that have been copied from the current objects mode. * Currently this is used for edit-mesh although it could be used for sculpt or other @@ -121,7 +126,7 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int * * While this could be the callers responsibility, keep here since it's * highly unlikely we want to create a duplicate and not use it for drawing. */ - mesh_dst->runtime.is_original_bmesh = false; + mesh_dst->runtime->is_original_bmesh = false; /* Only do tessface if we have no polys. */ const bool do_tessface = ((mesh_src->totface != 0) && (mesh_src->totpoly == 0)); @@ -194,6 +199,8 @@ static void mesh_free_data(ID *id) BKE_mesh_runtime_free_data(mesh); mesh_clear_geometry(mesh); MEM_SAFE_FREE(mesh->mat); + + delete mesh->runtime; } static void mesh_foreach_id(ID *id, LibraryForeachIDData *data) @@ -229,7 +236,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address mesh->mface = nullptr; mesh->totface = 0; memset(&mesh->fdata, 0, sizeof(mesh->fdata)); - mesh->runtime = blender::dna::shallow_zero_initialize(); + mesh->runtime = nullptr; /* Do not store actual geometry data in case this is a library override ID. */ if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) { @@ -339,8 +346,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; mesh->edit_mesh = nullptr; - mesh->runtime = blender::dna::shallow_zero_initialize(); - BKE_mesh_runtime_init_data(mesh); + mesh->runtime = new blender::bke::MeshRuntime(); /* happens with old files */ if (mesh->mselect == nullptr) { @@ -1137,7 +1143,7 @@ static void ensure_orig_index_layer(CustomData &data, const int size) void BKE_mesh_ensure_default_orig_index_customdata(Mesh *mesh) { - BLI_assert(mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA); + BLI_assert(mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA); BKE_mesh_ensure_default_orig_index_customdata_no_check(mesh); } @@ -2106,8 +2112,8 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals) } /* Update normals manually to avoid recalculation after this operation. */ - mesh->runtime.vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime.vert_normals, - sizeof(float[3]) * mesh->totvert); + mesh->runtime->vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime->vert_normals, + sizeof(float[3]) * mesh->totvert); /* Perform actual split of vertices and edges. */ split_faces_split_new_verts(mesh, new_verts, num_new_verts); @@ -2141,10 +2147,10 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh) /* We are here because something did change in the mesh. This means we can not trust the existing * 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->edit_mesh = nullptr; - BKE_id_free(nullptr, mesh->runtime.mesh_eval); - mesh->runtime.mesh_eval = nullptr; + if (mesh->runtime->mesh_eval != nullptr) { + mesh->runtime->mesh_eval->edit_mesh = nullptr; + BKE_id_free(nullptr, mesh->runtime->mesh_eval); + mesh->runtime->mesh_eval = nullptr; } if (DEG_is_active(depsgraph)) { Mesh *mesh_orig = (Mesh *)DEG_get_original_id(&mesh->id); diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index b4f729ca507..027423f5774 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -903,7 +903,7 @@ static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh) { /* While we could copy this into the new mesh, * add the data to 'mesh' so future calls to this function don't need to re-convert the data. */ - if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { BKE_mesh_wrapper_ensure_mdata(mesh); } else { diff --git a/source/blender/blenkernel/intern/mesh_debug.cc b/source/blender/blenkernel/intern/mesh_debug.cc index ba4f25c74ee..6cf237a7c8c 100644 --- a/source/blender/blenkernel/intern/mesh_debug.cc +++ b/source/blender/blenkernel/intern/mesh_debug.cc @@ -41,9 +41,9 @@ char *BKE_mesh_debug_info(const Mesh *me) BLI_dynstr_appendf(dynstr, " 'totface': %d,\n", me->totface); BLI_dynstr_appendf(dynstr, " 'totpoly': %d,\n", me->totpoly); - BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime.deformed_only); + BLI_dynstr_appendf(dynstr, " 'runtime.deformed_only': %d,\n", me->runtime->deformed_only); BLI_dynstr_appendf( - dynstr, " 'runtime.is_original_bmesh': %d,\n", me->runtime.is_original_bmesh); + dynstr, " 'runtime->is_original_bmesh': %d,\n", me->runtime->is_original_bmesh); BLI_dynstr_append(dynstr, " 'vert_layers': (\n"); CustomData_debug_info_from_layers(&me->vdata, indent8, dynstr); diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index cf2518d7c9b..a99e9b2348d 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -36,18 +36,18 @@ void BKE_mesh_foreach_mapped_vert( void *userData, MeshForeachFlag flag) { - if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data != nullptr) { + if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) { BMEditMesh *em = mesh->edit_mesh; BMesh *bm = em->bm; BMIter iter; BMVert *eve; int i; - if (mesh->runtime.edit_data->vertexCos != nullptr) { - const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos; + if (mesh->runtime->edit_data->vertexCos != nullptr) { + const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos; const float(*vertexNos)[3]; if (flag & MESH_FOREACH_USE_NORMAL) { - BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime.edit_data); - vertexNos = mesh->runtime.edit_data->vertexNos; + BKE_editmesh_cache_ensure_vert_normals(em, mesh->runtime->edit_data); + vertexNos = mesh->runtime->edit_data->vertexNos; } else { vertexNos = nullptr; @@ -96,14 +96,14 @@ void BKE_mesh_foreach_mapped_edge( void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]), void *userData) { - if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data) { + if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data) { BMEditMesh *em = mesh->edit_mesh; BMesh *bm = em->bm; BMIter iter; BMEdge *eed; int i; - if (mesh->runtime.edit_data->vertexCos != nullptr) { - const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos; + if (mesh->runtime->edit_data->vertexCos != nullptr) { + const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos; BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { @@ -154,13 +154,13 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, /* We can't use `dm->getLoopDataLayout(dm)` here, * we want to always access `dm->loopData`, `EditDerivedBMesh` would * return loop data from BMesh itself. */ - if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data) { + if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data) { BMEditMesh *em = mesh->edit_mesh; BMesh *bm = em->bm; BMIter iter; BMFace *efa; - const float(*vertexCos)[3] = mesh->runtime.edit_data->vertexCos; + const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos; /* XXX: investigate using EditMesh data. */ const float(*lnors)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? @@ -231,7 +231,7 @@ void BKE_mesh_foreach_mapped_face_center( void *userData, MeshForeachFlag flag) { - if (mesh->edit_mesh != nullptr && mesh->runtime.edit_data != nullptr) { + if (mesh->edit_mesh != nullptr && mesh->runtime->edit_data != nullptr) { BMEditMesh *em = mesh->edit_mesh; BMesh *bm = em->bm; const float(*polyCos)[3]; @@ -240,12 +240,12 @@ void BKE_mesh_foreach_mapped_face_center( BMIter iter; int i; - BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime.edit_data); - polyCos = mesh->runtime.edit_data->polyCos; /* always set */ + BKE_editmesh_cache_ensure_poly_centers(em, mesh->runtime->edit_data); + polyCos = mesh->runtime->edit_data->polyCos; /* always set */ if (flag & MESH_FOREACH_USE_NORMAL) { - BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime.edit_data); - polyNos = mesh->runtime.edit_data->polyNos; /* maybe nullptr */ + BKE_editmesh_cache_ensure_poly_normals(em, mesh->runtime->edit_data); + polyNos = mesh->runtime->edit_data->polyNos; /* maybe nullptr */ } else { polyNos = nullptr; @@ -317,7 +317,7 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( BKE_mesh_vertex_normals_ensure(mesh) : nullptr; const int *index = static_cast(CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX)); - const BLI_bitmap *facedot_tags = mesh->runtime.subsurf_face_dot_tags; + const BLI_bitmap *facedot_tags = mesh->runtime->subsurf_face_dot_tags; BLI_assert(facedot_tags != nullptr); if (index) { diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 76f2078e6c8..c2594ea3816 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -95,72 +95,72 @@ static void add_v3_v3_atomic(float r[3], const float a[3]) void BKE_mesh_normals_tag_dirty(Mesh *mesh) { - mesh->runtime.vert_normals_dirty = true; - mesh->runtime.poly_normals_dirty = true; + mesh->runtime->vert_normals_dirty = true; + mesh->runtime->poly_normals_dirty = true; } float (*BKE_mesh_vertex_normals_for_write(Mesh *mesh))[3] { - if (mesh->runtime.vert_normals == nullptr) { - mesh->runtime.vert_normals = (float(*)[3])MEM_malloc_arrayN( + if (mesh->runtime->vert_normals == nullptr) { + mesh->runtime->vert_normals = (float(*)[3])MEM_malloc_arrayN( mesh->totvert, sizeof(float[3]), __func__); } - BLI_assert(MEM_allocN_len(mesh->runtime.vert_normals) >= sizeof(float[3]) * mesh->totvert); + BLI_assert(MEM_allocN_len(mesh->runtime->vert_normals) >= sizeof(float[3]) * mesh->totvert); - return mesh->runtime.vert_normals; + return mesh->runtime->vert_normals; } float (*BKE_mesh_poly_normals_for_write(Mesh *mesh))[3] { - if (mesh->runtime.poly_normals == nullptr) { - mesh->runtime.poly_normals = (float(*)[3])MEM_malloc_arrayN( + if (mesh->runtime->poly_normals == nullptr) { + mesh->runtime->poly_normals = (float(*)[3])MEM_malloc_arrayN( mesh->totpoly, sizeof(float[3]), __func__); } - BLI_assert(MEM_allocN_len(mesh->runtime.poly_normals) >= sizeof(float[3]) * mesh->totpoly); + BLI_assert(MEM_allocN_len(mesh->runtime->poly_normals) >= sizeof(float[3]) * mesh->totpoly); - return mesh->runtime.poly_normals; + return mesh->runtime->poly_normals; } void BKE_mesh_vertex_normals_clear_dirty(Mesh *mesh) { - mesh->runtime.vert_normals_dirty = false; + mesh->runtime->vert_normals_dirty = false; BKE_mesh_assert_normals_dirty_or_calculated(mesh); } void BKE_mesh_poly_normals_clear_dirty(Mesh *mesh) { - mesh->runtime.poly_normals_dirty = false; + mesh->runtime->poly_normals_dirty = false; BKE_mesh_assert_normals_dirty_or_calculated(mesh); } bool BKE_mesh_vertex_normals_are_dirty(const Mesh *mesh) { - return mesh->runtime.vert_normals_dirty; + return mesh->runtime->vert_normals_dirty; } bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh) { - return mesh->runtime.poly_normals_dirty; + return mesh->runtime->poly_normals_dirty; } void BKE_mesh_clear_derived_normals(Mesh *mesh) { - MEM_SAFE_FREE(mesh->runtime.vert_normals); - MEM_SAFE_FREE(mesh->runtime.poly_normals); + MEM_SAFE_FREE(mesh->runtime->vert_normals); + MEM_SAFE_FREE(mesh->runtime->poly_normals); - mesh->runtime.vert_normals_dirty = true; - mesh->runtime.poly_normals_dirty = true; + mesh->runtime->vert_normals_dirty = true; + mesh->runtime->poly_normals_dirty = true; } void BKE_mesh_assert_normals_dirty_or_calculated(const Mesh *mesh) { - if (!mesh->runtime.vert_normals_dirty) { - BLI_assert(mesh->runtime.vert_normals || mesh->totvert == 0); + if (!mesh->runtime->vert_normals_dirty) { + BLI_assert(mesh->runtime->vert_normals || mesh->totvert == 0); } - if (!mesh->runtime.poly_normals_dirty) { - BLI_assert(mesh->runtime.poly_normals || mesh->totpoly == 0); + if (!mesh->runtime->poly_normals_dirty) { + BLI_assert(mesh->runtime->poly_normals || mesh->totpoly == 0); } } @@ -348,20 +348,20 @@ void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert, const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3] { if (!BKE_mesh_vertex_normals_are_dirty(mesh)) { - BLI_assert(mesh->runtime.vert_normals != nullptr || mesh->totvert == 0); - return mesh->runtime.vert_normals; + BLI_assert(mesh->runtime->vert_normals != nullptr || mesh->totvert == 0); + return mesh->runtime->vert_normals; } if (mesh->totvert == 0) { return nullptr; } - ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime.normals_mutex; + ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime->normals_mutex; BLI_mutex_lock(normals_mutex); if (!BKE_mesh_vertex_normals_are_dirty(mesh)) { - BLI_assert(mesh->runtime.vert_normals != nullptr); + BLI_assert(mesh->runtime->vert_normals != nullptr); BLI_mutex_unlock(normals_mutex); - return mesh->runtime.vert_normals; + return mesh->runtime->vert_normals; } float(*vert_normals)[3]; @@ -397,20 +397,20 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3] const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3] { if (!BKE_mesh_poly_normals_are_dirty(mesh)) { - BLI_assert(mesh->runtime.poly_normals != nullptr || mesh->totpoly == 0); - return mesh->runtime.poly_normals; + BLI_assert(mesh->runtime->poly_normals != nullptr || mesh->totpoly == 0); + return mesh->runtime->poly_normals; } if (mesh->totpoly == 0) { return nullptr; } - ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime.normals_mutex; + ThreadMutex *normals_mutex = (ThreadMutex *)mesh->runtime->normals_mutex; BLI_mutex_lock(normals_mutex); if (!BKE_mesh_poly_normals_are_dirty(mesh)) { - BLI_assert(mesh->runtime.poly_normals != nullptr); + BLI_assert(mesh->runtime->poly_normals != nullptr); BLI_mutex_unlock(normals_mutex); - return mesh->runtime.poly_normals; + return mesh->runtime->poly_normals; } float(*poly_normals)[3]; @@ -441,7 +441,7 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3] void BKE_mesh_ensure_normals_for_display(Mesh *mesh) { - switch ((eMeshWrapperType)mesh->runtime.wrapper_type) { + switch (mesh->runtime->wrapper_type) { case ME_WRAPPER_TYPE_SUBD: case ME_WRAPPER_TYPE_MDATA: BKE_mesh_vertex_normals_ensure(mesh); @@ -449,7 +449,7 @@ void BKE_mesh_ensure_normals_for_display(Mesh *mesh) break; case ME_WRAPPER_TYPE_BMESH: { struct BMEditMesh *em = mesh->edit_mesh; - EditMeshData *emd = mesh->runtime.edit_data; + EditMeshData *emd = mesh->runtime->edit_data; if (emd->vertexCos) { BKE_editmesh_cache_ensure_vert_normals(em, emd); BKE_editmesh_cache_ensure_poly_normals(em, emd); diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index cb05d33bc2e..90798ea593d 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -1529,7 +1529,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, BLI_bitmap *looptri_active; looptri_src = BKE_mesh_runtime_looptri_ensure(me_src); - num_looptri_src = me_src->runtime.looptris.len; + num_looptri_src = BKE_mesh_runtime_looptri_len(me_src); looptri_active = BLI_BITMAP_NEW((size_t)num_looptri_src, __func__); for (tindex = 0; tindex < num_trees; tindex++) { diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index bd9f8242274..100b4de9045 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -17,6 +17,7 @@ #include "BLI_task.hh" #include "BKE_bvhutils.h" +#include "BKE_editmesh_cache.h" #include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" @@ -30,81 +31,50 @@ using blender::Span; /** \name Mesh Runtime Struct Utils * \{ */ -/** - * \brief Initialize the runtime mutexes of the given mesh. - * - * Any existing mutexes will be overridden. - */ -static void mesh_runtime_init_mutexes(Mesh *mesh) +void BKE_mesh_runtime_free_data(Mesh *mesh) { - mesh->runtime.eval_mutex = MEM_new("mesh runtime eval_mutex"); - BLI_mutex_init(static_cast(mesh->runtime.eval_mutex)); - mesh->runtime.normals_mutex = MEM_new("mesh runtime normals_mutex"); - BLI_mutex_init(static_cast(mesh->runtime.normals_mutex)); - mesh->runtime.render_mutex = MEM_new("mesh runtime render_mutex"); - BLI_mutex_init(static_cast(mesh->runtime.render_mutex)); + BKE_mesh_runtime_clear_cache(mesh); } -/** - * \brief free the mutexes of the given mesh runtime. - */ -static void mesh_runtime_free_mutexes(Mesh *mesh) -{ - if (mesh->runtime.eval_mutex != nullptr) { - BLI_mutex_end(static_cast(mesh->runtime.eval_mutex)); - MEM_freeN(mesh->runtime.eval_mutex); - mesh->runtime.eval_mutex = nullptr; - } - if (mesh->runtime.normals_mutex != nullptr) { - BLI_mutex_end(static_cast(mesh->runtime.normals_mutex)); - MEM_freeN(mesh->runtime.normals_mutex); - mesh->runtime.normals_mutex = nullptr; - } - if (mesh->runtime.render_mutex != nullptr) { - BLI_mutex_end(static_cast(mesh->runtime.render_mutex)); - MEM_freeN(mesh->runtime.render_mutex); - mesh->runtime.render_mutex = nullptr; - } -} +namespace blender::bke { -void BKE_mesh_runtime_init_data(Mesh *mesh) +MeshRuntime::MeshRuntime() { - mesh_runtime_init_mutexes(mesh); + this->eval_mutex = MEM_new("mesh runtime eval_mutex"); + BLI_mutex_init(static_cast(this->eval_mutex)); + this->normals_mutex = MEM_new("mesh runtime normals_mutex"); + BLI_mutex_init(static_cast(this->normals_mutex)); + this->render_mutex = MEM_new("mesh runtime render_mutex"); + BLI_mutex_init(static_cast(this->render_mutex)); } -void BKE_mesh_runtime_free_data(Mesh *mesh) +MeshRuntime::~MeshRuntime() { - BKE_mesh_runtime_clear_cache(mesh); - mesh_runtime_free_mutexes(mesh); + if (this->eval_mutex != nullptr) { + BLI_mutex_end(static_cast(this->eval_mutex)); + MEM_freeN(this->eval_mutex); + this->eval_mutex = nullptr; + } + if (this->normals_mutex != nullptr) { + BLI_mutex_end(static_cast(this->normals_mutex)); + MEM_freeN(this->normals_mutex); + this->normals_mutex = nullptr; + } + if (this->render_mutex != nullptr) { + BLI_mutex_end(static_cast(this->render_mutex)); + MEM_freeN(this->render_mutex); + this->render_mutex = nullptr; + } } -void BKE_mesh_runtime_reset_on_copy(Mesh *mesh, const int /*flag*/) -{ - Mesh_Runtime *runtime = &mesh->runtime; - - runtime->mesh_eval = nullptr; - runtime->edit_data = nullptr; - runtime->batch_cache = nullptr; - runtime->subdiv_ccg = nullptr; - runtime->looptris = blender::dna::shallow_zero_initialize(); - runtime->bvh_cache = nullptr; - runtime->shrinkwrap_data = nullptr; - runtime->subsurf_face_dot_tags = nullptr; - - runtime->vert_normals_dirty = true; - runtime->poly_normals_dirty = true; - runtime->vert_normals = nullptr; - runtime->poly_normals = nullptr; - - mesh_runtime_init_mutexes(mesh); -} +} // namespace blender::bke void BKE_mesh_runtime_clear_cache(Mesh *mesh) { - if (mesh->runtime.mesh_eval != nullptr) { - mesh->runtime.mesh_eval->edit_mesh = nullptr; - BKE_id_free(nullptr, mesh->runtime.mesh_eval); - mesh->runtime.mesh_eval = nullptr; + if (mesh->runtime->mesh_eval != nullptr) { + mesh->runtime->mesh_eval->edit_mesh = nullptr; + BKE_id_free(nullptr, mesh->runtime->mesh_eval); + mesh->runtime->mesh_eval = nullptr; } BKE_mesh_runtime_clear_geometry(mesh); BKE_mesh_batch_cache_free(mesh); @@ -131,32 +101,32 @@ static void mesh_ensure_looptri_data(Mesh *mesh) const uint totpoly = mesh->totpoly; const int looptris_len = poly_to_tri_count(totpoly, mesh->totloop); - BLI_assert(mesh->runtime.looptris.array_wip == nullptr); + BLI_assert(mesh->runtime->looptris.array_wip == nullptr); - SWAP(MLoopTri *, mesh->runtime.looptris.array, mesh->runtime.looptris.array_wip); + SWAP(MLoopTri *, mesh->runtime->looptris.array, mesh->runtime->looptris.array_wip); - if ((looptris_len > mesh->runtime.looptris.len_alloc) || - (looptris_len < mesh->runtime.looptris.len_alloc * 2) || (totpoly == 0)) { - MEM_SAFE_FREE(mesh->runtime.looptris.array_wip); - mesh->runtime.looptris.len_alloc = 0; - mesh->runtime.looptris.len = 0; + if ((looptris_len > mesh->runtime->looptris.len_alloc) || + (looptris_len < mesh->runtime->looptris.len_alloc * 2) || (totpoly == 0)) { + MEM_SAFE_FREE(mesh->runtime->looptris.array_wip); + mesh->runtime->looptris.len_alloc = 0; + mesh->runtime->looptris.len = 0; } if (totpoly) { - if (mesh->runtime.looptris.array_wip == nullptr) { - mesh->runtime.looptris.array_wip = static_cast( - MEM_malloc_arrayN(looptris_len, sizeof(*mesh->runtime.looptris.array_wip), __func__)); - mesh->runtime.looptris.len_alloc = looptris_len; + if (mesh->runtime->looptris.array_wip == nullptr) { + mesh->runtime->looptris.array_wip = static_cast( + MEM_malloc_arrayN(looptris_len, sizeof(*mesh->runtime->looptris.array_wip), __func__)); + mesh->runtime->looptris.len_alloc = looptris_len; } - mesh->runtime.looptris.len = looptris_len; + mesh->runtime->looptris.len = looptris_len; } } void BKE_mesh_runtime_looptri_recalc(Mesh *mesh) { mesh_ensure_looptri_data(mesh); - BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != nullptr); + BLI_assert(mesh->totpoly == 0 || mesh->runtime->looptris.array_wip != nullptr); const Span verts = mesh->verts(); const Span polys = mesh->polys(); const Span loops = mesh->loops(); @@ -167,7 +137,7 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh) verts.data(), mesh->totloop, mesh->totpoly, - mesh->runtime.looptris.array_wip, + mesh->runtime->looptris.array_wip, BKE_mesh_poly_normals_ensure(mesh)); } else { @@ -176,39 +146,39 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh) verts.data(), mesh->totloop, mesh->totpoly, - mesh->runtime.looptris.array_wip); + mesh->runtime->looptris.array_wip); } - BLI_assert(mesh->runtime.looptris.array == nullptr); - atomic_cas_ptr((void **)&mesh->runtime.looptris.array, - mesh->runtime.looptris.array, - mesh->runtime.looptris.array_wip); - mesh->runtime.looptris.array_wip = nullptr; + BLI_assert(mesh->runtime->looptris.array == nullptr); + atomic_cas_ptr((void **)&mesh->runtime->looptris.array, + mesh->runtime->looptris.array, + mesh->runtime->looptris.array_wip); + mesh->runtime->looptris.array_wip = nullptr; } int BKE_mesh_runtime_looptri_len(const Mesh *mesh) { /* This is a ported copy of `dm_getNumLoopTri(dm)`. */ const int looptri_len = poly_to_tri_count(mesh->totpoly, mesh->totloop); - BLI_assert(ELEM(mesh->runtime.looptris.len, 0, looptri_len)); + BLI_assert(ELEM(mesh->runtime->looptris.len, 0, looptri_len)); return looptri_len; } const MLoopTri *BKE_mesh_runtime_looptri_ensure(const Mesh *mesh) { - ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime.eval_mutex; + ThreadMutex *mesh_eval_mutex = (ThreadMutex *)mesh->runtime->eval_mutex; BLI_mutex_lock(mesh_eval_mutex); - MLoopTri *looptri = mesh->runtime.looptris.array; + MLoopTri *looptri = mesh->runtime->looptris.array; if (looptri != nullptr) { - BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime.looptris.len); + BLI_assert(BKE_mesh_runtime_looptri_len(mesh) == mesh->runtime->looptris.len); } else { /* Must isolate multithreaded tasks while holding a mutex lock. */ blender::threading::isolate_task( [&]() { BKE_mesh_runtime_looptri_recalc(const_cast(mesh)); }); - looptri = mesh->runtime.looptris.array; + looptri = mesh->runtime->looptris.array; } BLI_mutex_unlock(mesh_eval_mutex); @@ -230,17 +200,17 @@ void BKE_mesh_runtime_verttri_from_looptri(MVertTri *r_verttri, bool BKE_mesh_runtime_ensure_edit_data(struct Mesh *mesh) { - if (mesh->runtime.edit_data != nullptr) { + if (mesh->runtime->edit_data != nullptr) { return false; } - mesh->runtime.edit_data = MEM_cnew(__func__); + mesh->runtime->edit_data = MEM_cnew(__func__); return true; } bool BKE_mesh_runtime_reset_edit_data(Mesh *mesh) { - EditMeshData *edit_data = mesh->runtime.edit_data; + EditMeshData *edit_data = mesh->runtime->edit_data; if (edit_data == nullptr) { return false; } @@ -255,13 +225,13 @@ bool BKE_mesh_runtime_reset_edit_data(Mesh *mesh) bool BKE_mesh_runtime_clear_edit_data(Mesh *mesh) { - if (mesh->runtime.edit_data == nullptr) { + if (mesh->runtime->edit_data == nullptr) { return false; } BKE_mesh_runtime_reset_edit_data(mesh); - MEM_freeN(mesh->runtime.edit_data); - mesh->runtime.edit_data = nullptr; + MEM_freeN(mesh->runtime->edit_data); + mesh->runtime->edit_data = nullptr; return true; } @@ -271,22 +241,22 @@ void BKE_mesh_runtime_clear_geometry(Mesh *mesh) BKE_mesh_tag_coords_changed(mesh); /* TODO(sergey): Does this really belong here? */ - if (mesh->runtime.subdiv_ccg != nullptr) { - BKE_subdiv_ccg_destroy(mesh->runtime.subdiv_ccg); - mesh->runtime.subdiv_ccg = nullptr; + if (mesh->runtime->subdiv_ccg != nullptr) { + BKE_subdiv_ccg_destroy(mesh->runtime->subdiv_ccg); + mesh->runtime->subdiv_ccg = nullptr; } BKE_shrinkwrap_discard_boundary_data(mesh); - MEM_SAFE_FREE(mesh->runtime.subsurf_face_dot_tags); + MEM_SAFE_FREE(mesh->runtime->subsurf_face_dot_tags); } void BKE_mesh_tag_coords_changed(Mesh *mesh) { BKE_mesh_normals_tag_dirty(mesh); - MEM_SAFE_FREE(mesh->runtime.looptris.array); - if (mesh->runtime.bvh_cache) { - bvhcache_free(mesh->runtime.bvh_cache); - mesh->runtime.bvh_cache = nullptr; + MEM_SAFE_FREE(mesh->runtime->looptris.array); + if (mesh->runtime->bvh_cache) { + bvhcache_free(mesh->runtime->bvh_cache); + mesh->runtime->bvh_cache = nullptr; } } @@ -305,6 +275,16 @@ void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh) } } +bool BKE_mesh_is_deformed_only(const Mesh *mesh) +{ + return mesh->runtime->deformed_only; +} + +eMeshWrapperType BKE_mesh_wrapper_type(const struct Mesh *mesh) +{ + return mesh->runtime->wrapper_type; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -317,13 +297,13 @@ void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = nullptr; void BKE_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode) { - if (me->runtime.batch_cache) { + if (me->runtime->batch_cache) { BKE_mesh_batch_cache_dirty_tag_cb(me, mode); } } void BKE_mesh_batch_cache_free(Mesh *me) { - if (me->runtime.batch_cache) { + if (me->runtime->batch_cache) { BKE_mesh_batch_cache_free_cb(me); } } diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 1162986aaf5..49ea23a1552 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -570,8 +570,6 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, const char (*tangent_names)[MAX_NAME], int tangent_names_len) { - BKE_mesh_runtime_looptri_ensure(me_eval); - /* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */ short tangent_mask = 0; BKE_mesh_calc_loop_tangent_ex( @@ -579,8 +577,8 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, BKE_mesh_polys(me_eval), uint(me_eval->totpoly), BKE_mesh_loops(me_eval), - me_eval->runtime.looptris.array, - uint(me_eval->runtime.looptris.len), + BKE_mesh_runtime_looptri_ensure(me_eval), + uint(BKE_mesh_runtime_looptri_len(me_eval)), &me_eval->ldata, calc_active_tangent, tangent_names, diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 101fad2fce8..db15789e847 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -57,13 +57,13 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em, BKE_mesh_copy_parameters_for_eval(me, me_settings); BKE_mesh_runtime_ensure_edit_data(me); - me->runtime.wrapper_type = ME_WRAPPER_TYPE_BMESH; + me->runtime->wrapper_type = ME_WRAPPER_TYPE_BMESH; if (cd_mask_extra) { - me->runtime.cd_mask_extra = *cd_mask_extra; + me->runtime->cd_mask_extra = *cd_mask_extra; } /* Use edit-mesh directly where possible. */ - me->runtime.is_original_bmesh = true; + me->runtime->is_original_bmesh = true; me->edit_mesh = static_cast(MEM_dupallocN(em)); me->edit_mesh->is_shallow_copy = true; @@ -81,7 +81,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em, me->totloop = 0; #endif - EditMeshData *edit_data = me->runtime.edit_data; + EditMeshData *edit_data = me->runtime->edit_data; edit_data->vertexCos = vert_coords; return me; } @@ -95,17 +95,17 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em, void BKE_mesh_wrapper_ensure_mdata(Mesh *me) { - ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex; + ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime->eval_mutex; BLI_mutex_lock(mesh_eval_mutex); - if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) { + if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) { BLI_mutex_unlock(mesh_eval_mutex); return; } /* Must isolate multithreaded tasks while holding a mutex lock. */ blender::threading::isolate_task([&]() { - switch (static_cast(me->runtime.wrapper_type)) { + switch (static_cast(me->runtime->wrapper_type)) { case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: { break; /* Quiet warning. */ @@ -117,10 +117,10 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me) me->totloop = 0; BLI_assert(me->edit_mesh != nullptr); - BLI_assert(me->runtime.edit_data != nullptr); + BLI_assert(me->runtime->edit_data != nullptr); BMEditMesh *em = me->edit_mesh; - BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime.cd_mask_extra); + BM_mesh_bm_to_me_for_eval(em->bm, me, &me->runtime->cd_mask_extra); /* Adding original index layers assumes that all BMesh mesh wrappers are created from * original edit mode meshes (the only case where adding original indices makes sense). @@ -132,22 +132,22 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me) * harmful. */ BKE_mesh_ensure_default_orig_index_customdata_no_check(me); - EditMeshData *edit_data = me->runtime.edit_data; + EditMeshData *edit_data = me->runtime->edit_data; if (edit_data->vertexCos) { BKE_mesh_vert_coords_apply(me, edit_data->vertexCos); - me->runtime.is_original_bmesh = false; + me->runtime->is_original_bmesh = false; } break; } } - if (me->runtime.wrapper_type_finalize) { - BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime.cd_mask_extra); + if (me->runtime->wrapper_type_finalize) { + BKE_mesh_wrapper_deferred_finalize_mdata(me, &me->runtime->cd_mask_extra); } /* Keep type assignment last, so that read-only access only uses the mdata code paths after all * the underlying data has been initialized. */ - me->runtime.wrapper_type = ME_WRAPPER_TYPE_MDATA; + me->runtime->wrapper_type = ME_WRAPPER_TYPE_MDATA; }); BLI_mutex_unlock(mesh_eval_mutex); @@ -155,9 +155,9 @@ void BKE_mesh_wrapper_ensure_mdata(Mesh *me) bool BKE_mesh_wrapper_minmax(const Mesh *me, float min[3], float max[3]) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: - return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime.edit_data, min, max); + return BKE_editmesh_cache_calc_minmax(me->edit_mesh, me->runtime->edit_data, min, max); case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: return BKE_mesh_minmax(me, min, max); @@ -174,11 +174,11 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, float (*vert_coords)[3], int vert_coords_len) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: { BMesh *bm = me->edit_mesh->bm; BLI_assert(vert_coords_len <= bm->totvert); - EditMeshData *edit_data = me->runtime.edit_data; + EditMeshData *edit_data = me->runtime->edit_data; if (edit_data->vertexCos != nullptr) { for (int i = 0; i < vert_coords_len; i++) { copy_v3_v3(vert_coords[i], edit_data->vertexCos[i]); @@ -212,11 +212,11 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, int vert_coords_len, const float mat[4][4]) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: { BMesh *bm = me->edit_mesh->bm; BLI_assert(vert_coords_len == bm->totvert); - EditMeshData *edit_data = me->runtime.edit_data; + EditMeshData *edit_data = me->runtime->edit_data; if (edit_data->vertexCos != nullptr) { for (int i = 0; i < vert_coords_len; i++) { mul_v3_m4v3(vert_coords[i], mat, edit_data->vertexCos[i]); @@ -253,7 +253,7 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, int BKE_mesh_wrapper_vert_len(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: return me->edit_mesh->bm->totvert; case ME_WRAPPER_TYPE_MDATA: @@ -266,7 +266,7 @@ int BKE_mesh_wrapper_vert_len(const Mesh *me) int BKE_mesh_wrapper_edge_len(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: return me->edit_mesh->bm->totedge; case ME_WRAPPER_TYPE_MDATA: @@ -279,7 +279,7 @@ int BKE_mesh_wrapper_edge_len(const Mesh *me) int BKE_mesh_wrapper_loop_len(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: return me->edit_mesh->bm->totloop; case ME_WRAPPER_TYPE_MDATA: @@ -292,7 +292,7 @@ int BKE_mesh_wrapper_loop_len(const Mesh *me) int BKE_mesh_wrapper_poly_len(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: return me->edit_mesh->bm->totface; case ME_WRAPPER_TYPE_MDATA: @@ -311,7 +311,7 @@ int BKE_mesh_wrapper_poly_len(const Mesh *me) static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me) { - SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)me->runtime.subsurf_runtime_data; + SubsurfRuntimeData *runtime_data = (SubsurfRuntimeData *)me->runtime->subsurf_runtime_data; if (runtime_data == nullptr || runtime_data->settings.level == 0) { return me; } @@ -359,24 +359,24 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me) } if (subdiv_mesh != me) { - if (me->runtime.mesh_eval != nullptr) { - BKE_id_free(nullptr, me->runtime.mesh_eval); + if (me->runtime->mesh_eval != nullptr) { + BKE_id_free(nullptr, me->runtime->mesh_eval); } - me->runtime.mesh_eval = subdiv_mesh; - me->runtime.wrapper_type = ME_WRAPPER_TYPE_SUBD; + me->runtime->mesh_eval = subdiv_mesh; + me->runtime->wrapper_type = ME_WRAPPER_TYPE_SUBD; } - return me->runtime.mesh_eval; + return me->runtime->mesh_eval; } Mesh *BKE_mesh_wrapper_ensure_subdivision(Mesh *me) { - ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime.eval_mutex; + ThreadMutex *mesh_eval_mutex = (ThreadMutex *)me->runtime->eval_mutex; BLI_mutex_lock(mesh_eval_mutex); - if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_SUBD) { + if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_SUBD) { BLI_mutex_unlock(mesh_eval_mutex); - return me->runtime.mesh_eval; + return me->runtime->mesh_eval; } Mesh *result; diff --git a/source/blender/blenkernel/intern/modifier.cc b/source/blender/blenkernel/intern/modifier.cc index 2eb8ef70a4d..fc1a0f47684 100644 --- a/source/blender/blenkernel/intern/modifier.cc +++ b/source/blender/blenkernel/intern/modifier.cc @@ -963,9 +963,9 @@ void BKE_modifier_path_init(char *path, int path_maxlen, const char *name) */ static void modwrap_dependsOnNormals(Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: { - EditMeshData *edit_data = me->runtime.edit_data; + EditMeshData *edit_data = me->runtime->edit_data; if (edit_data->vertexCos) { /* Note that 'ensure' is acceptable here since these values aren't modified in-place. * If that changes we'll need to recalculate. */ @@ -993,7 +993,7 @@ struct Mesh *BKE_modifier_modify_mesh(ModifierData *md, { const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type)); - if (me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { if ((mti->flags & eModifierTypeFlag_AcceptsBMesh) == 0) { BKE_mesh_wrapper_ensure_mdata(me); } diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 61cfe043927..5ff9602650e 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -397,7 +397,7 @@ void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresMod * In a longer term maybe special dependency graph tag can help sanitizing this a bit. */ Object *object_eval = DEG_get_evaluated_object(depsgraph, object); Mesh *mesh = static_cast(object_eval->data); - SubdivCCG *subdiv_ccg = mesh->runtime.subdiv_ccg; + SubdivCCG *subdiv_ccg = mesh->runtime->subdiv_ccg; if (subdiv_ccg == nullptr) { return; } diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 9417d1afc7e..2d949fb5c65 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1691,7 +1691,7 @@ static void object_update_from_subsurf_ccg(Object *object) if (mesh_eval == nullptr) { return; } - SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg; + SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg; if (subdiv_ccg == nullptr) { return; } @@ -1699,7 +1699,7 @@ static void object_update_from_subsurf_ccg(Object *object) if (!subdiv_ccg->dirty.coords && !subdiv_ccg->dirty.hidden) { return; } - const int tot_level = mesh_eval->runtime.subdiv_ccg_tot_level; + const int tot_level = mesh_eval->runtime->subdiv_ccg_tot_level; Object *object_orig = DEG_get_original_object(object); Mesh *mesh_orig = (Mesh *)object_orig->data; multiresModifier_reshapeFromCCG(tot_level, mesh_orig, subdiv_ccg); @@ -3218,7 +3218,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) int count = 0; int numVerts = me_eval->totvert; - if (em && me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (em && me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { numVerts = em->bm->totvert; if (em->bm->elem_table_dirty & BM_VERT) { #ifdef VPARENT_THREADING_HACK @@ -3233,8 +3233,8 @@ static void give_parvert(Object *par, int nr, float vec[3]) #endif } if (nr < numVerts) { - if (me_eval && me_eval->runtime.edit_data && me_eval->runtime.edit_data->vertexCos) { - add_v3_v3(vec, me_eval->runtime.edit_data->vertexCos[nr]); + if (me_eval && me_eval->runtime->edit_data && me_eval->runtime->edit_data->vertexCos) { + add_v3_v3(vec, me_eval->runtime->edit_data->vertexCos[nr]); } else { const BMVert *v = BM_vert_at_index(em->bm, nr); diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 306e508dc83..96da99af97e 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -423,8 +423,8 @@ static const Mesh *mesh_data_from_duplicator_object(Object *ob, /* Note that this will only show deformation if #eModifierMode_OnCage is enabled. * We could change this but it matches 2.7x behavior. */ me_eval = BKE_object_get_editmesh_eval_cage(ob); - if ((me_eval == nullptr) || (me_eval->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH)) { - EditMeshData *emd = me_eval ? me_eval->runtime.edit_data : nullptr; + if ((me_eval == nullptr) || (me_eval->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH)) { + EditMeshData *emd = me_eval ? me_eval->runtime->edit_data : nullptr; /* Only assign edit-mesh in the case we can't use `me_eval`. */ *r_em = em; diff --git a/source/blender/blenkernel/intern/object_update.cc b/source/blender/blenkernel/intern/object_update.cc index 5328d956cee..f6a765e8809 100644 --- a/source/blender/blenkernel/intern/object_update.cc +++ b/source/blender/blenkernel/intern/object_update.cc @@ -373,7 +373,7 @@ void BKE_object_select_update(Depsgraph *depsgraph, Object *object) DEG_debug_print_eval(depsgraph, __func__, object->id.name, object); if (object->type == OB_MESH && !object->runtime.is_data_eval_owned) { Mesh *mesh_input = (Mesh *)object->runtime.data_orig; - Mesh_Runtime *mesh_runtime = &mesh_input->runtime; + blender::bke::MeshRuntime *mesh_runtime = mesh_input->runtime; BLI_mutex_lock(static_cast(mesh_runtime->eval_mutex)); BKE_object_data_select_update(depsgraph, static_cast(object->data)); BLI_mutex_unlock(static_cast(mesh_runtime->eval_mutex)); diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index fbb7642c067..d45ce776b64 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1743,7 +1743,7 @@ static void sculpt_update_object( ss->hide_poly = (bool *)CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly"); - ss->subdiv_ccg = me_eval->runtime.subdiv_ccg; + ss->subdiv_ccg = me_eval->runtime->subdiv_ccg; PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(depsgraph, ob); BLI_assert(pbvh == ss->pbvh); @@ -2258,7 +2258,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob) if (BKE_pbvh_type(pbvh) == PBVH_GRIDS) { Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *mesh_eval = static_cast(object_eval->data); - SubdivCCG *subdiv_ccg = mesh_eval->runtime.subdiv_ccg; + SubdivCCG *subdiv_ccg = mesh_eval->runtime->subdiv_ccg; if (subdiv_ccg != nullptr) { BKE_sculpt_bvh_update_from_ccg(pbvh, subdiv_ccg); } @@ -2277,8 +2277,8 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob) else { Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); Mesh *mesh_eval = static_cast(object_eval->data); - if (mesh_eval->runtime.subdiv_ccg != nullptr) { - pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime.subdiv_ccg, respect_hide); + if (mesh_eval->runtime->subdiv_ccg != nullptr) { + pbvh = build_pbvh_from_ccg(ob, mesh_eval->runtime->subdiv_ccg, respect_hide); } else if (ob->type == OB_MESH) { Mesh *me_eval_deform = object_eval->runtime.mesh_deform_eval; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 6d42d344b86..d6dd3cf0dbb 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -60,6 +60,7 @@ #include "BKE_material.h" #include "BKE_mesh.h" #include "BKE_mesh_legacy_convert.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_particle.h" @@ -1933,7 +1934,7 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX); } else { - BLI_assert(mesh_final->runtime.deformed_only); + BLI_assert(BKE_mesh_is_deformed_only(mesh_final)); index_mf_to_mpoly_deformed = index_mf_to_mpoly; } BLI_assert(index_mf_to_mpoly_deformed); @@ -2023,7 +2024,7 @@ static int psys_map_index_on_dm(Mesh *mesh, return 0; } - if (mesh->runtime.deformed_only || index_dmcache == DMCACHE_ISCHILD) { + if (BKE_mesh_is_deformed_only(mesh) || index_dmcache == DMCACHE_ISCHILD) { /* for meshes that are either only deformed or for child particles, the * index and fw do not require any mapping, so we can directly use it */ if (from == PART_FROM_VERT) { diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 4c56a8a9275..0301b83a043 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -29,6 +29,7 @@ #include "BKE_lib_id.h" #include "BKE_mesh.h" #include "BKE_mesh_legacy_convert.h" +#include "BKE_mesh_runtime.h" #include "BKE_object.h" #include "BKE_particle.h" @@ -899,7 +900,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, return 0; } - if (!final_mesh->runtime.deformed_only && + if (!BKE_mesh_is_deformed_only(final_mesh) && !CustomData_get_layer(&final_mesh->fdata, CD_ORIGINDEX)) { printf( "Can't create particles with the current modifier stack, disable destructive modifiers\n"); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index dec874caff4..c72bbe2fd08 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -48,6 +48,7 @@ #include "BKE_lib_id.h" #include "BKE_lib_query.h" #include "BKE_mesh_legacy_convert.h" +#include "BKE_mesh_runtime.h" #include "BKE_particle.h" #include "BKE_bvhutils.h" @@ -319,7 +320,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_original, Partic PARTICLE_P; /* CACHE LOCATIONS */ - if (!mesh_final->runtime.deformed_only) { + if (!BKE_mesh_is_deformed_only(mesh_final)) { /* Will use later to speed up subsurf/evaluated mesh. */ LinkNode *node, *nodedmelem, **nodearray; int totdmelem, totelem, i; diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 6b4cddb05f2..ffc6bc8d7a3 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -404,7 +404,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) const MVert *mvert = BKE_mesh_verts(mesh); totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); - tottri = mesh->runtime.looptris.len; + tottri = BKE_mesh_runtime_looptri_len(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); /* sanity checking - potential case when no data will be present */ @@ -679,7 +679,7 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) const MVert *mvert = BKE_mesh_verts(mesh); totvert = mesh->totvert; lt = BKE_mesh_runtime_looptri_ensure(mesh); - tottri = mesh->runtime.looptris.len; + tottri = BKE_mesh_runtime_looptri_len(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { @@ -753,7 +753,7 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) const MVert *mvert = BKE_mesh_verts(mesh); totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); - tottri = mesh->runtime.looptris.len; + tottri = BKE_mesh_runtime_looptri_len(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index 703b012d170..65226a5db9d 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -140,7 +140,7 @@ bool BKE_shrinkwrap_init_tree( } if (shrinkType == MOD_SHRINKWRAP_TARGET_PROJECT) { - data->boundary = mesh->runtime.shrinkwrap_data; + data->boundary = mesh->runtime->shrinkwrap_data; } return true; @@ -153,7 +153,7 @@ void BKE_shrinkwrap_free_tree(ShrinkwrapTreeData *data) void BKE_shrinkwrap_discard_boundary_data(Mesh *mesh) { - ShrinkwrapBoundaryData *data = mesh->runtime.shrinkwrap_data; + ShrinkwrapBoundaryData *data = mesh->runtime->shrinkwrap_data; if (data != nullptr) { MEM_freeN((void *)data->edge_is_boundary); @@ -164,7 +164,7 @@ void BKE_shrinkwrap_discard_boundary_data(Mesh *mesh) MEM_freeN(data); } - mesh->runtime.shrinkwrap_data = nullptr; + mesh->runtime->shrinkwrap_data = nullptr; } /* Accumulate edge for average boundary edge direction. */ @@ -327,7 +327,7 @@ void BKE_shrinkwrap_compute_boundary_data(Mesh *mesh) { BKE_shrinkwrap_discard_boundary_data(mesh); - mesh->runtime.shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); + mesh->runtime->shrinkwrap_data = shrinkwrap_build_boundary_data(mesh); } /** diff --git a/source/blender/blenkernel/intern/subdiv_ccg.cc b/source/blender/blenkernel/intern/subdiv_ccg.cc index 8ccf2c9cec5..bf09be444b1 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.cc +++ b/source/blender/blenkernel/intern/subdiv_ccg.cc @@ -615,7 +615,7 @@ Mesh *BKE_subdiv_to_ccg_mesh(Subdiv *subdiv, return nullptr; } Mesh *result = BKE_mesh_new_nomain_from_template(coarse_mesh, 0, 0, 0, 0, 0); - result->runtime.subdiv_ccg = subdiv_ccg; + result->runtime->subdiv_ccg = subdiv_ccg; return result; } diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index 00183ea90c2..3b97c1f5e68 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -528,9 +528,9 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex subdiv_context->coarse_mesh, num_vertices, num_edges, 0, num_loops, num_polygons, mask); subdiv_mesh_ctx_cache_custom_data_layers(subdiv_context); subdiv_mesh_prepare_accumulator(subdiv_context, num_vertices); - MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags); - subdiv_context->subdiv_mesh->runtime.subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices, - __func__); + MEM_SAFE_FREE(subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags); + subdiv_context->subdiv_mesh->runtime->subsurf_face_dot_tags = BLI_BITMAP_NEW(num_vertices, + __func__); return true; } @@ -595,7 +595,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext /* Evaluate undeformed texture coordinate. */ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index); /* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */ - BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index); + BLI_BITMAP_DISABLE(ctx->subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index); } static void evaluate_vertex_and_apply_displacement_interpolate( @@ -753,7 +753,7 @@ static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly, Mesh *subdiv_mesh) { if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) { - BLI_BITMAP_ENABLE(subdiv_mesh->runtime.subsurf_face_dot_tags, subdiv_vertex_index); + BLI_BITMAP_ENABLE(subdiv_mesh->runtime->subsurf_face_dot_tags, subdiv_vertex_index); } } diff --git a/source/blender/blenkernel/intern/subdiv_modifier.cc b/source/blender/blenkernel/intern/subdiv_modifier.cc index a5529e9b8fa..84b772db045 100644 --- a/source/blender/blenkernel/intern/subdiv_modifier.cc +++ b/source/blender/blenkernel/intern/subdiv_modifier.cc @@ -11,6 +11,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_subdiv.h" @@ -143,7 +144,7 @@ bool BKE_subsurf_modifier_can_do_gpu_subdiv(const Scene *scene, bool BKE_subsurf_modifier_has_gpu_subdiv(const Mesh *mesh) { - SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data; + SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data; return runtime_data && runtime_data->has_gpu_subdiv; } diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index dfbdd64ee7c..82d707c7e54 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -1238,7 +1238,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * * different than the BMesh's. */ BKE_mesh_clear_derived_normals(me); - me->runtime.deformed_only = true; + me->runtime->deformed_only = true; bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write(); diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 36a980bd506..fecdad5802c 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -14,6 +14,7 @@ #include "BLI_alloca.h" #include "BKE_editmesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_paint.h" @@ -231,7 +232,7 @@ static void workbench_cache_hair_populate(WORKBENCH_PrivateData *wpd, static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh) { - if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_BMESH) { BLI_assert(mesh->edit_mesh != NULL); BLI_assert(mesh->edit_mesh->bm != NULL); return &mesh->edit_mesh->bm->ldata; @@ -241,7 +242,7 @@ static const CustomData *workbench_mesh_get_loop_custom_data(const Mesh *mesh) static const CustomData *workbench_mesh_get_vert_custom_data(const Mesh *mesh) { - if (mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_BMESH) { BLI_assert(mesh->edit_mesh != NULL); BLI_assert(mesh->edit_mesh->bm != NULL); return &mesh->edit_mesh->bm->vdata; diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index d3170f4c776..f533904f355 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -686,7 +686,7 @@ void mesh_buffer_cache_create_requested(struct TaskGraph *task_graph, MeshRenderData *mr = mesh_render_data_create( object, me, is_editmode, is_paint_mode, is_mode_active, obmat, do_final, do_uvedit, ts); mr->use_hide = use_hide; - mr->use_subsurf_fdots = mr->me && mr->me->runtime.subsurf_face_dot_tags != nullptr; + mr->use_subsurf_fdots = mr->me && mr->me->runtime->subsurf_face_dot_tags != nullptr; mr->use_final_mesh = do_final; #ifdef DEBUG_TIME 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 f554e9e67c3..f606701ed09 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 @@ -463,7 +463,7 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->bm = me->edit_mesh->bm; mr->edit_bmesh = me->edit_mesh; mr->me = (do_final) ? editmesh_eval_final : editmesh_eval_cage; - mr->edit_data = is_mode_active ? mr->me->runtime.edit_data : nullptr; + mr->edit_data = is_mode_active ? mr->me->runtime->edit_data : nullptr; if (mr->edit_data) { EditMeshData *emd = mr->edit_data; @@ -499,8 +499,8 @@ MeshRenderData *mesh_render_data_create(Object *object, /* Use bmesh directly when the object is in edit mode unchanged by any modifiers. * For non-final UVs, always use original bmesh since the UV editor does not support * using the cage mesh with deformed coordinates. */ - if ((is_mode_active && mr->me->runtime.is_original_bmesh && - mr->me->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) || + if ((is_mode_active && mr->me->runtime->is_original_bmesh && + mr->me->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) || (do_uvedit && !do_final)) { mr->extract_type = MR_EXTRACT_BMESH; } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 5a041493a6a..423d1968eed 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -554,7 +554,7 @@ BLI_INLINE void mesh_batch_cache_add_request(MeshBatchCache *cache, DRWBatchFlag static bool mesh_batch_cache_valid(Object *object, Mesh *me) { - MeshBatchCache *cache = static_cast(me->runtime.batch_cache); + MeshBatchCache *cache = static_cast(me->runtime->batch_cache); if (cache == nullptr) { return false; @@ -588,11 +588,11 @@ static bool mesh_batch_cache_valid(Object *object, Mesh *me) static void mesh_batch_cache_init(Object *object, Mesh *me) { - MeshBatchCache *cache = static_cast(me->runtime.batch_cache); + MeshBatchCache *cache = static_cast(me->runtime->batch_cache); if (!cache) { - me->runtime.batch_cache = MEM_cnew(__func__); - cache = static_cast(me->runtime.batch_cache); + me->runtime->batch_cache = MEM_cnew(__func__); + cache = static_cast(me->runtime->batch_cache); } else { memset(cache, 0, sizeof(*cache)); @@ -634,7 +634,7 @@ void DRW_mesh_batch_cache_validate(Object *object, Mesh *me) static MeshBatchCache *mesh_batch_cache_get(Mesh *me) { - return static_cast(me->runtime.batch_cache); + return static_cast(me->runtime->batch_cache); } static void mesh_batch_cache_check_vertex_group(MeshBatchCache *cache, @@ -742,7 +742,7 @@ static void mesh_batch_cache_discard_uvedit_select(MeshBatchCache *cache) void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode) { - MeshBatchCache *cache = static_cast(me->runtime.batch_cache); + MeshBatchCache *cache = static_cast(me->runtime->batch_cache); if (cache == nullptr) { return; } @@ -830,7 +830,7 @@ static void mesh_batch_cache_free_subdiv_cache(MeshBatchCache *cache) static void mesh_batch_cache_clear(Mesh *me) { - MeshBatchCache *cache = static_cast(me->runtime.batch_cache); + MeshBatchCache *cache = static_cast(me->runtime->batch_cache); if (!cache) { return; } @@ -862,7 +862,7 @@ static void mesh_batch_cache_clear(Mesh *me) void DRW_mesh_batch_cache_free(Mesh *me) { mesh_batch_cache_clear(me); - MEM_SAFE_FREE(me->runtime.batch_cache); + MEM_SAFE_FREE(me->runtime->batch_cache); } /** \} */ @@ -1017,7 +1017,7 @@ GPUBatch **DRW_mesh_batch_cache_get_surface_shaded(Object *object, BLI_assert(gpumat_array_len == cache->mat_len); mesh_cd_layers_type_merge(&cache->cd_needed, cd_needed); - ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex; + ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex; drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex); mesh_batch_cache_request_surface_batches(cache); return cache->surface_per_mat; @@ -1046,7 +1046,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_vertpaint(Object *object, Mesh *me) DRW_Attributes attrs_needed{}; request_active_and_default_color_attributes(*object, *me, attrs_needed); - ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex; + ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex; drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex); mesh_batch_cache_request_surface_batches(cache); @@ -1060,7 +1060,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_sculpt(Object *object, Mesh *me) DRW_Attributes attrs_needed{}; request_active_and_default_color_attributes(*object, *me, attrs_needed); - ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex; + ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex; drw_attributes_merge(&cache->attr_needed, &attrs_needed, mesh_render_mutex); mesh_batch_cache_request_surface_batches(cache); @@ -1300,7 +1300,7 @@ GPUBatch *DRW_mesh_batch_cache_get_surface_edges(Object *object, Mesh *me) void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime) { - MeshBatchCache *cache = static_cast(me->runtime.batch_cache); + MeshBatchCache *cache = static_cast(me->runtime->batch_cache); if (cache == nullptr) { return; @@ -1446,7 +1446,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, } } - ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime.render_mutex; + ThreadMutex *mesh_render_mutex = (ThreadMutex *)me->runtime->render_mutex; /* Verify that all surface batches have needed attribute layers. */ @@ -1537,7 +1537,7 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, const bool do_update_sculpt_normals = ob->sculpt && ob->sculpt->pbvh; if (do_update_sculpt_normals) { Mesh *mesh = static_cast(ob->data); - BKE_pbvh_update_normals(ob->sculpt->pbvh, mesh->runtime.subdiv_ccg); + BKE_pbvh_update_normals(ob->sculpt->pbvh, mesh->runtime->subdiv_ccg); } cache->batch_ready |= batch_requested; @@ -1548,8 +1548,8 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph, Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob); do_cage = editmesh_eval_final != editmesh_eval_cage; - do_uvcage = !(editmesh_eval_final->runtime.is_original_bmesh && - editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH); + do_uvcage = !(editmesh_eval_final->runtime->is_original_bmesh && + editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH); } const bool do_subdivision = BKE_subsurf_modifier_has_gpu_subdiv(me); diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 9f445be9750..6a9e6c126e9 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -2036,7 +2036,7 @@ static bool draw_subdiv_create_requested_buffers(Object *ob, const bool use_hide, OpenSubdiv_EvaluatorCache *evaluator_cache) { - SubsurfRuntimeData *runtime_data = mesh->runtime.subsurf_runtime_data; + SubsurfRuntimeData *runtime_data = mesh->runtime->subsurf_runtime_data; BLI_assert(runtime_data && runtime_data->has_gpu_subdiv); if (runtime_data->settings.level == 0) { diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index 7d55a11a00f..9768f1ce9e7 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1347,7 +1347,7 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd) } Mesh *mesh = static_cast(scd->ob->data); - BKE_pbvh_update_normals(pbvh, mesh->runtime.subdiv_ccg); + BKE_pbvh_update_normals(pbvh, mesh->runtime->subdiv_ccg); BKE_pbvh_draw_cb(pbvh, update_only_visible, diff --git a/source/blender/draw/intern/draw_manager_text.cc b/source/blender/draw/intern/draw_manager_text.cc index d41127c3641..100ef528bc8 100644 --- a/source/blender/draw/intern/draw_manager_text.cc +++ b/source/blender/draw/intern/draw_manager_text.cc @@ -15,6 +15,7 @@ #include "BKE_editmesh.h" #include "BKE_editmesh_cache.h" #include "BKE_global.h" +#include "BKE_mesh.h" #include "BKE_unit.h" #include "DNA_mesh_types.h" @@ -233,8 +234,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, float clip_planes[4][4]; /* allow for displaying shape keys and deform mods */ BMIter iter; - const float(*vert_coords)[3] = (me->runtime.edit_data ? me->runtime.edit_data->vertexCos : - nullptr); + const float(*vert_coords)[3] = (me->runtime->edit_data ? me->runtime->edit_data->vertexCos : + nullptr); const bool use_coords = (vert_coords != nullptr); /* when 2 or more edge-info options are enabled, space apart */ @@ -339,8 +340,8 @@ void DRW_text_edit_mesh_measure_stats(ARegion *region, const float(*poly_normals)[3] = nullptr; if (use_coords) { BM_mesh_elem_index_ensure(em->bm, BM_VERT | BM_FACE); - BKE_editmesh_cache_ensure_poly_normals(em, me->runtime.edit_data); - poly_normals = me->runtime.edit_data->polyNos; + BKE_editmesh_cache_ensure_poly_normals(em, me->runtime->edit_data); + poly_normals = me->runtime->edit_data->polyNos; } BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index d9bb8d1d2b4..c6230e2695e 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -16,6 +16,8 @@ #include "BKE_customdata.h" #include "BKE_editmesh.h" +#include "BKE_editmesh_cache.h" +#include "BKE_mesh.h" #include "draw_cache_extract.hh" @@ -116,7 +118,7 @@ BLI_INLINE const Mesh *editmesh_final_or_this(const Object *object, const Mesh * BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_SUBD: case ME_WRAPPER_TYPE_MDATA: return &me->ldata; @@ -132,7 +134,7 @@ BLI_INLINE const CustomData *mesh_cd_ldata_get_from_mesh(const Mesh *me) BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_SUBD: case ME_WRAPPER_TYPE_MDATA: return &me->pdata; @@ -148,7 +150,7 @@ BLI_INLINE const CustomData *mesh_cd_pdata_get_from_mesh(const Mesh *me) BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_SUBD: case ME_WRAPPER_TYPE_MDATA: return &me->edata; @@ -164,7 +166,7 @@ BLI_INLINE const CustomData *mesh_cd_edata_get_from_mesh(const Mesh *me) BLI_INLINE const CustomData *mesh_cd_vdata_get_from_mesh(const Mesh *me) { - switch ((eMeshWrapperType)me->runtime.wrapper_type) { + switch (me->runtime->wrapper_type) { case ME_WRAPPER_TYPE_SUBD: case ME_WRAPPER_TYPE_MDATA: return &me->vdata; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc index be919b1af67..e40503a9707 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_edituv.cc @@ -557,7 +557,7 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr, const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false; if (mr->use_subsurf_fdots) { - const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags; + const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc index d964f608e52..1b552b01d6b 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_fdots.cc @@ -46,7 +46,7 @@ static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr, GPUIndexBufBuilder *elb = static_cast(_userdata); if (mr->use_subsurf_fdots) { - const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags; + const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc index 6d93a482623..d43eb6117df 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc @@ -77,7 +77,7 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, const MVert *mvert = mr->mvert; const MLoop *mloop = mr->mloop; - const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags; + const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const int ml_index_end = mp->loopstart + mp->totloop; for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc index 96240af2ee6..802f000cb43 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc @@ -74,7 +74,7 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr, void *_data) { MeshExtract_FdotUV_Data *data = static_cast(_data); - const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags; + const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; const MLoop *mloop = mr->mloop; const int ml_index_end = mp->loopstart + mp->totloop; diff --git a/source/blender/editors/mesh/editmesh_select.cc b/source/blender/editors/mesh/editmesh_select.cc index 0d1e3c08d84..76d0bab8a52 100644 --- a/source/blender/editors/mesh/editmesh_select.cc +++ b/source/blender/editors/mesh/editmesh_select.cc @@ -22,7 +22,9 @@ #include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_editmesh.h" +#include "BKE_editmesh_cache.h" #include "BKE_layer.h" +#include "BKE_mesh.h" #include "BKE_report.h" #include "WM_api.h" @@ -1065,8 +1067,8 @@ bool EDBM_unified_findnearest_from_raycast(ViewContext *vc, { Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(vc->depsgraph, static_cast(obedit->data)); - if (me_eval->runtime.edit_data) { - coords = me_eval->runtime.edit_data->vertexCos; + if (me_eval->runtime->edit_data) { + coords = me_eval->runtime->edit_data->vertexCos; } } diff --git a/source/blender/editors/mesh/editmesh_undo.cc b/source/blender/editors/mesh/editmesh_undo.cc index d810e782a1b..5c837e61a79 100644 --- a/source/blender/editors/mesh/editmesh_undo.cc +++ b/source/blender/editors/mesh/editmesh_undo.cc @@ -597,6 +597,11 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo * on it. Necessary to use the attribute API. */ strcpy(um->me.id.name, "MEundomesh_from_editmesh"); + /* Runtime data is necessary for some asserts in other code, and the overhead of creating it for + * undo meshes should be low. */ + BLI_assert(um->me.runtime == nullptr); + um->me.runtime = new blender::bke::MeshRuntime(); + CustomData_MeshMasks cd_mask_extra{}; cd_mask_extra.vmask = CD_MASK_SHAPE_KEYINDEX; BMeshToMeshParams params{}; diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 761a6702c6f..e6d0aca7902 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -3533,7 +3533,7 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg } const bool use_dm_final_indices = (psys->part->use_modifier_stack && - !psmd_eval->mesh_final->runtime.deformed_only); + !BKE_mesh_is_deformed_only(psmd_eval->mesh_final)); /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); @@ -4353,7 +4353,7 @@ static void brush_add_count_iter(void *__restrict iter_data_v, 0, 0, 0)) { - if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) { + if (psys->part->use_modifier_stack && !BKE_mesh_is_deformed_only(psmd_eval->mesh_final)) { add_pars[iter].num = add_pars[iter].num_dmcache; add_pars[iter].num_dmcache = DMCACHE_ISCHILD; } @@ -4430,7 +4430,7 @@ static int brush_add(const bContext *C, PEData *data, short number) timestep = psys_get_timestep(&sim); - if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) { + if (psys->part->use_modifier_stack || BKE_mesh_is_deformed_only(psmd_eval->mesh_final)) { mesh = psmd_eval->mesh_final; } else { diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 08db03db0e9..71ed32caede 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -732,7 +732,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, invert_m4_m4(to_imat, to_mat); const bool use_dm_final_indices = (target_psys->part->use_modifier_stack && - !target_psmd->mesh_final->runtime.deformed_only); + !BKE_mesh_is_deformed_only(target_psmd->mesh_final)); if (use_dm_final_indices || !target_psmd->mesh_original) { mesh = target_psmd->mesh_final; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 8ffa78cd457..41d5090b38c 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -4074,7 +4074,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p ps->totloop_eval = ps->me_eval->totloop; ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval); - ps->totlooptri_eval = ps->me_eval->runtime.looptris.len; + ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval); ps->poly_to_loop_uv = MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces"); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index cb981a3bfb1..ce4a5151a20 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -286,7 +286,7 @@ static void imapaint_pick_uv( const ePaintCanvasSource mode = scene->toolsettings->imapaint.mode; const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval); - const int tottri = me_eval->runtime.looptris.len; + const int tottri = BKE_mesh_runtime_looptri_len(me_eval); const MVert *mvert = BKE_mesh_verts(me_eval); const MLoop *mloop = BKE_mesh_loops(me_eval); diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc index cac0dbb0067..e8b005b2b67 100644 --- a/source/blender/editors/space_info/info_stats.cc +++ b/source/blender/editors/space_info/info_stats.cc @@ -40,6 +40,7 @@ #include "BKE_key.h" #include "BKE_layer.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" @@ -94,8 +95,8 @@ static bool stats_mesheval(const Mesh *me_eval, bool is_selected, SceneStats *st int totvert, totedge, totface, totloop; - const SubdivCCG *subdiv_ccg = me_eval->runtime.subdiv_ccg; - const SubsurfRuntimeData *subsurf_runtime_data = me_eval->runtime.subsurf_runtime_data; + const SubdivCCG *subdiv_ccg = me_eval->runtime->subdiv_ccg; + const SubsurfRuntimeData *subsurf_runtime_data = me_eval->runtime->subsurf_runtime_data; if (subdiv_ccg != nullptr) { BKE_subdiv_ccg_topology_counters(subdiv_ccg, &totvert, &totedge, &totface, &totloop); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 36ced74a8b7..6370d56ae8c 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -17,6 +17,7 @@ #include "BKE_editmesh.h" #include "BKE_global.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_object.h" #include "DEG_depsgraph.h" @@ -94,8 +95,8 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, const MPoly *mp; int i; - if (me->runtime.looptris.array) { - const MLoopTri *mlt = me->runtime.looptris.array; + if (BKE_mesh_runtime_looptri_ensure(me)) { + const MLoopTri *mlt = BKE_mesh_runtime_looptri_ensure(me); for (mp = polys, i = 0; i < mpoly_len; i++, mp++) { if (facemap_data[i] == facemap) { for (int j = 2; j < mp->totloop; j++) { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc index c61eac3c777..793ada4f577 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc +++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.cc @@ -19,8 +19,10 @@ #include "BKE_context.h" #include "BKE_editmesh.h" +#include "BKE_editmesh_cache.h" #include "BKE_global.h" #include "BKE_layer.h" +#include "BKE_mesh.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -234,8 +236,8 @@ static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int Object *ob = gz_ele->bases[gz_ele->base_index]->object; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, static_cast(ob->data)); - if (me_eval->runtime.edit_data) { - coords = me_eval->runtime.edit_data->vertexCos; + if (me_eval->runtime->edit_data) { + coords = me_eval->runtime->edit_data->vertexCos; } } EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords); diff --git a/source/blender/editors/space_view3d/view3d_iterators.cc b/source/blender/editors/space_view3d/view3d_iterators.cc index 204e4673aa4..932563863fe 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.cc +++ b/source/blender/editors/space_view3d/view3d_iterators.cc @@ -576,7 +576,7 @@ void mesh_foreachScreenFace( BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE); - if (me->runtime.subsurf_face_dot_tags != nullptr) { + if (me->runtime->subsurf_face_dot_tags != nullptr) { BKE_mesh_foreach_mapped_subdiv_face_center( me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); } diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 90a13722b63..f2711db5011 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -105,7 +105,7 @@ struct SnapData_EditMesh { /* Looptris. */ BVHTreeFromEditMesh treedata_editmesh; - struct Mesh_Runtime *mesh_runtime; + blender::bke::MeshRuntime *mesh_runtime; float min[3], max[3]; void clear() @@ -189,14 +189,14 @@ static const Mesh *mesh_for_snap(Object *ob_eval, eSnapEditType edit_mode_type, const Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval); if ((edit_mode_type == SNAP_GEOM_FINAL) && editmesh_eval_final) { - if (editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (editmesh_eval_final->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { return nullptr; } me_eval = editmesh_eval_final; use_hide = true; } else if ((edit_mode_type == SNAP_GEOM_CAGE) && editmesh_eval_cage) { - if (editmesh_eval_cage->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH) { + if (editmesh_eval_cage->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { return nullptr; } me_eval = editmesh_eval_cage; @@ -253,21 +253,21 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, sod = sod_p->get(); bool is_dirty = false; if (sod->treedata_mesh.tree && sod->treedata_mesh.cached && - !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->treedata_mesh.tree)) { + !bvhcache_has_tree(me_eval->runtime->bvh_cache, sod->treedata_mesh.tree)) { /* The tree is owned by the Mesh and may have been freed since we last used. */ is_dirty = true; } else if (sod->bvhtree[0] && sod->cached[0] && - !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->bvhtree[0])) { + !bvhcache_has_tree(me_eval->runtime->bvh_cache, sod->bvhtree[0])) { /* The tree is owned by the Mesh and may have been freed since we last used. */ is_dirty = true; } else if (sod->bvhtree[1] && sod->cached[1] && - !bvhcache_has_tree(me_eval->runtime.bvh_cache, sod->bvhtree[1])) { + !bvhcache_has_tree(me_eval->runtime->bvh_cache, sod->bvhtree[1])) { /* The tree is owned by the Mesh and may have been freed since we last used. */ is_dirty = true; } - else if (sod->treedata_mesh.looptri != me_eval->runtime.looptris.array) { + else if (sod->treedata_mesh.looptri != me_eval->looptris().data()) { is_dirty = true; } else if (sod->treedata_mesh.vert != verts.data()) { @@ -330,19 +330,19 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, /* Searches for the #Mesh_Runtime associated with the object that is most likely to be updated due * to changes in the `edit_mesh`. */ -static Mesh_Runtime *snap_object_data_editmesh_runtime_get(Object *ob_eval) +static blender::bke::MeshRuntime *snap_object_data_editmesh_runtime_get(Object *ob_eval) { Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob_eval); if (editmesh_eval_final) { - return &editmesh_eval_final->runtime; + return editmesh_eval_final->runtime; } Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob_eval); if (editmesh_eval_cage) { - return &editmesh_eval_cage->runtime; + return editmesh_eval_cage->runtime; } - return &((Mesh *)ob_eval->data)->runtime; + return ((Mesh *)ob_eval->data)->runtime; } static SnapData_EditMesh *snap_object_data_editmesh_get(SnapObjectContext *sctx, diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index a8cba959689..c1e71bde254 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -1953,8 +1953,6 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge LineartEdgeNeighbor *edge_nabr = MEM_mallocN(sizeof(LineartEdgeNeighbor) * total_edges, "LineartEdgeNeighbor arr"); - MLoopTri *mlooptri = me->runtime.looptris.array; - TaskParallelSettings en_settings; BLI_parallel_range_settings_defaults(&en_settings); /* Set the minimum amount of edges a thread has to process. */ @@ -1963,7 +1961,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge EdgeNeighborData en_data; en_data.adj_e = adj_e; en_data.edge_nabr = edge_nabr; - en_data.mlooptri = mlooptri; + en_data.mlooptri = BKE_mesh_runtime_looptri_ensure(me); en_data.mloop = BKE_mesh_loops(me); BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings); diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 2a17dbab8b3..3f951583741 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -19,10 +19,14 @@ namespace blender { template class Span; template class MutableSpan; namespace bke { +struct MeshRuntime; class AttributeAccessor; class MutableAttributeAccessor; } // namespace bke } // namespace blender +using MeshRuntimeHandle = blender::bke::MeshRuntime; +#else +typedef struct MeshRuntimeHandle MeshRuntimeHandle; #endif #ifdef __cplusplus @@ -30,133 +34,14 @@ extern "C" { #endif struct AnimData; -struct BVHCache; struct Ipo; struct Key; struct MCol; struct MEdge; struct MFace; -struct MLoopCol; struct MLoopTri; struct MVert; struct Material; -struct Mesh; -struct SubdivCCG; -struct SubsurfRuntimeData; - -# -# -typedef struct EditMeshData { - /** when set, \a vertexNos, polyNos are lazy initialized */ - const float (*vertexCos)[3]; - - /** lazy initialize (when \a vertexCos is set) */ - float const (*vertexNos)[3]; - float const (*polyNos)[3]; - /** also lazy init but don't depend on \a vertexCos */ - const float (*polyCos)[3]; -} EditMeshData; - -/** - * \warning Typical access is done via - * #BKE_mesh_runtime_looptri_ensure, #BKE_mesh_runtime_looptri_len. - */ -struct MLoopTri_Store { - DNA_DEFINE_CXX_METHODS(MLoopTri_Store) - - /* WARNING! swapping between array (ready-to-be-used data) and array_wip - * (where data is actually computed) - * shall always be protected by same lock as one used for looptris computing. */ - struct MLoopTri *array, *array_wip; - int len; - int len_alloc; -}; - -/** Runtime data, not saved in files. */ -typedef struct Mesh_Runtime { - DNA_DEFINE_CXX_METHODS(Mesh_Runtime) - - /* Evaluated mesh for objects which do not have effective modifiers. - * This mesh is used as a result of modifier stack evaluation. - * Since modifier stack evaluation is threaded on object level we need some synchronization. */ - struct Mesh *mesh_eval; - void *eval_mutex; - - /* A separate mutex is needed for normal calculation, because sometimes - * the normals are needed while #eval_mutex is already locked. */ - void *normals_mutex; - - /** Needed to ensure some thread-safety during render data pre-processing. */ - void *render_mutex; - - /** Lazily initialized SoA data from the #edit_mesh field in #Mesh. */ - struct EditMeshData *edit_data; - - /** - * Data used to efficiently draw the mesh in the viewport, especially useful when - * the same mesh is used in many objects or instances. See `draw_cache_impl_mesh.cc`. - */ - void *batch_cache; - - /** Cache for derived triangulation of the mesh. */ - struct MLoopTri_Store looptris; - - /** Cache for BVH trees generated for the mesh. Defined in 'BKE_bvhutil.c' */ - struct BVHCache *bvh_cache; - - /** Cache of non-manifold boundary data for Shrinkwrap Target Project. */ - struct ShrinkwrapBoundaryData *shrinkwrap_data; - - /** Needed in case we need to lazily initialize the mesh. */ - CustomData_MeshMasks cd_mask_extra; - - struct SubdivCCG *subdiv_ccg; - int subdiv_ccg_tot_level; - - /** Set by modifier stack if only deformed from original. */ - char deformed_only; - /** - * Copied from edit-mesh (hint, draw with edit-mesh data when true). - * - * Modifiers that edit the mesh data in-place must set this to false - * (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh - * data will be used for drawing, missing changes from modifiers. See T79517. - */ - char is_original_bmesh; - - /** #eMeshWrapperType and others. */ - char wrapper_type; - /** - * A type mask from wrapper_type, - * in case there are differences in finalizing logic between types. - */ - char wrapper_type_finalize; - - /** - * Settings for lazily evaluating the subdivision on the CPU if needed. These are - * set in the modifier when GPU subdivision can be performed, and owned by the by - * the modifier in the object. - */ - struct SubsurfRuntimeData *subsurf_runtime_data; - void *_pad1; - - /** - * Caches for lazily computed vertex and polygon normals. These are stored here rather than in - * #CustomData because they can be calculated on a const mesh, and adding custom data layers on a - * const mesh is not thread-safe. - */ - char _pad2[6]; - char vert_normals_dirty; - char poly_normals_dirty; - float (*vert_normals)[3]; - float (*poly_normals)[3]; - - /** - * A #BLI_bitmap containing tags for the center vertices of subdivided polygons, set by the - * subdivision surface modifier and used by drawing code instead of polygon center face dots. - */ - uint32_t *subsurf_face_dot_tags; -} Mesh_Runtime; typedef struct Mesh { DNA_DEFINE_CXX_METHODS(Mesh) @@ -316,9 +201,13 @@ typedef struct Mesh { char _pad1[4]; - void *_pad2; - - Mesh_Runtime runtime; + /** + * Data that isn't saved in files, including caches of derived data, temporary data to improve + * the editing experience, etc. Runtime data is created when reading files and can be accessed + * without null checks, with the exception of some temporary meshes which should allocate and + * free the data if they are passed to functions that expect run-time data. + */ + MeshRuntimeHandle *runtime; #ifdef __cplusplus /** * Array of vertex positions (and various other data). Edges and faces are defined by indices @@ -383,16 +272,6 @@ typedef struct TFace { /* **************** MESH ********************* */ -/** #Mesh_Runtime.wrapper_type */ -typedef enum eMeshWrapperType { - /** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */ - ME_WRAPPER_TYPE_MDATA = 0, - /** Use edit-mesh data (#Mesh.edit_mesh, #Mesh_Runtime.edit_data). */ - ME_WRAPPER_TYPE_BMESH = 1, - /** Use subdivision mesh data (#Mesh_Runtime.mesh_eval). */ - ME_WRAPPER_TYPE_SUBD = 2, -} eMeshWrapperType; - /** #Mesh.texflag */ enum { ME_AUTOSPACE = 1, diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 9c6702142f7..bad099815a4 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -406,12 +406,39 @@ static int rna_MeshLoopTriangle_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); const MLoopTri *ltri = (MLoopTri *)ptr->data; - const int index = (int)(ltri - mesh->runtime.looptris.array); + const int index = (int)(ltri - BKE_mesh_runtime_looptri_ensure(mesh)); BLI_assert(index >= 0); - BLI_assert(index < mesh->runtime.looptris.len); + BLI_assert(index < BKE_mesh_runtime_looptri_len(mesh)); return index; } +static void rna_Mesh_loop_triangles_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(mesh); + rna_iterator_array_begin( + iter, (void *)looptris, sizeof(MLoopTri), BKE_mesh_runtime_looptri_len(mesh), false, NULL); +} + +static int rna_Mesh_loop_triangles_length(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + return BKE_mesh_runtime_looptri_len(mesh); +} + +int rna_Mesh_loop_triangles_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + if (index < 0 || index >= BKE_mesh_runtime_looptri_len(mesh)) { + return false; + } + /* Casting away const is okay because this RNA type doesn't allow changing the value. */ + r_ptr->owner_id = (ID *)&mesh->id; + r_ptr->type = &RNA_MeshLoopTriangle; + r_ptr->data = (void *)&BKE_mesh_runtime_looptri_ensure(mesh)[index]; + return true; +} + static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value) { Mesh *mesh = rna_mesh(ptr); @@ -1502,8 +1529,9 @@ static char *rna_MeshPolygon_path(const PointerRNA *ptr) static char *rna_MeshLoopTriangle_path(const PointerRNA *ptr) { - return BLI_sprintfN("loop_triangles[%d]", - (int)((MLoopTri *)ptr->data - rna_mesh(ptr)->runtime.looptris.array)); + return BLI_sprintfN( + "loop_triangles[%d]", + (int)((MLoopTri *)ptr->data - BKE_mesh_runtime_looptri_ensure(rna_mesh(ptr)))); } static char *rna_MeshEdge_path(const PointerRNA *ptr) @@ -3684,7 +3712,15 @@ static void rna_def_mesh(BlenderRNA *brna) NULL); prop = RNA_def_property(srna, "loop_triangles", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "runtime.looptris.array", "runtime.looptris.len"); + RNA_def_property_collection_funcs(prop, + "rna_Mesh_loop_triangles_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Mesh_loop_triangles_length", + "rna_Mesh_loop_triangles_lookup_int", + NULL, + NULL); RNA_def_property_struct_type(prop, "MeshLoopTriangle"); RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text(prop, "Loop Triangles", "Tessellation of mesh polygons into triangles"); diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 1a4942fcaf1..30be1d33653 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -23,6 +23,7 @@ #include "BKE_lib_id.h" #include "BKE_lib_query.h" #include "BKE_mesh.h" +#include "BKE_mesh_runtime.h" #include "BKE_mesh_wrapper.h" #include "BKE_modifier.h" #include "BKE_screen.h" @@ -494,7 +495,7 @@ static void deformVertsEM(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); } - if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) { + if (mesh && BKE_mesh_wrapper_type(mesh) == ME_WRAPPER_TYPE_MDATA) { BLI_assert(mesh->totvert == verts_num); } diff --git a/source/blender/modifiers/intern/MOD_datatransfer.cc b/source/blender/modifiers/intern/MOD_datatransfer.cc index 4b6170598dd..25e8eb8fa20 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.cc +++ b/source/blender/modifiers/intern/MOD_datatransfer.cc @@ -213,7 +213,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * dtmd->defgrp_name, invert_vgroup, &reports)) { - result->runtime.is_original_bmesh = false; + result->runtime->is_original_bmesh = false; } if (BKE_reports_contain(&reports, RPT_ERROR)) { diff --git a/source/blender/modifiers/intern/MOD_multires.cc b/source/blender/modifiers/intern/MOD_multires.cc index a23ab73c651..2bc3763c46b 100644 --- a/source/blender/modifiers/intern/MOD_multires.cc +++ b/source/blender/modifiers/intern/MOD_multires.cc @@ -230,7 +230,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco && !for_render && !sculpt_base_mesh) { /* NOTE: CCG takes ownership over Subdiv. */ result = multires_as_ccg(mmd, ctx, mesh, subdiv); - result->runtime.subdiv_ccg_tot_level = mmd->totlvl; + result->runtime->subdiv_ccg_tot_level = mmd->totlvl; /* TODO(sergey): Usually it is sculpt stroke's update variants which * takes care of this, but is possible that we need this before the * stroke: i.e. when exiting blender right after stroke is done. @@ -238,7 +238,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * surely there is a better way of solving this. */ if (ctx->object->sculpt != nullptr) { SculptSession *sculpt_session = ctx->object->sculpt; - sculpt_session->subdiv_ccg = result->runtime.subdiv_ccg; + sculpt_session->subdiv_ccg = result->runtime->subdiv_ccg; sculpt_session->multires.active = true; sculpt_session->multires.modifier = mmd; sculpt_session->multires.level = mmd->sculptlvl; diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 6f86bf1d8cb..43ded18fcc4 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -623,7 +623,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, MEM_SAFE_FREE(loopnors); - result->runtime.is_original_bmesh = false; + result->runtime->is_original_bmesh = false; return result; } diff --git a/source/blender/modifiers/intern/MOD_particlesystem.cc b/source/blender/modifiers/intern/MOD_particlesystem.cc index b957bd26ca6..66291520176 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.cc +++ b/source/blender/modifiers/intern/MOD_particlesystem.cc @@ -159,7 +159,7 @@ static void deformVerts(ModifierData *md, BKE_mesh_tessface_ensure(psmd->mesh_final); - if (!psmd->mesh_final->runtime.deformed_only) { + if (!psmd->mesh_final->runtime->deformed_only) { /* Get the original mesh from the object, this is what the particles * are attached to so in case of non-deform modifiers we need to remap * them to the final mesh (typically subdivision surfaces). */ diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index 4241ca5a591..d6241fcb290 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -67,10 +67,9 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) input->mloop = (void *)BKE_mesh_loops(mesh); input->loop_stride = sizeof(MLoop); - BKE_mesh_runtime_looptri_ensure(mesh); - input->looptri = (void *)mesh->runtime.looptris.array; + input->looptri = (void *)BKE_mesh_runtime_looptri_ensure(mesh); input->tri_stride = sizeof(MLoopTri); - input->tottri = mesh->runtime.looptris.len; + input->tottri = BKE_mesh_runtime_looptri_len(mesh); INIT_MINMAX(input->min, input->max); BKE_mesh_minmax(mesh, input->min, input->max); diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 991bd0d876c..5e77f0ffa9e 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -208,7 +208,7 @@ static void subdiv_cache_mesh_wrapper_settings(const ModifierEvalContext *ctx, runtime_data->calc_loop_normals = false; /* Set at the end of modifier stack evaluation. */ runtime_data->use_loop_normals = (smd->flags & eSubsurfModifierFlag_UseCustomNormals); - mesh->runtime.subsurf_runtime_data = runtime_data; + mesh->runtime->subsurf_runtime_data = runtime_data; } /* Modifier itself. */ diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index 509ce95b073..589a3d28ad9 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -188,7 +188,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, &mesh_prior_modifiers->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE)); - mesh->runtime.deformed_only = 1; + mesh->runtime->deformed_only = 1; } if (em != nullptr) { @@ -218,7 +218,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, } } - if (mesh && mesh->runtime.wrapper_type == ME_WRAPPER_TYPE_MDATA) { + if (mesh && mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_MDATA) { BLI_assert(mesh->totvert == verts_num); } diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index 9861b318e82..c07b2059b5b 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -283,7 +283,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, } } - mesh->runtime.is_original_bmesh = false; + mesh->runtime->is_original_bmesh = false; return mesh; } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.cc b/source/blender/modifiers/intern/MOD_uvwarp.cc index 90415861c73..4ec273bcbc6 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.cc +++ b/source/blender/modifiers/intern/MOD_uvwarp.cc @@ -216,7 +216,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * settings.use_threading = (polys_num > 1000); BLI_task_parallel_range(0, polys_num, &data, uv_warp_compute, &settings); - mesh->runtime.is_original_bmesh = false; + mesh->runtime->is_original_bmesh = false; return mesh; } diff --git a/source/blender/modifiers/intern/MOD_wave.cc b/source/blender/modifiers/intern/MOD_wave.cc index 962bb60c8ad..647e0324707 100644 --- a/source/blender/modifiers/intern/MOD_wave.cc +++ b/source/blender/modifiers/intern/MOD_wave.cc @@ -21,6 +21,7 @@ #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_editmesh.h" +#include "BKE_editmesh_cache.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" #include "BKE_mesh.h" @@ -337,7 +338,7 @@ static void deformVertsEM(ModifierData *md, if (!ELEM(mesh_src, nullptr, mesh)) { /* Important not to free `vertexCos` owned by the caller. */ - EditMeshData *edit_data = mesh_src->runtime.edit_data; + EditMeshData *edit_data = mesh_src->runtime->edit_data; if (edit_data->vertexCos == vertexCos) { edit_data->vertexCos = nullptr; } diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 6e3961bef64..1ebd5423d39 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -676,7 +676,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_SAFE_FREE(wn_data.mode_pair); MEM_SAFE_FREE(wn_data.items_data); - result->runtime.is_original_bmesh = false; + result->runtime->is_original_bmesh = false; return result; } diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.cc b/source/blender/modifiers/intern/MOD_weightvgedit.cc index 439ad6a3f49..e4fbca633f7 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.cc +++ b/source/blender/modifiers/intern/MOD_weightvgedit.cc @@ -278,7 +278,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_freeN(new_w); MEM_freeN(dw); - mesh->runtime.is_original_bmesh = false; + mesh->runtime->is_original_bmesh = false; /* Return the vgroup-modified mesh. */ return mesh; diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.cc b/source/blender/modifiers/intern/MOD_weightvgmix.cc index 3a3901adaac..d860e93d535 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.cc +++ b/source/blender/modifiers/intern/MOD_weightvgmix.cc @@ -438,7 +438,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_freeN(dw2); MEM_SAFE_FREE(indices); - mesh->runtime.is_original_bmesh = false; + mesh->runtime->is_original_bmesh = false; /* Return the vgroup-modified mesh. */ return mesh; diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.cc b/source/blender/modifiers/intern/MOD_weightvgproximity.cc index 5f046b9cd68..93052f4215d 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.cc +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.cc @@ -639,7 +639,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * TIMEIT_END(perf); #endif - mesh->runtime.is_original_bmesh = false; + mesh->runtime->is_original_bmesh = false; /* Return the vgroup-modified mesh. */ return mesh; diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index 59719fb4590..8fd62f7ec34 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -590,7 +590,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, me_highpoly[i] = highpoly[i].me; BKE_mesh_runtime_looptri_ensure(me_highpoly[i]); - if (me_highpoly[i]->runtime.looptris.len != 0) { + if (BKE_mesh_runtime_looptri_len(me_highpoly[i]) != 0) { /* Create a BVH-tree for each `highpoly` object. */ BKE_bvhtree_from_mesh_get(&treeData[i], me_highpoly[i], BVHTREE_FROM_LOOPTRI, 2); -- cgit v1.2.3