diff options
Diffstat (limited to 'source/blender')
232 files changed, 3923 insertions, 3281 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 6af38b14ea4..f5ffd1190b1 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -79,7 +79,7 @@ typedef struct Cloth { int last_frame; float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */ float average_acceleration[3]; /* Moving average of overall acceleration. */ - struct MEdge *edges; /* Used for hair collisions. */ + const struct MEdge *edges; /* Used for hair collisions. */ struct EdgeSet *sew_edge_graph; /* Sewing edges represented using a GHash */ } Cloth; diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index a21d9141ac0..f58a5502788 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -240,23 +240,23 @@ void BKE_defvert_extract_vgroup_to_vertweights(const struct MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_edgeweights(const struct MDeformVert *dvert, int defgroup, int num_verts, - struct MEdge *edges, + const struct MEdge *edges, int num_edges, bool invert_vgroup, float *r_weights); void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert, int defgroup, int num_verts, - struct MLoop *loops, + const struct MLoop *loops, int num_loops, bool invert_vgroup, float *r_weights); void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert, int defgroup, int num_verts, - struct MLoop *loops, + const struct MLoop *loops, int num_loops, - struct MPoly *polys, + const struct MPoly *polys, int num_polys, bool invert_vgroup, float *r_weights); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index ec6799ee995..eb54861e79c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -6,12 +6,15 @@ * \ingroup bke */ +#include "BLI_compiler_attrs.h" +#include "BLI_compiler_compat.h" +#include "BLI_utildefines.h" + #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "BKE_customdata.h" #include "BKE_mesh_types.h" -#include "BLI_compiler_attrs.h" -#include "BLI_utildefines.h" struct BLI_Stack; struct BMesh; @@ -148,7 +151,6 @@ void BKE_mesh_copy_parameters_for_eval(struct Mesh *me_dst, const struct Mesh *m * when a new mesh is based on an existing mesh. */ void BKE_mesh_copy_parameters(struct Mesh *me_dst, const struct Mesh *me_src); -void BKE_mesh_update_customdata_pointers(struct Mesh *me, bool do_ensure_tess_cd); void BKE_mesh_ensure_skin_customdata(struct Mesh *me); struct Mesh *BKE_mesh_new_nomain( @@ -517,9 +519,9 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts, int numVerts, struct MEdge *medges, int numEdges, - struct MLoop *mloops, + const struct MLoop *mloops, int numLoops, - struct MPoly *mpolys, + const struct MPoly *mpolys, const float (*polynors)[3], int numPolys, float split_angle); @@ -637,12 +639,12 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space, void BKE_mesh_normals_loop_split(const struct MVert *mverts, const float (*vert_normals)[3], int numVerts, - struct MEdge *medges, + const struct MEdge *medges, int numEdges, - struct MLoop *mloops, + const struct MLoop *mloops, float (*r_loopnors)[3], int numLoops, - struct MPoly *mpolys, + const struct MPoly *mpolys, const float (*polynors)[3], int numPolys, bool use_split_normals, @@ -656,10 +658,10 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, int numVerts, struct MEdge *medges, int numEdges, - struct MLoop *mloops, + const struct MLoop *mloops, float (*r_custom_loopnors)[3], int numLoops, - struct MPoly *mpolys, + const struct MPoly *mpolys, const float (*polynors)[3], int numPolys, short (*r_clnors_data)[2]); @@ -669,9 +671,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(const struct MVert *mverts, int numVerts, struct MEdge *medges, int numEdges, - struct MLoop *mloops, + const struct MLoop *mloops, int numLoops, - struct MPoly *mpolys, + const struct MPoly *mpolys, const float (*polynors)[3], int numPolys, short (*r_clnors_data)[2]); @@ -796,19 +798,21 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip); * \param mloop: the full loops array. * \param ldata: the loops custom data. */ -void BKE_mesh_polygon_flip_ex(struct MPoly *mpoly, +void BKE_mesh_polygon_flip_ex(const struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, float (*lnors)[3], struct MDisps *mdisp, bool use_loop_mdisp_flip); -void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata); +void BKE_mesh_polygon_flip(const struct MPoly *mpoly, + struct MLoop *mloop, + struct CustomData *ldata); /** * Flip (invert winding of) all polygons (used to inverse their normals). * * \note Invalidates tessellation, caller must handle that. */ -void BKE_mesh_polygons_flip(struct MPoly *mpoly, +void BKE_mesh_polygons_flip(const struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata, int totpoly); @@ -1022,6 +1026,10 @@ char *BKE_mesh_debug_info(const struct Mesh *me) void BKE_mesh_debug_print(const struct Mesh *me) ATTR_NONNULL(1); #endif +/* -------------------------------------------------------------------- */ +/** \name Inline Mesh Data Access + * \{ */ + /** * \return The material index for each polygon. May be null. * \note In C++ code, prefer using the attribute API (#MutableAttributeAccessor)/ @@ -1046,6 +1054,110 @@ BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh) &mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, NULL, mesh->totpoly, "material_index"); } +BLI_INLINE const MVert *BKE_mesh_vertices(const Mesh *mesh) +{ + return (const MVert *)CustomData_get_layer(&mesh->vdata, CD_MVERT); +} +BLI_INLINE MVert *BKE_mesh_vertices_for_write(Mesh *mesh) +{ + return (MVert *)CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert); +} + +BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh) +{ + return (const MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE); +} +BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh) +{ + return (MEdge *)CustomData_duplicate_referenced_layer(&mesh->edata, CD_MEDGE, mesh->totedge); +} + +BLI_INLINE const MPoly *BKE_mesh_polygons(const Mesh *mesh) +{ + return (const MPoly *)CustomData_get_layer(&mesh->pdata, CD_MPOLY); +} +BLI_INLINE MPoly *BKE_mesh_polygons_for_write(Mesh *mesh) +{ + return (MPoly *)CustomData_duplicate_referenced_layer(&mesh->pdata, CD_MPOLY, mesh->totpoly); +} + +BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh) +{ + return (const MLoop *)CustomData_get_layer(&mesh->ldata, CD_MLOOP); +} +BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh) +{ + return (MLoop *)CustomData_duplicate_referenced_layer(&mesh->ldata, CD_MLOOP, mesh->totloop); +} + +BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh) +{ + return (const MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); +} +BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh) +{ + MDeformVert *dvert = (MDeformVert *)CustomData_duplicate_referenced_layer( + &mesh->vdata, CD_MDEFORMVERT, mesh->totvert); + if (dvert) { + return dvert; + } + return (MDeformVert *)CustomData_add_layer( + &mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, mesh->totvert); +} + #ifdef __cplusplus } #endif + +#ifdef __cplusplus + +# include "BLI_span.hh" + +inline blender::Span<MVert> Mesh::vertices() const +{ + return {BKE_mesh_vertices(this), this->totvert}; +} +inline blender::MutableSpan<MVert> Mesh::vertices_for_write() +{ + return {BKE_mesh_vertices_for_write(this), this->totvert}; +} + +inline blender::Span<MEdge> Mesh::edges() const +{ + return {BKE_mesh_edges(this), this->totedge}; +} +inline blender::MutableSpan<MEdge> Mesh::edges_for_write() +{ + return {BKE_mesh_edges_for_write(this), this->totedge}; +} + +inline blender::Span<MPoly> Mesh::polygons() const +{ + return {BKE_mesh_polygons(this), this->totpoly}; +} +inline blender::MutableSpan<MPoly> Mesh::polygons_for_write() +{ + return {BKE_mesh_polygons_for_write(this), this->totpoly}; +} + +inline blender::Span<MLoop> Mesh::loops() const +{ + return {BKE_mesh_loops(this), this->totloop}; +} +inline blender::MutableSpan<MLoop> Mesh::loops_for_write() +{ + return {BKE_mesh_loops_for_write(this), this->totloop}; +} + +inline blender::Span<MDeformVert> Mesh::deform_verts() const +{ + return {BKE_mesh_deform_verts(this), this->totvert}; +} +inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write() +{ + return {BKE_mesh_deform_verts_for_write(this), this->totvert}; +} + +#endif + +/** \} */ diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index abe590b6806..cf9763d50a4 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -248,13 +248,13 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, int num_innercut_items, int *innercut_item_indices); -typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts, +typedef bool (*MeshRemapIslandsCalc)(const struct MVert *verts, int totvert, - struct MEdge *edges, + const struct MEdge *edges, int totedge, - struct MPoly *polys, + const struct MPoly *polys, int totpoly, - struct MLoop *loops, + const struct MLoop *loops, int totloop, struct MeshIslandStore *r_island_store); @@ -265,13 +265,13 @@ typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts, * Calculate 'generic' UV islands, i.e. based only on actual geometry data (edge seams), * not some UV layers coordinates. */ -bool BKE_mesh_calc_islands_loop_poly_edgeseam(struct MVert *verts, +bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts, int totvert, - struct MEdge *edges, + const struct MEdge *edges, int totedge, - struct MPoly *polys, + const struct MPoly *polys, int totpoly, - struct MLoop *loops, + const struct MLoop *loops, int totloop, MeshIslandStore *r_island_store); diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h index ee0179c7a77..efbf542c831 100644 --- a/source/blender/blenkernel/BKE_mesh_remap.h +++ b/source/blender/blenkernel/BKE_mesh_remap.h @@ -199,13 +199,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode, float max_dist, float ray_radius, struct Mesh *mesh_dst, - struct MVert *verts_dst, + const struct MVert *verts_dst, int numverts_dst, - struct MEdge *edges_dst, + const struct MEdge *edges_dst, int numedges_dst, - struct MLoop *loops_dst, + const struct MLoop *loops_dst, int numloops_dst, - struct MPoly *polys_dst, + const struct MPoly *polys_dst, int numpolys_dst, struct CustomData *ldata_dst, bool use_split_nors_dst, @@ -220,10 +220,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, - struct Mesh *mesh_dst, - struct MVert *verts_dst, - struct MLoop *loops_dst, - struct MPoly *polys_dst, + const struct Mesh *mesh_dst, + const struct MVert *verts_dst, + const struct MLoop *loops_dst, + const struct MPoly *polys_dst, int numpolys_dst, struct Mesh *me_src, struct MeshPairRemap *r_map); diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index fb01083f334..94dc52d5ec9 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -127,7 +127,8 @@ int sample_surface_points_projected( Vector<int> &r_looptri_indices, Vector<float3> &r_positions); -float3 compute_bary_coord_in_triangle(const Mesh &mesh, +float3 compute_bary_coord_in_triangle(Span<MVert> verts, + Span<MLoop> loops, const MLoopTri &looptri, const float3 &position); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 92b1aacc300..2197fa3af1e 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -500,8 +500,8 @@ typedef struct SculptSession { /* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */ struct MVert *mvert; - struct MPoly *mpoly; - struct MLoop *mloop; + const struct MPoly *mpoly; + const struct MLoop *mloop; /* These contain the vertex and poly counts of the final mesh. */ int totvert, totpoly; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 5f8b2fafdd3..a797aef73f6 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -579,7 +579,7 @@ void psys_get_texture(struct ParticleSimulationData *sim, * Interpolate a location on a face based on face coordinates. */ void psys_interpolate_face(struct Mesh *mesh, - struct MVert *mvert, + const struct MVert *mvert, const float (*vert_normals)[3], struct MFace *mface, struct MTFace *tface, diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 3e06bd84805..3fe1ee10eb9 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -29,7 +29,8 @@ extern "C" { struct BVHTree; struct MDeformVert; struct Mesh; -struct ModifierEvalContext; + struct ModifierEvalContext; +struct MPoly; struct Object; struct ShrinkwrapGpencilModifierData; struct ShrinkwrapModifierData; @@ -72,6 +73,7 @@ typedef struct ShrinkwrapTreeData { BVHTree *bvh; BVHTreeFromMesh treeData; + const struct MPoly *polys; const float (*pnors)[3]; const float (*clnors)[3]; ShrinkwrapBoundaryData *boundary; @@ -104,7 +106,7 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Scene *scene, struct Object *ob, struct Mesh *mesh, - struct MDeformVert *dvert, + const struct MDeformVert *dvert, int defgrp_index, float (*vertexCos)[3], int numVerts); diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 7ef6eaa64cd..46a8caafa70 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -68,6 +68,8 @@ using blender::float3; using blender::IndexRange; +using blender::Span; +using blender::VArray; /* very slow! enable for testing only! */ //#define USE_MODIFIER_VALIDATE @@ -585,7 +587,6 @@ static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orc if (!(layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer))) { CustomData_add_layer(&mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert); - BKE_mesh_update_customdata_pointers(mesh, false); layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer); } @@ -2002,9 +2003,9 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to MEM_freeN(userData.vertex_visit); } else { - MVert *mv = me_eval->mvert; - for (int i = 0; i < totcos; i++, mv++) { - copy_v3_v3(r_cos[i], mv->co); + const Span<MVert> verts = me_eval->vertices(); + for (int i = 0; i < totcos; i++) { + copy_v3_v3(r_cos[i], verts[i].co); } } } @@ -2017,9 +2018,11 @@ static void mesh_init_origspace(Mesh *mesh) CD_ORIGSPACE_MLOOP); const int numpoly = mesh->totpoly; // const int numloop = mesh->totloop; - MVert *mv = mesh->mvert; - MLoop *ml = mesh->mloop; - MPoly *mp = mesh->mpoly; + const Span<MVert> verts = mesh->vertices(); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); + + const MPoly *mp = polys.data(); int i, j, k; blender::Vector<blender::float2, 64> vcos_2d; @@ -2033,19 +2036,19 @@ static void mesh_init_origspace(Mesh *mesh) } } else { - MLoop *l = &ml[mp->loopstart]; + const MLoop *l = &loops[mp->loopstart]; float p_nor[3], co[3]; float mat[3][3]; float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX}; float translate[2], scale[2]; - BKE_mesh_calc_poly_normal(mp, l, mv, p_nor); + BKE_mesh_calc_poly_normal(mp, l, verts.data(), p_nor); axis_dominant_v3_to_m3(mat, p_nor); vcos_2d.resize(mp->totloop); for (j = 0; j < mp->totloop; j++, l++) { - mul_v3_m3v3(co, mat, mv[l->v].co); + mul_v3_m3v3(co, mat, verts[l->v].co); copy_v2_v2(vcos_2d[j], co); for (k = 0; k < 2; k++) { diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index cc1bfcc087c..84bb1af011a 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -35,6 +35,7 @@ #include "BKE_deform.h" #include "BKE_editmesh.h" #include "BKE_lattice.h" +#include "BKE_mesh.h" #include "DEG_depsgraph_build.h" @@ -406,8 +407,8 @@ static void armature_vert_task(void *__restrict userdata, if (data->use_dverts || data->armature_def_nr != -1) { if (data->me_target) { BLI_assert(i < data->me_target->totvert); - if (data->me_target->dvert != NULL) { - dvert = data->me_target->dvert + i; + if (data->dverts != NULL) { + dvert = data->dverts + i; } else { dvert = NULL; @@ -488,7 +489,7 @@ static void armature_deform_coords_impl(const Object *ob_arm, target_data_id = me_target == NULL ? (const ID *)ob_target->data : &me_target->id; if (em_target == NULL) { const Mesh *me = (const Mesh *)target_data_id; - dverts = me->dvert; + dverts = BKE_mesh_deform_verts(me); if (dverts) { dverts_len = me->totvert; } @@ -523,7 +524,7 @@ static void armature_deform_coords_impl(const Object *ob_arm, use_dverts = (cd_dvert_offset != -1); } else if (me_target) { - use_dverts = (me_target->dvert != NULL); + use_dverts = (BKE_mesh_deform_verts(me_target) != NULL); } else if (dverts) { use_dverts = true; diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index d0b57b45d35..d33ff933004 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -15,6 +15,7 @@ #include "BLI_linklist.h" #include "BLI_math.h" +#include "BLI_span.hh" #include "BLI_task.h" #include "BLI_threads.h" #include "BLI_utildefines.h" @@ -27,6 +28,7 @@ #include "MEM_guardedalloc.h" +using blender::Span; using blender::VArray; /* -------------------------------------------------------------------- */ @@ -1229,14 +1231,17 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, looptri = BKE_mesh_runtime_looptri_ensure(mesh); looptri_len = BKE_mesh_runtime_looptri_len(mesh); } + const Span<MVert> verts = mesh->vertices(); + const Span<MEdge> edges = mesh->edges(); + const Span<MLoop> loops = mesh->loops(); /* Setup BVHTreeFromMesh */ bvhtree_from_mesh_setup_data(nullptr, bvh_cache_type, - mesh->mvert, - mesh->medge, - mesh->mface, - mesh->mloop, + verts.data(), + edges.data(), + (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), + loops.data(), looptri, BKE_mesh_vertex_normals_ensure(mesh), data); @@ -1260,31 +1265,38 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, switch (bvh_cache_type) { case BVHTREE_FROM_LOOSEVERTS: mask = loose_verts_map_get( - mesh->medge, mesh->totedge, mesh->mvert, mesh->totvert, &mask_bits_act_len); + edges.data(), mesh->totedge, verts.data(), mesh->totvert, &mask_bits_act_len); ATTR_FALLTHROUGH; case BVHTREE_FROM_VERTS: data->tree = bvhtree_from_mesh_verts_create_tree( - 0.0f, tree_type, 6, mesh->mvert, mesh->totvert, mask, mask_bits_act_len); + 0.0f, tree_type, 6, verts.data(), mesh->totvert, mask, mask_bits_act_len); break; case BVHTREE_FROM_LOOSEEDGES: - mask = loose_edges_map_get(mesh->medge, mesh->totedge, &mask_bits_act_len); + mask = loose_edges_map_get(edges.data(), mesh->totedge, &mask_bits_act_len); ATTR_FALLTHROUGH; case BVHTREE_FROM_EDGES: data->tree = bvhtree_from_mesh_edges_create_tree( - mesh->mvert, mesh->medge, mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6); + verts.data(), edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6); break; case BVHTREE_FROM_FACES: BLI_assert(!(mesh->totface == 0 && mesh->totpoly != 0)); data->tree = bvhtree_from_mesh_faces_create_tree( - 0.0f, tree_type, 6, mesh->mvert, mesh->mface, mesh->totface, nullptr, -1); + 0.0f, + tree_type, + 6, + verts.data(), + (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), + mesh->totface, + nullptr, + -1); break; case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: { blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh); mask = looptri_no_hidden_map_get( - mesh->mpoly, + mesh->polygons().data(), attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false), looptri_len, &mask_bits_act_len); @@ -1294,8 +1306,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f, tree_type, 6, - mesh->mvert, - mesh->mloop, + verts.data(), + loops.data(), looptri, looptri_len, mask, diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 8622174231c..ef3d71cdacf 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -97,7 +97,7 @@ static BVHTree *bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon) } } else { - MEdge *edges = cloth->edges; + const MEdge *edges = cloth->edges; for (int i = 0; i < cloth->primitive_num; i++) { float co[2][3]; @@ -177,7 +177,7 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving, bool self) } else { if (verts) { - MEdge *edges = cloth->edges; + const MEdge *edges = cloth->edges; for (i = 0; i < cloth->primitive_num; i++) { float co[2][3]; @@ -258,7 +258,7 @@ static int do_step_cloth( cloth = clmd->clothObject; verts = cloth->verts; - mvert = result->mvert; + mvert = BKE_mesh_vertices_for_write(result); vert_mass_changed = verts->mass != clmd->sim_parms->mass; /* force any pinned verts to their constrained location. */ @@ -713,7 +713,6 @@ static bool cloth_from_object( Object *ob, ClothModifierData *clmd, Mesh *mesh, float UNUSED(framenr), int first) { int i = 0; - MVert *mvert = NULL; ClothVertex *verts = NULL; const float(*shapekey_rest)[3] = NULL; const float tnull[3] = {0, 0, 0}; @@ -755,7 +754,7 @@ static bool cloth_from_object( shapekey_rest = CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO); } - mvert = mesh->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(mesh); verts = clmd->clothObject->verts; @@ -824,7 +823,7 @@ static bool cloth_from_object( static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh) { - const MLoop *mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh); const unsigned int mvert_num = mesh->totvert; const unsigned int looptri_num = mesh->runtime.looptris.len; @@ -859,7 +858,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes } BKE_mesh_runtime_verttri_from_looptri(clmd->clothObject->tri, mloop, looptri, looptri_num); - clmd->clothObject->edges = mesh->medge; + clmd->clothObject->edges = BKE_mesh_edges(mesh); /* Free the springs since they can't be correct if the vertices * changed. @@ -1150,7 +1149,7 @@ static void cloth_update_springs(ClothModifierData *clmd) static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh) { unsigned int i = 0; - MVert *mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); ClothVertex *verts = clmd->clothObject->verts; /* vertex count is already ensured to match */ @@ -1165,7 +1164,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh) { Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false); ClothVertex *verts = clmd->clothObject->verts; - MVert *mvert = new_mesh->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(mesh); /* vertex count is already ensured to match */ for (unsigned i = 0; i < mesh->totvert; i++, verts++) { @@ -1459,9 +1458,9 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) unsigned int numedges = (unsigned int)mesh->totedge; unsigned int numpolys = (unsigned int)mesh->totpoly; float shrink_factor; - const MEdge *medge = mesh->medge; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; + const MEdge *medge = BKE_mesh_edges(mesh); + const MPoly *mpoly = BKE_mesh_polygons(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); int index2 = 0; /* our second vertex index */ LinkNodePair *edgelist = NULL; EdgeSet *edgeset = NULL; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 071fa5fe6bf..50b620c42bb 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -531,6 +531,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ if (me_eval) { const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval); const MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT); + const MVert *verts = BKE_mesh_vertices(me_eval); int numVerts = me_eval->totvert; /* check that dvert is a valid pointers (just in case) */ @@ -539,7 +540,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ /* get the average of all verts with that are in the vertex-group */ for (int i = 0; i < numVerts; i++) { const MDeformVert *dv = &dvert[i]; - const MVert *mv = &me_eval->mvert[i]; + const MVert *mv = &verts[i]; const MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup); if (dw && dw->weight > 0.0f) { diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index fdd269bd9c8..17fb9fdb03e 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -182,19 +182,22 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, float (*mappedcos)[3], float (*quats)[4]) { + using namespace blender; + using namespace blender::bke; BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ - MVert *mvert = me->mvert; - MPoly *mp = me->mpoly; - MLoop *mloop = me->mloop; + const Span<MVert> verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); - for (int i = 0; i < me->totpoly; i++, mp++) { - MLoop *ml_next = &mloop[mp->loopstart]; - MLoop *ml_curr = &ml_next[mp->totloop - 1]; - MLoop *ml_prev = &ml_next[mp->totloop - 2]; + for (int i = 0; i < me->totpoly; i++) { + const MPoly *poly = &polys[i]; + const MLoop *ml_next = &loops[poly->loopstart]; + const MLoop *ml_curr = &ml_next[poly->totloop - 1]; + const MLoop *ml_prev = &ml_next[poly->totloop - 2]; - for (int j = 0; j < mp->totloop; j++) { + for (int j = 0; j < poly->totloop; j++) { if (!BLI_BITMAP_TEST(vert_tag, ml_curr->v)) { const float *co_prev, *co_curr, *co_next; /* orig */ const float *vd_prev, *vd_curr, *vd_next; /* deform */ @@ -210,9 +213,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, co_next = origcos[ml_next->v]; } else { - co_prev = mvert[ml_prev->v].co; - co_curr = mvert[ml_curr->v].co; - co_next = mvert[ml_next->v].co; + co_prev = verts[ml_prev->v].co; + co_curr = verts[ml_curr->v].co; + co_next = verts[ml_next->v].co; } set_crazy_vertex_quat( diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 7f051b683b4..47cd8495b18 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -640,10 +640,10 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, offsets.vert.last(), offsets.edge.last(), 0, offsets.loop.last(), offsets.poly.last()); mesh->flag |= ME_AUTOSMOOTH; mesh->smoothresh = DEG2RADF(180.0f); - MutableSpan<MVert> verts(mesh->mvert, mesh->totvert); - MutableSpan<MEdge> edges(mesh->medge, mesh->totedge); - MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop); - MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly); + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { fill_mesh_topology(info.vert_range.start(), diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 02b5175f65f..4c8b7a590ed 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -256,13 +256,14 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, { if (dtdata_type == DT_TYPE_LNOR) { /* Compute custom normals into regular loop normals, which will be used for the transfer. */ - MVert *verts_dst = me_dst->mvert; + + const MVert *verts_dst = BKE_mesh_vertices(me_dst); const int num_verts_dst = me_dst->totvert; - MEdge *edges_dst = me_dst->medge; + const MEdge *edges_dst = BKE_mesh_edges(me_dst); const int num_edges_dst = me_dst->totedge; - MPoly *polys_dst = me_dst->mpoly; + const MPoly *polys_dst = BKE_mesh_polygons(me_dst); const int num_polys_dst = me_dst->totpoly; - MLoop *loops_dst = me_dst->mloop; + const MLoop *loops_dst = BKE_mesh_loops(me_dst); const int num_loops_dst = me_dst->totloop; CustomData *ldata_dst = &me_dst->ldata; @@ -318,13 +319,13 @@ static void data_transfer_dtdata_type_postprocess(Object *UNUSED(ob_src), } /* Bake edited destination loop normals into custom normals again. */ - MVert *verts_dst = me_dst->mvert; + const MVert *verts_dst = BKE_mesh_vertices(me_dst); const int num_verts_dst = me_dst->totvert; - MEdge *edges_dst = me_dst->medge; + MEdge *edges_dst = BKE_mesh_edges_for_write(me_dst); const int num_edges_dst = me_dst->totedge; - MPoly *polys_dst = me_dst->mpoly; + MPoly *polys_dst = BKE_mesh_polygons_for_write(me_dst); const int num_polys_dst = me_dst->totpoly; - MLoop *loops_dst = me_dst->mloop; + MLoop *loops_dst = BKE_mesh_loops_for_write(me_dst); const int num_loops_dst = me_dst->totloop; CustomData *ldata_dst = &me_dst->ldata; @@ -946,8 +947,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_mode, mix_factor, mix_weights, - me_src->mvert, - me_dst->mvert, + BKE_mesh_vertices(me_src), + BKE_mesh_vertices_for_write(me_dst), me_src->totvert, me_dst->totvert, elem_size, @@ -979,9 +980,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, me_dst != ob_dst->data, fromlayers, tolayers); - - /* Mesh stores its dvert in a specific pointer too. :( */ - me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT); return ret; } if (cddata_type == CD_FAKE_SHAPEKEY) { @@ -1034,8 +1032,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_mode, mix_factor, mix_weights, - me_src->medge, - me_dst->medge, + BKE_mesh_edges(me_src), + BKE_mesh_edges_for_write(me_dst), me_src->totedge, me_dst->totedge, elem_size, @@ -1066,8 +1064,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_mode, mix_factor, mix_weights, - me_src->medge, - me_dst->medge, + BKE_mesh_edges(me_src), + BKE_mesh_edges_for_write(me_dst), me_src->totedge, me_dst->totedge, elem_size, @@ -1090,8 +1088,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_mode, mix_factor, mix_weights, - me_src->medge, - me_dst->medge, + BKE_mesh_edges(me_src), + BKE_mesh_edges_for_write(me_dst), me_src->totedge, me_dst->totedge, elem_size, @@ -1184,8 +1182,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_mode, mix_factor, mix_weights, - me_src->mpoly, - me_dst->mpoly, + BKE_mesh_polygons(me_src), + BKE_mesh_polygons_for_write(me_dst), me_src->totpoly, me_dst->totpoly, elem_size, @@ -1432,7 +1430,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } BKE_mesh_remap_find_best_match_from_mesh( - me_dst->mvert, me_dst->totvert, me_src, space_transform); + BKE_mesh_vertices(me_dst), me_dst->totvert, me_src, space_transform); } /* Check all possible data types. @@ -1460,7 +1458,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } if (DT_DATATYPE_IS_VERT(dtdata_type)) { - MVert *verts_dst = me_dst->mvert; + MVert *verts_dst = BKE_mesh_vertices_for_write(me_dst); const int num_verts_dst = me_dst->totvert; if (!geom_map_init[VDATA]) { @@ -1542,9 +1540,9 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } } if (DT_DATATYPE_IS_EDGE(dtdata_type)) { - MVert *verts_dst = me_dst->mvert; + const MVert *verts_dst = BKE_mesh_vertices_for_write(me_dst); const int num_verts_dst = me_dst->totvert; - MEdge *edges_dst = me_dst->medge; + const MEdge *edges_dst = BKE_mesh_edges(me_dst); const int num_edges_dst = me_dst->totedge; if (!geom_map_init[EDATA]) { @@ -1621,13 +1619,13 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } } if (DT_DATATYPE_IS_LOOP(dtdata_type)) { - MVert *verts_dst = me_dst->mvert; + const MVert *verts_dst = BKE_mesh_vertices(me_dst); const int num_verts_dst = me_dst->totvert; - MEdge *edges_dst = me_dst->medge; + const MEdge *edges_dst = BKE_mesh_edges(me_dst); const int num_edges_dst = me_dst->totedge; - MPoly *polys_dst = me_dst->mpoly; + const MPoly *polys_dst = BKE_mesh_polygons(me_dst); const int num_polys_dst = me_dst->totpoly; - MLoop *loops_dst = me_dst->mloop; + const MLoop *loops_dst = BKE_mesh_loops(me_dst); const int num_loops_dst = me_dst->totloop; CustomData *ldata_dst = &me_dst->ldata; @@ -1716,11 +1714,11 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } } if (DT_DATATYPE_IS_POLY(dtdata_type)) { - MVert *verts_dst = me_dst->mvert; + const MVert *verts_dst = BKE_mesh_vertices(me_dst); const int num_verts_dst = me_dst->totvert; - MPoly *polys_dst = me_dst->mpoly; + const MPoly *polys_dst = BKE_mesh_polygons(me_dst); const int num_polys_dst = me_dst->totpoly; - MLoop *loops_dst = me_dst->mloop; + const MLoop *loops_dst = BKE_mesh_loops(me_dst); const int num_loops_dst = me_dst->totloop; if (!geom_map_init[PDATA]) { diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index d904744995d..f928079f3ea 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -1030,7 +1030,7 @@ void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, const int defgroup, const int num_verts, - MEdge *edges, + const MEdge *edges, const int num_edges, const bool invert_vgroup, float *r_weights) @@ -1043,7 +1043,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, dvert, defgroup, num_verts, invert_vgroup, tmp_weights); while (i--) { - MEdge *me = &edges[i]; + const MEdge *me = &edges[i]; r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f; } @@ -1058,7 +1058,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, const int defgroup, const int num_verts, - MLoop *loops, + const MLoop *loops, const int num_loops, const bool invert_vgroup, float *r_weights) @@ -1071,7 +1071,7 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, dvert, defgroup, num_verts, invert_vgroup, tmp_weights); while (i--) { - MLoop *ml = &loops[i]; + const MLoop *ml = &loops[i]; r_weights[i] = tmp_weights[ml->v]; } @@ -1086,9 +1086,9 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, const int defgroup, const int num_verts, - MLoop *loops, + const MLoop *loops, const int UNUSED(num_loops), - MPoly *polys, + const MPoly *polys, const int num_polys, const bool invert_vgroup, float *r_weights) @@ -1101,8 +1101,8 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, dvert, defgroup, num_verts, invert_vgroup, tmp_weights); while (i--) { - MPoly *mp = &polys[i]; - MLoop *ml = &loops[mp->loopstart]; + const MPoly *mp = &polys[i]; + const MLoop *ml = &loops[mp->loopstart]; int j = mp->totloop; float w = 0.0f; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 8a41b2294f5..9c09ebb6973 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1402,24 +1402,24 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b /* For vertex format, count every vertex that is connected by an edge */ int numOfEdges = mesh->totedge; int numOfPolys = mesh->totpoly; - struct MEdge *edge = mesh->medge; - struct MPoly *mpoly = mesh->mpoly; - struct MLoop *mloop = mesh->mloop; + const MEdge *edges = BKE_mesh_edges(mesh); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); /* count number of edges per vertex */ for (int i = 0; i < numOfEdges; i++) { - ad->n_num[edge[i].v1]++; - ad->n_num[edge[i].v2]++; + ad->n_num[edges[i].v1]++; + ad->n_num[edges[i].v2]++; - temp_data[edge[i].v1]++; - temp_data[edge[i].v2]++; + temp_data[edges[i].v1]++; + temp_data[edges[i].v2]++; } /* also add number of vertices to temp_data * to locate points on "mesh edge" */ for (int i = 0; i < numOfPolys; i++) { - for (int j = 0; j < mpoly[i].totloop; j++) { - temp_data[mloop[mpoly[i].loopstart + j].v]++; + for (int j = 0; j < polys[i].totloop; j++) { + temp_data[loops[polys[i].loopstart + j].v]++; } } @@ -1444,15 +1444,15 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b /* and now add neighbor data using that info */ for (int i = 0; i < numOfEdges; i++) { /* first vertex */ - int index = edge[i].v1; + int index = edges[i].v1; n_pos = ad->n_index[index] + temp_data[index]; - ad->n_target[n_pos] = edge[i].v2; + ad->n_target[n_pos] = edges[i].v2; temp_data[index]++; /* second vertex */ - index = edge[i].v2; + index = edges[i].v2; n_pos = ad->n_index[index] + temp_data[index]; - ad->n_target[n_pos] = edge[i].v1; + ad->n_target[n_pos] = edges[i].v1; temp_data[index]++; } } @@ -1604,7 +1604,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { Tex *tex = surface->init_texture; - const MLoop *mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); const int tottri = BKE_mesh_runtime_looptri_len(mesh); @@ -1660,7 +1660,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* for vertex surface, just copy colors from mcol */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { - const MLoop *mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); const int totloop = mesh->totloop; const MLoopCol *col = CustomData_get_layer_named( &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); @@ -1811,7 +1811,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh /* displace paint */ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { - MVert *mvert = result->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(result); DynamicPaintModifierApplyData data = { .surface = surface, @@ -1913,9 +1913,9 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* vertex color paint */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { - MLoop *mloop = result->mloop; + const MLoop *mloop = BKE_mesh_loops(result); const int totloop = result->totloop; - MPoly *mpoly = result->mpoly; + const MPoly *mpoly = BKE_mesh_polygons(result); const int totpoly = result->totpoly; /* paint is stored on dry and wet layers, so mix final color first */ @@ -1989,8 +1989,6 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) { dvert = CustomData_add_layer( &result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, sData->total_points); - /* Make the dvert layer easily accessible from the mesh data. */ - result->dvert = dvert; } if (defgrp_index != -1 && dvert) { for (int i = 0; i < sData->total_points; i++) { @@ -2012,7 +2010,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } /* wave simulation */ else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { - MVert *mvert = result->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(result); DynamicPaintModifierApplyData data = { .surface = surface, @@ -2823,7 +2821,7 @@ int dynamicPaint_createUVSurface(Scene *scene, return setError(canvas, N_("Cannot bake non-'image sequence' formats")); } - mloop = mesh->mloop; + mloop = BKE_mesh_loops(mesh); mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); const int tottri = BKE_mesh_runtime_looptri_len(mesh); @@ -2963,7 +2961,7 @@ int dynamicPaint_createUVSurface(Scene *scene, BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map, &vert_to_looptri_map_mem, - mesh->mvert, + BKE_mesh_vertices_for_write(mesh), mesh->totvert, mlooptri, tottri, @@ -3783,7 +3781,8 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, eModifierType_DynamicPaint); mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false); numOfVerts_p = mesh_p->totvert; - mvert_p = mesh_p->mvert; + + mvert_p = BKE_mesh_vertices_for_write(mesh_p); copy_m4_m4(prev_obmat, ob->obmat); /* current frame mesh */ @@ -3799,7 +3798,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, eModifierType_DynamicPaint); mesh_c = dynamicPaint_brush_mesh_get(brush); numOfVerts_c = mesh_c->totvert; - mvert_c = mesh_c->mvert; + mvert_c = BKE_mesh_vertices_for_write(mesh_c); (*brushVel) = (struct Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f), "Dynamic Paint brush velocity"); @@ -4270,10 +4269,10 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, VolumeGrid *grid = bData->grid; mesh = BKE_mesh_copy_for_eval(brush_mesh, false); - mvert = mesh->mvert; + mvert = BKE_mesh_vertices_for_write(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); - mloop = mesh->mloop; + mloop = BKE_mesh_loops(mesh); numOfVerts = mesh->totvert; /* Transform collider vertices to global space @@ -4759,7 +4758,7 @@ static bool dynamicPaint_paintSinglePoint( } const Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush); - const MVert *mvert = brush_mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(brush_mesh); /* * Loop through every surface point @@ -5862,7 +5861,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; Mesh *mesh = dynamicPaint_canvas_mesh_get(surface->canvas); - MVert *mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); int numOfVerts = mesh->totvert; @@ -6022,7 +6021,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0; int canvasNumOfVerts = mesh->totvert; - MVert *mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); Vec3f *canvas_verts; if (bData) { diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 7722c2fa004..f2fce3edb88 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -700,9 +700,10 @@ bool get_effector_data(EffectorCache *eff, else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) { /* TODO: hair and points object support */ const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob); + const MVert *verts = BKE_mesh_vertices(me_eval); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval); if (me_eval != NULL) { - copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co); + copy_v3_v3(efd->loc, verts[*efd->index].co); copy_v3_v3(efd->nor, vert_normals[*efd->index]); mul_m4_v3(eff->ob->obmat, efd->loc); diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 74ff10cc32c..24c61a792eb 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -403,7 +403,8 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds, size_t i; float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; float size[3]; - MVert *verts = me->mvert; + + MVert *verts = BKE_mesh_vertices_for_write(me); float scale = 0.0; int res; @@ -994,9 +995,7 @@ static void obstacles_from_mesh(Object *coll_ob, { if (fes->mesh) { Mesh *me = NULL; - MVert *mvert = NULL; const MLoopTri *looptri; - const MLoop *mloop; BVHTreeFromMesh tree_data = {NULL}; int numverts, i; @@ -1008,13 +1007,9 @@ static void obstacles_from_mesh(Object *coll_ob, int min[3], max[3], res[3]; /* Duplicate vertices to modify. */ - if (me->mvert) { - me->mvert = MEM_dupallocN(me->mvert); - CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert); - } + MVert *verts = MEM_dupallocN(BKE_mesh_vertices(me)); - mvert = me->mvert; - mloop = me->mloop; + const MLoop *mloop = BKE_mesh_loops(me); looptri = BKE_mesh_runtime_looptri_ensure(me); numverts = me->totvert; @@ -1041,11 +1036,11 @@ static void obstacles_from_mesh(Object *coll_ob, float co[3]; /* Vertex position. */ - mul_m4_v3(coll_ob->obmat, mvert[i].co); - manta_pos_to_cell(fds, mvert[i].co); + mul_m4_v3(coll_ob->obmat, verts[i].co); + manta_pos_to_cell(fds, verts[i].co); /* Vertex velocity. */ - add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift); + add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift); if (has_velocity) { sub_v3_v3v3(&vert_vel[i * 3], co, &fes->verts_old[i * 3]); mul_v3_fl(&vert_vel[i * 3], 1.0f / dt); @@ -1053,7 +1048,7 @@ static void obstacles_from_mesh(Object *coll_ob, copy_v3_v3(&fes->verts_old[i * 3], co); /* Calculate emission map bounds. */ - bb_boundInsert(bb, mvert[i].co); + bb_boundInsert(bb, verts[i].co); } /* Set emission map. @@ -1075,7 +1070,7 @@ static void obstacles_from_mesh(Object *coll_ob, ObstaclesFromDMData data = { .fes = fes, - .mvert = mvert, + .mvert = verts, .mloop = mloop, .mlooptri = looptri, .tree = &tree_data, @@ -1098,9 +1093,7 @@ static void obstacles_from_mesh(Object *coll_ob, if (vert_vel) { MEM_freeN(vert_vel); } - if (me->mvert) { - MEM_freeN(me->mvert); - } + MEM_SAFE_FREE(verts); BKE_id_free(NULL, me); } } @@ -2080,16 +2073,12 @@ static void emit_from_mesh( Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, true); /* Duplicate vertices to modify. */ - if (me->mvert) { - me->mvert = MEM_dupallocN(me->mvert); - CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert); - } + MVert *verts = MEM_dupallocN(BKE_mesh_vertices(me)); - MVert *mvert = me->mvert; - const MLoop *mloop = me->mloop; + const MLoop *mloop = BKE_mesh_loops(me); const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); const int numverts = me->totvert; - const MDeformVert *dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT); + const MDeformVert *dvert = BKE_mesh_deform_verts(me); const MLoopUV *mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ffs->uvlayer_name); if (ffs->flags & FLUID_FLOW_INITVELOCITY) { @@ -2109,12 +2098,11 @@ static void emit_from_mesh( /* Transform mesh vertices to domain grid space for fast lookups. * This is valid because the mesh is copied above. */ - BKE_mesh_vertex_normals_ensure(me); - float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me); + float(*vert_normals)[3] = MEM_dupallocN(BKE_mesh_vertex_normals_ensure(me)); for (i = 0; i < numverts; i++) { /* Vertex position. */ - mul_m4_v3(flow_ob->obmat, mvert[i].co); - manta_pos_to_cell(fds, mvert[i].co); + mul_m4_v3(flow_ob->obmat, verts[i].co); + manta_pos_to_cell(fds, verts[i].co); /* Vertex normal. */ mul_mat3_m4_v3(flow_ob->obmat, vert_normals[i]); @@ -2124,7 +2112,7 @@ static void emit_from_mesh( /* Vertex velocity. */ if (ffs->flags & FLUID_FLOW_INITVELOCITY) { float co[3]; - add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift); + add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift); if (has_velocity) { sub_v3_v3v3(&vert_vel[i * 3], co, &ffs->verts_old[i * 3]); mul_v3_fl(&vert_vel[i * 3], 1.0 / dt); @@ -2133,7 +2121,7 @@ static void emit_from_mesh( } /* Calculate emission map bounds. */ - bb_boundInsert(bb, mvert[i].co); + bb_boundInsert(bb, verts[i].co); } mul_m4_v3(flow_ob->obmat, flow_center); manta_pos_to_cell(fds, flow_center); @@ -2158,7 +2146,7 @@ static void emit_from_mesh( EmitFromDMData data = { .fds = fds, .ffs = ffs, - .mvert = mvert, + .mvert = verts, .vert_normals = vert_normals, .mloop = mloop, .mlooptri = mlooptri, @@ -2186,9 +2174,8 @@ static void emit_from_mesh( if (vert_vel) { MEM_freeN(vert_vel); } - if (me->mvert) { - MEM_freeN(me->mvert); - } + MEM_SAFE_FREE(verts); + MEM_SAFE_FREE(vert_normals); BKE_id_free(NULL, me); } } @@ -3241,7 +3228,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, * If there are no faces in original mesh, keep materials and flags unchanged. */ MPoly *mpoly; MPoly mp_example = {0}; - mpoly = orgmesh->mpoly; + mpoly = BKE_mesh_polygons_for_write(orgmesh); if (mpoly) { mp_example = *mpoly; } @@ -3273,9 +3260,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, if (!me) { return NULL; } - mverts = me->mvert; - mpolys = me->mpoly; - mloops = me->mloop; + mverts = BKE_mesh_vertices_for_write(me); + mpolys = BKE_mesh_polygons_for_write(me); + mloops = BKE_mesh_loops_for_write(me); /* Get size (dimension) but considering scaling. */ copy_v3_v3(cell_size_scaled, fds->cell_size); @@ -3409,9 +3396,9 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje } result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces); - mverts = result->mvert; - mpolys = result->mpoly; - mloops = result->mloop; + mverts = BKE_mesh_vertices_for_write(result); + mpolys = BKE_mesh_polygons_for_write(result); + mloops = BKE_mesh_loops_for_write(result); if (num_verts) { /* Volume bounds. */ diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index ff55409d5fc..f5f667a02eb 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -134,8 +134,8 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh, * instead of the GeometryComponent API to avoid calculating unnecessary values and to * allow normalizing the result more simply. */ Span<float3> vert_normals{(float3 *)BKE_mesh_vertex_normals_ensure(&mesh), mesh.totvert}; + const Span<MEdge> edges = mesh.edges(); Array<float3> edge_normals(mask.min_array_size()); - Span<MEdge> edges{mesh.medge, mesh.totedge}; for (const int i : mask) { const MEdge &edge = edges[i]; edge_normals[i] = math::normalize( @@ -175,11 +175,13 @@ static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totvert); + const Span<MLoop> loops = mesh.loops(); + attribute_math::DefaultMixer<T> mixer(r_values); for (const int loop_index : IndexRange(mesh.totloop)) { const T value = old_values[loop_index]; - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const int point_index = loop.v; mixer.mix_in(point_index, value); } @@ -193,11 +195,13 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh, MutableSpan<bool> r_values) { BLI_assert(r_values.size() == mesh.totvert); + const Span<MLoop> loops = mesh.loops(); + Array<bool> loose_verts(mesh.totvert, true); r_values.fill(true); for (const int loop_index : IndexRange(mesh.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const int point_index = loop.v; loose_verts[point_index] = false; @@ -235,12 +239,14 @@ static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray */ static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray &varray) { + const Span<MLoop> loops = mesh.loops(); + GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); new_varray = VArray<T>::ForFunc(mesh.totloop, - [&mesh, varray = varray.typed<T>()](const int64_t loop_index) { - const int vertex_index = mesh.mloop[loop_index].v; + [loops, varray = varray.typed<T>()](const int64_t loop_index) { + const int vertex_index = loops[loop_index].v; return varray[vertex_index]; }); }); @@ -249,15 +255,17 @@ static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray &varray) { + const Span<MPoly> polys = mesh.polygons(); + GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) { if constexpr (std::is_same_v<T, bool>) { new_varray = VArray<T>::ForFunc( - mesh.totpoly, [&mesh, varray = varray.typed<bool>()](const int face_index) { + polys.size(), [polys, varray = varray.typed<bool>()](const int face_index) { /* A face is selected if all of its corners were selected. */ - const MPoly &poly = mesh.mpoly[face_index]; + const MPoly &poly = polys[face_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { if (!varray[loop_index]) { return false; @@ -268,10 +276,10 @@ static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray } else { new_varray = VArray<T>::ForFunc( - mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) { + polys.size(), [polys, varray = varray.typed<T>()](const int face_index) { T return_value; attribute_math::DefaultMixer<T> mixer({&return_value, 1}); - const MPoly &poly = mesh.mpoly[face_index]; + const MPoly &poly = polys[face_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { const T value = varray[loop_index]; mixer.mix_in(0, value); @@ -291,17 +299,20 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totedge); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + attribute_math::DefaultMixer<T> mixer(r_values); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; /* For every edge, mix values from the two adjacent corners (the current and next corner). */ for (const int i : IndexRange(poly.totloop)) { const int next_i = (i + 1) % poly.totloop; const int loop_i = poly.loopstart + i; const int next_loop_i = poly.loopstart + next_i; - const MLoop &loop = mesh.mloop[loop_i]; + const MLoop &loop = loops[loop_i]; const int edge_index = loop.e; mixer.mix_in(edge_index, old_values[loop_i]); mixer.mix_in(edge_index, old_values[next_loop_i]); @@ -318,19 +329,21 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh, MutableSpan<bool> r_values) { BLI_assert(r_values.size() == mesh.totedge); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); /* It may be possible to rely on the #ME_LOOSEEDGE flag, but that seems error-prone. */ Array<bool> loose_edges(mesh.totedge, true); r_values.fill(true); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; for (const int i : IndexRange(poly.totloop)) { const int next_i = (i + 1) % poly.totloop; const int loop_i = poly.loopstart + i; const int next_loop_i = poly.loopstart + next_i; - const MLoop &loop = mesh.mloop[loop_i]; + const MLoop &loop = loops[loop_i]; const int edge_index = loop.e; loose_edges[edge_index] = false; @@ -371,13 +384,16 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totvert); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + attribute_math::DefaultMixer<T> mixer(r_values); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; const T value = old_values[poly_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const int point_index = loop.v; mixer.mix_in(point_index, value); } @@ -393,13 +409,15 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh, MutableSpan<bool> r_values) { BLI_assert(r_values.size() == mesh.totvert); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); r_values.fill(false); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; if (old_values[poly_index]) { for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const int vert_index = loop.v; r_values[vert_index] = true; } @@ -428,10 +446,11 @@ void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totloop); + const Span<MPoly> polys = mesh.polygons(); - threading::parallel_for(IndexRange(mesh.totpoly), 1024, [&](const IndexRange range) { + threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { for (const int poly_index : range) { - const MPoly &poly = mesh.mpoly[poly_index]; + const MPoly &poly = polys[poly_index]; MutableSpan<T> poly_corner_values = r_values.slice(poly.loopstart, poly.totloop); poly_corner_values.fill(old_values[poly_index]); } @@ -458,13 +477,16 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totedge); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + attribute_math::DefaultMixer<T> mixer(r_values); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; const T value = old_values[poly_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; mixer.mix_in(loop.e, value); } } @@ -478,13 +500,15 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh, MutableSpan<bool> r_values) { BLI_assert(r_values.size() == mesh.totedge); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); r_values.fill(false); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; if (old_values[poly_index]) { for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const int edge_index = loop.e; r_values[edge_index] = true; } @@ -508,17 +532,20 @@ static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &v static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &varray) { + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) { if constexpr (std::is_same_v<T, bool>) { new_varray = VArray<T>::ForFunc( - mesh.totpoly, [&mesh, varray = varray.typed<bool>()](const int face_index) { + mesh.totpoly, [loops, polys, varray = varray.typed<bool>()](const int face_index) { /* A face is selected if all of its vertices were selected. */ - const MPoly &poly = mesh.mpoly[face_index]; + const MPoly &poly = polys[face_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; if (!varray[loop.v]) { return false; } @@ -528,12 +555,12 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray & } else { new_varray = VArray<T>::ForFunc( - mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) { + mesh.totpoly, [loops, polys, varray = varray.typed<T>()](const int face_index) { T return_value; attribute_math::DefaultMixer<T> mixer({&return_value, 1}); - const MPoly &poly = mesh.mpoly[face_index]; + const MPoly &poly = polys[face_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const T value = varray[loop.v]; mixer.mix_in(0, value); } @@ -548,6 +575,8 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray & static GVArray adapt_mesh_domain_point_to_edge(const Mesh &mesh, const GVArray &varray) { + const Span<MEdge> edges = mesh.edges(); + GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); @@ -555,17 +584,17 @@ static GVArray adapt_mesh_domain_point_to_edge(const Mesh &mesh, const GVArray & if constexpr (std::is_same_v<T, bool>) { /* An edge is selected if both of its vertices were selected. */ new_varray = VArray<bool>::ForFunc( - mesh.totedge, [&mesh, varray = varray.typed<bool>()](const int edge_index) { - const MEdge &edge = mesh.medge[edge_index]; + edges.size(), [edges, varray = varray.typed<bool>()](const int edge_index) { + const MEdge &edge = edges[edge_index]; return varray[edge.v1] && varray[edge.v2]; }); } else { new_varray = VArray<T>::ForFunc( - mesh.totedge, [&mesh, varray = varray.typed<T>()](const int edge_index) { + edges.size(), [edges, varray = varray.typed<T>()](const int edge_index) { T return_value; attribute_math::DefaultMixer<T> mixer({&return_value, 1}); - const MEdge &edge = mesh.medge[edge_index]; + const MEdge &edge = edges[edge_index]; mixer.mix_in(0, varray[edge.v1]); mixer.mix_in(0, varray[edge.v2]); mixer.finalize(); @@ -583,16 +612,19 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totloop); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + attribute_math::DefaultMixer<T> mixer(r_values); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; /* For every corner, mix the values from the adjacent edges on the face. */ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop; - const MLoop &loop = mesh.mloop[loop_index]; - const MLoop &loop_prev = mesh.mloop[loop_index_prev]; + const MLoop &loop = loops[loop_index]; + const MLoop &loop_prev = loops[loop_index_prev]; mixer.mix_in(loop_index, old_values[loop.e]); mixer.mix_in(loop_index, old_values[loop_prev.e]); } @@ -608,15 +640,17 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, MutableSpan<bool> r_values) { BLI_assert(r_values.size() == mesh.totloop); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); r_values.fill(false); - for (const int poly_index : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop; - const MLoop &loop = mesh.mloop[loop_index]; - const MLoop &loop_prev = mesh.mloop[loop_index_prev]; + const MLoop &loop = loops[loop_index]; + const MLoop &loop_prev = loops[loop_index_prev]; if (old_values[loop.e] && old_values[loop_prev.e]) { r_values[loop_index] = true; } @@ -644,10 +678,12 @@ static void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh, MutableSpan<T> r_values) { BLI_assert(r_values.size() == mesh.totvert); + const Span<MEdge> edges = mesh.edges(); + attribute_math::DefaultMixer<T> mixer(r_values); for (const int edge_index : IndexRange(mesh.totedge)) { - const MEdge &edge = mesh.medge[edge_index]; + const MEdge &edge = edges[edge_index]; const T value = old_values[edge_index]; mixer.mix_in(edge.v1, value); mixer.mix_in(edge.v2, value); @@ -663,10 +699,11 @@ void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh, MutableSpan<bool> r_values) { BLI_assert(r_values.size() == mesh.totvert); + const Span<MEdge> edges = mesh.edges(); r_values.fill(false); - for (const int edge_index : IndexRange(mesh.totedge)) { - const MEdge &edge = mesh.medge[edge_index]; + for (const int edge_index : edges.index_range()) { + const MEdge &edge = edges[edge_index]; if (old_values[edge_index]) { r_values[edge.v1] = true; r_values[edge.v2] = true; @@ -690,6 +727,9 @@ static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray & static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &varray) { + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + GVArray new_varray; attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) { using T = decltype(dummy); @@ -697,10 +737,10 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v if constexpr (std::is_same_v<T, bool>) { /* A face is selected if all of its edges are selected. */ new_varray = VArray<bool>::ForFunc( - mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) { - const MPoly &poly = mesh.mpoly[face_index]; + polys.size(), [loops, polys, varray = varray.typed<T>()](const int face_index) { + const MPoly &poly = polys[face_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; if (!varray[loop.e]) { return false; } @@ -710,12 +750,12 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v } else { new_varray = VArray<T>::ForFunc( - mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) { + polys.size(), [loops, polys, varray = varray.typed<T>()](const int face_index) { T return_value; attribute_math::DefaultMixer<T> mixer({&return_value, 1}); - const MPoly &poly = mesh.mpoly[face_index]; + const MPoly &poly = polys[face_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const T value = varray[loop.e]; mixer.mix_in(0, value); } @@ -878,8 +918,15 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> { const int dvert_index_; public: - VArrayImpl_For_VertexWeights(MDeformVert *dverts, const int totvert, const int dvert_index) - : VMutableArrayImpl<float>(totvert), dverts_(dverts), dvert_index_(dvert_index) + VArrayImpl_For_VertexWeights(MutableSpan<MDeformVert> dverts, const int dvert_index) + : VMutableArrayImpl<float>(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index) + { + } + + VArrayImpl_For_VertexWeights(Span<MDeformVert> dverts, const int dvert_index) + : VMutableArrayImpl<float>(dverts.size()), + dverts_(const_cast<MDeformVert *>(dverts.data())), + dvert_index_(dvert_index) { } @@ -977,12 +1024,12 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { if (vertex_group_index < 0) { return {}; } - if (mesh->dvert == nullptr) { + const Span<MDeformVert> dverts = mesh->deform_verts(); + if (dverts.is_empty()) { static const float default_value = 0.0f; return {VArray<float>::ForSingle(default_value, mesh->totvert), ATTR_DOMAIN_POINT}; } - return {VArray<float>::For<VArrayImpl_For_VertexWeights>( - mesh->dvert, mesh->totvert, vertex_group_index), + return {VArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } @@ -1002,16 +1049,8 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { if (vertex_group_index < 0) { return {}; } - if (mesh->dvert == nullptr) { - BKE_object_defgroup_data_create(&mesh->id); - } - else { - /* Copy the data layer if it is shared with some other mesh. */ - mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer( - &mesh->vdata, CD_MDEFORMVERT, mesh->totvert); - } - return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>( - mesh->dvert, mesh->totvert, vertex_group_index), + MutableSpan<MDeformVert> dverts = mesh->deform_verts_for_write(); + return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, vertex_group_index), ATTR_DOMAIN_POINT}; } @@ -1034,15 +1073,11 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { } BLI_remlink(&mesh->vertex_group_names, group); MEM_freeN(group); - if (mesh->dvert == nullptr) { + if (mesh->deform_verts().is_empty()) { return true; } - /* Copy the data layer if it is shared with some other mesh. */ - mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer( - &mesh->vdata, CD_MDEFORMVERT, mesh->totvert); - - for (MDeformVert &dvert : MutableSpan(mesh->dvert, mesh->totvert)) { + for (MDeformVert &dvert : mesh->deform_verts_for_write()) { MDeformWeight *weight = BKE_defvert_find_index(&dvert, index); BKE_defvert_remove_group(&dvert, weight); for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { @@ -1123,10 +1158,7 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider { */ static ComponentAttributeProviders create_attribute_providers_for_mesh() { - static auto update_custom_data_pointers = [](void *owner) { - Mesh *mesh = static_cast<Mesh *>(owner); - BKE_mesh_update_customdata_pointers(mesh, false); - }; + static auto update_custom_data_pointers = [](void * /*owner*/) {}; #define MAKE_MUTABLE_CUSTOM_DATA_GETTER(NAME) \ [](void *owner) -> CustomData * { \ diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index 0a75b0f5339..9f231c8f5f2 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -2464,6 +2464,9 @@ static void gpencil_generate_edgeloops(Object *ob, if (me->totedge == 0) { return; } + const Span<MVert> verts = me->vertices(); + const Span<MEdge> edges = me->edges(); + const Span<MDeformVert> dverts = me->deform_verts(); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); /* Arrays for all edge vertices (forward and backward) that form a edge loop. @@ -2476,15 +2479,15 @@ static void gpencil_generate_edgeloops(Object *ob, GpEdge *gp_edges = (GpEdge *)MEM_callocN(sizeof(GpEdge) * me->totedge, __func__); GpEdge *gped = nullptr; for (int i = 0; i < me->totedge; i++) { - MEdge *ed = &me->medge[i]; + const MEdge *ed = &edges[i]; gped = &gp_edges[i]; - MVert *mv1 = &me->mvert[ed->v1]; + const MVert *mv1 = &verts[ed->v1]; copy_v3_v3(gped->n1, vert_normals[ed->v1]); gped->v1 = ed->v1; copy_v3_v3(gped->v1_co, mv1->co); - MVert *mv2 = &me->mvert[ed->v2]; + const MVert *mv2 = &verts[ed->v2]; copy_v3_v3(gped->n2, vert_normals[ed->v2]); gped->v2 = ed->v2; copy_v3_v3(gped->v2_co, mv2->co); @@ -2540,8 +2543,7 @@ static void gpencil_generate_edgeloops(Object *ob, gpf_stroke, MAX2(stroke_mat_index, 0), array_len + 1, thickness * thickness, false); /* Create dvert data. */ - MDeformVert *me_dvert = me->dvert; - if (use_vgroups && me_dvert) { + if (use_vgroups && !dverts.is_empty()) { gps_stroke->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * (array_len + 1), "gp_stroke_dverts"); } @@ -2550,7 +2552,7 @@ static void gpencil_generate_edgeloops(Object *ob, float fpt[3]; for (int i = 0; i < array_len + 1; i++) { int vertex_index = i == 0 ? gp_edges[stroke[0]].v1 : gp_edges[stroke[i - 1]].v2; - MVert *mv = &me->mvert[vertex_index]; + const MVert *mv = &verts[vertex_index]; /* Add segment. */ bGPDspoint *pt = &gps_stroke->points[i]; @@ -2563,9 +2565,9 @@ static void gpencil_generate_edgeloops(Object *ob, pt->strength = 1.0f; /* Copy vertex groups from mesh. Assuming they already exist in the same order. */ - if (use_vgroups && me_dvert) { + if (use_vgroups && !dverts.is_empty()) { MDeformVert *dv = &gps_stroke->dvert[i]; - MDeformVert *src_dv = &me_dvert[vertex_index]; + const MDeformVert *src_dv = &dverts[vertex_index]; dv->totweight = src_dv->totweight; dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight, "gp_stroke_dverts_dw"); @@ -2674,8 +2676,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain, /* Use evaluated data to get mesh with all modifiers on top. */ Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh); const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); - const MPoly *mpoly = me_eval->mpoly; - const MLoop *mloop = me_eval->mloop; + const Span<MVert> verts = me_eval->vertices(); + const Span<MPoly> polys = me_eval->polygons(); + const Span<MLoop> loops = me_eval->loops(); int mpoly_len = me_eval->totpoly; char element_name[200]; @@ -2715,7 +2718,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain, const VArray<int> mesh_material_indices = mesh_attributes(*me_eval).lookup_or_default<int>( "material_index", ATTR_DOMAIN_FACE, 0); for (i = 0; i < mpoly_len; i++) { - const MPoly *mp = &mpoly[i]; + const MPoly *mp = &polys[i]; /* Find material. */ int mat_idx = 0; @@ -2739,16 +2742,16 @@ bool BKE_gpencil_convert_mesh(Main *bmain, gps_fill->flag |= GP_STROKE_CYCLIC; /* Create dvert data. */ - MDeformVert *me_dvert = me_eval->dvert; - if (use_vgroups && me_dvert) { + const Span<MDeformVert> dverts = me_eval->deform_verts(); + if (use_vgroups && !dverts.is_empty()) { gps_fill->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * mp->totloop, "gp_fill_dverts"); } /* Add points to strokes. */ for (int j = 0; j < mp->totloop; j++) { - const MLoop *ml = &mloop[mp->loopstart + j]; - const MVert *mv = &me_eval->mvert[ml->v]; + const MLoop *ml = &loops[mp->loopstart + j]; + const MVert *mv = &verts[ml->v]; bGPDspoint *pt = &gps_fill->points[j]; copy_v3_v3(&pt->x, mv->co); @@ -2757,9 +2760,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain, pt->strength = 1.0f; /* Copy vertex groups from mesh. Assuming they already exist in the same order. */ - if (use_vgroups && me_dvert) { + if (use_vgroups && !dverts.is_empty()) { MDeformVert *dv = &gps_fill->dvert[j]; - MDeformVert *src_dv = &me_dvert[ml->v]; + const MDeformVert *src_dv = &dverts[ml->v]; dv->totweight = src_dv->totweight; dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight, "gp_fill_dverts_dw"); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 461a6f15ca1..a09f1e70d06 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1258,7 +1258,7 @@ static void do_key(const int start, static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cache) { - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; BMEditMesh *em = NULL; BMIter iter; BMVert *eve; @@ -1272,7 +1272,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac /* gather dvert and totvert */ if (ob->type == OB_MESH) { Mesh *me = ob->data; - dvert = me->dvert; + dvert = BKE_mesh_deform_verts(me); totvert = me->totvert; if (me->edit_mesh && me->edit_mesh->bm->totvert == totvert) { @@ -1602,8 +1602,9 @@ float *BKE_key_evaluate_object_ex( switch (GS(obdata->name)) { case ID_ME: { Mesh *mesh = (Mesh *)obdata; + MVert *verts = BKE_mesh_vertices_for_write(mesh); const int totvert = min_ii(tot, mesh->totvert); - keyblock_data_convert_to_mesh((const float(*)[3])out, mesh->mvert, totvert); + keyblock_data_convert_to_mesh((const float(*)[3])out, verts, totvert); break; } case ID_LT: { @@ -2168,7 +2169,6 @@ void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nu void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb) { - MVert *mvert; float(*fp)[3]; int a, tot; @@ -2179,7 +2179,7 @@ void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb) return; } - mvert = me->mvert; + const MVert *mvert = BKE_mesh_vertices(me); fp = kb->data; for (a = 0; a < tot; a++, fp++, mvert++) { copy_v3_v3(*fp, mvert->co); @@ -2227,8 +2227,11 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, return; } - MVert *mvert = MEM_dupallocN(mesh->mvert); - BKE_keyblock_convert_to_mesh(kb, mvert, mesh->totvert); + MVert *verts = MEM_dupallocN(BKE_mesh_vertices(mesh)); + BKE_keyblock_convert_to_mesh(kb, verts, mesh->totvert); + const MEdge *edges = BKE_mesh_edges(mesh); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); const bool loop_normals_needed = r_loopnors != NULL; const bool vert_normals_needed = r_vertnors != NULL || loop_normals_needed; @@ -2249,35 +2252,30 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, } if (poly_normals_needed) { - BKE_mesh_calc_normals_poly(mvert, - mesh->totvert, - mesh->mloop, - mesh->totloop, - mesh->mpoly, - mesh->totpoly, - poly_normals); + BKE_mesh_calc_normals_poly( + verts, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals); } if (vert_normals_needed) { - BKE_mesh_calc_normals_poly_and_vertex(mvert, + BKE_mesh_calc_normals_poly_and_vertex(verts, mesh->totvert, - mesh->mloop, + loops, mesh->totloop, - mesh->mpoly, + polys, mesh->totpoly, poly_normals, vert_normals); } if (loop_normals_needed) { short(*clnors)[2] = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* May be NULL. */ - BKE_mesh_normals_loop_split(mvert, + BKE_mesh_normals_loop_split(verts, vert_normals, mesh->totvert, - mesh->medge, + edges, mesh->totedge, - mesh->mloop, + loops, r_loopnors, mesh->totloop, - mesh->mpoly, + polys, poly_normals, mesh->totpoly, (mesh->flag & ME_AUTOSMOOTH) != 0, @@ -2293,7 +2291,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, if (free_poly_normals) { MEM_freeN(poly_normals); } - MEM_freeN(mvert); + MEM_freeN(verts); } /************************* raw coords ************************/ diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c index 40a9d4befdb..3a1c42b9178 100644 --- a/source/blender/blenkernel/intern/lattice_deform.c +++ b/source/blender/blenkernel/intern/lattice_deform.c @@ -30,6 +30,7 @@ #include "BKE_editmesh.h" #include "BKE_key.h" #include "BKE_lattice.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -363,7 +364,7 @@ static void lattice_deform_coords_impl(const Object *ob_lattice, dvert = ((Lattice *)ob_target->data)->dvert; } else { - dvert = ((Mesh *)ob_target->data)->dvert; + dvert = BKE_mesh_deform_verts((Mesh *)ob_target->data); } } } diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c index bfa11b74782..3917c020759 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.c +++ b/source/blender/blenkernel/intern/mball_tessellate.c @@ -1485,8 +1485,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) mesh->totloop = loop_offset; - BKE_mesh_update_customdata_pointers(mesh, false); - BKE_mesh_calc_edges(mesh, false, false); return mesh; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index b44a956eec4..c0379c50de4 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -66,6 +66,7 @@ using blender::float3; using blender::MutableSpan; +using blender::Span; using blender::VArray; using blender::Vector; @@ -146,8 +147,6 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int mesh_tessface_clear_intern(mesh_dst, false); } - BKE_mesh_update_customdata_pointers(mesh_dst, do_tessface); - mesh_dst->cd_flag = mesh_src->cd_flag; mesh_dst->edit_mesh = nullptr; @@ -234,29 +233,32 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address /* Do not store actual geometry data in case this is a library override ID. */ if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) { - mesh->mvert = nullptr; mesh->totvert = 0; memset(&mesh->vdata, 0, sizeof(mesh->vdata)); - mesh->medge = nullptr; mesh->totedge = 0; memset(&mesh->edata, 0, sizeof(mesh->edata)); - mesh->mloop = nullptr; mesh->totloop = 0; memset(&mesh->ldata, 0, sizeof(mesh->ldata)); - mesh->mpoly = nullptr; mesh->totpoly = 0; memset(&mesh->pdata, 0, sizeof(mesh->pdata)); } else { Set<std::string> names_to_skip; if (!BLO_write_is_undo(writer)) { + BKE_mesh_legacy_convert_hide_layers_to_flags(mesh); BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh); /* When converting to the old mesh format, don't save redundant attributes. */ names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly"}); + + /* Set deprecated mesh data pointers for forward compatibility. */ + mesh->mvert = const_cast<MVert *>(mesh->vertices().data()); + mesh->medge = const_cast<MEdge *>(mesh->edges().data()); + mesh->mpoly = const_cast<MPoly *>(mesh->polygons().data()); + mesh->mloop = const_cast<MLoop *>(mesh->loops().data()); } CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip); @@ -295,17 +297,16 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) Mesh *mesh = (Mesh *)id; BLO_read_pointer_array(reader, (void **)&mesh->mat); + /* Deprecated pointers to custom data layers are read here for backward compatibility + * with files where these were owning pointers rather than a view into custom data. */ BLO_read_data_address(reader, &mesh->mvert); BLO_read_data_address(reader, &mesh->medge); BLO_read_data_address(reader, &mesh->mface); - BLO_read_data_address(reader, &mesh->mloop); - BLO_read_data_address(reader, &mesh->mpoly); - BLO_read_data_address(reader, &mesh->tface); BLO_read_data_address(reader, &mesh->mtface); - BLO_read_data_address(reader, &mesh->mcol); BLO_read_data_address(reader, &mesh->dvert); - BLO_read_data_address(reader, &mesh->mloopcol); - BLO_read_data_address(reader, &mesh->mloopuv); + BLO_read_data_address(reader, &mesh->tface); + BLO_read_data_address(reader, &mesh->mcol); + BLO_read_data_address(reader, &mesh->mselect); /* animdata */ @@ -468,6 +469,8 @@ static int customdata_compare( CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR | CD_MASK_MDEFORMVERT; const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic; + const Span<MLoop> loops_1 = m1->loops(); + const Span<MLoop> loops_2 = m2->loops(); for (int i = 0; i < c1->totlayer; i++) { l1 = &c1->layers[i]; @@ -543,15 +546,14 @@ static int customdata_compare( int ptot = m1->totpoly; for (j = 0; j < ptot; j++, p1++, p2++) { - MLoop *lp1, *lp2; int k; if (p1->totloop != p2->totloop) { return MESHCMP_POLYMISMATCH; } - lp1 = m1->mloop + p1->loopstart; - lp2 = m2->mloop + p2->loopstart; + const MLoop *lp1 = &loops_1[p1->loopstart]; + const MLoop *lp2 = &loops_2[p2->loopstart]; for (k = 0; k < p1->totloop; k++, lp1++, lp2++) { if (lp1->v != lp2->v) { @@ -762,47 +764,6 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh) return nullptr; } -static void mesh_ensure_tessellation_customdata(Mesh *me) -{ - if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) { - /* Pass, otherwise this function clears 'mface' before - * versioning 'mface -> mpoly' code kicks in T30583. - * - * Callers could also check but safer to do here - campbell */ - } - else { - const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); - - const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE); - const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL); - - if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) { - BKE_mesh_tessface_clear(me); - - BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface); - - /* TODO: add some `--debug-mesh` option. */ - if (G.debug & G_DEBUG) { - /* NOTE(@campbellbarton): this warning may be un-called for if we are initializing the mesh - * for the first time from #BMesh, rather than giving a warning about this we could be - * smarter and check if there was any data to begin with, for now just print the warning - * with some info to help troubleshoot what's going on. */ - printf( - "%s: warning! Tessellation uvs or vcol data got out of sync, " - "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != " - "CD_PROP_BYTE_COLOR: " - "%d\n", - __func__, - tottex_tessface, - tottex_original, - totcol_tessface, - totcol_original); - } - } - } -} - void BKE_mesh_ensure_skin_customdata(Mesh *me) { BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr; @@ -874,43 +835,6 @@ bool BKE_mesh_clear_facemap_customdata(struct Mesh *me) return changed; } -/** - * This ensures grouped custom-data (e.g. #CD_MLOOPUV and #CD_MTFACE, or - * #CD_PROP_BYTE_COLOR and #CD_MCOL) have the same relative active/render/clone/mask indices. - * - * NOTE(@campbellbarton): that for undo mesh data we want to skip 'ensure_tess_cd' call since - * we don't want to store memory for #MFace data when its only used for older - * versions of the mesh. - */ -static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd) -{ - if (do_ensure_tess_cd) { - mesh_ensure_tessellation_customdata(me); - } - - CustomData_bmesh_update_active_layers(&me->fdata, &me->ldata); -} - -void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd) -{ - mesh_update_linked_customdata(me, do_ensure_tess_cd); - - me->mvert = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT); - me->dvert = (MDeformVert *)CustomData_get_layer(&me->vdata, CD_MDEFORMVERT); - - me->medge = (MEdge *)CustomData_get_layer(&me->edata, CD_MEDGE); - - me->mface = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE); - me->mcol = (MCol *)CustomData_get_layer(&me->fdata, CD_MCOL); - me->mtface = (MTFace *)CustomData_get_layer(&me->fdata, CD_MTFACE); - - me->mpoly = (MPoly *)CustomData_get_layer(&me->pdata, CD_MPOLY); - me->mloop = (MLoop *)CustomData_get_layer(&me->ldata, CD_MLOOP); - - me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR); - me->mloopuv = (MLoopUV *)CustomData_get_layer(&me->ldata, CD_MLOOPUV); -} - bool BKE_mesh_has_custom_loop_normals(Mesh *me) { if (me->edit_mesh) { @@ -954,8 +878,6 @@ static void mesh_clear_geometry(Mesh *mesh) mesh->totpoly = 0; mesh->act_face = -1; mesh->totselect = 0; - - BKE_mesh_update_customdata_pointers(mesh, false); } void BKE_mesh_clear_geometry(Mesh *mesh) @@ -974,9 +896,6 @@ static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata) CustomData_reset(&mesh->fdata); } - mesh->mface = nullptr; - mesh->mtface = nullptr; - mesh->mcol = nullptr; mesh->totface = 0; } @@ -1029,7 +948,6 @@ Mesh *BKE_mesh_new_nomain( mesh->totpoly = polys_len; mesh_ensure_cdlayers_primary(mesh, true); - BKE_mesh_update_customdata_pointers(mesh, false); return mesh; } @@ -1115,7 +1033,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src, /* The destination mesh should at least have valid primary CD layers, * even in cases where the source mesh does not. */ mesh_ensure_cdlayers_primary(me_dst, do_tessface); - BKE_mesh_update_customdata_pointers(me_dst, false); /* Expect that normals aren't copied at all, since the destination mesh is new. */ BLI_assert(BKE_mesh_vertex_normals_are_dirty(me_dst)); @@ -1338,11 +1255,12 @@ float (*BKE_mesh_orco_verts_get(Object *ob))[3] /* Get appropriate vertex coordinates */ float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(me->totvert, sizeof(*vcos), "orco mesh"); - MVert *mvert = tme->mvert; + const Span<MVert> verts = tme->vertices(); + int totvert = min_ii(tme->totvert, me->totvert); - for (int a = 0; a < totvert; a++, mvert++) { - copy_v3_v3(vcos[a], mvert->co); + for (int a = 0; a < totvert; a++) { + copy_v3_v3(vcos[a], verts[a].co); } return vcos; @@ -1512,14 +1430,15 @@ void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len) void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth) { + MutableSpan<MPoly> polys = me->polygons_for_write(); if (use_smooth) { - for (int i = 0; i < me->totpoly; i++) { - me->mpoly[i].flag |= ME_SMOOTH; + for (MPoly &poly : polys) { + poly.flag |= ME_SMOOTH; } } else { - for (int i = 0; i < me->totpoly; i++) { - me->mpoly[i].flag &= ~ME_SMOOTH; + for (MPoly &poly : polys) { + poly.flag &= ~ME_SMOOTH; } } } @@ -1575,9 +1494,12 @@ int BKE_mesh_edge_other_vert(const MEdge *e, int v) void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, int r_edges[3]) { + const Span<MEdge> edges = mesh->edges(); + const Span<MLoop> loops = mesh->loops(); + for (int i = 2, i_next = 0; i_next < 3; i = i_next++) { - const MLoop *l1 = &mesh->mloop[looptri->tri[i]], *l2 = &mesh->mloop[looptri->tri[i_next]]; - const MEdge *e = &mesh->medge[l1->e]; + const MLoop *l1 = &loops[looptri->tri[i]], *l2 = &loops[looptri->tri[i_next]]; + const MEdge *e = &edges[l1->e]; bool is_real = (l1->v == e->v1 && l2->v == e->v2) || (l1->v == e->v2 && l2->v == e->v1); @@ -1596,15 +1518,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3]) float3 min; float3 max; }; + const Span<MVert> verts = me->vertices(); const Result minmax = threading::parallel_reduce( - IndexRange(me->totvert), + verts.index_range(), 1024, Result{float3(FLT_MAX), float3(-FLT_MAX)}, - [&](IndexRange range, const Result &init) { + [verts](IndexRange range, const Result &init) { Result result = init; for (const int i : range) { - math::min_max(float3(me->mvert[i].co), result.min, result.max); + math::min_max(float3(verts[i].co), result.min, result.max); } return result; }, @@ -1620,22 +1543,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3]) void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) { - int i; - MVert *mvert = (MVert *)CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert); - float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer( - &me->ldata, CD_NORMAL, me->totloop); - - /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */ - BKE_mesh_update_customdata_pointers(me, false); + MutableSpan<MVert> verts = me->vertices_for_write(); - for (i = 0; i < me->totvert; i++, mvert++) { - mul_m4_v3(mat, mvert->co); + for (MVert &vert : verts) { + mul_m4_v3(mat, vert.co); } if (do_keys && me->key) { LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) { float *fp = (float *)kb->data; - for (i = kb->totelem; i--; fp += 3) { + for (int i = kb->totelem; i--; fp += 3) { mul_m4_v3(mat, fp); } } @@ -1644,12 +1561,14 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) /* don't update normals, caller can do this explicitly. * We do update loop normals though, those may not be auto-generated * (see e.g. STL import script)! */ + float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer( + &me->ldata, CD_NORMAL, me->totloop); if (lnors) { float m3[3][3]; copy_m3_m4(m3, mat); normalize_m3(m3); - for (i = 0; i < me->totloop; i++, lnors++) { + for (int i = 0; i < me->totloop; i++, lnors++) { mul_m3_v3(m3, *lnors); } } @@ -1658,15 +1577,12 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys) { - CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert); - /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */ - BKE_mesh_update_customdata_pointers(me, false); - - int i = me->totvert; - for (MVert *mvert = me->mvert; i--; mvert++) { - add_v3_v3(mvert->co, offset); + MutableSpan<MVert> verts = me->vertices_for_write(); + for (MVert &vert : verts) { + add_v3_v3(vert.co, offset); } + int i; if (do_keys && me->key) { LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) { float *fp = (float *)kb->data; @@ -1689,25 +1605,24 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) return; } - MVert *mv; - MEdge *med; - int i; + const Span<MVert> verts = mesh->vertices(); + const Span<MEdge> edges = mesh->edges(); - for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) { - if (mv->bweight != 0) { + for (const MVert &vert : verts) { + if (vert.bweight != 0) { mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; break; } } - for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) { - if (med->bweight != 0) { + for (const MEdge &edge : edges) { + if (edge.bweight != 0) { mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT; if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) { break; } } - if (med->crease != 0) { + if (edge.crease != 0) { mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE; if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { break; @@ -1733,6 +1648,9 @@ void BKE_mesh_mselect_validate(Mesh *me) if (me->totselect == 0) { return; } + const Span<MVert> verts = me->vertices(); + const Span<MEdge> edges = me->edges(); + const Span<MPoly> polys = me->polygons(); mselect_src = me->mselect; mselect_dst = (MSelect *)MEM_malloc_arrayN( @@ -1742,21 +1660,21 @@ void BKE_mesh_mselect_validate(Mesh *me) int index = mselect_src[i_src].index; switch (mselect_src[i_src].type) { case ME_VSEL: { - if (me->mvert[index].flag & SELECT) { + if (verts[index].flag & SELECT) { mselect_dst[i_dst] = mselect_src[i_src]; i_dst++; } break; } case ME_ESEL: { - if (me->medge[index].flag & SELECT) { + if (edges[index].flag & SELECT) { mselect_dst[i_dst] = mselect_src[i_src]; i_dst++; } break; } case ME_FSEL: { - if (me->mpoly[index].flag & SELECT) { + if (polys[index].flag & SELECT) { mselect_dst[i_dst] = mselect_src[i_src]; i_dst++; } @@ -1842,10 +1760,10 @@ void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3]) void BKE_mesh_vert_coords_get(const Mesh *mesh, float (*vert_coords)[3]) { - const MVert *mv = mesh->mvert; - for (int i = 0; i < mesh->totvert; i++, mv++) { - copy_v3_v3(vert_coords[i], mv->co); - } + blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh); + VArray<float3> positions = attributes.lookup_or_default( + "position", ATTR_DOMAIN_POINT, float3(0)); + positions.materialize({(float3 *)vert_coords, mesh->totvert}); } float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3] @@ -1860,12 +1778,9 @@ float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3] void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3]) { - /* This will just return the pointer if it wasn't a referenced layer. */ - MVert *mv = (MVert *)CustomData_duplicate_referenced_layer( - &mesh->vdata, CD_MVERT, mesh->totvert); - mesh->mvert = mv; - for (int i = 0; i < mesh->totvert; i++, mv++) { - copy_v3_v3(mv->co, vert_coords[i]); + MutableSpan<MVert> verts = mesh->vertices_for_write(); + for (const int i : verts.index_range()) { + copy_v3_v3(verts[i].co, vert_coords[i]); } BKE_mesh_tag_coords_changed(mesh); } @@ -1874,12 +1789,9 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh, const float (*vert_coords)[3], const float mat[4][4]) { - /* This will just return the pointer if it wasn't a referenced layer. */ - MVert *mv = (MVert *)CustomData_duplicate_referenced_layer( - &mesh->vdata, CD_MVERT, mesh->totvert); - mesh->mvert = mv; - for (int i = 0; i < mesh->totvert; i++, mv++) { - mul_v3_m4v3(mv->co, mat, vert_coords[i]); + MutableSpan<MVert> verts = mesh->vertices_for_write(); + for (const int i : verts.index_range()) { + mul_v3_m4v3(verts[i].co, mat, vert_coords[i]); } BKE_mesh_tag_coords_changed(mesh); } @@ -1915,17 +1827,22 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, /* may be nullptr */ clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); - BKE_mesh_normals_loop_split(mesh->mvert, + const Span<MVert> verts = mesh->vertices(); + const Span<MEdge> edges = mesh->edges(); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); + + BKE_mesh_normals_loop_split(verts.data(), BKE_mesh_vertex_normals_ensure(mesh), - mesh->totvert, - mesh->medge, - mesh->totedge, - mesh->mloop, + verts.size(), + edges.data(), + edges.size(), + loops.data(), r_corner_normals, - mesh->totloop, - mesh->mpoly, + loops.size(), + polys.data(), BKE_mesh_poly_normals_ensure(mesh), - mesh->totpoly, + polys.size(), use_split_normals, split_angle, r_lnors_spacearr, @@ -1971,14 +1888,14 @@ static int split_faces_prepare_new_verts(Mesh *mesh, const int loops_len = mesh->totloop; int verts_len = mesh->totvert; - MLoop *mloop = mesh->mloop; + MutableSpan<MLoop> loops = mesh->loops_for_write(); BKE_mesh_vertex_normals_ensure(mesh); float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh); BLI_bitmap *verts_used = BLI_BITMAP_NEW(verts_len, __func__); BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_len, __func__); - MLoop *ml = mloop; + MLoop *ml = loops.data(); MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr; BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX); @@ -2005,7 +1922,7 @@ static int split_faces_prepare_new_verts(Mesh *mesh, const int ml_fan_idx = POINTER_AS_INT(lnode->link); BLI_BITMAP_ENABLE(done_loops, ml_fan_idx); if (vert_used) { - mloop[ml_fan_idx].v = new_vert_idx; + loops[ml_fan_idx].v = new_vert_idx; } } } @@ -2040,23 +1957,23 @@ static int split_faces_prepare_new_verts(Mesh *mesh, /* Detect needed new edges, and update accordingly loops' edge indices. * WARNING! Leaves mesh in invalid state. */ -static int split_faces_prepare_new_edges(const Mesh *mesh, +static int split_faces_prepare_new_edges(Mesh *mesh, SplitFaceNewEdge **new_edges, MemArena *memarena) { const int num_polys = mesh->totpoly; int num_edges = mesh->totedge; - MEdge *medge = mesh->medge; - MLoop *mloop = mesh->mloop; - const MPoly *mpoly = mesh->mpoly; + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); + const Span<MPoly> polys = mesh->polygons(); BLI_bitmap *edges_used = BLI_BITMAP_NEW(num_edges, __func__); EdgeHash *edges_hash = BLI_edgehash_new_ex(__func__, num_edges); - const MPoly *mp = mpoly; + const MPoly *mp = polys.data(); for (int poly_idx = 0; poly_idx < num_polys; poly_idx++, mp++) { - MLoop *ml_prev = &mloop[mp->loopstart + mp->totloop - 1]; - MLoop *ml = &mloop[mp->loopstart]; + MLoop *ml_prev = &loops[mp->loopstart + mp->totloop - 1]; + MLoop *ml = &loops[mp->loopstart]; for (int loop_idx = 0; loop_idx < mp->totloop; loop_idx++, ml++) { void **eval; if (!BLI_edgehash_ensure_p(edges_hash, ml_prev->v, ml->v, &eval)) { @@ -2080,8 +1997,8 @@ static int split_faces_prepare_new_edges(const Mesh *mesh, } else { /* We can re-use original edge. */ - medge[edge_idx].v1 = ml_prev->v; - medge[edge_idx].v2 = ml->v; + edges[edge_idx].v1 = ml_prev->v; + edges[edge_idx].v2 = ml->v; *eval = POINTER_FROM_INT(edge_idx); BLI_BITMAP_ENABLE(edges_used, edge_idx); } @@ -2107,7 +2024,6 @@ static void split_faces_split_new_verts(Mesh *mesh, const int num_new_verts) { const int verts_len = mesh->totvert - num_new_verts; - MVert *mvert = mesh->mvert; float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh); /* Normals were already calculated at the beginning of this operation, we rely on that to update @@ -2115,8 +2031,7 @@ static void split_faces_split_new_verts(Mesh *mesh, BLI_assert(!BKE_mesh_vertex_normals_are_dirty(mesh)); /* Remember new_verts is a single linklist, so its items are in reversed order... */ - MVert *new_mv = &mvert[mesh->totvert - 1]; - for (int i = mesh->totvert - 1; i >= verts_len; i--, new_mv--, new_verts = new_verts->next) { + for (int i = mesh->totvert - 1; i >= verts_len; i--, new_verts = new_verts->next) { BLI_assert(new_verts->new_index == i); BLI_assert(new_verts->new_index != new_verts->orig_index); CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1); @@ -2132,10 +2047,10 @@ static void split_faces_split_new_edges(Mesh *mesh, const int num_new_edges) { const int num_edges = mesh->totedge - num_new_edges; - MEdge *medge = mesh->medge; + MutableSpan<MEdge> edges = mesh->edges_for_write(); /* Remember new_edges is a single linklist, so its items are in reversed order... */ - MEdge *new_med = &medge[mesh->totedge - 1]; + MEdge *new_med = &edges[mesh->totedge - 1]; for (int i = mesh->totedge - 1; i >= num_edges; i--, new_med--, new_edges = new_edges->next) { BLI_assert(new_edges->new_index == i); BLI_assert(new_edges->new_index != new_edges->orig_index); @@ -2163,14 +2078,6 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals) SplitFaceNewVert *new_verts = nullptr; SplitFaceNewEdge *new_edges = nullptr; - /* Ensure we own the layers, we need to do this before split_faces_prepare_new_verts as it will - * directly assign new indices to existing edges and loops. */ - CustomData_duplicate_referenced_layers(&mesh->vdata, mesh->totvert); - CustomData_duplicate_referenced_layers(&mesh->edata, mesh->totedge); - CustomData_duplicate_referenced_layers(&mesh->ldata, mesh->totloop); - /* Update pointers in case we duplicated referenced layers. */ - BKE_mesh_update_customdata_pointers(mesh, false); - /* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */ const int num_new_verts = split_faces_prepare_new_verts( mesh, &lnors_spacearr, &new_verts, memarena); @@ -2191,8 +2098,6 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals) mesh->totedge += num_new_edges; CustomData_realloc(&mesh->edata, mesh->totedge); } - /* Update pointers to a newly allocated memory. */ - BKE_mesh_update_customdata_pointers(mesh, false); /* Update normals manually to avoid recalculation after this operation. */ mesh->runtime.vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime.vert_normals, diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index fb4a9248d8d..d5671b53267 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -162,9 +162,10 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index, int orig_mesh_index = input_mesh_for_imesh_face(orig_index); BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size()); const Mesh *me = meshes[orig_mesh_index]; + const Span<MPoly> polys = me->polygons(); int index_in_mesh = orig_index - mesh_poly_offset[orig_mesh_index]; BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totpoly); - const MPoly *mp = &me->mpoly[index_in_mesh]; + const MPoly *mp = &polys[index_in_mesh]; if (r_orig_mesh) { *r_orig_mesh = me; } @@ -188,9 +189,10 @@ const MVert *MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index, int orig_mesh_index = input_mesh_for_imesh_vert(orig_index); BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size()); const Mesh *me = meshes[orig_mesh_index]; + const Span<MVert> verts = me->vertices(); int index_in_mesh = orig_index - mesh_vert_offset[orig_mesh_index]; BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totvert); - const MVert *mv = &me->mvert[index_in_mesh]; + const MVert *mv = &verts[index_in_mesh]; if (r_orig_mesh) { *r_orig_mesh = me; } @@ -208,9 +210,10 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index, int orig_mesh_index = input_mesh_for_imesh_edge(orig_index); BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size()); const Mesh *me = meshes[orig_mesh_index]; + const Span<MEdge> edges = me->edges(); int index_in_mesh = orig_index - mesh_edge_offset[orig_mesh_index]; BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totedge); - const MEdge *medge = &me->medge[index_in_mesh]; + const MEdge *medge = &edges[index_in_mesh]; if (r_orig_mesh) { *r_orig_mesh = me; } @@ -306,17 +309,19 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, bool need_face_flip = r_info->has_negative_transform[mi] != r_info->has_negative_transform[0]; Vector<Vert *> verts(me->totvert); - Span<MVert> mverts = Span(me->mvert, me->totvert); + const Span<MVert> mesh_verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); /* Allocate verts * Skip the matrix multiplication for each point when there is no transform for a mesh, * for example when the first mesh is already in the target space. (Note the logic * directly above, which uses an identity matrix with a null input transform). */ if (obmats[mi] == nullptr) { - threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) { + threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) { float3 co; for (int i : range) { - co = float3(mverts[i].co); + co = float3(mesh_verts[i].co); mpq3 mco = mpq3(co.x, co.y, co.z); double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); verts[i] = new Vert(mco, dco, NO_INDEX, i); @@ -324,26 +329,26 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes, }); } else { - threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) { + threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) { float3 co; for (int i : range) { - co = r_info->to_target_transform[mi] * float3(mverts[i].co); + co = r_info->to_target_transform[mi] * float3(mesh_verts[i].co); mpq3 mco = mpq3(co.x, co.y, co.z); double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); verts[i] = new Vert(mco, dco, NO_INDEX, i); } }); } - for (int i : mverts.index_range()) { + for (int i : mesh_verts.index_range()) { r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]); ++v; } - for (const MPoly &poly : Span(me->mpoly, me->totpoly)) { + for (const MPoly &poly : polys) { int flen = poly.totloop; face_vert.resize(flen); face_edge_orig.resize(flen); - const MLoop *l = &me->mloop[poly.loopstart]; + const MLoop *l = &loops[poly.loopstart]; for (int i = 0; i < flen; ++i) { int mverti = r_info->mesh_vert_offset[mi] + l->v; const Vert *fv = r_info->mesh_to_imesh_vert[mverti]; @@ -479,14 +484,16 @@ static int fill_orig_loops(const Face *f, const Mesh *orig_me, int orig_me_index, MeshesToIMeshInfo &mim, - Array<int> &orig_loops) + MutableSpan<int> r_orig_loops) { - orig_loops.fill(-1); + r_orig_loops.fill(-1); + const Span<MLoop> orig_loops = orig_me->loops(); + int orig_mplen = orig_mp->totloop; if (f->size() != orig_mplen) { return 0; } - BLI_assert(orig_loops.size() == orig_mplen); + BLI_assert(r_orig_loops.size() == orig_mplen); /* We'll look for the case where the first vertex in f has an original vertex * that is the same as one in orig_me (after correcting for offset in mim meshes). * Then see that loop and any subsequent ones have the same start and end vertex. @@ -508,7 +515,7 @@ static int fill_orig_loops(const Face *f, int offset = -1; for (int i = 0; i < orig_mplen; ++i) { int loop_i = i + orig_mp->loopstart; - if (orig_me->mloop[loop_i].v == first_orig_v_in_orig_me) { + if (orig_loops[loop_i].v == first_orig_v_in_orig_me) { offset = i; break; } @@ -519,7 +526,7 @@ static int fill_orig_loops(const Face *f, int num_orig_loops_found = 0; for (int mp_loop_index = 0; mp_loop_index < orig_mplen; ++mp_loop_index) { int orig_mp_loop_index = (mp_loop_index + offset) % orig_mplen; - MLoop *l = &orig_me->mloop[orig_mp->loopstart + orig_mp_loop_index]; + const MLoop *l = &orig_loops[orig_mp->loopstart + orig_mp_loop_index]; int fv_orig = f->vert[mp_loop_index]->orig; if (fv_orig != NO_INDEX) { fv_orig -= orig_me_vert_offset; @@ -528,7 +535,8 @@ static int fill_orig_loops(const Face *f, } } if (l->v == fv_orig) { - MLoop *lnext = &orig_me->mloop[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)]; + const MLoop *lnext = + &orig_loops[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)]; int fvnext_orig = f->vert[(mp_loop_index + 1) % orig_mplen]->orig; if (fvnext_orig != NO_INDEX) { fvnext_orig -= orig_me_vert_offset; @@ -537,7 +545,7 @@ static int fill_orig_loops(const Face *f, } } if (lnext->v == fvnext_orig) { - orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index; + r_orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index; ++num_orig_loops_found; } } @@ -555,19 +563,18 @@ static void get_poly2d_cos(const Mesh *me, const float4x4 &trans_mat, float r_axis_mat[3][3]) { - int n = mp->totloop; + const Span<MVert> verts = me->vertices(); + const Span<MLoop> loops = me->loops(); + const Span<MLoop> poly_loops = loops.slice(mp->loopstart, mp->totloop); /* Project coordinates to 2d in cos_2d, using normal as projection axis. */ float axis_dominant[3]; - BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, axis_dominant); + BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts.data(), axis_dominant); axis_dominant_v3_to_m3(r_axis_mat, axis_dominant); - MLoop *ml = &me->mloop[mp->loopstart]; - const MVert *mverts = me->mvert; - for (int i = 0; i < n; ++i) { - float3 co = mverts[ml->v].co; + for (const int i : poly_loops.index_range()) { + float3 co = verts[poly_loops[i].v].co; co = trans_mat * co; mul_v2_m3v3(cos_2d[i], r_axis_mat, co); - ++ml; } } @@ -602,6 +609,8 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, get_poly2d_cos(orig_me, orig_mp, cos_2d, mim.to_target_transform[orig_me_index], axis_mat); } CustomData *target_cd = &dest_mesh->ldata; + const Span<MVert> dst_vertices = dest_mesh->vertices(); + const Span<MLoop> dst_loops = dest_mesh->loops(); for (int i = 0; i < mp->totloop; ++i) { int loop_index = mp->loopstart + i; int orig_loop_index = norig > 0 ? orig_loops[i] : -1; @@ -611,7 +620,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, * The coordinate needs to be projected into 2d, just like the interpolating polygon's * coordinates were. The `dest_mesh` coordinates are already in object 0 local space. */ float co[2]; - mul_v2_m3v3(co, axis_mat, dest_mesh->mvert[dest_mesh->mloop[loop_index].v].co); + mul_v2_m3v3(co, axis_mat, dst_vertices[dst_loops[loop_index].v].co); interp_weights_poly_v2(weights.data(), cos_2d, orig_mp->totloop, co); } for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) { @@ -714,9 +723,10 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) merge_vertex_loop_poly_customdata_layers(result, mim); /* Set the vertex coordinate values and other data. */ + MutableSpan<MVert> vertices = result->vertices_for_write(); for (int vi : im->vert_index_range()) { const Vert *v = im->vert(vi); - MVert *mv = &result->mvert[vi]; + MVert *mv = &vertices[vi]; copy_v3fl_v3db(mv->co, v->co); if (v->orig != NO_INDEX) { const Mesh *orig_me; @@ -732,7 +742,9 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) bke::mesh_attributes_for_write(*result).lookup_or_add_for_write_only_span<int>( "material_index", ATTR_DOMAIN_FACE); int cur_loop_index = 0; - MLoop *l = result->mloop; + MutableSpan<MLoop> dst_loops = result->loops_for_write(); + MutableSpan<MPoly> dst_polys = result->polygons_for_write(); + MLoop *l = dst_loops.data(); for (int fi : im->face_index_range()) { const Face *f = im->face(fi); const Mesh *orig_me; @@ -740,7 +752,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) int orig_me_index; const MPoly *orig_mp = mim.input_mpoly_for_orig_index( f->orig, &orig_me, &orig_me_index, &index_in_orig_me); - MPoly *mp = &result->mpoly[fi]; + MPoly *mp = &dst_polys[fi]; mp->totloop = f->size(); mp->loopstart = cur_loop_index; for (int j : f->index_range()) { @@ -772,17 +784,18 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) /* Now that the MEdges are populated, we can copy over the required attributes and custom layers. */ + MutableSpan<MEdge> edges = result->edges_for_write(); for (int fi : im->face_index_range()) { const Face *f = im->face(fi); - MPoly *mp = &result->mpoly[fi]; + const MPoly *mp = &dst_polys[fi]; for (int j : f->index_range()) { if (f->edge_orig[j] != NO_INDEX) { const Mesh *orig_me; int index_in_orig_me; const MEdge *orig_medge = mim.input_medge_for_orig_index( f->edge_orig[j], &orig_me, &index_in_orig_me); - int e_index = result->mloop[mp->loopstart + j].e; - MEdge *medge = &result->medge[e_index]; + int e_index = dst_loops[mp->loopstart + j].e; + MEdge *medge = &edges[e_index]; copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me); } } @@ -844,12 +857,14 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes, /* Store intersecting edge indices. */ if (r_intersecting_edges != nullptr) { + const Span<MPoly> polys = result->polygons(); + const Span<MLoop> loops = result->loops(); for (int fi : m_out.face_index_range()) { const Face &face = *m_out.face(fi); - const MPoly &poly = result->mpoly[fi]; + const MPoly &poly = polys[fi]; for (int corner_i : face.index_range()) { if (face.is_intersect[corner_i]) { - int e_index = result->mloop[poly.loopstart + corner_i].e; + int e_index = loops[poly.loopstart + corner_i].e; r_intersecting_edges->append(e_index); } } diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc index 31e20750cf2..8a8960fb8a7 100644 --- a/source/blender/blenkernel/intern/mesh_calc_edges.cc +++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc @@ -80,9 +80,10 @@ static void add_existing_edges_to_hash_maps(Mesh *mesh, uint32_t parallel_mask) { /* Assume existing edges are valid. */ + const Span<MEdge> edges = mesh->edges(); threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) { const int task_index = &edge_map - edge_maps.data(); - for (const MEdge &edge : Span(mesh->medge, mesh->totedge)) { + for (const MEdge &edge : edges) { OrderedEdge ordered_edge{edge.v1, edge.v2}; /* Only add the edge when it belongs into this map. */ if (task_index == (parallel_mask & ordered_edge.hash2())) { @@ -96,10 +97,11 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh, MutableSpan<EdgeMap> edge_maps, uint32_t parallel_mask) { - const Span<MLoop> loops{mesh->mloop, mesh->totloop}; + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) { const int task_index = &edge_map - edge_maps.data(); - for (const MPoly &poly : Span(mesh->mpoly, mesh->totpoly)) { + for (const MPoly &poly : polys) { Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); const MLoop *prev_loop = &poly_loops.last(); for (const MLoop &next_loop : poly_loops) { @@ -157,10 +159,11 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh, Span<EdgeMap> edge_maps, uint32_t parallel_mask) { - const MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; + const Span<MPoly> polys = mesh->polygons(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); threading::parallel_for(IndexRange(mesh->totpoly), 100, [&](IndexRange range) { for (const int poly_index : range) { - MPoly &poly = mesh->mpoly[poly_index]; + const MPoly &poly = polys[poly_index]; MutableSpan<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); MLoop *prev_loop = &poly_loops.last(); @@ -242,7 +245,6 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select CustomData_reset(&mesh->edata); CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge); mesh->totedge = new_totedge; - mesh->medge = new_edges.data(); /* Explicitly clear edge maps, because that way it can be parallelized. */ clear_hash_tables(edge_maps); diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 393d54bb03e..e56c248e81a 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -81,8 +81,8 @@ static void make_edges_mdata_extend(Mesh &mesh) const MPoly *mp; int i; - Span<MPoly> polys(mesh.mpoly, mesh.totpoly); - MutableSpan<MLoop> loops(mesh.mloop, mesh.totloop); + const Span<MPoly> polys = mesh.polygons(); + MutableSpan<MLoop> loops = mesh.loops_for_write(); const int eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh.totpoly)); EdgeHash *eh = BLI_edgehash_new_ex(__func__, eh_reserve); @@ -96,20 +96,18 @@ static void make_edges_mdata_extend(Mesh &mesh) #ifdef DEBUG /* ensure that there's no overlap! */ if (totedge_new) { - MEdge *medge = mesh.medge; - for (i = 0; i < totedge; i++, medge++) { - BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false); + for (const MEdge &edge : mesh.edges()) { + BLI_assert(BLI_edgehash_haskey(eh, edge.v1, edge.v2) == false); } } #endif if (totedge_new) { CustomData_realloc(&mesh.edata, totedge + totedge_new); - BKE_mesh_update_customdata_pointers(&mesh, false); - - MEdge *medge = mesh.medge + totedge; mesh.totedge += totedge_new; + MutableSpan<MEdge> edges = mesh.edges_for_write(); + MEdge *medge = &edges[totedge]; EdgeHashIterator *ehi; uint e_index = totedge; @@ -123,7 +121,7 @@ static void make_edges_mdata_extend(Mesh &mesh) } BLI_edgehashIterator_free(ehi); - for (i = 0, mp = mesh.mpoly; i < mesh.totpoly; i++, mp++) { + for (i = 0, mp = polys.data(); i < mesh.totpoly; i++, mp++) { MLoop *l = &loops[mp->loopstart]; MLoop *l_prev = (l + (mp->totloop - 1)); int j; @@ -186,10 +184,10 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly); - MutableSpan<MVert> verts(mesh->mvert, mesh->totvert); - MutableSpan<MEdge> edges(mesh->medge, mesh->totedge); - MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly); - MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop); + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); MVert *mvert = verts.data(); MEdge *medge = edges.data(); @@ -434,7 +432,7 @@ Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob) struct EdgeLink { struct EdgeLink *next, *prev; - void *edge; + const void *edge; }; struct VertLink { @@ -458,10 +456,13 @@ static void appendPolyLineVert(ListBase *lb, uint index) void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test) { - MVert *mvert = me->mvert; - MEdge *med, *medge = me->medge; - MPoly *mp, *mpoly = me->mpoly; - MLoop *mloop = me->mloop; + const Span<MVert> verts = me->vertices(); + const Span<MEdge> mesh_edges = me->edges(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); + + const MEdge *med; + const MPoly *mp; int medge_len = me->totedge; int mpoly_len = me->totpoly; @@ -475,8 +476,8 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed /* get boundary edges */ edge_users = (int *)MEM_calloc_arrayN(medge_len, sizeof(int), __func__); - for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) { - MLoop *ml = &mloop[mp->loopstart]; + for (i = 0, mp = polys.data(); i < mpoly_len; i++, mp++) { + const MLoop *ml = &loops[mp->loopstart]; int j; for (j = 0; j < mp->totloop; j++, ml++) { edge_users[ml->e]++; @@ -484,7 +485,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed } /* create edges from all faces (so as to find edges not in any faces) */ - med = medge; + med = mesh_edges.data(); for (i = 0; i < medge_len; i++, med++) { if (edge_users[i] == edge_users_test) { EdgeLink *edl = MEM_cnew<EdgeLink>("EdgeLink"); @@ -587,7 +588,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed /* add points */ vl = (VertLink *)polyline.first; for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) { - copy_v3_v3(bp->vec, mvert[vl->index].co); + copy_v3_v3(bp->vec, verts[vl->index].co); bp->f1 = SELECT; bp->radius = bp->weight = 1.0; } @@ -682,19 +683,16 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me) &pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint); /* Convert the Position attribute to a mesh vertex. */ - me->mvert = (MVert *)CustomData_add_layer( - &me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); - CustomData_update_typemap(&me->vdata); + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); const int layer_idx = CustomData_get_named_layer_index( &me->vdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION); CustomDataLayer *pos_layer = &me->vdata.layers[layer_idx]; float(*positions)[3] = (float(*)[3])pos_layer->data; - MVert *mvert; - mvert = me->mvert; - for (int i = 0; i < me->totvert; i++, mvert++) { - copy_v3_v3(mvert->co, positions[i]); + MutableSpan<MVert> verts = me->vertices_for_write(); + for (int i = 0; i < me->totvert; i++) { + copy_v3_v3(verts[i].co, positions[i]); } /* Delete Position attribute since it is now in vertex coordinates. */ @@ -703,9 +701,9 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me) void BKE_mesh_edges_set_draw_render(Mesh *mesh) { - MEdge *med = mesh->medge; - for (int i = 0; i < mesh->totedge; i++, med++) { - med->flag |= ME_EDGEDRAW | ME_EDGERENDER; + MutableSpan<MEdge> edges = mesh->edges_for_write(); + for (int i = 0; i < mesh->totedge; i++) { + edges[i].flag |= ME_EDGEDRAW | ME_EDGERENDER; } } @@ -1171,7 +1169,8 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, if (build_shapekey_layers && me->key && (kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { - BKE_keyblock_convert_to_mesh(kb, me->mvert, me->totvert); + MutableSpan<MVert> verts = me->vertices_for_write(); + BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert); } Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); @@ -1274,10 +1273,9 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act kb->data = kbcos = (float(*)[3])MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__); if (kb->uid == actshape_uid) { - MVert *mvert = mesh_src->mvert; - - for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) { - copy_v3_v3(*kbcos, mvert->co); + const Span<MVert> verts = mesh_src->vertices(); + for (j = 0; j < mesh_src->totvert; j++, kbcos++) { + copy_v3_v3(*kbcos, verts[j].co); } } else { @@ -1306,6 +1304,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, const CustomData_MeshMasks *mask, bool take_ownership) { + using namespace blender::bke; BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN); /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */ @@ -1385,30 +1384,30 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, - (alloctype == CD_ASSIGN) ? mesh_src->mvert : - MEM_dupallocN(mesh_src->mvert), + (alloctype == CD_ASSIGN) ? mesh_src->vertices_for_write().data() : + MEM_dupallocN(mesh_src->vertices().data()), totvert); } if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) { CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, - (alloctype == CD_ASSIGN) ? mesh_src->medge : - MEM_dupallocN(mesh_src->medge), + (alloctype == CD_ASSIGN) ? mesh_src->edges_for_write().data() : + MEM_dupallocN(mesh_src->edges().data()), totedge); } if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) { CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, - (alloctype == CD_ASSIGN) ? mesh_src->mloop : - MEM_dupallocN(mesh_src->mloop), + (alloctype == CD_ASSIGN) ? mesh_src->loops_for_write().data() : + MEM_dupallocN(mesh_src->loops().data()), tmp.totloop); CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, - (alloctype == CD_ASSIGN) ? mesh_src->mpoly : - MEM_dupallocN(mesh_src->mpoly), + (alloctype == CD_ASSIGN) ? mesh_src->polygons_for_write().data() : + MEM_dupallocN(mesh_src->polygons().data()), tmp.totpoly); } @@ -1425,9 +1424,6 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, } } - /* yes, must be before _and_ after tessellate */ - BKE_mesh_update_customdata_pointers(&tmp, false); - CustomData_free(&mesh_dst->vdata, mesh_dst->totvert); CustomData_free(&mesh_dst->edata, mesh_dst->totedge); CustomData_free(&mesh_dst->fdata, mesh_dst->totface); @@ -1481,7 +1477,6 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb) int a, totvert = mesh_src->totvert; float *fp; - MVert *mvert; if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) { return; @@ -1494,9 +1489,8 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb) kb->totelem = totvert; fp = (float *)kb->data; - mvert = mesh_src->mvert; - - for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) { - copy_v3_v3(fp, mvert->co); + const Span<MVert> verts = mesh_src->vertices(); + for (a = 0; a < kb->totelem; a++, fp += 3) { + copy_v3_v3(fp, verts[a].co); } } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 9dba8eab340..7e52b96cc92 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -205,18 +205,13 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const float BKE_mesh_calc_area(const Mesh *me) { - MVert *mvert = me->mvert; - MLoop *mloop = me->mloop; - MPoly *mpoly = me->mpoly; + const Span<MVert> verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); - MPoly *mp; - int i = me->totpoly; - float total_area = 0; - - for (mp = mpoly; i--; mp++) { - MLoop *ml_start = &mloop[mp->loopstart]; - - total_area += BKE_mesh_calc_poly_area(mp, ml_start, mvert); + float total_area = 0.0f; + for (const MPoly &poly : polys) { + total_area += BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data()); } return total_area; } @@ -405,11 +400,10 @@ void BKE_mesh_poly_edgebitmap_insert(uint *edge_bitmap, const MPoly *mp, const M bool BKE_mesh_center_median(const Mesh *me, float r_cent[3]) { - int i = me->totvert; - const MVert *mvert; + const Span<MVert> verts = me->vertices(); zero_v3(r_cent); - for (mvert = me->mvert; i--; mvert++) { - add_v3_v3(r_cent, mvert->co); + for (const MVert &vert : verts) { + add_v3_v3(r_cent, vert.co); } /* otherwise we get NAN for 0 verts */ if (me->totvert) { @@ -420,18 +414,17 @@ bool BKE_mesh_center_median(const Mesh *me, float r_cent[3]) bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3]) { - int i = me->totpoly; int tot = 0; - const MPoly *mpoly = me->mpoly; - const MLoop *mloop = me->mloop; - const MVert *mvert = me->mvert; + const Span<MVert> verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); zero_v3(r_cent); - for (; i--; mpoly++) { - int loopend = mpoly->loopstart + mpoly->totloop; - for (int j = mpoly->loopstart; j < loopend; j++) { - add_v3_v3(r_cent, mvert[mloop[j].v].co); + for (const MPoly &poly : polys) { + int loopend = poly.loopstart + poly.totloop; + for (int j = poly.loopstart; j < loopend; j++) { + add_v3_v3(r_cent, verts[loops[j].v].co); } - tot += mpoly->totloop; + tot += poly.totloop; } /* otherwise we get NAN for 0 verts */ if (me->totpoly) { @@ -455,17 +448,19 @@ bool BKE_mesh_center_bounds(const Mesh *me, float r_cent[3]) bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3]) { int i = me->totpoly; - MPoly *mpoly; + const MPoly *mpoly; float poly_area; float total_area = 0.0f; float poly_cent[3]; + const MVert *verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); zero_v3(r_cent); /* calculate a weighted average of polygon centroids */ - for (mpoly = me->mpoly; i--; mpoly++) { - poly_area = mesh_calc_poly_area_centroid( - mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent); + for (mpoly = polys; i--; mpoly++) { + poly_area = mesh_calc_poly_area_centroid(mpoly, loops + mpoly->loopstart, verts, poly_cent); madd_v3_v3fl(r_cent, poly_cent, poly_area); total_area += poly_area; @@ -486,10 +481,13 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3]) bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) { int i = me->totpoly; - MPoly *mpoly; + const MPoly *mpoly; float poly_volume; float total_volume = 0.0f; float poly_cent[3]; + const MVert *verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); /* Use an initial center to avoid numeric instability of geometry far away from the center. */ float init_cent[3]; @@ -498,9 +496,9 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) zero_v3(r_cent); /* calculate a weighted average of polyhedron centroids */ - for (mpoly = me->mpoly; i--; mpoly++) { + for (mpoly = polys; i--; mpoly++) { poly_volume = mesh_calc_poly_volume_centroid_with_reference_center( - mpoly, me->mloop + mpoly->loopstart, me->mvert, init_cent, poly_cent); + mpoly, loops + mpoly->loopstart, verts, init_cent, poly_cent); /* poly_cent is already volume-weighted, so no need to multiply by the volume */ add_v3_v3(r_cent, poly_cent); @@ -670,7 +668,7 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip) } } -void BKE_mesh_polygon_flip_ex(MPoly *mpoly, +void BKE_mesh_polygon_flip_ex(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, float (*lnors)[3], @@ -713,16 +711,16 @@ void BKE_mesh_polygon_flip_ex(MPoly *mpoly, } } -void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata) +void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata) { MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true); } -void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly) +void BKE_mesh_polygons_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly) { MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); - MPoly *mp; + const MPoly *mp; int i; for (mp = mpoly, i = 0; i < totpoly; mp++, i++) { @@ -748,9 +746,9 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me) return; } const VArraySpan<bool> hide_vert_span{hide_vert}; - const Span<MEdge> edges(me->medge, me->totedge); - const Span<MPoly> polys(me->mpoly, me->totpoly); - const Span<MLoop> loops(me->mloop, me->totloop); + const Span<MEdge> edges = me->edges(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); /* Hide edges when either of their vertices are hidden. */ SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>( @@ -788,8 +786,8 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me) return; } const VArraySpan<bool> hide_poly_span{hide_poly}; - const Span<MPoly> polys(me->mpoly, me->totpoly); - const Span<MLoop> loops(me->mloop, me->totloop); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>( ".hide_vert", ATTR_DOMAIN_POINT); SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>( @@ -859,8 +857,13 @@ void BKE_mesh_flush_select_from_polys_ex(MVert *mvert, } void BKE_mesh_flush_select_from_polys(Mesh *me) { - BKE_mesh_flush_select_from_polys_ex( - me->mvert, me->totvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly); + BKE_mesh_flush_select_from_polys_ex(me->vertices_for_write().data(), + me->totvert, + me->loops().data(), + me->edges_for_write().data(), + me->totedge, + me->polygons().data(), + me->totpoly); } static void mesh_flush_select_from_verts(const Span<MVert> verts, @@ -906,12 +909,12 @@ void BKE_mesh_flush_select_from_verts(Mesh *me) { const blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*me); mesh_flush_select_from_verts( - {me->mvert, me->totvert}, - {me->mloop, me->totloop}, + me->vertices(), + me->loops(), attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false), attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false), - {me->medge, me->totedge}, - {me->mpoly, me->totpoly}); + me->edges_for_write(), + me->polygons_for_write()); } /** \} */ diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc index 8936d7b0ba6..0fe58366449 100644 --- a/source/blender/blenkernel/intern/mesh_fair.cc +++ b/source/blender/blenkernel/intern/mesh_fair.cc @@ -27,6 +27,8 @@ #include "eigen_capi.h" using blender::Map; +using blender::MutableSpan; +using blender::Span; using blender::Vector; using std::array; @@ -193,13 +195,14 @@ class MeshFairingContext : public FairingContext { totvert_ = mesh->totvert; totloop_ = mesh->totloop; - medge_ = mesh->medge; - mpoly_ = mesh->mpoly; - mloop_ = mesh->mloop; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + medge_ = mesh->edges(); + mpoly_ = mesh->polygons(); + mloop_ = mesh->loops(); BKE_mesh_vert_loop_map_create(&vlmap_, &vlmap_mem_, - mesh->mpoly, - mesh->mloop, + mpoly_.data(), + mloop_.data(), mesh->totvert, mesh->totpoly, mesh->totloop); @@ -213,14 +216,14 @@ class MeshFairingContext : public FairingContext { } else { for (int i = 0; i < mesh->totvert; i++) { - co_[i] = mesh->mvert[i].co; + co_[i] = verts[i].co; } } loop_to_poly_map_.reserve(mesh->totloop); for (int i = 0; i < mesh->totpoly; i++) { - for (int l = 0; l < mesh->mpoly[i].totloop; l++) { - loop_to_poly_map_[l + mesh->mpoly[i].loopstart] = i; + for (int l = 0; l < mpoly_[i].totloop; l++) { + loop_to_poly_map_[l + mpoly_[i].loopstart] = i; } } } @@ -244,7 +247,7 @@ class MeshFairingContext : public FairingContext { int other_vertex_index_from_loop(const int loop, const uint v) override { - MEdge *e = &medge_[mloop_[loop].e]; + const MEdge *e = &medge_[mloop_[loop].e]; if (e->v1 == v) { return e->v2; } @@ -253,9 +256,9 @@ class MeshFairingContext : public FairingContext { protected: Mesh *mesh_; - MLoop *mloop_; - MPoly *mpoly_; - MEdge *medge_; + Span<MLoop> mloop_; + Span<MPoly> mpoly_; + Span<MEdge> medge_; Vector<int> loop_to_poly_map_; }; diff --git a/source/blender/blenkernel/intern/mesh_iterators.c b/source/blender/blenkernel/intern/mesh_iterators.c index 77e62918441..352ad8e9042 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.c +++ b/source/blender/blenkernel/intern/mesh_iterators.c @@ -65,7 +65,7 @@ void BKE_mesh_foreach_mapped_vert( } } else { - const MVert *mv = mesh->mvert; + const MVert *mv = BKE_mesh_vertices(mesh); const int *index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX); const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? BKE_mesh_vertex_normals_ensure(mesh) : @@ -120,8 +120,8 @@ void BKE_mesh_foreach_mapped_edge( } } else { - const MVert *mv = mesh->mvert; - const MEdge *med = mesh->medge; + const MVert *mv = BKE_mesh_vertices(mesh); + const MEdge *med = BKE_mesh_edges(mesh); const int *index = CustomData_get_layer(&mesh->edata, CD_ORIGINDEX); if (index) { @@ -188,9 +188,9 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, CustomData_get_layer(&mesh->ldata, CD_NORMAL) : NULL; - const MVert *mv = mesh->mvert; - const MLoop *ml = mesh->mloop; - const MPoly *mp = mesh->mpoly; + const MVert *mv = BKE_mesh_vertices(mesh); + const MLoop *ml = BKE_mesh_loops(mesh); + const MPoly *mp = BKE_mesh_polygons(mesh); const int *v_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX); const int *f_index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX); int p_idx, i; @@ -261,8 +261,9 @@ void BKE_mesh_foreach_mapped_face_center( } } else { - const MVert *mvert = mesh->mvert; - const MPoly *mp = mesh->mpoly; + const MVert *mvert = BKE_mesh_vertices(mesh); + const MPoly *mp = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); const MLoop *ml; float _no_buf[3]; float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : NULL; @@ -275,7 +276,7 @@ void BKE_mesh_foreach_mapped_face_center( continue; } float cent[3]; - ml = &mesh->mloop[mp->loopstart]; + ml = &loops[mp->loopstart]; BKE_mesh_calc_poly_center(mp, ml, mvert, cent); if (flag & MESH_FOREACH_USE_NORMAL) { BKE_mesh_calc_poly_normal(mp, ml, mvert, no); @@ -286,7 +287,7 @@ void BKE_mesh_foreach_mapped_face_center( else { for (int i = 0; i < mesh->totpoly; i++, mp++) { float cent[3]; - ml = &mesh->mloop[mp->loopstart]; + ml = &loops[mp->loopstart]; BKE_mesh_calc_poly_center(mp, ml, mvert, cent); if (flag & MESH_FOREACH_USE_NORMAL) { BKE_mesh_calc_poly_normal(mp, ml, mvert, no); @@ -303,7 +304,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( void *userData, MeshForeachFlag flag) { - const MPoly *mp = mesh->mpoly; + const MVert *verts = BKE_mesh_vertices(mesh); + const MPoly *mp = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); const MLoop *ml; const MVert *mv; const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? @@ -319,9 +322,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( if (orig == ORIGINDEX_NONE) { continue; } - ml = &mesh->mloop[mp->loopstart]; + ml = &loops[mp->loopstart]; for (int j = 0; j < mp->totloop; j++, ml++) { - mv = &mesh->mvert[ml->v]; + mv = &verts[ml->v]; if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { func(userData, orig, @@ -333,9 +336,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( } else { for (int i = 0; i < mesh->totpoly; i++, mp++) { - ml = &mesh->mloop[mp->loopstart]; + ml = &loops[mp->loopstart]; for (int j = 0; j < mp->totloop; j++, ml++) { - mv = &mesh->mvert[ml->v]; + mv = &verts[ml->v]; if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { func(userData, i, mv->co, (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : NULL); } diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 58096081ad1..c2a4b0176c6 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -23,6 +23,7 @@ #include "BKE_attribute.hh" #include "BKE_customdata.h" +#include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_mesh_legacy_convert.h" #include "BKE_multires.h" @@ -165,9 +166,7 @@ static void convert_mfaces_to_mpolys(ID *id, MEdge *medge, MFace *mface, int *r_totloop, - int *r_totpoly, - MLoop **r_mloop, - MPoly **r_mpoly) + int *r_totpoly) { MFace *mf; MLoop *ml, *mloop; @@ -185,8 +184,7 @@ static void convert_mfaces_to_mpolys(ID *id, CustomData_free(pdata, totpoly_i); totpoly = totface_i; - mpoly = (MPoly *)MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted"); - CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, totpoly); + mpoly = (MPoly *)CustomData_add_layer(pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly); int *material_indices = static_cast<int *>( CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); if (material_indices == nullptr) { @@ -203,9 +201,7 @@ static void convert_mfaces_to_mpolys(ID *id, totloop += mf->v4 ? 4 : 3; } - mloop = (MLoop *)MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted"); - - CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop); + mloop = (MLoop *)CustomData_add_layer(ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, totloop); CustomData_to_bmeshpoly(fdata, ldata, totloop); @@ -277,12 +273,51 @@ static void convert_mfaces_to_mpolys(ID *id, *r_totpoly = totpoly; *r_totloop = totloop; - *r_mpoly = mpoly; - *r_mloop = mloop; #undef ME_FGON } +static void mesh_ensure_tessellation_customdata(Mesh *me) +{ + if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) { + /* Pass, otherwise this function clears 'mface' before + * versioning 'mface -> mpoly' code kicks in T30583. + * + * Callers could also check but safer to do here - campbell */ + } + else { + const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); + + const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE); + const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL); + + if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) { + BKE_mesh_tessface_clear(me); + + BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface); + + /* TODO: add some `--debug-mesh` option. */ + if (G.debug & G_DEBUG) { + /* NOTE(campbell): this warning may be un-called for if we are initializing the mesh for + * the first time from #BMesh, rather than giving a warning about this we could be smarter + * and check if there was any data to begin with, for now just print the warning with + * some info to help troubleshoot what's going on. */ + printf( + "%s: warning! Tessellation uvs or vcol data got out of sync, " + "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != " + "CD_PROP_BYTE_COLOR: " + "%d\n", + __func__, + tottex_tessface, + tottex_original, + totcol_tessface, + totcol_original); + } + } + } +} + void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh) { convert_mfaces_to_mpolys(&mesh->id, @@ -293,14 +328,12 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh) mesh->totface, mesh->totloop, mesh->totpoly, - mesh->medge, - mesh->mface, + mesh->edges_for_write().data(), + (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), &mesh->totloop, - &mesh->totpoly, - &mesh->mloop, - &mesh->mpoly); + &mesh->totpoly); - BKE_mesh_update_customdata_pointers(mesh, true); + mesh_ensure_tessellation_customdata(mesh); } /** @@ -352,16 +385,14 @@ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh) mesh->totface, mesh->totloop, mesh->totpoly, - mesh->medge, - mesh->mface, + mesh->edges_for_write().data(), + (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), &mesh->totloop, - &mesh->totpoly, - &mesh->mloop, - &mesh->mpoly); + &mesh->totpoly); CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->ldata); - BKE_mesh_update_customdata_pointers(mesh, true); + mesh_ensure_tessellation_customdata(mesh); } /** \} */ @@ -793,12 +824,12 @@ void BKE_mesh_tessface_calc(Mesh *mesh) mesh->totface = mesh_tessface_calc(&mesh->fdata, &mesh->ldata, &mesh->pdata, - mesh->mvert, + BKE_mesh_vertices_for_write(mesh), mesh->totface, mesh->totloop, mesh->totpoly); - BKE_mesh_update_customdata_pointers(mesh, true); + mesh_ensure_tessellation_customdata(mesh); } void BKE_mesh_tessface_ensure(struct Mesh *mesh) @@ -896,7 +927,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh) using namespace blender::bke; const AttributeAccessor attributes = mesh_attributes(*mesh); - MutableSpan<MVert> verts(mesh->mvert, mesh->totvert); + MutableSpan<MVert> verts = mesh->vertices_for_write(); const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( ".hide_vert", ATTR_DOMAIN_POINT, false); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { @@ -905,7 +936,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh) } }); - MutableSpan<MEdge> edges(mesh->medge, mesh->totedge); + MutableSpan<MEdge> edges = mesh->edges_for_write(); const VArray<bool> hide_edge = attributes.lookup_or_default<bool>( ".hide_edge", ATTR_DOMAIN_EDGE, false); threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { @@ -914,7 +945,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh) } }); - MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( ".hide_poly", ATTR_DOMAIN_FACE, false); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { @@ -930,7 +961,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) using namespace blender::bke; MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh); - const Span<MVert> verts(mesh->mvert, mesh->totvert); + const Span<MVert> verts = mesh->vertices(); if (std::any_of( verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag & ME_HIDE; })) { SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>( @@ -943,7 +974,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) hide_vert.finish(); } - const Span<MEdge> edges(mesh->medge, mesh->totedge); + const Span<MEdge> edges = mesh->edges(); if (std::any_of( edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) { SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>( @@ -956,7 +987,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) hide_edge.finish(); } - const Span<MPoly> polys(mesh->mpoly, mesh->totpoly); + const Span<MPoly> polys = mesh->polygons(); if (std::any_of( polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_HIDE; })) { SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>( @@ -980,7 +1011,7 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh) using namespace blender; using namespace blender::bke; const AttributeAccessor attributes = mesh_attributes(*mesh); - MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); const VArray<int> material_indices = attributes.lookup_or_default<int>( "material_index", ATTR_DOMAIN_FACE, 0); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { @@ -995,7 +1026,7 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) using namespace blender; using namespace blender::bke; MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh); - const Span<MPoly> polys(mesh->mpoly, mesh->totpoly); + const Span<MPoly> polys = mesh->polygons(); if (std::any_of( polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr != 0; })) { SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_only_span<int>( diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c index 798fe087ea8..f57effd49f4 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.c +++ b/source/blender/blenkernel/intern/mesh_mapping.c @@ -976,13 +976,13 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp), return (me->flag & ME_SEAM) != 0; } -static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts), +static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts), const int UNUSED(totvert), - MEdge *edges, + const MEdge *edges, const int totedge, - MPoly *polys, + const MPoly *polys, const int totpoly, - MLoop *loops, + const MLoop *loops, const int totloop, const MLoopUV *luvs, MeshIslandStore *r_island_store) @@ -1073,16 +1073,13 @@ static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts), } for (p_idx = 0; p_idx < totpoly; p_idx++) { - MPoly *mp; - if (poly_groups[p_idx] != grp_idx) { continue; } - - mp = &polys[p_idx]; + const MPoly *mp = &polys[p_idx]; poly_indices[num_pidx++] = p_idx; for (l_idx = mp->loopstart, pl_idx = 0; pl_idx < mp->totloop; l_idx++, pl_idx++) { - MLoop *ml = &loops[l_idx]; + const MLoop *ml = &loops[l_idx]; loop_indices[num_lidx++] = l_idx; if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, ml->e) && (edge_border_count[ml->e] < 2)) { @@ -1126,13 +1123,13 @@ static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts), return true; } -bool BKE_mesh_calc_islands_loop_poly_edgeseam(MVert *verts, +bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts, const int totvert, - MEdge *edges, + const MEdge *edges, const int totedge, - MPoly *polys, + const MPoly *polys, const int totpoly, - MLoop *loops, + const MLoop *loops, const int totloop, MeshIslandStore *r_island_store) { diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c index 4459e2514bc..18fbaaccb92 100644 --- a/source/blender/blenkernel/intern/mesh_merge.c +++ b/source/blender/blenkernel/intern/mesh_merge.c @@ -32,9 +32,9 @@ * and may be called again with direct_reverse=-1 for reverse order. * \return 1 if polys are identical, 0 if polys are different. */ -static int cddm_poly_compare(MLoop *mloop_array, - MPoly *mpoly_source, - MPoly *mpoly_target, +static int cddm_poly_compare(const MLoop *mloop_array, + const MPoly *mpoly_source, + const MPoly *mpoly_target, const int *vtargetmap, const int direct_reverse) { @@ -44,7 +44,7 @@ static int cddm_poly_compare(MLoop *mloop_array, bool compare_completed = false; bool same_loops = false; - MLoop *mloop_source, *mloop_target; + const MLoop *mloop_source, *mloop_target; BLI_assert(ELEM(direct_reverse, 1, -1)); @@ -203,10 +203,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, const int totedge = mesh->totedge; const int totloop = mesh->totloop; const int totpoly = mesh->totpoly; + const MVert *src_verts = BKE_mesh_vertices(mesh); + const MEdge *src_edges = BKE_mesh_edges(mesh); + const MPoly *src_polys = BKE_mesh_polygons(mesh); + const MLoop *src_loops = BKE_mesh_loops(mesh); const int totvert_final = totvert - tot_vtargetmap; - MVert *mv, *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__); + const MVert *mv; + MVert *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__); int *oldv = MEM_malloc_arrayN(totvert_final, sizeof(*oldv), __func__); int *newv = MEM_malloc_arrayN(totvert, sizeof(*newv), __func__); STACK_DECLARE(mvert); @@ -215,13 +220,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* NOTE: create (totedge + totloop) elements because partially invalid polys due to merge may * require generating new edges, and while in 99% cases we'll still end with less final edges * than totedge, cases can be forged that would end requiring more. */ - MEdge *med, *medge = MEM_malloc_arrayN((totedge + totloop), sizeof(*medge), __func__); + const MEdge *med; + MEdge *medge = MEM_malloc_arrayN((totedge + totloop), sizeof(*medge), __func__); int *olde = MEM_malloc_arrayN((totedge + totloop), sizeof(*olde), __func__); int *newe = MEM_malloc_arrayN((totedge + totloop), sizeof(*newe), __func__); STACK_DECLARE(medge); STACK_DECLARE(olde); - MLoop *ml, *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__); + const MLoop *ml; + MLoop *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__); int *oldl = MEM_malloc_arrayN(totloop, sizeof(*oldl), __func__); #ifdef USE_LOOPS int *newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__); @@ -229,7 +236,8 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, STACK_DECLARE(mloop); STACK_DECLARE(oldl); - MPoly *mp, *mpoly = MEM_malloc_arrayN(totpoly, sizeof(*medge), __func__); + const MPoly *mp; + MPoly *mpoly = MEM_malloc_arrayN(totpoly, sizeof(*medge), __func__); int *oldp = MEM_malloc_arrayN(totpoly, sizeof(*oldp), __func__); STACK_DECLARE(mpoly); STACK_DECLARE(oldp); @@ -254,7 +262,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, STACK_INIT(mpoly, totpoly); /* fill newv with destination vertex indices */ - mv = mesh->mvert; + mv = src_verts; c = 0; for (i = 0; i < totvert; i++, mv++) { if (vtargetmap[i] == -1) { @@ -281,7 +289,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, */ /* now go through and fix edges and faces */ - med = mesh->medge; + med = src_edges; c = 0; for (i = 0; i < totedge; i++, med++) { const uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1; @@ -316,12 +324,12 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* Duplicates allowed because our compare function is not pure equality */ BLI_gset_flag_set(poly_gset, GHASH_FLAG_ALLOW_DUPES); - mp = mesh->mpoly; + mp = src_polys; mpgh = poly_keys; for (i = 0; i < totpoly; i++, mp++, mpgh++) { mpgh->poly_index = i; mpgh->totloops = mp->totloop; - ml = mesh->mloop + mp->loopstart; + ml = src_loops + mp->loopstart; mpgh->hash_sum = mpgh->hash_xor = 0; for (j = 0; j < mp->totloop; j++, ml++) { mpgh->hash_sum += ml->v; @@ -333,17 +341,17 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* Can we optimize by reusing an old `pmap`? How do we know an old `pmap` is stale? */ /* When called by `MOD_array.c` the `cddm` has just been created, so it has no valid `pmap`. */ BKE_mesh_vert_poly_map_create( - &poly_map, &poly_map_mem, mesh->mpoly, mesh->mloop, totvert, totpoly, totloop); + &poly_map, &poly_map_mem, src_polys, src_loops, totvert, totpoly, totloop); } /* done preparing for fast poly compare */ BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__); - mp = mesh->mpoly; - mv = mesh->mvert; + mp = src_polys; + mv = src_verts; for (i = 0; i < totpoly; i++, mp++) { MPoly *mp_new; - ml = mesh->mloop + mp->loopstart; + ml = src_loops + mp->loopstart; /* check faces with all vertices merged */ bool all_vertices_merged = true; @@ -376,7 +384,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* Use poly_gset for fast (although not 100% certain) identification of same poly */ /* First, make up a poly_summary structure */ - ml = mesh->mloop + mp->loopstart; + ml = src_loops + mp->loopstart; pkey.hash_sum = pkey.hash_xor = 0; pkey.totloops = 0; for (j = 0; j < mp->totloop; j++, ml++) { @@ -394,17 +402,17 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, */ /* Consider current loop again */ - ml = mesh->mloop + mp->loopstart; + ml = src_loops + mp->loopstart; /* Consider the target of the loop's first vert */ v_target = vtargetmap[ml->v]; /* Now see if v_target belongs to a poly that shares all vertices with source poly, * in same order, or reverse order */ for (i_poly = 0; i_poly < poly_map[v_target].count; i_poly++) { - MPoly *target_poly = mesh->mpoly + *(poly_map[v_target].indices + i_poly); + const MPoly *target_poly = src_polys + *(poly_map[v_target].indices + i_poly); - if (cddm_poly_compare(mesh->mloop, mp, target_poly, vtargetmap, +1) || - cddm_poly_compare(mesh->mloop, mp, target_poly, vtargetmap, -1)) { + if (cddm_poly_compare(src_loops, mp, target_poly, vtargetmap, +1) || + cddm_poly_compare(src_loops, mp, target_poly, vtargetmap, -1)) { found = true; break; } @@ -422,7 +430,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, * or they were all merged, but targets do not make up an identical poly, * the poly is retained. */ - ml = mesh->mloop + mp->loopstart; + ml = src_loops + mp->loopstart; c = 0; MLoop *last_valid_ml = NULL; @@ -434,9 +442,9 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, const uint mlv = (vtargetmap[ml->v] != -1) ? vtargetmap[ml->v] : ml->v; #ifndef NDEBUG { - MLoop *next_ml = mesh->mloop + mp->loopstart + ((j + 1) % mp->totloop); + const MLoop *next_ml = src_loops + mp->loopstart + ((j + 1) % mp->totloop); uint next_mlv = (vtargetmap[next_ml->v] != -1) ? vtargetmap[next_ml->v] : next_ml->v; - med = mesh->medge + ml->e; + med = src_edges + ml->e; uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1; uint v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2; BLI_assert((mlv == v1 && next_mlv == v2) || (mlv == v2 && next_mlv == v1)); @@ -461,7 +469,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, else { const int new_eidx = STACK_SIZE(medge); STACK_PUSH(olde, olde[last_valid_ml->e]); - STACK_PUSH(medge, mesh->medge[last_valid_ml->e]); + STACK_PUSH(medge, src_edges[last_valid_ml->e]); medge[new_eidx].v1 = last_valid_ml->v; medge[new_eidx].v2 = ml->v; /* DO NOT change newe mapping, @@ -515,7 +523,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, else { const int new_eidx = STACK_SIZE(medge); STACK_PUSH(olde, olde[last_valid_ml->e]); - STACK_PUSH(medge, mesh->medge[last_valid_ml->e]); + STACK_PUSH(medge, src_edges[last_valid_ml->e]); medge[new_eidx].v1 = last_valid_ml->v; medge[new_eidx].v2 = first_valid_ml->v; /* DO NOT change newe mapping, @@ -566,25 +574,25 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, mesh, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly)); /* Update edge indices and copy customdata. */ - med = medge; - for (i = 0; i < result->totedge; i++, med++) { - BLI_assert(newv[med->v1] != -1); - med->v1 = newv[med->v1]; - BLI_assert(newv[med->v2] != -1); - med->v2 = newv[med->v2]; + MEdge *new_med = medge; + for (i = 0; i < result->totedge; i++, new_med++) { + BLI_assert(newv[new_med->v1] != -1); + new_med->v1 = newv[new_med->v1]; + BLI_assert(newv[new_med->v2] != -1); + new_med->v2 = newv[new_med->v2]; /* Can happen in case vtargetmap contains some double chains, we do not support that. */ - BLI_assert(med->v1 != med->v2); + BLI_assert(new_med->v1 != new_med->v2); CustomData_copy_data(&mesh->edata, &result->edata, olde[i], i, 1); } /* Update loop indices and copy customdata. */ - ml = mloop; - for (i = 0; i < result->totloop; i++, ml++) { + MLoop *new_ml = mloop; + for (i = 0; i < result->totloop; i++, new_ml++) { /* Edge remapping has already be done in main loop handling part above. */ - BLI_assert(newv[ml->v] != -1); - ml->v = newv[ml->v]; + BLI_assert(newv[new_ml->v] != -1); + new_ml->v = newv[new_ml->v]; CustomData_copy_data(&mesh->ldata, &result->ldata, oldl[i], i, 1); } @@ -603,16 +611,16 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* Copy over data. #CustomData_add_layer can do this, need to look it up. */ if (STACK_SIZE(mvert)) { - memcpy(result->mvert, mvert, sizeof(MVert) * STACK_SIZE(mvert)); + memcpy(BKE_mesh_vertices_for_write(result), mvert, sizeof(MVert) * STACK_SIZE(mvert)); } if (STACK_SIZE(medge)) { - memcpy(result->medge, medge, sizeof(MEdge) * STACK_SIZE(medge)); + memcpy(BKE_mesh_edges_for_write(result), medge, sizeof(MEdge) * STACK_SIZE(medge)); } if (STACK_SIZE(mloop)) { - memcpy(result->mloop, mloop, sizeof(MLoop) * STACK_SIZE(mloop)); + memcpy(BKE_mesh_loops_for_write(result), mloop, sizeof(MLoop) * STACK_SIZE(mloop)); } if (STACK_SIZE(mpoly)) { - memcpy(result->mpoly, mpoly, sizeof(MPoly) * STACK_SIZE(mpoly)); + memcpy(BKE_mesh_polygons_for_write(result), mpoly, sizeof(MPoly) * STACK_SIZE(mpoly)); } MEM_freeN(mvert); diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc index 7bc429954b0..b253d3f9c46 100644 --- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc +++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc @@ -113,8 +113,13 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) int *vert_map_mem; struct MeshElemMap *vert_to_loop; - BKE_mesh_vert_loop_map_create( - &vert_to_loop, &vert_map_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop); + BKE_mesh_vert_loop_map_create(&vert_to_loop, + &vert_map_mem, + BKE_mesh_polygons(me), + BKE_mesh_loops(me), + me->totvert, + me->totpoly, + me->totloop); Vector<MLoopUV *> mloopuv_layers; mloopuv_layers.reserve(mloopuv_layers_num); diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c index 715a1c9daf9..534c8241820 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.c +++ b/source/blender/blenkernel/intern/mesh_mirror.c @@ -211,14 +211,18 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* Subsurf for eg won't have mesh data in the custom-data arrays. * now add mvert/medge/mpoly layers. */ if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) { - memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert); + memcpy(BKE_mesh_vertices_for_write(result), + BKE_mesh_vertices(mesh), + sizeof(MVert) * mesh->totvert); } if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) { - memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge); + memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge); } if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) { - memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop); - memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly); + memcpy(BKE_mesh_loops_for_write(result), BKE_mesh_loops(mesh), sizeof(MLoop) * mesh->totloop); + memcpy(BKE_mesh_polygons_for_write(result), + BKE_mesh_polygons(mesh), + sizeof(MPoly) * mesh->totpoly); } /* Copy custom-data to new geometry, @@ -237,7 +241,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, } /* mirror vertex coordinates */ - mv_prev = result->mvert; + mv_prev = BKE_mesh_vertices_for_write(result); mv = mv_prev + maxVerts; for (i = 0; i < maxVerts; i++, mv++, mv_prev++) { mul_m4_v3(mtx, mv->co); @@ -304,15 +308,15 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, } /* adjust mirrored edge vertex indices */ - me = result->medge + maxEdges; + me = BKE_mesh_edges_for_write(result) + maxEdges; for (i = 0; i < maxEdges; i++, me++) { me->v1 += maxVerts; me->v2 += maxVerts; } /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */ - mp = result->mpoly + maxPolys; - ml = result->mloop; + mp = BKE_mesh_polygons_for_write(result) + maxPolys; + ml = BKE_mesh_loops_for_write(result); for (i = 0; i < maxPolys; i++, mp++) { MLoop *ml2; int j, e; @@ -341,7 +345,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, } /* adjust mirrored loop vertex and edge indices */ - ml = result->mloop + maxLoops; + ml = BKE_mesh_loops_for_write(result) + maxLoops; for (i = 0; i < maxLoops; i++, ml++) { ml->v += maxVerts; ml->e += maxEdges; @@ -405,15 +409,15 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* calculate custom normals into loop_normals, then mirror first half into second half */ - BKE_mesh_normals_loop_split(result->mvert, + BKE_mesh_normals_loop_split(BKE_mesh_vertices(result), BKE_mesh_vertex_normals_ensure(result), result->totvert, - result->medge, + BKE_mesh_edges(result), result->totedge, - result->mloop, + BKE_mesh_loops(result), loop_normals, totloop, - result->mpoly, + BKE_mesh_polygons(result), BKE_mesh_poly_normals_ensure(result), totpoly, true, @@ -423,9 +427,10 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, NULL); /* mirroring has to account for loops being reversed in polys in second half */ - mp = result->mpoly; + MPoly *result_polys = BKE_mesh_polygons_for_write(result); + mp = result_polys; for (i = 0; i < maxPolys; i++, mp++) { - MPoly *mpmirror = result->mpoly + maxPolys + i; + MPoly *mpmirror = result_polys + maxPolys + i; int j; for (j = mp->loopstart; j < mp->loopstart + mp->totloop; j++) { @@ -446,8 +451,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* handle vgroup stuff */ if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) { - MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&result->vdata, CD_MDEFORMVERT) + - maxVerts; + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result) + maxVerts; int *flip_map = NULL, flip_map_len = 0; flip_map = BKE_object_defgroup_flip_map(ob, &flip_map_len, false); diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index f90a2e1b887..7217cbf5880 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -37,6 +37,7 @@ #include "atomic_ops.h" +using blender::MutableSpan; using blender::Span; // #define DEBUG_TIME @@ -368,16 +369,19 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3] /* Isolate task because a mutex is locked and computing normals is multi-threaded. */ blender::threading::isolate_task([&]() { Mesh &mesh_mutable = *const_cast<Mesh *>(mesh); + const Span<MVert> verts = mesh_mutable.vertices(); + const Span<MPoly> polys = mesh_mutable.polygons(); + const Span<MLoop> loops = mesh_mutable.loops(); vert_normals = BKE_mesh_vertex_normals_for_write(&mesh_mutable); poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable); - BKE_mesh_calc_normals_poly_and_vertex(mesh_mutable.mvert, - mesh_mutable.totvert, - mesh_mutable.mloop, - mesh_mutable.totloop, - mesh_mutable.mpoly, - mesh_mutable.totpoly, + BKE_mesh_calc_normals_poly_and_vertex(verts.data(), + verts.size(), + loops.data(), + loops.size(), + polys.data(), + polys.size(), poly_normals, vert_normals); @@ -413,15 +417,18 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3] /* Isolate task because a mutex is locked and computing normals is multi-threaded. */ blender::threading::isolate_task([&]() { Mesh &mesh_mutable = *const_cast<Mesh *>(mesh); + const Span<MVert> verts = mesh_mutable.vertices(); + const Span<MPoly> polys = mesh_mutable.polygons(); + const Span<MLoop> loops = mesh_mutable.loops(); poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable); - BKE_mesh_calc_normals_poly(mesh_mutable.mvert, - mesh_mutable.totvert, - mesh_mutable.mloop, - mesh_mutable.totloop, - mesh_mutable.mpoly, - mesh_mutable.totpoly, + BKE_mesh_calc_normals_poly(verts.data(), + verts.size(), + loops.data(), + loops.size(), + polys.data(), + polys.size(), poly_normals); BKE_mesh_poly_normals_clear_dirty(&mesh_mutable); @@ -940,9 +947,9 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts, const int UNUSED(numVerts), struct MEdge *medges, const int numEdges, - struct MLoop *mloops, + const struct MLoop *mloops, const int numLoops, - struct MPoly *mpolys, + const struct MPoly *mpolys, const float (*polynors)[3], const int numPolys, const float split_angle) @@ -1600,12 +1607,12 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common void BKE_mesh_normals_loop_split(const MVert *mverts, const float (*vert_normals)[3], const int UNUSED(numVerts), - MEdge *medges, + const MEdge *medges, const int numEdges, - MLoop *mloops, + const MLoop *mloops, float (*r_loopnors)[3], const int numLoops, - MPoly *mpolys, + const MPoly *mpolys, const float (*polynors)[3], const int numPolys, const bool use_split_normals, @@ -1628,7 +1635,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, int mp_index; for (mp_index = 0; mp_index < numPolys; mp_index++) { - MPoly *mp = &mpolys[mp_index]; + const MPoly *mp = &mpolys[mp_index]; int ml_index = mp->loopstart; const int ml_index_end = ml_index + mp->totloop; const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0); @@ -1755,10 +1762,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, const int numVerts, MEdge *medges, const int numEdges, - MLoop *mloops, + const MLoop *mloops, float (*r_custom_loopnors)[3], const int numLoops, - MPoly *mpolys, + const MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2], @@ -1852,12 +1859,12 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, } LinkNode *loops = lnors_spacearr.lspacearr[i]->loops; - MLoop *prev_ml = nullptr; + const MLoop *prev_ml = nullptr; const float *org_nor = nullptr; while (loops) { const int lidx = POINTER_AS_INT(loops->link); - MLoop *ml = &mloops[lidx]; + const MLoop *ml = &mloops[lidx]; const int nidx = lidx; float *nor = r_custom_loopnors[nidx]; @@ -1889,7 +1896,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, loops = lnors_spacearr.lspacearr[i]->loops; if (loops && org_nor) { const int lidx = POINTER_AS_INT(loops->link); - MLoop *ml = &mloops[lidx]; + const MLoop *ml = &mloops[lidx]; const int nidx = lidx; float *nor = r_custom_loopnors[nidx]; @@ -1992,10 +1999,10 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, const int numVerts, MEdge *medges, const int numEdges, - MLoop *mloops, + const MLoop *mloops, float (*r_custom_loopnors)[3], const int numLoops, - MPoly *mpolys, + const MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2]) @@ -2021,9 +2028,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(const MVert *mverts, const int numVerts, MEdge *medges, const int numEdges, - MLoop *mloops, + const MLoop *mloops, const int numLoops, - MPoly *mpolys, + const MPoly *mpolys, const float (*polynors)[3], const int numPolys, short (*r_clnors_data)[2]) @@ -2056,18 +2063,22 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const clnors = (short(*)[2])CustomData_add_layer( &mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, numloops); } + const Span<MVert> verts = mesh->vertices(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); - mesh_normals_loop_custom_set(mesh->mvert, + mesh_normals_loop_custom_set(verts.data(), BKE_mesh_vertex_normals_ensure(mesh), - mesh->totvert, - mesh->medge, - mesh->totedge, - mesh->mloop, + verts.size(), + edges.data(), + edges.size(), + loops.data(), r_custom_nors, - mesh->totloop, - mesh->mpoly, + loops.size(), + polys.data(), BKE_mesh_poly_normals_ensure(mesh), - mesh->totpoly, + polys.size(), clnors, use_vertices); } diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 4c6ee0ae3ee..cdb8bc96dda 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -377,7 +377,7 @@ void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index) } static int mesh_remap_interp_poly_data_get(const MPoly *mp, - MLoop *mloops, + const MLoop *mloops, const float (*vcos_src)[3], const float point[3], size_t *buff_size, @@ -388,7 +388,7 @@ static int mesh_remap_interp_poly_data_get(const MPoly *mp, const bool do_weights, int *r_closest_index) { - MLoop *ml; + const MLoop *ml; float(*vco)[3]; float ref_dist_sq = FLT_MAX; int *index; @@ -520,7 +520,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, } } else if (ELEM(mode, MREMAP_MODE_VERT_EDGE_NEAREST, MREMAP_MODE_VERT_EDGEINTERP_NEAREST)) { - MEdge *edges_src = me_src->medge; + const MEdge *edges_src = BKE_mesh_edges(me_src); float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL); BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2); @@ -536,7 +536,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, if (mesh_remap_bvhtree_query_nearest( &treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) { - MEdge *me = &edges_src[nearest.index]; + const MEdge *me = &edges_src[nearest.index]; const float *v1cos = vcos_src[me->v1]; const float *v2cos = vcos_src[me->v2]; @@ -573,8 +573,8 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, MREMAP_MODE_VERT_POLY_NEAREST, MREMAP_MODE_VERT_POLYINTERP_NEAREST, MREMAP_MODE_VERT_POLYINTERP_VNORPROJ)) { - MPoly *polys_src = me_src->mpoly; - MLoop *loops_src = me_src->mloop; + const MPoly *polys_src = BKE_mesh_polygons(me_src); + const MLoop *loops_src = BKE_mesh_loops(me_src); float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL); const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst); @@ -599,7 +599,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, if (mesh_remap_bvhtree_query_raycast( &treedata, &rayhit, tmp_co, tmp_no, ray_radius, max_dist, &hit_dist)) { const MLoopTri *lt = &treedata.looptri[rayhit.index]; - MPoly *mp_src = &polys_src[lt->poly]; + const MPoly *mp_src = &polys_src[lt->poly]; const int sources_num = mesh_remap_interp_poly_data_get(mp_src, loops_src, (const float(*)[3])vcos_src, @@ -634,7 +634,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, if (mesh_remap_bvhtree_query_nearest( &treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) { const MLoopTri *lt = &treedata.looptri[nearest.index]; - MPoly *mp = &polys_src[lt->poly]; + const MPoly *mp = &polys_src[lt->poly]; if (mode == MREMAP_MODE_VERT_POLY_NEAREST) { int index; @@ -726,7 +726,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, if (mode == MREMAP_MODE_EDGE_VERT_NEAREST) { const int num_verts_src = me_src->totvert; const int num_edges_src = me_src->totedge; - MEdge *edges_src = me_src->medge; + const MEdge *edges_src = BKE_mesh_edges(me_src); float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL); MeshElemMap *vert_to_edge_src_map; @@ -797,7 +797,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, k = vert_to_edge_src_map[vidx_src].count; for (; k--; eidx_src++) { - MEdge *e_src = &edges_src[*eidx_src]; + const MEdge *e_src = &edges_src[*eidx_src]; const float *other_co_src = vcos_src[BKE_mesh_edge_other_vert(e_src, vidx_src)]; const float *other_co_dst = verts_dst[BKE_mesh_edge_other_vert(e_dst, (int)vidx_dst)].co; @@ -873,9 +873,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, } } else if (mode == MREMAP_MODE_EDGE_POLY_NEAREST) { - MEdge *edges_src = me_src->medge; - MPoly *polys_src = me_src->mpoly; - MLoop *loops_src = me_src->mloop; + const MEdge *edges_src = BKE_mesh_edges(me_src); + const MPoly *polys_src = BKE_mesh_polygons(me_src); + const MLoop *loops_src = BKE_mesh_loops(me_src); float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL); BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_LOOPTRI, 2); @@ -891,14 +891,14 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, if (mesh_remap_bvhtree_query_nearest( &treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) { const MLoopTri *lt = &treedata.looptri[nearest.index]; - MPoly *mp_src = &polys_src[lt->poly]; - MLoop *ml_src = &loops_src[mp_src->loopstart]; + const MPoly *mp_src = &polys_src[lt->poly]; + const MLoop *ml_src = &loops_src[mp_src->loopstart]; int nloops = mp_src->totloop; float best_dist_sq = FLT_MAX; int best_eidx_src = -1; for (; nloops--; ml_src++) { - MEdge *med_src = &edges_src[ml_src->e]; + const MEdge *med_src = &edges_src[ml_src->e]; float *co1_src = vcos_src[med_src->v1]; float *co2_src = vcos_src[med_src->v2]; float co_src[3]; @@ -1041,9 +1041,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, const int island_index, BLI_AStarGraph *as_graph, - MVert *verts, - MPoly *polys, - MLoop *loops, + const MVert *verts, + const MPoly *polys, + const MLoop *loops, const int edge_idx, BLI_bitmap *done_edges, MeshElemMap *edge_to_poly_map, @@ -1058,7 +1058,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, for (i = 0; i < edge_to_poly_map[edge_idx].count; i++) { const int pidx = edge_to_poly_map[edge_idx].indices[i]; - MPoly *mp = &polys[pidx]; + const MPoly *mp = &polys[pidx]; const int pidx_isld = islands ? poly_island_index_map[pidx] : pidx; void *custom_data = is_edge_innercut ? POINTER_FROM_INT(edge_idx) : POINTER_FROM_INT(-1); @@ -1099,11 +1099,11 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, static void mesh_island_to_astar_graph(MeshIslandStore *islands, const int island_index, - MVert *verts, + const MVert *verts, MeshElemMap *edge_to_poly_map, const int numedges, - MLoop *loops, - MPoly *polys, + const MLoop *loops, + const MPoly *polys, const int numpolys, BLI_AStarGraph *r_as_graph) { @@ -1153,7 +1153,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, for (pidx_isld = node_num; pidx_isld--;) { const int pidx = islands ? island_poly_map->indices[pidx_isld] : pidx_isld; - MPoly *mp = &polys[pidx]; + const MPoly *mp = &polys[pidx]; int pl_idx, l_idx; if (poly_status[pidx_isld] == POLY_COMPLETE) { @@ -1161,7 +1161,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, } for (pl_idx = 0, l_idx = mp->loopstart; pl_idx < mp->totloop; pl_idx++, l_idx++) { - MLoop *ml = &loops[l_idx]; + const MLoop *ml = &loops[l_idx]; if (BLI_BITMAP_TEST(done_edges, ml->e)) { continue; @@ -1229,13 +1229,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, const float max_dist, const float ray_radius, Mesh *mesh_dst, - MVert *verts_dst, + const MVert *verts_dst, const int numverts_dst, - MEdge *edges_dst, + const MEdge *edges_dst, const int numedges_dst, - MLoop *loops_dst, + const MLoop *loops_dst, const int numloops_dst, - MPoly *polys_dst, + const MPoly *polys_dst, const int numpolys_dst, CustomData *ldata_dst, const bool use_split_nors_dst, @@ -1302,14 +1302,14 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, /* Unlike above, those are one-to-one mappings, simpler! */ int *loop_to_poly_map_src = NULL; - MVert *verts_src = me_src->mvert; + const MVert *verts_src = BKE_mesh_vertices(me_src); const int num_verts_src = me_src->totvert; float(*vcos_src)[3] = NULL; - MEdge *edges_src = me_src->medge; + const MEdge *edges_src = BKE_mesh_edges(me_src); const int num_edges_src = me_src->totedge; - MLoop *loops_src = me_src->mloop; + const MLoop *loops_src = BKE_mesh_loops(me_src); const int num_loops_src = me_src->totloop; - MPoly *polys_src = me_src->mpoly; + const MPoly *polys_src = BKE_mesh_polygons(me_src); const int num_polys_src = me_src->totpoly; const MLoopTri *looptri_src = NULL; int num_looptri_src = 0; @@ -1319,8 +1319,10 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int *indices_interp = NULL; float *weights_interp = NULL; - MLoop *ml_src, *ml_dst; - MPoly *mp_src, *mp_dst; + const MLoop *ml_src; + const MLoop *ml_dst; + const MPoly *mp_src; + const MPoly *mp_dst; int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src; IslandResult **islands_res; @@ -2148,10 +2150,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, - Mesh *mesh_dst, - MVert *verts_dst, - MLoop *loops_dst, - MPoly *polys_dst, + const Mesh *mesh_dst, + const MVert *verts_dst, + const MLoop *loops_dst, + const MPoly *polys_dst, const int numpolys_dst, Mesh *me_src, MeshPairRemap *r_map) @@ -2188,7 +2190,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, nearest.index = -1; for (i = 0; i < numpolys_dst; i++) { - MPoly *mp = &polys_dst[i]; + const MPoly *mp = &polys_dst[i]; BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co); @@ -2213,7 +2215,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, BLI_assert(poly_nors_dst); for (i = 0; i < numpolys_dst; i++) { - MPoly *mp = &polys_dst[i]; + const MPoly *mp = &polys_dst[i]; BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co); copy_v3_v3(tmp_no, poly_nors_dst[i]); @@ -2259,7 +2261,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, /* For each dst poly, we sample some rays from it (2D grid in pnor space) * and use their hits to interpolate from source polys. */ /* NOTE: dst poly is early-converted into src space! */ - MPoly *mp = &polys_dst[i]; + const MPoly *mp = &polys_dst[i]; int tot_rays, done_rays = 0; float poly_area_2d_inv, done_area = 0.0f; @@ -2302,7 +2304,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, INIT_MINMAX2(poly_dst_2d_min, poly_dst_2d_max); for (j = 0; j < mp->totloop; j++) { - MLoop *ml = &loops_dst[j + mp->loopstart]; + const MLoop *ml = &loops_dst[j + mp->loopstart]; copy_v3_v3(tmp_co, verts_dst[ml->v].co); if (space_transform) { BLI_space_transform_apply(space_transform, tmp_co); diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 5a4fd0d7d96..1b583b6a851 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -61,14 +61,15 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data) { - /* Ensure that the triangulated mesh data is up to data */ + const Span<MVert> input_verts = input_mesh->vertices(); + const Span<MLoop> input_loops = input_mesh->loops(); const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh); /* Gather the required data for export to the internal quadriflow mesh format. */ MVertTri *verttri = (MVertTri *)MEM_callocN( sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh), "remesh_looptri"); BKE_mesh_runtime_verttri_from_looptri( - verttri, input_mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(input_mesh)); + verttri, input_loops.data(), looptri, BKE_mesh_runtime_looptri_len(input_mesh)); const int totfaces = BKE_mesh_runtime_looptri_len(input_mesh); const int totverts = input_mesh->totvert; @@ -76,7 +77,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, Array<int> faces(totfaces * 3); for (const int i : IndexRange(totverts)) { - verts[i] = input_mesh->mvert[i].co; + verts[i] = input_verts[i].co; } for (const int i : IndexRange(totfaces)) { @@ -123,20 +124,23 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, /* Construct the new output mesh */ Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, 0, qrd.out_totfaces * 4, qrd.out_totfaces); + MutableSpan<MVert> mesh_verts = mesh->vertices_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); for (const int i : IndexRange(qrd.out_totverts)) { - copy_v3_v3(mesh->mvert[i].co, &qrd.out_verts[i * 3]); + copy_v3_v3(mesh_verts[i].co, &qrd.out_verts[i * 3]); } for (const int i : IndexRange(qrd.out_totfaces)) { - MPoly &poly = mesh->mpoly[i]; + MPoly &poly = polys[i]; const int loopstart = i * 4; poly.loopstart = loopstart; poly.totloop = 4; - mesh->mloop[loopstart].v = qrd.out_faces[loopstart]; - mesh->mloop[loopstart + 1].v = qrd.out_faces[loopstart + 1]; - mesh->mloop[loopstart + 2].v = qrd.out_faces[loopstart + 2]; - mesh->mloop[loopstart + 3].v = qrd.out_faces[loopstart + 3]; + loops[loopstart].v = qrd.out_faces[loopstart]; + loops[loopstart + 1].v = qrd.out_faces[loopstart + 1]; + loops[loopstart + 2].v = qrd.out_faces[loopstart + 2]; + loops[loopstart + 3].v = qrd.out_faces[loopstart + 3]; } BKE_mesh_calc_edges(mesh, false, false); @@ -186,7 +190,8 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh, static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, const float voxel_size) { - Span<MLoop> mloop{mesh->mloop, mesh->totloop}; + const Span<MVert> verts = mesh->vertices(); + const Span<MLoop> loops = mesh->loops(); Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh), BKE_mesh_runtime_looptri_len(mesh)}; @@ -194,14 +199,14 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, std::vector<openvdb::Vec3I> triangles(looptris.size()); for (const int i : IndexRange(mesh->totvert)) { - const float3 co = mesh->mvert[i].co; + const float3 co = verts[i].co; points[i] = openvdb::Vec3s(co.x, co.y, co.z); } for (const int i : IndexRange(looptris.size())) { const MLoopTri &loop_tri = looptris[i]; triangles[i] = openvdb::Vec3I( - mloop[loop_tri.tri[0]].v, mloop[loop_tri.tri[1]].v, mloop[loop_tri.tri[2]].v); + loops[loop_tri.tri[0]].v, loops[loop_tri.tri[1]].v, loops[loop_tri.tri[2]].v); } openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform( @@ -225,34 +230,34 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set Mesh *mesh = BKE_mesh_new_nomain( vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size()); - MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> mloops{mesh->mloop, mesh->totloop}; - MutableSpan<MPoly> mpolys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> mesh_verts = mesh->vertices_for_write(); + MutableSpan<MPoly> mesh_polys = mesh->polygons_for_write(); + MutableSpan<MLoop> mesh_loops = mesh->loops_for_write(); - for (const int i : mverts.index_range()) { - copy_v3_v3(mverts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z())); + for (const int i : mesh_verts.index_range()) { + copy_v3_v3(mesh_verts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z())); } for (const int i : IndexRange(quads.size())) { - MPoly &poly = mpolys[i]; + MPoly &poly = mesh_polys[i]; const int loopstart = i * 4; poly.loopstart = loopstart; poly.totloop = 4; - mloops[loopstart].v = quads[i][0]; - mloops[loopstart + 1].v = quads[i][3]; - mloops[loopstart + 2].v = quads[i][2]; - mloops[loopstart + 3].v = quads[i][1]; + mesh_loops[loopstart].v = quads[i][0]; + mesh_loops[loopstart + 1].v = quads[i][3]; + mesh_loops[loopstart + 2].v = quads[i][2]; + mesh_loops[loopstart + 3].v = quads[i][1]; } const int triangle_loop_start = quads.size() * 4; for (const int i : IndexRange(tris.size())) { - MPoly &poly = mpolys[quads.size() + i]; + MPoly &poly = mesh_polys[quads.size() + i]; const int loopstart = triangle_loop_start + i * 3; poly.loopstart = loopstart; poly.totloop = 3; - mloops[loopstart].v = tris[i][2]; - mloops[loopstart + 1].v = tris[i][1]; - mloops[loopstart + 2].v = tris[i][0]; + mesh_loops[loopstart].v = tris[i][2]; + mesh_loops[loopstart + 1].v = tris[i][1]; + mesh_loops[loopstart + 2].v = tris[i][0]; } BKE_mesh_calc_edges(mesh, false, false); diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 4521c519f45..6ce47edf730 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -23,6 +23,9 @@ #include "BKE_shrinkwrap.h" #include "BKE_subdiv_ccg.h" +using blender::MutableSpan; +using blender::Span; + /* -------------------------------------------------------------------- */ /** \name Mesh Runtime Struct Utils * \{ */ @@ -147,10 +150,13 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh) { mesh_ensure_looptri_data(mesh); BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != nullptr); + const Span<MVert> verts = mesh->vertices(); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); - BKE_mesh_recalc_looptri(mesh->mloop, - mesh->mpoly, - mesh->mvert, + BKE_mesh_recalc_looptri(loops.data(), + polys.data(), + verts.data(), mesh->totloop, mesh->totpoly, mesh->runtime.looptris.array_wip); @@ -272,7 +278,7 @@ void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh) const bool poly_normals_were_dirty = BKE_mesh_poly_normals_are_dirty(mesh); BKE_mesh_tag_coords_changed(mesh); - /* The normals didn't change, since all vertices moved by the same amount. */ + /* The normals didn't change, since all verts moved by the same amount. */ if (!vert_normals_were_dirty) { BKE_mesh_poly_normals_clear_dirty(mesh); } @@ -324,6 +330,11 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) printf("MESH: %s\n", me_eval->id.name + 2); } + MutableSpan<MVert> verts = me_eval->vertices_for_write(); + MutableSpan<MEdge> edges = me_eval->edges_for_write(); + MutableSpan<MPoly> polys = me_eval->polygons_for_write(); + MutableSpan<MLoop> loops = me_eval->loops_for_write(); + is_valid &= BKE_mesh_validate_all_customdata( &me_eval->vdata, me_eval->totvert, @@ -338,21 +349,22 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) do_fixes, &changed); - is_valid &= BKE_mesh_validate_arrays(me_eval, - me_eval->mvert, - me_eval->totvert, - me_eval->medge, - me_eval->totedge, - me_eval->mface, - me_eval->totface, - me_eval->mloop, - me_eval->totloop, - me_eval->mpoly, - me_eval->totpoly, - me_eval->dvert, - do_verbose, - do_fixes, - &changed); + is_valid &= BKE_mesh_validate_arrays( + me_eval, + verts.data(), + verts.size(), + edges.data(), + edges.size(), + static_cast<MFace *>(CustomData_get_layer(&me_eval->fdata, CD_MFACE)), + me_eval->totface, + loops.data(), + loops.size(), + polys.data(), + polys.size(), + me_eval->deform_verts_for_write().data(), + do_verbose, + do_fixes, + &changed); BLI_assert(changed == false); diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index e54f2e6d687..f37246ced94 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -2,6 +2,7 @@ #include "BKE_attribute_math.hh" #include "BKE_bvhutils.h" +#include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_mesh_sample.hh" @@ -20,6 +21,7 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh, const IndexMask mask, const MutableSpan<T> dst) { + const Span<MLoop> loops = mesh.loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), BKE_mesh_runtime_looptri_len(&mesh)}; @@ -28,9 +30,9 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh, const MLoopTri &looptri = looptris[looptri_index]; const float3 &bary_coord = bary_coords[i]; - const int v0_index = mesh.mloop[looptri.tri[0]].v; - const int v1_index = mesh.mloop[looptri.tri[1]].v; - const int v2_index = mesh.mloop[looptri.tri[2]].v; + const int v0_index = loops[looptri.tri[0]].v; + const int v1_index = loops[looptri.tri[1]].v; + const int v2_index = loops[looptri.tri[2]].v; const T v0 = src[v0_index]; const T v1 = src[v1_index]; @@ -157,6 +159,8 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords() } bary_coords_.reinitialize(mask_.min_array_size()); + const Span<MVert> verts = mesh_->vertices(); + const Span<MLoop> loops = mesh_->loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_), BKE_mesh_runtime_looptri_len(mesh_)}; @@ -164,14 +168,14 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords() const int looptri_index = looptri_indices_[i]; const MLoopTri &looptri = looptris[looptri_index]; - const int v0_index = mesh_->mloop[looptri.tri[0]].v; - const int v1_index = mesh_->mloop[looptri.tri[1]].v; - const int v2_index = mesh_->mloop[looptri.tri[2]].v; + const int v0_index = loops[looptri.tri[0]].v; + const int v1_index = loops[looptri.tri[1]].v; + const int v2_index = loops[looptri.tri[2]].v; interp_weights_tri_v3(bary_coords_[i], - mesh_->mvert[v0_index].co, - mesh_->mvert[v1_index].co, - mesh_->mvert[v2_index].co, + verts[v0_index].co, + verts[v1_index].co, + verts[v2_index].co, positions_[i]); } return bary_coords_; @@ -185,6 +189,8 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights() } nearest_weights_.reinitialize(mask_.min_array_size()); + const Span<MVert> verts = mesh_->vertices(); + const Span<MLoop> loops = mesh_->loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_), BKE_mesh_runtime_looptri_len(mesh_)}; @@ -192,13 +198,13 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights() const int looptri_index = looptri_indices_[i]; const MLoopTri &looptri = looptris[looptri_index]; - const int v0_index = mesh_->mloop[looptri.tri[0]].v; - const int v1_index = mesh_->mloop[looptri.tri[1]].v; - const int v2_index = mesh_->mloop[looptri.tri[2]].v; + const int v0_index = loops[looptri.tri[0]].v; + const int v1_index = loops[looptri.tri[1]].v; + const int v2_index = loops[looptri.tri[2]].v; - const float d0 = len_squared_v3v3(positions_[i], mesh_->mvert[v0_index].co); - const float d1 = len_squared_v3v3(positions_[i], mesh_->mvert[v1_index].co); - const float d2 = len_squared_v3v3(positions_[i], mesh_->mvert[v2_index].co); + const float d0 = len_squared_v3v3(positions_[i], verts[v0_index].co); + const float d1 = len_squared_v3v3(positions_[i], verts[v1_index].co); + const float d2 = len_squared_v3v3(positions_[i], verts[v2_index].co); nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1)); } @@ -257,6 +263,8 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng, Vector<int> &r_looptri_indices, Vector<float3> &r_positions) { + const Span<MVert> verts = mesh.vertices(); + const Span<MLoop> loops = mesh.loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), BKE_mesh_runtime_looptri_len(&mesh)}; @@ -270,9 +278,9 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng, for (const int looptri_index : looptri_indices_to_sample) { const MLoopTri &looptri = looptris[looptri_index]; - const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co; - const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co; - const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co; + const float3 &v0 = verts[loops[looptri.tri[0]].v].co; + const float3 &v1 = verts[loops[looptri.tri[1]].v].co; + const float3 &v2 = verts[loops[looptri.tri[2]].v].co; const float looptri_area = area_tri_v3(v0, v1, v2); @@ -353,6 +361,8 @@ int sample_surface_points_projected( Vector<int> &r_looptri_indices, Vector<float3> &r_positions) { + const Span<MVert> verts = mesh.vertices(); + const Span<MLoop> loops = mesh.loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), BKE_mesh_runtime_looptri_len(&mesh)}; @@ -394,7 +404,8 @@ int sample_surface_points_projected( const int looptri_index = ray_hit.index; const float3 pos = ray_hit.co; - const float3 bary_coords = compute_bary_coord_in_triangle(mesh, looptris[looptri_index], pos); + const float3 bary_coords = compute_bary_coord_in_triangle( + verts, loops, looptris[looptri_index], pos); r_positions.append(pos); r_bary_coords.append(bary_coords); @@ -404,13 +415,14 @@ int sample_surface_points_projected( return point_count; } -float3 compute_bary_coord_in_triangle(const Mesh &mesh, +float3 compute_bary_coord_in_triangle(const Span<MVert> verts, + const Span<MLoop> loops, const MLoopTri &looptri, const float3 &position) { - const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co; - const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co; - const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co; + const float3 &v0 = verts[loops[looptri.tri[0]].v].co; + const float3 &v1 = verts[loops[looptri.tri[1]].v].co; + const float3 &v2 = verts[loops[looptri.tri[2]].v].co; float3 bary_coords; interp_weights_tri_v3(bary_coords, v0, v1, v2, position); return bary_coords; diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c index 497f9ff3cbd..8e3f98b9b95 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.c +++ b/source/blender/blenkernel/intern/mesh_tangent.c @@ -179,14 +179,14 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, return; } - BKE_mesh_calc_loop_tangent_single_ex(mesh->mvert, + BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_vertices(mesh), mesh->totvert, - mesh->mloop, + BKE_mesh_loops(mesh), r_looptangents, loopnors, loopuvs, mesh->totloop, - mesh->mpoly, + BKE_mesh_polygons(mesh), mesh->totpoly, reports); } @@ -719,10 +719,10 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, /* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */ short tangent_mask = 0; - BKE_mesh_calc_loop_tangent_ex(me_eval->mvert, - me_eval->mpoly, + BKE_mesh_calc_loop_tangent_ex(BKE_mesh_vertices(me_eval), + BKE_mesh_polygons(me_eval), (uint)me_eval->totpoly, - me_eval->mloop, + BKE_mesh_loops(me_eval), me_eval->runtime.looptris.array, (uint)me_eval->runtime.looptris.len, &me_eval->ldata, diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index c30f3661103..dafc2384282 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -33,6 +33,9 @@ #include "MEM_guardedalloc.h" +using blender::MutableSpan; +using blender::Span; + /* loop v/e are unsigned, so using max uint_32 value as invalid marker... */ #define INVALID_LOOP_EDGE_MARKER 4294967295u @@ -1064,19 +1067,23 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_ do_verbose, true, &changed); + MutableSpan<MVert> verts = me->vertices_for_write(); + MutableSpan<MEdge> edges = me->edges_for_write(); + MutableSpan<MPoly> polys = me->polygons_for_write(); + MutableSpan<MLoop> loops = me->loops_for_write(); BKE_mesh_validate_arrays(me, - me->mvert, - me->totvert, - me->medge, - me->totedge, - me->mface, + verts.data(), + verts.size(), + edges.data(), + edges.size(), + (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), me->totface, - me->mloop, - me->totloop, - me->mpoly, - me->totpoly, - me->dvert, + loops.data(), + loops.size(), + polys.data(), + polys.size(), + me->deform_verts_for_write().data(), do_verbose, true, &changed); @@ -1113,18 +1120,23 @@ bool BKE_mesh_is_valid(Mesh *me) do_fixes, &changed); + MutableSpan<MVert> verts = me->vertices_for_write(); + MutableSpan<MEdge> edges = me->edges_for_write(); + MutableSpan<MPoly> polys = me->polygons_for_write(); + MutableSpan<MLoop> loops = me->loops_for_write(); + is_valid &= BKE_mesh_validate_arrays(me, - me->mvert, - me->totvert, - me->medge, - me->totedge, - me->mface, + verts.data(), + verts.size(), + edges.data(), + edges.size(), + (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), me->totface, - me->mloop, - me->totloop, - me->mpoly, - me->totpoly, - me->dvert, + loops.data(), + loops.size(), + polys.data(), + polys.size(), + me->deform_verts_for_write().data(), do_verbose, do_fixes, &changed); @@ -1170,11 +1182,12 @@ void BKE_mesh_strip_loose_faces(Mesh *me) /* NOTE: We need to keep this for edge creation (for now?), and some old `readfile.c` code. */ MFace *f; int a, b; + MFace *mfaces = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE); - for (a = b = 0, f = me->mface; a < me->totface; a++, f++) { + for (a = b = 0, f = mfaces; a < me->totface; a++, f++) { if (f->v3) { if (a != b) { - memcpy(&me->mface[b], f, sizeof(me->mface[b])); + memcpy(&mfaces[b], f, sizeof(mfaces[b])); CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1); } b++; @@ -1188,13 +1201,16 @@ void BKE_mesh_strip_loose_faces(Mesh *me) void BKE_mesh_strip_loose_polysloops(Mesh *me) { + MutableSpan<MPoly> polys = me->polygons_for_write(); + MutableSpan<MLoop> loops = me->loops_for_write(); + MPoly *p; MLoop *l; int a, b; /* New loops idx! */ int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__); - for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) { + for (a = b = 0, p = polys.data(); a < me->totpoly; a++, p++) { bool invalid = false; int i = p->loopstart; int stop = i + p->totloop; @@ -1203,7 +1219,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me) invalid = true; } else { - l = &me->mloop[i]; + l = &loops[i]; i = stop - i; /* If one of the poly's loops is invalid, the whole poly is invalid! */ for (; i--; l++) { @@ -1216,7 +1232,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me) if (p->totloop >= 3 && !invalid) { if (a != b) { - memcpy(&me->mpoly[b], p, sizeof(me->mpoly[b])); + memcpy(&polys[b], p, sizeof(polys[b])); CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1); } b++; @@ -1228,10 +1244,10 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me) } /* And now, get rid of invalid loops. */ - for (a = b = 0, l = me->mloop; a < me->totloop; a++, l++) { + for (a = b = 0, l = loops.data(); a < me->totloop; a++, l++) { if (l->e != INVALID_LOOP_EDGE_MARKER) { if (a != b) { - memcpy(&me->mloop[b], l, sizeof(me->mloop[b])); + memcpy(&loops[b], l, sizeof(loops[b])); CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1); } new_idx[a] = b; @@ -1250,8 +1266,8 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me) /* And now, update polys' start loop index. */ /* NOTE: At this point, there should never be any poly using a striped loop! */ - for (a = 0, p = me->mpoly; a < me->totpoly; a++, p++) { - p->loopstart = new_idx[p->loopstart]; + for (const int i : polys.index_range()) { + polys[i].loopstart = new_idx[polys[i].loopstart]; } MEM_freeN(new_idx); @@ -1260,14 +1276,14 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me) void BKE_mesh_strip_loose_edges(Mesh *me) { MEdge *e; - MLoop *l; int a, b; uint *new_idx = (uint *)MEM_mallocN(sizeof(int) * me->totedge, __func__); + MutableSpan<MEdge> edges = me->edges_for_write(); - for (a = b = 0, e = me->medge; a < me->totedge; a++, e++) { + for (a = b = 0, e = edges.data(); a < me->totedge; a++, e++) { if (e->v1 != e->v2) { if (a != b) { - memcpy(&me->medge[b], e, sizeof(me->medge[b])); + memcpy(&edges[b], e, sizeof(edges[b])); CustomData_copy_data(&me->edata, &me->edata, a, b, 1); } new_idx[a] = b; @@ -1285,8 +1301,9 @@ void BKE_mesh_strip_loose_edges(Mesh *me) /* And now, update loops' edge indices. */ /* XXX We hope no loop was pointing to a striped edge! * Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */ - for (a = 0, l = me->mloop; a < me->totloop; a++, l++) { - l->e = new_idx[l->e]; + MutableSpan<MLoop> loops = me->loops_for_write(); + for (MLoop &loop : loops) { + loop.e = new_idx[loop.e]; } MEM_freeN(new_idx); @@ -1344,10 +1361,10 @@ static int vergedgesort(const void *v1, const void *v2) /* Create edges based on known verts and faces, * this function is only used when loading very old blend files */ -static void mesh_calc_edges_mdata(MVert *UNUSED(allvert), - MFace *allface, +static void mesh_calc_edges_mdata(const MVert *UNUSED(allvert), + const MFace *allface, MLoop *allloop, - MPoly *allpoly, + const MPoly *allpoly, int UNUSED(totvert), int totface, int UNUSED(totloop), @@ -1356,8 +1373,8 @@ static void mesh_calc_edges_mdata(MVert *UNUSED(allvert), MEdge **r_medge, int *r_totedge) { - MPoly *mpoly; - MFace *mface; + const MPoly *mpoly; + const MFace *mface; MEdge *medge, *med; EdgeHash *hash; struct EdgeSort *edsort, *ed; @@ -1480,28 +1497,29 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) { MEdge *medge; int totedge = 0; - - mesh_calc_edges_mdata(me->mvert, - me->mface, - me->mloop, - me->mpoly, - me->totvert, + const Span<MVert> verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + MutableSpan<MLoop> loops = me->loops_for_write(); + + mesh_calc_edges_mdata(verts.data(), + (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), + loops.data(), + polys.data(), + verts.size(), me->totface, - me->totloop, - me->totpoly, + loops.size(), + polys.size(), use_old, &medge, &totedge); if (totedge == 0) { /* flag that mesh has edges */ - me->medge = medge; me->totedge = 0; return; } medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge); - me->medge = medge; me->totedge = totedge; BKE_mesh_strip_loose_faces(me); @@ -1509,18 +1527,18 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) void BKE_mesh_calc_edges_loose(Mesh *mesh) { - MEdge *med = mesh->medge; - for (int i = 0; i < mesh->totedge; i++, med++) { - med->flag |= ME_LOOSEEDGE; + const Span<MLoop> loops = mesh->loops(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + + for (const int i : edges.index_range()) { + edges[i].flag |= ME_LOOSEEDGE; } - MLoop *ml = mesh->mloop; - for (int i = 0; i < mesh->totloop; i++, ml++) { - mesh->medge[ml->e].flag &= ~ME_LOOSEEDGE; + for (const int i : loops.index_range()) { + edges[loops[i].e].flag &= ~ME_LOOSEEDGE; } - med = mesh->medge; - for (int i = 0; i < mesh->totedge; i++, med++) { - if (med->flag & ME_LOOSEEDGE) { - med->flag |= ME_EDGEDRAW; + for (const int i : edges.index_range()) { + if (edges[i].flag & ME_LOOSEEDGE) { + edges[i].flag |= ME_EDGEDRAW; } } } @@ -1529,8 +1547,9 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh) { const int numFaces = mesh->totface; EdgeSet *eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces)); + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); - MFace *mf = mesh->mface; + MFace *mf = mfaces; for (int i = 0; i < numFaces; i++, mf++) { BLI_edgeset_add(eh, mf->v1, mf->v2); BLI_edgeset_add(eh, mf->v2, mf->v3); @@ -1570,8 +1589,6 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh) mesh->edata = edgeData; mesh->totedge = numEdges; - mesh->medge = (MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE); - BLI_edgeset_free(eh); } diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 19d4444aa2f..fe28fc37d45 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -46,6 +46,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +using blender::Span; + Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em, const CustomData_MeshMasks *cd_mask_extra, const float (*vert_coords)[3], @@ -195,9 +197,9 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: { BLI_assert(vert_coords_len <= me->totvert); - const MVert *mvert = me->mvert; + const Span<MVert> verts = me->vertices(); for (int i = 0; i < vert_coords_len; i++) { - copy_v3_v3(vert_coords[i], mvert[i].co); + copy_v3_v3(vert_coords[i], verts[i].co); } return; } @@ -233,9 +235,9 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: { BLI_assert(vert_coords_len == me->totvert); - const MVert *mvert = me->mvert; + const Span<MVert> verts = me->vertices(); for (int i = 0; i < vert_coords_len; i++) { - mul_v3_m4v3(vert_coords[i], mat, mvert[i].co); + mul_v3_m4v3(vert_coords[i], mat, verts[i].co); } return; } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 5c382a4e864..20b7ed7b4b2 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -183,6 +183,7 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidde static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int level) { + const MPoly *polys = BKE_mesh_polygons(me); const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); BLI_bitmap **grid_hidden = ccgdm->gridHidden; int *gridOffset; @@ -191,7 +192,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int gridOffset = ccgdm->dm.getGridOffset(&ccgdm->dm); for (i = 0; i < me->totpoly; i++) { - for (j = 0; j < me->mpoly[i].totloop; j++) { + for (j = 0; j < polys[i].totloop; j++) { int g = gridOffset[i] + j; const MDisps *md = &mdisps[g]; BLI_bitmap *gh = md->hidden; @@ -466,15 +467,16 @@ void multires_force_external_reload(Object *object) static int get_levels_from_disps(Object *ob) { Mesh *me = ob->data; + const MPoly *polys = BKE_mesh_polygons(me); MDisps *mdisp, *md; int i, j, totlvl = 0; mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS); for (i = 0; i < me->totpoly; i++) { - md = mdisp + me->mpoly[i].loopstart; + md = mdisp + polys[i].loopstart; - for (j = 0; j < me->mpoly[i].totloop; j++, md++) { + for (j = 0; j < polys[i].totloop; j++, md++) { if (md->totdisp == 0) { continue; } @@ -633,6 +635,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level) static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) { Mesh *me = (Mesh *)ob->data; + const MPoly *polys = BKE_mesh_polygons(me); int levels = mmd->totlvl - lvl; MDisps *mdisps; GridPaintMask *gpm; @@ -652,8 +655,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) int i, j; for (i = 0; i < me->totpoly; i++) { - for (j = 0; j < me->mpoly[i].totloop; j++) { - int g = me->mpoly[i].loopstart + j; + for (j = 0; j < polys[i].totloop; j++) { + int g = polys[i].loopstart + j; MDisps *mdisp = &mdisps[g]; float(*disps)[3], (*ndisps)[3], (*hdisps)[3]; int totdisp = multires_grid_tot[lvl]; @@ -828,7 +831,7 @@ typedef struct MultiresThreadedData { CCGElem **gridData, **subGridData; CCGKey *key; CCGKey *sub_key; - MPoly *mpoly; + const MPoly *mpoly; MDisps *mdisps; GridPaintMask *grid_paint_mask; int *gridOffset; @@ -846,7 +849,7 @@ static void multires_disp_run_cb(void *__restrict userdata, CCGElem **gridData = tdata->gridData; CCGElem **subGridData = tdata->subGridData; CCGKey *key = tdata->key; - MPoly *mpoly = tdata->mpoly; + const MPoly *mpoly = tdata->mpoly; MDisps *mdisps = tdata->mdisps; GridPaintMask *grid_paint_mask = tdata->grid_paint_mask; int *gridOffset = tdata->gridOffset; @@ -939,7 +942,7 @@ static void multiresModifier_disp_run( CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGElem **gridData, **subGridData; CCGKey key; - MPoly *mpoly = me->mpoly; + const MPoly *mpoly = BKE_mesh_polygons(me); MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); GridPaintMask *grid_paint_mask = NULL; int *gridOffset; diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h index c4f320b86d8..5e2822ad5df 100644 --- a/source/blender/blenkernel/intern/multires_reshape.h +++ b/source/blender/blenkernel/intern/multires_reshape.h @@ -14,8 +14,12 @@ struct Depsgraph; struct GridPaintMask; struct MDisps; +struct MEdge; struct Mesh; +struct MLoop; +struct MPoly; struct MultiresModifierData; +struct MVert; struct Object; struct Subdiv; struct SubdivCCG; @@ -30,6 +34,10 @@ typedef struct MultiresReshapeContext { /* Base mesh from original object. * NOTE: Does NOT include any leading modifiers in it. */ struct Mesh *base_mesh; + const struct MVert *base_verts; + const struct MEdge *base_edges; + const struct MPoly *base_polys; + const struct MLoop *base_loops; /* Subdivision surface created for multires modifier. * diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c index f7d29806353..73f7197dcc9 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c @@ -30,11 +30,14 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context) { Mesh *base_mesh = reshape_context->base_mesh; - const MLoop *mloop = base_mesh->mloop; - MVert *mvert = base_mesh->mvert; + MVert *base_verts = BKE_mesh_vertices_for_write(base_mesh); + /* Update the context in case the vertices were duplicated. */ + reshape_context->base_verts = base_verts; + + const MLoop *mloop = reshape_context->base_loops; for (int loop_index = 0; loop_index < base_mesh->totloop; ++loop_index) { const MLoop *loop = &mloop[loop_index]; - MVert *vert = &mvert[loop->v]; + MVert *vert = &base_verts[loop->v]; GridCoord grid_coord; grid_coord.grid_index = loop_index; @@ -66,13 +69,15 @@ static float v3_dist_from_plane(const float v[3], const float center[3], const f void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context) { Mesh *base_mesh = reshape_context->base_mesh; - + MVert *base_verts = BKE_mesh_vertices_for_write(base_mesh); + /* Update the context in case the vertices were duplicated. */ + reshape_context->base_verts = base_verts; MeshElemMap *pmap; int *pmap_mem; BKE_mesh_vert_poly_map_create(&pmap, &pmap_mem, - base_mesh->mpoly, - base_mesh->mloop, + reshape_context->base_polys, + reshape_context->base_loops, base_mesh->totvert, base_mesh->totpoly, base_mesh->totloop); @@ -80,7 +85,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape float(*origco)[3] = MEM_calloc_arrayN( base_mesh->totvert, sizeof(float[3]), "multires apply base origco"); for (int i = 0; i < base_mesh->totvert; i++) { - copy_v3_v3(origco[i], base_mesh->mvert[i].co); + copy_v3_v3(origco[i], base_verts[i].co); } for (int i = 0; i < base_mesh->totvert; i++) { @@ -94,11 +99,11 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape /* Find center. */ int tot = 0; for (int j = 0; j < pmap[i].count; j++) { - const MPoly *p = &base_mesh->mpoly[pmap[i].indices[j]]; + const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; /* This double counts, not sure if that's bad or good. */ for (int k = 0; k < p->totloop; k++) { - const int vndx = base_mesh->mloop[p->loopstart + k].v; + const int vndx = reshape_context->base_loops[p->loopstart + k].v; if (vndx != i) { add_v3_v3(center, origco[vndx]); tot++; @@ -109,7 +114,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape /* Find normal. */ for (int j = 0; j < pmap[i].count; j++) { - const MPoly *p = &base_mesh->mpoly[pmap[i].indices[j]]; + const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; MPoly fake_poly; MLoop *fake_loops; float(*fake_co)[3]; @@ -122,7 +127,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape fake_co = MEM_malloc_arrayN(p->totloop, sizeof(float[3]), "fake_co"); for (int k = 0; k < p->totloop; k++) { - const int vndx = base_mesh->mloop[p->loopstart + k].v; + const int vndx = reshape_context->base_loops[p->loopstart + k].v; fake_loops[k].v = k; @@ -143,10 +148,10 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape normalize_v3(avg_no); /* Push vertex away from the plane. */ - const float dist = v3_dist_from_plane(base_mesh->mvert[i].co, center, avg_no); + const float dist = v3_dist_from_plane(base_verts[i].co, center, avg_no); copy_v3_v3(push, avg_no); mul_v3_fl(push, dist); - add_v3_v3(base_mesh->mvert[i].co, push); + add_v3_v3(base_verts[i].co, push); } MEM_freeN(origco); diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c index 8246de12ebf..97c85ae526c 100644 --- a/source/blender/blenkernel/intern/multires_reshape_smooth.c +++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c @@ -643,8 +643,7 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context, const int face_index = multires_reshape_grid_to_face_index(reshape_context, grid_coord.grid_index); - const Mesh *base_mesh = reshape_context->base_mesh; - const MPoly *base_poly = &base_mesh->mpoly[face_index]; + const MPoly *base_poly = &reshape_context->base_polys[face_index]; const int num_corners = base_poly->totloop; const int start_grid_index = reshape_context->face_start_grid_index[face_index]; const int corner = grid_coord.grid_index - start_grid_index; @@ -834,8 +833,7 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context, return; } /* Edges without crease are to be ignored as well. */ - const Mesh *base_mesh = reshape_context->base_mesh; - const MEdge *base_edge = &base_mesh->medge[coarse_edge_index]; + const MEdge *base_edge = &reshape_context->base_edges[coarse_edge_index]; const char crease = get_effective_crease_char(reshape_smooth_context, base_edge); if (crease == 0) { return; @@ -847,9 +845,9 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap { const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; const Mesh *base_mesh = reshape_context->base_mesh; - const MPoly *base_mpoly = base_mesh->mpoly; - const MLoop *base_mloop = base_mesh->mloop; - const MEdge *base_edge = base_mesh->medge; + const MPoly *base_mpoly = reshape_context->base_polys; + const MLoop *base_mloop = reshape_context->base_loops; + const MEdge *base_edge = reshape_context->base_edges; reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge, "non_loose_base_edge_map"); diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.c index cecb57f4de4..0a630a4343e 100644 --- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c +++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.c @@ -28,12 +28,16 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) { + const MVert *verts = BKE_mesh_vertices(mesh); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); + MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); const int totpoly = mesh->totpoly; for (int p = 0; p < totpoly; p++) { - MPoly *poly = &mesh->mpoly[p]; + const MPoly *poly = &polys[p]; float poly_center[3]; - BKE_mesh_calc_poly_center(poly, &mesh->mloop[poly->loopstart], mesh->mvert, poly_center); + BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], verts, poly_center); for (int l = 0; l < poly->totloop; l++) { const int loop_index = poly->loopstart + l; @@ -44,14 +48,14 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) int prev_loop_index = l - 1 >= 0 ? loop_index - 1 : loop_index + poly->totloop - 1; int next_loop_index = l + 1 < poly->totloop ? loop_index + 1 : poly->loopstart; - MLoop *loop = &mesh->mloop[loop_index]; - MLoop *loop_next = &mesh->mloop[next_loop_index]; - MLoop *loop_prev = &mesh->mloop[prev_loop_index]; + const MLoop *loop = &loops[loop_index]; + const MLoop *loop_next = &loops[next_loop_index]; + const MLoop *loop_prev = &loops[prev_loop_index]; copy_v3_v3(disps[0], poly_center); - mid_v3_v3v3(disps[1], mesh->mvert[loop->v].co, mesh->mvert[loop_next->v].co); - mid_v3_v3v3(disps[2], mesh->mvert[loop->v].co, mesh->mvert[loop_prev->v].co); - copy_v3_v3(disps[3], mesh->mvert[loop->v].co); + mid_v3_v3v3(disps[1], verts[loop->v].co, verts[loop_next->v].co); + mid_v3_v3v3(disps[2], verts[loop->v].co, verts[loop_prev->v].co); + copy_v3_v3(disps[3], verts[loop->v].co); } } } diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c index 34aa90aa554..43768ef158a 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.c +++ b/source/blender/blenkernel/intern/multires_reshape_util.c @@ -66,7 +66,7 @@ static void context_zero(MultiresReshapeContext *reshape_context) static void context_init_lookup(MultiresReshapeContext *reshape_context) { const Mesh *base_mesh = reshape_context->base_mesh; - const MPoly *mpoly = base_mesh->mpoly; + const MPoly *mpoly = reshape_context->base_polys; const int num_faces = base_mesh->totpoly; reshape_context->face_start_grid_index = MEM_malloc_arrayN( @@ -152,6 +152,10 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; + reshape_context->base_verts = BKE_mesh_vertices(base_mesh); + reshape_context->base_edges = BKE_mesh_edges(base_mesh); + reshape_context->base_polys = BKE_mesh_polygons(base_mesh); + reshape_context->base_loops = BKE_mesh_loops(base_mesh); reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd); reshape_context->need_free_subdiv = true; @@ -185,6 +189,10 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; + reshape_context->base_verts = BKE_mesh_vertices(base_mesh); + reshape_context->base_edges = BKE_mesh_edges(base_mesh); + reshape_context->base_polys = BKE_mesh_polygons(base_mesh); + reshape_context->base_loops = BKE_mesh_loops(base_mesh); reshape_context->subdiv = multires_reshape_create_subdiv(depsgraph, object, mmd); reshape_context->need_free_subdiv = true; @@ -212,6 +220,10 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co context_zero(reshape_context); reshape_context->base_mesh = base_mesh; + reshape_context->base_verts = BKE_mesh_vertices(base_mesh); + reshape_context->base_edges = BKE_mesh_edges(base_mesh); + reshape_context->base_polys = BKE_mesh_polygons(base_mesh); + reshape_context->base_loops = BKE_mesh_loops(base_mesh); reshape_context->subdiv = subdiv_ccg->subdiv; reshape_context->need_free_subdiv = false; @@ -255,6 +267,10 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; + reshape_context->base_verts = BKE_mesh_vertices(base_mesh); + reshape_context->base_edges = BKE_mesh_edges(base_mesh); + reshape_context->base_polys = BKE_mesh_polygons(base_mesh); + reshape_context->base_loops = BKE_mesh_loops(base_mesh); reshape_context->subdiv = subdiv; reshape_context->need_free_subdiv = false; @@ -344,7 +360,7 @@ int multires_reshape_grid_to_corner(const MultiresReshapeContext *reshape_contex bool multires_reshape_is_quad_face(const MultiresReshapeContext *reshape_context, int face_index) { - const MPoly *base_poly = &reshape_context->base_mesh->mpoly[face_index]; + const MPoly *base_poly = &reshape_context->base_polys[face_index]; return (base_poly->totloop == 4); } @@ -636,8 +652,7 @@ static void foreach_grid_face_coordinate_task(void *__restrict userdata_v, const MultiresReshapeContext *reshape_context = data->reshape_context; - const Mesh *base_mesh = data->reshape_context->base_mesh; - const MPoly *mpoly = base_mesh->mpoly; + const MPoly *mpoly = reshape_context->base_polys; const int grid_size = data->grid_size; const float grid_size_1_inv = 1.0f / (((float)grid_size) - 1.0f); diff --git a/source/blender/blenkernel/intern/multires_reshape_vertcos.c b/source/blender/blenkernel/intern/multires_reshape_vertcos.c index e50f5e71bf7..7cf853e0374 100644 --- a/source/blender/blenkernel/intern/multires_reshape_vertcos.c +++ b/source/blender/blenkernel/intern/multires_reshape_vertcos.c @@ -52,8 +52,7 @@ static void multires_reshape_vertcos_foreach_vertex(const SubdivForeachContext * const int face_index = multires_reshape_grid_to_face_index(reshape_context, grid_coord.grid_index); - const Mesh *base_mesh = reshape_context->base_mesh; - const MPoly *base_poly = &base_mesh->mpoly[face_index]; + const MPoly *base_poly = &reshape_context->base_polys[face_index]; const int num_corners = base_poly->totloop; const int start_grid_index = reshape_context->face_start_grid_index[face_index]; const int corner = grid_coord.grid_index - start_grid_index; diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c index 27a1f84579e..26ae914d67e 100644 --- a/source/blender/blenkernel/intern/multires_unsubdivide.c +++ b/source/blender/blenkernel/intern/multires_unsubdivide.c @@ -639,9 +639,10 @@ static void store_grid_data(MultiresUnsubdivideContext *context, int grid_x, int grid_y) { - Mesh *original_mesh = context->original_mesh; - MPoly *poly = &original_mesh->mpoly[BM_elem_index_get(f)]; + const MPoly *polys = BKE_mesh_polygons(original_mesh); + const MLoop *loops = BKE_mesh_loops(original_mesh); + const MPoly *poly = &polys[BM_elem_index_get(f)]; const int corner_vertex_index = BM_elem_index_get(v); @@ -650,7 +651,7 @@ static void store_grid_data(MultiresUnsubdivideContext *context, int loop_offset = 0; for (int i = 0; i < poly->totloop; i++) { const int loop_index = poly->loopstart + i; - MLoop *l = &original_mesh->mloop[loop_index]; + const MLoop *l = &loops[loop_index]; if (l->v == corner_vertex_index) { loop_offset = i; break; @@ -918,8 +919,9 @@ static void multires_unsubdivide_add_original_index_datalayers(Mesh *mesh) static void multires_unsubdivide_prepare_original_bmesh_for_extract( MultiresUnsubdivideContext *context) { - Mesh *original_mesh = context->original_mesh; + const MPoly *original_polys = BKE_mesh_polygons(original_mesh); + Mesh *base_mesh = context->base_mesh; BMesh *bm_original_mesh = context->bm_original_mesh = get_bmesh_from_mesh(original_mesh); @@ -949,7 +951,7 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract( context->loop_to_face_map = MEM_calloc_arrayN(original_mesh->totloop, sizeof(int), "loop map"); for (int i = 0; i < original_mesh->totpoly; i++) { - MPoly *poly = &original_mesh->mpoly[i]; + const MPoly *poly = &original_polys[i]; for (int l = 0; l < poly->totloop; l++) { int original_loop_index = l + poly->loopstart; context->loop_to_face_map[original_loop_index] = i; @@ -963,16 +965,19 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract( */ static bool multires_unsubdivide_flip_grid_x_axis(Mesh *mesh, int poly, int loop, int v_x) { - MPoly *p = &mesh->mpoly[poly]; + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); + + const MPoly *p = &polys[poly]; - MLoop *l_first = &mesh->mloop[p->loopstart]; + const MLoop *l_first = &loops[p->loopstart]; if ((loop == (p->loopstart + (p->totloop - 1))) && l_first->v == v_x) { return true; } int next_l_index = loop + 1; if (next_l_index < p->loopstart + p->totloop) { - MLoop *l_next = &mesh->mloop[next_l_index]; + const MLoop *l_next = &loops[next_l_index]; if (l_next->v == v_x) { return true; } diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 0389fa2f1c6..ec21d0b127b 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -145,6 +145,8 @@ #include "atomic_ops.h" using blender::float3; +using blender::MutableSpan; +using blender::Span; static CLG_LogRef LOG = {"bke.object"}; @@ -3189,6 +3191,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) BKE_object_get_evaluated_mesh(par); if (me_eval) { + const MVert *verts = BKE_mesh_vertices(me_eval); int count = 0; int numVerts = me_eval->totvert; @@ -3222,14 +3225,14 @@ static void give_parvert(Object *par, int nr, float vec[3]) /* Get the average of all verts with (original index == nr). */ for (int i = 0; i < numVerts; i++) { if (index[i] == nr) { - add_v3_v3(vec, me_eval->mvert[i].co); + add_v3_v3(vec, verts[i].co); count++; } } } else { if (nr < numVerts) { - add_v3_v3(vec, me_eval->mvert[nr].co); + add_v3_v3(vec, verts[nr].co); count++; } } @@ -3243,7 +3246,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) else { /* use first index if its out of range */ if (me_eval->totvert) { - copy_v3_v3(vec, me_eval->mvert[0].co); + copy_v3_v3(vec, verts[0].co); } } } @@ -4127,10 +4130,10 @@ void BKE_object_foreach_display_point(Object *ob, float3 co; if (mesh_eval != nullptr) { - const MVert *mv = mesh_eval->mvert; + const MVert *verts = BKE_mesh_vertices(mesh_eval); const int totvert = mesh_eval->totvert; - for (int i = 0; i < totvert; i++, mv++) { - mul_v3_m4v3(co, obmat, mv->co); + for (int i = 0; i < totvert; i++) { + mul_v3_m4v3(co, obmat, verts[i].co); func_cb(co, user_data); } } @@ -4754,7 +4757,8 @@ bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb) switch (ob->type) { case OB_MESH: { Mesh *mesh = (Mesh *)ob->data; - BKE_keyblock_convert_to_mesh(key->refkey, mesh->mvert, mesh->totvert); + MutableSpan<MVert> verts = mesh->vertices_for_write(); + BKE_keyblock_convert_to_mesh(key->refkey, verts.data(), mesh->totvert); break; } case OB_CURVES_LEGACY: @@ -5250,32 +5254,31 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot) const int *index; if (me_eval && (index = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX))) { - MVert *mvert = me_eval->mvert; - uint totvert = me_eval->totvert; + const Span<MVert> verts = me->vertices(); /* Tree over-allocates in case where some verts have #ORIGINDEX_NONE. */ tot = 0; - tree = BLI_kdtree_3d_new(totvert); + tree = BLI_kdtree_3d_new(verts.size()); /* We don't how many verts from the DM we can use. */ - for (i = 0; i < totvert; i++) { + for (i = 0; i < verts.size(); i++) { if (index[i] != ORIGINDEX_NONE) { float co[3]; - mul_v3_m4v3(co, ob->obmat, mvert[i].co); + mul_v3_m4v3(co, ob->obmat, verts[i].co); BLI_kdtree_3d_insert(tree, index[i], co); tot++; } } } else { - MVert *mvert = me->mvert; + const Span<MVert> verts = me->vertices(); - tot = me->totvert; + tot = verts.size(); tree = BLI_kdtree_3d_new(tot); for (i = 0; i < tot; i++) { float co[3]; - mul_v3_m4v3(co, ob->obmat, mvert[i].co); + mul_v3_m4v3(co, ob->obmat, verts[i].co); BLI_kdtree_3d_insert(tree, i, co); } } diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 08d98775e34..4c59b4a5210 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -114,10 +114,7 @@ bDeformGroup *BKE_object_defgroup_add(Object *ob) MDeformVert *BKE_object_defgroup_data_create(ID *id) { if (GS(id->name) == ID_ME) { - Mesh *me = (Mesh *)id; - me->dvert = CustomData_add_layer( - &me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, me->totvert); - return me->dvert; + return BKE_mesh_deform_verts_for_write((Mesh *)id); } if (GS(id->name) == ID_LT) { Lattice *lt = (Lattice *)id; @@ -165,12 +162,12 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele } } else { - if (me->dvert) { - MVert *mv; + if (BKE_mesh_deform_verts(me)) { + const MVert *mv; int i; - mv = me->mvert; - dv = me->dvert; + mv = BKE_mesh_vertices(me); + dv = BKE_mesh_deform_verts_for_write(me); for (i = 0; i < me->totvert; i++, mv++, dv++) { if (dv->dw && (!use_selection || (mv->flag & SELECT))) { @@ -265,7 +262,6 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in if (ob->type == OB_MESH) { Mesh *me = ob->data; CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert = NULL; } else if (ob->type == OB_LATTICE) { Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); @@ -413,7 +409,6 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked) if (ob->type == OB_MESH) { Mesh *me = ob->data; CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - me->dvert = NULL; } else if (ob->type == OB_LATTICE) { Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data)); @@ -502,7 +497,7 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t switch (GS(id->name)) { case ID_ME: { Mesh *me = (Mesh *)id; - *dvert_arr = me->dvert; + *dvert_arr = BKE_mesh_deform_verts_for_write(me); *dvert_tot = me->totvert; return true; } diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 228bc682ddd..d42404922e3 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -628,7 +628,7 @@ static void make_duplis_verts(const DupliContext *ctx) VertexDupliData_Mesh vdd{}; vdd.params = vdd_params; vdd.totvert = me_eval->totvert; - vdd.mvert = me_eval->mvert; + vdd.mvert = me_eval->vertices().data(); vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval); vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO); @@ -1178,9 +1178,9 @@ static void make_duplis_faces(const DupliContext *ctx) FaceDupliData_Mesh fdd{}; fdd.params = fdd_params; fdd.totface = me_eval->totpoly; - fdd.mpoly = me_eval->mpoly; - fdd.mloop = me_eval->mloop; - fdd.mvert = me_eval->mvert; + fdd.mpoly = me_eval->polygons().data(); + fdd.mloop = me_eval->loops().data(); + fdd.mvert = me_eval->vertices().data(); fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n( &me_eval->ldata, CD_MLOOPUV, uv_idx) : nullptr; diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 4c3da5eabc4..10dfa3f59e7 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -64,6 +64,9 @@ #include "bmesh.h" +using blender::MutableSpan; +using blender::Span; + static void palette_init_data(ID *id) { Palette *palette = (Palette *)id; @@ -1624,7 +1627,7 @@ static void sculpt_update_object(Depsgraph *depsgraph, Scene *scene = DEG_get_input_scene(depsgraph); Sculpt *sd = scene->toolsettings->sculpt; SculptSession *ss = ob->sculpt; - const Mesh *me = BKE_object_get_original_mesh(ob); + Mesh *me = BKE_object_get_original_mesh(ob); Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0; @@ -1664,17 +1667,17 @@ static void sculpt_update_object(Depsgraph *depsgraph, /* These are assigned to the base mesh in Multires. This is needed because Face Sets operators * and tools use the Face Sets data from the base mesh when Multires is active. */ - ss->mvert = me->mvert; - ss->mpoly = me->mpoly; - ss->mloop = me->mloop; + ss->mvert = BKE_mesh_vertices_for_write(me); + ss->mpoly = BKE_mesh_polygons(me); + ss->mloop = BKE_mesh_loops(me); } else { ss->totvert = me->totvert; ss->totpoly = me->totpoly; ss->totfaces = me->totpoly; - ss->mvert = me->mvert; - ss->mpoly = me->mpoly; - ss->mloop = me->mloop; + ss->mvert = BKE_mesh_vertices_for_write(me); + ss->mpoly = BKE_mesh_polygons(me); + ss->mloop = BKE_mesh_loops(me); ss->multires.active = false; ss->multires.modifier = nullptr; ss->multires.level = 0; @@ -1724,8 +1727,13 @@ static void sculpt_update_object(Depsgraph *depsgraph, BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default); if (need_pmap && ob->type == OB_MESH && !ss->pmap) { - BKE_mesh_vert_poly_map_create( - &ss->pmap, &ss->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop); + BKE_mesh_vert_poly_map_create(&ss->pmap, + &ss->pmap_mem, + BKE_mesh_polygons(me), + BKE_mesh_loops(me), + me->totvert, + me->totpoly, + me->totloop); if (ss->pbvh) { BKE_pbvh_pmap_set(ss->pbvh, ss->pmap); @@ -1743,7 +1751,8 @@ static void sculpt_update_object(Depsgraph *depsgraph, /* If the fully evaluated mesh has the same topology as the deform-only version, use it. * This matters because 'deform eval' is very restrictive and excludes even modifiers that * simply recompute vertex weights. */ - if (me_eval_deform->mpoly == me_eval->mpoly && me_eval_deform->mloop == me_eval->mloop && + if (me_eval_deform->polygons().data() == me_eval->polygons().data() && + me_eval_deform->loops().data() == me_eval->loops().data() && me_eval_deform->totvert == me_eval->totvert) { me_eval_deform = me_eval; } @@ -1921,7 +1930,7 @@ void BKE_sculpt_color_layer_create_if_needed(Object *object) CustomDataLayer *layer = orig_me->vdata.layers + CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR); - BKE_mesh_update_customdata_pointers(orig_me, true); + BKE_mesh_tessface_clear(orig_me); BKE_id_attributes_active_color_set(&orig_me->id, layer); DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES); @@ -1944,6 +1953,8 @@ void BKE_sculpt_update_object_for_edit( int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) { Mesh *me = static_cast<Mesh *>(ob->data); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); int ret = 0; const float *paint_mask = static_cast<const float *>( @@ -1972,12 +1983,12 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) /* if vertices already have mask, copy into multires data */ if (paint_mask) { for (i = 0; i < me->totpoly; i++) { - const MPoly *p = &me->mpoly[i]; + const MPoly *p = &polys[i]; float avg = 0; /* mask center */ for (j = 0; j < p->totloop; j++) { - const MLoop *l = &me->mloop[p->loopstart + j]; + const MLoop *l = &loops[p->loopstart + j]; avg += paint_mask[l->v]; } avg /= (float)p->totloop; @@ -1985,9 +1996,9 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) /* fill in multires mask corner */ for (j = 0; j < p->totloop; j++) { GridPaintMask *gpm = &gmask[p->loopstart + j]; - const MLoop *l = &me->mloop[p->loopstart + j]; - const MLoop *prev = ME_POLY_LOOP_PREV(me->mloop, p, j); - const MLoop *next = ME_POLY_LOOP_NEXT(me->mloop, p, j); + const MLoop *l = &loops[p->loopstart + j]; + const MLoop *prev = ME_POLY_LOOP_PREV(loops, p, j); + const MLoop *next = ME_POLY_LOOP_NEXT(loops, p, j); gpm->data[0] = avg; gpm->data[1] = (paint_mask[l->v] + paint_mask[next->v]) * 0.5f; @@ -2234,18 +2245,23 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool PBVH *pbvh = BKE_pbvh_new(); BKE_pbvh_respect_hide_set(pbvh, respect_hide); + MutableSpan<MVert> verts = me->vertices_for_write(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); + MLoopTri *looptri = static_cast<MLoopTri *>( MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__)); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri( + loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri); BKE_sculpt_sync_face_set_visibility(me, nullptr); BKE_pbvh_build_mesh(pbvh, me, - me->mpoly, - me->mloop, - me->mvert, + polys.data(), + loops.data(), + verts.data(), me->totvert, &me->vdata, &me->ldata, diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 9ccd6562649..8db83031e17 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1399,7 +1399,8 @@ static void init_particle_interpolation(Object *ob, pind->dietime = (key + pa->totkey - 1)->time; if (pind->mesh) { - pind->mvert[0] = &pind->mesh->mvert[pa->hair_index]; + MVert *verts = BKE_mesh_vertices_for_write(pind->mesh); + pind->mvert[0] = &verts[pa->hair_index]; pind->mvert[1] = pind->mvert[0] + 1; } } @@ -1664,7 +1665,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /************************************************/ void psys_interpolate_face(Mesh *mesh, - MVert *mvert, + const MVert *mvert, const float (*vert_normals)[3], MFace *mface, MTFace *tface, @@ -1676,7 +1677,7 @@ void psys_interpolate_face(Mesh *mesh, float vtan[3], float orco[3]) { - float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; + const float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; float e1[3], e2[3], s1, s2, t1, t2; float *uv1, *uv2, *uv3, *uv4; float n1[3], n2[3], n3[3], n4[3]; @@ -1852,7 +1853,8 @@ static float psys_interpolate_value_from_verts( return values[index]; case PART_FROM_FACE: case PART_FROM_VOLUME: { - MFace *mf = &mesh->mface[index]; + MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mf = &mfaces[index]; return interpolate_particle_value( values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4); } @@ -1941,7 +1943,7 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, index_mf_to_mpoly_deformed = NULL; - mtessface_final = mesh_final->mface; + mtessface_final = CustomData_get_layer(&mesh_final->fdata, CD_MFACE); osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE); if (osface_final == NULL) { @@ -2061,7 +2063,8 @@ static int psys_map_index_on_dm(Mesh *mesh, /* modify the original weights to become * weights for the derived mesh face */ OrigSpaceFace *osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE); - const MFace *mface = &mesh->mface[i]; + const MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE); + const MFace *mface = &mfaces[i]; if (osface == NULL) { mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f; @@ -2117,7 +2120,8 @@ void psys_particle_on_dm(Mesh *mesh_final, const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh_final); if (from == PART_FROM_VERT) { - copy_v3_v3(vec, mesh_final->mvert[mapindex].co); + const MVert *vertices = BKE_mesh_vertices(mesh_final); + copy_v3_v3(vec, vertices[mapindex].co); if (nor) { copy_v3_v3(nor, vert_normals[mapindex]); @@ -2143,9 +2147,10 @@ void psys_particle_on_dm(Mesh *mesh_final, MTFace *mtface; MVert *mvert; - mface = &mesh_final->mface[mapindex]; - mvert = mesh_final->mvert; - mtface = mesh_final->mtface; + MFace *mfaces = CustomData_get_layer(&mesh_final->fdata, CD_MFACE); + mface = &mfaces[mapindex]; + mvert = BKE_mesh_vertices_for_write(mesh_final); + mtface = CustomData_get_layer(&mesh_final->fdata, CD_MTFACE); if (mtface) { mtface += mapindex; @@ -2634,7 +2639,7 @@ float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup) /* hair dynamics pinning vgroup */ } else if (psys->vgroup[vgroup]) { - MDeformVert *dvert = mesh->dvert; + const MDeformVert *dvert = BKE_mesh_deform_verts(mesh); if (dvert) { int totvert = mesh->totvert, i; vg = MEM_callocN(sizeof(float) * totvert, "vg_cache"); @@ -3848,7 +3853,8 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] return; } - mface = &mesh->mface[i]; + MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = &mfaces[i]; const OrigSpaceFace *osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE); if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) { @@ -3863,9 +3869,10 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] } } else { - copy_v3_v3(v[0], mesh->mvert[mface->v1].co); - copy_v3_v3(v[1], mesh->mvert[mface->v2].co); - copy_v3_v3(v[2], mesh->mvert[mface->v3].co); + const MVert *verts = BKE_mesh_vertices(mesh); + copy_v3_v3(v[0], verts[mface->v1].co); + copy_v3_v3(v[1], verts[mface->v2].co); + copy_v3_v3(v[2], verts[mface->v3].co); } triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat); @@ -4155,6 +4162,7 @@ static int get_particle_uv(Mesh *mesh, float *texco, bool from_vert) { + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); MFace *mf; const MTFace *tf; int i; @@ -4162,10 +4170,6 @@ static int get_particle_uv(Mesh *mesh, tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name); if (tf == NULL) { - tf = mesh->mtface; - } - - if (tf == NULL) { return 0; } @@ -4186,7 +4190,7 @@ static int get_particle_uv(Mesh *mesh, } else { if (from_vert) { - mf = mesh->mface; + mf = mfaces; /* This finds the first face to contain the emitting vertex, * this is not ideal, but is mostly fine as UV seams generally @@ -4199,7 +4203,7 @@ static int get_particle_uv(Mesh *mesh, } } else { - mf = &mesh->mface[i]; + mf = &mfaces[i]; } psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco); diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index da769515f08..e19b25b2da1 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -97,7 +97,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) { ParticleData *pa = NULL; float min[3], max[3], delta[3], d; - MVert *mv, *mvert = mesh->mvert; + MVert *mv, *mvert = BKE_mesh_vertices_for_write(mesh); int totvert = mesh->totvert, from = psys->part->from; int i, j, k, p, res = psys->part->grid_res, size[3], axis; @@ -181,7 +181,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) int amax = from == PART_FROM_FACE ? 3 : 1; totface = mesh->totface; - mface = mface_array = mesh->mface; + mface = mface_array = CustomData_get_layer(&mesh->fdata, CD_MFACE); for (a = 0; a < amax; a++) { if (a == 0) { @@ -464,7 +464,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i ParticleThreadContext *ctx = thread->ctx; MFace *mface; - mface = ctx->mesh->mface; + mface = CustomData_get_layer(&ctx->mesh->fdata, CD_MFACE); int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */ @@ -525,10 +525,11 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i int i; int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */ + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); MFace *mface; pa->num = i = ctx->index[p]; - mface = &mesh->mface[i]; + mface = &mfaces[i]; switch (distr) { case PART_DISTR_JIT: @@ -575,10 +576,11 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */ MFace *mface; - MVert *mvert = mesh->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(mesh); pa->num = i = ctx->index[p]; - mface = &mesh->mface[i]; + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = &mfaces[i]; switch (distr) { case PART_DISTR_JIT: @@ -619,8 +621,8 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, min_d = FLT_MAX; intersect = 0; - - for (i = 0, mface = mesh->mface; i < tot; i++, mface++) { + mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); + for (i = 0; i < tot; i++, mface++) { if (i == pa->num) { continue; } @@ -689,7 +691,8 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i return; } - mf = &mesh->mface[ctx->index[p]]; + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + mf = &mfaces[ctx->index[p]]; randu = BLI_rng_get_float(thread->rng); randv = BLI_rng_get_float(thread->rng); @@ -989,7 +992,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, BKE_mesh_orco_ensure(ob, mesh); if (from == PART_FROM_VERT) { - MVert *mv = mesh->mvert; + MVert *mv = BKE_mesh_vertices_for_write(mesh); const float(*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO); int totvert = mesh->totvert; @@ -1042,8 +1045,9 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO); + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); for (i = 0; i < totelem; i++) { - MFace *mf = &mesh->mface[i]; + MFace *mf = &mfaces[i]; if (orcodata) { /* Transform orcos from normalized 0..1 to object space. */ @@ -1059,14 +1063,15 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, } } else { - v1 = &mesh->mvert[mf->v1]; - v2 = &mesh->mvert[mf->v2]; - v3 = &mesh->mvert[mf->v3]; + MVert *verts = BKE_mesh_vertices_for_write(mesh); + v1 = &verts[mf->v1]; + v2 = &verts[mf->v2]; + v3 = &verts[mf->v3]; copy_v3_v3(co1, v1->co); copy_v3_v3(co2, v2->co); copy_v3_v3(co3, v3->co); if (mf->v4) { - v4 = &mesh->mvert[mf->v4]; + v4 = &verts[mf->v4]; copy_v3_v3(co4, v4->co); } } @@ -1105,8 +1110,9 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, } } else { /* PART_FROM_FACE / PART_FROM_VOLUME */ + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); for (i = 0; i < totelem; i++) { - MFace *mf = &mesh->mface[i]; + MFace *mf = &mfaces[i]; tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3]; if (mf->v4) { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 254cea0bd8b..14c4691413d 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -3322,12 +3322,10 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, mesh = *r_mesh; if (!mesh) { *r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0); - CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, mesh->totvert); - BKE_mesh_update_customdata_pointers(mesh, false); } - mvert = mesh->mvert; - medge = mesh->medge; - dvert = mesh->dvert; + mvert = BKE_mesh_vertices_for_write(mesh); + medge = BKE_mesh_edges_for_write(mesh); + dvert = BKE_mesh_deform_verts_for_write(mesh); if (psys->clmd->hairdata == NULL) { psys->clmd->hairdata = MEM_mallocN(sizeof(ClothHairData) * totpoint, "hair data"); diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 49397797c0d..f733f3145ec 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -2,6 +2,7 @@ * Copyright 2022 Blender Foundation. All rights reserved. */ #include "BKE_customdata.h" +#include "BKE_mesh.h" #include "BKE_mesh_mapping.h" #include "BKE_pbvh.h" #include "BKE_pbvh_pixels.hh" @@ -291,7 +292,8 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image for (PBVHNode *node : nodes_to_update) { NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data); - init_triangles(pbvh, node, node_data, mesh->mloop); + const Span<MLoop> loops = mesh->loops(); + init_triangles(pbvh, node, node_data, loops.data()); } EncodePixelsUserData user_data; diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index e5fb61bfa2f..fb078a299b5 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -364,7 +364,7 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, if (ob->type == OB_MESH && ob->data) { mesh = rigidbody_get_mesh(ob); - mvert = (mesh) ? mesh->mvert : NULL; + mvert = (mesh) ? BKE_mesh_vertices_for_write(mesh) : NULL; totvert = (mesh) ? mesh->totvert : 0; } else { @@ -390,11 +390,9 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) if (ob->type == OB_MESH) { Mesh *mesh = NULL; - MVert *mvert; const MLoopTri *looptri; int totvert; int tottri; - const MLoop *mloop; mesh = rigidbody_get_mesh(ob); @@ -403,11 +401,11 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) return NULL; } - mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); tottri = mesh->runtime.looptris.len; - mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); /* sanity checking - potential case when no data will be present */ if ((totvert == 0) || (tottri == 0)) { @@ -670,21 +668,19 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) case RB_SHAPE_TRIMESH: { if (ob->type == OB_MESH) { Mesh *mesh = rigidbody_get_mesh(ob); - MVert *mvert; const MLoopTri *lt = NULL; int totvert, tottri = 0; - const MLoop *mloop = NULL; /* ensure mesh validity, then grab data */ if (mesh == NULL) { return; } - mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); totvert = mesh->totvert; lt = BKE_mesh_runtime_looptri_ensure(mesh); tottri = mesh->runtime.looptris.len; - mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL); @@ -746,21 +742,19 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) case RB_SHAPE_TRIMESH: { if (ob->type == OB_MESH) { Mesh *mesh = rigidbody_get_mesh(ob); - MVert *mvert; const MLoopTri *looptri; int totvert, tottri; - const MLoop *mloop; /* ensure mesh validity, then grab data */ if (mesh == NULL) { return; } - mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); tottri = mesh->runtime.looptris.len; - mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center); @@ -1677,7 +1671,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) { Mesh *mesh = ob->runtime.mesh_deform_eval; if (mesh) { - MVert *mvert = mesh->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(mesh); int totvert = mesh->totvert; const BoundBox *bb = BKE_object_boundbox_get(ob); diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 82cc250c6d1..bea2f8f3c4f 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -64,9 +64,9 @@ typedef struct ShrinkwrapCalcData { float (*vertexCos)[3]; /* vertexs being shrinkwraped */ int numVerts; - struct MDeformVert *dvert; /* Pointer to mdeform array */ - int vgroup; /* Vertex group num */ - bool invert_vgroup; /* invert vertex group influence */ + const struct MDeformVert *dvert; /* Pointer to mdeform array */ + int vgroup; /* Vertex group num */ + bool invert_vgroup; /* invert vertex group influence */ struct Mesh *target; /* mesh we are shrinking to */ struct SpaceTransform local2target; /* transform to move between local and target space */ @@ -113,6 +113,7 @@ bool BKE_shrinkwrap_init_tree( } data->mesh = mesh; + data->polys = BKE_mesh_polygons(mesh); if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) { data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2); @@ -191,9 +192,9 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata, static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh) { - const MLoop *mloop = mesh->mloop; - const MEdge *medge = mesh->medge; - const MVert *mvert = mesh->mvert; + const MVert *mvert = BKE_mesh_vertices(mesh); + const MEdge *medge = BKE_mesh_edges(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); /* Count faces per edge (up to 2). */ char *edge_mode = MEM_calloc_arrayN((size_t)mesh->totedge, sizeof(char), __func__); @@ -937,7 +938,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree, int eidx) { const BVHTreeFromMesh *data = &tree->treeData; - const MEdge *edge = &tree->mesh->medge[eidx]; + const MEdge *edge = &data->edge[eidx]; const float *vedge_co[2] = {data->vert[edge->v1].co, data->vert[edge->v2].co}; #ifdef TRACE_TARGET_PROJECT @@ -1179,7 +1180,7 @@ void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree, const float(*vert_normals)[3] = tree->treeData.vert_normals; /* Interpolate smooth normals if enabled. */ - if ((tree->mesh->mpoly[tri->poly].flag & ME_SMOOTH) != 0) { + if ((tree->polys[tri->poly].flag & ME_SMOOTH) != 0) { const uint32_t vert_indices[3] = {treeData->loop[tri->tri[0]].v, treeData->loop[tri->tri[1]].v, treeData->loop[tri->tri[2]].v}; @@ -1369,7 +1370,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, struct Scene *scene, Object *ob, Mesh *mesh, - MDeformVert *dvert, + const MDeformVert *dvert, const int defgrp_index, float (*vertexCos)[3], int numVerts) @@ -1411,7 +1412,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, if (mesh != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { /* Setup arrays to get vertexs positions, normals and deform weights */ - calc.vert = mesh->mvert; + calc.vert = BKE_mesh_vertices_for_write(mesh); calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh); /* Using vertexs positions/normals as if a subsurface was applied */ @@ -1574,7 +1575,7 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object calc.vgroup = -1; calc.target = target_me; calc.keepDist = ssmd.keepDist; - calc.vert = src_me->mvert; + calc.vert = BKE_mesh_vertices_for_write(src_me); BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob_target, ob_target); ShrinkwrapTreeData tree; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index afb8d5cb9f8..a426782af04 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -567,7 +567,7 @@ static void ccd_update_deflector_hash(Depsgraph *depsgraph, static int count_mesh_quads(Mesh *me) { int a, result = 0; - const MPoly *mp = me->mpoly; + const MPoly *mp = BKE_mesh_polygons(me); if (mp) { for (a = me->totpoly; a > 0; a--, mp++) { @@ -591,8 +591,8 @@ static void add_mesh_quad_diag_springs(Object *ob) nofquads = count_mesh_quads(me); if (nofquads) { - const MLoop *mloop = me->mloop; - const MPoly *mp = me->mpoly; + const MLoop *mloop = BKE_mesh_loops(me); + const MPoly *mp = BKE_mesh_polygons(me); BodySpring *bs; /* resize spring-array to hold additional quad springs */ @@ -2632,6 +2632,7 @@ static void springs_from_mesh(Object *ob) BodyPoint *bp; int a; float scale = 1.0f; + const MVert *vertices = BKE_mesh_vertices(me); sb = ob->soft; if (me && sb) { @@ -2642,7 +2643,7 @@ static void springs_from_mesh(Object *ob) if (me->totvert) { bp = ob->soft->bpoint; for (a = 0; a < me->totvert; a++, bp++) { - copy_v3_v3(bp->origS, me->mvert[a].co); + copy_v3_v3(bp->origS, vertices[a].co); mul_m4_v3(ob->obmat, bp->origS); } } @@ -2663,7 +2664,7 @@ static void mesh_to_softbody(Object *ob) { SoftBody *sb; Mesh *me = ob->data; - MEdge *medge = me->medge; + const MEdge *medge = BKE_mesh_edges(me); BodyPoint *bp; BodySpring *bs; int a, totedge; @@ -2683,10 +2684,11 @@ static void mesh_to_softbody(Object *ob) sb = ob->soft; bp = sb->bpoint; - defgroup_index = me->dvert ? (sb->vertgroup - 1) : -1; - defgroup_index_mass = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1; - defgroup_index_spring = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) : - -1; + const MDeformVert *dvert = BKE_mesh_deform_verts(me); + + defgroup_index = dvert ? (sb->vertgroup - 1) : -1; + defgroup_index_mass = dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1; + defgroup_index_spring = dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) : -1; for (a = 0; a < me->totvert; a++, bp++) { /* get scalar values needed *per vertex* from vertex group functions, @@ -2699,7 +2701,7 @@ static void mesh_to_softbody(Object *ob) BLI_assert(bp->goal == sb->defgoal); } if ((ob->softflag & OB_SB_GOAL) && (defgroup_index != -1)) { - bp->goal *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index); + bp->goal *= BKE_defvert_find_weight(&dvert[a], defgroup_index); } /* to proof the concept @@ -2707,11 +2709,11 @@ static void mesh_to_softbody(Object *ob) */ if (defgroup_index_mass != -1) { - bp->mass *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_mass); + bp->mass *= BKE_defvert_find_weight(&dvert[a], defgroup_index_mass); } if (defgroup_index_spring != -1) { - bp->springweight *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_spring); + bp->springweight *= BKE_defvert_find_weight(&dvert[a], defgroup_index_spring); } } @@ -2753,19 +2755,23 @@ static void mesh_faces_to_scratch(Object *ob) MLoopTri *looptri, *lt; BodyFace *bodyface; int a; + const MVert *vertices = BKE_mesh_vertices(me); + const MPoly *polygons = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); + /* Allocate and copy faces. */ sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop); looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri(loops, polygons, vertices, me->totloop, me->totpoly, looptri); bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface, "SB_body_Faces"); for (a = 0; a < sb->scratch->totface; a++, lt++, bodyface++) { - bodyface->v1 = me->mloop[lt->tri[0]].v; - bodyface->v2 = me->mloop[lt->tri[1]].v; - bodyface->v3 = me->mloop[lt->tri[2]].v; + bodyface->v1 = loops[lt->tri[0]].v; + bodyface->v2 = loops[lt->tri[1]].v; + bodyface->v3 = loops[lt->tri[2]].v; zero_v3(bodyface->ext_force); bodyface->ext_force[0] = bodyface->ext_force[1] = bodyface->ext_force[2] = 0.0f; bodyface->flag = 0; diff --git a/source/blender/blenkernel/intern/subdiv_ccg_mask.c b/source/blender/blenkernel/intern/subdiv_ccg_mask.c index 1290f1e0834..95bbbfeb17e 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_mask.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_mask.c @@ -17,6 +17,7 @@ #include "BLI_utildefines.h" #include "BKE_customdata.h" +#include "BKE_mesh.h" #include "BKE_subdiv.h" #include "MEM_guardedalloc.h" @@ -102,7 +103,7 @@ static void free_mask_data(SubdivCCGMaskEvaluator *mask_evaluator) static int count_num_ptex_faces(const Mesh *mesh) { int num_ptex_faces = 0; - const MPoly *mpoly = mesh->mpoly; + const MPoly *mpoly = BKE_mesh_polygons(mesh); for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { const MPoly *poly = &mpoly[poly_index]; num_ptex_faces += (poly->totloop == 4) ? 1 : poly->totloop; @@ -113,7 +114,7 @@ static int count_num_ptex_faces(const Mesh *mesh) static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh) { GridPaintMaskData *data = mask_evaluator->user_data; - const MPoly *mpoly = mesh->mpoly; + const MPoly *mpoly = BKE_mesh_polygons(mesh); const int num_ptex_faces = count_num_ptex_faces(mesh); /* Allocate memory. */ data->ptex_poly_corner = MEM_malloc_arrayN( @@ -141,7 +142,7 @@ static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const static void mask_init_data(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh) { GridPaintMaskData *data = mask_evaluator->user_data; - data->mpoly = mesh->mpoly; + data->mpoly = BKE_mesh_polygons(mesh); data->grid_paint_mask = CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK); mask_data_init_mapping(mask_evaluator, mesh); } diff --git a/source/blender/blenkernel/intern/subdiv_ccg_material.c b/source/blender/blenkernel/intern/subdiv_ccg_material.c index 9095a628418..e84a5b6ca46 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_material.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_material.c @@ -5,7 +5,7 @@ * \ingroup bke */ -#include "BKE_customdata.h" +#include "BKE_mesh.h" #include "BKE_subdiv_ccg.h" #include "MEM_guardedalloc.h" @@ -15,6 +15,7 @@ typedef struct CCGMaterialFromMeshData { const Mesh *mesh; + const MPoly *polys; const int *material_indices; } CCGMaterialFromMeshData; @@ -22,10 +23,8 @@ static DMFlagMat subdiv_ccg_material_flags_eval( SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator, const int coarse_face_index) { CCGMaterialFromMeshData *data = (CCGMaterialFromMeshData *)material_flags_evaluator->user_data; - const Mesh *mesh = data->mesh; - BLI_assert(coarse_face_index < mesh->totpoly); - const MPoly *mpoly = mesh->mpoly; - const MPoly *poly = &mpoly[coarse_face_index]; + BLI_assert(coarse_face_index < data->mesh->totpoly); + const MPoly *poly = &data->polys[coarse_face_index]; DMFlagMat material_flags; material_flags.flag = poly->flag; material_flags.mat_nr = data->material_indices ? data->material_indices[coarse_face_index] : 0; @@ -46,6 +45,7 @@ void BKE_subdiv_ccg_material_flags_init_from_mesh( data->mesh = mesh; data->material_indices = (const int *)CustomData_get_layer_named( &mesh->pdata, CD_PROP_INT32, "material_index"); + data->polys = BKE_mesh_polygons(mesh); material_flags_evaluator->eval_material_flags = subdiv_ccg_material_flags_eval; material_flags_evaluator->free = subdiv_ccg_material_flags_free; material_flags_evaluator->user_data = data; diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 9c6d507d42c..f908e1af4ac 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -16,6 +16,7 @@ #include "BLI_utildefines.h" #include "BKE_customdata.h" +#include "BKE_mesh.h" #include "BKE_mesh_mapping.h" #include "BKE_subdiv.h" @@ -33,6 +34,11 @@ typedef struct ConverterStorage { SubdivSettings settings; const Mesh *mesh; + const MVert *verts; + const MEdge *edges; + const MPoly *polys; + const MLoop *loops; + /* CustomData layer for vertex sharpnesses. */ const float *cd_vertex_crease; /* Indexed by loop index, value denotes index of face-varying vertex @@ -116,7 +122,7 @@ static int get_num_vertices(const OpenSubdiv_Converter *converter) static int get_num_face_vertices(const OpenSubdiv_Converter *converter, int manifold_face_index) { ConverterStorage *storage = converter->user_data; - return storage->mesh->mpoly[manifold_face_index].totloop; + return storage->polys[manifold_face_index].totloop; } static void get_face_vertices(const OpenSubdiv_Converter *converter, @@ -124,8 +130,8 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter, int *manifold_face_vertices) { ConverterStorage *storage = converter->user_data; - const MPoly *poly = &storage->mesh->mpoly[manifold_face_index]; - const MLoop *mloop = storage->mesh->mloop; + const MPoly *poly = &storage->polys[manifold_face_index]; + const MLoop *mloop = storage->loops; for (int corner = 0; corner < poly->totloop; corner++) { manifold_face_vertices[corner] = storage->manifold_vertex_index[mloop[poly->loopstart + corner].v]; @@ -138,7 +144,7 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter, { ConverterStorage *storage = converter->user_data; const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index]; - const MEdge *edge = &storage->mesh->medge[edge_index]; + const MEdge *edge = &storage->edges[edge_index]; manifold_edge_vertices[0] = storage->manifold_vertex_index[edge->v1]; manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2]; } @@ -155,7 +161,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manif return 0.0f; } const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index]; - const MEdge *medge = storage->mesh->medge; + const MEdge *medge = storage->edges; return BKE_subdiv_crease_to_sharpness_char(medge[edge_index].crease); } @@ -193,8 +199,6 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la { ConverterStorage *storage = converter->user_data; const Mesh *mesh = storage->mesh; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index); const int num_poly = mesh->totpoly; const int num_vert = mesh->totvert; @@ -205,9 +209,9 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la mesh->totloop, sizeof(int), "loop uv vertex index"); } UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( - mpoly, + storage->polys, (const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"), - mloop, + storage->loops, mloopuv, num_poly, num_vert, @@ -222,7 +226,7 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la if (uv_vert->separate) { storage->num_uv_coordinates++; } - const MPoly *mp = &mpoly[uv_vert->poly_index]; + const MPoly *mp = &storage->polys[uv_vert->poly_index]; const int global_loop_index = mp->loopstart + uv_vert->loop_of_poly_index; storage->loop_uv_indices[global_loop_index] = storage->num_uv_coordinates; uv_vert = uv_vert->next; @@ -250,7 +254,7 @@ static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter, const int corner) { ConverterStorage *storage = converter->user_data; - const MPoly *mp = &storage->mesh->mpoly[face_index]; + const MPoly *mp = &storage->polys[face_index]; return storage->loop_uv_indices[mp->loopstart + corner]; } @@ -344,9 +348,9 @@ static void initialize_manifold_index_array(const BLI_bitmap *used_map, static void initialize_manifold_indices(ConverterStorage *storage) { const Mesh *mesh = storage->mesh; - const MEdge *medge = mesh->medge; - const MLoop *mloop = mesh->mloop; - const MPoly *mpoly = mesh->mpoly; + const MEdge *medge = storage->edges; + const MLoop *mloop = storage->loops; + const MPoly *mpoly = storage->polys; /* Set bits of elements which are not loose. */ BLI_bitmap *vert_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map"); BLI_bitmap *edge_used_map = BLI_BITMAP_NEW(mesh->totedge, "edge used map"); @@ -389,6 +393,10 @@ static void init_user_data(OpenSubdiv_Converter *converter, ConverterStorage *user_data = MEM_mallocN(sizeof(ConverterStorage), __func__); user_data->settings = *settings; user_data->mesh = mesh; + user_data->verts = BKE_mesh_vertices(mesh); + user_data->edges = BKE_mesh_edges(mesh); + user_data->polys = BKE_mesh_polygons(mesh); + user_data->loops = BKE_mesh_loops(mesh); user_data->cd_vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE); user_data->loop_uv_indices = NULL; initialize_manifold_indices(user_data); diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.c index 0decb57bb38..54078dea8da 100644 --- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c +++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.c @@ -18,6 +18,7 @@ #include "BLI_utildefines.h" #include "BKE_customdata.h" +#include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_subdiv_eval.h" @@ -360,7 +361,7 @@ static void free_displacement(SubdivDisplacement *displacement) static int count_num_ptex_faces(const Mesh *mesh) { int num_ptex_faces = 0; - const MPoly *mpoly = mesh->mpoly; + const MPoly *mpoly = BKE_mesh_polygons(mesh); for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) { const MPoly *poly = &mpoly[poly_index]; num_ptex_faces += (poly->totloop == 4) ? 1 : poly->totloop; @@ -371,7 +372,7 @@ static int count_num_ptex_faces(const Mesh *mesh) static void displacement_data_init_mapping(SubdivDisplacement *displacement, const Mesh *mesh) { MultiresDisplacementData *data = displacement->user_data; - const MPoly *mpoly = mesh->mpoly; + const MPoly *mpoly = BKE_mesh_polygons(mesh); const int num_ptex_faces = count_num_ptex_faces(mesh); /* Allocate memory. */ data->ptex_poly_corner = MEM_malloc_arrayN( @@ -406,7 +407,7 @@ static void displacement_init_data(SubdivDisplacement *displacement, data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl); data->mesh = mesh; data->mmd = mmd; - data->mpoly = mesh->mpoly; + data->mpoly = BKE_mesh_polygons(mesh); data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); data->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv); data->is_initialized = false; diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 841b47818f1..91b64145396 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -16,6 +16,7 @@ #include "BLI_utildefines.h" #include "BKE_customdata.h" +#include "BKE_mesh.h" #include "BKE_subdiv.h" #include "MEM_guardedalloc.h" @@ -80,9 +81,9 @@ static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh, const float (*coarse_vertex_cos)[3]) { - const MVert *mvert = mesh->mvert; - const MLoop *mloop = mesh->mloop; - const MPoly *mpoly = mesh->mpoly; + const MVert *mvert = BKE_mesh_vertices(mesh); + const MPoly *mpoly = BKE_mesh_polygons(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); /* Mark vertices which needs new coordinates. */ /* TODO(sergey): This is annoying to calculate this on every update, * maybe it's better to cache this mapping. Or make it possible to have @@ -125,6 +126,7 @@ static void set_coarse_positions(Subdiv *subdiv, typedef struct FaceVaryingDataFromUVContext { OpenSubdiv_TopologyRefiner *topology_refiner; const Mesh *mesh; + const MPoly *polys; const MLoopUV *mloopuv; float (*buffer)[2]; int layer_index; @@ -137,8 +139,7 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata, FaceVaryingDataFromUVContext *ctx = userdata; OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner; const int layer_index = ctx->layer_index; - const Mesh *mesh = ctx->mesh; - const MPoly *mpoly = &mesh->mpoly[face_index]; + const MPoly *mpoly = &ctx->polys[face_index]; const MLoopUV *mluv = &ctx->mloopuv[mpoly->loopstart]; /* TODO(sergey): OpenSubdiv's C-API converter can change winding of @@ -171,6 +172,7 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, ctx.layer_index = layer_index; ctx.mloopuv = mluv; ctx.mesh = mesh; + ctx.polys = BKE_mesh_polygons(mesh); ctx.buffer = buffer; TaskParallelSettings parallel_range_settings; diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c index 80364561d01..ac402ceaca0 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.c +++ b/source/blender/blenkernel/intern/subdiv_foreach.c @@ -158,8 +158,8 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx) const int num_inner_vertices_per_noquad_patch = (no_quad_patch_resolution - 2) * (no_quad_patch_resolution - 2); const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); ctx->num_subdiv_vertices = coarse_mesh->totvert; ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1); /* Calculate extra vertices and edges created by non-loose geometry. */ @@ -225,7 +225,7 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx) ctx->edge_inner_offset = ctx->edge_boundary_offset + coarse_mesh->totedge * num_subdiv_edges_per_coarse_edge; /* "Indexed" offsets. */ - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); int vertex_offset = 0; int edge_offset = 0; int polygon_offset = 0; @@ -301,8 +301,9 @@ static void subdiv_foreach_corner_vertices_regular_do( { const float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}}; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; @@ -342,8 +343,9 @@ static void subdiv_foreach_corner_vertices_special_do( bool check_usage) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; @@ -407,7 +409,7 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx, return; } const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (coarse_poly->totloop == 4) { @@ -432,11 +434,11 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct const float inv_resolution_1 = 1.0f / (float)resolution_1; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; - const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = ctx->face_ptex_offset[poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner]; @@ -499,11 +501,11 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1); const float inv_ptex_resolution_1 = 1.0f / (float)(num_vertices_per_ptex_edge - 1); const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; - const int poly_index = coarse_poly - coarse_mesh->mpoly; + const int poly_index = coarse_poly - coarse_mpoly; const int ptex_face_start_index = ctx->face_ptex_offset[poly_index]; int ptex_face_index = ptex_face_start_index; for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) { @@ -595,7 +597,7 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo return; } const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (coarse_poly->totloop == 4) { @@ -616,7 +618,8 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx, const int resolution = ctx->settings->resolution; const float inv_resolution_1 = 1.0f / (float)(resolution - 1); const Mesh *coarse_mesh = ctx->coarse_mesh; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index]; int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index; @@ -644,7 +647,8 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx, const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); const float inv_ptex_face_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1); const Mesh *coarse_mesh = ctx->coarse_mesh; - const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const int coarse_poly_index = coarse_poly - coarse_mpoly; int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index]; int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index; @@ -691,7 +695,7 @@ static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx, static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx, void *tls, const int poly_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (ctx->foreach_context->vertex_inner != NULL) { subdiv_foreach_inner_vertices(ctx, tls, coarse_poly); @@ -775,9 +779,9 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int poly_index = coarse_poly - coarse_mpoly; const int resolution = ctx->settings->resolution; const int start_vertex_index = ctx->vertices_inner_offset + @@ -856,9 +860,9 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int poly_index = coarse_poly - coarse_mpoly; const int resolution = ctx->settings->resolution; const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); @@ -984,7 +988,7 @@ static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx, static void subdiv_foreach_edges(SubdivForeachTaskContext *ctx, void *tls, int poly_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; subdiv_foreach_edges_all_patches(ctx, tls, coarse_poly); } @@ -994,7 +998,7 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx, int coarse_edge_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); const MEdge *coarse_edge = &coarse_medge[coarse_edge_index]; const int resolution = ctx->settings->resolution; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; @@ -1125,9 +1129,9 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx, const int resolution = ctx->settings->resolution; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution); const int ptex_inner_resolution = ptex_resolution - 2; @@ -1319,9 +1323,9 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, const int resolution = ctx->settings->resolution; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; - const MLoop *coarse_mloop = coarse_mesh->mloop; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh); + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); const int coarse_poly_index = coarse_poly - coarse_mpoly; const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); const int ptex_face_inner_resolution = ptex_face_resolution - 2; @@ -1654,7 +1658,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, static void subdiv_foreach_loops(SubdivForeachTaskContext *ctx, void *tls, int poly_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; if (coarse_poly->totloop == 4) { subdiv_foreach_loops_regular(ctx, tls, coarse_poly); @@ -1676,7 +1680,7 @@ static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int p const int start_poly_index = ctx->subdiv_polygon_offset[poly_index]; /* Base/coarse mesh information. */ const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); const MPoly *coarse_poly = &coarse_mpoly[poly_index]; const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly); const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution); @@ -1731,7 +1735,8 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat const float inv_resolution_1 = 1.0f / (float)resolution_1; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index]; + const MEdge *coarse_edges = BKE_mesh_edges(coarse_mesh); + const MEdge *coarse_edge = &coarse_edges[coarse_edge_index]; /* Subdivision vertices which corresponds to edge's v1 and v2. */ const int subdiv_v1_index = ctx->vertices_corner_offset + coarse_edge->v1; const int subdiv_v2_index = ctx->vertices_corner_offset + coarse_edge->v2; @@ -1768,7 +1773,7 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct return; } const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; subdiv_foreach_corner_vertices(ctx, tls, coarse_poly); @@ -1779,8 +1784,8 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MLoop *coarse_mloop = coarse_mesh->mloop; + const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh); + const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh); for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) { const MPoly *coarse_poly = &coarse_mpoly[poly_index]; for (int corner = 0; corner < coarse_poly->totloop; corner++) { diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index da22ee6fd47..c222fc46800 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -32,8 +32,18 @@ struct SubdivMeshContext { const SubdivToMeshSettings *settings; const Mesh *coarse_mesh; + const MVert *coarse_verts; + const MEdge *coarse_edges; + const MPoly *coarse_polys; + const MLoop *coarse_loops; + Subdiv *subdiv; Mesh *subdiv_mesh; + MVert *subdiv_verts; + MEdge *subdiv_edges; + MPoly *subdiv_polys; + MLoop *subdiv_loops; + /* Cached custom data arrays for faster access. */ int *vert_origindex; int *edge_origindex; @@ -63,6 +73,10 @@ static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx) static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) { Mesh *subdiv_mesh = ctx->subdiv_mesh; + ctx->subdiv_verts = BKE_mesh_vertices_for_write(subdiv_mesh); + ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh); + ctx->subdiv_polys = BKE_mesh_polygons_for_write(subdiv_mesh); + ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh); /* Pointers to original indices layers. */ ctx->vert_origindex = static_cast<int *>( CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX)); @@ -115,7 +129,7 @@ static void loops_of_ptex_get(const SubdivMeshContext *ctx, const MPoly *coarse_poly, const int ptex_of_poly_index) { - const MLoop *coarse_mloop = ctx->coarse_mesh->mloop; + const MLoop *coarse_mloop = ctx->coarse_loops; const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index; /* Loop which look in the (opposite) V direction of the current * ptex face. @@ -171,7 +185,7 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx, const MPoly *coarse_poly) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; + const MLoop *coarse_mloop = ctx->coarse_loops; if (coarse_poly->totloop == 4) { vertex_interpolation->vertex_data = &coarse_mesh->vdata; vertex_interpolation->vertex_indices[0] = coarse_mloop[coarse_poly->loopstart + 0].v; @@ -223,8 +237,7 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx, } else { const CustomData *vertex_data = &ctx->coarse_mesh->vdata; - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; + const MLoop *coarse_mloop = ctx->coarse_loops; LoopsOfPtex loops_of_ptex; loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner); /* Ptex face corner corresponds to a poly loop with same index. */ @@ -358,8 +371,7 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx, } else { const CustomData *loop_data = &ctx->coarse_mesh->ldata; - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MLoop *coarse_mloop = coarse_mesh->mloop; + const MLoop *coarse_mloop = ctx->coarse_loops; LoopsOfPtex loops_of_ptex; loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner); /* Ptex face corner corresponds to a poly loop with same index. */ @@ -466,7 +478,7 @@ static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx, { /* Accumulate displacement. */ Subdiv *subdiv = ctx->subdiv; - const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert; + const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts; float dummy_P[3], dPdu[3], dPdv[3], D[3]; BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv); @@ -520,9 +532,8 @@ static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx, MVert *subdiv_vertex) { const Mesh *coarse_mesh = ctx->coarse_mesh; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert; - const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert; + const int coarse_vertex_index = coarse_vertex - ctx->coarse_verts; + const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts; CustomData_copy_data( &coarse_mesh->vdata, &ctx->subdiv_mesh->vdata, coarse_vertex_index, subdiv_vertex_index, 1); } @@ -533,7 +544,7 @@ static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx, const float u, const float v) { - const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert; + const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts; const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v}; CustomData_interp(vertex_interpolation->vertex_data, &ctx->subdiv_mesh->vdata, @@ -554,7 +565,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext const MVert *coarse_vert, MVert *subdiv_vert) { - const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert; + const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts; /* Displacement is accumulated in subdiv vertex position. * Needs to be backed up before copying data from original vertex. */ float D[3] = {0.0f, 0.0f, 0.0f}; @@ -582,7 +593,7 @@ static void evaluate_vertex_and_apply_displacement_interpolate( VerticesForInterpolation *vertex_interpolation, MVert *subdiv_vert) { - const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert; + const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts; /* Displacement is accumulated in subdiv vertex position. * Needs to be backed up before copying data from original vertex. */ float D[3] = {0.0f, 0.0f, 0.0f}; @@ -609,9 +620,7 @@ static void subdiv_mesh_vertex_displacement_every_corner_or_edge( const int subdiv_vertex_index) { SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_mvert = subdiv_mesh->mvert; - MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index]; + MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert); } @@ -656,12 +665,8 @@ static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_contex { BLI_assert(coarse_vertex_index != ORIGINDEX_NONE); SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MVert *coarse_mvert = coarse_mesh->mvert; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_mvert = subdiv_mesh->mvert; - const MVert *coarse_vert = &coarse_mvert[coarse_vertex_index]; - MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index]; + const MVert *coarse_vert = &ctx->coarse_verts[coarse_vertex_index]; + MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; evaluate_vertex_and_apply_displacement_copy( ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert); } @@ -706,12 +711,8 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context, { SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v); - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index]; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_mvert = subdiv_mesh->mvert; - MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index]; + const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index]; + MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner); evaluate_vertex_and_apply_displacement_interpolate( ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vert); @@ -755,12 +756,9 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v); Subdiv *subdiv = ctx->subdiv; - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index]; + const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index]; Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_mvert = subdiv_mesh->mvert; - MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index]; + MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner); subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v); BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co); @@ -778,7 +776,7 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx, MEdge *subdiv_edge, const MEdge *coarse_edge) { - const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge; + const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges; if (coarse_edge == nullptr) { subdiv_edge->crease = 0; subdiv_edge->bweight = 0; @@ -791,7 +789,7 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx, } return; } - const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge; + const int coarse_edge_index = coarse_edge - ctx->coarse_edges; CustomData_copy_data( &ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1); subdiv_edge->flag |= ME_EDGERENDER; @@ -806,13 +804,11 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context, const int subdiv_v2) { SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MEdge *subdiv_medge = subdiv_mesh->medge; + MEdge *subdiv_medge = ctx->subdiv_edges; MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index]; const MEdge *coarse_edge = nullptr; if (coarse_edge_index != ORIGINDEX_NONE) { - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_medge = coarse_mesh->medge; + const MEdge *coarse_medge = ctx->coarse_edges; coarse_edge = &coarse_medge[coarse_edge_index]; } subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge); @@ -832,7 +828,7 @@ static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx, const float u, const float v) { - const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop; + const int subdiv_loop_index = subdiv_loop - ctx->subdiv_loops; const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v}; CustomData_interp(loop_interpolation->loop_data, &ctx->subdiv_mesh->ldata, @@ -854,7 +850,7 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, return; } Subdiv *subdiv = ctx->subdiv; - const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop; + const int mloop_index = subdiv_loop - ctx->subdiv_loops; for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index]; BKE_subdiv_eval_face_varying(subdiv, layer_index, ptex_face_index, u, v, subdiv_loopuv->uv); @@ -903,12 +899,9 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context, { SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v); - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; + const MPoly *coarse_mpoly = ctx->coarse_polys; const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index]; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MLoop *subdiv_mloop = subdiv_mesh->mloop; - MLoop *subdiv_loop = &subdiv_mloop[subdiv_loop_index]; + MLoop *subdiv_loop = &ctx->subdiv_loops[subdiv_loop_index]; subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly, coarse_corner); subdiv_interpolate_loop_data(ctx, subdiv_loop, &tls->loop_interpolation, u, v); subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v); @@ -926,8 +919,8 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx, MPoly *subdiv_poly, const MPoly *coarse_poly) { - const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly; - const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly; + const int coarse_poly_index = coarse_poly - ctx->coarse_polys; + const int subdiv_poly_index = subdiv_poly - ctx->subdiv_polys; CustomData_copy_data( &ctx->coarse_mesh->pdata, &ctx->subdiv_mesh->pdata, coarse_poly_index, subdiv_poly_index, 1); } @@ -941,12 +934,8 @@ static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context, { BLI_assert(coarse_poly_index != ORIGINDEX_NONE); SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MPoly *coarse_mpoly = coarse_mesh->mpoly; - const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index]; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MPoly *subdiv_mpoly = subdiv_mesh->mpoly; - MPoly *subdiv_poly = &subdiv_mpoly[subdiv_poly_index]; + const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index]; + MPoly *subdiv_poly = &ctx->subdiv_polys[subdiv_poly_index]; subdiv_copy_poly_data(ctx, subdiv_poly, coarse_poly); subdiv_poly->loopstart = start_loop_index; subdiv_poly->totloop = num_loops; @@ -964,12 +953,8 @@ static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context const int subdiv_vertex_index) { SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); - const Mesh *coarse_mesh = ctx->coarse_mesh; - const MVert *coarse_mvert = coarse_mesh->mvert; - const MVert *coarse_vertex = &coarse_mvert[coarse_vertex_index]; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_mvert = subdiv_mesh->mvert; - MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index]; + const MVert *coarse_vertex = &ctx->coarse_verts[coarse_vertex_index]; + MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index]; subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex); } @@ -980,12 +965,12 @@ static void find_edge_neighbors(const Mesh *coarse_mesh, const MEdge *edge, const MEdge *neighbors[2]) { - const MEdge *coarse_medge = coarse_mesh->medge; + const blender::Span<MEdge> coarse_edges = coarse_mesh->edges(); neighbors[0] = nullptr; neighbors[1] = nullptr; int neighbor_counters[2] = {0, 0}; for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) { - const MEdge *current_edge = &coarse_medge[edge_index]; + const MEdge *current_edge = &coarse_edges[edge_index]; if (current_edge == edge) { continue; } @@ -1014,7 +999,7 @@ static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh, const MEdge *neighbors[2], float points_r[4][3]) { - const MVert *coarse_mvert = coarse_mesh->mvert; + const MVert *coarse_mvert = BKE_mesh_vertices(coarse_mesh); /* Middle points corresponds to the edge. */ copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co); copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co); @@ -1053,7 +1038,7 @@ void BKE_subdiv_mesh_interpolate_position_on_edge(const Mesh *coarse_mesh, float pos_r[3]) { if (is_simple) { - const MVert *coarse_mvert = coarse_mesh->mvert; + const MVert *coarse_mvert = BKE_mesh_vertices(coarse_mesh); const MVert *vert_1 = &coarse_mvert[coarse_edge->v1]; const MVert *vert_2 = &coarse_mvert[coarse_edge->v2]; interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u); @@ -1103,9 +1088,7 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach { SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data); const Mesh *coarse_mesh = ctx->coarse_mesh; - const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index]; - Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_mvert = subdiv_mesh->mvert; + const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; const bool is_simple = ctx->subdiv->settings.is_simple; /* Interpolate custom data when not an end point. * This data has already been copied from the original vertex by #subdiv_mesh_vertex_loose. */ @@ -1113,7 +1096,7 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach subdiv_mesh_vertex_of_loose_edge_interpolate(ctx, coarse_edge, u, subdiv_vertex_index); } /* Interpolate coordinate. */ - MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index]; + MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index]; BKE_subdiv_mesh_interpolate_position_on_edge( coarse_mesh, coarse_edge, is_simple, u, subdiv_vertex->co); /* Reset flags and such. */ @@ -1179,7 +1162,13 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, /* Initialize subdivision mesh creation context. */ SubdivMeshContext subdiv_context = {0}; subdiv_context.settings = settings; + subdiv_context.coarse_mesh = coarse_mesh; + subdiv_context.coarse_verts = BKE_mesh_vertices(coarse_mesh); + subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh); + subdiv_context.coarse_polys = BKE_mesh_polygons(coarse_mesh); + subdiv_context.coarse_loops = BKE_mesh_loops(coarse_mesh); + subdiv_context.subdiv = subdiv; subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr); /* Multi-threaded traversal/evaluation. */ diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index ef75d3d2482..2005959d360 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -178,9 +178,9 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid, 0, 0, 0, - {mesh->mvert, mesh->totvert}, - {mesh->mpoly, mesh->totpoly}, - {mesh->mloop, mesh->totloop}); + mesh->vertices_for_write(), + mesh->polygons_for_write(), + mesh->loops_for_write()); BKE_mesh_calc_edges(mesh, false, false); diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index cfdae2620d0..bc856fd7a10 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -54,6 +54,7 @@ #include "BKE_global.h" /* for G */ #include "BKE_lib_id.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_multires.h" #include "BKE_node_tree_update.h" @@ -995,9 +996,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) { data = key->refkey->data; tot = MIN2(me->totvert, key->refkey->totelem); - + MVert *vertices = BKE_mesh_vertices_for_write(me); for (a = 0; a < tot; a++, data += 3) { - copy_v3_v3(me->mvert[a].co, data); + copy_v3_v3(vertices[a].co, data); } } } diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index c1ea96aaedc..e4dc8d006ae 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1794,10 +1794,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (DNA_struct_find(fd->filesdna, "MTexPoly")) { for (Mesh *me = bmain->meshes.first; me; me = me->id.next) { /* If we have UV's, so this file will have MTexPoly layers too! */ - if (me->mloopuv != NULL) { + if (CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { CustomData_update_typemap(&me->pdata); CustomData_free_layers(&me->pdata, CD_MTEXPOLY, me->totpoly); - BKE_mesh_update_customdata_pointers(me, false); } } } diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index c79eb2d530b..ab07c6cc6b8 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -819,21 +819,22 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (MAIN_VERSION_ATLEAST(bmain, 290, 2) && MAIN_VERSION_OLDER(bmain, 291, 1)) { /* In this range, the extrude manifold could generate meshes with degenerated face. */ LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) { - for (MPoly *mp = me->mpoly, *mp_end = mp + me->totpoly; mp < mp_end; mp++) { + for (const MPoly *mp = BKE_mesh_polygons(me), *mp_end = mp + me->totpoly; mp < mp_end; + mp++) { if (mp->totloop == 2) { bool changed; BKE_mesh_validate_arrays(me, - me->mvert, + BKE_mesh_vertices_for_write(me), me->totvert, - me->medge, + BKE_mesh_edges_for_write(me), me->totedge, - me->mface, + (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), me->totface, - me->mloop, + BKE_mesh_loops_for_write(me), me->totloop, - me->mpoly, + BKE_mesh_polygons_for_write(me), me->totpoly, - me->dvert, + BKE_mesh_deform_verts_for_write(me), false, true, &changed); diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index 113fc244086..06903865381 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -345,7 +345,8 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) /* Correct default startup UV's. */ Mesh *me = BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2); - if (me && (me->totloop == 24) && (me->mloopuv != NULL)) { + if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { + MLoopUV *mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV); const float uv_values[24][2] = { {0.625, 0.50}, {0.875, 0.50}, {0.875, 0.75}, {0.625, 0.75}, {0.375, 0.75}, {0.625, 0.75}, {0.625, 1.00}, {0.375, 1.00}, {0.375, 0.00}, {0.625, 0.00}, {0.625, 0.25}, {0.375, 0.25}, @@ -353,7 +354,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) {0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50}, }; for (int i = 0; i < ARRAY_SIZE(uv_values); i++) { - copy_v2_v2(me->mloopuv[i].uv, uv_values[i]); + copy_v2_v2(mloopuv[i].uv, uv_values[i]); } } diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 20659daabd6..94438acf4fa 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -342,8 +342,6 @@ static void customdata_version_242(Mesh *me) mcoln++; } } - - BKE_mesh_update_customdata_pointers(me, true); } /* Only copy render texface layer from active. */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index cd5e6f117ae..0190f91250b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -366,7 +366,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); - Span<MVert> mvert{me->mvert, me->totvert}; + Span<MVert> mvert = me->vertices(); Array<BMVert *> vtable(me->totvert); for (const int i : mvert.index_range()) { BMVert *v = vtable[i] = BM_vert_create( @@ -412,7 +412,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar bm->elem_index_dirty &= ~BM_VERT; /* Added in order, clear dirty flag. */ } - Span<MEdge> medge{me->medge, me->totedge}; + const Span<MEdge> medge = me->edges(); Array<BMEdge *> etable(me->totedge); for (const int i : medge.index_range()) { BMEdge *e = etable[i] = BM_edge_create( @@ -444,8 +444,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */ } - Span<MPoly> mpoly{me->mpoly, me->totpoly}; - Span<MLoop> mloop{me->mloop, me->totloop}; + const Span<MPoly> mpoly = me->polygons(); + const Span<MLoop> mloop = me->loops(); /* Only needed for selection. */ @@ -1049,9 +1049,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm); - /* This is called again, 'dotess' arg is used there. */ - BKE_mesh_update_customdata_pointers(me, false); - i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { copy_v3_v3(mvert->co, v->co); @@ -1226,8 +1223,6 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh convert_bmesh_hide_flags_to_mesh_attributes( *bm, need_hide_vert, need_hide_edge, need_hide_poly, *me); - BKE_mesh_update_customdata_pointers(me, false); - { me->totselect = BLI_listbase_count(&(bm->selected)); @@ -1253,7 +1248,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh } if (me->key) { - bm_to_mesh_shape(bm, me->key, me->mvert, params->active_shapekey_to_mvert); + bm_to_mesh_shape(bm, me->key, mvert, params->active_shapekey_to_mvert); } /* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */ @@ -1303,16 +1298,15 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); - BKE_mesh_update_customdata_pointers(me, false); - BMIter iter; BMVert *eve; BMEdge *eed; BMFace *efa; - MVert *mvert = me->mvert; - MEdge *medge = me->medge; - MLoop *mloop = me->mloop; - MPoly *mpoly = me->mpoly; + MutableSpan<MVert> mvert = me->vertices_for_write(); + MutableSpan<MEdge> medge = me->edges_for_write(); + MutableSpan<MPoly> mpoly = me->polygons_for_write(); + MutableSpan<MLoop> loops = me->loops_for_write(); + MLoop *mloop = loops.data(); unsigned int i, j; const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); 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 e07fe81840e..fe73f4cfc12 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 @@ -339,9 +339,9 @@ void mesh_render_data_update_looptris(MeshRenderData *mr, mr->mlooptri = static_cast<MLoopTri *>( MEM_mallocN(sizeof(*mr->mlooptri) * mr->tri_len, "MR_DATATYPE_LOOPTRI")); if (mr->poly_normals != nullptr) { - BKE_mesh_recalc_looptri_with_normals(me->mloop, - me->mpoly, - me->mvert, + BKE_mesh_recalc_looptri_with_normals(mr->mloop, + mr->mpoly, + mr->mvert, me->totloop, me->totpoly, mr->mlooptri, @@ -349,7 +349,7 @@ void mesh_render_data_update_looptris(MeshRenderData *mr, } else { BKE_mesh_recalc_looptri( - me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mr->mlooptri); + mr->mloop, mr->mpoly, mr->mvert, me->totloop, me->totpoly, mr->mlooptri); } } } @@ -379,15 +379,15 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__)); short(*clnors)[2] = static_cast<short(*)[2]>( CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL)); - BKE_mesh_normals_loop_split(mr->me->mvert, + BKE_mesh_normals_loop_split(mr->mvert, mr->vert_normals, mr->vert_len, - mr->me->medge, + mr->medge, mr->edge_len, - mr->me->mloop, + mr->mloop, mr->loop_normals, mr->loop_len, - mr->me->mpoly, + mr->mpoly, mr->poly_normals, mr->poly_len, is_auto_smooth, @@ -568,10 +568,10 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->poly_len = mr->me->totpoly; mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len); - mr->mvert = static_cast<MVert *>(CustomData_get_layer(&mr->me->vdata, CD_MVERT)); - mr->medge = static_cast<MEdge *>(CustomData_get_layer(&mr->me->edata, CD_MEDGE)); - mr->mloop = static_cast<MLoop *>(CustomData_get_layer(&mr->me->ldata, CD_MLOOP)); - mr->mpoly = static_cast<MPoly *>(CustomData_get_layer(&mr->me->pdata, CD_MPOLY)); + mr->mvert = BKE_mesh_vertices(mr->me); + mr->medge = BKE_mesh_edges(mr->me); + mr->mpoly = BKE_mesh_polygons(mr->me); + mr->mloop = BKE_mesh_loops(mr->me); mr->v_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX)); mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX)); diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 4fdc46ea18b..9c1784b1de2 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -315,7 +315,8 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, } } if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + MFace *mface = &mfaces[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -344,7 +345,8 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, } } if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + MFace *mface = &mfaces[num]; for (int j = 0; j < num_col_layers; j++) { /* CustomDataLayer CD_MCOL has 4 structs per face. */ psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); @@ -370,7 +372,8 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys, ChildParticle *particle = &psys->child[child_index]; int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + MFace *mface = &mfaces[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -394,7 +397,8 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys, ChildParticle *particle = &psys->child[child_index]; int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + MFace *mface = &mfaces[num]; for (int j = 0; j < num_col_layers; j++) { /* CustomDataLayer CD_MCOL has 4 structs per face. */ psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index e02bf57815d..9882ebf66f0 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -45,6 +45,8 @@ #include "draw_cache_inline.h" #include "mesh_extractors/extract_mesh.hh" +using blender::Span; + extern "C" char datatoc_common_subdiv_custom_data_interp_comp_glsl[]; extern "C" char datatoc_common_subdiv_ibo_lines_comp_glsl[]; extern "C" char datatoc_common_subdiv_ibo_tris_comp_glsl[]; @@ -673,18 +675,19 @@ static void draw_subdiv_cache_extra_coarse_face_data_mesh(const MeshRenderData * Mesh *mesh, uint32_t *flags_data) { - for (int i = 0; i < mesh->totpoly; i++) { + const Span<MPoly> polys = mesh->polygons(); + for (const int i : polys.index_range()) { uint32_t flag = 0; - if ((mesh->mpoly[i].flag & ME_SMOOTH) != 0) { + if ((polys[i].flag & ME_SMOOTH) != 0) { flag |= SUBDIV_COARSE_FACE_FLAG_SMOOTH; } - if ((mesh->mpoly[i].flag & ME_FACE_SEL) != 0) { + if ((polys[i].flag & ME_FACE_SEL) != 0) { flag |= SUBDIV_COARSE_FACE_FLAG_SELECT; } if (mr->hide_poly && mr->hide_poly[i]) { flag |= SUBDIV_COARSE_FACE_FLAG_HIDDEN; } - flags_data[i] = (uint)(mesh->mpoly[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET); + flags_data[i] = (uint)(polys[i].loopstart) | (flag << SUBDIV_COARSE_FACE_FLAG_OFFSET); } } @@ -1092,6 +1095,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, } /* Only build polygon related data if we have polygons. */ + const Span<MPoly> polys = mesh_eval->polygons(); if (cache->num_subdiv_loops != 0) { /* Build buffers for the PatchMap. */ draw_patch_map_build(&cache->gpu_patch_map, subdiv); @@ -1105,7 +1109,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, GPU_vertbuf_get_data(cache->fdots_patch_coords); for (int i = 0; i < mesh_eval->totpoly; i++) { const int ptex_face_index = cache->face_ptex_offset[i]; - if (mesh_eval->mpoly[i].totloop == 4) { + if (polys[i].totloop == 4) { /* For quads, the center coordinate of the coarse face has `u = v = 0.5`. */ blender_fdots_patch_coords[i] = make_patch_coord(ptex_face_index, 0.5f, 0.5f); } @@ -1118,16 +1122,16 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, } cache->subdiv_polygon_offset_buffer = draw_subdiv_build_origindex_buffer( - cache->subdiv_polygon_offset, mesh_eval->totpoly); + cache->subdiv_polygon_offset, polys.size()); cache->face_ptex_offset_buffer = draw_subdiv_build_origindex_buffer(cache->face_ptex_offset, - mesh_eval->totpoly + 1); + polys.size() + 1); build_vertex_face_adjacency_maps(cache); } cache->resolution = to_mesh_settings.resolution; - cache->num_coarse_poly = mesh_eval->totpoly; + cache->num_coarse_poly = polys.size(); /* To avoid floating point precision issues when evaluating patches at patch boundaries, * ensure that all loops sharing a vertex use the same patch coordinate. This could cause @@ -2152,9 +2156,10 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac int subd_vert_offset = 0; /* Subdivide each loose coarse edge. */ + const Span<MEdge> coarse_edges = coarse_mesh->edges(); for (int i = 0; i < coarse_loose_edge_len; i++) { const int coarse_edge_index = cache->loose_geom.edges[i]; - const MEdge *coarse_edge = &coarse_mesh->medge[cache->loose_geom.edges[i]]; + const MEdge *coarse_edge = &coarse_edges[cache->loose_geom.edges[i]]; /* Perform interpolation of each vertex. */ for (int i = 0; i < resolution - 1; i++, subd_edge_offset++) { @@ -2182,9 +2187,10 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac } /* Copy the remaining loose_verts. */ + const Span<MVert> coarse_verts = coarse_mesh->vertices(); for (int i = 0; i < coarse_loose_vert_len; i++) { const int coarse_vertex_index = cache->loose_geom.verts[i]; - const MVert &coarse_vertex = coarse_mesh->mvert[coarse_vertex_index]; + const MVert &coarse_vertex = coarse_verts[coarse_vertex_index]; DRWSubdivLooseVertex &subd_v = loose_subd_verts[subd_vert_offset++]; subd_v.coarse_vertex_index = cache->loose_geom.verts[i]; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc index 951990466d0..fe2a02b6b63 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc @@ -259,7 +259,8 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) } struct BVHTree_OverlapData { - const Mesh *me; + const MVert *verts; + const MLoop *loops; const MLoopTri *mlooptri; float epsilon; }; @@ -267,7 +268,6 @@ struct BVHTree_OverlapData { static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { struct BVHTree_OverlapData *data = static_cast<struct BVHTree_OverlapData *>(userdata); - const Mesh *me = data->me; const MLoopTri *tri_a = &data->mlooptri[index_a]; const MLoopTri *tri_b = &data->mlooptri[index_b]; @@ -276,12 +276,12 @@ static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED( return false; } - const float *tri_a_co[3] = {me->mvert[me->mloop[tri_a->tri[0]].v].co, - me->mvert[me->mloop[tri_a->tri[1]].v].co, - me->mvert[me->mloop[tri_a->tri[2]].v].co}; - const float *tri_b_co[3] = {me->mvert[me->mloop[tri_b->tri[0]].v].co, - me->mvert[me->mloop[tri_b->tri[1]].v].co, - me->mvert[me->mloop[tri_b->tri[2]].v].co}; + const float *tri_a_co[3] = {data->verts[data->loops[tri_a->tri[0]].v].co, + data->verts[data->loops[tri_a->tri[1]].v].co, + data->verts[data->loops[tri_a->tri[2]].v].co}; + const float *tri_b_co[3] = {data->verts[data->loops[tri_b->tri[0]].v].co, + data->verts[data->loops[tri_b->tri[1]].v].co, + data->verts[data->loops[tri_b->tri[2]].v].co}; float ix_pair[2][3]; int verts_shared = 0; @@ -342,7 +342,8 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) BVHTree *tree = BKE_bvhtree_from_mesh_get(&treeData, mr->me, BVHTREE_FROM_LOOPTRI, 4); struct BVHTree_OverlapData data = {nullptr}; - data.me = mr->me; + data.verts = mr->mvert; + data.loops = mr->mloop; data.mlooptri = mr->mlooptri; data.epsilon = BLI_bvhtree_get_epsilon(tree); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc index 492721b4853..4e3d4235487 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_sculpt_data.cc @@ -9,6 +9,7 @@ #include "BLI_string.h" +#include "BKE_mesh.h" #include "BKE_paint.h" #include "draw_subdivision.h" @@ -128,6 +129,9 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache, GPUVertBuf *subdiv_mask_vbo = nullptr; const float *cd_mask = (const float *)CustomData_get_layer(cd_vdata, CD_PAINT_MASK); + const Span<MPoly> coarse_polys = coarse_mesh->polygons(); + const Span<MLoop> coarse_loops = coarse_mesh->loops(); + if (cd_mask) { GPUVertFormat mask_format = {0}; GPU_vertformat_attr_add(&mask_format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); @@ -138,11 +142,11 @@ static void extract_sculpt_data_init_subdiv(const DRWSubdivCache *subdiv_cache, float *v_mask = static_cast<float *>(GPU_vertbuf_get_data(mask_vbo)); for (int i = 0; i < coarse_mesh->totpoly; i++) { - const MPoly *mpoly = &coarse_mesh->mpoly[i]; + const MPoly *mpoly = &coarse_polys[i]; for (int loop_index = mpoly->loopstart; loop_index < mpoly->loopstart + mpoly->totloop; loop_index++) { - const MLoop *ml = &coarse_mesh->mloop[loop_index]; + const MLoop *ml = &coarse_loops[loop_index]; *v_mask++ = cd_mask[ml->v]; } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc index ba194a4b167..8fe4940c6de 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_weights.cc @@ -8,6 +8,7 @@ #include "MEM_guardedalloc.h" #include "BKE_deform.h" +#include "BKE_mesh.h" #include "draw_subdivision.h" #include "extract_mesh.hh" @@ -105,7 +106,7 @@ static void extract_weights_init(const MeshRenderData *mr, data->cd_ofs = CustomData_get_offset(&mr->bm->vdata, CD_MDEFORMVERT); } else { - data->dvert = (const MDeformVert *)CustomData_get_layer(&mr->me->vdata, CD_MDEFORMVERT); + data->dvert = mr->me->deform_verts().data(); data->cd_ofs = -1; } } @@ -171,8 +172,9 @@ static void extract_weights_init_subdiv(const DRWSubdivCache *subdiv_cache, extract_weights_init(mr, cache, coarse_weights, _data); if (mr->extract_type != MR_EXTRACT_BMESH) { - for (int i = 0; i < coarse_mesh->totpoly; i++) { - const MPoly *mpoly = &coarse_mesh->mpoly[i]; + const Span<MPoly> coarse_polys = coarse_mesh->polygons(); + for (const int i : coarse_polys.index_range()) { + const MPoly *mpoly = &coarse_polys[i]; extract_weights_iter_poly_mesh(mr, mpoly, i, _data); } } diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 3a1e7419d3c..2cd4b53f7f4 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -21,6 +21,7 @@ #include "BKE_action.h" #include "BKE_armature.h" #include "BKE_deform.h" +#include "BKE_mesh.h" #include "BKE_mesh_iterators.h" #include "BKE_mesh_runtime.h" #include "BKE_modifier.h" @@ -203,9 +204,9 @@ static void envelope_bone_weighting(Object *ob, } /* for each vertex in the mesh */ + const MVert *mesh_verts = BKE_mesh_vertices(mesh); for (int i = 0; i < mesh->totvert; i++) { - - if (use_mask && !(mesh->mvert[i].flag & SELECT)) { + if (use_mask && !(mesh_verts[i].flag & SELECT)) { continue; } @@ -405,9 +406,10 @@ static void add_verts_to_dgroups(ReportList *reports, } /* transform verts to global space */ + const MVert *mesh_verts = BKE_mesh_vertices(mesh); for (int i = 0; i < mesh->totvert; i++) { if (!vertsfilled) { - copy_v3_v3(verts[i], mesh->mvert[i].co); + copy_v3_v3(verts[i], mesh_verts[i].co); } mul_m4_v3(ob->obmat, verts[i]); } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 7016511111e..2b3f8f4c853 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -645,14 +645,16 @@ void heat_bone_weighting(Object *ob, { LaplacianSystem *sys; MLoopTri *mlooptri; - MPoly *mp; - MLoop *ml; + const MPoly *mp; + const MLoop *ml; float solution, weight; int *vertsflipped = NULL, *mask = NULL; int a, tris_num, j, bbone, firstsegment, lastsegment; bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; - MVert *mvert = me->mvert; + const MVert *mesh_verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; @@ -667,16 +669,16 @@ void heat_bone_weighting(Object *ob, /* (added selectedVerts content for vertex mask, they used to just equal 1) */ if (use_vert_sel) { - for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) { - for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) { - mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0; + for (a = 0, mp = polys; a < me->totpoly; mp++, a++) { + for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) { + mask[ml->v] = (mesh_verts[ml->v].flag & SELECT) != 0; } } } else if (use_face_sel) { - for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) { + for (a = 0, mp = polys; a < me->totpoly; mp++, a++) { if (mp->flag & ME_FACE_SEL) { - for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) { + for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) { mask[ml->v] = 1; } } @@ -690,10 +692,10 @@ void heat_bone_weighting(Object *ob, sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop); mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri); + BKE_mesh_recalc_looptri(loops, polys, mesh_verts, me->totloop, me->totpoly, mlooptri); sys->heat.mlooptri = mlooptri; - sys->heat.mloop = me->mloop; + sys->heat.mloop = loops; sys->heat.verts_num = me->totvert; sys->heat.verts = verts; sys->heat.root = root; @@ -1606,8 +1608,8 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin /* initialize data from 'cagedm' for reuse */ { Mesh *me = mdb->cagemesh; - mdb->cagemesh_cache.mpoly = me->mpoly; - mdb->cagemesh_cache.mloop = me->mloop; + mdb->cagemesh_cache.mpoly = BKE_mesh_polygons(me); + mdb->cagemesh_cache.mloop = BKE_mesh_loops(me); mdb->cagemesh_cache.looptri = BKE_mesh_runtime_looptri_ensure(me); mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me); } @@ -1743,7 +1745,7 @@ void ED_mesh_deform_bind_callback(Object *object, MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original( object, &mmd->modifier); MeshDeformBind mdb; - MVert *mvert; + const MVert *mvert; int a; waitcursor(1); @@ -1763,7 +1765,7 @@ void ED_mesh_deform_bind_callback(Object *object, mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos"); copy_m4_m4(mdb.cagemat, cagemat); - mvert = mdb.cagemesh->mvert; + mvert = BKE_mesh_vertices(mdb.cagemesh); for (a = 0; a < mdb.cage_verts_num; a++) { copy_v3_v3(mdb.cagecos[a], mvert[a].co); } diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index eec2c5d205d..6582ce6e6d7 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -139,7 +139,8 @@ using bke::CurvesGeometry; namespace convert_to_particle_system { -static int find_mface_for_root_position(const Mesh &mesh, +static int find_mface_for_root_position(const Span<MVert> verts, + const MFace *mface, const Span<int> possible_mface_indices, const float3 &root_pos) { @@ -151,14 +152,14 @@ static int find_mface_for_root_position(const Mesh &mesh, int mface_i; float best_distance_sq = FLT_MAX; for (const int possible_mface_i : possible_mface_indices) { - const MFace &possible_mface = mesh.mface[possible_mface_i]; + const MFace &possible_mface = mface[possible_mface_i]; { float3 point_in_triangle; closest_on_tri_to_point_v3(point_in_triangle, root_pos, - mesh.mvert[possible_mface.v1].co, - mesh.mvert[possible_mface.v2].co, - mesh.mvert[possible_mface.v3].co); + verts[possible_mface.v1].co, + verts[possible_mface.v2].co, + verts[possible_mface.v3].co); const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle); if (distance_sq < best_distance_sq) { best_distance_sq = distance_sq; @@ -170,9 +171,9 @@ static int find_mface_for_root_position(const Mesh &mesh, float3 point_in_triangle; closest_on_tri_to_point_v3(point_in_triangle, root_pos, - mesh.mvert[possible_mface.v1].co, - mesh.mvert[possible_mface.v3].co, - mesh.mvert[possible_mface.v4].co); + verts[possible_mface.v1].co, + verts[possible_mface.v3].co, + verts[possible_mface.v4].co); const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle); if (distance_sq < best_distance_sq) { best_distance_sq = distance_sq; @@ -186,25 +187,22 @@ static int find_mface_for_root_position(const Mesh &mesh, /** * \return Barycentric coordinates in the #MFace. */ -static float4 compute_mface_weights_for_position(const Mesh &mesh, +static float4 compute_mface_weights_for_position(const Span<MVert> verts, const MFace &mface, const float3 &position) { float4 mface_weights; if (mface.v4) { float mface_verts_su[4][3]; - copy_v3_v3(mface_verts_su[0], mesh.mvert[mface.v1].co); - copy_v3_v3(mface_verts_su[1], mesh.mvert[mface.v2].co); - copy_v3_v3(mface_verts_su[2], mesh.mvert[mface.v3].co); - copy_v3_v3(mface_verts_su[3], mesh.mvert[mface.v4].co); + copy_v3_v3(mface_verts_su[0], verts[mface.v1].co); + copy_v3_v3(mface_verts_su[1], verts[mface.v2].co); + copy_v3_v3(mface_verts_su[2], verts[mface.v3].co); + copy_v3_v3(mface_verts_su[3], verts[mface.v4].co); interp_weights_poly_v3(mface_weights, mface_verts_su, 4, position); } else { - interp_weights_tri_v3(mface_weights, - mesh.mvert[mface.v1].co, - mesh.mvert[mface.v2].co, - mesh.mvert[mface.v3].co, - position); + interp_weights_tri_v3( + mface_weights, verts[mface.v1].co, verts[mface.v2].co, verts[mface.v3].co, position); mface_weights[3] = 0.0f; } return mface_weights; @@ -287,6 +285,9 @@ static void try_convert_single_object(Object &curves_ob, /* Prepare transformation matrices. */ const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob}; + const MFace *mfaces = (const MFace *)CustomData_get_layer(&surface_me.fdata, CD_MFACE); + const Span<MVert> verts = surface_me.vertices(); + for (const int new_hair_i : IndexRange(hair_num)) { const int curve_i = new_hair_i; const IndexRange points = curves.points_for_curve(curve_i); @@ -305,11 +306,10 @@ static void try_convert_single_object(Object &curves_ob, const int poly_i = looptri.poly; const int mface_i = find_mface_for_root_position( - surface_me, poly_to_mface_map[poly_i], root_pos_su); - const MFace &mface = surface_me.mface[mface_i]; + verts, mfaces, poly_to_mface_map[poly_i], root_pos_su); + const MFace &mface = mfaces[mface_i]; - const float4 mface_weights = compute_mface_weights_for_position( - surface_me, mface, root_pos_su); + const float4 mface_weights = compute_mface_weights_for_position(verts, mface, root_pos_su); ParticleData &particle = particles[new_hair_i]; const int num_keys = points.size(); @@ -541,8 +541,11 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, Curves &curves_id = *static_cast<Curves *>(curves_ob.data); CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); - Mesh &surface_mesh = *static_cast<Mesh *>(surface_ob.data); - + const Mesh &surface_mesh = *static_cast<const Mesh *>(surface_ob.data); + const Span<MVert> verts = surface_mesh.vertices(); + const Span<MLoop> loops = surface_mesh.loops(); + const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh), + BKE_mesh_runtime_looptri_len(&surface_mesh)}; VArraySpan<float2> surface_uv_map; if (curves_id.surface_uv_map != nullptr) { const bke::AttributeAccessor surface_attributes = bke::mesh_attributes(surface_mesh); @@ -554,9 +557,6 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, MutableSpan<float3> positions_cu = curves.positions_for_write(); MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write(); - const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh), - BKE_mesh_runtime_looptri_len(&surface_mesh)}; - const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob}; switch (attach_mode) { @@ -603,9 +603,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const float2 &uv0 = surface_uv_map[corner0]; const float2 &uv1 = surface_uv_map[corner1]; const float2 &uv2 = surface_uv_map[corner2]; - const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[corner0].v].co; - const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[corner1].v].co; - const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[corner2].v].co; + const float3 &p0_su = verts[loops[corner0].v].co; + const float3 &p1_su = verts[loops[corner1].v].co; + const float3 &p2_su = verts[loops[corner2].v].co; float3 bary_coords; interp_weights_tri_v3(bary_coords, p0_su, p1_su, p2_su, new_first_point_pos_su); const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2); @@ -639,9 +639,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const MLoopTri &looptri = *lookup_result.looptri; const float3 &bary_coords = lookup_result.bary_weights; - const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[0]].v].co; - const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[1]].v].co; - const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[2]].v].co; + const float3 &p0_su = verts[loops[looptri.tri[0]].v].co; + const float3 &p1_su = verts[loops[looptri.tri[1]].v].co; + const float3 &p2_su = verts[loops[looptri.tri[2]].v].co; float3 new_first_point_pos_su; interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords); diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 2dcb7aa438f..eafe13f093d 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -471,11 +471,6 @@ static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (GS(id->name) == ID_ME) { - Mesh *me = static_cast<Mesh *>(ob->data); - BKE_mesh_update_customdata_pointers(me, true); - } - DEG_id_tag_update(id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, id); diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 054c01626f8..6313c01011e 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -44,9 +44,7 @@ void paintface_flush_flags(bContext *C, { using namespace blender; Mesh *me = BKE_mesh_from_object(ob); - MPoly *polys, *mp_orig; const int *index_array = nullptr; - int totpoly; BLI_assert(flush_selection || flush_hidden); @@ -75,11 +73,13 @@ void paintface_flush_flags(bContext *C, Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval; bke::MutableAttributeAccessor attributes_eval = bke::mesh_attributes_for_write(*me_eval); bool updated = false; + const Span<MPoly> me_polys = me->polygons(); if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) { /* Update the COW copy of the mesh. */ + MutableSpan<MPoly> orig_polys = me_orig->polygons_for_write(); for (int i = 0; i < me->totpoly; i++) { - me_orig->mpoly[i].flag = me->mpoly[i].flag; + orig_polys[i].flag = me_polys[i].flag; } if (flush_hidden) { const VArray<bool> hide_poly_me = attributes_me.lookup_or_default<bool>( @@ -92,15 +92,12 @@ void paintface_flush_flags(bContext *C, /* Mesh polys => Final derived polys */ if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) { - polys = me_eval->mpoly; - totpoly = me_eval->totpoly; - + MutableSpan<MPoly> eval_polys = me_orig->polygons_for_write(); /* loop over final derived polys */ - for (int i = 0; i < totpoly; i++) { + for (const int i : eval_polys.index_range()) { if (index_array[i] != ORIGINDEX_NONE) { /* Copy flags onto the final derived poly from the original mesh poly */ - mp_orig = me->mpoly + index_array[i]; - polys[i].flag = mp_orig->flag; + eval_polys[i].flag = me_polys[index_array[i]].flag; } } const VArray<bool> hide_poly_orig = attributes_orig.lookup_or_default<bool>( @@ -144,12 +141,13 @@ void paintface_hide(bContext *C, Object *ob, const bool unselected) return; } + MutableSpan<MPoly> polys = me->polygons_for_write(); bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me); bke::SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_span<bool>( ".hide_poly", ATTR_DOMAIN_FACE); for (int i = 0; i < me->totpoly; i++) { - MPoly *mpoly = &me->mpoly[i]; + MPoly *mpoly = &polys[i]; if (!hide_poly.span[i]) { if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) { hide_poly.span[i] = true; @@ -176,13 +174,14 @@ void paintface_reveal(bContext *C, Object *ob, const bool select) return; } + MutableSpan<MPoly> polys = me->polygons_for_write(); bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me); if (select) { const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( ".hide_poly", ATTR_DOMAIN_FACE, false); for (int i = 0; i < me->totpoly; i++) { - MPoly *mpoly = &me->mpoly[i]; + MPoly *mpoly = &polys[i]; if (hide_poly[i]) { mpoly->flag |= ME_FACE_SEL; } @@ -207,25 +206,28 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__); BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__); + const Span<MEdge> edges = me->edges(); + MutableSpan<MPoly> polys = me->polygons_for_write(); + const Span<MLoop> loops = me->loops(); bke::AttributeAccessor attributes = bke::mesh_attributes(*me); const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( ".hide_poly", ATTR_DOMAIN_FACE, false); if (index != (uint)-1) { /* only put face under cursor in array */ - MPoly *mp = &me->mpoly[index]; - BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart); + const MPoly *mp = &polys[index]; + BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]); BLI_BITMAP_ENABLE(poly_tag, index); } else { /* fill array by selection */ for (int i = 0; i < me->totpoly; i++) { - MPoly *mp = &me->mpoly[i]; + MPoly *mp = &polys[i]; if (hide_poly[i]) { /* pass */ } else if (mp->flag & ME_FACE_SEL) { - BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart); + BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]); BLI_BITMAP_ENABLE(poly_tag, i); } } @@ -236,7 +238,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo /* expand selection */ for (int i = 0; i < me->totpoly; i++) { - MPoly *mp = &me->mpoly[i]; + MPoly *mp = &polys[i]; if (hide_poly[i]) { continue; } @@ -244,9 +246,9 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo if (!BLI_BITMAP_TEST(poly_tag, i)) { mark = false; - MLoop *ml = me->mloop + mp->loopstart; + const MLoop *ml = &loops[mp->loopstart]; for (int b = 0; b < mp->totloop; b++, ml++) { - if ((me->medge[ml->e].flag & ME_SEAM) == 0) { + if ((edges[ml->e].flag & ME_SEAM) == 0) { if (BLI_BITMAP_TEST(edge_tag, ml->e)) { mark = true; break; @@ -256,7 +258,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo if (mark) { BLI_BITMAP_ENABLE(poly_tag, i); - BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart); + BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]); do_it = true; } } @@ -266,7 +268,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo MEM_freeN(edge_tag); for (int i = 0; i < me->totpoly; i++) { - MPoly *mp = &me->mpoly[i]; + MPoly *mp = &polys[index]; if (BLI_BITMAP_TEST(poly_tag, i)) { SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL); } @@ -303,6 +305,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl return false; } + MutableSpan<MPoly> polys = me->polygons_for_write(); bke::AttributeAccessor attributes = bke::mesh_attributes(*me); const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( ".hide_poly", ATTR_DOMAIN_FACE, false); @@ -311,7 +314,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl action = SEL_SELECT; for (int i = 0; i < me->totpoly; i++) { - MPoly *mpoly = &me->mpoly[i]; + MPoly *mpoly = &polys[i]; if (!hide_poly[i] && mpoly->flag & ME_FACE_SEL) { action = SEL_DESELECT; break; @@ -322,7 +325,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl bool changed = false; for (int i = 0; i < me->totpoly; i++) { - MPoly *mpoly = &me->mpoly[i]; + MPoly *mpoly = &polys[i]; if (!hide_poly[i]) { switch (action) { case SEL_SELECT: @@ -360,26 +363,28 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) float vec[3], bmat[3][3]; const Mesh *me = BKE_mesh_from_object(ob); - if (!me || !me->mloopuv) { + if (!me || !CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { return ok; } - const MVert *mvert = me->mvert; copy_m3_m4(bmat, ob->obmat); + const Span<MVert> verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); bke::AttributeAccessor attributes = bke::mesh_attributes(*me); const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( ".hide_poly", ATTR_DOMAIN_FACE, false); for (int i = 0; i < me->totpoly; i++) { - MPoly *mp = &me->mpoly[i]; + const MPoly *mp = &polys[i]; if (hide_poly[i] || !(mp->flag & ME_FACE_SEL)) { continue; } - const MLoop *ml = me->mloop + mp->loopstart; + const MLoop *ml = &loops[mp->loopstart]; for (int b = 0; b < mp->totloop; b++, ml++) { - mul_v3_m3v3(vec, bmat, mvert[ml->v].co); + mul_v3_m3v3(vec, bmat, verts[ml->v].co); add_v3_v3v3(vec, vec, ob->obmat[3]); minmax_v3v3_v3(r_min, r_max, vec); } @@ -404,13 +409,14 @@ bool paintface_mouse_select(bContext *C, /* Get the face under the cursor */ Mesh *me = BKE_mesh_from_object(ob); + MutableSpan<MPoly> polys = me->polygons_for_write(); bke::AttributeAccessor attributes = bke::mesh_attributes(*me); const VArray<bool> hide_poly = attributes.lookup_or_default<bool>( ".hide_poly", ATTR_DOMAIN_FACE, false); if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) { if (index < me->totpoly) { - mpoly_sel = me->mpoly + index; + mpoly_sel = polys.data() + index; if (!hide_poly[index]) { found = true; } @@ -469,12 +475,10 @@ bool paintface_mouse_select(bContext *C, void paintvert_flush_flags(Object *ob) { + using namespace blender; Mesh *me = BKE_mesh_from_object(ob); Mesh *me_eval = BKE_object_get_evaluated_mesh(ob); - MVert *mvert_eval, *mv; const int *index_array = nullptr; - int totvert; - int i; if (me == nullptr) { return; @@ -490,23 +494,21 @@ void paintvert_flush_flags(Object *ob) index_array = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX); - mvert_eval = me_eval->mvert; - totvert = me_eval->totvert; - - mv = mvert_eval; + const Span<MVert> vertices = me->vertices_for_write(); + MutableSpan<MVert> vertices_eval = me_eval->vertices_for_write(); if (index_array) { int orig_index; - for (i = 0; i < totvert; i++, mv++) { + for (const int i : vertices_eval.index_range()) { orig_index = index_array[i]; if (orig_index != ORIGINDEX_NONE) { - mv->flag = me->mvert[index_array[i]].flag; + vertices_eval[i].flag = vertices[index_array[i]].flag; } } } else { - for (i = 0; i < totvert; i++, mv++) { - mv->flag = me->mvert[i].flag; + for (const int i : vertices_eval.index_range()) { + vertices_eval[i].flag = vertices[i].flag; } } @@ -527,6 +529,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) return false; } + MutableSpan<MVert> verts = me->vertices_for_write(); bke::AttributeAccessor attributes = bke::mesh_attributes(*me); const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( ".hide_vert", ATTR_DOMAIN_POINT, false); @@ -535,7 +538,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) action = SEL_SELECT; for (int i = 0; i < me->totvert; i++) { - MVert *mvert = &me->mvert[i]; + MVert *mvert = &verts[i]; if (!hide_vert[i] && mvert->flag & SELECT) { action = SEL_DESELECT; break; @@ -545,7 +548,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags) bool changed = false; for (int i = 0; i < me->totvert; i++) { - MVert *mvert = &me->mvert[i]; + MVert *mvert = &verts[i]; if (!hide_vert[i]) { switch (action) { case SEL_SELECT: @@ -591,8 +594,11 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags) { using namespace blender; Mesh *me = BKE_mesh_from_object(ob); - - if (me == nullptr || me->dvert == nullptr) { + if (me == nullptr) { + return; + } + const Span<MDeformVert> dverts = me->deform_verts(); + if (dverts.is_empty()) { return; } @@ -600,13 +606,14 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags) paintvert_deselect_all_visible(ob, SEL_DESELECT, false); } + MutableSpan<MVert> verts = me->vertices_for_write(); bke::AttributeAccessor attributes = bke::mesh_attributes(*me); const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( ".hide_vert", ATTR_DOMAIN_POINT, false); for (int i = 0; i < me->totvert; i++) { - MVert *mv = &me->mvert[i]; - MDeformVert *dv = &me->dvert[i]; + MVert *mv = &verts[i]; + const MDeformVert *dv = &dverts[i]; if (!hide_vert[i]) { if (dv->dw == nullptr) { /* if null weight then not grouped */ @@ -628,10 +635,10 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected) return; } + MutableSpan<MVert> verts = me->vertices_for_write(); bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me); bke::SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_span<bool>( ".hide_vert", ATTR_DOMAIN_POINT); - MutableSpan<MVert> verts(me->mvert, me->totvert); for (const int i : verts.index_range()) { MVert &vert = verts[i]; @@ -661,10 +668,10 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select) return; } + MutableSpan<MVert> verts = me->vertices_for_write(); bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me); const VArray<bool> hide_vert = attributes.lookup_or_default<bool>( ".hide_vert", ATTR_DOMAIN_POINT, false); - MutableSpan<MVert> verts(me->mvert, me->totvert); for (const int i : verts.index_range()) { MVert &vert = verts[i]; diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 15e28381cb6..7bb1dc3723f 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -361,8 +361,6 @@ static void um_arraystore_compact_ex(UndoMesh *um, const UndoMesh *um_ref, bool if (create) { um_arraystore.users += 1; } - - BKE_mesh_update_customdata_pointers(me, false); } /** @@ -465,9 +463,6 @@ static void um_arraystore_expand(UndoMesh *um) BLI_assert(me->totselect == (state_len / stride)); UNUSED_VARS_NDEBUG(stride); } - - /* not essential, but prevents accidental dangling pointer access */ - BKE_mesh_update_customdata_pointers(me, false); } static void um_arraystore_free(UndoMesh *um) diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 1511da810cb..09673b3d7ad 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -18,6 +18,7 @@ #include "BLI_utildefines.h" #include "BKE_attribute.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_editmesh.h" @@ -44,6 +45,8 @@ #include "mesh_intern.h" /* own include */ using blender::Array; +using blender::MutableSpan; +using blender::Span; static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot) { @@ -128,7 +131,6 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) } else { CustomData_free_layer(data, type, tot, layer_index + n); - BKE_mesh_update_customdata_pointers(me, true); } } @@ -186,7 +188,7 @@ static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset) mesh_uv_reset_array(fuv.data(), f->len); } -static void mesh_uv_reset_mface(MPoly *mp, MLoopUV *mloopuv) +static void mesh_uv_reset_mface(const MPoly *mp, MLoopUV *mloopuv) { Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(mp->totloop); @@ -223,8 +225,9 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum) BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV)); MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, layernum); + const MPoly *polys = BKE_mesh_polygons(me); for (int i = 0; i < me->totpoly; i++) { - mesh_uv_reset_mface(&me->mpoly[i], mloopuv); + mesh_uv_reset_mface(&polys[i], mloopuv); } } @@ -280,9 +283,13 @@ int ED_mesh_uv_add( return -1; } - if (me->mloopuv && do_init) { - CustomData_add_layer_named( - &me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name); + if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) && do_init) { + CustomData_add_layer_named(&me->ldata, + CD_MLOOPUV, + CD_DUPLICATE, + CustomData_get_layer(&me->ldata, CD_MLOOPUV), + me->totloop, + name); is_init = true; } else { @@ -293,8 +300,6 @@ int ED_mesh_uv_add( if (active_set || layernum_dst == 0) { CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst); } - - BKE_mesh_update_customdata_pointers(me, true); } /* don't overwrite our copied coords */ @@ -399,9 +404,13 @@ int ED_mesh_color_add(Mesh *me, else { layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); - if (me->mloopcol && do_init) { - CustomData_add_layer_named( - &me->ldata, CD_PROP_BYTE_COLOR, CD_DUPLICATE, me->mloopcol, me->totloop, name); + if (CustomData_get_active_layer(&me->ldata, CD_PROP_BYTE_COLOR) != -1 && do_init) { + CustomData_add_layer_named(&me->ldata, + CD_PROP_BYTE_COLOR, + CD_DUPLICATE, + CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR), + me->totloop, + name); } else { CustomData_add_layer_named( @@ -412,7 +421,7 @@ int ED_mesh_color_add(Mesh *me, CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, layernum); } - BKE_mesh_update_customdata_pointers(me, true); + BKE_mesh_tessface_clear(me); } DEG_id_tag_update(&me->id, 0); @@ -432,7 +441,7 @@ bool ED_mesh_color_ensure(Mesh *me, const char *name) layer = me->ldata.layers + CustomData_get_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); BKE_id_attributes_active_color_set(&me->id, layer); - BKE_mesh_update_customdata_pointers(me, true); + BKE_mesh_tessface_clear(me); } DEG_id_tag_update(&me->id, 0); @@ -496,7 +505,7 @@ int ED_mesh_sculpt_color_add(Mesh *me, CustomData_set_layer_active(&me->vdata, CD_PROP_COLOR, layernum); } - BKE_mesh_update_customdata_pointers(me, true); + BKE_mesh_tessface_clear(me); } DEG_id_tag_update(&me->id, 0); @@ -767,15 +776,20 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator /* Tag edges as sharp according to smooth threshold if needed, * to preserve autosmooth shading. */ if (me->flag & ME_AUTOSMOOTH) { - BKE_edges_sharp_from_angle_set(me->mvert, - me->totvert, - me->medge, - me->totedge, - me->mloop, - me->totloop, - me->mpoly, + const Span<MVert> verts = me->vertices(); + MutableSpan<MEdge> edges = me->edges_for_write(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); + + BKE_edges_sharp_from_angle_set(verts.data(), + verts.size(), + edges.data(), + edges.size(), + loops.data(), + loops.size(), + polys.data(), BKE_mesh_poly_normals_ensure(me), - me->totpoly, + polys.size(), me->smoothresh); } @@ -873,27 +887,22 @@ static void mesh_add_verts(Mesh *mesh, int len) CustomData_free(&mesh->vdata, mesh->totvert); mesh->vdata = vdata; - BKE_mesh_update_customdata_pointers(mesh, false); BKE_mesh_runtime_clear_cache(mesh); - /* scan the input list and insert the new vertices */ + const int old_vertex_num = mesh->totvert; + mesh->totvert = totvert; - /* set default flags */ - MVert *mvert = &mesh->mvert[mesh->totvert]; - for (int i = 0; i < len; i++, mvert++) { - mvert->flag |= SELECT; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + for (MVert &vert : verts.drop_front(old_vertex_num)) { + vert.flag = SELECT; } - - /* set final vertex list size */ - mesh->totvert = totvert; } static void mesh_add_edges(Mesh *mesh, int len) { CustomData edata; - MEdge *medge; - int i, totedge; + int totedge; if (len == 0) { return; @@ -911,17 +920,16 @@ static void mesh_add_edges(Mesh *mesh, int len) CustomData_free(&mesh->edata, mesh->totedge); mesh->edata = edata; - BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */ BKE_mesh_runtime_clear_cache(mesh); - /* set default flags */ - medge = &mesh->medge[mesh->totedge]; - for (i = 0; i < len; i++, medge++) { - medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; - } - + const int old_edges_num = mesh->totedge; mesh->totedge = totedge; + + MutableSpan<MEdge> edges = mesh->edges_for_write(); + for (MEdge &edge : edges.drop_front(old_edges_num)) { + edge.flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; + } } static void mesh_add_loops(Mesh *mesh, int len) @@ -947,7 +955,6 @@ static void mesh_add_loops(Mesh *mesh, int len) CustomData_free(&mesh->ldata, mesh->totloop); mesh->ldata = ldata; - BKE_mesh_update_customdata_pointers(mesh, true); mesh->totloop = totloop; } @@ -955,8 +962,7 @@ static void mesh_add_loops(Mesh *mesh, int len) static void mesh_add_polys(Mesh *mesh, int len) { CustomData pdata; - MPoly *mpoly; - int i, totpoly; + int totpoly; if (len == 0) { return; @@ -974,17 +980,16 @@ static void mesh_add_polys(Mesh *mesh, int len) CustomData_free(&mesh->pdata, mesh->totpoly); mesh->pdata = pdata; - BKE_mesh_update_customdata_pointers(mesh, true); BKE_mesh_runtime_clear_cache(mesh); - /* set default flags */ - mpoly = &mesh->mpoly[mesh->totpoly]; - for (i = 0; i < len; i++, mpoly++) { - mpoly->flag = ME_FACE_SEL; - } - + const int old_polys_num = mesh->totpoly; mesh->totpoly = totpoly; + + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + for (MPoly &poly : polys.drop_front(old_polys_num)) { + poly.flag = ME_FACE_SEL; + } } /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c index 82e77a88a57..905eb5d43e1 100644 --- a/source/blender/editors/mesh/mesh_mirror.c +++ b/source/blender/editors/mesh/mesh_mirror.c @@ -55,11 +55,9 @@ void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *me_eva } } else { - MVert *mvert = me_eval ? me_eval->mvert : me->mvert; - int i; - - for (i = 0; i < totvert; i++, mvert++) { - BLI_kdtree_3d_insert(MirrKdStore.tree, i, mvert->co); + const MVert *verts = BKE_mesh_vertices(me_eval ? me_eval : me); + for (int i = 0; i < totvert; i++) { + BLI_kdtree_3d_insert(MirrKdStore.tree, i, verts[i].co); } } @@ -164,7 +162,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em, BLI_assert(me == NULL); } const bool is_editmode = (em != NULL); - MEdge *medge = NULL, *med; + const MEdge *medge = NULL, *med; /* Edit-mode variables. */ BMEdge *eed; @@ -210,8 +208,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em, } else { totedge = me->totedge; - medge = me->medge; - + medge = BKE_mesh_edges(me); for (a = 0, med = medge; a < totedge; a++, med++) { const uint i1 = med->v1, i2 = med->v2; topo_hash[i1]++; diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index 330560be026..88c204b56e9 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -55,6 +55,9 @@ #include "WM_api.h" #include "WM_types.h" +using blender::MutableSpan; +using blender::Span; + /* * ********************** no editmode!!! *********** */ /*********************** JOIN ***************************/ @@ -691,9 +694,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) me->ldata = ldata; me->pdata = pdata; - /* tessface data removed above, no need to update */ - BKE_mesh_update_customdata_pointers(me, false); - /* Tag normals dirty because vertex positions could be changed from the original. */ BKE_mesh_normals_tag_dirty(me); @@ -906,13 +906,13 @@ static bool ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval) static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *me_eval, int index) { Mesh *me = static_cast<Mesh *>(ob->data); - MVert *mvert = me_eval ? me_eval->mvert : me->mvert; + const Span<MVert> verts = me_eval ? me_eval->vertices() : me->vertices(); + float vec[3]; - mvert = &mvert[index]; - vec[0] = -mvert->co[0]; - vec[1] = mvert->co[1]; - vec[2] = mvert->co[2]; + vec[0] = -verts[index].co[0]; + vec[1] = verts[index].co[1]; + vec[2] = verts[index].co[2]; return ED_mesh_mirror_spatial_table_lookup(ob, nullptr, me_eval, vec); } @@ -1128,8 +1128,8 @@ static bool mirror_facecmp(const void *a, const void *b) int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) { Mesh *me = static_cast<Mesh *>(ob->data); - MVert *mv, *mvert; - MFace mirrormf, *mf, *hashmf, *mface; + const MVert *mv; + MFace mirrormf, *mf, *hashmf; GHash *fhash; int *mirrorverts, *mirrorfaces; @@ -1143,12 +1143,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) mirrorverts = static_cast<int *>(MEM_callocN(sizeof(int) * totvert, "MirrorVerts")); mirrorfaces = static_cast<int *>(MEM_callocN(sizeof(int[2]) * totface, "MirrorFaces")); - mvert = me_eval ? me_eval->mvert : me->mvert; - mface = me_eval ? me_eval->mface : me->mface; + const Span<MVert> verts = me_eval ? me_eval->vertices() : me->vertices(); + MFace *mface = (MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, CD_MFACE); ED_mesh_mirror_spatial_table_begin(ob, em, me_eval); - for (a = 0, mv = mvert; a < totvert; a++, mv++) { + for (a = 0, mv = verts.data(); a < totvert; a++, mv++) { mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology); } @@ -1275,42 +1275,28 @@ bool ED_mesh_pick_face_vert( const float mval_f[2] = {(float)mval[0], (float)mval[1]}; float len_best = FLT_MAX; - MPoly *me_eval_mpoly; - MLoop *me_eval_mloop; - MVert *me_eval_mvert; - uint me_eval_mpoly_len; - - me_eval_mpoly = me_eval->mpoly; - me_eval_mloop = me_eval->mloop; - me_eval_mvert = me_eval->mvert; - - me_eval_mpoly_len = me_eval->totpoly; + const Span<MVert> verts = me_eval->vertices(); + const Span<MPoly> polys = me_eval->polygons(); + const Span<MLoop> loops = me_eval->loops(); const int *index_mp_to_orig = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); /* tag all verts using this face */ if (index_mp_to_orig) { - uint i; - - for (i = 0; i < me_eval_mpoly_len; i++) { + for (const int i : polys.index_range()) { if (index_mp_to_orig[i] == poly_index) { - ed_mesh_pick_face_vert__mpoly_find(region, - mval_f, - &me_eval_mpoly[i], - me_eval_mvert, - me_eval_mloop, - &len_best, - &v_idx_best); + ed_mesh_pick_face_vert__mpoly_find( + region, mval_f, &polys[i], verts.data(), loops.data(), &len_best, &v_idx_best); } } } else { - if (poly_index < me_eval_mpoly_len) { + if (poly_index < polys.size()) { ed_mesh_pick_face_vert__mpoly_find(region, mval_f, - &me_eval_mpoly[poly_index], - me_eval_mvert, - me_eval_mloop, + &polys[poly_index], + verts.data(), + loops.data(), &len_best, &v_idx_best); } @@ -1425,7 +1411,8 @@ bool ED_mesh_pick_vert( } /* setup data */ - data.mvert = me->mvert; + const Span<MVert> verts = me->vertices(); + data.mvert = verts.data(); data.region = region; data.mval_f = mval_f; data.len_best = FLT_MAX; @@ -1479,10 +1466,11 @@ MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index) if (r_index) { *r_index = index; } - if (index == -1 || me->dvert == nullptr) { + if (index == -1 || me->deform_verts().is_empty()) { return nullptr; } - return me->dvert + index; + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); + return &dverts[index]; } MDeformVert *ED_mesh_active_dvert_get_only(Object *ob) diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 3170ce2c620..8d505bbca3e 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -155,7 +155,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) break; } - if (!me->mloopuv) { + if (!CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); ok = false; diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 708f1d02656..2e07214a5b3 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -971,7 +971,8 @@ static bool bake_targets_init_vertex_colors(Main *bmain, return true; } -static int find_original_loop(const Mesh *me_orig, +static int find_original_loop(const MPoly *orig_polys, + const MLoop *orig_loops, const int *vert_origindex, const int *poly_origindex, const int poly_eval, @@ -987,8 +988,8 @@ static int find_original_loop(const Mesh *me_orig, } /* Find matching loop with original vertex in original polygon. */ - MPoly *mpoly_orig = me_orig->mpoly + poly_orig; - MLoop *mloop_orig = me_orig->mloop + mpoly_orig->loopstart; + const MPoly *mpoly_orig = orig_polys + poly_orig; + const MLoop *mloop_orig = orig_loops + mpoly_orig->loopstart; for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) { if (mloop_orig->v == vert_orig) { return mpoly_orig->loopstart + j; @@ -1025,23 +1026,31 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop); MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); - BKE_mesh_recalc_looptri( - me_eval->mloop, me_eval->mpoly, me_eval->mvert, me_eval->totloop, me_eval->totpoly, looptri); + const MLoop *loops = BKE_mesh_loops(me_eval); + BKE_mesh_recalc_looptri(loops, + BKE_mesh_polygons(me_eval), + BKE_mesh_vertices(me_eval), + me_eval->totloop, + me_eval->totpoly, + looptri); /* For mapping back to original mesh in case there are modifiers. */ const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX); const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); + const MPoly *orig_polys = BKE_mesh_polygons(me); + const MLoop *orig_loops = BKE_mesh_loops(me); for (int i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; for (int j = 0; j < 3; j++) { unsigned int l = lt->tri[j]; - unsigned int v = me_eval->mloop[l].v; + unsigned int v = loops[l].v; /* Map back to original loop if there are modifiers. */ if (vert_origindex != NULL && poly_origindex != NULL) { - l = find_original_loop(me, vert_origindex, poly_origindex, lt->poly, v); + l = find_original_loop( + orig_polys, orig_loops, vert_origindex, poly_origindex, lt->poly, v); if (l == ORIGINDEX_NONE || l >= me->totloop) { continue; } @@ -1135,7 +1144,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex"); memset(mcol, 0, sizeof(MPropCol) * me->totvert); - MLoop *mloop = me->mloop; + const MLoop *mloop = BKE_mesh_loops(me); for (int i = 0; i < totloop; i++, mloop++) { const int v = mloop->v; bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num); diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 58ddde75844..5e642a00727 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -94,6 +94,8 @@ #include "object_intern.h" +using blender::Span; + static void modifier_skin_customdata_delete(struct Object *ob); /* ------------------------------------------------------------------- */ @@ -587,14 +589,14 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports), me->totvert = verts_num; me->totedge = edges_num; - me->mvert = (MVert *)CustomData_add_layer( - &me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num); - me->medge = (MEdge *)CustomData_add_layer( - &me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num); - me->mface = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0); + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num); + CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num); + CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0); - MVert *mvert = me->mvert; - MEdge *medge = me->medge; + blender::MutableSpan<MVert> verts = me->vertices_for_write(); + blender::MutableSpan<MEdge> edges = me->edges_for_write(); + MVert *mvert = verts.data(); + MEdge *medge = edges.data(); /* copy coordinates */ cache = psys_eval->pathcache; @@ -2591,8 +2593,8 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot) } static void skin_armature_bone_create(Object *skin_ob, - MVert *mvert, - MEdge *medge, + const MVert *mvert, + const MEdge *medge, bArmature *arm, BLI_bitmap *edges_visited, const MeshElemMap *emap, @@ -2637,12 +2639,15 @@ static void skin_armature_bone_create(Object *skin_ob, static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob) { Mesh *me = static_cast<Mesh *>(skin_ob->data); + const Span<MVert> me_verts = me->vertices(); + const Span<MEdge> me_edges = me->edges(); Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, skin_ob); - Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); - MVert *mvert = me_eval_deform->mvert; + const Mesh *me_eval_deform = mesh_get_eval_deform( + depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); + const Span<MVert> verts_eval = me_eval_deform->vertices(); /* add vertex weights to original mesh */ CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, me->totvert); @@ -2660,7 +2665,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, CustomData_get_layer(&me->vdata, CD_MVERT_SKIN)); int *emap_mem; MeshElemMap *emap; - BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge); + BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me_edges.data(), me->totvert, me->totedge); BLI_bitmap *edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited"); @@ -2676,15 +2681,16 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, if (emap[v].count > 1) { bone = ED_armature_ebone_add(arm, "Bone"); - copy_v3_v3(bone->head, me->mvert[v].co); - copy_v3_v3(bone->tail, me->mvert[v].co); + copy_v3_v3(bone->head, me_verts[v].co); + copy_v3_v3(bone->tail, me_verts[v].co); bone->head[1] = 1.0f; bone->rad_head = bone->rad_tail = 0.25; } if (emap[v].count >= 1) { - skin_armature_bone_create(skin_ob, mvert, me->medge, arm, edges_visited, emap, bone, v); + skin_armature_bone_create( + skin_ob, verts_eval.data(), me_edges.data(), arm, edges_visited, emap, bone, v); } } } diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index 812d9bbbc08..56cccd984b6 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -73,6 +73,9 @@ #include "object_intern.h" /* own include */ +using blender::IndexRange; +using blender::Span; + /* TODO(sebpa): unstable, can lead to unrecoverable errors. */ // #define USE_MESH_CURVATURE @@ -128,7 +131,8 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op) } /* Output mesh will be all smooth or all flat shading. */ - const bool smooth_normals = mesh->mpoly[0].flag & ME_SMOOTH; + const Span<MPoly> polygons = mesh->polygons(); + const bool smooth_normals = polygons.first().flag & ME_SMOOTH; float isovalue = 0.0f; if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) { @@ -678,9 +682,11 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) * check that the direction of the faces are consistent and doesn't suddenly * flip */ + const Span<MVert> verts = mesh->vertices(); + const Span<MEdge> edges = mesh->edges(); + const Span<MLoop> loops = mesh->loops(); bool is_manifold_consistent = true; - const MLoop *mloop = mesh->mloop; char *edge_faces = (char *)MEM_callocN(mesh->totedge * sizeof(char), "remesh_manifold_check"); int *edge_vert = (int *)MEM_malloc_arrayN( mesh->totedge, sizeof(uint), "remesh_consistent_check"); @@ -689,18 +695,17 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) edge_vert[i] = -1; } - for (uint loop_idx = 0; loop_idx < mesh->totloop; loop_idx++) { - const MLoop *loop = &mloop[loop_idx]; - edge_faces[loop->e] += 1; - if (edge_faces[loop->e] > 2) { + for (const MLoop &loop : loops) { + edge_faces[loop.e] += 1; + if (edge_faces[loop.e] > 2) { is_manifold_consistent = false; break; } - if (edge_vert[loop->e] == -1) { - edge_vert[loop->e] = loop->v; + if (edge_vert[loop.e] == -1) { + edge_vert[loop.e] = loop.v; } - else if (edge_vert[loop->e] == loop->v) { + else if (edge_vert[loop.e] == loop.v) { /* Mesh has flips in the surface so it is non consistent */ is_manifold_consistent = false; break; @@ -708,16 +713,16 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) } if (is_manifold_consistent) { - for (uint i = 0; i < mesh->totedge; i++) { + for (const int i : edges.index_range()) { /* Check for wire edges. */ if (edge_faces[i] == 0) { is_manifold_consistent = false; break; } /* Check for zero length edges */ - MVert *v1 = &mesh->mvert[mesh->medge[i].v1]; - MVert *v2 = &mesh->mvert[mesh->medge[i].v2]; - if (compare_v3v3(v1->co, v2->co, 1e-4f)) { + const MVert &v1 = verts[edges[i].v1]; + const MVert &v2 = verts[edges[i].v2]; + if (compare_v3v3(v1.co, v2.co, 1e-4f)) { is_manifold_consistent = false; break; } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 0e3945bff15..0328f6a6230 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -114,14 +114,13 @@ static bool object_shape_key_mirror( if (ob->type == OB_MESH) { Mesh *me = ob->data; - MVert *mv; int i1, i2; float *fp1, *fp2; float tvec[3]; ED_mesh_mirror_spatial_table_begin(ob, NULL, NULL); - for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) { + for (i1 = 0; i1 < me->totvert; i1++) { i2 = mesh_get_x_mirror_vert(ob, NULL, i1, use_topology); if (i2 == i1) { fp1 = ((float *)kb->data) + i1 * 3; diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 7727dbeadfd..310d73daa76 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -67,6 +67,9 @@ #include "object_intern.h" +using blender::MutableSpan; +using blender::Span; + static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob); /* -------------------------------------------------------------------- */ @@ -196,9 +199,9 @@ bool ED_vgroup_parray_alloc(ID *id, return true; } - if (me->dvert) { - MVert *mvert = me->mvert; - MDeformVert *dvert = me->dvert; + if (!me->deform_verts().is_empty()) { + const Span<MVert> verts = me->vertices(); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); *dvert_tot = me->totvert; *dvert_arr = static_cast<MDeformVert **>( @@ -206,12 +209,12 @@ bool ED_vgroup_parray_alloc(ID *id, if (use_vert_sel) { for (int i = 0; i < me->totvert; i++) { - (*dvert_arr)[i] = (mvert[i].flag & SELECT) ? &dvert[i] : nullptr; + (*dvert_arr)[i] = (verts[i].flag & SELECT) ? &dverts[i] : nullptr; } } else { for (int i = 0; i < me->totvert; i++) { - (*dvert_arr)[i] = me->dvert + i; + (*dvert_arr)[i] = &dverts[i]; } } @@ -548,9 +551,10 @@ static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx) vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) { - MDeformVert *dvert_src = &me->dvert[vidx]; - MDeformVert *dvert_dst = &me->dvert[vidx_mirr]; + MDeformVert *dvert_src = &dverts[vidx]; + MDeformVert *dvert_dst = &dverts[vidx_mirr]; mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr); } } @@ -659,15 +663,15 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type) } } else { - MDeformVert *dv; + const Span<MVert> verts = me->vertices(); int v_act; dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act); if (dvert_act) { - dv = me->dvert; - for (i = 0; i < me->totvert; i++, dv++) { - if ((me->mvert[i].flag & SELECT) && dv != dvert_act) { - BKE_defvert_copy_subset(dv, dvert_act, vgroup_validmap, vgroup_tot); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); + for (i = 0; i < me->totvert; i++) { + if ((verts[i].flag & SELECT) && &dverts[i] != dvert_act) { + BKE_defvert_copy_subset(&dverts[i], dvert_act, vgroup_validmap, vgroup_tot); if (me->symmetry & ME_SYMMETRY_X) { ED_mesh_defvert_mirror_update_ob(ob, -1, i); } @@ -927,7 +931,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) { - MDeformVert *dv = nullptr; + const MDeformVert *dv = nullptr; /* get the deform vertices corresponding to the vertnum */ if (ob->type == OB_MESH) { @@ -942,18 +946,19 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) BMVert *eve; BM_mesh_elem_table_ensure(em->bm, BM_VERT); eve = BM_vert_at_index(em->bm, vertnum); - dv = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset)); + dv = static_cast<const MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset)); } else { return 0.0f; } } else { - if (me->dvert) { + const Span<MDeformVert> dverts = me->deform_verts(); + if (!dverts.is_empty()) { if (vertnum >= me->totvert) { return 0.0f; } - dv = &me->dvert[vertnum]; + dv = &dverts[vertnum]; } } } @@ -1044,19 +1049,18 @@ static void vgroup_select_verts(Object *ob, int select) } } else { - if (me->dvert) { + const Span<MDeformVert> dverts = me->deform_verts(); + if (!dverts.is_empty()) { const bool *hide_vert = (const bool *)CustomData_get_layer_named( &me->vdata, CD_PROP_BOOL, ".hide_vert"); MVert *mv; - MDeformVert *dv; int i; - mv = me->mvert; - dv = me->dvert; + mv = me->vertices_for_write().data(); - for (i = 0; i < me->totvert; i++, mv++, dv++) { + for (i = 0; i < me->totvert; i++, mv++) { if (hide_vert != nullptr && !hide_vert[i]) { - if (BKE_defvert_find_index(dv, def_nr)) { + if (BKE_defvert_find_index(&dverts[i], def_nr)) { if (select) { mv->flag |= SELECT; } @@ -1214,7 +1218,8 @@ static bool vgroup_normalize(Object *ob) * count is an int passed by reference so it can be assigned the value of the length here. */ static blender::Vector<int> getSurroundingVerts(Mesh *me, int vert) { - MPoly *mp = me->mpoly; + const MPoly *mp = me->polygons().data(); + const MLoop *loops = me->loops().data(); int i = me->totpoly; blender::Vector<int> verts; @@ -1222,7 +1227,7 @@ static blender::Vector<int> getSurroundingVerts(Mesh *me, int vert) while (i--) { int j = mp->totloop; int first_l = mp->totloop - 1; - MLoop *ml = &me->mloop[mp->loopstart]; + const MLoop *ml = &loops[mp->loopstart]; while (j--) { /* XXX This assume a vert can only be once in a poly, even though * it seems logical to me, not totally sure of that. */ @@ -1236,7 +1241,7 @@ static blender::Vector<int> getSurroundingVerts(Mesh *me, int vert) else if (!j) { /* We are on the last corner. */ a = (ml - 1)->v; - b = me->mloop[mp->loopstart].v; + b = loops[mp->loopstart].v; } else { a = (ml - 1)->v; @@ -1348,8 +1353,8 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, Mesh *me_deform; MDeformWeight *dw, *dw_eval; MVert m; - MDeformVert *dvert = me->dvert + index; - MDeformVert *dvert_eval = mesh_eval->dvert + index; + MDeformVert *dvert = me->deform_verts_for_write().data() + index; + MDeformVert *dvert_eval = mesh_eval->deform_verts_for_write().data() + index; int totweight = dvert->totweight; float oldw = 0; float oldPos[3] = {0}; @@ -1372,7 +1377,8 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, do { wasChange = false; me_deform = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); - m = me_deform->mvert[index]; + const Span<MVert> verts = me_deform->vertices(); + m = verts[index]; copy_v3_v3(oldPos, m.co); distToStart = dot_v3v3(norm, oldPos) + d; @@ -1414,7 +1420,7 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, } dw_eval->weight = dw->weight; me_deform = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); - m = me_deform->mvert[index]; + m = verts[index]; getVerticalAndHorizontalChange( norm, d, coord, oldPos, distToStart, m.co, changes, dists, i); dw->weight = oldw; @@ -1519,7 +1525,7 @@ static void vgroup_fix( int i; Mesh *me = static_cast<Mesh *>(ob->data); - MVert *mvert = me->mvert; + MVert *mvert = me->vertices_for_write().data(); if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL)) { return; } @@ -1534,9 +1540,10 @@ static void vgroup_fix( Mesh *me_deform = mesh_get_eval_deform( depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); + const Span<MVert> verts_deform = me_deform->vertices(); k = count; while (k--) { - p[k] = me_deform->mvert[verts[k]]; + p[k] = verts_deform[verts[k]]; } if (count >= 3) { @@ -1544,7 +1551,7 @@ static void vgroup_fix( float coord[3]; float norm[3]; getSingleCoordinate(p, count, coord); - m = me_deform->mvert[i]; + m = verts_deform[i]; sub_v3_v3v3(norm, m.co, coord); mag = normalize_v3(norm); if (mag) { /* zeros fix */ @@ -1929,7 +1936,7 @@ static void vgroup_smooth_subset(Object *ob, emap_mem = nullptr; } else { - BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge); + BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->edges().data(), me->totvert, me->totedge); } weight_accum_prev = static_cast<float *>( @@ -1968,11 +1975,13 @@ static void vgroup_smooth_subset(Object *ob, } } else { + const Span<MVert> verts = me->vertices(); + const blender::Span<MEdge> edges = me->edges(); for (int i = 0; i < dvert_tot; i++) { - const MVert *v = &me->mvert[i]; + const MVert *v = &verts[i]; if (IS_ME_VERT_WRITE(v)) { for (int j = 0; j < emap[i].count; j++) { - const MEdge *e = &me->medge[emap[i].indices[j]]; + const MEdge *e = &edges[emap[i].indices[j]]; const int i_other = (e->v1 == i) ? e->v2 : e->v1; if (IS_ME_VERT_READ(i_other)) { STACK_PUSH(verts_used, i); @@ -2041,12 +2050,13 @@ static void vgroup_smooth_subset(Object *ob, } else { int j; + const blender::Span<MEdge> edges = me->edges(); /* checked already */ - BLI_assert(IS_ME_VERT_WRITE(&me->mvert[i])); + BLI_assert(IS_ME_VERT_WRITE(&me->vertices()[i])); for (j = 0; j < emap[i].count; j++) { - MEdge *e = &me->medge[emap[i].indices[j]]; + const MEdge *e = &edges[emap[i].indices[j]]; const int i_other = (e->v1 == i ? e->v2 : e->v1); if (IS_ME_VERT_READ(i_other)) { WEIGHT_ACCUMULATE; @@ -2366,7 +2376,7 @@ void ED_vgroup_mirror(Object *ob, def_nr) BMVert *eve, *eve_mirr; - MDeformVert *dvert, *dvert_mirr; + MDeformVert *dvert_mirr; char sel, sel_mirr; int *flip_map = nullptr, flip_map_len; const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1; @@ -2424,7 +2434,8 @@ void ED_vgroup_mirror(Object *ob, sel_mirr = BM_elem_flag_test(eve_mirr, BM_ELEM_SELECT); if ((sel || sel_mirr) && (eve != eve_mirr)) { - dvert = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset)); + MDeformVert *dvert = static_cast<MDeformVert *>( + BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset)); dvert_mirr = static_cast<MDeformVert *>( BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset)); @@ -2447,11 +2458,11 @@ void ED_vgroup_mirror(Object *ob, } else { /* object mode / weight paint */ - MVert *mv, *mv_mirr; + const MVert *mv, *mv_mirr; int vidx, vidx_mirr; const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - if (me->dvert == nullptr) { + if (me->deform_verts().is_empty()) { goto cleanup; } @@ -2460,12 +2471,14 @@ void ED_vgroup_mirror(Object *ob, } BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); + const MVert *verts = me->vertices().data(); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); - for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) { + for (vidx = 0, mv = verts; vidx < me->totvert; vidx++, mv++) { if (!BLI_BITMAP_TEST(vert_tag, vidx)) { if ((vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology)) != -1) { if (vidx != vidx_mirr) { - mv_mirr = &me->mvert[vidx_mirr]; + mv_mirr = &verts[vidx_mirr]; if (!BLI_BITMAP_TEST(vert_tag, vidx_mirr)) { if (use_vert_sel) { @@ -2474,8 +2487,8 @@ void ED_vgroup_mirror(Object *ob, } if (sel || sel_mirr) { - dvert = &me->dvert[vidx]; - dvert_mirr = &me->dvert[vidx_mirr]; + MDeformVert *dvert = &dverts[vidx]; + dvert_mirr = &dvert[vidx_mirr]; VGROUP_MIRR_OP; totmirr++; @@ -2528,7 +2541,7 @@ void ED_vgroup_mirror(Object *ob, sel_mirr = bp_mirr->f1 & SELECT; if (sel || sel_mirr) { - dvert = <->dvert[i1]; + MDeformVert *dvert = <->dvert[i1]; dvert_mirr = <->dvert[i2]; VGROUP_MIRR_OP; @@ -2612,14 +2625,12 @@ static void vgroup_assign_verts(Object *ob, const float weight) } } else { - if (!me->dvert) { - BKE_object_defgroup_data_create(&me->id); - } + const Span<MVert> verts = me->vertices(); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); + MDeformVert *dv = dverts.data(); - MVert *mv = me->mvert; - MDeformVert *dv = me->dvert; - - for (int i = 0; i < me->totvert; i++, mv++, dv++) { + for (int i = 0; i < me->totvert; i++, dv++) { + const MVert *mv = &verts[i]; if (mv->flag & SELECT) { MDeformWeight *dw; dw = BKE_defvert_ensure_index(dv, def_nr); @@ -2733,7 +2744,7 @@ static bool vertex_group_mesh_with_dvert_poll(bContext *C) } Mesh *me = static_cast<Mesh *>(ob->data); - if (me->dvert == nullptr) { + if (me->deform_verts().is_empty()) { CTX_wm_operator_poll_msg_set(C, "The active mesh object has no vertex group data"); return false; } @@ -4345,9 +4356,12 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr) return; } - dv = me->dvert; + const Span<MVert> verts = me->vertices(); + MutableSpan<MDeformVert> dverts = me->deform_verts_for_write(); + + dv = dverts.data(); for (i = 0; i < me->totvert; i++, dv++) { - if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) { + if ((verts[i].flag & SELECT) && (dv != dvert_act)) { BKE_defvert_copy_index(dv, def_nr, dvert_act, def_nr); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 167952ba1fb..7067d558d7a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1451,26 +1451,27 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part vec = edit->emitter_cosnos; nor = vec + 3; + const MVert *verts = BKE_mesh_vertices(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); - + MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); for (i = 0; i < totface; i++, vec += 6, nor += 6) { - MFace *mface = &mesh->mface[i]; - MVert *mvert; + MFace *mface = &mfaces[i]; + const MVert *mvert; - mvert = &mesh->mvert[mface->v1]; + mvert = &verts[mface->v1]; copy_v3_v3(vec, mvert->co); copy_v3_v3(nor, vert_normals[mface->v1]); - mvert = &mesh->mvert[mface->v2]; + mvert = &verts[mface->v2]; add_v3_v3v3(vec, vec, mvert->co); add_v3_v3(nor, vert_normals[mface->v2]); - mvert = &mesh->mvert[mface->v3]; + mvert = &verts[mface->v3]; add_v3_v3v3(vec, vec, mvert->co); add_v3_v3(nor, vert_normals[mface->v3]); if (mface->v4) { - mvert = &mesh->mvert[mface->v4]; + mvert = &verts[mface->v4]; add_v3_v3v3(vec, vec, mvert->co); add_v3_v3(nor, vert_normals[mface->v4]); @@ -3568,7 +3569,9 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface; + MFace *mtessface = use_dm_final_indices ? + (MFace *)CustomData_get_layer(&psmd_eval->mesh_final->fdata, CD_MFACE) : + (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE); /* allocate new arrays and copy existing */ new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new"); @@ -4176,8 +4179,8 @@ static int particle_intersect_mesh(Depsgraph *depsgraph, } totface = mesh->totface; - mface = mesh->mface; - mvert = mesh->mvert; + mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + mvert = BKE_mesh_vertices_for_write(mesh); /* lets intersect the faces */ for (i = 0; i < totface; i++, mface++) { diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 96aea0ededf..a9fa325c341 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -704,7 +704,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, PTCacheEditKey *ekey; BVHTreeFromMesh bvhtree = {NULL}; MFace *mface = NULL, *mf; - MEdge *medge = NULL, *me; + const MEdge *medge = NULL, *me; MVert *mvert; Mesh *mesh, *target_mesh; int numverts; @@ -750,7 +750,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, BKE_mesh_tessface_ensure(mesh); numverts = mesh->totvert; - mvert = mesh->mvert; + mvert = BKE_mesh_vertices_for_write(mesh); /* convert to global coordinates */ for (int i = 0; i < numverts; i++) { @@ -758,11 +758,11 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, } if (mesh->totface != 0) { - mface = mesh->mface; + mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_FACES, 2); } else if (mesh->totedge != 0) { - medge = mesh->medge; + medge = BKE_mesh_edges(mesh); BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_EDGES, 2); } else { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index f6539284f74..3b13575f7bb 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -90,6 +90,8 @@ struct AddOperationExecutor { Object *surface_ob_eval_ = nullptr; Mesh *surface_eval_ = nullptr; + Span<MVert> surface_verts_eval_; + Span<MLoop> surface_loops_eval_; Span<MLoopTri> surface_looptris_eval_; VArraySpan<float2> surface_uv_map_eval_; BVHTreeFromMesh surface_bvh_eval_; @@ -140,6 +142,12 @@ struct AddOperationExecutor { report_empty_evaluated_surface(stroke_extension.reports); return; } + surface_verts_eval_ = surface_eval_->vertices(); + surface_loops_eval_ = surface_eval_->loops(); + surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_), + BKE_mesh_runtime_looptri_len(surface_eval_)}; + BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2); + BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); }); curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); @@ -179,12 +187,6 @@ struct AddOperationExecutor { /* Use a pointer cast to avoid overflow warnings. */ RandomNumberGenerator rng{*(uint32_t *)(&time)}; - BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2); - BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); }); - - surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_), - BKE_mesh_runtime_looptri_len(surface_eval_)}; - /* Sample points on the surface using one of multiple strategies. */ Vector<float2> sampled_uvs; if (add_amount_ == 1) { @@ -296,7 +298,7 @@ struct AddOperationExecutor { const MLoopTri &looptri = surface_looptris_eval_[looptri_index]; const float3 brush_pos_su = ray_hit.co; const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle( - *surface_eval_, looptri, brush_pos_su); + surface_verts_eval_, surface_loops_eval_, looptri, brush_pos_su); const float2 uv = bke::mesh_surface_sample::sample_corner_attrribute_with_bary_coords( bary_coords, looptri, surface_uv_map_eval_); @@ -421,9 +423,9 @@ struct AddOperationExecutor { brush_radius_su, [&](const int index, const float3 &UNUSED(co), const float UNUSED(dist_sq)) { const MLoopTri &looptri = surface_looptris_eval_[index]; - const float3 v0_su = surface_eval_->mvert[surface_eval_->mloop[looptri.tri[0]].v].co; - const float3 v1_su = surface_eval_->mvert[surface_eval_->mloop[looptri.tri[1]].v].co; - const float3 v2_su = surface_eval_->mvert[surface_eval_->mloop[looptri.tri[2]].v].co; + const float3 v0_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[0]].v].co; + const float3 v1_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[1]].v].co; + const float3 v2_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[2]].v].co; float3 normal_su; normal_tri_v3(normal_su, v0_su, v1_su, v2_su); if (math::dot(normal_su, view_direction_su) >= 0.0f) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index 139e0d67e89..062bacc7add 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -70,6 +70,8 @@ struct PuffOperationExecutor { Object *surface_ob_ = nullptr; Mesh *surface_ = nullptr; + Span<MVert> surface_verts_; + Span<MLoop> surface_loops_; Span<MLoopTri> surface_looptris_; Span<float3> corner_normals_su_; BVHTreeFromMesh surface_bvh_; @@ -117,11 +119,12 @@ struct PuffOperationExecutor { reinterpret_cast<const float3 *>(CustomData_get_layer(&surface_->ldata, CD_NORMAL)), surface_->totloop}; - BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2); - BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); }); - + surface_verts_ = surface_->vertices(); + surface_loops_ = surface_->loops(); surface_looptris_ = {BKE_mesh_runtime_looptri_ensure(surface_), BKE_mesh_runtime_looptri_len(surface_)}; + BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2); + BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); }); if (stroke_extension.is_first) { this->initialize_segment_lengths(); @@ -289,9 +292,9 @@ struct PuffOperationExecutor { const MLoopTri &looptri = surface_looptris_[nearest.index]; const float3 closest_pos_su = nearest.co; - const float3 &v0_su = surface_->mvert[surface_->mloop[looptri.tri[0]].v].co; - const float3 &v1_su = surface_->mvert[surface_->mloop[looptri.tri[1]].v].co; - const float3 &v2_su = surface_->mvert[surface_->mloop[looptri.tri[2]].v].co; + const float3 &v0_su = surface_verts_[surface_loops_[looptri.tri[0]].v].co; + const float3 &v1_su = surface_verts_[surface_loops_[looptri.tri[1]].v].co; + const float3 &v2_su = surface_verts_[surface_loops_[looptri.tri[2]].v].co; float3 bary_coords; interp_weights_tri_v3(bary_coords, v0_su, v1_su, v2_su, closest_pos_su); const float3 normal_su = geometry::compute_surface_point_normal( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index 007bff0b170..e65d81a4225 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -112,6 +112,8 @@ struct SlideOperationExecutor { Object *surface_ob_eval_ = nullptr; Mesh *surface_eval_ = nullptr; + Span<MVert> surface_verts_eval_; + Span<MLoop> surface_loops_eval_; Span<MLoopTri> surface_looptris_eval_; VArraySpan<float2> surface_uv_map_eval_; BVHTreeFromMesh surface_bvh_eval_; @@ -175,8 +177,8 @@ struct SlideOperationExecutor { if (surface_orig_->totpoly == 0) { report_empty_original_surface(stroke_extension.reports); return; - } - surface_looptris_orig_ = {BKE_mesh_runtime_looptri_ensure(surface_orig_), + } + surface_looptris_orig_ = {BKE_mesh_runtime_looptri_ensure(surface_orig_), BKE_mesh_runtime_looptri_len(surface_orig_)}; surface_uv_map_orig_ = bke::mesh_attributes(*surface_orig_).lookup<float2>(uv_map_name, ATTR_DOMAIN_CORNER); @@ -205,6 +207,8 @@ struct SlideOperationExecutor { } surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_), BKE_mesh_runtime_looptri_len(surface_eval_)}; + surface_verts_eval_ = surface_eval_->vertices(); + surface_loops_eval_ = surface_eval_->loops(); surface_uv_map_eval_ = bke::mesh_attributes(*surface_eval_).lookup<float2>(uv_map_name, ATTR_DOMAIN_CORNER); if (surface_uv_map_eval_.is_empty()) { @@ -319,8 +323,8 @@ struct SlideOperationExecutor { { const float4x4 brush_transform_inv = brush_transform.inverted(); - const Span<MVert> verts_orig_su{surface_orig_->mvert, surface_orig_->totvert}; - const Span<MLoop> loops_orig{surface_orig_->mloop, surface_orig_->totloop}; + const Span<MVert> verts_orig_su = surface_orig_->vertices(); + const Span<MLoop> loops_orig = surface_orig_->loops(); MutableSpan<float3> positions_orig_cu = curves_orig_->positions_for_write(); MutableSpan<float2> surface_uv_coords = curves_orig_->surface_uv_coords_for_write(); @@ -383,7 +387,7 @@ struct SlideOperationExecutor { /* Compute the uv of the new surface position on the evaluated mesh. */ const MLoopTri &looptri_eval = surface_looptris_eval_[looptri_index_eval]; const float3 bary_weights_eval = bke::mesh_surface_sample::compute_bary_coord_in_triangle( - *surface_eval_, looptri_eval, hit_pos_eval_su); + surface_verts_eval_, surface_loops_eval_, looptri_eval, hit_pos_eval_su); const float2 uv = attribute_math::mix3(bary_weights_eval, surface_uv_map_eval_[looptri_eval.tri[0]], surface_uv_map_eval_[looptri_eval.tri[1]], diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index a1bb2bf41ea..f1e6c7bf8dd 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -4055,13 +4055,13 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p } ps->mat_array[totmat - 1] = NULL; - ps->mvert_eval = ps->me_eval->mvert; + ps->mvert_eval = BKE_mesh_vertices(ps->me_eval); ps->vert_normals = BKE_mesh_vertex_normals_ensure(ps->me_eval); if (ps->do_mask_cavity) { - ps->medge_eval = ps->me_eval->medge; + ps->medge_eval = BKE_mesh_edges(ps->me_eval); } - ps->mloop_eval = ps->me_eval->mloop; - ps->mpoly_eval = ps->me_eval->mpoly; + ps->mloop_eval = BKE_mesh_loops(ps->me_eval); + ps->mpoly_eval = BKE_mesh_polygons(ps->me_eval); ps->material_indices = (const int *)CustomData_get_layer_named( &ps->me_eval->pdata, CD_PROP_INT32, "material_index"); @@ -4155,7 +4155,7 @@ static void proj_paint_face_lookup_init(const ProjPaintState *ps, ProjPaintFaceL memset(face_lookup, 0, sizeof(*face_lookup)); if (ps->do_face_sel) { face_lookup->index_mp_to_orig = CustomData_get_layer(&ps->me_eval->pdata, CD_ORIGINDEX); - face_lookup->mpoly_orig = ((Mesh *)ps->ob->data)->mpoly; + face_lookup->mpoly_orig = BKE_mesh_polygons((Mesh *)ps->ob->data); } } diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index dcc6e734cf4..34c5fc3124c 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1123,6 +1123,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex const float(*ob_imat)[4] = vc->obact->imat; /* Write vertices coordinates for the front face. */ + MVert *verts = BKE_mesh_vertices_for_write(trim_operation->mesh); float depth_point[3]; madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front); for (int i = 0; i < tot_screen_points; i++) { @@ -1134,7 +1135,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); madd_v3_v3fl(new_point, shape_normal, depth_front); } - mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point); + mul_v3_m4v3(verts[i].co, ob_imat, new_point); mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point); } @@ -1149,7 +1150,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); madd_v3_v3fl(new_point, shape_normal, depth_back); } - mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point); + mul_v3_m4v3(verts[i + tot_screen_points].co, ob_imat, new_point); mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point); } @@ -1159,10 +1160,12 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris); /* Write the front face triangle indices. */ - MPoly *mp = trim_operation->mesh->mpoly; - MLoop *ml = trim_operation->mesh->mloop; + MPoly *polys = BKE_mesh_polygons_for_write(trim_operation->mesh); + MLoop *loops = BKE_mesh_loops_for_write(trim_operation->mesh); + MPoly *mp = polys; + MLoop *ml = loops; for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->loopstart = (int)(ml - loops); mp->totloop = 3; ml[0].v = r_tris[i][0]; ml[1].v = r_tris[i][1]; @@ -1171,7 +1174,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Write the back face triangle indices. */ for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->loopstart = (int)(ml - loops); mp->totloop = 3; ml[0].v = r_tris[i][0] + tot_screen_points; ml[1].v = r_tris[i][1] + tot_screen_points; @@ -1182,7 +1185,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Write the indices for the lateral triangles. */ for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->loopstart = (int)(ml - loops); mp->totloop = 3; int current_index = i; int next_index = current_index + 1; @@ -1195,7 +1198,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex } for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - trim_operation->mesh->mloop); + mp->loopstart = (int)(ml - loops); mp->totloop = 3; int current_index = i; int next_index = current_index + 1; @@ -1330,8 +1333,9 @@ static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), { SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; Mesh *trim_mesh = trim_operation->mesh; + MVert *verts = BKE_mesh_vertices_for_write(trim_mesh); for (int i = 0; i < trim_mesh->totvert; i++) { - flip_v3_v3(trim_mesh->mvert[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass); + flip_v3_v3(verts[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass); } sculpt_gesture_trim_normals_update(sgcontext); sculpt_gesture_apply_trim(sgcontext); diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index adf21154842..7336166d651 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -30,6 +30,7 @@ #include "BKE_image.h" #include "BKE_layer.h" #include "BKE_material.h" +#include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_paint.h" #include "BKE_report.h" @@ -287,8 +288,8 @@ static void imapaint_pick_uv( const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval); const int tottri = me_eval->runtime.looptris.len; - const MVert *mvert = me_eval->mvert; - const MLoop *mloop = me_eval->mloop; + const MVert *mvert = BKE_mesh_vertices(me_eval); + const MLoop *mloop = BKE_mesh_loops(me_eval); const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); /* get the needed opengl matrices */ @@ -702,7 +703,7 @@ static int vert_select_ungrouped_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Mesh *me = ob->data; - if (BLI_listbase_is_empty(&me->vertex_group_names) || (me->dvert == NULL)) { + if (BLI_listbase_is_empty(&me->vertex_group_names) || (BKE_mesh_deform_verts(me) == NULL)) { BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index ccaf8b1ba37..c1a2a326d14 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -773,6 +773,8 @@ struct WeightPaintGroupData { * paint stroke update - campbell */ struct WeightPaintInfo { + MutableSpan<MDeformVert> dvert; + int defbase_tot; /* both must add up to 'defbase_tot' */ @@ -815,7 +817,7 @@ static void do_weight_paint_vertex_single( float paintweight) { Mesh *me = (Mesh *)ob->data; - MDeformVert *dv = &me->dvert[index]; + MDeformVert *dv = &wpi->dvert[index]; bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; MDeformWeight *dw; @@ -875,7 +877,7 @@ static void do_weight_paint_vertex_single( /* get the mirror def vars */ if (index_mirr != -1) { - dv_mirr = &me->dvert[index_mirr]; + dv_mirr = &wpi->dvert[index_mirr]; if (wp->flag & VP_FLAG_VGROUP_RESTRICT) { dw_mirr = BKE_defvert_find_index(dv_mirr, vgroup_mirr); @@ -915,9 +917,9 @@ static void do_weight_paint_vertex_single( if (!brush_use_accumulate(wp)) { MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev; - MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index); + MDeformVert *dv_prev = defweight_prev_init(dvert_prev, wpi->dvert.data(), index); if (index_mirr != -1) { - defweight_prev_init(dvert_prev, me->dvert, index_mirr); + defweight_prev_init(dvert_prev, wpi->dvert.data(), index_mirr); } weight_prev = BKE_defvert_find_weight(dv_prev, wpi->active.index); @@ -1028,7 +1030,7 @@ static void do_weight_paint_vertex_multi( float paintweight) { Mesh *me = (Mesh *)ob->data; - MDeformVert *dv = &me->dvert[index]; + MDeformVert *dv = &wpi->dvert[index]; bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; /* mirror vars */ @@ -1044,7 +1046,7 @@ static void do_weight_paint_vertex_multi( index_mirr = mesh_get_x_mirror_vert(ob, nullptr, index, topology); if (!ELEM(index_mirr, -1, index)) { - dv_mirr = &me->dvert[index_mirr]; + dv_mirr = &wpi->dvert[index_mirr]; } else { index_mirr = -1; @@ -1071,9 +1073,9 @@ static void do_weight_paint_vertex_multi( if (!brush_use_accumulate(wp)) { MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev; - MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index); + MDeformVert *dv_prev = defweight_prev_init(dvert_prev, wpi->dvert.data(), index); if (index_mirr != -1) { - defweight_prev_init(dvert_prev, me->dvert, index_mirr); + defweight_prev_init(dvert_prev, wpi->dvert.data(), index_mirr); } oldw = BKE_defvert_multipaint_collective_weight( @@ -1235,6 +1237,8 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) } Mesh *me = (Mesh *)ob->data; + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); if (gmap->vert_to_loop == nullptr) { gmap->vert_map_mem = nullptr; @@ -1243,15 +1247,15 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) gmap->vert_to_poly = nullptr; BKE_mesh_vert_loop_map_create(&gmap->vert_to_loop, &gmap->vert_map_mem, - me->mpoly, - me->mloop, + polys.data(), + loops.data(), me->totvert, me->totpoly, me->totloop); BKE_mesh_vert_poly_map_create(&gmap->vert_to_poly, &gmap->poly_map_mem, - me->mpoly, - me->mloop, + polys.data(), + loops.data(), me->totvert, me->totpoly, me->totloop); @@ -1900,7 +1904,7 @@ static void do_wpaint_precompute_weight_cb_ex(void *__restrict userdata, const TaskParallelTLS *__restrict UNUSED(tls)) { SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata; - const MDeformVert *dv = &data->me->dvert[n]; + const MDeformVert *dv = &data->wpi->dvert[n]; data->wpd->precomputed_weight[n] = wpaint_get_active_weight(dv, data->wpi); } @@ -1961,10 +1965,9 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const char v_flag = data->me->mvert[v_index].flag; + const char v_flag = ss->mvert[v_index].flag; /* If the vertex is selected */ if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) { /* Get the average poly weight */ @@ -1972,12 +1975,12 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, float weight_final = 0.0f; for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; - const MPoly *mp = &data->me->mpoly[p_index]; + const MPoly *mp = &ss->mpoly[p_index]; total_hit_loops += mp->totloop; for (int k = 0; k < mp->totloop; k++) { const int l_index = mp->loopstart + k; - const MLoop *ml = &data->me->mloop[l_index]; + const MLoop *ml = &ss->mloop[l_index]; weight_final += data->wpd->precomputed_weight[ml->v]; } } @@ -2057,10 +2060,9 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv_curr = &data->me->mvert[v_index]; + const MVert *mv_curr = &ss->mvert[v_index]; /* If the vertex is selected */ if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) { @@ -2082,12 +2084,12 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, float weight_final = 0.0; for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; - const MPoly *mp = &data->me->mpoly[p_index]; - const MLoop *ml_other = &data->me->mloop[mp->loopstart]; + const MPoly *mp = &ss->mpoly[p_index]; + const MLoop *ml_other = &ss->mloop[mp->loopstart]; for (int k = 0; k < mp->totloop; k++, ml_other++) { const uint v_other_index = ml_other->v; if (v_other_index != v_index) { - const MVert *mv_other = &data->me->mvert[v_other_index]; + const MVert *mv_other = &ss->mvert[v_other_index]; /* Get the direction from the selected vert to the neighbor. */ float other_dir[3]; @@ -2164,11 +2166,10 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata, /* NOTE: grids are 1:1 with corners (aka loops). * For multires, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const char v_flag = data->me->mvert[v_index].flag; + const char v_flag = ss->mvert[v_index].flag; /* If the vertex is selected */ if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) { float brush_strength = cache->bstrength; @@ -2232,13 +2233,12 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( 1.0f; if (angle_cos > 0.0 && BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) { - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; - const char v_flag = data->me->mvert[v_index].flag; + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; + const char v_flag = ss->mvert[v_index].flag; /* If the vertex is selected. */ if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) { - const MDeformVert *dv = &data->me->dvert[v_index]; + const MDeformVert *dv = &data->wpi->dvert[v_index]; accum->len += 1; accum->value += wpaint_get_active_weight(dv, data->wpi); } @@ -2510,7 +2510,11 @@ static void wpaint_stroke_update_step(bContext *C, /* load projection matrix */ mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat); + Mesh *mesh = static_cast<Mesh *>(ob->data); + /* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */ + wpi.dvert = mesh->deform_verts_for_write(); + wpi.defbase_tot = wpd->defbase_tot; wpi.defbase_sel = wpd->defbase_sel; wpi.defbase_tot_sel = wpd->defbase_tot_sel; @@ -2532,7 +2536,7 @@ static void wpaint_stroke_update_step(bContext *C, /* *** done setting up WeightPaintInfo *** */ if (wpd->precomputed_weight) { - precompute_weight_values(C, ob, brush, wpd, &wpi, (Mesh *)ob->data); + precompute_weight_values(C, ob, brush, wpd, &wpi, mesh); } wpaint_do_symmetrical_brush_actions(C, ob, wp, sd, wpd, &wpi); @@ -2545,9 +2549,9 @@ static void wpaint_stroke_update_step(bContext *C, mul_v3_m4v3(loc_world, ob->obmat, ss->cache->true_location); paint_last_stroke_update(scene, loc_world); - BKE_mesh_batch_cache_dirty_tag((Mesh *)ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL); - DEG_id_tag_update((ID *)ob->data, 0); + DEG_id_tag_update(&mesh->id, 0); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); swap_m4m4(wpd->vc.rv3d->persmat, mat); @@ -2980,10 +2984,10 @@ static void do_vpaint_brush_blur_loops(bContext *C, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv = &me->mvert[v_index]; + const MVert *mv = &ss->mvert[v_index]; /* If the vertex is selected for painting. */ if (!use_vert_sel || mv->flag & SELECT) { @@ -3006,7 +3010,7 @@ static void do_vpaint_brush_blur_loops(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { int p_index = gmap->vert_to_poly[v_index].indices[j]; - const MPoly *mp = &me->mpoly[p_index]; + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { total_hit_loops += mp->totloop; for (int k = 0; k < mp->totloop; k++) { @@ -3040,8 +3044,8 @@ static void do_vpaint_brush_blur_loops(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(me->mloop[l_index].v == v_index); - const MPoly *mp = &me->mpoly[p_index]; + BLI_assert(ss->mloop[l_index].v == v_index); + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ @@ -3122,10 +3126,10 @@ static void do_vpaint_brush_blur_verts(bContext *C, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv = &me->mvert[v_index]; + const MVert *mv = &ss->mvert[v_index]; /* If the vertex is selected for painting. */ if (!use_vert_sel || mv->flag & SELECT) { @@ -3148,12 +3152,12 @@ static void do_vpaint_brush_blur_verts(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { int p_index = gmap->vert_to_poly[v_index].indices[j]; - const MPoly *mp = &me->mpoly[p_index]; + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { total_hit_loops += mp->totloop; for (int k = 0; k < mp->totloop; k++) { const uint l_index = mp->loopstart + k; - const uint v_index = me->mloop[l_index].v; + const uint v_index = ss->mloop[l_index].v; Color *col = lcol + v_index; @@ -3184,9 +3188,9 @@ static void do_vpaint_brush_blur_verts(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; - BLI_assert(me->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index); + BLI_assert(ss->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index); - const MPoly *mp = &me->mpoly[p_index]; + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ @@ -3273,10 +3277,10 @@ static void do_vpaint_brush_smear(bContext *C, if (sculpt_brush_test_sq_fn(&test, vd.co)) { /* For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv_curr = &me->mvert[v_index]; + const MVert *mv_curr = &ss->mvert[v_index]; /* if the vertex is selected for painting. */ if (!use_vert_sel || mv_curr->flag & SELECT) { @@ -3305,15 +3309,15 @@ static void do_vpaint_brush_smear(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(me->mloop[l_index].v == v_index); + BLI_assert(ss->mloop[l_index].v == v_index); UNUSED_VARS_NDEBUG(l_index); - const MPoly *mp = &me->mpoly[p_index]; + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { - const MLoop *ml_other = &me->mloop[mp->loopstart]; + const MLoop *ml_other = &ss->mloop[mp->loopstart]; for (int k = 0; k < mp->totloop; k++, ml_other++) { const uint v_other_index = ml_other->v; if (v_other_index != v_index) { - const MVert *mv_other = &me->mvert[v_other_index]; + const MVert *mv_other = &ss->mvert[v_other_index]; /* Get the direction from the * selected vert to the neighbor. */ @@ -3359,10 +3363,10 @@ static void do_vpaint_brush_smear(bContext *C, else { const int l_index = gmap->vert_to_loop[v_index].indices[j]; elem_index = l_index; - BLI_assert(me->mloop[l_index].v == v_index); + BLI_assert(ss->mloop[l_index].v == v_index); } - const MPoly *mp = &me->mpoly[p_index]; + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { /* Get the previous element color */ Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ @@ -3435,11 +3439,11 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd, BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { /* Test to see if the vertex coordinates are within the spherical brush region. */ if (sculpt_brush_test_sq_fn(&test, vd.co)) { - const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; if (BKE_brush_curve_strength(brush, 0.0, cache->radius) > 0.0) { /* If the vertex is selected for painting. */ - const MVert *mv = &me->mvert[v_index]; + const MVert *mv = &ss->mvert[v_index]; if (!use_vert_sel || mv->flag & SELECT) { accum2->len += gmap->vert_to_loop[v_index].count; /* if a vertex is within the brush region, then add its color to the blend. */ @@ -3555,10 +3559,10 @@ static void vpaint_do_draw(bContext *C, /* NOTE: Grids are 1:1 with corners (aka loops). * For grid based pbvh, take the vert whose loop corresponds to the current grid. * Otherwise, take the current vert. */ - const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv = &me->mvert[v_index]; + const MVert *mv = &ss->mvert[v_index]; /* If the vertex is selected for painting. */ if (!use_vert_sel || mv->flag & SELECT) { @@ -3612,8 +3616,8 @@ static void vpaint_do_draw(bContext *C, for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { const int p_index = gmap->vert_to_poly[v_index].indices[j]; const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(me->mloop[l_index].v == v_index); - const MPoly *mp = &me->mpoly[p_index]; + BLI_assert(ss->mloop[l_index].v == v_index); + const MPoly *mp = &ss->mpoly[p_index]; if (!use_face_sel || mp->flag & ME_FACE_SEL) { Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */ @@ -4084,27 +4088,30 @@ static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, CustomDataLay } else { Color *color_layer = static_cast<Color *>(layer->data); + const Span<MVert> verts = me->vertices(); + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); - const MPoly *mp = me->mpoly; - for (int i = 0; i < me->totpoly; i++, mp++) { - if (use_face_sel && !(mp->flag & ME_FACE_SEL)) { + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + if (use_face_sel && !(poly.flag & ME_FACE_SEL)) { continue; } int j = 0; do { - uint vidx = me->mloop[mp->loopstart + j].v; + uint vidx = loops[poly.loopstart + j].v; - if (!(use_vert_sel && !(me->mvert[vidx].flag & SELECT))) { + if (!(use_vert_sel && !(verts[vidx].flag & SELECT))) { if constexpr (domain == ATTR_DOMAIN_CORNER) { - color_layer[mp->loopstart + j] = paintcol; + color_layer[poly.loopstart + j] = paintcol; } else { color_layer[vidx] = paintcol; } } j++; - } while (j < mp->totloop); + } while (j < poly.totloop); } /* remove stale me->mcol, will be added later */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc index 8b726c7b942..7aa0adfc3d4 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc @@ -50,7 +50,7 @@ static bool vertex_weight_paint_mode_poll(bContext *C) Object *ob = CTX_data_active_object(C); Mesh *me = BKE_mesh_from_object(ob); return (ob && (ELEM(ob->mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT))) && - (me && me->totpoly && me->dvert); + (me && me->totpoly && !me->deform_verts().is_empty()); } static void tag_object_after_update(Object *object) @@ -159,15 +159,15 @@ static IndexMask get_selected_indices(const Mesh &mesh, Vector<int64_t> &indices) { using namespace blender; - Span<MVert> verts(mesh.mvert, mesh.totvert); - Span<MPoly> faces(mesh.mpoly, mesh.totpoly); + Span<MVert> verts = mesh.vertices(); + Span<MPoly> polys = mesh.polygons(); bke::AttributeAccessor attributes = bke::mesh_attributes(mesh); if (mesh.editflag & ME_EDIT_PAINT_FACE_SEL) { const VArray<bool> selection = attributes.adapt_domain( - VArray<bool>::ForFunc(faces.size(), - [&](const int i) { return faces[i].flag & ME_FACE_SEL; }), + VArray<bool>::ForFunc(polys.size(), + [&](const int i) { return polys[i].flag & ME_FACE_SEL; }), ATTR_DOMAIN_FACE, domain); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c index d98660d8939..f40a287adf6 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c @@ -168,8 +168,9 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even ED_view3d_viewcontext_init(C, &vc, depsgraph); me = BKE_mesh_from_object(vc.obact); + const MDeformVert *dvert = BKE_mesh_deform_verts(me); - if (me && me->dvert && vc.v3d && vc.rv3d && (me->vertex_group_active_index != 0)) { + if (me && dvert && vc.v3d && vc.rv3d && (me->vertex_group_active_index != 0)) { const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; int v_idx_best = -1; uint index; @@ -200,7 +201,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even ToolSettings *ts = vc.scene->toolsettings; Brush *brush = BKE_paint_brush(&ts->wpaint->paint); const int vgroup_active = me->vertex_group_active_index - 1; - float vgroup_weight = BKE_defvert_find_weight(&me->dvert[v_idx_best], vgroup_active); + float vgroup_weight = BKE_defvert_find_weight(&dvert[v_idx_best], vgroup_active); const int defbase_tot = BLI_listbase_count(&me->vertex_group_names); bool use_lock_relative = ts->wpaint_lock_relative; bool *defbase_locked = NULL, *defbase_unlocked = NULL; @@ -232,7 +233,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even bool is_normalized = ts->auto_normalize || use_lock_relative; vgroup_weight = BKE_defvert_multipaint_collective_weight( - &me->dvert[v_idx_best], defbase_tot, defbase_sel, defbase_tot_sel, is_normalized); + &dvert[v_idx_best], defbase_tot, defbase_sel, defbase_tot_sel, is_normalized); } MEM_freeN(defbase_sel); @@ -243,7 +244,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even defbase_tot, defbase_locked, defbase_unlocked, defbase_locked, defbase_unlocked); vgroup_weight = BKE_defvert_lock_relative_weight( - vgroup_weight, &me->dvert[v_idx_best], defbase_tot, defbase_locked, defbase_unlocked); + vgroup_weight, &dvert[v_idx_best], defbase_tot, defbase_locked, defbase_unlocked); } MEM_SAFE_FREE(defbase_locked); @@ -316,8 +317,11 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, ED_view3d_viewcontext_init(C, &vc, depsgraph); me = BKE_mesh_from_object(vc.obact); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); + const MDeformVert *dverts = BKE_mesh_deform_verts(me); - if (me && me->dvert && vc.v3d && vc.rv3d && me->vertex_group_names.first) { + if (me && dverts && vc.v3d && vc.rv3d && me->vertex_group_names.first) { const int defbase_tot = BLI_listbase_count(&me->vertex_group_names); const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups"); @@ -334,17 +338,17 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, if (use_vert_sel) { if (ED_mesh_pick_vert(C, vc.obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, true, &index)) { - MDeformVert *dvert = &me->dvert[index]; + const MDeformVert *dvert = &dverts[index]; found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups); } } else { if (ED_mesh_pick_face(C, vc.obact, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) { - const MPoly *mp = &me->mpoly[index]; + const MPoly *mp = &polys[index]; uint fidx = mp->totloop - 1; do { - MDeformVert *dvert = &me->dvert[me->mloop[mp->loopstart + fidx].v]; + const MDeformVert *dvert = &dverts[loops[mp->loopstart + fidx].v]; found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups); } while (fidx--); } @@ -441,7 +445,12 @@ static bool weight_paint_set(Object *ob, float paintweight) /* mutually exclusive, could be made into a */ const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me); - if (me->totpoly == 0 || me->dvert == NULL || !me->mpoly) { + const MVert *verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); + + if (me->totpoly == 0 || dvert == NULL) { return false; } @@ -453,9 +462,9 @@ static bool weight_paint_set(Object *ob, float paintweight) } struct WPaintPrev wpp; - wpaint_prev_create(&wpp, me->dvert, me->totvert); + wpaint_prev_create(&wpp, dvert, me->totvert); - for (index = 0, mp = me->mpoly; index < me->totpoly; index++, mp++) { + for (index = 0, mp = polys; index < me->totpoly; index++, mp++) { uint fidx = mp->totloop - 1; if ((paint_selmode == SCE_SELECT_FACE) && !(mp->flag & ME_FACE_SEL)) { @@ -463,14 +472,14 @@ static bool weight_paint_set(Object *ob, float paintweight) } do { - uint vidx = me->mloop[mp->loopstart + fidx].v; + uint vidx = loops[mp->loopstart + fidx].v; - if (!me->dvert[vidx].flag) { - if ((paint_selmode == SCE_SELECT_VERTEX) && !(me->mvert[vidx].flag & SELECT)) { + if (!dvert[vidx].flag) { + if ((paint_selmode == SCE_SELECT_VERTEX) && !(verts[vidx].flag & SELECT)) { continue; } - dw = BKE_defvert_ensure_index(&me->dvert[vidx], vgroup_active); + dw = BKE_defvert_ensure_index(&dvert[vidx], vgroup_active); if (dw) { dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + vidx, vgroup_active); dw_prev->weight = dw->weight; /* set the undo weight */ @@ -482,11 +491,11 @@ static bool weight_paint_set(Object *ob, float paintweight) if (j >= 0) { /* copy, not paint again */ if (vgroup_mirror != -1) { - dw = BKE_defvert_ensure_index(me->dvert + j, vgroup_mirror); + dw = BKE_defvert_ensure_index(dvert + j, vgroup_mirror); dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + j, vgroup_mirror); } else { - dw = BKE_defvert_ensure_index(me->dvert + j, vgroup_active); + dw = BKE_defvert_ensure_index(dvert + j, vgroup_active); dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + j, vgroup_active); } dw_prev->weight = dw->weight; /* set the undo weight */ @@ -494,14 +503,14 @@ static bool weight_paint_set(Object *ob, float paintweight) } } } - me->dvert[vidx].flag = 1; + dvert[vidx].flag = 1; } } while (fidx--); } { - MDeformVert *dv = me->dvert; + MDeformVert *dv = dvert; for (index = me->totvert; index != 0; index--, dv++) { dv->flag = 0; } @@ -574,6 +583,7 @@ typedef struct WPGradient_userData { struct ARegion *region; Scene *scene; Mesh *me; + MDeformVert *dvert; Brush *brush; const float *sco_start; /* [2] */ const float *sco_end; /* [2] */ @@ -593,7 +603,6 @@ typedef struct WPGradient_userData { static void gradientVert_update(WPGradient_userData *grad_data, int index) { - Mesh *me = grad_data->me; WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; /* Optionally restrict to assigned vertices only. */ @@ -617,7 +626,7 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index) alpha = BKE_brush_curve_strength_clamped(grad_data->brush, alpha, 1.0f); if (alpha != 0.0f) { - MDeformVert *dv = &me->dvert[index]; + MDeformVert *dv = &grad_data->dvert[index]; MDeformWeight *dw = BKE_defvert_ensure_index(dv, grad_data->def_nr); // dw->weight = alpha; // testing int tool = grad_data->brush->blend; @@ -631,7 +640,7 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index) vs->flag |= VGRAD_STORE_IS_MODIFIED; } else { - MDeformVert *dv = &me->dvert[index]; + MDeformVert *dv = &grad_data->dvert[index]; if (vs->flag & VGRAD_STORE_DW_EXIST) { /* normally we NULL check, but in this case we know it exists */ MDeformWeight *dw = BKE_defvert_find_index(dv, grad_data->def_nr); @@ -669,10 +678,9 @@ static void gradientVertInit__mapFunc(void *userData, const float UNUSED(no[3])) { WPGradient_userData *grad_data = userData; - Mesh *me = grad_data->me; WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; - if (grad_data->use_select && !(me->mvert[index].flag & SELECT)) { + if (grad_data->use_select && !(grad_data->dvert[index].flag & SELECT)) { copy_v2_fl(vs->sco, FLT_MAX); return; } @@ -693,7 +701,7 @@ static void gradientVertInit__mapFunc(void *userData, return; } - MDeformVert *dv = &me->dvert[index]; + MDeformVert *dv = &grad_data->dvert[index]; const MDeformWeight *dw = BKE_defvert_find_index(dv, grad_data->def_nr); if (dw) { vs->weight_orig = dw->weight; @@ -727,8 +735,9 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven if (vert_cache != NULL) { Mesh *me = ob->data; if (vert_cache->wpp.wpaint_prev) { - BKE_defvert_array_free_elems(me->dvert, me->totvert); - BKE_defvert_array_copy(me->dvert, vert_cache->wpp.wpaint_prev, me->totvert); + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); + BKE_defvert_array_free_elems(dvert, me->totvert); + BKE_defvert_array_copy(dvert, vert_cache->wpp.wpaint_prev, me->totvert); wpaint_prev_destroy(&vert_cache->wpp); } MEM_freeN(vert_cache); @@ -753,6 +762,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Mesh *me = ob->data; + MDeformVert *dverts = BKE_mesh_deform_verts_for_write(me); int x_start = RNA_int_get(op->ptr, "xstart"); int y_start = RNA_int_get(op->ptr, "ystart"); int x_end = RNA_int_get(op->ptr, "xend"); @@ -774,7 +784,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) data.is_init = true; wpaint_prev_create( - &((WPGradient_vertStoreBase *)gesture->user_data.data)->wpp, me->dvert, me->totvert); + &((WPGradient_vertStoreBase *)gesture->user_data.data)->wpp, dverts, me->totvert); /* On initialization only, convert face -> vert sel. */ if (me->editflag & ME_EDIT_PAINT_FACE_SEL) { @@ -797,6 +807,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) data.region = region; data.scene = scene; data.me = ob->data; + data.dvert = dverts; data.sco_start = sco_start; data.sco_end = sco_end; data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end); @@ -851,7 +862,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) const int vgroup_num = BLI_listbase_count(&me->vertex_group_names); bool *vgroup_validmap = BKE_object_defgroup_validmap_get(ob, vgroup_num); if (vgroup_validmap != NULL) { - MDeformVert *dvert = me->dvert; + MDeformVert *dvert = dverts; for (int i = 0; i < me->totvert; i++) { if ((data.vert_cache->elem[i].flag & VGRAD_STORE_IS_MODIFIED) != 0) { BKE_defvert_normalize_lock_single(&dvert[i], vgroup_validmap, vgroup_num, data.def_nr); diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c index 5a63af4149a..ac16631f115 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c @@ -59,7 +59,7 @@ bool ED_wpaint_ensure_data(bContext *C, } /* if nothing was added yet, we make dverts and a vertex deform group */ - if (!me->dvert) { + if (BKE_mesh_deform_verts(me) == NULL) { BKE_object_defgroup_data_create(&me->id); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a56755edf92..74fd2f904e5 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -600,10 +600,10 @@ void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss) { if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { for (int i = 0; i < ss->totfaces; i++) { - MPoly *poly = &ss->mpoly[i]; + const MPoly *poly = &ss->mpoly[i]; bool poly_visible = true; for (int l = 0; l < poly->totloop; l++) { - MLoop *loop = &ss->mloop[poly->loopstart + l]; + const MLoop *loop = &ss->mloop[poly->loopstart + l]; if (!SCULPT_vertex_visible_get(ss, BKE_pbvh_make_vref(loop->v))) { poly_visible = false; } @@ -644,9 +644,9 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss MeshElemMap *vert_map = &ss->pmap[v1]; int p1 = -1, p2 = -1; for (int i = 0; i < ss->pmap[v1].count; i++) { - MPoly *p = &ss->mpoly[vert_map->indices[i]]; + const MPoly *p = &ss->mpoly[vert_map->indices[i]]; for (int l = 0; l < p->totloop; l++) { - MLoop *loop = &ss->mloop[p->loopstart + l]; + const MLoop *loop = &ss->mloop[p->loopstart + l]; if (loop->v == v2) { if (p1 == -1) { p1 = vert_map->indices[i]; @@ -3162,10 +3162,10 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) /* Modifying of basis key should update mesh. */ if (kb == me->key->refkey) { - MVert *mvert = me->mvert; + MVert *verts = BKE_mesh_vertices_for_write(me); - for (a = 0; a < me->totvert; a++, mvert++) { - copy_v3_v3(mvert->co, vertCos[a]); + for (a = 0; a < me->totvert; a++) { + copy_v3_v3(verts[a].co, vertCos[a]); } BKE_mesh_tag_coords_changed(me); } @@ -3589,8 +3589,9 @@ static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd) copy_v3_v3(ss->deform_cos[index], vd->co); copy_v3_v3(ss->orig_cos[index], newco); + MVert *verts = BKE_mesh_vertices_for_write(me); if (!ss->shapekey_active) { - copy_v3_v3(me->mvert[index].co, newco); + copy_v3_v3(verts[index].co, newco); } } @@ -5908,21 +5909,25 @@ void SCULPT_boundary_info_ensure(Object *object) } Mesh *base_mesh = BKE_mesh_from_object(object); + const MEdge *edges = BKE_mesh_edges(base_mesh); + const MPoly *polys = BKE_mesh_polygons(base_mesh); + const MLoop *loops = BKE_mesh_loops(base_mesh); + ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info"); int *adjacent_faces_edge_count = MEM_calloc_arrayN( base_mesh->totedge, sizeof(int), "Adjacent face edge count"); for (int p = 0; p < base_mesh->totpoly; p++) { - MPoly *poly = &base_mesh->mpoly[p]; + const MPoly *poly = &polys[p]; for (int l = 0; l < poly->totloop; l++) { - MLoop *loop = &base_mesh->mloop[l + poly->loopstart]; + const MLoop *loop = &loops[l + poly->loopstart]; adjacent_faces_edge_count[loop->e]++; } } for (int e = 0; e < base_mesh->totedge; e++) { if (adjacent_faces_edge_count[e] < 2) { - MEdge *edge = &base_mesh->medge[e]; + const MEdge *edge = &edges[e]; BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v1, true); BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v2, true); } diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c index 000b69cc2ba..ad8a1cde9dc 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c @@ -210,8 +210,6 @@ static void SCULPT_dynamic_topology_disable_ex( &geometry->ldata, &me->ldata, CD_MASK_MESH.lmask, CD_DUPLICATE, geometry->totloop); CustomData_copy( &geometry->pdata, &me->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly); - - BKE_mesh_update_customdata_pointers(me, false); } else { BKE_sculptsession_bm_to_me(ob, true); diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index 75cc966c0b2..63d5c14a931 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -690,7 +690,6 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR } /* Propagate the falloff increasing the value by 1 each time a new vertex is visited. */ - Mesh *mesh = ob->data; while (!BLI_gsqueue_is_empty(queue)) { PBVHVertRef v_next; BLI_gsqueue_pop(queue, &v_next); @@ -698,9 +697,9 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next); for (int j = 0; j < ss->pmap[v_next_i].count; j++) { - MPoly *p = &ss->mpoly[ss->pmap[v_next_i].indices[j]]; + const MPoly *p = &ss->mpoly[ss->pmap[v_next_i].indices[j]]; for (int l = 0; l < p->totloop; l++) { - const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(mesh->mloop[p->loopstart + l].v); + const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(ss->mloop[p->loopstart + l].v); if (BLI_BITMAP_TEST(visited_vertices, neighbor_v.i)) { continue; } @@ -777,11 +776,11 @@ static void sculpt_expand_grids_to_faces_falloff(SculptSession *ss, Mesh *mesh, ExpandCache *expand_cache) { - + const MPoly *polys = BKE_mesh_polygons(mesh); const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); for (int p = 0; p < mesh->totpoly; p++) { - MPoly *poly = &mesh->mpoly[p]; + const MPoly *poly = &polys[p]; float accum = 0.0f; for (int l = 0; l < poly->totloop; l++) { const int grid_loop_index = (poly->loopstart + l) * key->grid_area; @@ -795,11 +794,14 @@ static void sculpt_expand_grids_to_faces_falloff(SculptSession *ss, static void sculpt_expand_vertex_to_faces_falloff(Mesh *mesh, ExpandCache *expand_cache) { + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); + for (int p = 0; p < mesh->totpoly; p++) { - MPoly *poly = &mesh->mpoly[p]; + const MPoly *poly = &polys[p]; float accum = 0.0f; for (int l = 0; l < poly->totloop; l++) { - MLoop *loop = &mesh->mloop[l + poly->loopstart]; + const MLoop *loop = &loops[l + poly->loopstart]; accum += expand_cache->vert_falloff[loop->v]; } expand_cache->face_falloff[p] = accum / poly->totloop; @@ -1093,10 +1095,10 @@ static void sculpt_expand_snap_initialize_from_enabled(SculptSession *ss, } for (int p = 0; p < totface; p++) { - MPoly *poly = &ss->mpoly[p]; + const MPoly *poly = &ss->mpoly[p]; bool any_disabled = false; for (int l = 0; l < poly->totloop; l++) { - MLoop *loop = &ss->mloop[l + poly->loopstart]; + const MLoop *loop = &ss->mloop[l + poly->loopstart]; if (!BLI_BITMAP_TEST(enabled_vertices, loop->v)) { any_disabled = true; break; @@ -1938,6 +1940,8 @@ static void sculpt_expand_delete_face_set_id(int *r_face_sets, { const int totface = ss->totfaces; MeshElemMap *pmap = ss->pmap; + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); /* Check that all the face sets IDs in the mesh are not equal to `delete_id` * before attempting to delete it. */ @@ -1972,9 +1976,9 @@ static void sculpt_expand_delete_face_set_id(int *r_face_sets, while (BLI_LINKSTACK_SIZE(queue)) { const int f_index = POINTER_AS_INT(BLI_LINKSTACK_POP(queue)); int other_id = delete_id; - const MPoly *c_poly = &mesh->mpoly[f_index]; + const MPoly *c_poly = &polys[f_index]; for (int l = 0; l < c_poly->totloop; l++) { - const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; + const MLoop *c_loop = &loops[c_poly->loopstart + l]; const MeshElemMap *vert_map = &pmap[c_loop->v]; for (int i = 0; i < vert_map->count; i++) { diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index a2a34566bb6..c8e546ecef3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -1096,13 +1096,16 @@ static void sculpt_face_set_grow(Object *ob, const bool modify_hidden) { Mesh *mesh = BKE_mesh_from_object(ob); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); + for (int p = 0; p < mesh->totpoly; p++) { if (!modify_hidden && prev_face_sets[p] <= 0) { continue; } - const MPoly *c_poly = &mesh->mpoly[p]; + const MPoly *c_poly = &polys[p]; for (int l = 0; l < c_poly->totloop; l++) { - const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; + const MLoop *c_loop = &loops[c_poly->loopstart + l]; const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; for (int i = 0; i < vert_map->count; i++) { const int neighbor_face_index = vert_map->indices[i]; @@ -1124,14 +1127,16 @@ static void sculpt_face_set_shrink(Object *ob, const bool modify_hidden) { Mesh *mesh = BKE_mesh_from_object(ob); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); for (int p = 0; p < mesh->totpoly; p++) { if (!modify_hidden && prev_face_sets[p] <= 0) { continue; } if (abs(prev_face_sets[p]) == active_face_set_id) { - const MPoly *c_poly = &mesh->mpoly[p]; + const MPoly *c_poly = &polys[p]; for (int l = 0; l < c_poly->totloop; l++) { - const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; + const MLoop *c_loop = &loops[c_poly->loopstart + l]; const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; for (int i = 0; i < vert_map->count; i++) { const int neighbor_face_index = vert_map->indices[i]; diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c index ecf8c4586ae..4b871da1d02 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c @@ -37,7 +37,6 @@ #include "DEG_depsgraph.h" #include "WM_api.h" -#include "WM_message.h" #include "WM_toolsystem.h" #include "WM_types.h" @@ -108,8 +107,10 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, const float limit_radius_sq = limit_radius * limit_radius; - MEdge *edges = mesh->medge; MVert *verts = SCULPT_mesh_deformed_mverts_get(ss); + const MEdge *edges = BKE_mesh_edges(mesh); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "distances"); BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag"); @@ -117,16 +118,15 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, if (!ss->epmap) { BKE_mesh_edge_poly_map_create(&ss->epmap, &ss->epmap_mem, - mesh->medge, + edges, mesh->totedge, - mesh->mpoly, + polys, mesh->totpoly, - mesh->mloop, + loops, mesh->totloop); } if (!ss->vemap) { - BKE_mesh_vert_edge_map_create( - &ss->vemap, &ss->vemap_mem, mesh->medge, mesh->totvert, mesh->totedge); + BKE_mesh_vert_edge_map_create(&ss->vemap, &ss->vemap_mem, edges, mesh->totvert, mesh->totedge); } /* Both contain edge indices encoded as *void. */ @@ -202,10 +202,10 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, if (ss->face_sets[poly] <= 0) { continue; } - const MPoly *mpoly = &mesh->mpoly[poly]; + const MPoly *mpoly = &polys[poly]; for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) { - const MLoop *mloop = &mesh->mloop[loop_index + mpoly->loopstart]; + const MLoop *mloop = &loops[loop_index + mpoly->loopstart]; const int v_other = mloop->v; if (ELEM(v_other, v1, v2)) { continue; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index e667f9ce2fc..07dbb5964bf 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -627,8 +627,6 @@ static void sculpt_undo_geometry_restore_data(SculptUndoNodeGeometry *geometry, CustomData_copy( &geometry->pdata, &mesh->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly); - BKE_mesh_update_customdata_pointers(mesh, false); - BKE_mesh_runtime_clear_cache(mesh); } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 68f172169f4..3c79e66f436 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -168,45 +168,49 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values( else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) { const MeshComponent &component = static_cast<const MeshComponent &>(*component_); if (const Mesh *mesh = component.get_for_read()) { + const Span<MEdge> edges = mesh->edges(); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); + if (domain_ == ATTR_DOMAIN_EDGE) { if (STREQ(column_id.name, "Vertex 1")) { return std::make_unique<ColumnValues>( - column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) { - return mesh->medge[index].v1; + column_id.name, VArray<int>::ForFunc(edges.size(), [edges](int64_t index) { + return edges[index].v1; })); } if (STREQ(column_id.name, "Vertex 2")) { return std::make_unique<ColumnValues>( - column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) { - return mesh->medge[index].v2; + column_id.name, VArray<int>::ForFunc(edges.size(), [edges](int64_t index) { + return edges[index].v2; })); } } else if (domain_ == ATTR_DOMAIN_FACE) { if (STREQ(column_id.name, "Corner Start")) { return std::make_unique<ColumnValues>( - column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) { - return mesh->mpoly[index].loopstart; + column_id.name, VArray<int>::ForFunc(polys.size(), [polys](int64_t index) { + return polys[index].loopstart; })); } if (STREQ(column_id.name, "Corner Size")) { return std::make_unique<ColumnValues>( - column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) { - return mesh->mpoly[index].totloop; + column_id.name, VArray<int>::ForFunc(polys.size(), [polys](int64_t index) { + return polys[index].totloop; })); } } else if (domain_ == ATTR_DOMAIN_CORNER) { if (STREQ(column_id.name, "Vertex")) { return std::make_unique<ColumnValues>( - column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) { - return mesh->mloop[index].v; + column_id.name, VArray<int>::ForFunc(loops.size(), [loops](int64_t index) { + return loops[index].v; })); } if (STREQ(column_id.name, "Edge")) { return std::make_unique<ColumnValues>( - column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) { - return mesh->mloop[index].e; + column_id.name, VArray<int>::ForFunc(loops.size(), [loops](int64_t index) { + return loops[index].e; })); } } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 8add6886584..2019ff28e33 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -16,6 +16,7 @@ #include "BKE_customdata.h" #include "BKE_editmesh.h" #include "BKE_global.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "DEG_depsgraph.h" @@ -67,9 +68,9 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, if (facemap_data) { GPU_blend(GPU_BLEND_ALPHA); - const MVert *mvert = me->mvert; - const MPoly *mpoly = me->mpoly; - const MLoop *mloop = me->mloop; + const MVert *verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); int mpoly_len = me->totpoly; int mloop_len = me->totloop; @@ -95,12 +96,12 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, int i; if (me->runtime.looptris.array) { const MLoopTri *mlt = me->runtime.looptris.array; - for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) { + for (mp = polys, i = 0; i < mpoly_len; i++, mp++) { if (facemap_data[i] == facemap) { for (int j = 2; j < mp->totloop; j++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[0]].v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[1]].v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[2]].v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[0]].v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[1]].v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[2]].v].co); vbo_len_used += 3; mlt++; } @@ -112,15 +113,15 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, } else { /* No tessellation data, fan-fill. */ - for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) { + for (mp = polys, i = 0; i < mpoly_len; i++, mp++) { if (facemap_data[i] == facemap) { - const MLoop *ml_start = &mloop[mp->loopstart]; + const MLoop *ml_start = &loops[mp->loopstart]; const MLoop *ml_a = ml_start + 1; const MLoop *ml_b = ml_start + 2; for (int j = 2; j < mp->totloop; j++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_start->v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_a->v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_b->v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_start->v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_a->v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_b->v].co); vbo_len_used += 3; ml_a++; diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 6256eeb9621..4d5068c45ad 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -23,6 +23,7 @@ #include "BKE_curve.h" #include "BKE_displist.h" #include "BKE_editmesh.h" +#include "BKE_mesh.h" #include "BKE_mesh_iterators.h" #include "BKE_mesh_runtime.h" #include "BKE_mesh_wrapper.h" @@ -205,6 +206,7 @@ typedef struct foreachScreenObjectVert_userData { void (*func)(void *userData, MVert *mv, const float screen_co[2], int index); void *userData; ViewContext vc; + MVert *verts; const bool *hide_vert; eV3DProjTest clip_flag; } foreachScreenObjectVert_userData; @@ -266,7 +268,7 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData, if (data->hide_vert && data->hide_vert[index]) { return; } - struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index]; + MVert *mv = &data->verts[index]; float screen_co[2]; @@ -299,6 +301,7 @@ void meshobject_foreachScreenVert( data.func = func; data.userData = userData; data.clip_flag = clip_flag; + data.verts = BKE_mesh_vertices_for_write((Mesh *)vc->obact->data); data.hide_vert = (const bool *)CustomData_get_layer_named( &me->vdata, CD_PROP_BOOL, ".hide_vert"); diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index f757cb45eec..714eff79777 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -334,7 +334,8 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me, EditSelectBuf_Cache *esel, const eSelectOp sel_op) { - MVert *mv = me->mvert; + MVert *verts = BKE_mesh_vertices_for_write(me); + MVert *mv = verts; bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; @@ -363,22 +364,22 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me, EditSelectBuf_Cache *esel, const eSelectOp sel_op) { - MPoly *mpoly = me->mpoly; + MPoly *polygons = BKE_mesh_polygons_for_write(me); bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - if (mpoly) { + if (polygons) { const bool *hide_poly = (const bool *)CustomData_get_layer_named( - &me->pdata, CD_PROP_BOOL, ".hide_poly"); + &me->vdata, CD_PROP_BOOL, ".hide_poly"); - for (int index = 0; index < me->totpoly; index++, mpoly++) { + for (int index = 0; index < me->totpoly; index++) { if (!(hide_poly && hide_poly[index])) { - const bool is_select = mpoly->flag & ME_FACE_SEL; + const bool is_select = polygons[index].flag & ME_FACE_SEL; const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index); const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); if (sel_op_result != -1) { - SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL); + SET_FLAG_FROM_TEST(polygons[index].flag, sel_op_result, ME_FACE_SEL); changed = true; } } @@ -2813,13 +2814,15 @@ static bool ed_wpaint_vertex_select_pick(bContext *C, Mesh *me = static_cast<Mesh *>(obact->data); /* already checked for nullptr */ uint index = 0; + MVert *verts = BKE_mesh_vertices_for_write(me); + MVert *mv; bool changed = false; bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index); if (params->sel_op == SEL_OP_SET) { - if ((found && params->select_passthrough) && (me->mvert[index].flag & SELECT)) { + if ((found && params->select_passthrough) && (verts[index].flag & SELECT)) { found = false; } else if (found || params->deselect_all) { @@ -2829,7 +2832,7 @@ static bool ed_wpaint_vertex_select_pick(bContext *C, } if (found) { - mv = &me->mvert[index]; + mv = &verts[index]; switch (params->sel_op) { case SEL_OP_ADD: { mv->flag |= SELECT; diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 6808f06bdd3..e4c152bc630 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -47,6 +47,7 @@ using blender::float3; using blender::float4x4; using blender::Map; +using blender::Span; /* -------------------------------------------------------------------- */ /** \name Internal Data Types @@ -243,6 +244,11 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, SnapData_Mesh *sod; bool init = false; + const Span<MVert> verts = me_eval->vertices(); + const Span<MEdge> edges = me_eval->edges(); + const Span<MPoly> polys = me_eval->polygons(); + const Span<MLoop> loops = me_eval->loops(); + if (std::unique_ptr<SnapData_Mesh> *sod_p = sctx->mesh_caches.lookup_ptr(ob_eval)) { sod = sod_p->get(); bool is_dirty = false; @@ -264,16 +270,16 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, else if (sod->treedata_mesh.looptri != me_eval->runtime.looptris.array) { is_dirty = true; } - else if (sod->treedata_mesh.vert != me_eval->mvert) { + else if (sod->treedata_mesh.vert != verts.data()) { is_dirty = true; } - else if (sod->treedata_mesh.loop != me_eval->mloop) { + else if (sod->treedata_mesh.loop != loops.data()) { is_dirty = true; } - else if (sod->treedata_mesh.edge != me_eval->medge) { + else if (sod->treedata_mesh.edge != edges.data()) { is_dirty = true; } - else if (sod->poly != me_eval->mpoly) { + else if (sod->poly != polys.data()) { is_dirty = true; } @@ -303,16 +309,16 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx, use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI, 4); - BLI_assert(sod->treedata_mesh.vert == me_eval->mvert); - BLI_assert(!me_eval->mvert || sod->treedata_mesh.vert_normals); - BLI_assert(sod->treedata_mesh.loop == me_eval->mloop); - BLI_assert(!me_eval->mpoly || sod->treedata_mesh.looptri); + BLI_assert(sod->treedata_mesh.vert == verts.data()); + BLI_assert(!verts.data() || sod->treedata_mesh.vert_normals); + BLI_assert(sod->treedata_mesh.loop == loops.data()); + BLI_assert(!polys.data() || sod->treedata_mesh.looptri); sod->has_looptris = sod->treedata_mesh.tree != nullptr; /* Required for snapping with occlusion. */ - sod->treedata_mesh.edge = me_eval->medge; - sod->poly = me_eval->mpoly; + sod->treedata_mesh.edge = edges.data(); + sod->poly = polys.data(); /* Start assuming that it has each of these element types. */ sod->has_loose_edge = true; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index f82d6f6164b..1aa3f2cc54a 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -14,6 +14,8 @@ #include <sstream> +using blender::Span; + namespace Freestyle { BlenderFileLoader::BlenderFileLoader(Render *re, ViewLayer *view_layer, Depsgraph *depsgraph) @@ -378,9 +380,12 @@ int BlenderFileLoader::testDegenerateTriangle(float v1[3], float v2[3], float v3 static bool testEdgeMark(Mesh *me, const FreestyleEdge *fed, const MLoopTri *lt, int i) { - MLoop *mloop = &me->mloop[lt->tri[i]]; - MLoop *mloop_next = &me->mloop[lt->tri[(i + 1) % 3]]; - MEdge *medge = &me->medge[mloop->e]; + const Span<MEdge> edges = me->edges(); + const Span<MLoop> loops = me->loops(); + + const MLoop *mloop = &loops[lt->tri[i]]; + const MLoop *mloop_next = &loops[lt->tri[(i + 1) % 3]]; + const MEdge *medge = &edges[mloop->e]; if (!ELEM(mloop_next->v, medge->v1, medge->v2)) { /* Not an edge in the original mesh before triangulation. */ @@ -394,10 +399,15 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) { char *name = ob->id.name + 2; + const Span<MVert> mesh_verts = me->vertices(); + const Span<MPoly> mesh_polys = me->polygons(); + const Span<MLoop> mesh_loops = me->loops(); + // Compute loop triangles int tottri = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *mlooptri = (MLoopTri *)MEM_malloc_arrayN(tottri, sizeof(*mlooptri), __func__); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri); + BKE_mesh_recalc_looptri( + mesh_loops.data(), mesh_polys.data(), mesh_verts.data(), me->totloop, me->totpoly, mlooptri); // Compute loop normals BKE_mesh_calc_normals_split(me); @@ -408,9 +418,6 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) } // Get other mesh data - MVert *mvert = me->mvert; - MLoop *mloop = me->mloop; - MPoly *mpoly = me->mpoly; const FreestyleEdge *fed = (FreestyleEdge *)CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE); const FreestyleFace *ffa = (FreestyleFace *)CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE); @@ -435,9 +442,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) for (int a = 0; a < tottri; a++) { const MLoopTri *lt = &mlooptri[a]; - copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co); - copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co); - copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co); + copy_v3_v3(v1, mesh_verts[mesh_loops[lt->tri[0]].v].co); + copy_v3_v3(v2, mesh_verts[mesh_loops[lt->tri[1]].v].co); + copy_v3_v3(v3, mesh_verts[mesh_loops[lt->tri[2]].v].co); mul_m4_v3(obmat, v1); mul_m4_v3(obmat, v2); @@ -506,12 +513,12 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) // by the near and far view planes. for (int a = 0; a < tottri; a++) { const MLoopTri *lt = &mlooptri[a]; - const MPoly *mp = &mpoly[lt->poly]; + const MPoly *mp = &mesh_polys[lt->poly]; Material *mat = BKE_object_material_get(ob, material_indices[lt->poly] + 1); - copy_v3_v3(v1, mvert[mloop[lt->tri[0]].v].co); - copy_v3_v3(v2, mvert[mloop[lt->tri[1]].v].co); - copy_v3_v3(v3, mvert[mloop[lt->tri[2]].v].co); + copy_v3_v3(v1, mesh_verts[mesh_loops[lt->tri[0]].v].co); + copy_v3_v3(v2, mesh_verts[mesh_loops[lt->tri[1]].v].co); + copy_v3_v3(v3, mesh_verts[mesh_loops[lt->tri[2]].v].co); mul_m4_v3(obmat, v1); mul_m4_v3(obmat, v2); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index dd041abfd1f..0b035a08433 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -576,36 +576,28 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) mesh->totloop = group->totloop; mesh->totcol = group->materials.size(); - mesh->mvert = (MVert *)CustomData_add_layer( + MVert *vertices = (MVert *)CustomData_add_layer( &mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert); - mesh->medge = (MEdge *)CustomData_add_layer( + MEdge *edges = (MEdge *)CustomData_add_layer( &mesh->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, mesh->totedge); - mesh->mpoly = (MPoly *)CustomData_add_layer( + MPoly *polys = (MPoly *)CustomData_add_layer( &mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, mesh->totpoly); - mesh->mloop = (MLoop *)CustomData_add_layer( + MLoop *loops = (MLoop *)CustomData_add_layer( &mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, mesh->totloop); int *material_indices = (int *)CustomData_add_layer_named( &mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, mesh->totpoly, "material_index"); - MVert *vertices = mesh->mvert; - MEdge *edges = mesh->medge; - MPoly *polys = mesh->mpoly; - MLoop *loops = mesh->mloop; MLoopUV *loopsuv[2] = {nullptr}; if (hasTex) { // First UV layer - CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[0]); + loopsuv[0] = static_cast<MLoopUV *>(CustomData_add_layer_named( + &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[0])); CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0); - BKE_mesh_update_customdata_pointers(mesh, true); - loopsuv[0] = mesh->mloopuv; // Second UV layer - CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[1]); + loopsuv[1] = static_cast<MLoopUV *>(CustomData_add_layer_named( + &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[1])); CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1); - BKE_mesh_update_customdata_pointers(mesh, true); - loopsuv[1] = mesh->mloopuv; } // colors and transparency (the latter represented by grayscale colors) @@ -613,7 +605,7 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) &mesh->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, mesh->totloop, "Color"); MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named( &mesh->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, mesh->totloop, "Alpha"); - mesh->mloopcol = colors; + CustomData_set_layer_active(&mesh->ldata, CD_PROP_BYTE_COLOR, 0); mesh->mat = (Material **)MEM_mallocN(sizeof(Material *) * mesh->totcol, "MaterialList"); for (const auto item : group->materials.items()) { diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index 7f269578f5d..7490694bf12 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -4,6 +4,7 @@ #include "BLI_task.hh" #include "BKE_attribute_math.hh" +#include "BKE_mesh.h" #include "BKE_mesh_sample.hh" #include "GEO_add_curves_on_mesh.hh" @@ -244,6 +245,8 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, Vector<float2> used_uvs; /* Find faces that the passed in uvs belong to. */ + const Span<MVert> surface_verts = inputs.surface->vertices(); + const Span<MLoop> surface_loops = inputs.surface->loops(); for (const int i : inputs.uvs.index_range()) { const float2 &uv = inputs.uvs[i]; const ReverseUVSampler::Result result = inputs.reverse_uv_sampler->sample(uv); @@ -256,9 +259,9 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, looptris.append(&looptri); const float3 root_position_su = attribute_math::mix3<float3>( result.bary_weights, - inputs.surface->mvert[inputs.surface->mloop[looptri.tri[0]].v].co, - inputs.surface->mvert[inputs.surface->mloop[looptri.tri[1]].v].co, - inputs.surface->mvert[inputs.surface->mloop[looptri.tri[2]].v].co); + surface_verts[surface_loops[looptri.tri[0]].v].co, + surface_verts[surface_loops[looptri.tri[1]].v].co, + surface_verts[surface_loops[looptri.tri[2]].v].co); root_positions_cu.append(inputs.transforms->surface_to_curves * root_position_su); used_uvs.append(uv); } diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index d3a5a194555..ad39f686dd4 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1164,26 +1164,26 @@ static void weld_mesh_context_create(const Mesh &mesh, const int vert_kill_len, WeldMesh *r_weld_mesh) { - Span<MEdge> medge{mesh.medge, mesh.totedge}; - Span<MPoly> mpoly{mesh.mpoly, mesh.totpoly}; - Span<MLoop> mloop{mesh.mloop, mesh.totloop}; const int mvert_len = mesh.totvert; + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); Vector<WeldVert> wvert = weld_vert_ctx_alloc_and_setup(vert_dest_map, vert_kill_len); r_weld_mesh->vert_kill_len = vert_kill_len; - Array<int> edge_dest_map(medge.size()); - Array<int> edge_ctx_map(medge.size()); - Vector<WeldEdge> wedge = weld_edge_ctx_alloc(medge, vert_dest_map, edge_dest_map, edge_ctx_map); + Array<int> edge_dest_map(edges.size()); + Array<int> edge_ctx_map(edges.size()); + Vector<WeldEdge> wedge = weld_edge_ctx_alloc(edges, vert_dest_map, edge_dest_map, edge_ctx_map); Array<WeldGroup> v_links(mvert_len, {0, 0}); weld_edge_ctx_setup(v_links, edge_dest_map, wedge, &r_weld_mesh->edge_kill_len); - weld_poly_loop_ctx_alloc(mpoly, mloop, vert_dest_map, edge_dest_map, r_weld_mesh); + weld_poly_loop_ctx_alloc(polys, loops, vert_dest_map, edge_dest_map, r_weld_mesh); - weld_poly_loop_ctx_setup(mloop, + weld_poly_loop_ctx_setup(loops, #ifdef USE_WELD_DEBUG - mpoly, + polys, #endif mvert_len, @@ -1198,7 +1198,7 @@ static void weld_mesh_context_create(const Mesh &mesh, r_weld_mesh->vert_groups_buffer, r_weld_mesh->vert_groups); - weld_edge_groups_setup(medge.size(), + weld_edge_groups_setup(edges.size(), r_weld_mesh->edge_kill_len, wedge, edge_ctx_map, @@ -1360,23 +1360,24 @@ static Mesh *create_merged_mesh(const Mesh &mesh, MutableSpan<int> vert_dest_map, const int removed_vertex_count) { - Span<MPoly> mpoly{mesh.mpoly, mesh.totpoly}; - Span<MLoop> mloop{mesh.mloop, mesh.totloop}; + const Span<MPoly> src_polys = mesh.polygons(); + const Span<MLoop> src_loops = mesh.loops(); const int totvert = mesh.totvert; const int totedge = mesh.totedge; - const int totloop = mesh.totloop; - const int totpoly = mesh.totpoly; WeldMesh weld_mesh; weld_mesh_context_create(mesh, vert_dest_map, removed_vertex_count, &weld_mesh); const int result_nverts = totvert - weld_mesh.vert_kill_len; const int result_nedges = totedge - weld_mesh.edge_kill_len; - const int result_nloops = totloop - weld_mesh.loop_kill_len; - const int result_npolys = totpoly - weld_mesh.poly_kill_len + weld_mesh.wpoly_new_len; + const int result_nloops = src_loops.size() - weld_mesh.loop_kill_len; + const int result_npolys = src_polys.size() - weld_mesh.poly_kill_len + weld_mesh.wpoly_new_len; Mesh *result = BKE_mesh_new_nomain_from_template( &mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys); + MutableSpan<MEdge> dst_edges = result->edges_for_write(); + MutableSpan<MPoly> dst_polys = result->polygons_for_write(); + MutableSpan<MLoop> dst_loops = result->loops_for_write(); /* Vertices. */ @@ -1431,7 +1432,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh, } if (count) { CustomData_copy_data(&mesh.edata, &result->edata, source_index, dest_index, count); - MEdge *me = &result->medge[dest_index]; + MEdge *me = &dst_edges[dest_index]; dest_index += count; for (; count--; me++) { me->v1 = vert_final[me->v1]; @@ -1448,7 +1449,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh, &weld_mesh.edge_groups_buffer[wegrp->group.ofs], wegrp->group.len, dest_index); - MEdge *me = &result->medge[dest_index]; + MEdge *me = &dst_edges[dest_index]; me->v1 = vert_final[wegrp->v1]; me->v2 = vert_final[wegrp->v2]; /* "For now, assume that all merged edges are loose. This flag will be cleared in the @@ -1464,13 +1465,13 @@ static Mesh *create_merged_mesh(const Mesh &mesh, /* Polys/Loops. */ - MPoly *r_mp = &result->mpoly[0]; - MLoop *r_ml = &result->mloop[0]; + MPoly *r_mp = dst_polys.data(); + MLoop *r_ml = dst_loops.data(); int r_i = 0; int loop_cur = 0; Array<int, 64> group_buffer(weld_mesh.max_poly_len); - for (const int i : mpoly.index_range()) { - const MPoly &mp = mpoly[i]; + for (const int i : src_polys.index_range()) { + const MPoly &mp = src_polys[i]; const int loop_start = loop_cur; const int poly_ctx = weld_mesh.poly_map[i]; if (poly_ctx == OUT_OF_CONTEXT) { @@ -1486,7 +1487,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh, const WeldPoly &wp = weld_mesh.wpoly[poly_ctx]; WeldLoopOfPolyIter iter; if (!weld_iter_loop_of_poly_begin( - iter, wp, weld_mesh.wloop, mloop, weld_mesh.loop_map, group_buffer.data())) { + iter, wp, weld_mesh.wloop, src_loops, weld_mesh.loop_map, group_buffer.data())) { continue; } @@ -1503,9 +1504,9 @@ static Mesh *create_merged_mesh(const Mesh &mesh, r_ml++; loop_cur++; if (iter.type) { - result->medge[e].flag &= ~ME_LOOSEEDGE; + dst_edges[e].flag &= ~ME_LOOSEEDGE; } - BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0); + BLI_assert((dst_edges[e].flag & ME_LOOSEEDGE) == 0); } } @@ -1522,7 +1523,7 @@ static Mesh *create_merged_mesh(const Mesh &mesh, const int loop_start = loop_cur; WeldLoopOfPolyIter iter; if (!weld_iter_loop_of_poly_begin( - iter, wp, weld_mesh.wloop, mloop, weld_mesh.loop_map, group_buffer.data())) { + iter, wp, weld_mesh.wloop, src_loops, weld_mesh.loop_map, group_buffer.data())) { continue; } @@ -1538,9 +1539,9 @@ static Mesh *create_merged_mesh(const Mesh &mesh, r_ml++; loop_cur++; if (iter.type) { - result->medge[e].flag &= ~ME_LOOSEEDGE; + dst_edges[e].flag &= ~ME_LOOSEEDGE; } - BLI_assert((result->medge[e].flag & ME_LOOSEEDGE) == 0); + BLI_assert((dst_edges[e].flag & ME_LOOSEEDGE) == 0); } r_mp->loopstart = loop_start; @@ -1569,8 +1570,9 @@ std::optional<Mesh *> mesh_merge_by_distance_all(const Mesh &mesh, KDTree_3d *tree = BLI_kdtree_3d_new(selection.size()); + const Span<MVert> verts = mesh.vertices(); for (const int i : selection) { - BLI_kdtree_3d_insert(tree, i, mesh.mvert[i].co); + BLI_kdtree_3d_insert(tree, i, verts[i].co); } BLI_kdtree_3d_balance(tree); @@ -1595,8 +1597,8 @@ std::optional<Mesh *> mesh_merge_by_distance_connected(const Mesh &mesh, const float merge_distance, const bool only_loose_edges) { - Span<MVert> verts{mesh.mvert, mesh.totvert}; - Span<MEdge> edges{mesh.medge, mesh.totedge}; + const Span<MVert> verts = mesh.vertices(); + const Span<MEdge> edges = mesh.edges(); int vert_kill_len = 0; diff --git a/source/blender/geometry/intern/mesh_primitive_cuboid.cc b/source/blender/geometry/intern/mesh_primitive_cuboid.cc index 486d8adbf39..1e734a82e43 100644 --- a/source/blender/geometry/intern/mesh_primitive_cuboid.cc +++ b/source/blender/geometry/intern/mesh_primitive_cuboid.cc @@ -405,10 +405,13 @@ Mesh *create_cuboid_mesh(const float3 &size, Mesh *mesh = BKE_mesh_new_nomain( config.vertex_count, 0, 0, config.loop_count, config.poly_count); + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); - calculate_vertices(config, {mesh->mvert, mesh->totvert}); + calculate_vertices(config, verts); - calculate_polys(config, {mesh->mpoly, mesh->totpoly}, {mesh->mloop, mesh->totloop}); + calculate_polys(config, polys, loops); BKE_mesh_calc_edges(mesh, false, false); if (uv_id) { diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 350dfe73d57..1951c960d0d 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -12,6 +12,7 @@ #include "BKE_attribute_math.hh" #include "BKE_curves.hh" #include "BKE_geometry_set.hh" +#include "BKE_mesh.h" #include "GEO_mesh_to_curve.hh" @@ -213,8 +214,9 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(Span<MVert> verts, static Vector<std::pair<int, int>> get_selected_edges(const Mesh &mesh, const IndexMask selection) { Vector<std::pair<int, int>> selected_edges; + const Span<MEdge> edges = mesh.edges(); for (const int i : selection) { - selected_edges.append({mesh.medge[i].v1, mesh.medge[i].v2}); + selected_edges.append({edges[i].v1, edges[i].v2}); } return selected_edges; } @@ -222,8 +224,8 @@ static Vector<std::pair<int, int>> get_selected_edges(const Mesh &mesh, const In bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh, const IndexMask selection) { Vector<std::pair<int, int>> selected_edges = get_selected_edges(mesh, selection); - CurveFromEdgesOutput output = edges_to_curve_point_indices({mesh.mvert, mesh.totvert}, - selected_edges); + const Span<MVert> verts = mesh.vertices(); + CurveFromEdgesOutput output = edges_to_curve_point_indices(verts, selected_edges); return create_curve_from_vert_indices( mesh, output.vert_indices, output.curve_offsets, output.cyclic_curves); diff --git a/source/blender/geometry/intern/mesh_to_volume.cc b/source/blender/geometry/intern/mesh_to_volume.cc index ae98b048a6c..39078b1c511 100644 --- a/source/blender/geometry/intern/mesh_to_volume.cc +++ b/source/blender/geometry/intern/mesh_to_volume.cc @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_volume.h" @@ -29,7 +30,7 @@ class OpenVDBMeshAdapter { }; OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform) - : vertices_(mesh.mvert, mesh.totvert), loops_(mesh.mloop, mesh.totloop), transform_(transform) + : vertices_(mesh.vertices()), loops_(mesh.loops()), transform_(transform) { /* This only updates a cache and can be considered to be logically const. */ const MLoopTri *looptris = BKE_mesh_runtime_looptri_ensure(&mesh); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 25ff705385c..8d1c43866eb 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -97,6 +97,11 @@ struct MeshElementStartIndices { struct MeshRealizeInfo { const Mesh *mesh = nullptr; + Span<MVert> verts; + Span<MEdge> edges; + Span<MPoly> polys; + Span<MLoop> loops; + /** Maps old material indices to new material indices. */ Array<int> material_index_map; /** Matches the order in #AllMeshesInfo.attributes. */ @@ -859,6 +864,10 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, MeshRealizeInfo &mesh_info = info.realize_info[mesh_index]; const Mesh *mesh = info.order[mesh_index]; mesh_info.mesh = mesh; + mesh_info.verts = mesh->vertices(); + mesh_info.edges = mesh->edges(); + mesh_info.polys = mesh->polygons(); + mesh_info.loops = mesh->loops(); /* Create material index mapping. */ mesh_info.material_index_map.reinitialize(std::max<int>(mesh->totcol, 1)); @@ -900,30 +909,31 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, static void execute_realize_mesh_task(const RealizeInstancesOptions &options, const RealizeMeshTask &task, const OrderedAttributes &ordered_attributes, - Mesh &dst_mesh, MutableSpan<GSpanAttributeWriter> dst_attribute_writers, + MutableSpan<MVert> all_dst_verts, + MutableSpan<MEdge> all_dst_edges, + MutableSpan<MPoly> all_dst_polys, + MutableSpan<MLoop> all_dst_loops, MutableSpan<int> all_dst_vertex_ids, MutableSpan<int> all_dst_material_indices) { const MeshRealizeInfo &mesh_info = *task.mesh_info; const Mesh &mesh = *mesh_info.mesh; - const Span<MVert> src_verts{mesh.mvert, mesh.totvert}; - const Span<MEdge> src_edges{mesh.medge, mesh.totedge}; - const Span<MLoop> src_loops{mesh.mloop, mesh.totloop}; - const Span<MPoly> src_polys{mesh.mpoly, mesh.totpoly}; + const Span<MVert> src_verts = mesh_info.verts; + const Span<MEdge> src_edges = mesh_info.edges; + const Span<MPoly> src_polys = mesh_info.polys; + const Span<MLoop> src_loops = mesh_info.loops; const IndexRange dst_vert_range(task.start_indices.vertex, src_verts.size()); const IndexRange dst_edge_range(task.start_indices.edge, src_edges.size()); const IndexRange dst_poly_range(task.start_indices.poly, src_polys.size()); const IndexRange dst_loop_range(task.start_indices.loop, src_loops.size()); - MutableSpan dst_verts = MutableSpan(dst_mesh.mvert, dst_mesh.totvert).slice(dst_vert_range); - MutableSpan dst_edges = MutableSpan(dst_mesh.medge, dst_mesh.totedge).slice(dst_edge_range); - MutableSpan dst_polys = MutableSpan(dst_mesh.mpoly, dst_mesh.totpoly).slice(dst_poly_range); - MutableSpan dst_loops = MutableSpan(dst_mesh.mloop, dst_mesh.totloop).slice(dst_loop_range); - - const Span<int> material_index_map = mesh_info.material_index_map; + MutableSpan<MVert> dst_verts = all_dst_verts.slice(dst_vert_range); + MutableSpan<MEdge> dst_edges = all_dst_edges.slice(dst_edge_range); + MutableSpan<MPoly> dst_polys = all_dst_polys.slice(dst_poly_range); + MutableSpan<MLoop> dst_loops = all_dst_loops.slice(dst_loop_range); threading::parallel_for(src_verts.index_range(), 1024, [&](const IndexRange vert_range) { for (const int i : vert_range) { @@ -960,6 +970,7 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, } }); if (!all_dst_material_indices.is_empty()) { + const Span<int> material_index_map = mesh_info.material_index_map; MutableSpan<int> dst_material_indices = all_dst_material_indices.slice(dst_poly_range); if (mesh.totcol == 0) { /* The material index map contains the index of the null material in the result. */ @@ -1035,6 +1046,10 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, MeshComponent &dst_component = r_realized_geometry.get_component_for_write<MeshComponent>(); dst_component.replace(dst_mesh); bke::MutableAttributeAccessor dst_attributes = bke::mesh_attributes_for_write(*dst_mesh); + MutableSpan<MVert> dst_verts = dst_mesh->vertices_for_write(); + MutableSpan<MEdge> dst_edges = dst_mesh->edges_for_write(); + MutableSpan<MPoly> dst_polys = dst_mesh->polygons_for_write(); + MutableSpan<MLoop> dst_loops = dst_mesh->loops_for_write(); /* Copy settings from the first input geometry set with a mesh. */ const RealizeMeshTask &first_task = tasks.first(); @@ -1079,8 +1094,11 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, execute_realize_mesh_task(options, task, ordered_attributes, - *dst_mesh, dst_attribute_writers, + dst_verts, + dst_edges, + dst_polys, + dst_loops, vertex_ids.span, material_indices.span); } diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index bf17e53c2ce..6c3fadc1b29 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -1411,7 +1411,7 @@ typedef struct LineartEdgeNeighbor { } LineartEdgeNeighbor; typedef struct VertData { - MVert *mvert; + const MVert *mvert; LineartVert *v_arr; double (*model_view)[4]; double (*model_view_proj)[4]; @@ -1422,7 +1422,7 @@ static void lineart_mvert_transform_task(void *__restrict userdata, const TaskParallelTLS *__restrict UNUSED(tls)) { VertData *vert_task_data = (VertData *)userdata; - MVert *m_v = &vert_task_data->mvert[i]; + const MVert *m_v = &vert_task_data->mvert[i]; double co[4]; LineartVert *v = &vert_task_data->v_arr[i]; copy_v3db_v3fl(co, m_v->co); @@ -1638,12 +1638,13 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, } if (!only_contour) { + const MPoly *polys = BKE_mesh_polygons(me); if (ld->conf.use_crease) { bool do_crease = true; if (!ld->conf.force_crease && !e_feat_data->use_auto_smooth && - (me->mpoly[mlooptri[f1].poly].flag & ME_SMOOTH) && - (me->mpoly[mlooptri[f2].poly].flag & ME_SMOOTH)) { + (polys[mlooptri[f1].poly].flag & ME_SMOOTH) && + (polys[mlooptri[f2].poly].flag & ME_SMOOTH)) { do_crease = false; } if (do_crease && (dot_v3v3_db(tri1->gn, tri2->gn) < e_feat_data->crease_threshold)) { @@ -1675,11 +1676,13 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, } } + const MEdge *edges = BKE_mesh_edges(me); + int real_edges[3]; BKE_mesh_looptri_get_real_edges(me, &mlooptri[i / 3], real_edges); if (real_edges[i % 3] >= 0) { - MEdge *medge = &me->medge[real_edges[i % 3]]; + const MEdge *medge = &edges[real_edges[i % 3]]; if (ld->conf.use_crease && ld->conf.sharp_as_crease && (medge->flag & ME_SHARP)) { edge_flag_result |= LRT_EDGE_FLAG_CREASE; @@ -1710,16 +1713,16 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, typedef struct LooseEdgeData { int loose_count; int loose_max; - MEdge **loose_array; - Mesh *me; + int *loose_array; + const MEdge *edges; } LooseEdgeData; static void lineart_loose_data_reallocate(LooseEdgeData *loose_data, int count) { - MEdge **new_arr = MEM_callocN(sizeof(MEdge *) * count, "loose edge array"); + int *new_arr = MEM_calloc_arrayN(count, sizeof(int), "loose edge array"); if (loose_data->loose_array) { - memcpy(new_arr, loose_data->loose_array, sizeof(MEdge *) * loose_data->loose_max); - MEM_freeN(loose_data->loose_array); + memcpy(new_arr, loose_data->loose_array, sizeof(int) * loose_data->loose_max); + MEM_SAFE_FREE(loose_data->loose_array); } loose_data->loose_max = count; loose_data->loose_array = new_arr; @@ -1736,19 +1739,19 @@ static void lineart_join_loose_edge_arr(LooseEdgeData *loose_data, LooseEdgeData } memcpy(&loose_data->loose_array[loose_data->loose_count], to_be_joined->loose_array, - sizeof(MEdge *) * to_be_joined->loose_count); + sizeof(int) * to_be_joined->loose_count); loose_data->loose_count += to_be_joined->loose_count; MEM_freeN(to_be_joined->loose_array); to_be_joined->loose_array = NULL; } -static void lineart_add_loose_edge(LooseEdgeData *loose_data, MEdge *e) +static void lineart_add_loose_edge(LooseEdgeData *loose_data, const int i) { if (loose_data->loose_count >= loose_data->loose_max) { int min_amount = MAX2(100, loose_data->loose_count * 2); lineart_loose_data_reallocate(loose_data, min_amount); } - loose_data->loose_array[loose_data->loose_count] = e; + loose_data->loose_array[loose_data->loose_count] = i; loose_data->loose_count++; } @@ -1757,10 +1760,9 @@ static void lineart_identify_loose_edges(void *__restrict UNUSED(userdata), const TaskParallelTLS *__restrict tls) { LooseEdgeData *loose_data = (LooseEdgeData *)tls->userdata_chunk; - Mesh *me = loose_data->me; - if (me->medge[i].flag & ME_LOOSEEDGE) { - lineart_add_loose_edge(loose_data, &me->medge[i]); + if (loose_data->edges[i].flag & ME_LOOSEEDGE) { + lineart_add_loose_edge(loose_data, i); } } @@ -1861,12 +1863,13 @@ static void lineart_load_tri_task(void *__restrict userdata, const int *material_indices = tri_task_data->material_indices; LineartVert *vert_arr = tri_task_data->vert_arr; LineartTriangle *tri = tri_task_data->tri_arr; + const MLoop *loops = BKE_mesh_loops(me); tri = (LineartTriangle *)(((uchar *)tri) + tri_task_data->lineart_triangle_size * i); - int v1 = me->mloop[mlooptri->tri[0]].v; - int v2 = me->mloop[mlooptri->tri[1]].v; - int v3 = me->mloop[mlooptri->tri[2]].v; + int v1 = loops[mlooptri->tri[0]].v; + int v2 = loops[mlooptri->tri[1]].v; + int v3 = loops[mlooptri->tri[2]].v; tri->v[0] = &vert_arr[v1]; tri->v[1] = &vert_arr[v2]; @@ -1893,7 +1896,8 @@ static void lineart_load_tri_task(void *__restrict userdata, double gn[3]; float no[3]; - normal_tri_v3(no, me->mvert[v1].co, me->mvert[v2].co, me->mvert[v3].co); + const MVert *verts = BKE_mesh_vertices(me); + normal_tri_v3(no, verts[v1].co, verts[v2].co, verts[v3].co); copy_v3db_v3fl(gn, no); mul_v3_mat3_m4v3_db(tri->gn, ob_info->normal, gn); normalize_v3_db(tri->gn); @@ -1912,8 +1916,8 @@ static void lineart_load_tri_task(void *__restrict userdata, typedef struct EdgeNeighborData { LineartEdgeNeighbor *edge_nabr; LineartAdjacentEdge *adj_e; - MLoopTri *mlooptri; - MLoop *mloop; + const MLoopTri *mlooptri; + const MLoop *mloop; } EdgeNeighborData; static void lineart_edge_neighbor_init_task(void *__restrict userdata, @@ -1922,9 +1926,9 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata, { EdgeNeighborData *en_data = (EdgeNeighborData *)userdata; LineartAdjacentEdge *adj_e = &en_data->adj_e[i]; - MLoopTri *looptri = &en_data->mlooptri[i / 3]; + const MLoopTri *looptri = &en_data->mlooptri[i / 3]; LineartEdgeNeighbor *edge_nabr = &en_data->edge_nabr[i]; - MLoop *mloop = en_data->mloop; + const MLoop *mloop = en_data->mloop; adj_e->e = i; adj_e->v1 = mloop[looptri->tri[i % 3]].v; @@ -1958,7 +1962,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge en_data.adj_e = adj_e; en_data.edge_nabr = edge_nabr; en_data.mlooptri = mlooptri; - en_data.mloop = me->mloop; + en_data.mloop = BKE_mesh_loops(me); BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings); @@ -2084,7 +2088,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, vert_settings.min_iter_per_thread = 4000; VertData vert_data; - vert_data.mvert = me->mvert; + vert_data.mvert = BKE_mesh_vertices(me); vert_data.v_arr = la_v_arr; vert_data.model_view = ob_info->model_view; vert_data.model_view_proj = ob_info->model_view_proj; @@ -2154,6 +2158,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, &edge_feat_settings); LooseEdgeData loose_data = {0}; + if (la_data->conf.use_loose) { /* Only identifying floating edges at this point because other edges has been taken care of * inside #lineart_identify_mlooptri_feature_edges function. */ @@ -2163,7 +2168,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_loose_settings.func_reduce = loose_data_sum_reduce; edge_loose_settings.userdata_chunk = &loose_data; edge_loose_settings.userdata_chunk_size = sizeof(LooseEdgeData); - loose_data.me = me; + loose_data.edges = BKE_mesh_edges(me); BLI_task_parallel_range( 0, me->totedge, &loose_data, lineart_identify_loose_edges, &edge_loose_settings); } @@ -2268,8 +2273,9 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, if (loose_data.loose_array) { for (int i = 0; i < loose_data.loose_count; i++) { - la_edge->v1 = &la_v_arr[loose_data.loose_array[i]->v1]; - la_edge->v2 = &la_v_arr[loose_data.loose_array[i]->v2]; + const MEdge *edge = &loose_data.edges[loose_data.loose_array[i]]; + la_edge->v1 = &la_v_arr[edge->v1]; + la_edge->v2 = &la_v_arr[edge->v2]; la_edge->flags = LRT_EDGE_FLAG_LOOSE; la_edge->object_ref = orig_ob; la_edge->edge_identifier = LRT_EDGE_IDENTIFIER(ob_info, la_edge); @@ -2287,7 +2293,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, la_edge++; la_seg++; } - MEM_freeN(loose_data.loose_array); + MEM_SAFE_FREE(loose_data.loose_array); } MEM_freeN(edge_feat_data.edge_nabr); @@ -5315,7 +5321,8 @@ static void lineart_gpencil_generate(LineartCache *cache, if (eval_ob && eval_ob->type == OB_MESH) { int dindex = 0; Mesh *me = BKE_object_get_evaluated_mesh(eval_ob); - if (me->dvert) { + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); + if (dvert) { LISTBASE_FOREACH (bDeformGroup *, db, &me->vertex_group_names) { if ((!source_vgname) || strstr(db->name, source_vgname) == db->name) { if (match_output) { @@ -5330,7 +5337,7 @@ static void lineart_gpencil_generate(LineartCache *cache, if (vindex >= me->totvert) { break; } - MDeformWeight *mdw = BKE_defvert_ensure_index(&me->dvert[vindex], dindex); + MDeformWeight *mdw = BKE_defvert_ensure_index(&dvert[vindex], dindex); MDeformWeight *gdw = BKE_defvert_ensure_index(&gps->dvert[sindex], gpdg); float use_weight = mdw->weight; diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index a87c7ea4809..72d77cc7857 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -467,8 +467,8 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh, int i, tottri; int tot_real_edges = 0; - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); @@ -476,14 +476,14 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh, &mesh->vdata, CD_PROP_BOOL, ".hide_vert"); /* smooth or flat for all */ - buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH; + buffers->smooth = polys[looptri[face_indices[0]].poly].flag & ME_SMOOTH; buffers->show_overlay = false; /* Count the number of visible triangles */ for (i = 0, tottri = 0; i < face_indices_len; i++) { const MLoopTri *lt = &looptri[face_indices[i]]; - if (gpu_pbvh_is_looptri_visible(lt, hide_vert, mloop, sculpt_face_sets)) { + if (gpu_pbvh_is_looptri_visible(lt, hide_vert, loops, sculpt_face_sets)) { int r_edges[3]; BKE_mesh_looptri_get_real_edges(mesh, lt, r_edges); for (int j = 0; j < 3; j++) { @@ -498,8 +498,8 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh, if (tottri == 0) { buffers->tot_tri = 0; - buffers->mpoly = mpoly; - buffers->mloop = mloop; + buffers->mpoly = polys; + buffers->mloop = loops; buffers->looptri = looptri; buffers->face_indices = face_indices; buffers->face_indices_len = 0; @@ -516,7 +516,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh, const MLoopTri *lt = &looptri[face_indices[i]]; /* Skip hidden faces */ - if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, mloop, sculpt_face_sets)) { + if (!gpu_pbvh_is_looptri_visible(lt, hide_vert, loops, sculpt_face_sets)) { continue; } @@ -538,8 +538,8 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const Mesh *mesh, buffers->tot_tri = tottri; - buffers->mpoly = mpoly; - buffers->mloop = mloop; + buffers->mpoly = polys; + buffers->mloop = loops; buffers->looptri = looptri; buffers->face_indices = face_indices; diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc index 99c609b0235..b06b973f764 100644 --- a/source/blender/io/alembic/exporter/abc_writer_hair.cc +++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc @@ -120,9 +120,9 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, float inv_mat[4][4]; invert_m4_m4_safe(inv_mat, context.object->obmat); - MTFace *mtface = mesh->mtface; - MFace *mface = mesh->mface; - MVert *mverts = mesh->mvert; + MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE); + MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + const MVert *mverts = BKE_mesh_vertices(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); if ((!mtface || !mface) && !uv_warning_shown_) { @@ -243,8 +243,9 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context, float inv_mat[4][4]; invert_m4_m4_safe(inv_mat, context.object->obmat); - MTFace *mtface = mesh->mtface; - MVert *mverts = mesh->mvert; + MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE); + const MVert *mverts = BKE_mesh_vertices(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); ParticleSystem *psys = context.particle_system; @@ -269,7 +270,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context, continue; } - MFace *face = &mesh->mface[num]; + MFace *face = &mface[num]; MTFace *tface = mtface + num; float r_uv[2], tmpnor[3], mapfw[4], vec[3]; diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index 83f970d3965..acfa4c1ea08 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -176,8 +176,8 @@ void ABCGenericMeshWriter::do_write(HierarchyContext &context) m_custom_data_config.pack_uvs = args_.export_params->packuv; m_custom_data_config.mesh = mesh; - m_custom_data_config.mpoly = mesh->mpoly; - m_custom_data_config.mloop = mesh->mloop; + m_custom_data_config.mpoly = mesh->polygons_for_write().data(); + m_custom_data_config.mloop = mesh->loops_for_write().data(); m_custom_data_config.totpoly = mesh->totpoly; m_custom_data_config.totloop = mesh->totloop; m_custom_data_config.totvert = mesh->totvert; @@ -436,8 +436,7 @@ static void get_vertices(struct Mesh *mesh, std::vector<Imath::V3f> &points) points.clear(); points.resize(mesh->totvert); - MVert *verts = mesh->mvert; - + const Span<MVert> verts = mesh->vertices(); for (int i = 0, e = mesh->totvert; i < e; i++) { copy_yup_from_zup(points[i].getValue(), verts[i].co); } @@ -448,25 +447,23 @@ static void get_topology(struct Mesh *mesh, std::vector<int32_t> &loop_counts, bool &r_has_flat_shaded_poly) { - const int num_poly = mesh->totpoly; - const int num_loops = mesh->totloop; - MLoop *mloop = mesh->mloop; - MPoly *mpoly = mesh->mpoly; + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); r_has_flat_shaded_poly = false; poly_verts.clear(); loop_counts.clear(); - poly_verts.reserve(num_loops); - loop_counts.reserve(num_poly); + poly_verts.reserve(loops.size()); + loop_counts.reserve(polys.size()); /* NOTE: data needs to be written in the reverse order. */ - for (int i = 0; i < num_poly; i++) { - MPoly &poly = mpoly[i]; + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; loop_counts.push_back(poly.totloop); r_has_flat_shaded_poly |= (poly.flag & ME_SMOOTH) == 0; - MLoop *loop = mloop + poly.loopstart + (poly.totloop - 1); + const MLoop *loop = &loops[poly.loopstart + (poly.totloop - 1)]; for (int j = 0; j < poly.totloop; j++, loop--) { poly_verts.push_back(loop->v); @@ -485,14 +482,14 @@ static void get_edge_creases(struct Mesh *mesh, lengths.clear(); sharpnesses.clear(); - MEdge *edge = mesh->medge; + const Span<MEdge> edges = mesh->edges(); - for (int i = 0, e = mesh->totedge; i < e; i++) { - const float sharpness = static_cast<float>(edge[i].crease) * factor; + for (const int i : edges.index_range()) { + const float sharpness = static_cast<float>(edges[i].crease) * factor; if (sharpness != 0.0f) { - indices.push_back(edge[i].v1); - indices.push_back(edge[i].v2); + indices.push_back(edges[i].v1); + indices.push_back(edges[i].v2); sharpnesses.push_back(sharpness); } } @@ -544,8 +541,10 @@ static void get_loop_normals(struct Mesh *mesh, /* NOTE: data needs to be written in the reverse order. */ int abc_index = 0; - MPoly *mp = mesh->mpoly; - for (int i = 0, e = mesh->totpoly; i < e; i++, mp++) { + const Span<MPoly> polys = mesh->polygons(); + + for (const int i : polys.index_range()) { + const MPoly *mp = &polys[i]; for (int j = mp->totloop - 1; j >= 0; j--, abc_index++) { int blender_index = mp->loopstart + j; copy_yup_from_zup(normals[abc_index].getValue(), lnors[blender_index]); diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index a4b6c32ef64..cb87ee78fcd 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -157,8 +157,9 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data) void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySamplePtr normals) { + MutableSpan<MVert> verts = mesh.vertices_for_write(); for (int i = 0; i < positions->size(); i++) { - MVert &mvert = mesh.mvert[i]; + MVert &mvert = verts[i]; Imath::V3f pos_in = (*positions)[i]; copy_zup_from_yup(mvert.co, pos_in.getValue()); @@ -274,7 +275,7 @@ static void process_loop_normals(CDStreamConfig &config, const N3fArraySamplePtr float(*lnors)[3] = static_cast<float(*)[3]>( MEM_malloc_arrayN(loop_count, sizeof(float[3]), "ABC::FaceNormals")); - MPoly *mpoly = mesh->mpoly; + MPoly *mpoly = mesh->polygons_for_write().data(); const N3fArraySample &loop_normals = *loop_normals_ptr; int abc_index = 0; for (int i = 0, e = mesh->totpoly; i < e; i++, mpoly++) { @@ -519,13 +520,10 @@ static void read_mesh_sample(const std::string &iobject_full_name, CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation) { CDStreamConfig config; - - BLI_assert(mesh->mvert || mesh->totvert == 0); - config.mesh = mesh; - config.mvert = mesh->mvert; - config.mloop = mesh->mloop; - config.mpoly = mesh->mpoly; + config.mvert = mesh->vertices_for_write().data(); + config.mloop = mesh->loops_for_write().data(); + config.mpoly = mesh->polygons_for_write().data(); config.totvert = mesh->totvert; config.totloop = mesh->totloop; config.totpoly = mesh->totpoly; @@ -925,12 +923,10 @@ static void read_edge_creases(Mesh *mesh, return; } - MEdge *edges = mesh->medge; - const int totedge = mesh->totedge; - - EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, mesh->totedge); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, edges.size()); - for (int i = 0; i < totedge; i++) { + for (const int i : edges.index_range()) { MEdge *edge = &edges[i]; BLI_edgehash_insert(edge_hash, edge->v1, edge->v2, edge); } diff --git a/source/blender/io/collada/ArmatureExporter.cpp b/source/blender/io/collada/ArmatureExporter.cpp index 87dd2fbd816..3cc98917116 100644 --- a/source/blender/io/collada/ArmatureExporter.cpp +++ b/source/blender/io/collada/ArmatureExporter.cpp @@ -76,7 +76,7 @@ bool ArmatureExporter::add_instance_controller(Object *ob) ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); Mesh *me = (Mesh *)ob->data; - if (!me->dvert) { + if (BKE_mesh_deform_verts(me) == nullptr) { return false; } diff --git a/source/blender/io/collada/ControllerExporter.cpp b/source/blender/io/collada/ControllerExporter.cpp index 38ad0e42d0f..6bf8d904a41 100644 --- a/source/blender/io/collada/ControllerExporter.cpp +++ b/source/blender/io/collada/ControllerExporter.cpp @@ -63,7 +63,7 @@ bool ControllerExporter::add_instance_controller(Object *ob) ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); Mesh *me = (Mesh *)ob->data; - if (!me->dvert) { + if (BKE_mesh_deform_verts(me) == nullptr) { return false; } @@ -160,7 +160,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) bool use_instantiation = this->export_settings.get_use_object_instantiation(); Mesh *me; - if (((Mesh *)ob->data)->dvert == nullptr) { + if (BKE_mesh_deform_verts((Mesh *)ob->data) == nullptr) { return; } @@ -203,9 +203,10 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) } } + const MDeformVert *dvert = BKE_mesh_deform_verts(me); int oob_counter = 0; for (i = 0; i < me->totvert; i++) { - MDeformVert *vert = &me->dvert[i]; + const MDeformVert *vert = &dvert[i]; std::map<int, float> jw; /* We're normalizing the weights later */ diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 1a3a68923e3..f8123432f4e 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -27,6 +27,8 @@ #include "collada_internal.h" #include "collada_utils.h" +using blender::Span; + void GeometryExporter::exportGeom() { Scene *sce = blender_context.get_scene(); @@ -117,11 +119,12 @@ void GeometryExporter::operator()(Object *ob) if (this->export_settings.get_include_shapekeys()) { Key *key = BKE_key_from_object(ob); if (key) { + blender::MutableSpan<MVert> verts = me->vertices_for_write(); KeyBlock *kb = (KeyBlock *)key->block.first; /* skip the basis */ kb = kb->next; for (; kb; kb = kb->next) { - BKE_keyblock_convert_to_mesh(kb, me->mvert, me->totvert); + BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert); export_key_mesh(ob, me, kb); } } @@ -197,8 +200,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &geom_id) { - - MEdge *medges = me->medge; + const Span<MEdge> edges = me->edges(); int totedges = me->totedge; int edges_in_linelist = 0; std::vector<unsigned int> edge_list; @@ -207,7 +209,7 @@ void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &ge /* Find all loose edges in Mesh * and save vertex indices in edge_list */ for (index = 0; index < totedges; index++) { - MEdge *edge = &medges[index]; + const MEdge *edge = &edges[index]; if (edge->flag & ME_LOOSEEDGE) { edges_in_linelist += 1; @@ -285,19 +287,17 @@ static bool collect_vertex_counts_per_poly(Mesh *me, int material_index, std::vector<unsigned long> &vcount_list) { + const Span<MPoly> polys = me->polygons(); const blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*me); const blender::VArray<int> material_indices = attributes.lookup_or_default<int>( "material_index", ATTR_DOMAIN_FACE, 0); - MPoly *mpolys = me->mpoly; - int totpolys = me->totpoly; bool is_triangulated = true; - int i; /* Expecting that the material index is always 0 if the mesh has no materials assigned */ - for (i = 0; i < totpolys; i++) { + for (const int i : polys.index_range()) { if (material_indices[i] == material_index) { - MPoly *p = &mpolys[i]; - int vertex_count = p->totloop; + const MPoly &poly = polys[i]; + const int vertex_count = poly.totloop; vcount_list.push_back(vertex_count); if (vertex_count != 3) { is_triangulated = false; @@ -322,10 +322,8 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, std::string &geom_id, std::vector<BCPolygonNormalsIndices> &norind) { - - MPoly *mpolys = me->mpoly; - MLoop *mloops = me->mloop; - int totpolys = me->totpoly; + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); std::vector<unsigned long> vcount_list; @@ -407,12 +405,12 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, /* <p> */ int texindex = 0; - for (int i = 0; i < totpolys; i++) { - MPoly *p = &mpolys[i]; + for (const int i : polys.index_range()) { + const MPoly *p = &polys[i]; int loop_count = p->totloop; if (material_indices[i] == material_index) { - MLoop *l = &mloops[p->loopstart]; + const MLoop *l = &loops[p->loopstart]; BCPolygonNormalsIndices normal_indices = norind[i]; for (int j = 0; j < loop_count; j++) { @@ -436,18 +434,13 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) { -#if 0 - int totverts = dm->getNumVerts(dm); - MVert *verts = dm->getVertArray(dm); -#endif - int totverts = me->totvert; - MVert *verts = me->mvert; + const Span<MVert> verts = me->vertices(); COLLADASW::FloatSourceF source(mSW); source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) + ARRAY_ID_SUFFIX); - source.setAccessorCount(totverts); + source.setAccessorCount(verts.size()); source.setAccessorStride(3); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); @@ -458,8 +451,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) * count = ""> */ source.prepareToAppendValues(); /* appends data to <float_array> */ - int i = 0; - for (i = 0; i < totverts; i++) { + for (const int i : verts.index_range()) { Vector co; if (export_settings.get_apply_global_orientation()) { bc_add_global_transform(co, verts[i].co, export_settings.get_global_transform()); @@ -508,11 +500,11 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) source.prepareToAppendValues(); - MPoly *mpoly; - int i; - for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) { - const MLoopCol *mlc = mloopcol + mpoly->loopstart; - for (int j = 0; j < mpoly->totloop; j++, mlc++) { + const Span<MPoly> polys = me->polygons(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + const MLoopCol *mlc = mloopcol + poly.loopstart; + for (int j = 0; j < poly.totloop; j++, mlc++) { source.appendValues(mlc->r / 255.0f, mlc->g / 255.0f, mlc->b / 255.0f, mlc->a / 255.0f); } } @@ -537,10 +529,8 @@ std::string GeometryExporter::makeTexcoordSourceId(std::string &geom_id, void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) { - - int totpoly = me->totpoly; int totuv = me->totloop; - MPoly *mpolys = me->mpoly; + const Span<MPoly> polys = me->polygons(); int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); @@ -566,8 +556,8 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) source.prepareToAppendValues(); - for (int index = 0; index < totpoly; index++) { - MPoly *mpoly = mpolys + index; + for (const int i : polys.index_range()) { + const MPoly *mpoly = &polys[i]; MLoopUV *mloop = mloops + mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++) { source.appendValues(mloop[j].uv[0], mloop[j].uv[1]); @@ -625,9 +615,10 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals, std::map<Normal, unsigned int> shared_normal_indices; int last_normal_index = -1; - MVert *verts = me->mvert; + const Span<MVert> verts = me->vertices(); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); - MLoop *mloops = me->mloop; + const Span<MPoly> polys = me->polygons(); + const Span<MLoop> loops = me->loops(); const float(*lnors)[3] = nullptr; bool use_custom_normals = false; @@ -637,15 +628,15 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals, use_custom_normals = true; } - for (int poly_index = 0; poly_index < me->totpoly; poly_index++) { - MPoly *mpoly = &me->mpoly[poly_index]; + for (const int poly_index : polys.index_range()) { + const MPoly *mpoly = &polys[poly_index]; bool use_vertex_normals = use_custom_normals || mpoly->flag & ME_SMOOTH; if (!use_vertex_normals) { /* For flat faces use face normal as vertex normal: */ float vector[3]; - BKE_mesh_calc_poly_normal(mpoly, mloops + mpoly->loopstart, verts, vector); + BKE_mesh_calc_poly_normal(mpoly, &loops[mpoly->loopstart], verts.data(), vector); Normal n = {vector[0], vector[1], vector[2]}; normals.push_back(n); @@ -662,7 +653,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals, normalize_v3_v3(normalized, lnors[loop_idx]); } else { - copy_v3_v3(normalized, vert_normals[mloops[loop_index].v]); + copy_v3_v3(normalized, vert_normals[loops[loop_index].v]); normalize_v3(normalized); } Normal n = {normalized[0], normalized[1], normalized[2]}; diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index fab53908d5a..8aa1685030f 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -33,6 +33,8 @@ #include "MeshImporter.h" #include "collada_utils.h" +using blender::MutableSpan; + /* get node name, or fall back to original id if not present (name is optional) */ template<class T> static std::string bc_get_dae_name(T *node) { @@ -341,14 +343,10 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) } me->totvert = pos.getFloatValues()->getCount() / stride; - me->mvert = (MVert *)CustomData_add_layer( - &me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); - - MVert *mvert; - int i; - - for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { - get_vector(mvert->co, pos, i, stride); + CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); + MutableSpan<MVert> verts = me->vertices_for_write(); + for (const int i : verts.index_range()) { + get_vector(verts[i].co, pos, i, stride); } } @@ -449,10 +447,8 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) if (total_poly_count > 0) { me->totpoly = total_poly_count; me->totloop = total_loop_count; - me->mpoly = (MPoly *)CustomData_add_layer( - &me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly); - me->mloop = (MLoop *)CustomData_add_layer( - &me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop); + CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly); + CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop); unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount(); for (int i = 0; i < totuvset; i++) { @@ -472,7 +468,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, uvname.c_str()); } /* activate the first uv map */ - me->mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0); + CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, 0); } int totcolset = collada_mesh->getColors().getInputInfosArray().getCount(); @@ -484,7 +480,7 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) CustomData_add_layer_named( &me->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, me->totloop, colname.c_str()); } - me->mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_PROP_BYTE_COLOR, 0); + CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, 0); } } } @@ -556,10 +552,11 @@ void MeshImporter::mesh_add_edges(Mesh *mesh, int len) CustomData_free(&mesh->edata, mesh->totedge); mesh->edata = edata; - BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */ + + MutableSpan<MEdge> edges = mesh->edges_for_write(); /* set default flags */ - medge = &mesh->medge[mesh->totedge]; + medge = &edges[mesh->totedge]; for (int i = 0; i < len; i++, medge++) { medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; } @@ -576,7 +573,8 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) /* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */ mesh_add_edges(me, loose_edge_count); - MEdge *med = me->medge + face_edge_count; + MutableSpan<MEdge> edges = me->edges_for_write(); + MEdge *med = edges.data() + face_edge_count; COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives(); @@ -609,8 +607,10 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) UVDataWrapper uvs(collada_mesh->getUVCoords()); VCOLDataWrapper vcol(collada_mesh->getColors()); - MPoly *mpoly = me->mpoly; - MLoop *mloop = me->mloop; + MutableSpan<MPoly> polys = me->polygons_for_write(); + MutableSpan<MLoop> loops = me->loops_for_write(); + MPoly *mpoly = polys.data(); + MLoop *mloop = loops.data(); int loop_index = 0; MaterialIdPrimitiveArrayMap mat_prim_map; diff --git a/source/blender/io/stl/importer/stl_import_mesh.cc b/source/blender/io/stl/importer/stl_import_mesh.cc index 178b5b9347f..d85185ede6e 100644 --- a/source/blender/io/stl/importer/stl_import_mesh.cc +++ b/source/blender/io/stl/importer/stl_import_mesh.cc @@ -76,27 +76,26 @@ Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name) id_us_min(&mesh->id); mesh->totvert = verts_.size(); - mesh->mvert = static_cast<MVert *>( - CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert)); + CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert); + MutableSpan<MVert> verts = mesh->vertices_for_write(); for (int i = 0; i < mesh->totvert; i++) { - copy_v3_v3(mesh->mvert[i].co, verts_[i]); + copy_v3_v3(verts[i].co, verts_[i]); } mesh->totpoly = tris_.size(); mesh->totloop = tris_.size() * 3; - mesh->mpoly = static_cast<MPoly *>( - CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, mesh->totpoly)); - mesh->mloop = static_cast<MLoop *>( - CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CONSTRUCT, nullptr, mesh->totloop)); - + CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, mesh->totpoly); + CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, mesh->totloop); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); threading::parallel_for(tris_.index_range(), 2048, [&](IndexRange tris_range) { for (const int i : tris_range) { - mesh->mpoly[i].loopstart = 3 * i; - mesh->mpoly[i].totloop = 3; + polys[i].loopstart = 3 * i; + polys[i].totloop = 3; - mesh->mloop[3 * i].v = tris_[i].v1; - mesh->mloop[3 * i + 1].v = tris_[i].v2; - mesh->mloop[3 * i + 2].v = tris_[i].v3; + loops[3 * i].v = tris_[i].v1; + loops[3 * i + 1].v = tris_[i].v2; + loops[3 * i + 2].v = tris_[i].v3; } }); diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 4155f6ac40f..86e3aeece5d 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -312,15 +312,15 @@ bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double mot void USDMeshReader::read_mpolys(Mesh *mesh) { - MPoly *mpolys = mesh->mpoly; - MLoop *mloops = mesh->mloop; + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); int loop_index = 0; for (int i = 0; i < face_counts_.size(); i++) { const int face_size = face_counts_[i]; - MPoly &poly = mpolys[i]; + MPoly &poly = polys[i]; poly.loopstart = loop_index; poly.totloop = face_size; @@ -331,12 +331,12 @@ void USDMeshReader::read_mpolys(Mesh *mesh) if (is_left_handed_) { int loop_end_index = loop_index + (face_size - 1); for (int f = 0; f < face_size; ++f, ++loop_index) { - mloops[loop_index].v = face_indices_[loop_end_index - f]; + loops[loop_index].v = face_indices_[loop_end_index - f]; } } else { for (int f = 0; f < face_size; ++f, ++loop_index) { - mloops[loop_index].v = face_indices_[loop_index]; + loops[loop_index].v = face_indices_[loop_index]; } } } @@ -400,6 +400,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo } } + const Span<MLoop> loops = mesh->loops(); for (int i = 0; i < face_counts_.size(); i++) { const int face_size = face_counts_[i]; @@ -435,7 +436,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo /* For Vertex interpolation, use the vertex index. */ int usd_uv_index = sample.interpolation == pxr::UsdGeomTokens->vertex ? - mesh->mloop[loop_index].v : + loops[loop_index].v : loop_index; if (usd_uv_index >= sample.uvs.size()) { @@ -515,24 +516,23 @@ void USDMeshReader::read_colors(Mesh *mesh, const double motionSampleTime) MLoopCol *colors = static_cast<MLoopCol *>(cd_ptr); - mesh->mloopcol = colors; - - MPoly *poly = mesh->mpoly; - - for (int i = 0, e = mesh->totpoly; i < e; ++i, ++poly) { - for (int j = 0; j < poly->totloop; ++j) { - int loop_index = poly->loopstart + j; + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (int j = 0; j < poly.totloop; ++j) { + int loop_index = poly.loopstart + j; /* Default for constant varying interpolation. */ int usd_index = 0; if (interp == pxr::UsdGeomTokens->vertex) { - usd_index = mesh->mloop[loop_index].v; + usd_index = loops[loop_index].v; } else if (interp == pxr::UsdGeomTokens->faceVarying) { - usd_index = poly->loopstart; + usd_index = poly.loopstart; if (is_left_handed_) { - usd_index += poly->totloop - 1 - j; + usd_index += poly.totloop - 1 - j; } else { usd_index += j; @@ -630,15 +630,15 @@ void USDMeshReader::process_normals_face_varying(Mesh *mesh) float(*lnors)[3] = static_cast<float(*)[3]>( MEM_malloc_arrayN(loop_count, sizeof(float[3]), "USD::FaceNormals")); - MPoly *mpoly = mesh->mpoly; - - for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) { - for (int j = 0; j < mpoly->totloop; j++) { - int blender_index = mpoly->loopstart + j; + const Span<MPoly> polys = mesh->polygons(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (int j = 0; j < poly.totloop; j++) { + int blender_index = poly.loopstart + j; - int usd_index = mpoly->loopstart; + int usd_index = poly.loopstart; if (is_left_handed_) { - usd_index += mpoly->totloop - 1 - j; + usd_index += poly.totloop - 1 - j; } else { usd_index += j; @@ -671,12 +671,11 @@ void USDMeshReader::process_normals_uniform(Mesh *mesh) float(*lnors)[3] = static_cast<float(*)[3]>( MEM_malloc_arrayN(mesh->totloop, sizeof(float[3]), "USD::FaceNormals")); - MPoly *mpoly = mesh->mpoly; - - for (int i = 0, e = mesh->totpoly; i < e; ++i, ++mpoly) { - - for (int j = 0; j < mpoly->totloop; j++) { - int loop_index = mpoly->loopstart + j; + const Span<MPoly> polys = mesh->polygons(); + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + for (int j = 0; j < poly.totloop; j++) { + int loop_index = poly.loopstart + j; lnors[loop_index][0] = normals_[i][0]; lnors[loop_index][1] = normals_[i][1]; lnors[loop_index][2] = normals_[i][2]; @@ -699,8 +698,9 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings, * in code that expect this data to be there. */ if (new_mesh || (settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) { + MutableSpan<MVert> verts = mesh->vertices_for_write(); for (int i = 0; i < positions_.size(); i++) { - MVert &mvert = mesh->mvert[i]; + MVert &mvert = verts[i]; mvert.co[0] = positions_[i][0]; mvert.co[1] = positions_[i][1]; mvert.co[2] = positions_[i][2]; @@ -903,8 +903,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh, existing_mesh, positions_.size(), 0, 0, face_indices_.size(), face_counts_.size()); for (pxr::TfToken token : uv_tokens) { - void *cd_ptr = add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV); - active_mesh->mloopuv = static_cast<MLoopUV *>(cd_ptr); + add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV); } } @@ -914,8 +913,8 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh, /* Here we assume that the number of materials doesn't change, i.e. that * the material slots that were created when the object was loaded from * USD are still valid now. */ - size_t num_polys = active_mesh->totpoly; - if (num_polys > 0 && import_params_.import_materials) { + MutableSpan<MPoly> polys = active_mesh->polygons_for_write(); + if (!polys.is_empty() && import_params_.import_materials) { std::map<pxr::SdfPath, int> mat_map; bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*active_mesh); bke::SpanAttributeWriter<int> material_indices = diff --git a/source/blender/io/usd/intern/usd_reader_mesh.h b/source/blender/io/usd/intern/usd_reader_mesh.h index 9a3b0565668..181fd5ebf79 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.h +++ b/source/blender/io/usd/intern/usd_reader_mesh.h @@ -10,8 +10,6 @@ #include "pxr/usd/usdGeom/mesh.h" -struct MPoly; - namespace blender::io::usd { class USDMeshReader : public USDGeomReader { diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index ade75fdb365..f6250eebd5d 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -246,8 +246,8 @@ static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data) { usd_mesh_data.points.reserve(mesh->totvert); - const MVert *verts = mesh->mvert; - for (int i = 0; i < mesh->totvert; ++i) { + const Span<MVert> verts = mesh->vertices(); + for (const int i : verts.index_range()) { usd_mesh_data.points.push_back(pxr::GfVec3f(verts[i].co)); } } @@ -269,13 +269,14 @@ static void get_loops_polys(const Mesh *mesh, USDMeshData &usd_mesh_data) usd_mesh_data.face_vertex_counts.reserve(mesh->totpoly); usd_mesh_data.face_indices.reserve(mesh->totloop); - MLoop *mloop = mesh->mloop; - MPoly *mpoly = mesh->mpoly; - for (int i = 0; i < mesh->totpoly; ++i, ++mpoly) { - MLoop *loop = mloop + mpoly->loopstart; - usd_mesh_data.face_vertex_counts.push_back(mpoly->totloop); - for (int j = 0; j < mpoly->totloop; ++j, ++loop) { - usd_mesh_data.face_indices.push_back(loop->v); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); + + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; + usd_mesh_data.face_vertex_counts.push_back(poly.totloop); + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + usd_mesh_data.face_indices.push_back(loop.v); } } } @@ -284,22 +285,23 @@ static void get_edge_creases(const Mesh *mesh, USDMeshData &usd_mesh_data) { const float factor = 1.0f / 255.0f; - MEdge *edge = mesh->medge; + const Span<MEdge> edges = mesh->edges(); float sharpness; - for (int edge_idx = 0, totedge = mesh->totedge; edge_idx < totedge; ++edge_idx, ++edge) { - if (edge->crease == 0) { + for (const int i : edges.index_range()) { + const MEdge &edge = edges[i]; + if (edge.crease == 0) { continue; } - if (edge->crease == 255) { + if (edge.crease == 255) { sharpness = pxr::UsdGeomMesh::SHARPNESS_INFINITE; } else { - sharpness = static_cast<float>(edge->crease) * factor; + sharpness = static_cast<float>(edge.crease) * factor; } - usd_mesh_data.crease_vertex_indices.push_back(edge->v1); - usd_mesh_data.crease_vertex_indices.push_back(edge->v2); + usd_mesh_data.crease_vertex_indices.push_back(edge.v1); + usd_mesh_data.crease_vertex_indices.push_back(edge.v2); usd_mesh_data.crease_lengths.push_back(2); usd_mesh_data.crease_sharpnesses.push_back(sharpness); } @@ -397,6 +399,8 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_ { pxr::UsdTimeCode timecode = get_export_time_code(); const float(*lnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); pxr::VtVec3fArray loop_normals; loop_normals.reserve(mesh->totloop); @@ -411,21 +415,20 @@ void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_ /* Compute the loop normals based on the 'smooth' flag. */ const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); const float(*face_normals)[3] = BKE_mesh_poly_normals_ensure(mesh); - MPoly *mpoly = mesh->mpoly; - for (int poly_idx = 0, totpoly = mesh->totpoly; poly_idx < totpoly; ++poly_idx, ++mpoly) { - MLoop *mloop = mesh->mloop + mpoly->loopstart; + for (const int i : polys.index_range()) { + const MPoly &poly = polys[i]; - if ((mpoly->flag & ME_SMOOTH) == 0) { + if ((poly.flag & ME_SMOOTH) == 0) { /* Flat shaded, use common normal for all verts. */ - pxr::GfVec3f pxr_normal(face_normals[poly_idx]); - for (int loop_idx = 0; loop_idx < mpoly->totloop; ++loop_idx) { + pxr::GfVec3f pxr_normal(face_normals[i]); + for (int loop_idx = 0; loop_idx < poly.totloop; ++loop_idx) { loop_normals.push_back(pxr_normal); } } else { /* Smooth shaded, use individual vert normals. */ - for (int loop_idx = 0; loop_idx < mpoly->totloop; ++loop_idx, ++mloop) { - loop_normals.push_back(pxr::GfVec3f(vert_normals[mloop->v])); + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + loop_normals.push_back(pxr::GfVec3f(vert_normals[loop.v])); } } } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index a888c6d11a2..272afe4a843 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -188,12 +188,15 @@ void OBJMesh::ensure_mesh_edges() const void OBJMesh::calc_smooth_groups(const bool use_bitflags) { - poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(export_mesh_eval_->medge, - export_mesh_eval_->totedge, - export_mesh_eval_->mpoly, - export_mesh_eval_->totpoly, - export_mesh_eval_->mloop, - export_mesh_eval_->totloop, + const Span<MEdge> edges = export_mesh_eval_->edges(); + const Span<MPoly> polys = export_mesh_eval_->polygons(); + const Span<MLoop> loops = export_mesh_eval_->loops(); + poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(edges.data(), + edges.size(), + polys.data(), + polys.size(), + loops.data(), + loops.size(), &tot_smooth_groups_, use_bitflags); } @@ -239,7 +242,8 @@ const Material *OBJMesh::get_object_material(const int16_t mat_nr) const bool OBJMesh::is_ith_poly_smooth(const int poly_index) const { - return export_mesh_eval_->mpoly[poly_index].flag & ME_SMOOTH; + const Span<MPoly> polygons = export_mesh_eval_->polygons(); + return polygons[poly_index].flag & ME_SMOOTH; } const char *OBJMesh::get_object_name() const @@ -264,7 +268,8 @@ const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const float3 OBJMesh::calc_vertex_coords(const int vert_index, const float scaling_factor) const { float3 r_coords; - copy_v3_v3(r_coords, export_mesh_eval_->mvert[vert_index].co); + const Span<MVert> verts = export_mesh_eval_->vertices(); + copy_v3_v3(r_coords, verts[vert_index].co); mul_m4_v3(world_and_axes_transform_, r_coords); mul_v3_fl(r_coords, scaling_factor); return r_coords; @@ -272,8 +277,10 @@ float3 OBJMesh::calc_vertex_coords(const int vert_index, const float scaling_fac Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const { - const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index]; - const MLoop *mloop = &export_mesh_eval_->mloop[mpoly.loopstart]; + const Span<MPoly> polys = export_mesh_eval_->polygons(); + const Span<MLoop> loops = export_mesh_eval_->loops(); + const MPoly &mpoly = polys[poly_index]; + const MLoop *mloop = &loops[mpoly.loopstart]; const int totloop = mpoly.totloop; Vector<int> r_poly_vertex_indices(totloop); for (int loop_index = 0; loop_index < totloop; loop_index++) { @@ -284,9 +291,8 @@ Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const void OBJMesh::store_uv_coords_and_indices() { - const MPoly *mpoly = export_mesh_eval_->mpoly; - const MLoop *mloop = export_mesh_eval_->mloop; - const int totpoly = export_mesh_eval_->totpoly; + const Span<MPoly> polys = export_mesh_eval_->polygons(); + const Span<MLoop> loops = export_mesh_eval_->loops(); const int totvert = export_mesh_eval_->totvert; const MLoopUV *mloopuv = static_cast<const MLoopUV *>( CustomData_get_layer(&export_mesh_eval_->ldata, CD_MLOOPUV)); @@ -297,9 +303,9 @@ void OBJMesh::store_uv_coords_and_indices() const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( - mpoly, nullptr, mloop, mloopuv, totpoly, totvert, limit, false, false); + polys.data(), nullptr, loops.data(), mloopuv, polys.size(), totvert, limit, false, false); - uv_indices_.resize(totpoly); + uv_indices_.resize(polys.size()); /* At least total vertices of a mesh will be present in its texture map. So * reserve minimum space early. */ uv_coords_.reserve(totvert); @@ -311,11 +317,11 @@ void OBJMesh::store_uv_coords_and_indices() if (uv_vert->separate) { tot_uv_vertices_ += 1; } - const int vertices_in_poly = mpoly[uv_vert->poly_index].totloop; + const int vertices_in_poly = polys[uv_vert->poly_index].totloop; /* Store UV vertex coordinates. */ uv_coords_.resize(tot_uv_vertices_); - const int loopstart = mpoly[uv_vert->poly_index].loopstart; + const int loopstart = polys[uv_vert->poly_index].loopstart; Span<float> vert_uv_coords(mloopuv[loopstart + uv_vert->loop_of_poly_index].uv, 2); uv_coords_[tot_uv_vertices_ - 1] = float2(vert_uv_coords[0], vert_uv_coords[1]); @@ -341,10 +347,11 @@ Span<int> OBJMesh::calc_poly_uv_indices(const int poly_index) const float3 OBJMesh::calc_poly_normal(const int poly_index) const { float3 r_poly_normal; - const MPoly &poly = export_mesh_eval_->mpoly[poly_index]; - const MLoop &mloop = export_mesh_eval_->mloop[poly.loopstart]; - const MVert &mvert = *(export_mesh_eval_->mvert); - BKE_mesh_calc_poly_normal(&poly, &mloop, &mvert, r_poly_normal); + const Span<MVert> verts = export_mesh_eval_->vertices(); + const Span<MPoly> polys = export_mesh_eval_->polygons(); + const Span<MLoop> loops = export_mesh_eval_->loops(); + const MPoly &poly = polys[poly_index]; + BKE_mesh_calc_poly_normal(&poly, &loops[poly.loopstart], verts.data(), r_poly_normal); mul_m3_v3(world_and_axes_normal_transform_, r_poly_normal); normalize_v3(r_poly_normal); return r_poly_normal; @@ -368,6 +375,8 @@ static float3 round_float3_to_n_digits(const float3 &v, int round_digits) void OBJMesh::store_normal_coords_and_indices() { + const Span<MPoly> polys = export_mesh_eval_->polygons(); + /* We'll round normal components to 4 digits. * This will cover up some minor differences * between floating point calculations on different platforms. @@ -383,7 +392,7 @@ void OBJMesh::store_normal_coords_and_indices() const float(*lnors)[3] = static_cast<const float(*)[3]>( CustomData_get_layer(&export_mesh_eval_->ldata, CD_NORMAL)); for (int poly_index = 0; poly_index < export_mesh_eval_->totpoly; ++poly_index) { - const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index]; + const MPoly &mpoly = polys[poly_index]; bool need_per_loop_normals = lnors != nullptr || (mpoly.flag & ME_SMOOTH); if (need_per_loop_normals) { for (int loop_of_poly = 0; loop_of_poly < mpoly.totloop; ++loop_of_poly) { @@ -427,7 +436,8 @@ Vector<int> OBJMesh::calc_poly_normal_indices(const int poly_index) const if (loop_to_normal_index_.is_empty()) { return {}; } - const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index]; + const Span<MPoly> polys = export_mesh_eval_->polygons(); + const MPoly &mpoly = polys[poly_index]; const int totloop = mpoly.totloop; Vector<int> r_poly_normal_indices(totloop); for (int poly_loop_index = 0; poly_loop_index < totloop; poly_loop_index++) { @@ -450,23 +460,23 @@ int16_t OBJMesh::get_poly_deform_group_index(const int poly_index, { BLI_assert(poly_index < export_mesh_eval_->totpoly); BLI_assert(group_weights.size() == BKE_object_defgroup_count(&export_object_eval_)); - - const MDeformVert *dvert_layer = static_cast<const MDeformVert *>( - CustomData_get_layer(&export_mesh_eval_->vdata, CD_MDEFORMVERT)); - if (!dvert_layer) { + const Span<MPoly> polys = export_mesh_eval_->polygons(); + const Span<MLoop> loops = export_mesh_eval_->loops(); + const Span<MDeformVert> dverts = export_mesh_eval_->deform_verts(); + if (dverts.is_empty()) { return NOT_FOUND; } group_weights.fill(0); bool found_any_group = false; - const MPoly &mpoly = export_mesh_eval_->mpoly[poly_index]; - const MLoop *mloop = &export_mesh_eval_->mloop[mpoly.loopstart]; + const MPoly &mpoly = polys[poly_index]; + const MLoop *mloop = &loops[mpoly.loopstart]; for (int loop_i = 0; loop_i < mpoly.totloop; ++loop_i, ++mloop) { - const MDeformVert &dvert = dvert_layer[mloop->v]; - for (int weight_i = 0; weight_i < dvert.totweight; ++weight_i) { - const auto group = dvert.dw[weight_i].def_nr; + const MDeformVert &dv = dverts[mloop->v]; + for (int weight_i = 0; weight_i < dv.totweight; ++weight_i) { + const auto group = dv.dw[weight_i].def_nr; if (group < group_weights.size()) { - group_weights[group] += dvert.dw[weight_i].weight; + group_weights[group] += dv.dw[weight_i].weight; found_any_group = true; } } @@ -490,7 +500,8 @@ const char *OBJMesh::get_poly_deform_group_name(const int16_t def_group_index) c std::optional<std::array<int, 2>> OBJMesh::calc_loose_edge_vert_indices(const int edge_index) const { - const MEdge &edge = export_mesh_eval_->medge[edge_index]; + const Span<MEdge> edges = export_mesh_eval_->edges(); + const MEdge &edge = edges[edge_index]; if (edge.flag & ME_LOOSEEDGE) { return std::array<int, 2>{static_cast<int>(edge.v1), static_cast<int>(edge.v2)}; } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index e01b64d7885..4b4609c053b 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -158,6 +158,7 @@ void MeshFromGeometry::fixup_invalid_faces() void MeshFromGeometry::create_vertices(Mesh *mesh) { + MutableSpan<MVert> verts = mesh->vertices_for_write(); /* Go through all the global vertex indices from min to max, * checking which ones are actually and building a global->local * index mapping. Write out the used vertex positions into the Mesh @@ -171,20 +172,21 @@ void MeshFromGeometry::create_vertices(Mesh *mesh) } int local_vi = (int)mesh_geometry_.global_to_local_vertices_.size(); BLI_assert(local_vi >= 0 && local_vi < mesh->totvert); - copy_v3_v3(mesh->mvert[local_vi].co, global_vertices_.vertices[vi]); + copy_v3_v3(verts[local_vi].co, global_vertices_.vertices[vi]); mesh_geometry_.global_to_local_vertices_.add_new(vi, local_vi); } } void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) { - mesh->dvert = nullptr; + MutableSpan<MDeformVert> dverts; const int64_t total_verts = mesh_geometry_.get_vertex_count(); if (use_vertex_groups && total_verts && mesh_geometry_.has_vertex_groups_) { - mesh->dvert = static_cast<MDeformVert *>( - CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, total_verts)); + dverts = mesh->deform_verts_for_write(); } + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); bke::SpanAttributeWriter<int> material_indices = bke::mesh_attributes_for_write(*mesh).lookup_or_add_for_write_only_span<int>( "material_index", ATTR_DOMAIN_FACE); @@ -200,7 +202,7 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) continue; } - MPoly &mpoly = mesh->mpoly[poly_idx]; + MPoly &mpoly = polys[poly_idx]; mpoly.totloop = curr_face.corner_count_; mpoly.loopstart = tot_loop_idx; if (curr_face.shaded_smooth) { @@ -215,16 +217,16 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) for (int idx = 0; idx < curr_face.corner_count_; ++idx) { const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx]; - MLoop &mloop = mesh->mloop[tot_loop_idx]; + MLoop &mloop = loops[tot_loop_idx]; tot_loop_idx++; mloop.v = mesh_geometry_.global_to_local_vertices_.lookup_default(curr_corner.vert_index, 0); /* Setup vertex group data, if needed. */ - if (!mesh->dvert) { + if (dverts.is_empty()) { continue; } const int group_index = curr_face.vertex_group_index; - MDeformWeight *dw = BKE_defvert_ensure_index(mesh->dvert + mloop.v, group_index); + MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index); dw->weight = 1.0f; } } @@ -235,7 +237,7 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) void MeshFromGeometry::create_vertex_groups(Object *obj) { Mesh *mesh = static_cast<Mesh *>(obj->data); - if (mesh->dvert == nullptr) { + if (mesh->deform_verts().is_empty()) { return; } for (const std::string &name : mesh_geometry_.group_order_) { @@ -245,12 +247,14 @@ void MeshFromGeometry::create_vertex_groups(Object *obj) void MeshFromGeometry::create_edges(Mesh *mesh) { + MutableSpan<MEdge> edges = mesh->edges_for_write(); + const int64_t tot_edges{mesh_geometry_.edges_.size()}; const int64_t total_verts{mesh_geometry_.get_vertex_count()}; UNUSED_VARS_NDEBUG(total_verts); for (int i = 0; i < tot_edges; ++i) { const MEdge &src_edge = mesh_geometry_.edges_[i]; - MEdge &dst_edge = mesh->medge[i]; + MEdge &dst_edge = edges[i]; dst_edge.v1 = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge.v1, 0); dst_edge.v2 = mesh_geometry_.global_to_local_vertices_.lookup_default(src_edge.v2, 0); BLI_assert(dst_edge.v1 < total_verts && dst_edge.v2 < total_verts); diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index 35f977f41df..669a7ba80cf 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -8,6 +8,7 @@ #include "BKE_curve.h" #include "BKE_customdata.h" #include "BKE_main.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_scene.h" @@ -95,8 +96,9 @@ class obj_importer_test : public BlendfileLoadingBaseTest { EXPECT_EQ(mesh->totedge, exp.mesh_totedge_or_curve_endp); EXPECT_EQ(mesh->totpoly, exp.mesh_totpoly_or_curve_order); EXPECT_EQ(mesh->totloop, exp.mesh_totloop_or_curve_cyclic); - EXPECT_V3_NEAR(mesh->mvert[0].co, exp.vert_first, 0.0001f); - EXPECT_V3_NEAR(mesh->mvert[mesh->totvert - 1].co, exp.vert_last, 0.0001f); + const Span<MVert> verts = mesh->vertices(); + EXPECT_V3_NEAR(verts.first().co, exp.vert_first, 0.0001f); + EXPECT_V3_NEAR(verts.last().co, exp.vert_last, 0.0001f); const float3 *lnors = (const float3 *)(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0); EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f); diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 9912ec8ec3b..6b48f1e029f 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -10,8 +10,17 @@ #include "DNA_ID.h" #include "DNA_customdata_types.h" #include "DNA_defs.h" +#include "DNA_meshdata_types.h" #include "DNA_session_uuid_types.h" +/** Workaround to forward-declare C++ type in C header. */ +#ifdef __cplusplus +namespace blender { +template<typename T> class Span; +template<typename T> class MutableSpan; +} // namespace blender +#endif + #ifdef __cplusplus extern "C" { #endif @@ -23,11 +32,8 @@ struct Key; struct MCol; struct MEdge; struct MFace; -struct MLoop; struct MLoopCol; struct MLoopTri; -struct MLoopUV; -struct MPoly; struct MVert; struct Material; struct Mesh; @@ -166,30 +172,6 @@ typedef struct Mesh { */ struct Material **mat; - /** - * Array of vertices. Edges and faces are defined by indices into this array. - * \note This pointer is for convenient access to the #CD_MVERT layer in #vdata. - */ - struct MVert *mvert; - /** - * Array of edges, containing vertex indices. For simple triangle or quad meshes, edges could be - * calculated from the #MPoly and #MLoop arrays, however, edges need to be stored explicitly to - * edge domain attributes and to support loose edges that aren't connected to faces. - * \note This pointer is for convenient access to the #CD_MEDGE layer in #edata. - */ - struct MEdge *medge; - /** - * Face topology storage of the size and offset of each face's section of the #mloop face corner - * array. Also stores various flags and the `material_index` attribute. - * \note This pointer is for convenient access to the #CD_MPOLY layer in #pdata. - */ - struct MPoly *mpoly; - /** - * The vertex and edge index at each face corner. - * \note This pointer is for convenient access to the #CD_MLOOP layer in #ldata. - */ - struct MLoop *mloop; - /** The number of vertices (#MVert) in the mesh, and the size of #vdata. */ int totvert; /** The number of edges (#MEdge) in the mesh, and the size of #edata. */ @@ -201,8 +183,6 @@ typedef struct Mesh { CustomData vdata, edata, pdata, ldata; - /** "Vertex group" vertices. */ - struct MDeformVert *dvert; /** * List of vertex group (#bDeformGroup) names and flags only. Actual weights are stored in dvert. * \note This pointer is for convenient access to the #CD_MDEFORMVERT layer in #vdata. @@ -218,18 +198,6 @@ typedef struct Mesh { int attributes_active_index; /** - * 2D vector data used for UVs. "UV" data can also be stored as generic attributes in #ldata. - * \note This pointer is for convenient access to the #CD_MLOOPUV layer in #ldata. - */ - struct MLoopUV *mloopuv; - /** - * The active vertex corner color layer, if it exists. Also called "Vertex Color" in Blender's - * UI, even though it is stored per face corner. - * \note This pointer is for convenient access to the #CD_PROP_BYTE_COLOR layer in #ldata. - */ - struct MLoopCol *mloopcol; - - /** * Runtime storage of the edit mode mesh. If it exists, it generally has the most up-to-date * information about the mesh. * \note When the object is available, the preferred access method is #BKE_editmesh_from_object. @@ -304,29 +272,32 @@ typedef struct Mesh { char subdivr DNA_DEPRECATED; char subsurftype DNA_DEPRECATED; - /** - * Deprecated. Store of runtime data for tessellation face UVs and texture. - * - * \note This would be marked deprecated, however the particles still use this at run-time - * for placing particles on the mesh (something which should be eventually upgraded). - */ - struct MTFace *mtface; + /** Deprecated pointer to mesh polygons, kept for forward compatibility. */ + struct MPoly *mpoly DNA_DEPRECATED; + /** Deprecated pointer to face corners, kept for forward compatibility. */ + struct MLoop *mloop DNA_DEPRECATED; + + /** Deprecated array of mesh vertices, kept for reading old files, now stored in #CustomData. */ + struct MVert *mvert DNA_DEPRECATED; + /** Deprecated array of mesh edges, kept for reading old files, now stored in #CustomData. */ + struct MEdge *medge DNA_DEPRECATED; + /** Deprecated "Vertex group" data. Kept for reading old files, now stored in #CustomData.*/ + struct MDeformVert *dvert DNA_DEPRECATED; + /** Deprecated runtime data for tessellation face UVs and texture, kept for reading old files. */ + struct MTFace *mtface DNA_DEPRECATED; /** Deprecated, use mtface. */ struct TFace *tface DNA_DEPRECATED; - - /* Deprecated. Array of colors for the tessellated faces, must be number of tessellated - * faces * 4 in length. This is stored in #fdata, and deprecated. */ - struct MCol *mcol; + /** Deprecated array of colors for the tessellated faces, kept for reading old files. */ + struct MCol *mcol DNA_DEPRECATED; + /** Deprecated face storage (quads & triangles only). Kept for reading old files. */ + struct MFace *mface DNA_DEPRECATED; /** - * Deprecated face storage (quads & triangles only); - * faces are now pointed to by #Mesh.mpoly and #Mesh.mloop. + * Deprecated storage of old faces (only triangles or quads). * * \note This would be marked deprecated, however the particles still use this at run-time * for placing particles on the mesh (something which should be eventually upgraded). */ - struct MFace *mface; - /* Deprecated storage of old faces (only triangles or quads). */ CustomData fdata; /* Deprecated size of #fdata. */ int totface; @@ -345,6 +316,45 @@ typedef struct Mesh { void *_pad2; Mesh_Runtime runtime; +#ifdef __cplusplus + /** + * Array of vertex positions (and various other data). Edges and faces are defined by indices + * into this array. + */ + blender::Span<MVert> vertices() const; + /** Write access to vertex data. */ + blender::MutableSpan<MVert> vertices_for_write(); + /** + * Array of edges, containing vertex indices. For simple triangle or quad meshes, edges could be + * calculated from the #MPoly and #MLoop arrays, however, edges need to be stored explicitly to + * edge domain attributes and to support loose edges that aren't connected to faces. + */ + blender::Span<MEdge> edges() const; + /** Write access to edge data. */ + blender::MutableSpan<MEdge> edges_for_write(); + /** + * Face topology storage of the size and offset of each face's section of the face corners. + */ + blender::Span<MPoly> polygons() const; + /** Write access to polygon data. */ + blender::MutableSpan<MPoly> polygons_for_write(); + /** + * Mesh face corners that "loop" around each face, storing the vertex index and the index of the + * subsequent edge. + */ + blender::Span<MLoop> loops() const; + /** Write access to loop data. */ + blender::MutableSpan<MLoop> loops_for_write(); + + /** + * Vertex group data, encoded as an array of indices and weights for every vertex. + * \warning: May be empty. + */ + blender::Span<MDeformVert> deform_verts() const; + /** Write access to vertex group data. */ + blender::MutableSpan<MDeformVert> deform_verts_for_write(); + +#endif } Mesh; /* deprecated by MTFace, only here for file reading */ diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 6979b65cfc9..f63d91d5943 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -348,7 +348,7 @@ static int rna_MeshVertex_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); const MVert *vert = (MVert *)ptr->data; - const int index = (int)(vert - mesh->mvert); + const int index = (int)(vert - BKE_mesh_vertices(mesh)); BLI_assert(index >= 0); BLI_assert(index < mesh->totvert); return index; @@ -358,7 +358,7 @@ static int rna_MeshEdge_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); const MEdge *edge = (MEdge *)ptr->data; - const int index = (int)(edge - mesh->medge); + const int index = (int)(edge - BKE_mesh_edges(mesh)); BLI_assert(index >= 0); BLI_assert(index < mesh->totedge); return index; @@ -368,7 +368,7 @@ static int rna_MeshPolygon_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); const MPoly *mpoly = (MPoly *)ptr->data; - const int index = (int)(mpoly - mesh->mpoly); + const int index = (int)(mpoly - BKE_mesh_polygons(mesh)); BLI_assert(index >= 0); BLI_assert(index < mesh->totpoly); return index; @@ -378,7 +378,7 @@ static int rna_MeshLoop_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); const MLoop *mloop = (MLoop *)ptr->data; - const int index = (int)(mloop - mesh->mloop); + const int index = (int)(mloop - BKE_mesh_loops(mesh)); BLI_assert(index >= 0); BLI_assert(index < mesh->totloop); return index; @@ -532,8 +532,9 @@ static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); MPoly *mp = (MPoly *)ptr->data; - - BKE_mesh_calc_poly_normal(mp, me->mloop + mp->loopstart, me->mvert, values); + const MVert *verts = BKE_mesh_vertices(me); + const MLoop *loops = BKE_mesh_loops(me); + BKE_mesh_calc_poly_normal(mp, loops + mp->loopstart, verts, values); } static bool rna_MeshPolygon_hide_get(PointerRNA *ptr) @@ -582,23 +583,25 @@ static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); MPoly *mp = (MPoly *)ptr->data; - - BKE_mesh_calc_poly_center(mp, me->mloop + mp->loopstart, me->mvert, values); + const MVert *verts = BKE_mesh_vertices(me); + const MLoop *loops = BKE_mesh_loops(me); + BKE_mesh_calc_poly_center(mp, loops + mp->loopstart, verts, values); } static float rna_MeshPolygon_area_get(PointerRNA *ptr) { Mesh *me = (Mesh *)ptr->owner_id; MPoly *mp = (MPoly *)ptr->data; - - return BKE_mesh_calc_poly_area(mp, me->mloop + mp->loopstart, me->mvert); + const MVert *verts = BKE_mesh_vertices(me); + const MLoop *loops = BKE_mesh_loops(me); + return BKE_mesh_calc_poly_area(mp, loops + mp->loopstart, verts); } static void rna_MeshPolygon_flip(ID *id, MPoly *mp) { Mesh *me = (Mesh *)id; - - BKE_mesh_polygon_flip(mp, me->mloop, &me->ldata); + MLoop *loops = BKE_mesh_loops_for_write(me); + BKE_mesh_polygon_flip(mp, loops, &me->ldata); BKE_mesh_tessface_clear(me); BKE_mesh_runtime_clear_geometry(me); BKE_mesh_normals_tag_dirty(me); @@ -607,21 +610,24 @@ static void rna_MeshPolygon_flip(ID *id, MPoly *mp) static void rna_MeshLoopTriangle_verts_get(PointerRNA *ptr, int *values) { Mesh *me = rna_mesh(ptr); + const MLoop *loops = BKE_mesh_loops(me); MLoopTri *lt = (MLoopTri *)ptr->data; - values[0] = me->mloop[lt->tri[0]].v; - values[1] = me->mloop[lt->tri[1]].v; - values[2] = me->mloop[lt->tri[2]].v; + values[0] = loops[lt->tri[0]].v; + values[1] = loops[lt->tri[1]].v; + values[2] = loops[lt->tri[2]].v; } static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); MLoopTri *lt = (MLoopTri *)ptr->data; - unsigned int v1 = me->mloop[lt->tri[0]].v; - unsigned int v2 = me->mloop[lt->tri[1]].v; - unsigned int v3 = me->mloop[lt->tri[2]].v; + const MVert *verts = BKE_mesh_vertices(me); + const MLoop *loops = BKE_mesh_loops(me); + unsigned int v1 = loops[lt->tri[0]].v; + unsigned int v2 = loops[lt->tri[1]].v; + unsigned int v3 = loops[lt->tri[2]].v; - normal_tri_v3(values, me->mvert[v1].co, me->mvert[v2].co, me->mvert[v3].co); + normal_tri_v3(values, verts[v1].co, verts[v2].co, verts[v3].co); } static void rna_MeshLoopTriangle_split_normals_get(PointerRNA *ptr, float *values) @@ -646,11 +652,12 @@ static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); MLoopTri *lt = (MLoopTri *)ptr->data; - unsigned int v1 = me->mloop[lt->tri[0]].v; - unsigned int v2 = me->mloop[lt->tri[1]].v; - unsigned int v3 = me->mloop[lt->tri[2]].v; - - return area_tri_v3(me->mvert[v1].co, me->mvert[v2].co, me->mvert[v3].co); + const MVert *verts = BKE_mesh_vertices(me); + const MLoop *loops = BKE_mesh_loops(me); + unsigned int v1 = loops[lt->tri[0]].v; + unsigned int v2 = loops[lt->tri[1]].v; + unsigned int v3 = loops[lt->tri[2]].v; + return area_tri_v3(verts[v1].co, verts[v2].co, verts[v3].co); } static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values) @@ -700,10 +707,10 @@ static void rna_Mesh_texspace_loc_get(PointerRNA *ptr, float values[3]) static void rna_MeshVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); - - if (me->dvert) { + MDeformVert *dverts = (MDeformVert *)BKE_mesh_deform_verts(me); + if (dverts) { const int index = rna_MeshVertex_index_get(ptr); - MDeformVert *dvert = &me->dvert[index]; + MDeformVert *dvert = &dverts[index]; rna_iterator_array_begin( iter, (void *)dvert->dw, sizeof(MDeformWeight), dvert->totweight, 0, NULL); @@ -768,7 +775,7 @@ static void rna_CustomDataLayer_active_set( CustomData_set_layer_active(data, type, n); } - BKE_mesh_update_customdata_pointers(me, true); + BKE_mesh_tessface_clear(me); } static void rna_CustomDataLayer_clone_set(PointerRNA *ptr, CustomData *data, int value, int type) @@ -1258,7 +1265,8 @@ static void rna_MeshPoly_vertices_get(PointerRNA *ptr, int *values) { Mesh *me = rna_mesh(ptr); MPoly *mp = (MPoly *)ptr->data; - MLoop *ml = &me->mloop[mp->loopstart]; + const MLoop *loops = BKE_mesh_loops(me); + const MLoop *ml = &loops[mp->loopstart]; unsigned int i; for (i = mp->totloop; i > 0; i--, values++, ml++) { *values = ml->v; @@ -1268,8 +1276,10 @@ static void rna_MeshPoly_vertices_get(PointerRNA *ptr, int *values) static void rna_MeshPoly_vertices_set(PointerRNA *ptr, const int *values) { Mesh *me = rna_mesh(ptr); - MPoly *mp = (MPoly *)ptr->data; - MLoop *ml = &me->mloop[mp->loopstart]; + const MPoly *mp = (const MPoly *)ptr->data; + MLoop *loops = BKE_mesh_loops_for_write(me); + + MLoop *ml = &loops[mp->loopstart]; unsigned int i; for (i = mp->totloop; i > 0; i--, values++, ml++) { ml->v = *values; @@ -1325,7 +1335,8 @@ static bool rna_MeshLoopTriangle_use_smooth_get(PointerRNA *ptr) { const Mesh *me = rna_mesh(ptr); const MLoopTri *ltri = (MLoopTri *)ptr->data; - return me->mpoly[ltri->poly].flag & ME_SMOOTH; + const MPoly *polys = BKE_mesh_polygons(me); + return polys[ltri->poly].flag & ME_SMOOTH; } /* path construction */ @@ -1334,10 +1345,10 @@ static char *rna_VertexGroupElement_path(const PointerRNA *ptr) { const Mesh *me = rna_mesh(ptr); /* XXX not always! */ const MDeformWeight *dw = (MDeformWeight *)ptr->data; - const MDeformVert *dvert; + const MDeformVert *dvert = BKE_mesh_deform_verts(me); int a, b; - for (a = 0, dvert = me->dvert; a < me->totvert; a++, dvert++) { + for (a = 0; a < me->totvert; a++, dvert++) { for (b = 0; b < dvert->totweight; b++) { if (dw == &dvert->dw[b]) { return BLI_sprintfN("vertices[%d].groups[%d]", a, b); @@ -1437,6 +1448,98 @@ static char *rna_LoopCustomData_data_path(const PointerRNA *ptr, const char *col return NULL; } +static void rna_Mesh_vertices_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *mesh = rna_mesh(ptr); + rna_iterator_array_begin( + iter, BKE_mesh_vertices_for_write(mesh), sizeof(MVert), mesh->totvert, false, NULL); +} +static int rna_Mesh_vertices_length(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + return mesh->totvert; +} +int rna_Mesh_vertices_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + Mesh *mesh = rna_mesh(ptr); + if (index < 0 || index >= mesh->totvert) { + return false; + } + r_ptr->owner_id = &mesh->id; + r_ptr->type = &RNA_MeshVertex; + r_ptr->data = &BKE_mesh_vertices_for_write(mesh)[index]; + return true; +} + +static void rna_Mesh_edges_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *mesh = rna_mesh(ptr); + rna_iterator_array_begin( + iter, BKE_mesh_edges_for_write(mesh), sizeof(MEdge), mesh->totedge, false, NULL); +} +static int rna_Mesh_edges_length(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + return mesh->totedge; +} +int rna_Mesh_edges_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + Mesh *mesh = rna_mesh(ptr); + if (index < 0 || index >= mesh->totedge) { + return false; + } + r_ptr->owner_id = &mesh->id; + r_ptr->type = &RNA_MeshEdge; + r_ptr->data = &BKE_mesh_edges_for_write(mesh)[index]; + return true; +} + +static void rna_Mesh_polygons_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *mesh = rna_mesh(ptr); + rna_iterator_array_begin( + iter, BKE_mesh_polygons_for_write(mesh), sizeof(MPoly), mesh->totpoly, false, NULL); +} +static int rna_Mesh_polygons_length(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + return mesh->totpoly; +} +int rna_Mesh_polygons_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + Mesh *mesh = rna_mesh(ptr); + if (index < 0 || index >= mesh->totpoly) { + return false; + } + r_ptr->owner_id = &mesh->id; + r_ptr->type = &RNA_MeshPolygon; + r_ptr->data = &BKE_mesh_polygons_for_write(mesh)[index]; + return true; +} + +static void rna_Mesh_loops_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Mesh *mesh = rna_mesh(ptr); + rna_iterator_array_begin( + iter, BKE_mesh_loops_for_write(mesh), sizeof(MLoop), mesh->totloop, false, NULL); +} +static int rna_Mesh_loops_length(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + return mesh->totloop; +} +int rna_Mesh_loops_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + Mesh *mesh = rna_mesh(ptr); + if (index < 0 || index >= mesh->totloop) { + return false; + } + r_ptr->owner_id = &mesh->id; + r_ptr->type = &RNA_MeshLoop; + r_ptr->data = &BKE_mesh_loops_for_write(mesh)[index]; + return true; +} + static void rna_Mesh_vertex_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); @@ -3267,28 +3370,60 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_struct_ui_icon(srna, ICON_MESH_DATA); prop = RNA_def_property(srna, "vertices", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "mvert", "totvert"); + RNA_def_property_collection_funcs(prop, + "rna_Mesh_vertices_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Mesh_vertices_length", + "rna_Mesh_vertices_lookup_int", + NULL, + NULL); RNA_def_property_struct_type(prop, "MeshVertex"); RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text(prop, "Vertices", "Vertices of the mesh"); rna_def_mesh_vertices(brna, prop); prop = RNA_def_property(srna, "edges", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "medge", "totedge"); + RNA_def_property_collection_funcs(prop, + "rna_Mesh_edges_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Mesh_edges_length", + "rna_Mesh_edges_lookup_int", + NULL, + NULL); RNA_def_property_struct_type(prop, "MeshEdge"); RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text(prop, "Edges", "Edges of the mesh"); rna_def_mesh_edges(brna, prop); prop = RNA_def_property(srna, "loops", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "mloop", "totloop"); + RNA_def_property_collection_funcs(prop, + "rna_Mesh_loops_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Mesh_loops_length", + "rna_Mesh_loops_lookup_int", + NULL, + NULL); RNA_def_property_struct_type(prop, "MeshLoop"); RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text(prop, "Loops", "Loops of the mesh (polygon corners)"); rna_def_mesh_loops(brna, prop); prop = RNA_def_property(srna, "polygons", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "mpoly", "totpoly"); + RNA_def_property_collection_funcs(prop, + "rna_Mesh_polygons_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Mesh_polygons_length", + "rna_Mesh_polygons_lookup_int", + NULL, + NULL); RNA_def_property_struct_type(prop, "MeshPolygon"); RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text(prop, "Polygons", "Polygons of the mesh"); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 41b0d0b0bfd..4c0707ba186 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -90,11 +90,11 @@ static void rna_Mesh_calc_smooth_groups( Mesh *mesh, bool use_bitflags, int *r_poly_group_len, int **r_poly_group, int *r_group_total) { *r_poly_group_len = mesh->totpoly; - *r_poly_group = BKE_mesh_calc_smoothgroups(mesh->medge, + *r_poly_group = BKE_mesh_calc_smoothgroups(BKE_mesh_edges(mesh), mesh->totedge, - mesh->mpoly, + BKE_mesh_polygons(mesh), mesh->totpoly, - mesh->mloop, + BKE_mesh_loops(mesh), mesh->totloop, r_group_total, use_bitflags); @@ -165,7 +165,8 @@ static void rna_Mesh_transform(Mesh *mesh, float mat[16], bool shape_keys) static void rna_Mesh_flip_normals(Mesh *mesh) { - BKE_mesh_polygons_flip(mesh->mpoly, mesh->mloop, &mesh->ldata, mesh->totpoly); + BKE_mesh_polygons_flip( + BKE_mesh_polygons(mesh), BKE_mesh_loops_for_write(mesh), &mesh->ldata, mesh->totpoly); BKE_mesh_tessface_clear(mesh); BKE_mesh_normals_tag_dirty(mesh); BKE_mesh_runtime_clear_geometry(mesh); diff --git a/source/blender/makesrna/intern/rna_mesh_utils.h b/source/blender/makesrna/intern/rna_mesh_utils.h index 0b1a8ddcb4d..495c58d7b30 100644 --- a/source/blender/makesrna/intern/rna_mesh_utils.h +++ b/source/blender/makesrna/intern/rna_mesh_utils.h @@ -81,7 +81,7 @@ layer++, a++) { \ if (value.data == layer) { \ CustomData_set_layer_##active_type(data, layer_type, a); \ - BKE_mesh_update_customdata_pointers(me, true); \ + BKE_mesh_tessface_clear(me); \ return; \ } \ } \ @@ -105,6 +105,6 @@ CustomData *data = rna_mesh_##customdata_type(ptr); \ if (data) { \ CustomData_set_layer_##active_type(data, layer_type, value); \ - BKE_mesh_update_customdata_pointers(me, true); \ + BKE_mesh_tessface_clear(me); \ } \ } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index e4bddd1f3c7..d9ef30d6f7f 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -212,9 +212,9 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu if (pa) { Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; - + const MVert *vertices = BKE_mesh_vertices(hair_mesh); if (hair_mesh) { - MVert *mvert = &hair_mesh->mvert[pa->hair_index + (hkey - pa->hair)]; + const MVert *mvert = &vertices[pa->hair_index + (hkey - pa->hair)]; copy_v3_v3(values, mvert->co); } else { @@ -279,8 +279,8 @@ static void hair_key_location_object_set(HairKey *hair_key, if (hair_key_index == -1) { return; } - - MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hair_key_index)]; + MVert *vertices = BKE_mesh_vertices_for_write(hair_mesh); + MVert *mvert = &vertices[particle->hair_index + (hair_key_index)]; copy_v3_v3(mvert->co, src_co); return; } @@ -324,7 +324,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, NULL; if (particle) { if (hair_mesh) { - MVert *mvert = &hair_mesh->mvert[particle->hair_index + (hairkey - particle->hair)]; + const MVert *vertices = BKE_mesh_vertices(hair_mesh); + const MVert *mvert = &vertices[particle->hair_index + (hairkey - particle->hair)]; copy_v3_v3(n_co, mvert->co); } else { @@ -402,8 +403,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, MFace *mface; MTFace *mtface; - mface = modifier->mesh_final->mface; - mtface = modifier->mesh_final->mtface; + mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + mtface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MTFACE); if (mface && mtface) { mtface += num; @@ -567,7 +568,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = modifier->mesh_final->mface; + MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); *r_fuv = &particle->fuv; @@ -610,7 +611,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = modifier->mesh_final->mface; + MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); *r_fuv = &parent->fuv; @@ -660,7 +661,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, zero_v2(r_uv); } else { - MFace *mface = &modifier->mesh_final->mface[num]; + MFace *mfaces = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + MFace *mface = &mfaces[num]; const MTFace *mtface = (const MTFace *)CustomData_get_layer_n( &modifier->mesh_final->fdata, CD_MTFACE, uv_no); @@ -694,7 +696,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, zero_v3(r_mcol); } else { - MFace *mface = &modifier->mesh_final->mface[num]; + MFace *mfaces = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + MFace *mface = &mfaces[num]; const MCol *mc = (const MCol *)CustomData_get_layer_n( &modifier->mesh_final->fdata, CD_MCOL, vcol_no); MCol mcol; diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index b29b34436ca..3bba1ac07a6 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -279,13 +279,17 @@ static void mesh_merge_transform(Mesh *result, MEdge *me; MLoop *ml; MPoly *mp; + MVert *result_verts = BKE_mesh_vertices_for_write(result); + MEdge *result_edges = BKE_mesh_edges_for_write(result); + MPoly *result_polys = BKE_mesh_polygons_for_write(result); + MLoop *result_loops = BKE_mesh_loops_for_write(result); CustomData_copy_data(&cap_mesh->vdata, &result->vdata, 0, cap_verts_index, cap_nverts); CustomData_copy_data(&cap_mesh->edata, &result->edata, 0, cap_edges_index, cap_nedges); CustomData_copy_data(&cap_mesh->ldata, &result->ldata, 0, cap_loops_index, cap_nloops); CustomData_copy_data(&cap_mesh->pdata, &result->pdata, 0, cap_polys_index, cap_npolys); - mv = result->mvert + cap_verts_index; + mv = result_verts + cap_verts_index; for (i = 0; i < cap_nverts; i++, mv++) { mul_m4_v3(cap_offset, mv->co); @@ -303,26 +307,26 @@ static void mesh_merge_transform(Mesh *result, } /* remap the vertex groups if necessary */ - if (result->dvert != NULL) { - BKE_object_defgroup_index_map_apply( - &result->dvert[cap_verts_index], cap_nverts, remap, remap_len); + if (BKE_mesh_deform_verts(result) != NULL) { + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result); + BKE_object_defgroup_index_map_apply(&dvert[cap_verts_index], cap_nverts, remap, remap_len); } /* adjust cap edge vertex indices */ - me = result->medge + cap_edges_index; + me = result_edges + cap_edges_index; for (i = 0; i < cap_nedges; i++, me++) { me->v1 += cap_verts_index; me->v2 += cap_verts_index; } /* adjust cap poly loopstart indices */ - mp = result->mpoly + cap_polys_index; + mp = result_polys + cap_polys_index; for (i = 0; i < cap_npolys; i++, mp++) { mp->loopstart += cap_loops_index; } /* adjust cap loop vertex and edge indices */ - ml = result->mloop + cap_loops_index; + ml = result_loops + cap_loops_index; for (i = 0; i < cap_nloops; i++, ml++) { ml->v += cap_verts_index; ml->e += cap_edges_index; @@ -352,11 +356,8 @@ static void mesh_merge_transform(Mesh *result, static Mesh *arrayModifier_doArray(ArrayModifierData *amd, const ModifierEvalContext *ctx, - Mesh *mesh) + const Mesh *mesh) { - const MVert *src_mvert; - MVert *result_dm_verts; - MEdge *me; MLoop *ml; MPoly *mp; @@ -429,7 +430,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Build up offset array, accumulating all settings options. */ unit_m4(offset); - src_mvert = mesh->mvert; + const MVert *src_verts = BKE_mesh_vertices(mesh); + const MEdge *src_edges = BKE_mesh_edges(mesh); + const MPoly *src_polys = BKE_mesh_polygons(mesh); + const MLoop *src_loops = BKE_mesh_loops(mesh); if (amd->offset_type & MOD_ARR_OFF_CONST) { add_v3_v3(offset[3], amd->offset); @@ -440,7 +444,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, const MVert *src_mv; INIT_MINMAX(min, max); - for (src_mv = src_mvert, j = chunk_nverts; j--; src_mv++) { + for (src_mv = src_verts, j = chunk_nverts; j--; src_mv++) { minmax_v3v3_v3(min, max, src_mv->co); } @@ -539,7 +543,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Initialize a result dm */ result = BKE_mesh_new_nomain_from_template( mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys); - result_dm_verts = result->mvert; + MVert *result_verts = BKE_mesh_vertices_for_write(result); + MEdge *result_edges = BKE_mesh_edges_for_write(result); + MPoly *result_polys = BKE_mesh_polygons_for_write(result); + MLoop *result_loops = BKE_mesh_loops_for_write(result); if (use_merge) { /* Will need full_doubles_map for handling merge */ @@ -556,14 +563,14 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Subsurf for eg won't have mesh data in the custom data arrays. * now add mvert/medge/mpoly layers. */ if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) { - memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert); + memcpy(result_verts, src_verts, sizeof(MVert) * mesh->totvert); } if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) { - memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge); + memcpy(result_edges, src_edges, sizeof(MEdge) * mesh->totedge); } if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) { - memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop); - memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly); + memcpy(result_loops, src_loops, sizeof(MLoop) * mesh->totloop); + memcpy(result_polys, src_polys, sizeof(MPoly) * mesh->totpoly); } /* Remember first chunk, in case of cap merge */ @@ -594,7 +601,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* apply offset to all new verts */ for (i = 0; i < chunk_nverts; i++) { const int i_dst = vert_offset + i; - mul_m4_v3(current_offset, result_dm_verts[i_dst].co); + mul_m4_v3(current_offset, result_verts[i_dst].co); /* We have to correct normals too, if we do not tag them as dirty! */ if (!use_recalc_normals) { @@ -605,19 +612,19 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } /* adjust edge vertex indices */ - me = result->medge + c * chunk_nedges; + me = result_edges + c * chunk_nedges; for (i = 0; i < chunk_nedges; i++, me++) { me->v1 += c * chunk_nverts; me->v2 += c * chunk_nverts; } - mp = result->mpoly + c * chunk_npolys; + mp = result_polys + c * chunk_npolys; for (i = 0; i < chunk_npolys; i++, mp++) { mp->loopstart += c * chunk_nloops; } /* adjust loop vertex and edge indices */ - ml = result->mloop + c * chunk_nloops; + ml = result_loops + c * chunk_nloops; for (i = 0; i < chunk_nloops; i++, ml++) { ml->v += c * chunk_nverts; ml->e += c * chunk_nedges; @@ -638,8 +645,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, while (target != -1 && !ELEM(full_doubles_map[target], -1, target)) { /* If target is already mapped, we only follow that mapping if final target remains * close enough from current vert (otherwise no mapping at all). */ - if (compare_len_v3v3(result_dm_verts[this_chunk_index].co, - result_dm_verts[full_doubles_map[target]].co, + if (compare_len_v3v3(result_verts[this_chunk_index].co, + result_verts[full_doubles_map[target]].co, amd->merge_dist)) { target = full_doubles_map[target]; } @@ -653,7 +660,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } else { dm_mvert_map_doubles(full_doubles_map, - result_dm_verts, + result_verts, (c - 1) * chunk_nverts, chunk_nverts, c * chunk_nverts, @@ -691,7 +698,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (use_merge && (amd->flags & MOD_ARR_MERGEFINAL) && (count > 1)) { /* Merge first and last copies */ dm_mvert_map_doubles(full_doubles_map, - result_dm_verts, + result_verts, last_chunk_start, last_chunk_nverts, first_chunk_start, @@ -721,7 +728,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Identify doubles with first chunk */ if (use_merge) { dm_mvert_map_doubles(full_doubles_map, - result_dm_verts, + result_verts, first_chunk_start, first_chunk_nverts, start_cap_start, @@ -751,7 +758,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Identify doubles with last chunk */ if (use_merge) { dm_mvert_map_doubles(full_doubles_map, - result_dm_verts, + result_verts, last_chunk_start, last_chunk_nverts, end_cap_start, diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 94f2090e081..ee9a2856ab0 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -88,7 +88,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BMVert *v; float weight, weight2; int vgroup = -1; - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; BevelModifierData *bmd = (BevelModifierData *)md; const float threshold = cosf(bmd->bevel_angle + 0.000000175f); const bool do_clamp = !(bmd->flags & MOD_BEVEL_OVERLAP_OK); diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 685338cf351..39667a3f1d5 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -144,11 +144,9 @@ static Mesh *get_quick_mesh( invert_m4_m4(imat, ob_self->obmat); mul_m4_m4m4(omat, imat, ob_operand_ob->obmat); - const int mverts_len = result->totvert; - MVert *mv = result->mvert; - - for (int i = 0; i < mverts_len; i++, mv++) { - mul_m4_v3(omat, mv->co); + MutableSpan<MVert> verts = result->vertices_for_write(); + for (const int i : verts.index_range()) { + mul_m4_v3(omat, verts[i].co); } BKE_mesh_tag_coords_changed(result); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index a9b6af967be..02d56560fc5 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -62,7 +62,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct int *vertMap, *edgeMap, *faceMap; float frac; MPoly *mpoly_dst; - MLoop *ml_dst, *ml_src /*, *mloop_dst */; + MLoop *ml_dst; + const MLoop *ml_src; GHashIterator gh_iter; /* maps vert indices in old mesh to indices in new mesh */ GHash *vertHash = BLI_ghash_int_new("build ve apply gh"); @@ -74,10 +75,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct const int vert_src_num = mesh->totvert; const int edge_src_num = mesh->totedge; const int poly_src_num = mesh->totpoly; - MPoly *mpoly_src = mesh->mpoly; - MLoop *mloop_src = mesh->mloop; - MEdge *medge_src = mesh->medge; - MVert *mvert_src = mesh->mvert; + const MVert *mvert_src = BKE_mesh_vertices(mesh); + const MEdge *medge_src = BKE_mesh_edges(mesh); + const MPoly *mpoly_src = BKE_mesh_polygons(mesh); + const MLoop *mloop_src = BKE_mesh_loops(mesh); vertMap = MEM_malloc_arrayN(vert_src_num, sizeof(*vertMap), "build modifier vertMap"); edgeMap = MEM_malloc_arrayN(edge_src_num, sizeof(*edgeMap), "build modifier edgeMap"); @@ -99,8 +100,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct /* if there's at least one face, build based on faces */ if (faces_dst_num) { - MPoly *mpoly, *mp; - MLoop *ml, *mloop; + const MPoly *mpoly, *mp; + const MLoop *ml, *mloop; uintptr_t hash_num, hash_num_alt; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { @@ -135,7 +136,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct hash_num = 0; hash_num_alt = 0; for (i = 0; i < edge_src_num; i++, hash_num_alt++) { - MEdge *me = medge_src + i; + const MEdge *me = medge_src + i; if (BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v1)) && BLI_ghash_haskey(vertHash, POINTER_FROM_INT(me->v2))) { @@ -147,7 +148,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct BLI_assert(hash_num == BLI_ghash_len(edgeHash)); } else if (edges_dst_num) { - MEdge *medge, *me; + const MEdge *medge, *me; uintptr_t hash_num; if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) { @@ -201,6 +202,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct /* now we know the number of verts, edges and faces, we can create the mesh. */ result = BKE_mesh_new_nomain_from_template( mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, loops_dst_num, faces_dst_num); + MVert *result_verts = BKE_mesh_vertices_for_write(result); + MEdge *result_edges = BKE_mesh_edges_for_write(result); + MPoly *result_polys = BKE_mesh_polygons_for_write(result); + MLoop *result_loops = BKE_mesh_loops_for_write(result); /* copy the vertices across */ GHASH_ITER (gh_iter, vertHash) { @@ -210,7 +215,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct int newIndex = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); source = mvert_src[oldIndex]; - dest = &result->mvert[newIndex]; + dest = &result_verts[newIndex]; CustomData_copy_data(&mesh->vdata, &result->vdata, oldIndex, newIndex, 1); *dest = source; @@ -223,7 +228,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct int oldIndex = POINTER_AS_INT(BLI_ghash_lookup(edgeHash, POINTER_FROM_INT(i))); source = medge_src[oldIndex]; - dest = &result->medge[i]; + dest = &result_edges[i]; source.v1 = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(source.v1))); source.v2 = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(source.v2))); @@ -232,13 +237,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct *dest = source; } - mpoly_dst = result->mpoly; - ml_dst = result->mloop; + mpoly_dst = result_polys; + ml_dst = result_loops; /* copy the faces across, remapping indices */ k = 0; for (i = 0; i < faces_dst_num; i++) { - MPoly *source; + const MPoly *source; MPoly *dest; source = mpoly_src + faceMap[i]; diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index e17a612376d..3f0c212999f 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -98,7 +98,7 @@ static void sphere_do(CastModifierData *cmd, float (*vertexCos)[3], int verts_num) { - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; const bool invert_vgroup = (cmd->flag & MOD_CAST_INVERT_VGROUP) != 0; Object *ctrl_ob = NULL; @@ -239,7 +239,7 @@ static void cuboid_do(CastModifierData *cmd, float (*vertexCos)[3], int verts_num) { - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; int defgrp_index; const bool invert_vgroup = (cmd->flag & MOD_CAST_INVERT_VGROUP) != 0; diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 42a8ba804ed..3ae83cb2244 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -145,7 +145,7 @@ static void deformVerts(ModifierData *md, if (collmd->time_xnew == -1000) { /* first time */ - collmd->x = MEM_dupallocN(mesh_src->mvert); /* frame start position */ + collmd->x = MEM_dupallocN(BKE_mesh_vertices(mesh_src)); /* frame start position */ for (uint i = 0; i < mvert_num; i++) { /* we save global positions */ @@ -160,7 +160,7 @@ static void deformVerts(ModifierData *md, collmd->mvert_num = mvert_num; { - const MLoop *mloop = mesh_src->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh_src); const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh_src); collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh_src); MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__); @@ -182,7 +182,7 @@ static void deformVerts(ModifierData *md, collmd->xnew = tempVert; collmd->time_x = collmd->time_xnew; - memcpy(collmd->xnew, mesh_src->mvert, mvert_num * sizeof(MVert)); + memcpy(collmd->xnew, BKE_mesh_vertices(mesh_src), mvert_num * sizeof(MVert)); bool is_static = true; diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index 4df0479372f..30afb993cc7 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -109,7 +109,7 @@ static void requiredDataMask(Object *UNUSED(ob), } /* check individual weights for changes and cache values */ -static void mesh_get_weights(MDeformVert *dvert, +static void mesh_get_weights(const MDeformVert *dvert, const int defgrp_index, const uint verts_num, const bool use_invert_vgroup, @@ -131,9 +131,9 @@ static void mesh_get_weights(MDeformVert *dvert, static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) { - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; - const MEdge *medge = mesh->medge; + const MEdge *medge = BKE_mesh_edges(mesh); + const MPoly *mpoly = BKE_mesh_polygons(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); uint mpoly_num, medge_num, i; ushort *boundaries; @@ -178,7 +178,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, uint i; const uint edges_num = (uint)mesh->totedge; - const MEdge *edges = mesh->medge; + const MEdge *edges = BKE_mesh_edges(mesh); float *vertex_edge_count_div; struct SmoothingData_Simple { @@ -255,7 +255,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, /* NOTE: the way this smoothing method works, its approx half as strong as the simple-smooth, * and 2.0 rarely spikes, double the value for consistent behavior. */ const float lambda = csmd->lambda * 2.0f; - const MEdge *edges = mesh->medge; + const MEdge *edges = BKE_mesh_edges(mesh); float *vertex_edge_count; uint i; @@ -358,7 +358,7 @@ static void smooth_iter(CorrectiveSmoothModifierData *csmd, static void smooth_verts(CorrectiveSmoothModifierData *csmd, Mesh *mesh, - MDeformVert *dvert, + const MDeformVert *dvert, const int defgrp_index, float (*vertexCos)[3], uint verts_num) @@ -452,8 +452,8 @@ static void calc_tangent_spaces(Mesh *mesh, float (*vertexCos)[3], float (*r_tan #ifndef USE_TANGENT_CALC_INLINE const uint mvert_num = (uint)dm->getNumVerts(dm); #endif - const MPoly *mpoly = mesh->mpoly; - const MLoop *mloop = mesh->mloop; + const MPoly *mpoly = BKE_mesh_polygons(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); uint i; for (i = 0; i < mpoly_num; i++) { @@ -519,7 +519,7 @@ static bool cache_settings_equal(CorrectiveSmoothModifierData *csmd) */ static void calc_deltas(CorrectiveSmoothModifierData *csmd, Mesh *mesh, - MDeformVert *dvert, + const MDeformVert *dvert, const int defgrp_index, const float (*rest_coords)[3], uint verts_num) @@ -579,7 +579,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, (((ID *)ob->data)->recalc & ID_RECALC_ALL)); bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0; - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; int defgrp_index; MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index af639915bd8..2043c1096c1 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -114,7 +114,7 @@ static void deformVerts(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false); } - struct MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; int defgrp_index = -1; MOD_get_vgroup(ctx->object, mesh_src, cmd->name, &dvert, &defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index 7590318c52b..729a912b079 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -22,6 +22,7 @@ #include "BKE_data_transfer.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" +#include "BKE_mesh.h" #include "BKE_mesh_mapping.h" #include "BKE_mesh_remap.h" #include "BKE_modifier.h" @@ -178,7 +179,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BLI_SPACE_TRANSFORM_SETUP(space_transform, ctx->object, ob_source); } - if (((result == me) || (me->mvert == result->mvert) || (me->medge == result->medge)) && + const MVert *me_verts = BKE_mesh_vertices(me); + const MEdge *me_edges = BKE_mesh_edges(me); + const MVert *result_verts = BKE_mesh_vertices(result); + const MEdge *result_edges = BKE_mesh_edges(result); + + if (((result == me) || (me_verts == result_verts) || (me_edges == result_edges)) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) { /* We need to duplicate data here, otherwise setting custom normals, edges' sharpness, etc., * could modify org mesh, see T43671. */ diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 55d9d148d10..1615fb28007 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -135,7 +135,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) { if (dmd->defgrp_name[0] && (dmd->defgrp_factor > 0.0f)) { - MDeformVert *dvert; + const MDeformVert *dvert; int defgrp_index; MOD_get_vgroup(ctx->object, mesh, dmd->defgrp_name, &dvert, &defgrp_index); @@ -203,7 +203,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* make sure we never alloc'd these */ BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL && bm->ftoolflagpool == NULL); - BLI_assert(bm->vtable == NULL && bm->etable == NULL && bm->ftable == NULL); result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh); diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 367809953b6..00a6cb5878f 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -150,7 +150,7 @@ typedef struct DisplaceUserdata { /*const*/ DisplaceModifierData *dmd; struct Scene *scene; struct ImagePool *pool; - MDeformVert *dvert; + const MDeformVert *dvert; float weight; int defgrp_index; int direction; @@ -170,7 +170,7 @@ static void displaceModifier_do_task(void *__restrict userdata, { DisplaceUserdata *data = (DisplaceUserdata *)userdata; DisplaceModifierData *dmd = data->dmd; - MDeformVert *dvert = data->dvert; + const MDeformVert *dvert = data->dvert; const bool invert_vgroup = (dmd->flag & MOD_DISP_INVERT_VGROUP) != 0; float weight = data->weight; int defgrp_index = data->defgrp_index; @@ -270,7 +270,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, { Object *ob = ctx->object; MVert *mvert; - MDeformVert *dvert; + const MDeformVert *dvert; int direction = dmd->direction; int defgrp_index; float(*tex_co)[3]; @@ -286,7 +286,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, return; } - mvert = mesh->mvert; + mvert = BKE_mesh_vertices_for_write(mesh); MOD_get_vgroup(ob, mesh, dmd->defgrp_name, &dvert, &defgrp_index); if (defgrp_index >= 0 && dvert == NULL) { @@ -316,7 +316,7 @@ static void displaceModifier_do(DisplaceModifierData *dmd, float(*clnors)[3] = CustomData_get_layer(ldata, CD_NORMAL); vert_clnors = MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__); BKE_mesh_normals_loop_to_vertex( - verts_num, mesh->mloop, mesh->totloop, (const float(*)[3])clnors, vert_clnors); + verts_num, BKE_mesh_loops(mesh), mesh->totloop, (const float(*)[3])clnors, vert_clnors); } else { direction = MOD_DISP_DIR_NOR; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index e243c32173d..e5579819cf0 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -100,8 +100,8 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p int i, p, v1, v2, v3, v4 = 0; const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0; - mvert = mesh->mvert; - mface = mesh->mface; + mvert = BKE_mesh_vertices_for_write(mesh); + mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); totvert = mesh->totvert; totface = mesh->totface; totpart = psmd->psys->totpart; @@ -216,7 +216,8 @@ static const short add_faces[24] = { static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf) { - MFace *df = &split->mface[cur]; + MFace *mfaces = CustomData_get_layer(&split->fdata, CD_MFACE); + MFace *df = &mfaces[cur]; CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1); *df = *mf; return df; @@ -639,7 +640,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) { Mesh *split_m; MFace *mf = NULL, *df1 = NULL; - MFace *mface = mesh->mface; + MFace *mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); MVert *dupve, *mv; EdgeHash *edgehash; EdgeHashIterator *ehi; @@ -729,12 +730,15 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) layers_num = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE); + const MVert *mesh_verts = BKE_mesh_vertices(mesh); + MVert *split_m_verts = BKE_mesh_vertices_for_write(split_m); + /* copy new faces & verts (is it really this painful with custom data??) */ for (i = 0; i < totvert; i++) { MVert source; MVert *dest; - source = mesh->mvert[i]; - dest = &split_m->mvert[i]; + source = mesh_verts[i]; + dest = &split_m_verts[i]; CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1); *dest = source; @@ -755,14 +759,14 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); - mv = &split_m->mvert[ed_v2]; - dupve = &split_m->mvert[esplit]; + mv = &split_m_verts[ed_v2]; + dupve = &split_m_verts[esplit]; CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1); *dupve = *mv; - mv = &split_m->mvert[ed_v1]; + mv = &split_m_verts[ed_v1]; mid_v3_v3v3(dupve->co, dupve->co, mv->co); } @@ -772,7 +776,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) curdupface = 0; //=totface; // curdupin=totesplit; for (i = 0, fs = facesplit; i < totface; i++, fs++) { - mf = &mesh->mface[i]; + mf = &mface[i]; switch (*fs) { case 3: @@ -876,8 +880,9 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) curdupface += add_faces[*fs] + 1; } + MFace *split_mface = CustomData_get_layer(&split_m->fdata, CD_MFACE); for (i = 0; i < curdupface; i++) { - mf = &split_m->mface[i]; + mf = &split_mface[i]; BKE_mesh_mface_index_validate(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); } @@ -915,7 +920,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, totface = mesh->totface; totvert = mesh->totvert; - mface = mesh->mface; + mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); totpart = psmd->psys->totpart; sim.depsgraph = ctx->depsgraph; @@ -984,6 +989,9 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, psmd->psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); + const MVert *mesh_verts = BKE_mesh_vertices(mesh); + MVert *explode_verts = BKE_mesh_vertices_for_write(explode); + /* duplicate & displace vertices */ ehi = BLI_edgehashIterator_new(vertpahash); for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { @@ -995,8 +1003,8 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, ed_v2 -= totvert; v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); - source = mesh->mvert[ed_v1]; - dest = &explode->mvert[v]; + source = mesh_verts[ed_v1]; + dest = &explode_verts[v]; CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1); @@ -1011,7 +1019,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, state.time = ctime; psys_get_particle_state(&sim, ed_v2, &state, 1); - vertco = explode->mvert[v].co; + vertco = explode_verts[v].co; mul_m4_v3(ctx->object->obmat, vertco); sub_v3_v3(vertco, birth.co); @@ -1035,6 +1043,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, BLI_edgehashIterator_free(ehi); /* Map new vertices to faces. */ + MFace *explode_mface = CustomData_get_layer(&explode->fdata, CD_MFACE); for (i = 0, u = 0; i < totface; i++) { MFace source; int orig_v4; @@ -1056,8 +1065,8 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, pa = NULL; } - source = mesh->mface[i]; - mf = &explode->mface[u]; + source = mface[i]; + mf = &explode_mface[u]; orig_v4 = source.v4; diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 979a08483e1..1336b896cae 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -281,7 +281,7 @@ static void deformVerts_do(HookModifierData *hmd, bPoseChannel *pchan = BKE_pose_channel_find_name(ob_target->pose, hmd->subtarget); float dmat[4][4]; int i, *index_pt; - MDeformVert *dvert; + const MDeformVert *dvert; struct HookData_cb hd; const bool invert_vgroup = (hmd->flag & MOD_HOOK_INVERT_VGROUP) != 0; diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 6333eb699b3..479ea25b09e 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -512,7 +512,7 @@ static void laplacianDeformPreview(LaplacianSystem *sys, float (*vertexCos)[3]) static bool isValidVertexGroup(LaplacianDeformModifierData *lmd, Object *ob, Mesh *mesh) { int defgrp_index; - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; MOD_get_vgroup(ob, mesh, lmd->anchor_grp_name, &dvert, &defgrp_index); @@ -526,8 +526,8 @@ static void initSystem( int defgrp_index; int anchors_num; float wpaint; - MDeformVert *dvert = NULL; - MDeformVert *dv = NULL; + const MDeformVert *dvert = NULL; + const MDeformVert *dv = NULL; LaplacianSystem *sys; const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0; @@ -570,14 +570,14 @@ static void initSystem( createFaceRingMap(mesh->totvert, BKE_mesh_runtime_looptri_ensure(mesh), BKE_mesh_runtime_looptri_len(mesh), - mesh->mloop, + BKE_mesh_loops(mesh), &sys->ringf_map, &sys->ringf_indices); createVertRingMap( - mesh->totvert, mesh->medge, mesh->totedge, &sys->ringv_map, &sys->ringv_indices); + mesh->totvert, BKE_mesh_edges(mesh), mesh->totedge, &sys->ringv_map, &sys->ringv_indices); mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); - mloop = mesh->mloop; + mloop = BKE_mesh_loops(mesh); for (i = 0; i < sys->tris_num; i++) { sys->tris[i][0] = mloop[mlooptri[i].tri[0]].v; @@ -596,8 +596,8 @@ static int isSystemDifferent(LaplacianDeformModifierData *lmd, int defgrp_index; int anchors_num = 0; float wpaint; - MDeformVert *dvert = NULL; - MDeformVert *dv = NULL; + const MDeformVert *dvert = NULL; + const MDeformVert *dv = NULL; LaplacianSystem *sys = (LaplacianSystem *)lmd->cache_system; const bool invert_vgroup = (lmd->flag & MOD_LAPLACIANDEFORM_INVERT_VGROUP) != 0; diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index c42f7b33919..d74c1e7ac2d 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -376,8 +376,8 @@ static void laplaciansmoothModifier_do( LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num) { LaplacianSystem *sys; - MDeformVert *dvert = NULL; - MDeformVert *dv = NULL; + const MDeformVert *dvert = NULL; + const MDeformVert *dv = NULL; float w, wpaint; int i, iter; int defgrp_index; @@ -388,9 +388,9 @@ static void laplaciansmoothModifier_do( return; } - sys->mpoly = mesh->mpoly; - sys->mloop = mesh->mloop; - sys->medges = mesh->medge; + sys->mpoly = BKE_mesh_polygons(mesh); + sys->mloop = BKE_mesh_loops(mesh); + sys->medges = BKE_mesh_edges(mesh); sys->vertexCos = vertexCos; sys->min_area = 0.00001f; MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index e48a949baf4..cfa0299da66 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -169,10 +169,11 @@ static void computed_masked_edges(const Mesh *mesh, uint *r_edges_masked_num) { BLI_assert(mesh->totedge == r_edge_map.size()); + const Span<MEdge> edges = mesh->edges(); uint edges_masked_num = 0; for (int i : IndexRange(mesh->totedge)) { - const MEdge &edge = mesh->medge[i]; + const MEdge &edge = edges[i]; /* only add if both verts will be in new mesh */ if (vertex_mask[edge.v1] && vertex_mask[edge.v2]) { @@ -194,11 +195,12 @@ static void computed_masked_edges_smooth(const Mesh *mesh, uint *r_verts_add_num) { BLI_assert(mesh->totedge == r_edge_map.size()); + const Span<MEdge> edges = mesh->edges(); uint edges_masked_num = 0; uint verts_add_num = 0; for (int i : IndexRange(mesh->totedge)) { - const MEdge &edge = mesh->medge[i]; + const MEdge &edge = edges[i]; /* only add if both verts will be in new mesh */ bool v1 = vertex_mask[edge.v1]; @@ -229,16 +231,18 @@ static void computed_masked_polygons(const Mesh *mesh, uint *r_loops_masked_num) { BLI_assert(mesh->totvert == vertex_mask.size()); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); r_masked_poly_indices.reserve(mesh->totpoly); r_loop_starts.reserve(mesh->totpoly); uint loops_masked_num = 0; for (int i : IndexRange(mesh->totpoly)) { - const MPoly &poly_src = mesh->mpoly[i]; + const MPoly &poly_src = polys[i]; bool all_verts_in_mask = true; - Span<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop); + Span<MLoop> loops_src = loops.slice(poly_src.loopstart, poly_src.totloop); for (const MLoop &loop : loops_src) { if (!vertex_mask[loop.v]) { all_verts_in_mask = false; @@ -273,17 +277,19 @@ static void compute_interpolated_polygons(const Mesh *mesh, /* NOTE: this reserve can only lift the capacity if there are ngons, which get split. */ r_masked_poly_indices.reserve(r_masked_poly_indices.size() + verts_add_num); r_loop_starts.reserve(r_loop_starts.size() + verts_add_num); + const Span<MPoly> polys = mesh->polygons(); + const Span<MLoop> loops = mesh->loops(); uint edges_add_num = 0; uint polys_add_num = 0; uint loops_add_num = 0; for (int i : IndexRange(mesh->totpoly)) { - const MPoly &poly_src = mesh->mpoly[i]; + const MPoly &poly_src = polys[i]; int in_count = 0; int start = -1; int dst_totloop = -1; - Span<MLoop> loops_src(&mesh->mloop[poly_src.loopstart], poly_src.totloop); + const Span<MLoop> loops_src = loops.slice(poly_src.loopstart, poly_src.totloop); for (const int j : loops_src.index_range()) { const MLoop &loop = loops_src[j]; if (vertex_mask[loop.v]) { @@ -332,14 +338,17 @@ static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, Span<int> vertex_map) { BLI_assert(src_mesh.totvert == vertex_map.size()); + const Span<MVert> src_verts = src_mesh.vertices(); + MutableSpan<MVert> dst_verts = dst_mesh.vertices_for_write(); + for (const int i_src : vertex_map.index_range()) { const int i_dst = vertex_map[i_src]; if (i_dst == -1) { continue; } - const MVert &v_src = src_mesh.mvert[i_src]; - MVert &v_dst = dst_mesh.mvert[i_dst]; + const MVert &v_src = src_verts[i_src]; + MVert &v_dst = dst_verts[i_dst]; v_dst = v_src; CustomData_copy_data(&src_mesh.vdata, &dst_mesh.vdata, i_src, i_dst, 1); @@ -369,6 +378,10 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, { BLI_assert(src_mesh.totvert == vertex_mask.size()); BLI_assert(src_mesh.totedge == r_edge_map.size()); + const Span<MVert> src_verts = src_mesh.vertices(); + const Span<MEdge> src_edges = src_mesh.edges(); + MutableSpan<MVert> dst_verts = dst_mesh.vertices_for_write(); + MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); uint vert_index = dst_mesh.totvert - verts_add_num; uint edge_index = edges_masked_num - verts_add_num; @@ -378,8 +391,8 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, if (i_dst == -2) { i_dst = edge_index; } - const MEdge &e_src = src_mesh.medge[i_src]; - MEdge &e_dst = dst_mesh.medge[i_dst]; + const MEdge &e_src = src_edges[i_src]; + MEdge &e_dst = dst_edges[i_dst]; CustomData_copy_data(&src_mesh.edata, &dst_mesh.edata, i_src, i_dst, 1); e_dst = e_src; @@ -389,9 +402,9 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, if (r_edge_map[i_src] == -2) { const int i_dst = edge_index++; r_edge_map[i_src] = i_dst; - const MEdge &e_src = src_mesh.medge[i_src]; + const MEdge &e_src = src_edges[i_src]; /* Cut destination edge and make v1 the new vertex. */ - MEdge &e_dst = dst_mesh.medge[i_dst]; + MEdge &e_dst = dst_edges[i_dst]; if (!vertex_mask[e_src.v1]) { e_dst.v1 = vert_index; } @@ -407,9 +420,9 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, float weights[2] = {1.0f - fac, fac}; CustomData_interp( &src_mesh.vdata, &dst_mesh.vdata, (int *)&e_src.v1, weights, nullptr, 2, vert_index); - MVert &v = dst_mesh.mvert[vert_index]; - MVert &v1 = src_mesh.mvert[e_src.v1]; - MVert &v2 = src_mesh.mvert[e_src.v2]; + MVert &v = dst_verts[vert_index]; + const MVert &v1 = src_verts[e_src.v1]; + const MVert &v2 = src_verts[e_src.v2]; interp_v3_v3v3(v.co, v1.co, v2.co, fac); vert_index++; @@ -424,6 +437,9 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Span<int> vertex_map, Span<int> edge_map) { + const Span<MEdge> src_edges = src_mesh.edges(); + MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); + BLI_assert(src_mesh.totvert == vertex_map.size()); BLI_assert(src_mesh.totedge == edge_map.size()); for (const int i_src : IndexRange(src_mesh.totedge)) { @@ -432,8 +448,8 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, continue; } - const MEdge &e_src = src_mesh.medge[i_src]; - MEdge &e_dst = dst_mesh.medge[i_dst]; + const MEdge &e_src = src_edges[i_src]; + MEdge &e_dst = dst_edges[i_dst]; CustomData_copy_data(&src_mesh.edata, &dst_mesh.edata, i_src, i_dst, 1); e_dst = e_src; @@ -450,19 +466,24 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span<int> new_loop_starts, int polys_masked_num) { + const Span<MPoly> src_polys = src_mesh.polygons(); + const Span<MLoop> src_loops = src_mesh.loops(); + MutableSpan<MPoly> dst_polys = dst_mesh.polygons_for_write(); + MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); + for (const int i_dst : IndexRange(polys_masked_num)) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_mesh.mpoly[i_src]; - MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const MPoly &mp_src = src_polys[i_src]; + MPoly &mp_dst = dst_polys[i_dst]; const int i_ml_src = mp_src.loopstart; const int i_ml_dst = new_loop_starts[i_dst]; CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1); CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop); - const MLoop *ml_src = src_mesh.mloop + i_ml_src; - MLoop *ml_dst = dst_mesh.mloop + i_ml_dst; + const MLoop *ml_src = src_loops.data() + i_ml_src; + MLoop *ml_dst = dst_loops.data() + i_ml_dst; mp_dst = mp_src; mp_dst.loopstart = i_ml_dst; @@ -486,6 +507,12 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, int polys_masked_num, int edges_add_num) { + const Span<MPoly> src_polys = src_mesh.polygons(); + const Span<MLoop> src_loops = src_mesh.loops(); + MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); + MutableSpan<MPoly> dst_polys = dst_mesh.polygons_for_write(); + MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); + int edge_index = dst_mesh.totedge - edges_add_num; int sub_poly_index = 0; int last_i_src = -1; @@ -500,8 +527,8 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, last_i_src = i_src; } - const MPoly &mp_src = src_mesh.mpoly[i_src]; - MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const MPoly &mp_src = src_polys[i_src]; + MPoly &mp_dst = dst_polys[i_dst]; const int i_ml_src = mp_src.loopstart; int i_ml_dst = new_loop_starts[i_dst]; const int mp_totloop = (i_dst + 1 < new_loop_starts.size() ? new_loop_starts[i_dst + 1] : @@ -517,7 +544,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, /* Ring search starting at a vertex which is not included in the mask. */ int start = -sub_poly_index - 1; bool skip = false; - Span<MLoop> loops_src(&src_mesh.mloop[i_ml_src], mp_src.totloop); + Span<MLoop> loops_src(&src_loops[i_ml_src], mp_src.totloop); for (const int j : loops_src.index_range()) { if (!vertex_mask[loops_src[j].v]) { if (start == -1) { @@ -552,13 +579,13 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, int indices[2] = {i_ml_src + last_index, i_ml_src + index}; CustomData_interp( &src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst); - MLoop &cut_dst_loop = dst_mesh.mloop[i_ml_dst]; + MLoop &cut_dst_loop = dst_loops[i_ml_dst]; cut_dst_loop.e = edge_map[last_loop->e]; - cut_dst_loop.v = dst_mesh.medge[cut_dst_loop.e].v1; + cut_dst_loop.v = dst_edges[cut_dst_loop.e].v1; i_ml_dst++; CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1); - MLoop &next_dst_loop = dst_mesh.mloop[i_ml_dst]; + MLoop &next_dst_loop = dst_loops[i_ml_dst]; next_dst_loop.v = vertex_map[loop.v]; next_dst_loop.e = edge_map[loop.e]; i_ml_dst++; @@ -572,14 +599,14 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, int indices[2] = {i_ml_src + last_index, i_ml_src + index}; CustomData_interp( &src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst); - MLoop &cut_dst_loop = dst_mesh.mloop[i_ml_dst]; + MLoop &cut_dst_loop = dst_loops[i_ml_dst]; cut_dst_loop.e = edge_index; - cut_dst_loop.v = dst_mesh.medge[edge_map[last_loop->e]].v1; + cut_dst_loop.v = dst_edges[edge_map[last_loop->e]].v1; i_ml_dst++; /* Create closing edge. */ - MEdge &cut_edge = dst_mesh.medge[edge_index]; - cut_edge.v1 = dst_mesh.mloop[mp_dst.loopstart].v; + MEdge &cut_edge = dst_edges[edge_index]; + cut_edge.v1 = dst_loops[mp_dst.loopstart].v; cut_edge.v2 = cut_dst_loop.v; BLI_assert(cut_edge.v1 != cut_edge.v2); cut_edge.flag = ME_EDGEDRAW | ME_EDGERENDER; @@ -592,7 +619,7 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh, BLI_assert(i_ml_dst != mp_dst.loopstart); /* Extend active poly. */ CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1); - MLoop &dst_loop = dst_mesh.mloop[i_ml_dst]; + MLoop &dst_loop = dst_loops[i_ml_dst]; dst_loop.v = vertex_map[loop.v]; dst_loop.e = edge_map[loop.e]; i_ml_dst++; @@ -619,9 +646,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) (mmd->flag & MOD_MASK_SMOOTH); /* Return empty or input mesh when there are no vertex groups. */ - const MDeformVert *dvert = (const MDeformVert *)CustomData_get_layer(&mesh->vdata, - CD_MDEFORMVERT); - if (dvert == nullptr) { + const Span<MDeformVert> dverts = mesh->deform_verts(); + if (dverts.is_empty()) { return invert_mask ? mesh : BKE_mesh_new_nomain_from_template(mesh, 0, 0, 0, 0, 0); } @@ -643,7 +669,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) } vertex_mask = Array<bool>(mesh->totvert); - compute_vertex_mask__armature_mode(dvert, mesh, armature_ob, mmd->threshold, vertex_mask); + compute_vertex_mask__armature_mode( + dverts.data(), mesh, armature_ob, mmd->threshold, vertex_mask); } else { BLI_assert(mmd->mode == MOD_MASK_MODE_VGROUP); @@ -655,7 +682,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) } vertex_mask = Array<bool>(mesh->totvert); - compute_vertex_mask__vertex_group_mode(dvert, defgrp_index, mmd->threshold, vertex_mask); + compute_vertex_mask__vertex_group_mode( + dverts.data(), defgrp_index, mmd->threshold, vertex_mask); } if (invert_mask) { @@ -716,7 +744,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) *result, vertex_mask, vertex_map, - dvert, + dverts.data(), defgrp_index, mmd->threshold, edges_masked_num, @@ -739,7 +767,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) vertex_mask, vertex_map, edge_map, - dvert, + dverts.data(), defgrp_index, mmd->threshold, masked_poly_indices, diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 3e81f987da3..162ff3fe4ff 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -79,7 +79,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, { const bool use_factor = mcmd->factor < 1.0f; int influence_group_index; - MDeformVert *dvert; + const MDeformVert *dvert; MOD_get_vgroup(ob, mesh, mcmd->defgrp_name, &dvert, &influence_group_index); float(*vertexCos_Store)[3] = (use_factor || influence_group_index != -1 || @@ -182,16 +182,16 @@ static void meshcache_do(MeshCacheModifierData *mcmd, float(*vertexCos_Source)[3] = MEM_malloc_arrayN( verts_num, sizeof(*vertexCos_Source), __func__); float(*vertexCos_New)[3] = MEM_malloc_arrayN(verts_num, sizeof(*vertexCos_New), __func__); - MVert *mv = me->mvert; + const MVert *mv = BKE_mesh_vertices(me); for (i = 0; i < verts_num; i++, mv++) { copy_v3_v3(vertexCos_Source[i], mv->co); } BKE_mesh_calc_relative_deform( - me->mpoly, + BKE_mesh_polygons(me), me->totpoly, - me->mloop, + BKE_mesh_loops(me), me->totvert, (const float(*)[3])vertexCos_Source, /* From the original Mesh. */ @@ -257,7 +257,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, const float global_offset = (mcmd->flag & MOD_MESHCACHE_INVERT_VERTEX_GROUP) ? mcmd->factor : 0.0f; - if (mesh->dvert != NULL) { + if (BKE_mesh_deform_verts(mesh) != NULL) { for (int i = 0; i < verts_num; i++) { /* For each vertex, compute its blending factor between the mesh cache (for `fac = 0`) * and the former position of the vertex (for `fac = 1`). */ diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index d1df86b1010..04d17cec10d 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -330,7 +330,7 @@ static void meshdeformModifier_do(ModifierData *md, Object *ob = ctx->object; Mesh *cagemesh; - MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; float imat[4][4], cagemat[4][4], iobmat[4][4], icagemat[3][3], cmat[4][4]; float(*dco)[3] = NULL, (*bindcagecos)[3]; int a, cage_verts_num, defgrp_index; diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc index 1c35160d3ef..bdaa90af5d8 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc @@ -60,6 +60,8 @@ # include "usd.h" #endif +using blender::Span; + static void initData(ModifierData *md) { MeshSeqCacheModifierData *mcmd = reinterpret_cast<MeshSeqCacheModifierData *>(md); @@ -176,13 +178,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (me != nullptr) { - MVert *mvert = mesh->mvert; - MEdge *medge = mesh->medge; - MPoly *mpoly = mesh->mpoly; + const Span<MVert> mesh_verts = mesh->vertices(); + const Span<MEdge> mesh_edges = mesh->edges(); + const Span<MPoly> mesh_polys = mesh->polygons(); + const Span<MVert> me_vertices = me->vertices(); + const Span<MEdge> me_edges = me->edges(); + const Span<MPoly> me_polygons = me->polygons(); /* TODO(sybren+bastien): possibly check relevant custom data layers (UV/color depending on - * flags) and duplicate those too. */ - if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) { + * flags) and duplicate those too. + * XXX(Hans): This probably isn't true anymore with various CoW improvements, etc. */ + if ((me_vertices.data() == mesh_verts.data()) || (me_edges.data() == mesh_edges.data()) || + (me_polygons.data() == mesh_polys.data())) { /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */ mesh = reinterpret_cast<Mesh *>( BKE_id_copy_ex(nullptr, diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 9e3e06fb4dc..41d6e339999 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -53,7 +53,7 @@ static void generate_vert_coordinates(Mesh *mesh, INIT_MINMAX(min_co, max_co); - MVert *mv = mesh->mvert; + const MVert *mv = BKE_mesh_vertices(mesh); for (int i = 0; i < mesh->totvert; i++, mv++) { copy_v3_v3(r_cos[i], mv->co); if (r_size != NULL && ob_center == NULL) { @@ -117,13 +117,13 @@ static void generate_vert_coordinates(Mesh *mesh, /* Note this modifies nos_new in-place. */ static void mix_normals(const float mix_factor, - MDeformVert *dvert, + const MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, const float mix_limit, const short mix_mode, const int verts_num, - MLoop *mloop, + const MLoop *mloop, float (*nos_old)[3], float (*nos_new)[3], const int loops_num) @@ -175,11 +175,11 @@ static void mix_normals(const float mix_factor, static bool polygons_check_flip(MLoop *mloop, float (*nos)[3], CustomData *ldata, - MPoly *mpoly, + const MPoly *mpoly, float (*polynors)[3], const int polys_num) { - MPoly *mp; + const MPoly *mp; MDisps *mdisp = CustomData_get_layer(ldata, CD_MDISPS); int i; bool flipped = false; @@ -218,16 +218,16 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const short mix_mode, const float mix_factor, const float mix_limit, - MDeformVert *dvert, + const MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, - MVert *mvert, + const MVert *mvert, const int verts_num, MEdge *medge, const int edges_num, MLoop *mloop, const int loops_num, - MPoly *mpoly, + const MPoly *mpoly, const int polys_num) { Object *ob_target = enmd->target; @@ -279,7 +279,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const float m2 = (b * b) / (a * a); const float n2 = (c * c) / (a * a); - MLoop *ml; + const MLoop *ml; float(*no)[3]; /* We reuse cos to now store the ellipsoid-normal of the verts! */ @@ -355,16 +355,16 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const short mix_mode, const float mix_factor, const float mix_limit, - MDeformVert *dvert, + const MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, - MVert *mvert, + const MVert *mvert, const int verts_num, MEdge *medge, const int edges_num, MLoop *mloop, const int loops_num, - MPoly *mpoly, + const MPoly *mpoly, const int polys_num) { Object *ob_target = enmd->target; @@ -399,7 +399,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, generate_vert_coordinates(mesh, ob, ob_target, NULL, verts_num, cos, NULL); BLI_bitmap *done_verts = BLI_BITMAP_NEW((size_t)verts_num, __func__); - MLoop *ml; + const MLoop *ml; float(*no)[3]; /* We reuse cos to now store the 'to target' normal of the verts! */ @@ -509,7 +509,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, } Mesh *result; - if (mesh->medge == ((Mesh *)ob->data)->medge) { + if (BKE_mesh_edges(mesh) == BKE_mesh_edges(((Mesh *)ob->data))) { /* We need to duplicate data here, otherwise setting custom normals * (which may also affect sharp edges) could * modify original mesh, see T43671. */ @@ -523,13 +523,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, const int edges_num = result->totedge; const int loops_num = result->totloop; const int polys_num = result->totpoly; - MVert *mvert = result->mvert; - MEdge *medge = result->medge; - MLoop *mloop = result->mloop; - MPoly *mpoly = result->mpoly; + const MVert *verts = BKE_mesh_vertices(result); + MEdge *edges = BKE_mesh_edges_for_write(result); + const MPoly *polys = BKE_mesh_polygons(result); + MLoop *loops = BKE_mesh_loops_for_write(result); int defgrp_index; - MDeformVert *dvert; + const MDeformVert *dvert; float(*loopnors)[3] = NULL; @@ -543,15 +543,15 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, clnors = CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num); loopnors = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loopnors), __func__); - BKE_mesh_normals_loop_split(mvert, + BKE_mesh_normals_loop_split(verts, vert_normals, verts_num, - medge, + edges, edges_num, - mloop, + loops, loopnors, loops_num, - mpoly, + polys, poly_normals, polys_num, true, @@ -581,13 +581,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, dvert, defgrp_index, use_invert_vgroup, - mvert, + verts, verts_num, - medge, + edges, edges_num, - mloop, + loops, loops_num, - mpoly, + polys, polys_num); } else if (enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) { @@ -604,13 +604,13 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, dvert, defgrp_index, use_invert_vgroup, - mvert, + verts, verts_num, - medge, + edges, edges_num, - mloop, + loops, loops_num, - mpoly, + polys, polys_num); } diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index ea8e534f585..cca49b42208 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -273,9 +273,9 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co result = BKE_mesh_new_nomain(verts_num, 0, 0, polys_num * 4, polys_num); BKE_mesh_copy_parameters_for_eval(result, mesh_orig); - gogd.mverts = result->mvert; - gogd.mpolys = result->mpoly; - gogd.mloops = result->mloop; + gogd.mverts = BKE_mesh_vertices_for_write(result); + gogd.mpolys = BKE_mesh_polygons_for_write(result); + gogd.mloops = BKE_mesh_loops_for_write(result); TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -322,8 +322,6 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution : omd->viewport_resolution; - MVert *mverts; - int cfra_for_cache; int i, j; @@ -368,14 +366,15 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend); cfra_for_cache -= omd->bakestart; /* shift to 0 based */ - mverts = result->mvert; + MVert *verts = BKE_mesh_vertices_for_write(result); + MPoly *polys = BKE_mesh_polygons_for_write(result); /* add vcols before displacement - allows lookup based on position */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { const int polys_num = result->totpoly; const int loops_num = result->totloop; - MLoop *mloops = result->mloop; + MLoop *mloops = BKE_mesh_loops_for_write(result); MLoopCol *mloopcols = CustomData_add_layer_named( &result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, NULL, loops_num, omd->foamlayername); @@ -390,10 +389,9 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } if (mloopcols) { /* unlikely to fail */ - MPoly *mpolys = result->mpoly; MPoly *mp; - for (i = 0, mp = mpolys; i < polys_num; i++, mp++) { + for (i = 0, mp = polys; i < polys_num; i++, mp++) { MLoop *ml = &mloops[mp->loopstart]; MLoopCol *mlcol = &mloopcols[mp->loopstart]; @@ -403,7 +401,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } for (j = mp->totloop; j--; ml++, mlcol++) { - const float *vco = mverts[ml->v].co; + const float *vco = verts[ml->v].co; const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); float foam; @@ -451,7 +449,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const int verts_num = result->totvert; for (i = 0; i < verts_num; i++) { - float *vco = mverts[i].co; + float *vco = verts[i].co; const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index d6435c55211..599c056f27c 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -200,9 +200,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ParticleSimulationData sim; ParticleSystem *psys = NULL; ParticleData *pa = NULL; - MPoly *mpoly, *orig_mpoly; - MLoop *mloop, *orig_mloop; - MVert *mvert, *orig_mvert; int totvert, totpoly, totloop, totedge; int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start; int k, p, p_skip; @@ -320,12 +317,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly); - mvert = result->mvert; - orig_mvert = mesh->mvert; - mpoly = result->mpoly; - orig_mpoly = mesh->mpoly; - mloop = result->mloop; - orig_mloop = mesh->mloop; + const MVert *orig_mvert = BKE_mesh_vertices(mesh); + const MPoly *orig_mpoly = BKE_mesh_polygons(mesh); + const MLoop *orig_mloop = BKE_mesh_loops(mesh); + MVert *mvert = BKE_mesh_vertices_for_write(result); + MEdge *edges = BKE_mesh_edges_for_write(result); + MPoly *mpoly = BKE_mesh_polygons_for_write(result); + MLoop *mloop = BKE_mesh_loops_for_write(result); MLoopCol *mloopcols_index = CustomData_get_layer_named( &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name); @@ -353,7 +351,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* set vertices coordinates */ for (k = 0; k < totvert; k++) { ParticleKey state; - MVert *inMV; + const MVert *inMV; int vindex = p_skip * totvert + k; MVert *mv = mvert + vindex; @@ -477,7 +475,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Create edges and adjust edge vertex indices. */ CustomData_copy_data(&mesh->edata, &result->edata, 0, p_skip * totedge, totedge); - MEdge *me = &result->medge[p_skip * totedge]; + MEdge *me = &edges[p_skip * totedge]; for (k = 0; k < totedge; k++, me++) { me->v1 += p_skip * totvert; me->v2 += p_skip * totvert; @@ -486,7 +484,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* create polys and loops */ for (k = 0; k < totpoly; k++) { - MPoly *inMP = orig_mpoly + k; + const MPoly *inMP = orig_mpoly + k; MPoly *mp = mpoly + p_skip * totpoly + k; CustomData_copy_data(&mesh->pdata, &result->pdata, k, p_skip * totpoly + k, 1); @@ -494,7 +492,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mp->loopstart += p_skip * totloop; { - MLoop *inML = orig_mloop + inMP->loopstart; + const MLoop *inML = orig_mloop + inMP->loopstart; MLoop *ml = mloop + mp->loopstart; int j = mp->totloop; diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index f21d536fadf..37d711a4bfa 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -60,11 +60,11 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) { memset(input, 0, sizeof(DualConInput)); - input->co = (void *)mesh->mvert; + input->co = (void *)BKE_mesh_vertices(mesh); input->co_stride = sizeof(MVert); input->totco = mesh->totvert; - input->mloop = (void *)mesh->mloop; + input->mloop = (void *)BKE_mesh_loops(mesh); input->loop_stride = sizeof(MLoop); BKE_mesh_runtime_looptri_ensure(mesh); @@ -80,6 +80,9 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) * keep track of the current elements */ typedef struct { Mesh *mesh; + MVert *verts; + MPoly *polys; + MLoop *loops; int curvert, curface; } DualConOutput; @@ -93,17 +96,20 @@ static void *dualcon_alloc_output(int totvert, int totquad) } output->mesh = BKE_mesh_new_nomain(totvert, 0, 0, 4 * totquad, totquad); + output->verts = BKE_mesh_vertices_for_write(output->mesh); + output->polys = BKE_mesh_polygons_for_write(output->mesh); + output->loops = BKE_mesh_loops_for_write(output->mesh); + return output; } static void dualcon_add_vert(void *output_v, const float co[3]) { DualConOutput *output = output_v; - Mesh *mesh = output->mesh; - BLI_assert(output->curvert < mesh->totvert); + BLI_assert(output->curvert < output->mesh->totvert); - copy_v3_v3(mesh->mvert[output->curvert].co, co); + copy_v3_v3(output->verts[output->curvert].co, co); output->curvert++; } @@ -111,14 +117,13 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4]) { DualConOutput *output = output_v; Mesh *mesh = output->mesh; - MLoop *mloop; - MPoly *cur_poly; int i; BLI_assert(output->curface < mesh->totpoly); + UNUSED_VARS_NDEBUG(mesh); - mloop = mesh->mloop; - cur_poly = &mesh->mpoly[output->curface]; + MLoop *mloop = output->loops; + MPoly *cur_poly = &output->polys[output->curface]; cur_poly->loopstart = output->curface * 4; cur_poly->totloop = 4; @@ -195,7 +200,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) } if (rmd->flag & MOD_REMESH_SMOOTH_SHADING) { - MPoly *mpoly = result->mpoly; + MPoly *mpoly = BKE_mesh_polygons_for_write(result); int i, totpoly = result->totpoly; /* Apply smooth shading to output faces */ diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index d8b11c0e89e..d657d658e46 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -182,7 +182,7 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *meshData) { - Mesh *mesh = meshData; + const Mesh *mesh = meshData; Mesh *result; ScrewModifierData *ltmd = (ScrewModifierData *)md; const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER) != 0; @@ -241,11 +241,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uint edge_offset; - MPoly *mpoly_orig, *mpoly_new, *mp_new; - MLoop *mloop_orig, *mloop_new, *ml_new; - MEdge *medge_orig, *med_orig, *med_new, *med_new_firstloop, *medge_new; - MVert *mvert_new, *mvert_orig, *mv_orig, *mv_new, *mv_new_base; - + MPoly *mp_new; + MLoop *ml_new; + MEdge *med_new, *med_new_firstloop; + MVert *mv_new, *mv_new_base; + const MVert *mv_orig; Object *ob_axis = ltmd->ob_axis; ScrewVertConnect *vc, *vc_tmp, *vert_connect = NULL; @@ -388,14 +388,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_new_nomain_from_template( mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); - /* copy verts from mesh */ - mvert_orig = mesh->mvert; - medge_orig = mesh->medge; + const MVert *mvert_orig = BKE_mesh_vertices(mesh); + const MEdge *medge_orig = BKE_mesh_edges(mesh); + const MPoly *mpoly_orig = BKE_mesh_polygons(mesh); + const MLoop *mloop_orig = BKE_mesh_loops(mesh); - mvert_new = result->mvert; - mpoly_new = result->mpoly; - mloop_new = result->mloop; - medge_new = result->medge; + MVert *mvert_new = BKE_mesh_vertices_for_write(result); + MEdge *medge_new = BKE_mesh_edges_for_write(result); + MPoly *mpoly_new = BKE_mesh_polygons_for_write(result); + MLoop *mloop_new = BKE_mesh_loops_for_write(result); if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) { CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, NULL, (int)maxPolys); @@ -438,7 +439,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BLI_bitmap *vert_tag = BLI_BITMAP_NEW(totvert, __func__); /* Copy the first set of edges */ - med_orig = medge_orig; + const MEdge *med_orig = medge_orig; med_new = medge_new; for (i = 0; i < totedge; i++, med_orig++, med_new++) { med_new->v1 = med_orig->v1; @@ -453,10 +454,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* build polygon -> edge map */ if (totpoly) { - MPoly *mp_orig; + const MPoly *mp_orig; - mpoly_orig = mesh->mpoly; - mloop_orig = mesh->mloop; edge_poly_map = MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__); memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge); @@ -467,7 +466,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uint loopstart = (uint)mp_orig->loopstart; uint loopend = loopstart + (uint)mp_orig->totloop; - MLoop *ml_orig = &mloop_orig[loopstart]; + const MLoop *ml_orig = &mloop_orig[loopstart]; uint k; for (k = loopstart; k < loopend; k++, ml_orig++) { edge_poly_map[ml_orig->e] = i; diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index 4a927d92956..cd36d82e746 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -111,7 +111,7 @@ static void deformVerts(ModifierData *md, mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false); } - struct MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; int defgrp_index = -1; MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index); @@ -143,7 +143,7 @@ static void deformVertsEM(ModifierData *md, BKE_mesh_wrapper_ensure_mdata(mesh_src); } - struct MDeformVert *dvert = NULL; + const MDeformVert *dvert = NULL; int defgrp_index = -1; if (swmd->vgroup_name[0] != '\0') { MOD_get_vgroup(ctx->object, mesh_src, swmd->vgroup_name, &dvert, &defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 1fc4f11bc66..b49e47fa589 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -294,7 +294,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, float smd_limit[2], smd_factor; SpaceTransform *transf = NULL, tmp_transf; int vgroup; - MDeformVert *dvert; + const MDeformVert *dvert; /* This is historically the lock axis, _not_ the deform axis as the name would imply */ const int deform_axis = smd->deform_axis; diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 982f5802df6..5b9b496b0d3 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -889,9 +889,9 @@ static Mesh *subdivide_base(const Mesh *orig) float radrat; const MVertSkin *orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN); - const MVert *origvert = orig->mvert; - const MEdge *origedge = orig->medge; - const MDeformVert *origdvert = orig->dvert; + const MVert *origvert = BKE_mesh_vertices(orig); + const MEdge *origedge = BKE_mesh_edges(orig); + const MDeformVert *origdvert = BKE_mesh_deform_verts(orig); int orig_vert_num = orig->totvert; int orig_edge_num = orig->totedge; @@ -916,10 +916,13 @@ static Mesh *subdivide_base(const Mesh *orig) Mesh *result = BKE_mesh_new_nomain_from_template( orig, orig_vert_num + subd_num, orig_edge_num + subd_num, 0, 0, 0); - MVert *outvert = result->mvert; - MEdge *outedge = result->medge; + MVert *outvert = BKE_mesh_vertices_for_write(result); + MEdge *outedge = BKE_mesh_edges_for_write(result); MVertSkin *outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN); - MDeformVert *outdvert = result->dvert; + MDeformVert *outdvert = NULL; + if (origdvert) { + outdvert = BKE_mesh_deform_verts_for_write(result); + } /* Copy original vertex data */ CustomData_copy_data(&orig->vdata, &result->vdata, 0, 0, orig_vert_num); @@ -1907,17 +1910,17 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ SkinNode *skin_nodes; MeshElemMap *emap; int *emapmem; - MVert *mvert; - MEdge *medge; - MDeformVert *dvert; + const MVert *mvert; + const MEdge *medge; + const MDeformVert *dvert; int verts_num, edges_num; bool has_valid_root = false; nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN); - mvert = origmesh->mvert; - dvert = origmesh->dvert; - medge = origmesh->medge; + mvert = BKE_mesh_vertices(origmesh); + dvert = BKE_mesh_deform_verts(origmesh); + medge = BKE_mesh_edges(origmesh); verts_num = origmesh->totvert; edges_num = origmesh->totedge; diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 6dd3d491283..76332c61e1e 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -99,10 +99,10 @@ static void smoothModifier_do( const float fac_orig = 1.0f - fac_new; const bool invert_vgroup = (smd->flag & MOD_SMOOTH_INVERT_VGROUP) != 0; - MEdge *medges = mesh->medge; + const MEdge *medges = BKE_mesh_edges(mesh); const int edges_num = mesh->totedge; - MDeformVert *dvert; + const MDeformVert *dvert; int defgrp_index; MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); @@ -128,7 +128,7 @@ static void smoothModifier_do( const short flag = smd->flag; if (dvert) { - MDeformVert *dv = dvert; + const MDeformVert *dv = dvert; for (int i = 0; i < verts_num; i++, dv++) { float *vco_orig = vertexCos[i]; if (accumulated_vecs_count[i] > 0) { diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index aa8c49ee0b8..d7b2db87a60 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -61,27 +61,16 @@ static void mesh_calc_hq_normal(Mesh *mesh, #endif ) { - int i, verts_num, edges_num, polys_num; - MPoly *mpoly, *mp; - MLoop *mloop, *ml; - MEdge *medge, *ed; + int i; - verts_num = mesh->totvert; - edges_num = mesh->totedge; - polys_num = mesh->totpoly; - mpoly = mesh->mpoly; - medge = mesh->medge; - mloop = mesh->mloop; + const int verts_num = mesh->totvert; + const int edges_num = mesh->totedge; + const int polys_num = mesh->totpoly; + const MPoly *mpoly = BKE_mesh_polygons(mesh); + const MLoop *mloop = BKE_mesh_loops(mesh); + const MEdge *medge = BKE_mesh_edges(mesh); - /* we don't want to overwrite any referenced layers */ - - /* Doesn't work here! */ -#if 0 - mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, verts_num); - cddm->mvert = mv; -#endif - - mp = mpoly; + const MPoly *mp = mpoly; { EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN( @@ -93,7 +82,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, for (i = 0; i < polys_num; i++, mp++) { int j; - ml = mloop + mp->loopstart; + const MLoop *ml = mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { /* --- add edge ref to face --- */ @@ -116,6 +105,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, } } + const MEdge *ed; for (i = 0, ed = medge, edge_ref = edge_ref_array; i < edges_num; i++, ed++, edge_ref++) { /* Get the edge vert indices, and edge value (the face indices that use it) */ @@ -166,10 +156,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; - MVert *mv, *mvert, *orig_mvert; - MEdge *ed, *medge, *orig_medge; - MLoop *ml, *mloop, *orig_mloop; - MPoly *mp, *mpoly, *orig_mpoly; const uint verts_num = (uint)mesh->totvert; const uint edges_num = (uint)mesh->totedge; const uint polys_num = (uint)mesh->totpoly; @@ -216,7 +202,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const bool do_shell = !(do_rim && (smd->flag & MOD_SOLIDIFY_NOSHELL) != 0); /* weights */ - MDeformVert *dvert; + const MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; const int shell_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->shell_defgrp_name); @@ -229,10 +215,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); - orig_mvert = mesh->mvert; - orig_medge = mesh->medge; - orig_mloop = mesh->mloop; - orig_mpoly = mesh->mpoly; + const MVert *orig_mvert = BKE_mesh_vertices(mesh); + const MEdge *orig_medge = BKE_mesh_edges(mesh); + const MPoly *orig_mpoly = BKE_mesh_polygons(mesh); + const MLoop *orig_mloop = BKE_mesh_loops(mesh); if (need_poly_normals) { /* calculate only face normals */ @@ -262,16 +248,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex copy_vn_i(edge_users, edges_num, INVALID_UNUSED); #endif + const MEdge *ed; for (eidx = 0, ed = orig_medge; eidx < edges_num; eidx++, ed++) { edge_users[eidx] = INVALID_UNUSED; } + const MPoly *mp; for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) { - MLoop *ml_prev; int j; - ml = orig_mloop + mp->loopstart; - ml_prev = ml + (mp->totloop - 1); + const MLoop *ml = orig_mloop + mp->loopstart; + const MLoop *ml_prev = ml + (mp->totloop - 1); for (j = 0; j < mp->totloop; j++, ml++) { /* add edge user */ @@ -348,10 +335,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex (int)((loops_num * stride) + newLoops), (int)((polys_num * stride) + newPolys)); - mpoly = result->mpoly; - mloop = result->mloop; - medge = result->medge; - mvert = result->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(result); + MEdge *medge = BKE_mesh_edges_for_write(result); + MPoly *mpoly = BKE_mesh_polygons_for_write(result); + MLoop *mloop = BKE_mesh_loops_for_write(result); if (do_bevel_convex) { /* Make sure bweight is enabled. */ @@ -432,7 +419,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_shell) { uint i; - mp = mpoly + polys_num; + MPoly *mp = mpoly + polys_num; for (i = 0; i < mesh->totpoly; i++, mp++) { const int loop_end = mp->totloop - 1; MLoop *ml2; @@ -482,6 +469,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } } + MEdge *ed; for (i = 0, ed = medge + edges_num; i < edges_num; i++, ed++) { ed->v1 += verts_num; ed->v2 += verts_num; @@ -530,15 +518,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex edge_user_pairs[eidx][0] = INVALID_UNUSED; edge_user_pairs[eidx][1] = INVALID_UNUSED; } - mp = orig_mpoly; + const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { - ml = orig_mloop + mp->loopstart; - MLoop *ml_prev = ml + (mp->totloop - 1); + const MLoop *ml = orig_mloop + mp->loopstart; + const MLoop *ml_prev = ml + (mp->totloop - 1); for (uint j = 0; j < mp->totloop; j++, ml++) { /* add edge user */ eidx = ml_prev->e; - ed = orig_medge + eidx; + const MEdge *ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { @@ -551,7 +539,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ml_prev = ml; } } - ed = orig_medge; + const MEdge *ed = orig_medge; float e[3]; for (uint i = 0; i < edges_num; i++, ed++) { if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && @@ -582,12 +570,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ofs_new_vgroup = ofs_new; + MVert *mv; INIT_VERT_ARRAY_OFFSETS(false); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { const uint i = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (dvert) { - MDeformVert *dv = &dvert[i]; + const MDeformVert *dv = &dvert[i]; if (defgrp_invert) { ofs_new_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } @@ -633,12 +622,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ofs_new_vgroup = ofs_orig; /* as above but swapped */ + MVert *mv; INIT_VERT_ARRAY_OFFSETS(true); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { const uint i = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (dvert) { - MDeformVert *dv = &dvert[i]; + const MDeformVert *dv = &dvert[i]; if (defgrp_invert) { ofs_new_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } @@ -724,11 +714,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (vert_nors == NULL) { vert_nors = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno"); + const MVert *mv; for (i = 0, mv = mvert; i < verts_num; i++, mv++) { copy_v3_v3(vert_nors[i], mesh_vert_normals[i]); } } + const MPoly *mp; for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { /* #BKE_mesh_calc_poly_angles logic is inlined here */ float nor_prev[3]; @@ -737,7 +729,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex int i_curr = mp->totloop - 1; int i_next = 0; - ml = &mloop[mp->loopstart]; + const MLoop *ml = &mloop[mp->loopstart]; sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co); normalize_v3(nor_prev); @@ -781,7 +773,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* vertex group support */ if (dvert) { - MDeformVert *dv = dvert; + const MDeformVert *dv = dvert; float scalar; if (defgrp_invert) { @@ -824,13 +816,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex edge_user_pairs[eidx][1] = INVALID_UNUSED; } for (i = 0, mp = orig_mpoly; i < polys_num; i++, mp++) { - ml = orig_mloop + mp->loopstart; - MLoop *ml_prev = ml + (mp->totloop - 1); + const MLoop *ml = orig_mloop + mp->loopstart; + const MLoop *ml_prev = ml + (mp->totloop - 1); for (int j = 0; j < mp->totloop; j++, ml++) { /* add edge user */ eidx = ml_prev->e; - ed = orig_medge + eidx; + const MEdge *ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { @@ -843,7 +835,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ml_prev = ml; } } - ed = orig_medge; + const MEdge *ed = orig_medge; float e[3]; for (i = 0; i < edges_num; i++, ed++) { if (!ELEM(edge_user_pairs[i][0], INVALID_UNUSED, INVALID_PAIR) && @@ -938,6 +930,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex uint i_orig, i_end; bool do_shell_align; + MVert *mv; INIT_VERT_ARRAY_OFFSETS(false); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { @@ -954,6 +947,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex bool do_shell_align; /* same as above but swapped, intentional use of 'ofs_new' */ + MVert *mv; INIT_VERT_ARRAY_OFFSETS(true); for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { @@ -983,7 +977,6 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex else if (do_shell) { uint i; /* flip vertex normals for copied verts */ - mv = mvert + verts_num; for (i = 0; i < verts_num; i++) { negate_v3((float *)mesh_vert_normals[i]); } @@ -991,22 +984,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* Add vertex weights for rim and shell vgroups. */ if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { - dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); - /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ - if (dvert == NULL) { - /* Add a valid data layer! */ - dvert = CustomData_add_layer( - &result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, result->totvert); - } + MDeformVert *dst_dvert = BKE_mesh_deform_verts_for_write(result); + /* Ultimate security check. */ - if (dvert != NULL) { - result->dvert = dvert; + if (dst_dvert != NULL) { if (rim_defgrp_index != -1) { for (uint i = 0; i < rimVerts; i++) { - BKE_defvert_ensure_index(&result->dvert[new_vert_arr[i]], rim_defgrp_index)->weight = - 1.0f; - BKE_defvert_ensure_index(&result->dvert[(do_shell ? new_vert_arr[i] : i) + verts_num], + BKE_defvert_ensure_index(&dst_dvert[new_vert_arr[i]], rim_defgrp_index)->weight = 1.0f; + BKE_defvert_ensure_index(&dst_dvert[(do_shell ? new_vert_arr[i] : i) + verts_num], rim_defgrp_index) ->weight = 1.0f; } @@ -1014,7 +1000,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (shell_defgrp_index != -1) { for (uint i = verts_num; i < result->totvert; i++) { - BKE_defvert_ensure_index(&result->dvert[i], shell_defgrp_index)->weight = 1.0f; + BKE_defvert_ensure_index(&dst_dvert[i], shell_defgrp_index)->weight = 1.0f; } } } @@ -1057,7 +1043,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* add faces & edges */ origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : NULL; - ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ + MEdge *ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ for (i = 0; i < rimVerts; i++, ed++) { ed->v1 = new_vert_arr[i]; ed->v2 = (do_shell ? new_vert_arr[i] : i) + verts_num; @@ -1074,8 +1060,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } /* faces */ - mp = mpoly + (polys_num * stride); - ml = mloop + (loops_num * stride); + MPoly *mp = mpoly + (polys_num * stride); + MLoop *ml = mloop + (loops_num * stride); j = 0; for (i = 0; i < newPolys; i++, mp++) { uint eidx = new_edge_arr[i]; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 29adbd70198..0bce954a67a 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -76,7 +76,7 @@ static float clamp_nonzero(const float value, const float epsilon) /* Data structures for manifold solidify. */ typedef struct NewFaceRef { - MPoly *face; + const MPoly *face; uint index; bool reversed; struct NewEdgeRef **link_edges; @@ -137,10 +137,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; - MVert *mv, *mvert, *orig_mvert; - MEdge *ed, *medge, *orig_medge; - MLoop *ml, *mloop, *orig_mloop; - MPoly *mp, *mpoly, *orig_mpoly; const uint verts_num = (uint)mesh->totvert; const uint edges_num = (uint)mesh->totedge; const uint polys_num = (uint)mesh->totpoly; @@ -178,7 +174,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const float bevel_convex = smd->bevel_convex; - MDeformVert *dvert; + const MDeformVert *dvert; const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0; int defgrp_index; const int shell_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->shell_defgrp_name); @@ -188,10 +184,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const bool do_flat_faces = dvert && (smd->flag & MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES); - orig_mvert = mesh->mvert; - orig_medge = mesh->medge; - orig_mloop = mesh->mloop; - orig_mpoly = mesh->mpoly; + const MVert *orig_mvert = BKE_mesh_vertices(mesh); + const MEdge *orig_medge = BKE_mesh_edges(mesh); + const MPoly *orig_mpoly = BKE_mesh_polygons(mesh); + const MLoop *orig_mloop = BKE_mesh_loops(mesh); uint new_verts_num = 0; uint new_edges_num = 0; @@ -213,11 +209,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint largest_ngon = 3; /* Calculate face to #NewFaceRef map. */ { - mp = orig_mpoly; + const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { /* Make normals for faces without area (should really be avoided though). */ if (len_squared_v3(poly_nors[i]) < 0.5f) { - MEdge *e = orig_medge + orig_mloop[mp->loopstart].e; + const MEdge *e = orig_medge + orig_mloop[mp->loopstart].e; float edgedir[3]; sub_v3_v3v3(edgedir, orig_mvert[e->v2].co, orig_mvert[e->v1].co); if (fabsf(edgedir[2]) < fabsf(edgedir[1])) { @@ -254,9 +250,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, edges_num, sizeof(*edge_adj_faces_len), "edge_adj_faces_len in solidify"); /* Count for each edge how many faces it has adjacent. */ { - mp = orig_mpoly; + const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { - ml = orig_mloop + mp->loopstart; + const MLoop *ml = orig_mloop + mp->loopstart; for (uint j = 0; j < mp->totloop; j++, ml++) { edge_adj_faces_len[ml->e]++; } @@ -304,9 +300,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create link_faces for edges. */ { - mp = orig_mpoly; + const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { - ml = orig_mloop + mp->loopstart; + const MLoop *ml = orig_mloop + mp->loopstart; for (uint j = 0; j < mp->totloop; j++, ml++) { const uint edge = ml->e; const bool reversed = orig_medge[edge].v2 != ml->v; @@ -353,7 +349,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint *combined_verts = MEM_calloc_arrayN( verts_num, sizeof(*combined_verts), "combined_verts in solidify"); - ed = orig_medge; + const MEdge *ed = orig_medge; for (uint i = 0; i < edges_num; i++, ed++) { if (edge_adj_faces_len[i] > 0) { uint v1 = vm[ed->v1]; @@ -377,7 +373,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (k != i && edge_adj_faces_len[k] > 0 && (ELEM(vm[orig_medge[k].v1], v1, v2) != ELEM(vm[orig_medge[k].v2], v1, v2))) { for (uint j = 0; j < edge_adj_faces[k]->faces_len && can_merge; j++) { - mp = orig_mpoly + edge_adj_faces[k]->faces[j]; + const MPoly *mp = orig_mpoly + edge_adj_faces[k]->faces[j]; uint changes = 0; int cur = mp->totloop - 1; for (int next = 0; next < mp->totloop && changes <= 2; next++) { @@ -473,7 +469,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create vert_adj_edges for verts. */ { - ed = orig_medge; + const MEdge *ed = orig_medge; for (uint i = 0; i < edges_num; i++, ed++) { if (edge_adj_faces_len[i] > 0) { const uint vs[2] = {vm[ed->v1], vm[ed->v2]}; @@ -592,7 +588,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Filter duplicate polys. */ { - ed = orig_medge; + const MEdge *ed = orig_medge; /* Iterate over edges and only check the faces around an edge for duplicates * (performance optimization). */ for (uint i = 0; i < edges_num; i++, ed++) { @@ -615,7 +611,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Find first face first loop vert in second face loops. */ const int k_loopstart = orig_mpoly[adj_faces->faces[k]].loopstart; int l; - ml = orig_mloop + k_loopstart; + const MLoop *ml = orig_mloop + k_loopstart; for (l = 0; l < totloop && vm[ml->v] != j_first_v; l++, ml++) { /* Pass. */ } @@ -703,7 +699,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create #NewEdgeRef array. */ { - ed = orig_medge; + const MEdge *ed = orig_medge; for (uint i = 0; i < edges_num; i++, ed++) { const uint v1 = vm[ed->v1]; const uint v2 = vm[ed->v2]; @@ -848,7 +844,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, new_edges[j] = edge_data; for (uint k = 0; k < 2; k++) { if (faces[k] != NULL) { - ml = orig_mloop + faces[k]->face->loopstart; + const MLoop *ml = orig_mloop + faces[k]->face->loopstart; for (int l = 0; l < faces[k]->face->totloop; l++, ml++) { if (edge_adj_faces[ml->e] == edge_adj_faces[i]) { if (ml->e != i && orig_edge_data_arr[ml->e] == NULL) { @@ -1377,13 +1373,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (do_flat_faces) { face_weight = MEM_malloc_arrayN(polys_num, sizeof(*face_weight), "face_weight in solidify"); - mp = orig_mpoly; + const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { float scalar_vgroup = 1.0f; int loopend = mp->loopstart + mp->totloop; - ml = orig_mloop + mp->loopstart; + const MLoop *ml = orig_mloop + mp->loopstart; for (int j = mp->loopstart; j < loopend; j++, ml++) { - MDeformVert *dv = &dvert[ml->v]; + const MDeformVert *dv = &dvert[ml->v]; if (defgrp_invert) { scalar_vgroup = min_ff(1.0f - BKE_defvert_find_weight(dv, defgrp_index), scalar_vgroup); @@ -1397,7 +1393,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } - mv = orig_mvert; + const MVert *mv = orig_mvert; gs_ptr = orig_vert_groups_arr; for (uint i = 0; i < verts_num; i++, mv++, gs_ptr++) { if (*gs_ptr) { @@ -1655,9 +1651,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_EVEN) { - MLoop *ml_next = orig_mloop + face->face->loopstart; - ml = ml_next + (face->face->totloop - 1); - MLoop *ml_prev = ml - 1; + const MLoop *ml_next = orig_mloop + face->face->loopstart; + const MLoop *ml = ml_next + (face->face->totloop - 1); + const MLoop *ml_prev = ml - 1; for (int m = 0; m < face->face->totloop && vm[ml->v] != i; m++, ml_next++) { ml_prev = ml; @@ -1766,7 +1762,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, float tmp[3]; int k; for (k = 1; k + 1 < g->edges_len; k++, edge_ptr++) { - MEdge *e = orig_medge + (*edge_ptr)->old_edge; + const MEdge *e = orig_medge + (*edge_ptr)->old_edge; sub_v3_v3v3(tmp, orig_mvert_co[vm[e->v1] == i ? e->v2 : e->v1], orig_mvert_co[i]); add_v3_v3(move_nor, tmp); } @@ -1781,8 +1777,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!disable_boundary_fix) { /* Constraint normal, nor * constr_nor == 0 after this fix. */ float constr_nor[3]; - MEdge *e0_edge = orig_medge + g->edges[0]->old_edge; - MEdge *e1_edge = orig_medge + g->edges[g->edges_len - 1]->old_edge; + const MEdge *e0_edge = orig_medge + g->edges[0]->old_edge; + const MEdge *e1_edge = orig_medge + g->edges[g->edges_len - 1]->old_edge; float e0[3]; float e1[3]; sub_v3_v3v3(e0, @@ -1831,7 +1827,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, float scalar_vgroup = 1; /* Use vertex group. */ if (dvert && !do_flat_faces) { - MDeformVert *dv = &dvert[i]; + const MDeformVert *dv = &dvert[i]; if (defgrp_invert) { scalar_vgroup = 1.0f - BKE_defvert_find_weight(dv, defgrp_index); } @@ -1961,10 +1957,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, (int)(new_loops_num), (int)(new_polys_num)); - mpoly = result->mpoly; - mloop = result->mloop; - medge = result->medge; - mvert = result->mvert; + MVert *mvert = BKE_mesh_vertices_for_write(result); + MEdge *medge = BKE_mesh_edges_for_write(result); + MPoly *mpoly = BKE_mesh_polygons_for_write(result); + MLoop *mloop = BKE_mesh_loops_for_write(result); int *origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); int *origindex_poly = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); @@ -1975,15 +1971,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Checks that result has dvert data. */ + MDeformVert *dst_dvert = NULL; if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { - dvert = CustomData_duplicate_referenced_layer(&result->vdata, CD_MDEFORMVERT, result->totvert); - /* If no vertices were ever added to an object's vgroup, dvert might be NULL. */ - if (dvert == NULL) { - /* Add a valid data layer! */ - dvert = CustomData_add_layer( - &result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, result->totvert); - } - result->dvert = dvert; + dst_dvert = BKE_mesh_deform_verts_for_write(result); } /* Get vertex crease layer and ensure edge creases are active if vertex creases are found, since @@ -2114,7 +2104,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Make boundary edges/faces. */ { gs_ptr = orig_vert_groups_arr; - mv = orig_mvert; + const MVert *mv = orig_mvert; for (uint i = 0; i < verts_num; i++, gs_ptr++, mv++) { EdgeGroup *gs = *gs_ptr; if (gs) { @@ -2147,7 +2137,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } else { for (uint k = 1; k < g->edges_len - 1; k++) { - ed = orig_medge + g->edges[k]->old_edge; + const MEdge *ed = orig_medge + g->edges[k]->old_edge; if (ed->crease > max_crease) { max_crease = ed->crease; } @@ -2279,8 +2269,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint k = 0; g2->valid && k < j; g2++) { if ((do_rim && !g2->is_orig_closed) || (do_shell && g2->split)) { - MPoly *face = g2->edges[0]->faces[0]->face; - ml = orig_mloop + face->loopstart; + const MPoly *face = g2->edges[0]->faces[0]->face; + const MLoop *ml = orig_mloop + face->loopstart; for (int l = 0; l < face->totloop; l++, ml++) { if (vm[ml->v] == i) { loops[k] = face->loopstart + l; @@ -2342,7 +2332,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } const uint orig_face_index = (*new_edges)->faces[0]->index; - MPoly *face = &orig_mpoly[orig_face_index]; + const MPoly *face = (*new_edges)->faces[0]->face; CustomData_copy_data( &mesh->pdata, &result->pdata, (int)(*new_edges)->faces[0]->index, (int)poly_index, 1); mpoly[poly_index].loopstart = (int)loop_index; @@ -2355,7 +2345,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, int loop1 = -1; int loop2 = -1; - ml = orig_mloop + face->loopstart; + const MLoop *ml = orig_mloop + face->loopstart; const uint old_v1 = vm[orig_medge[edge1->old_edge].v1]; const uint old_v2 = vm[orig_medge[edge1->old_edge].v2]; for (uint j = 0; j < face->totloop; j++, ml++) { @@ -2371,7 +2361,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint open_face_edge_index; if (!do_flip) { if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); @@ -2381,7 +2371,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!v2_singularity) { open_face_edge_index = edge1->link_edge_groups[1]->open_face_edge; if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); @@ -2396,7 +2386,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); @@ -2406,7 +2396,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!v1_singularity) { open_face_edge_index = edge2->link_edge_groups[0]->open_face_edge; if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); @@ -2424,7 +2414,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!v1_singularity) { open_face_edge_index = edge1->link_edge_groups[0]->open_face_edge; if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v1], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); @@ -2439,7 +2429,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v1], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); @@ -2449,7 +2439,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!v2_singularity) { open_face_edge_index = edge2->link_edge_groups[1]->open_face_edge; if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge2->new_edge].v2], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); @@ -2464,7 +2454,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } if (rim_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[medge[edge1->new_edge].v2], rim_defgrp_index) + BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); @@ -2547,8 +2537,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (fr->reversed != do_flip) { for (int l = (int)k - 1; l >= 0; l--) { if (shell_defgrp_index != -1) { - BKE_defvert_ensure_index(&result->dvert[face_verts[l]], shell_defgrp_index) - ->weight = 1.0f; + BKE_defvert_ensure_index(&dst_dvert[face_verts[l]], shell_defgrp_index)->weight = + 1.0f; } CustomData_copy_data( &mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1); diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 3e5a577a806..93da7969a09 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -125,7 +125,6 @@ static void deformVerts(ModifierData *md, if (surmd->mesh) { uint mesh_verts_num = 0, i = 0; int init = 0; - float *vec; MVert *x, *v; BKE_mesh_vert_coords_apply(surmd->mesh, vertexCos); @@ -152,8 +151,9 @@ static void deformVerts(ModifierData *md, } /* convert to global coordinates and calculate velocity */ + MVert *verts = BKE_mesh_vertices_for_write(surmd->mesh); for (i = 0, x = surmd->x, v = surmd->v; i < mesh_verts_num; i++, x++, v++) { - vec = surmd->mesh->mvert[i].co; + float *vec = verts[i].co; mul_m4_v3(ctx->object->obmat, vec); if (init) { diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 96e761e86b6..50071cad1b9 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1171,10 +1171,10 @@ static bool surfacedeformBind(Object *ob, Mesh *mesh) { BVHTreeFromMesh treeData = {NULL}; - const MVert *mvert = target->mvert; - const MPoly *mpoly = target->mpoly; - const MEdge *medge = target->medge; - const MLoop *mloop = target->mloop; + const MVert *mvert = BKE_mesh_vertices(target); + const MPoly *mpoly = BKE_mesh_polygons(target); + const MEdge *medge = BKE_mesh_edges(target); + const MLoop *mloop = BKE_mesh_loops(target); uint tedges_num = target->totedge; int adj_result; SDefAdjacencyArray *vert_edges; @@ -1236,7 +1236,7 @@ static bool surfacedeformBind(Object *ob, smd_orig->target_polys_num = target_polys_num; int defgrp_index; - MDeformVert *dvert; + const MDeformVert *dvert; MOD_get_vgroup(ob, mesh, smd_orig->defgrp_name, &dvert, &defgrp_index); const bool invert_vgroup = (smd_orig->flags & MOD_SDEF_INVERT_VGROUP) != 0; const bool sparse_bind = (smd_orig->flags & MOD_SDEF_SPARSE_BIND) != 0; @@ -1538,7 +1538,7 @@ static void surfacedeformModifier_do(ModifierData *md, } int defgrp_index; - MDeformVert *dvert; + const MDeformVert *dvert; MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index); const bool invert_vgroup = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0; diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index d4faf682cdc..e8280bc9c97 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -82,7 +82,7 @@ static Mesh *triangulate_mesh(Mesh *mesh, } edges_num = result->totedge; - me = result->medge; + me = BKE_mesh_edges_for_write(result); /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */ for (i = 0; i < edges_num; i++, me++) { diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index fc17ddffa87..654d2c51c34 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -94,9 +94,9 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, /* UVs need special handling, since they come from faces */ if (texmapping == MOD_DISP_MAP_UV) { if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { - MPoly *mpoly = mesh->mpoly; - MPoly *mp; - MLoop *mloop = mesh->mloop; + const MPoly *mpoly = BKE_mesh_polygons(mesh); + const MPoly *mp; + const MLoop *mloop = BKE_mesh_loops(mesh); BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__); const int polys_num = mesh->totpoly; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; @@ -130,7 +130,7 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, texmapping = MOD_DISP_MAP_LOCAL; } - MVert *mv = mesh->mvert; + const MVert *mv = BKE_mesh_vertices(mesh); for (i = 0; i < verts_num; i++, mv++, r_texco++) { switch (texmapping) { case MOD_DISP_MAP_LOCAL: @@ -224,12 +224,12 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, } void MOD_get_vgroup( - Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index) + Object *ob, struct Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index) { if (mesh) { *defgrp_index = BKE_id_defgroup_name_index(&mesh->id, name); if (*defgrp_index != -1) { - *dvert = mesh->dvert; + *dvert = BKE_mesh_deform_verts(mesh); } else { *dvert = NULL; diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index b675c11b370..5f9bd97744b 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -47,7 +47,7 @@ struct Mesh *MOD_deform_mesh_eval_get(struct Object *ob, void MOD_get_vgroup(struct Object *ob, struct Mesh *mesh, const char *name, - struct MDeformVert **dvert, + const struct MDeformVert **dvert, int *defgrp_index); void MOD_depsgraph_update_object_bone_relation(struct DepsNodeHandle *node, diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index ccef867b752..9af201c924f 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -99,8 +99,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, float(*coords)[3], (*co)[3]; MLoopUV *mloop_uv; int i, verts_num, polys_num, loops_num; - MPoly *mpoly, *mp; - MLoop *mloop; + const MPoly *mp; Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; int projectors_num = 0; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; @@ -205,17 +204,17 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, } } - mpoly = mesh->mpoly; - mloop = mesh->mloop; + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); /* apply coords as UVs */ - for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { + for (i = 0, mp = polys; i < polys_num; i++, mp++) { if (projectors_num == 1) { if (projectors[0].uci) { uint fidx = mp->totloop - 1; do { uint lidx = mp->loopstart + fidx; - uint vidx = mloop[lidx].v; + uint vidx = loops[lidx].v; BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], projectors[0].uci); } while (fidx--); } @@ -224,7 +223,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = mp->totloop - 1; do { uint lidx = mp->loopstart + fidx; - uint vidx = mloop[lidx].v; + uint vidx = loops[lidx].v; copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]); } while (fidx--); } @@ -238,7 +237,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, /* get the untransformed face normal */ BKE_mesh_calc_poly_normal_coords( - mp, mloop + mp->loopstart, (const float(*)[3])coords, face_no); + mp, loops + mp->loopstart, (const float(*)[3])coords, face_no); /* find the projector which the face points at most directly * (projector normal with largest dot product is best) @@ -258,7 +257,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = mp->totloop - 1; do { uint lidx = mp->loopstart + fidx; - uint vidx = mloop[lidx].v; + uint vidx = loops[lidx].v; BLI_uvproject_from_camera(mloop_uv[lidx].uv, coords[vidx], best_projector->uci); } while (fidx--); } @@ -266,7 +265,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint fidx = mp->totloop - 1; do { uint lidx = mp->loopstart + fidx; - uint vidx = mloop[lidx].v; + uint vidx = loops[lidx].v; mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]); } while (fidx--); } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 0439f92ac57..9561f177cf1 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -23,6 +23,7 @@ #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_lib_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_screen.h" @@ -81,11 +82,11 @@ static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonen } typedef struct UVWarpData { - MPoly *mpoly; - MLoop *mloop; + const MPoly *mpoly; + const MLoop *mloop; MLoopUV *mloopuv; - MDeformVert *dvert; + const MDeformVert *dvert; int defgrp_index; float (*warp_mat)[4]; @@ -131,10 +132,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * { UVWarpModifierData *umd = (UVWarpModifierData *)md; int polys_num, loops_num; - MPoly *mpoly; - MLoop *mloop; MLoopUV *mloopuv; - MDeformVert *dvert; + const MDeformVert *dvert; int defgrp_index; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; float warp_mat[4][4]; @@ -196,19 +195,19 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* make sure we're using an existing layer */ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); + const MPoly *polys = BKE_mesh_polygons(mesh); + const MLoop *loops = BKE_mesh_loops(mesh); polys_num = mesh->totpoly; loops_num = mesh->totloop; - mpoly = mesh->mpoly; - mloop = mesh->mloop; /* make sure we are not modifying the original UV map */ mloopuv = CustomData_duplicate_referenced_layer_named( &mesh->ldata, CD_MLOOPUV, uvname, loops_num); MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index); UVWarpData data = { - .mpoly = mpoly, - .mloop = mloop, + .mpoly = polys, + .mloop = loops, .mloopuv = mloopuv, .dvert = dvert, .defgrp_index = defgrp_index, diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 0968d0646a5..ab6b2941d2f 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -196,7 +196,7 @@ static void warpModifier_do(WarpModifierData *wmd, float fac = 1.0f, weight; int i; int defgrp_index; - MDeformVert *dvert, *dv = NULL; + const MDeformVert *dvert, *dv = NULL; const bool invert_vgroup = (wmd->flag & MOD_WARP_INVERT_VGROUP) != 0; float(*tex_co)[3] = NULL; diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 9647f47c6e0..a6b274909c0 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -134,8 +134,7 @@ static void waveModifier_do(WaveModifierData *md, int verts_num) { WaveModifierData *wmd = (WaveModifierData *)md; - MVert *mvert = NULL; - MDeformVert *dvert; + const MDeformVert *dvert; int defgrp_index; float ctime = DEG_get_ctime(ctx->depsgraph); float minfac = (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow)); @@ -148,7 +147,6 @@ static void waveModifier_do(WaveModifierData *md, const float(*vert_normals)[3] = NULL; if ((wmd->flag & MOD_WAVE_NORM) && (mesh != NULL)) { - mvert = mesh->mvert; vert_normals = BKE_mesh_vertex_normals_ensure(mesh); } @@ -269,7 +267,7 @@ static void waveModifier_do(WaveModifierData *md, /* Apply weight & falloff. */ amplit *= def_weight * falloff_fac; - if (mvert) { + if (vert_normals) { /* move along normals */ if (wmd->flag & MOD_WAVE_NORM_X) { co[0] += (lifefac * amplit) * vert_normals[i][0]; diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index 5b5d464a710..c6c0ce58463 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -71,20 +71,20 @@ typedef struct WeightedNormalData { const int loops_num; const int polys_num; - MVert *mvert; + const MVert *mvert; const float (*vert_normals)[3]; MEdge *medge; - MLoop *mloop; + const MLoop *mloop; short (*clnors)[2]; const bool has_clnors; /* True if clnors already existed, false if we had to create them. */ const float split_angle; - MPoly *mpoly; + const MPoly *mpoly; const float (*polynors)[3]; const int *poly_strength; - MDeformVert *dvert; + const MDeformVert *dvert; const int defgrp_index; const bool use_invert_vgroup; @@ -133,7 +133,7 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd, { const float(*polynors)[3] = wn_data->polynors; - MDeformVert *dvert = wn_data->dvert; + const MDeformVert *dvert = wn_data->dvert; const int defgrp_index = wn_data->defgrp_index; const bool use_invert_vgroup = wn_data->use_invert_vgroup; @@ -186,18 +186,18 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, const int loops_num = wn_data->loops_num; const int polys_num = wn_data->polys_num; - MVert *mvert = wn_data->mvert; + const MVert *mvert = wn_data->mvert; MEdge *medge = wn_data->medge; - MLoop *mloop = wn_data->mloop; + const MLoop *mloop = wn_data->mloop; short(*clnors)[2] = wn_data->clnors; int *loop_to_poly = wn_data->loop_to_poly; - MPoly *mpoly = wn_data->mpoly; + const MPoly *mpoly = wn_data->mpoly; const float(*polynors)[3] = wn_data->polynors; const int *poly_strength = wn_data->poly_strength; - MDeformVert *dvert = wn_data->dvert; + const MDeformVert *dvert = wn_data->dvert; const short mode = wn_data->mode; ModePair *mode_pair = wn_data->mode_pair; @@ -243,7 +243,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, /* In this first loop, we assign each WeightedNormalDataAggregateItem * to its smooth fan of loops (aka lnor space). */ - MPoly *mp; + const MPoly *mp; int mp_index; int item_index; for (mp = mpoly, mp_index = 0, item_index = 0; mp_index < polys_num; mp++, mp_index++) { @@ -446,11 +446,11 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w { const int polys_num = wn_data->polys_num; - MVert *mvert = wn_data->mvert; - MLoop *mloop = wn_data->mloop; - MPoly *mpoly = wn_data->mpoly; + const MVert *mvert = wn_data->mvert; + const MLoop *mloop = wn_data->mloop; + const MPoly *mpoly = wn_data->mpoly; - MPoly *mp; + const MPoly *mp; int mp_index; ModePair *face_area = MEM_malloc_arrayN((size_t)polys_num, sizeof(*face_area), __func__); @@ -472,11 +472,11 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData const int loops_num = wn_data->loops_num; const int polys_num = wn_data->polys_num; - MVert *mvert = wn_data->mvert; - MLoop *mloop = wn_data->mloop; - MPoly *mpoly = wn_data->mpoly; + const MVert *mvert = wn_data->mvert; + const MLoop *mloop = wn_data->mloop; + const MPoly *mpoly = wn_data->mpoly; - MPoly *mp; + const MPoly *mp; int mp_index; int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__); @@ -484,7 +484,7 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData ModePair *corner_angle = MEM_malloc_arrayN((size_t)loops_num, sizeof(*corner_angle), __func__); for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) { - MLoop *ml_start = &mloop[mp->loopstart]; + const MLoop *ml_start = &mloop[mp->loopstart]; float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__); BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle); @@ -513,11 +513,11 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD const int loops_num = wn_data->loops_num; const int polys_num = wn_data->polys_num; - MVert *mvert = wn_data->mvert; - MLoop *mloop = wn_data->mloop; - MPoly *mpoly = wn_data->mpoly; + const MVert *mvert = wn_data->mvert; + const MLoop *mloop = wn_data->mloop; + const MPoly *mpoly = wn_data->mpoly; - MPoly *mp; + const MPoly *mp; int mp_index; int *loop_to_poly = MEM_malloc_arrayN((size_t)loops_num, sizeof(*loop_to_poly), __func__); @@ -525,7 +525,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD ModePair *combined = MEM_malloc_arrayN((size_t)loops_num, sizeof(*combined), __func__); for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) { - MLoop *ml_start = &mloop[mp->loopstart]; + const MLoop *ml_start = &mloop[mp->loopstart]; float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert); float *index_angle = MEM_malloc_arrayN((size_t)mp->totloop, sizeof(*index_angle), __func__); @@ -579,11 +579,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const int edges_num = result->totedge; const int loops_num = result->totloop; const int polys_num = result->totpoly; - - MEdge *medge = result->medge; - MPoly *mpoly = result->mpoly; - MVert *mvert = result->mvert; - MLoop *mloop = result->mloop; + const MVert *mvert = BKE_mesh_vertices(result); + MEdge *medge = BKE_mesh_edges_for_write(result); + const MPoly *mpoly = BKE_mesh_polygons(result); + const MLoop *mloop = BKE_mesh_loops(result); /* Right now: * If weight = 50 then all faces are given equal weight. @@ -613,7 +612,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * &result->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, NULL, loops_num); } - MDeformVert *dvert; + const MDeformVert *dvert; int defgrp_index; MOD_get_vgroup(ctx->object, mesh, wnmd->defgrp_name, &dvert, &defgrp_index); diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index d71813c7dd5..4002718d06c 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -27,6 +27,7 @@ #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_lib_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_screen.h" #include "BKE_texture.h" /* Texture masking. */ @@ -158,7 +159,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md; - MDeformVert *dvert = NULL; MDeformWeight **dw = NULL; float *org_w; /* Array original weights. */ float *new_w; /* Array new weights. */ @@ -198,18 +198,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } - if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num); - } - else { - /* Add a valid data layer! */ - dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, verts_num); - } + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(mesh); + /* Ultimate security check. */ if (!dvert) { return mesh; } - mesh->dvert = dvert; /* Get org weights, assuming 0.0 for vertices not in given vgroup. */ org_w = MEM_malloc_arrayN(verts_num, sizeof(float), "WeightVGEdit Modifier, org_w"); diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index 1d38333f15b..1481ffad82c 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -23,6 +23,7 @@ #include "BKE_customdata.h" #include "BKE_deform.h" #include "BKE_lib_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_screen.h" #include "BKE_texture.h" /* Texture masking. */ @@ -206,7 +207,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * WeightVGMixModifierData *wmd = (WeightVGMixModifierData *)md; - MDeformVert *dvert = NULL; MDeformWeight **dw1, **tdw1, **dw2, **tdw2; float *org_w; float *new_w; @@ -263,18 +263,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } - if (has_mdef) { - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num); - } - else { - /* Add a valid data layer! */ - dvert = CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, verts_num); - } + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(mesh); + /* Ultimate security check. */ if (!dvert) { return mesh; } - mesh->dvert = dvert; /* Find out which vertices to work on. */ tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGMix Modifier, tidx"); diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index df2b494199e..80c49745003 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -423,7 +423,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BLI_assert(mesh != NULL); WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md; - MDeformVert *dvert = NULL; MDeformWeight **dw, **tdw; float(*v_cos)[3] = NULL; /* The vertices coordinates. */ Object *ob = ctx->object; @@ -475,12 +474,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return mesh; } - dvert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MDEFORMVERT, verts_num); + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(mesh); /* Ultimate security check. */ if (!dvert) { return mesh; } - mesh->dvert = dvert; /* Find out which vertices to work on (all vertices in vgroup), and get their relevant weight. */ tidx = MEM_malloc_arrayN(verts_num, sizeof(int), "WeightVGProximity Modifier, tidx"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 03892501c89..d03f036eaa4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -46,6 +46,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) } /* Copy vertices. */ + MutableSpan<MVert> dst_verts = result->vertices_for_write(); for (const int i : IndexRange(verts_num)) { float co[3]; int original_index; @@ -59,7 +60,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) } # endif /* Copy the position of the original point. */ - copy_v3_v3(result->mvert[i].co, co); + copy_v3_v3(dst_verts[i].co, co); } else { BLI_assert_msg(0, "Unexpected new vertex in hull output"); @@ -73,6 +74,8 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) * to a loop and edges need to be created from that. */ Array<MLoop> mloop_src(loops_num); uint edge_index = 0; + MutableSpan<MEdge> edges = result->edges_for_write(); + for (const int i : IndexRange(loops_num)) { int v_from; int v_to; @@ -81,7 +84,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) mloop_src[i].v = (uint)v_from; /* Add edges for ascending order loops only. */ if (v_from < v_to) { - MEdge &edge = result->medge[edge_index]; + MEdge &edge = edges[edge_index]; edge.v1 = v_from; edge.v2 = v_to; edge.flag = ME_EDGEDRAW | ME_EDGERENDER; @@ -95,7 +98,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) } if (edges_num == 1) { /* In this case there are no loops. */ - MEdge &edge = result->medge[0]; + MEdge &edge = edges[0]; edge.v1 = 0; edge.v2 = 1; edge.flag |= ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE; @@ -106,7 +109,10 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) /* Copy faces. */ Array<int> loops; int j = 0; - MLoop *loop = result->mloop; + MutableSpan<MPoly> polys = result->polygons_for_write(); + MutableSpan<MLoop> mesh_loops = result->loops_for_write(); + MLoop *loop = mesh_loops.data(); + for (const int i : IndexRange(faces_num)) { const int len = plConvexHullGetFaceSize(hull, i); @@ -116,7 +122,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) loops.reinitialize(len); plConvexHullGetFaceLoops(hull, i, loops.data()); - MPoly &face = result->mpoly[i]; + MPoly &face = polys[i]; face.loopstart = j; face.totloop = len; for (const int k : IndexRange(len)) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index c9a8dba55b2..580886ad6be 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -79,10 +79,10 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result<double> &result) } Mesh *mesh = BKE_mesh_new_nomain(vert_len, edge_len, 0, loop_len, poly_len); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); for (const int i : IndexRange(result.vert.size())) { copy_v3_v3(verts[i].co, float3((float)result.vert[i].x, (float)result.vert[i].y, 0.0f)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index 2481170835b..07b419cc05c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -66,6 +66,12 @@ static void deform_curves(const CurvesGeometry &curves, const float4x4 curves_to_surface = surface_to_curves.inverted(); + const Span<MVert> surface_verts_old = surface_mesh_old.vertices(); + const Span<MLoop> surface_loops_old = surface_mesh_old.loops(); + + const Span<MVert> surface_verts_new = surface_mesh_new.vertices(); + const Span<MLoop> surface_loops_new = surface_mesh_new.loops(); + threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { const ReverseUVSampler::Result &surface_sample_old = surface_samples_old[curve_i]; @@ -92,13 +98,13 @@ static void deform_curves(const CurvesGeometry &curves, const int corner_1_new = looptri_new.tri[1]; const int corner_2_new = looptri_new.tri[2]; - const int vert_0_old = surface_mesh_old.mloop[corner_0_old].v; - const int vert_1_old = surface_mesh_old.mloop[corner_1_old].v; - const int vert_2_old = surface_mesh_old.mloop[corner_2_old].v; + const int vert_0_old = surface_loops_old[corner_0_old].v; + const int vert_1_old = surface_loops_old[corner_1_old].v; + const int vert_2_old = surface_loops_old[corner_2_old].v; - const int vert_0_new = surface_mesh_new.mloop[corner_0_new].v; - const int vert_1_new = surface_mesh_new.mloop[corner_1_new].v; - const int vert_2_new = surface_mesh_new.mloop[corner_2_new].v; + const int vert_0_new = surface_loops_new[corner_0_new].v; + const int vert_1_new = surface_loops_new[corner_1_new].v; + const int vert_2_new = surface_loops_new[corner_2_new].v; const float3 &normal_0_old = corner_normals_old[corner_0_old]; const float3 &normal_1_old = corner_normals_old[corner_1_old]; @@ -112,14 +118,14 @@ static void deform_curves(const CurvesGeometry &curves, const float3 normal_new = math::normalize( mix3(bary_weights_new, normal_0_new, normal_1_new, normal_2_new)); - const float3 &pos_0_old = surface_mesh_old.mvert[vert_0_old].co; - const float3 &pos_1_old = surface_mesh_old.mvert[vert_1_old].co; - const float3 &pos_2_old = surface_mesh_old.mvert[vert_2_old].co; + const float3 &pos_0_old = surface_verts_old[vert_0_old].co; + const float3 &pos_1_old = surface_verts_old[vert_1_old].co; + const float3 &pos_2_old = surface_verts_old[vert_2_old].co; const float3 pos_old = mix3(bary_weights_old, pos_0_old, pos_1_old, pos_2_old); - const float3 &pos_0_new = surface_mesh_new.mvert[vert_0_new].co; - const float3 &pos_1_new = surface_mesh_new.mvert[vert_1_new].co; - const float3 &pos_2_new = surface_mesh_new.mvert[vert_2_new].co; + const float3 &pos_0_new = surface_verts_new[vert_0_new].co; + const float3 &pos_1_new = surface_verts_new[vert_1_new].co; + const float3 &pos_2_new = surface_verts_new[vert_2_new].co; const float3 pos_new = mix3(bary_weights_new, pos_0_new, pos_1_new, pos_2_new); /* The translation is just the difference between the old and new position on the surface. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index 58ba2fefff9..a4096efb79f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -161,10 +161,11 @@ static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind> const Span<int> selected_poly_indices, const Mesh &mesh_in) { + const Span<MPoly> polys = mesh_in.polygons(); Vector<int64_t> indices; indices.reserve(selected_loops_num); for (const int src_poly_index : selected_poly_indices) { - const MPoly &src_poly = mesh_in.mpoly[src_poly_index]; + const MPoly &src_poly = polys[src_poly_index]; const int src_loop_start = src_poly.loopstart; const int tot_loop = src_poly.totloop; for (const int i : IndexRange(tot_loop)) { @@ -180,34 +181,30 @@ static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh, Span<int> vertex_map) { BLI_assert(src_mesh.totvert == vertex_map.size()); + const Span<MVert> src_verts = src_mesh.vertices(); + MutableSpan<MVert> dst_verts = dst_mesh.vertices_for_write(); + for (const int i_src : vertex_map.index_range()) { const int i_dst = vertex_map[i_src]; if (i_dst == -1) { continue; } - - const MVert &v_src = src_mesh.mvert[i_src]; - MVert &v_dst = dst_mesh.mvert[i_dst]; - - v_dst = v_src; + dst_verts[i_dst] = src_verts[i_src]; } } static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span<int> edge_map) { BLI_assert(src_mesh.totedge == edge_map.size()); + const Span<MEdge> src_edges = src_mesh.edges(); + MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); + for (const int i_src : IndexRange(src_mesh.totedge)) { const int i_dst = edge_map[i_src]; if (ELEM(i_dst, -1, -2)) { continue; } - - const MEdge &e_src = src_mesh.medge[i_src]; - MEdge &e_dst = dst_mesh.medge[i_dst]; - - e_dst = e_src; - e_dst.v1 = e_src.v1; - e_dst.v2 = e_src.v2; + dst_edges[i_dst] = src_edges[i_src]; } } @@ -218,14 +215,16 @@ static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, { BLI_assert(src_mesh.totvert == vertex_map.size()); BLI_assert(src_mesh.totedge == edge_map.size()); + const Span<MEdge> src_edges = src_mesh.edges(); + MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write(); + for (const int i_src : IndexRange(src_mesh.totedge)) { const int i_dst = edge_map[i_src]; if (i_dst == -1) { continue; } - - const MEdge &e_src = src_mesh.medge[i_src]; - MEdge &e_dst = dst_mesh.medge[i_dst]; + const MEdge &e_src = src_edges[i_src]; + MEdge &e_dst = dst_edges[i_dst]; e_dst = e_src; e_dst.v1 = vertex_map[e_src.v1]; @@ -240,16 +239,21 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span<int> masked_poly_indices, Span<int> new_loop_starts) { + const Span<MPoly> src_polygons = src_mesh.polygons(); + const Span<MLoop> src_loops = src_mesh.loops(); + MutableSpan<MPoly> dst_polygons = dst_mesh.polygons_for_write(); + MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); + for (const int i_dst : masked_poly_indices.index_range()) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_mesh.mpoly[i_src]; - MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const MPoly &mp_src = src_polygons[i_src]; + MPoly &mp_dst = dst_polygons[i_dst]; const int i_ml_src = mp_src.loopstart; const int i_ml_dst = new_loop_starts[i_dst]; - const MLoop *ml_src = src_mesh.mloop + i_ml_src; - MLoop *ml_dst = dst_mesh.mloop + i_ml_dst; + const MLoop *ml_src = &src_loops[i_ml_src]; + MLoop *ml_dst = &dst_loops[i_ml_dst]; mp_dst = mp_src; mp_dst.loopstart = i_ml_dst; @@ -266,16 +270,21 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span<int> masked_poly_indices, Span<int> new_loop_starts) { + const Span<MPoly> src_polygons = src_mesh.polygons(); + const Span<MLoop> src_loops = src_mesh.loops(); + MutableSpan<MPoly> dst_polygons = dst_mesh.polygons_for_write(); + MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); + for (const int i_dst : masked_poly_indices.index_range()) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_mesh.mpoly[i_src]; - MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const MPoly &mp_src = src_polygons[i_src]; + MPoly &mp_dst = dst_polygons[i_dst]; const int i_ml_src = mp_src.loopstart; const int i_ml_dst = new_loop_starts[i_dst]; - const MLoop *ml_src = src_mesh.mloop + i_ml_src; - MLoop *ml_dst = dst_mesh.mloop + i_ml_dst; + const MLoop *ml_src = &src_loops[i_ml_src]; + MLoop *ml_dst = &dst_loops[i_ml_dst]; mp_dst = mp_src; mp_dst.loopstart = i_ml_dst; @@ -293,16 +302,21 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, Span<int> masked_poly_indices, Span<int> new_loop_starts) { + const Span<MPoly> src_polygons = src_mesh.polygons(); + const Span<MLoop> src_loops = src_mesh.loops(); + MutableSpan<MPoly> dst_polygons = dst_mesh.polygons_for_write(); + MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write(); + for (const int i_dst : masked_poly_indices.index_range()) { const int i_src = masked_poly_indices[i_dst]; - const MPoly &mp_src = src_mesh.mpoly[i_src]; - MPoly &mp_dst = dst_mesh.mpoly[i_dst]; + const MPoly &mp_src = src_polygons[i_src]; + MPoly &mp_dst = dst_polygons[i_dst]; const int i_ml_src = mp_src.loopstart; const int i_ml_dst = new_loop_starts[i_dst]; - const MLoop *ml_src = src_mesh.mloop + i_ml_src; - MLoop *ml_dst = dst_mesh.mloop + i_ml_dst; + const MLoop *ml_src = &src_loops[i_ml_src]; + MLoop *ml_dst = &dst_loops[i_ml_dst]; mp_dst = mp_src; mp_dst.loopstart = i_ml_dst; @@ -419,10 +433,11 @@ static void compute_selected_edges_from_vertex_selection(const Mesh &mesh, int *r_selected_edges_num) { BLI_assert(mesh.totedge == r_edge_map.size()); + const Span<MEdge> edges = mesh.edges(); int selected_edges_num = 0; for (const int i : IndexRange(mesh.totedge)) { - const MEdge &edge = mesh.medge[i]; + const MEdge &edge = edges[i]; /* Only add the edge if both vertices will be in the new mesh. */ if (vertex_selection[edge.v1] && vertex_selection[edge.v2]) { @@ -445,17 +460,19 @@ static void compute_selected_polygons_from_vertex_selection(const Mesh &mesh, int *r_selected_loops_num) { BLI_assert(mesh.totvert == vertex_selection.size()); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); int selected_loops_num = 0; - for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly_src = mesh.mpoly[i]; + for (const int i : polys.index_range()) { + const MPoly &poly_src = polys[i]; bool all_verts_in_selection = true; - Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); - for (const MLoop &loop : loops_src) { + const Span<MLoop> poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); + for (const MLoop &loop : poly_loops) { if (!vertex_selection[loop.v]) { all_verts_in_selection = false; break; @@ -486,11 +503,12 @@ static void compute_selected_vertices_and_edges_from_edge_selection( int *r_selected_edges_num) { BLI_assert(mesh.totedge == edge_selection.size()); + const Span<MEdge> edges = mesh.edges(); int selected_edges_num = 0; int selected_verts_num = 0; for (const int i : IndexRange(mesh.totedge)) { - const MEdge &edge = mesh.medge[i]; + const MEdge &edge = edges[i]; if (edge_selection[i]) { r_edge_map[i] = selected_edges_num; selected_edges_num++; @@ -547,16 +565,19 @@ static void compute_selected_polygons_from_edge_selection(const Mesh &mesh, int *r_selected_polys_num, int *r_selected_loops_num) { + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); int selected_loops_num = 0; - for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly_src = mesh.mpoly[i]; + for (const int i : polys.index_range()) { + const MPoly &poly_src = polys[i]; bool all_edges_in_selection = true; - Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); - for (const MLoop &loop : loops_src) { + const Span<MLoop> poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); + for (const MLoop &loop : poly_loops) { if (!edge_selection[loop.e]) { all_edges_in_selection = false; break; @@ -654,7 +675,7 @@ static void compute_selected_mesh_data_from_edge_selection_edge_face( /** * Checks for every edge if it is in `edge_selection`. If it is, the vertices belonging to - * that edge are kept as well. The polygons are kept if all edges are in the selection. + * that edge are kept as well. The polys are kept if all edges are in the selection. */ static void compute_selected_mesh_data_from_edge_selection(const Mesh &mesh, const Span<bool> edge_selection, @@ -693,13 +714,14 @@ static void compute_selected_polygons_from_poly_selection(const Mesh &mesh, int *r_selected_loops_num) { BLI_assert(mesh.totpoly == poly_selection.size()); + const Span<MPoly> polys = mesh.polygons(); r_selected_poly_indices.reserve(mesh.totpoly); r_loop_starts.reserve(mesh.totloop); int selected_loops_num = 0; - for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly_src = mesh.mpoly[i]; + for (const int i : polys.index_range()) { + const MPoly &poly_src = polys[i]; /* We keep this one. */ if (poly_selection[i]) { r_selected_poly_indices.append_unchecked(i); @@ -726,6 +748,9 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( { BLI_assert(mesh.totpoly == poly_selection.size()); BLI_assert(mesh.totedge == r_edge_map.size()); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + r_edge_map.fill(-1); r_selected_poly_indices.reserve(mesh.totpoly); @@ -733,8 +758,8 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( int selected_loops_num = 0; int selected_edges_num = 0; - for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly_src = mesh.mpoly[i]; + for (const int i : polys.index_range()) { + const MPoly &poly_src = polys[i]; /* We keep this one. */ if (poly_selection[i]) { r_selected_poly_indices.append_unchecked(i); @@ -742,8 +767,8 @@ static void compute_selected_mesh_data_from_poly_selection_edge_face( selected_loops_num += poly_src.totloop; /* Add the vertices and the edges. */ - Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); - for (const MLoop &loop : loops_src) { + const Span<MLoop> poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); + for (const MLoop &loop : poly_loops) { /* Check first if it has not yet been added. */ if (r_edge_map[loop.e] == -1) { r_edge_map[loop.e] = selected_edges_num; @@ -774,6 +799,9 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, { BLI_assert(mesh.totpoly == poly_selection.size()); BLI_assert(mesh.totedge == r_edge_map.size()); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + r_vertex_map.fill(-1); r_edge_map.fill(-1); @@ -783,8 +811,8 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, int selected_loops_num = 0; int selected_verts_num = 0; int selected_edges_num = 0; - for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly_src = mesh.mpoly[i]; + for (const int i : polys.index_range()) { + const MPoly &poly_src = polys[i]; /* We keep this one. */ if (poly_selection[i]) { r_selected_poly_indices.append_unchecked(i); @@ -792,8 +820,8 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh, selected_loops_num += poly_src.totloop; /* Add the vertices and the edges. */ - Span<MLoop> loops_src(&mesh.mloop[poly_src.loopstart], poly_src.totloop); - for (const MLoop &loop : loops_src) { + const Span<MLoop> poly_loops = loops.slice(poly_src.loopstart, poly_src.totloop); + for (const MLoop &loop : poly_loops) { /* Check first if it has not yet been added. */ if (r_vertex_map[loop.v] == -1) { r_vertex_map[loop.v] = selected_verts_num; @@ -968,7 +996,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, selected_polys_num); /* Copy the selected parts of the mesh over to the new mesh. */ - memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert)); + mesh_out->vertices_for_write().copy_from(mesh_in.vertices()); copy_masked_edges_to_new_mesh(mesh_in, *mesh_out, edge_map); copy_masked_polys_to_new_mesh( mesh_in, *mesh_out, edge_map, selected_poly_indices, new_loop_starts); @@ -1031,8 +1059,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, &mesh_in, mesh_in.totvert, mesh_in.totedge, 0, selected_loops_num, selected_polys_num); /* Copy the selected parts of the mesh over to the new mesh. */ - memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert)); - memcpy(mesh_out->medge, mesh_in.medge, mesh_in.totedge * sizeof(MEdge)); + mesh_out->vertices_for_write().copy_from(mesh_in.vertices()); + mesh_out->edges_for_write().copy_from(mesh_in.edges()); copy_masked_polys_to_new_mesh(mesh_in, *mesh_out, selected_poly_indices, new_loop_starts); /* Copy attributes. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index d9115d39705..2bb321a349a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -105,6 +105,8 @@ static void sample_mesh_surface(const Mesh &mesh, Vector<float3> &r_bary_coords, Vector<int> &r_looptri_indices) { + const Span<MVert> verts = mesh.vertices(); + const Span<MLoop> loops = mesh.loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), BKE_mesh_runtime_looptri_len(&mesh)}; @@ -113,12 +115,12 @@ static void sample_mesh_surface(const Mesh &mesh, const int v0_loop = looptri.tri[0]; const int v1_loop = looptri.tri[1]; const int v2_loop = looptri.tri[2]; - const int v0_index = mesh.mloop[v0_loop].v; - const int v1_index = mesh.mloop[v1_loop].v; - const int v2_index = mesh.mloop[v2_loop].v; - const float3 v0_pos = float3(mesh.mvert[v0_index].co); - const float3 v1_pos = float3(mesh.mvert[v1_index].co); - const float3 v2_pos = float3(mesh.mvert[v2_index].co); + const int v0_index = loops[v0_loop].v; + const int v1_index = loops[v1_loop].v; + const int v2_index = loops[v2_loop].v; + const float3 v0_pos = verts[v0_index].co; + const float3 v1_pos = verts[v1_index].co; + const float3 v2_pos = verts[v2_index].co; float looptri_density_factor = 1.0f; if (!density_factors.is_empty()) { @@ -348,6 +350,8 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, attribute_outputs.rotation_id.get(), ATTR_DOMAIN_POINT); } + const Span<MVert> verts = mesh.vertices(); + const Span<MLoop> loops = mesh.loops(); const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh), BKE_mesh_runtime_looptri_len(&mesh)}; @@ -356,12 +360,12 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, const MLoopTri &looptri = looptris[looptri_index]; const float3 &bary_coord = bary_coords[i]; - const int v0_index = mesh.mloop[looptri.tri[0]].v; - const int v1_index = mesh.mloop[looptri.tri[1]].v; - const int v2_index = mesh.mloop[looptri.tri[2]].v; - const float3 v0_pos = float3(mesh.mvert[v0_index].co); - const float3 v1_pos = float3(mesh.mvert[v1_index].co); - const float3 v2_pos = float3(mesh.mvert[v2_index].co); + const int v0_index = loops[looptri.tri[0]].v; + const int v1_index = loops[looptri.tri[1]].v; + const int v2_index = loops[looptri.tri[2]].v; + const float3 v0_pos = verts[v0_index].co; + const float3 v1_pos = verts[v1_index].co; + const float3 v2_pos = verts[v2_index].co; ids.span[i] = noise::hash(noise::hash_float(bary_coord), looptri_index); diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index 76eeee95239..1b9e9ae9b4a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -209,13 +209,18 @@ static void calc_boundaries(const Mesh &mesh, { BLI_assert(r_vertex_types.size() == mesh.totvert); BLI_assert(r_edge_types.size() == mesh.totedge); + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + r_vertex_types.fill(VertexType::Loose); r_edge_types.fill(EdgeType::Loose); /* Add up the number of polys connected to each edge. */ for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[i]; - for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) { + const MPoly &poly = polys[i]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + for (const MLoop &loop : poly_loops) { r_edge_types[loop.e] = get_edge_type_with_added_neighbor(r_edge_types[loop.e]); } } @@ -226,7 +231,7 @@ static void calc_boundaries(const Mesh &mesh, if (edge_type == EdgeType::Loose) { continue; } - const MEdge &edge = mesh.medge[i]; + const MEdge &edge = edges[i]; if (edge_type == EdgeType::Boundary) { r_vertex_types[edge.v1] = get_vertex_type_with_added_neighbor(r_vertex_types[edge.v1]); r_vertex_types[edge.v2] = get_vertex_type_with_added_neighbor(r_vertex_types[edge.v2]); @@ -241,7 +246,7 @@ static void calc_boundaries(const Mesh &mesh, for (const int i : IndexRange(mesh.totedge)) { const EdgeType edge_type = r_edge_types[i]; if (edge_type == EdgeType::Normal) { - const MEdge &edge = mesh.medge[i]; + const MEdge &edge = edges[i]; if (r_vertex_types[edge.v1] == VertexType::Loose) { r_vertex_types[edge.v1] = VertexType::Normal; } @@ -258,9 +263,12 @@ static void calc_boundaries(const Mesh &mesh, static void create_vertex_poly_map(const Mesh &mesh, MutableSpan<Vector<int>> r_vertex_poly_indices) { - for (const int i : IndexRange(mesh.totpoly)) { - const MPoly &poly = mesh.mpoly[i]; - for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) { + const Span<MPoly> polygons = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + for (const int i : polygons.index_range()) { + const MPoly &poly = polygons[i]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + for (const MLoop &loop : poly_loops) { r_vertex_poly_indices[loop.v].append(i); } } @@ -321,7 +329,9 @@ static void create_vertex_poly_map(const Mesh &mesh, * - Finally if we are in the normal case we also need to add the last "shared edge" to close the * loop. */ -static bool sort_vertex_polys(const Mesh &mesh, +static bool sort_vertex_polys(const Span<MEdge> edges, + const Span<MPoly> polys, + const Span<MLoop> loops, const int vertex_index, const bool boundary_vertex, const Span<EdgeType> edge_types, @@ -336,11 +346,11 @@ static bool sort_vertex_polys(const Mesh &mesh, /* For each polygon store the two corners whose edge contains the vertex. */ Array<std::pair<int, int>> poly_vertex_corners(connected_polygons.size()); for (const int i : connected_polygons.index_range()) { - const MPoly &poly = mesh.mpoly[connected_polygons[i]]; + const MPoly &poly = polys[connected_polygons[i]]; bool first_edge_done = false; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; - if (mesh.medge[loop.e].v1 == vertex_index || mesh.medge[loop.e].v2 == vertex_index) { + const MLoop &loop = loops[loop_index]; + if (edges[loop.e].v1 == vertex_index || edges[loop.e].v2 == vertex_index) { if (!first_edge_done) { poly_vertex_corners[i].first = loop_index; first_edge_done = true; @@ -360,8 +370,8 @@ static bool sort_vertex_polys(const Mesh &mesh, if (boundary_vertex) { /* Our first polygon needs to be one which has a boundary edge. */ for (const int i : connected_polygons.index_range()) { - const MLoop &first_loop = mesh.mloop[poly_vertex_corners[i].first]; - const MLoop &second_loop = mesh.mloop[poly_vertex_corners[i].second]; + const MLoop &first_loop = loops[poly_vertex_corners[i].first]; + const MLoop &second_loop = loops[poly_vertex_corners[i].second]; if (edge_types[first_loop.e] == EdgeType::Boundary && first_loop.v == vertex_index) { shared_edge_i = second_loop.e; r_sorted_corners[0] = poly_vertex_corners[i].first; @@ -381,8 +391,8 @@ static bool sort_vertex_polys(const Mesh &mesh, /* The rotation is inconsistent between the two polygons on the boundary. Just choose one * of the polygon's orientation. */ for (const int i : connected_polygons.index_range()) { - const MLoop &first_loop = mesh.mloop[poly_vertex_corners[i].first]; - const MLoop &second_loop = mesh.mloop[poly_vertex_corners[i].second]; + const MLoop &first_loop = loops[poly_vertex_corners[i].first]; + const MLoop &second_loop = loops[poly_vertex_corners[i].second]; if (edge_types[first_loop.e] == EdgeType::Boundary) { shared_edge_i = second_loop.e; r_sorted_corners[0] = poly_vertex_corners[i].first; @@ -402,8 +412,8 @@ static bool sort_vertex_polys(const Mesh &mesh, } else { /* Any polygon can be the first. Just need to check the orientation. */ - const MLoop &first_loop = mesh.mloop[poly_vertex_corners[0].first]; - const MLoop &second_loop = mesh.mloop[poly_vertex_corners[0].second]; + const MLoop &first_loop = loops[poly_vertex_corners[0].first]; + const MLoop &second_loop = loops[poly_vertex_corners[0].second]; if (first_loop.v == vertex_index) { shared_edge_i = second_loop.e; r_sorted_corners[0] = poly_vertex_corners[0].first; @@ -421,8 +431,8 @@ static bool sort_vertex_polys(const Mesh &mesh, /* Look at the other polys to see if it has this shared edge. */ int j = i + 1; for (; j < connected_polygons.size(); ++j) { - const MLoop &first_loop = mesh.mloop[poly_vertex_corners[j].first]; - const MLoop &second_loop = mesh.mloop[poly_vertex_corners[j].second]; + const MLoop &first_loop = loops[poly_vertex_corners[j].first]; + const MLoop &second_loop = loops[poly_vertex_corners[j].second]; if (first_loop.e == shared_edge_i) { r_sorted_corners[i + 1] = poly_vertex_corners[j].first; shared_edge_i = second_loop.e; @@ -455,14 +465,16 @@ static bool sort_vertex_polys(const Mesh &mesh, * Get the edge on the poly that contains the given vertex and is a boundary edge. */ static void boundary_edge_on_poly(const MPoly &poly, - const Mesh &mesh, + const Span<MEdge> edges, + const Span<MLoop> loops, const int vertex_index, const Span<EdgeType> edge_types, int &r_edge) { - for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) { + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + for (const MLoop &loop : poly_loops) { if (edge_types[loop.e] == EdgeType::Boundary) { - const MEdge &edge = mesh.medge[loop.e]; + const MEdge &edge = edges[loop.e]; if (edge.v1 == vertex_index || edge.v2 == vertex_index) { r_edge = loop.e; return; @@ -476,7 +488,8 @@ static void boundary_edge_on_poly(const MPoly &poly, * orientation of the poly is taken into account. */ static void boundary_edges_on_poly(const MPoly &poly, - const Mesh &mesh, + const Span<MEdge> edges, + const Span<MLoop> loops, const int vertex_index, const Span<EdgeType> edge_types, int &r_edge1, @@ -486,9 +499,10 @@ static void boundary_edges_on_poly(const MPoly &poly, /* This is set to true if the order in which we encounter the two edges is inconsistent with the * orientation of the polygon. */ bool needs_swap = false; - for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) { + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + for (const MLoop &loop : poly_loops) { if (edge_types[loop.e] == EdgeType::Boundary) { - const MEdge &edge = mesh.medge[loop.e]; + const MEdge &edge = edges[loop.e]; if (edge.v1 == vertex_index || edge.v2 == vertex_index) { if (edge1_done) { if (needs_swap) { @@ -510,7 +524,7 @@ static void boundary_edges_on_poly(const MPoly &poly, } } -static void add_edge(const Mesh &mesh, +static void add_edge(const Span<MEdge> src_edges, const int old_edge_i, const int v1, const int v2, @@ -518,7 +532,7 @@ static void add_edge(const Mesh &mesh, Vector<MEdge> &new_edges, Vector<int> &loop_edges) { - MEdge new_edge = MEdge(mesh.medge[old_edge_i]); + MEdge new_edge = src_edges[old_edge_i]; new_edge.v1 = v1; new_edge.v2 = v2; const int new_edge_i = new_edges.size(); @@ -549,14 +563,17 @@ static bool vertex_needs_dissolving(const int vertex, * edges in the input mesh which contain such a vertex are marked as 'done' to prevent duplicate * edges being created. (See T94144) */ -static void dissolve_redundant_verts(const Mesh &mesh, +static void dissolve_redundant_verts(const Span<MEdge> edges, + const Span<MPoly> polys, + const Span<MLoop> loops, const Span<Vector<int>> vertex_poly_indices, MutableSpan<VertexType> vertex_types, MutableSpan<int> old_to_new_edges_map, Vector<MEdge> &new_edges, Vector<int> &new_to_old_edges_map) { - for (const int vert_i : IndexRange(mesh.totvert)) { + const int vertex_num = vertex_types.size(); + for (const int vert_i : IndexRange(vertex_num)) { if (vertex_poly_indices[vert_i].size() != 2 || vertex_types[vert_i] != VertexType::Normal) { continue; } @@ -564,9 +581,10 @@ static void dissolve_redundant_verts(const Mesh &mesh, const int second_poly_index = vertex_poly_indices[vert_i][1]; const int new_edge_index = new_edges.size(); bool edge_created = false; - const MPoly &poly = mesh.mpoly[first_poly_index]; - for (const MLoop &loop : Span<MLoop>(&mesh.mloop[poly.loopstart], poly.totloop)) { - const MEdge &edge = mesh.medge[loop.e]; + const MPoly &poly = polys[first_poly_index]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); + for (const MLoop &loop : poly_loops) { + const MEdge &edge = edges[loop.e]; const int v1 = edge.v1; const int v2 = edge.v2; bool mark_edge = false; @@ -617,6 +635,10 @@ static void calc_dual_mesh(GeometrySet &geometry_set, const bool keep_boundaries) { const Mesh &mesh_in = *in_component.get_for_read(); + const Span<MVert> src_verts = mesh_in.vertices(); + const Span<MEdge> src_edges = mesh_in.edges(); + const Span<MPoly> src_polys = mesh_in.polygons(); + const Span<MLoop> src_loops = mesh_in.loops(); Map<AttributeIDRef, AttributeKind> attributes; geometry_set.gather_attributes_for_propagation( @@ -644,14 +666,28 @@ static void calc_dual_mesh(GeometrySet &geometry_set, bool vertex_ok = true; if (vertex_types[i] == VertexType::Normal) { Array<int> shared_edges(loop_indices.size()); - vertex_ok = sort_vertex_polys( - mesh_in, i, false, edge_types, loop_indices, shared_edges, sorted_corners); + vertex_ok = sort_vertex_polys(src_edges, + src_polys, + src_loops, + i, + false, + edge_types, + loop_indices, + shared_edges, + sorted_corners); vertex_shared_edges[i] = std::move(shared_edges); } else { Array<int> shared_edges(loop_indices.size() - 1); - vertex_ok = sort_vertex_polys( - mesh_in, i, true, edge_types, loop_indices, shared_edges, sorted_corners); + vertex_ok = sort_vertex_polys(src_edges, + src_polys, + src_loops, + i, + true, + edge_types, + loop_indices, + shared_edges, + sorted_corners); vertex_shared_edges[i] = std::move(shared_edges); } if (!vertex_ok) { @@ -666,9 +702,9 @@ static void calc_dual_mesh(GeometrySet &geometry_set, Vector<float3> vertex_positions(mesh_in.totpoly); for (const int i : IndexRange(mesh_in.totpoly)) { - const MPoly poly = mesh_in.mpoly[i]; + const MPoly &poly = src_polys[i]; BKE_mesh_calc_poly_center( - &poly, &mesh_in.mloop[poly.loopstart], mesh_in.mvert, vertex_positions[i]); + &poly, &src_loops[poly.loopstart], src_verts.data(), vertex_positions[i]); } Array<int> boundary_edge_midpoint_index; @@ -679,8 +715,8 @@ static void calc_dual_mesh(GeometrySet &geometry_set, for (const int i : IndexRange(mesh_in.totedge)) { if (edge_types[i] == EdgeType::Boundary) { float3 mid; - const MEdge &edge = mesh_in.medge[i]; - mid_v3_v3v3(mid, mesh_in.mvert[edge.v1].co, mesh_in.mvert[edge.v2].co); + const MEdge &edge = src_edges[i]; + mid_v3_v3v3(mid, src_verts[edge.v1].co, src_verts[edge.v2].co); boundary_edge_midpoint_index[i] = vertex_positions.size(); vertex_positions.append(mid); } @@ -706,7 +742,9 @@ static void calc_dual_mesh(GeometrySet &geometry_set, /* This is necessary to prevent duplicate edges from being created, but will likely not do * anything for most meshes. */ - dissolve_redundant_verts(mesh_in, + dissolve_redundant_verts(src_edges, + src_polys, + src_loops, vertex_poly_indices, vertex_types, old_to_new_edges_map, @@ -734,7 +772,7 @@ static void calc_dual_mesh(GeometrySet &geometry_set, const int old_edge_i = shared_edges[i]; if (old_to_new_edges_map[old_edge_i] == -1) { /* This edge has not been created yet. */ - MEdge new_edge = MEdge(mesh_in.medge[old_edge_i]); + MEdge new_edge = src_edges[old_edge_i]; new_edge.v1 = loop_indices[i]; new_edge.v2 = loop_indices[(i + 1) % loop_indices.size()]; new_to_old_edges_map.append(old_edge_i); @@ -776,7 +814,7 @@ static void calc_dual_mesh(GeometrySet &geometry_set, const int old_edge_i = shared_edges[i]; if (old_to_new_edges_map[old_edge_i] == -1) { /* This edge has not been created yet. */ - MEdge new_edge = MEdge(mesh_in.medge[old_edge_i]); + MEdge new_edge = src_edges[old_edge_i]; new_edge.v1 = loop_indices[i]; new_edge.v2 = loop_indices[i + 1]; new_to_old_edges_map.append(old_edge_i); @@ -795,13 +833,15 @@ static void calc_dual_mesh(GeometrySet &geometry_set, int edge2; if (loop_indices.size() >= 2) { /* The first boundary edge is at the end of the chain of polygons. */ - boundary_edge_on_poly(mesh_in.mpoly[loop_indices.last()], mesh_in, i, edge_types, edge1); - boundary_edge_on_poly(mesh_in.mpoly[loop_indices.first()], mesh_in, i, edge_types, edge2); + boundary_edge_on_poly( + src_polys[loop_indices.last()], src_edges, src_loops, i, edge_types, edge1); + boundary_edge_on_poly( + src_polys[loop_indices.first()], src_edges, src_loops, i, edge_types, edge2); } else { /* If there is only one polygon both edges are in that polygon. */ boundary_edges_on_poly( - mesh_in.mpoly[loop_indices[0]], mesh_in, i, edge_types, edge1, edge2); + src_polys[loop_indices[0]], src_edges, src_loops, i, edge_types, edge1, edge2); } const int last_face_center = loop_indices.last(); @@ -809,7 +849,7 @@ static void calc_dual_mesh(GeometrySet &geometry_set, new_to_old_face_corners_map.append(sorted_corners.last()); const int first_midpoint = loop_indices.last(); if (old_to_new_edges_map[edge1] == -1) { - add_edge(mesh_in, + add_edge(src_edges, edge1, last_face_center, first_midpoint, @@ -827,9 +867,9 @@ static void calc_dual_mesh(GeometrySet &geometry_set, new_to_old_face_corners_map.append(sorted_corners.first()); boundary_vertex_to_relevant_face_map.append( std::pair(loop_indices.last(), last_face_center)); - vertex_positions.append(mesh_in.mvert[i].co); + vertex_positions.append(src_verts[i].co); const int boundary_vertex = loop_indices.last(); - add_edge(mesh_in, + add_edge(src_edges, edge1, first_midpoint, boundary_vertex, @@ -840,7 +880,7 @@ static void calc_dual_mesh(GeometrySet &geometry_set, loop_indices.append(boundary_edge_midpoint_index[edge2]); new_to_old_face_corners_map.append(sorted_corners.first()); const int second_midpoint = loop_indices.last(); - add_edge(mesh_in, + add_edge(src_edges, edge2, boundary_vertex, second_midpoint, @@ -850,7 +890,7 @@ static void calc_dual_mesh(GeometrySet &geometry_set, if (old_to_new_edges_map[edge2] == -1) { const int first_face_center = loop_indices.first(); - add_edge(mesh_in, + add_edge(src_edges, edge2, second_midpoint, first_face_center, @@ -881,20 +921,25 @@ static void calc_dual_mesh(GeometrySet &geometry_set, bke::mesh_attributes(mesh_in), bke::mesh_attributes_for_write(*mesh_out)); + MutableSpan<MVert> dst_verts = mesh_out->vertices_for_write(); + MutableSpan<MEdge> dst_edges = mesh_out->edges_for_write(); + MutableSpan<MPoly> dst_polys = mesh_out->polygons_for_write(); + MutableSpan<MLoop> dst_loops = mesh_out->loops_for_write(); + int loop_start = 0; for (const int i : IndexRange(mesh_out->totpoly)) { - mesh_out->mpoly[i].loopstart = loop_start; - mesh_out->mpoly[i].totloop = loop_lengths[i]; + dst_polys[i].loopstart = loop_start; + dst_polys[i].totloop = loop_lengths[i]; loop_start += loop_lengths[i]; } for (const int i : IndexRange(mesh_out->totloop)) { - mesh_out->mloop[i].v = loops[i]; - mesh_out->mloop[i].e = loop_edges[i]; + dst_loops[i].v = loops[i]; + dst_loops[i].e = loop_edges[i]; } for (const int i : IndexRange(mesh_out->totvert)) { - copy_v3_v3(mesh_out->mvert[i].co, vertex_positions[i]); + copy_v3_v3(dst_verts[i].co, vertex_positions[i]); } - memcpy(mesh_out->medge, new_edges.data(), sizeof(MEdge) * new_edges.size()); + dst_edges.copy_from(new_edges); geometry_set.replace_mesh(mesh_out); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 2eb3706bac9..9af1536a194 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -486,7 +486,7 @@ static void copy_stable_id_faces(const Mesh &mesh, VArraySpan<int> src{src_attribute.varray.typed<int>()}; MutableSpan<int> dst = dst_attribute.span.typed<int>(); - Span<MPoly> polys(mesh.mpoly, mesh.totpoly); + const Span<MPoly> polys = mesh.polygons(); int loop_index = 0; for (const int i_poly : selection.index_range()) { const IndexRange range = range_for_offsets_index(poly_offsets, i_poly); @@ -522,10 +522,10 @@ static void duplicate_faces(GeometrySet &geometry_set, geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH}); const Mesh &mesh = *geometry_set.get_mesh_for_read(); - Span<MVert> verts(mesh.mvert, mesh.totvert); - Span<MEdge> edges(mesh.medge, mesh.totedge); - Span<MPoly> polys(mesh.mpoly, mesh.totpoly); - Span<MLoop> loops(mesh.mloop, mesh.totloop); + const Span<MVert> verts = mesh.vertices(); + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator(field_context, polys.size()); @@ -547,10 +547,10 @@ static void duplicate_faces(GeometrySet &geometry_set, offsets[selection.size()] = total_polys; Mesh *new_mesh = BKE_mesh_new_nomain(total_loops, total_loops, 0, total_loops, total_polys); - MutableSpan<MVert> new_verts(new_mesh->mvert, new_mesh->totvert); - MutableSpan<MEdge> new_edges(new_mesh->medge, new_mesh->totedge); - MutableSpan<MLoop> new_loops(new_mesh->mloop, new_mesh->totloop); - MutableSpan<MPoly> new_poly(new_mesh->mpoly, new_mesh->totpoly); + MutableSpan<MVert> new_verts = new_mesh->vertices_for_write(); + MutableSpan<MEdge> new_edges = new_mesh->edges_for_write(); + MutableSpan<MPoly> new_polys = new_mesh->polygons_for_write(); + MutableSpan<MLoop> new_loops = new_mesh->loops_for_write(); Array<int> vert_mapping(new_verts.size()); Array<int> edge_mapping(new_edges.size()); @@ -563,8 +563,8 @@ static void duplicate_faces(GeometrySet &geometry_set, const MPoly &source = polys[selection[i_selection]]; for ([[maybe_unused]] const int i_duplicate : IndexRange(poly_range.size())) { - new_poly[poly_index] = source; - new_poly[poly_index].loopstart = loop_index; + new_polys[poly_index] = source; + new_polys[poly_index].loopstart = loop_index; for (const int i_loops : IndexRange(source.totloop)) { const MLoop ¤t_loop = loops[source.loopstart + i_loops]; loop_mapping[loop_index] = source.loopstart + i_loops; @@ -577,7 +577,7 @@ static void duplicate_faces(GeometrySet &geometry_set, new_edges[loop_index].v2 = loop_index + 1; } else { - new_edges[loop_index].v2 = new_poly[poly_index].loopstart; + new_edges[loop_index].v2 = new_polys[poly_index].loopstart; } new_loops[loop_index].v = loop_index; new_loops[loop_index].e = loop_index; @@ -689,7 +689,7 @@ static void copy_stable_id_edges(const Mesh &mesh, return; } - Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MEdge> edges = mesh.edges(); VArraySpan<int> src{src_attribute.varray.typed<int>()}; MutableSpan<int> dst = dst_attribute.span.typed<int>(); @@ -723,8 +723,7 @@ static void duplicate_edges(GeometrySet &geometry_set, return; }; const Mesh &mesh = *geometry_set.get_mesh_for_read(); - Span<MVert> verts(mesh.mvert, mesh.totvert); - Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MEdge> edges = mesh.edges(); bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator evaluator{field_context, edges.size()}; @@ -737,8 +736,7 @@ static void duplicate_edges(GeometrySet &geometry_set, Array<int> edge_offsets = accumulate_counts_to_offsets(selection, counts); Mesh *new_mesh = BKE_mesh_new_nomain(edge_offsets.last() * 2, edge_offsets.last(), 0, 0, 0); - MutableSpan<MVert> new_verts(new_mesh->mvert, new_mesh->totvert); - MutableSpan<MEdge> new_edges(new_mesh->medge, new_mesh->totedge); + MutableSpan<MEdge> new_edges = new_mesh->edges_for_write(); Array<int> vert_orig_indices(edge_offsets.last() * 2); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { @@ -906,7 +904,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, const IndexAttributes &attribute_outputs) { const Mesh &mesh = *geometry_set.get_mesh_for_read(); - Span<MVert> src_verts(mesh.mvert, mesh.totvert); + const Span<MVert> src_verts = mesh.vertices(); bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_POINT}; FieldEvaluator evaluator{field_context, src_verts.size()}; @@ -919,7 +917,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, Array<int> offsets = accumulate_counts_to_offsets(selection, counts); Mesh *new_mesh = BKE_mesh_new_nomain(offsets.last(), 0, 0, 0, 0); - MutableSpan<MVert> dst_verts(new_mesh->mvert, new_mesh->totvert); + MutableSpan<MVert> dst_verts = new_mesh->vertices_for_write(); threaded_slice_fill(offsets.as_span(), selection, src_verts, dst_verts); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc index 30b5b7fbd22..ba09acf0bf0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc @@ -3,7 +3,6 @@ #include "BKE_curves.hh" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "GEO_mesh_to_curve.hh" @@ -23,7 +22,6 @@ static Curves *edge_paths_to_curves_convert(const Mesh &mesh, const IndexMask start_verts_mask, const Span<int> next_indices) { - const Span<MVert> mvert{mesh.mvert, mesh.totvert}; Vector<int> vert_indices; Vector<int> curve_offsets; Array<bool> visited(mesh.totvert, false); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc index 5e9826837a0..ac66e3906a7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc @@ -7,9 +7,6 @@ #include "BLI_set.hh" #include "BLI_task.hh" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - #include "node_geometry_util.hh" #include <set> @@ -28,6 +25,8 @@ static void edge_paths_to_selection(const Mesh &src_mesh, const Span<int> next_indices, MutableSpan<bool> r_selection) { + const Span<MEdge> edges = src_mesh.edges(); + Array<bool> selection(src_mesh.totvert, false); for (const int start_vert : start_selection) { @@ -45,8 +44,8 @@ static void edge_paths_to_selection(const Mesh &src_mesh, } } - for (const int i : IndexRange(src_mesh.totedge)) { - const MEdge &edge = src_mesh.medge[i]; + for (const int i : edges.index_range()) { + const MEdge &edge = edges[i]; if ((selection[edge.v1] && selection[edge.v2]) && (edge.v1 == next_indices[edge.v2] || edge.v2 == next_indices[edge.v1])) { r_selection[i] = true; diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 237e8ffaa7c..d81b335ebb3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -83,31 +83,6 @@ static void save_selection_as_attribute(Mesh &mesh, attribute.finish(); } -static MutableSpan<MVert> mesh_verts(Mesh &mesh) -{ - return {mesh.mvert, mesh.totvert}; -} -static MutableSpan<MEdge> mesh_edges(Mesh &mesh) -{ - return {mesh.medge, mesh.totedge}; -} -static Span<MPoly> mesh_polys(const Mesh &mesh) -{ - return {mesh.mpoly, mesh.totpoly}; -} -static MutableSpan<MPoly> mesh_polys(Mesh &mesh) -{ - return {mesh.mpoly, mesh.totpoly}; -} -static Span<MLoop> mesh_loops(const Mesh &mesh) -{ - return {mesh.mloop, mesh.totloop}; -} -static MutableSpan<MLoop> mesh_loops(Mesh &mesh) -{ - return {mesh.mloop, mesh.totloop}; -} - /** * \note Some areas in this file rely on the new sections of attributes from #CustomData_realloc * to be zeroed. @@ -142,7 +117,6 @@ static void expand_mesh(Mesh &mesh, mesh.totloop += loop_expand; CustomData_realloc(&mesh.ldata, mesh.totloop); } - BKE_mesh_update_customdata_pointers(&mesh, false); } static CustomData &get_customdata(Mesh &mesh, const eAttrDomain domain) @@ -264,15 +238,15 @@ static void extrude_mesh_vertices(Mesh &mesh, const VArray<float3> offsets = evaluator.get_evaluated<float3>(0); /* This allows parallelizing attribute mixing for new edges. */ - Array<Vector<int>> vert_to_edge_map = create_vert_to_edge_map(orig_vert_size, mesh_edges(mesh)); + Array<Vector<int>> vert_to_edge_map = create_vert_to_edge_map(orig_vert_size, mesh.edges()); expand_mesh(mesh, selection.size(), selection.size(), 0, 0); const IndexRange new_vert_range{orig_vert_size, selection.size()}; const IndexRange new_edge_range{orig_edge_size, selection.size()}; - MutableSpan<MVert> new_verts = mesh_verts(mesh).slice(new_vert_range); - MutableSpan<MEdge> new_edges = mesh_edges(mesh).slice(new_edge_range); + MutableSpan<MVert> new_verts = mesh.vertices_for_write().slice(new_vert_range); + MutableSpan<MEdge> new_edges = mesh.edges_for_write().slice(new_edge_range); for (const int i_selection : selection.index_range()) { new_edges[i_selection] = new_loose_edge(selection[i_selection], new_vert_range[i_selection]); @@ -337,8 +311,8 @@ static void extrude_mesh_vertices(Mesh &mesh, static Array<Vector<int, 2>> mesh_calculate_polys_of_edge(const Mesh &mesh) { - Span<MPoly> polys = mesh_polys(mesh); - Span<MLoop> loops = mesh_loops(mesh); + Span<MPoly> polys = mesh.polygons(); + Span<MLoop> loops = mesh.loops(); Array<Vector<int, 2>> polys_of_edge(mesh.totedge); for (const int i_poly : polys.index_range()) { @@ -396,11 +370,12 @@ template<typename T> static VectorSet<int> vert_indices_from_edges(const Mesh &mesh, const Span<T> edge_indices) { static_assert(is_same_any_v<T, int, int64_t>); + const Span<MEdge> edges = mesh.edges(); VectorSet<int> vert_indices; vert_indices.reserve(edge_indices.size()); for (const T i_edge : edge_indices) { - const MEdge &edge = mesh.medge[i_edge]; + const MEdge &edge = edges[i_edge]; vert_indices.add(edge.v1); vert_indices.add(edge.v2); } @@ -413,8 +388,8 @@ static void extrude_mesh_edges(Mesh &mesh, const AttributeOutputs &attribute_outputs) { const int orig_vert_size = mesh.totvert; - Span<MEdge> orig_edges = mesh_edges(mesh); - Span<MPoly> orig_polys = mesh_polys(mesh); + Span<MEdge> orig_edges = mesh.edges(); + Span<MPoly> orig_polys = mesh.polygons(); const int orig_loop_size = mesh.totloop; bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; @@ -463,12 +438,12 @@ static void extrude_mesh_edges(Mesh &mesh, new_poly_range.size(), new_loop_range.size()); - MutableSpan<MVert> new_verts = mesh_verts(mesh).slice(new_vert_range); - MutableSpan<MEdge> connect_edges = mesh_edges(mesh).slice(connect_edge_range); - MutableSpan<MEdge> duplicate_edges = mesh_edges(mesh).slice(duplicate_edge_range); - MutableSpan<MPoly> polys = mesh_polys(mesh); + MutableSpan<MEdge> edges = mesh.edges_for_write(); + MutableSpan<MEdge> connect_edges = edges.slice(connect_edge_range); + MutableSpan<MEdge> duplicate_edges = edges.slice(duplicate_edge_range); + MutableSpan<MPoly> polys = mesh.polygons_for_write(); MutableSpan<MPoly> new_polys = polys.slice(new_poly_range); - MutableSpan<MLoop> loops = mesh_loops(mesh); + MutableSpan<MLoop> loops = mesh.loops_for_write(); MutableSpan<MLoop> new_loops = loops.slice(new_loop_range); for (const int i : connect_edges.index_range()) { @@ -476,7 +451,7 @@ static void extrude_mesh_edges(Mesh &mesh, } for (const int i : duplicate_edges.index_range()) { - const MEdge &orig_edge = mesh.medge[edge_selection[i]]; + const MEdge &orig_edge = edges[edge_selection[i]]; const int i_new_vert_1 = new_vert_indices.index_of(orig_edge.v1); const int i_new_vert_2 = new_vert_indices.index_of(orig_edge.v2); duplicate_edges[i] = new_edge(new_vert_range[i_new_vert_1], new_vert_range[i_new_vert_2]); @@ -631,6 +606,7 @@ static void extrude_mesh_edges(Mesh &mesh, return true; }); + MutableSpan<MVert> new_verts = mesh.vertices_for_write().slice(new_vert_range); if (edge_offsets.is_single()) { const float3 offset = edge_offsets.get_internal_single(); threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) { @@ -676,9 +652,9 @@ static void extrude_mesh_face_regions(Mesh &mesh, const AttributeOutputs &attribute_outputs) { const int orig_vert_size = mesh.totvert; - Span<MEdge> orig_edges = mesh_edges(mesh); - Span<MPoly> orig_polys = mesh_polys(mesh); - Span<MLoop> orig_loops = mesh_loops(mesh); + Span<MEdge> orig_edges = mesh.edges(); + Span<MPoly> orig_polys = mesh.polygons(); + Span<MLoop> orig_loops = mesh.loops(); bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator poly_evaluator{poly_context, mesh.totpoly}; @@ -781,7 +757,7 @@ static void extrude_mesh_face_regions(Mesh &mesh, /* The vertices attached to duplicate inner edges also have to be duplicated. */ for (const int i_edge : new_inner_edge_indices) { - const MEdge &edge = mesh.medge[i_edge]; + const MEdge &edge = orig_edges[i_edge]; new_vert_indices.add(edge.v1); new_vert_indices.add(edge.v2); } @@ -805,13 +781,13 @@ static void extrude_mesh_face_regions(Mesh &mesh, side_poly_range.size(), side_loop_range.size()); - MutableSpan<MEdge> edges = mesh_edges(mesh); + MutableSpan<MEdge> edges = mesh.edges_for_write(); MutableSpan<MEdge> connect_edges = edges.slice(connect_edge_range); MutableSpan<MEdge> boundary_edges = edges.slice(boundary_edge_range); MutableSpan<MEdge> new_inner_edges = edges.slice(new_inner_edge_range); - MutableSpan<MPoly> polys = mesh_polys(mesh); + MutableSpan<MPoly> polys = mesh.polygons_for_write(); MutableSpan<MPoly> new_polys = polys.slice(side_poly_range); - MutableSpan<MLoop> loops = mesh_loops(mesh); + MutableSpan<MLoop> loops = mesh.loops_for_write(); MutableSpan<MLoop> new_loops = loops.slice(side_loop_range); /* Initialize the edges that form the sides of the extrusion. */ @@ -1000,13 +976,14 @@ static void extrude_mesh_face_regions(Mesh &mesh, /* Translate vertices based on the offset. If the vertex is used by a selected edge, it will * have been duplicated and only the new vertex should use the offset. Otherwise the vertex might * still need an offset, but it was reused on the inside of a region of extruded faces. */ + MutableSpan<MVert> verts = mesh.vertices_for_write(); if (poly_offsets.is_single()) { const float3 offset = poly_offsets.get_internal_single(); threading::parallel_for( IndexRange(all_selected_verts.size()), 1024, [&](const IndexRange range) { for (const int i_orig : all_selected_verts.as_span().slice(range)) { const int i_new = new_vert_indices.index_of_try(i_orig); - MVert &vert = mesh_verts(mesh)[(i_new == -1) ? i_orig : new_vert_range[i_new]]; + MVert &vert = verts[(i_new == -1) ? i_orig : new_vert_range[i_new]]; add_v3_v3(vert.co, offset); } }); @@ -1017,7 +994,7 @@ static void extrude_mesh_face_regions(Mesh &mesh, for (const int i_orig : all_selected_verts.as_span().slice(range)) { const int i_new = new_vert_indices.index_of_try(i_orig); const float3 offset = vert_offsets[i_orig]; - MVert &vert = mesh_verts(mesh)[(i_new == -1) ? i_orig : new_vert_range[i_new]]; + MVert &vert = verts[(i_new == -1) ? i_orig : new_vert_range[i_new]]; add_v3_v3(vert.co, offset); } }); @@ -1061,8 +1038,8 @@ static void extrude_individual_mesh_faces(Mesh &mesh, { const int orig_vert_size = mesh.totvert; const int orig_edge_size = mesh.totedge; - Span<MPoly> orig_polys = mesh_polys(mesh); - Span<MLoop> orig_loops = mesh_loops(mesh); + Span<MPoly> orig_polys = mesh.polygons(); + Span<MLoop> orig_loops = mesh.loops(); /* Use a mesh for the result of the evaluation because the mesh is reallocated before * the vertices are moved, and the evaluated result might reference an attribute. */ @@ -1101,13 +1078,13 @@ static void extrude_individual_mesh_faces(Mesh &mesh, side_poly_range.size(), side_loop_range.size()); - MutableSpan<MVert> new_verts = mesh_verts(mesh).slice(new_vert_range); - MutableSpan<MEdge> edges{mesh.medge, mesh.totedge}; + MutableSpan<MVert> new_verts = mesh.vertices_for_write().slice(new_vert_range); + MutableSpan<MEdge> edges = mesh.edges_for_write(); MutableSpan<MEdge> connect_edges = edges.slice(connect_edge_range); MutableSpan<MEdge> duplicate_edges = edges.slice(duplicate_edge_range); - MutableSpan<MPoly> polys{mesh.mpoly, mesh.totpoly}; + MutableSpan<MPoly> polys = mesh.polygons_for_write(); MutableSpan<MPoly> new_polys = polys.slice(side_poly_range); - MutableSpan<MLoop> loops{mesh.mloop, mesh.totloop}; + MutableSpan<MLoop> loops = mesh.loops_for_write(); /* For every selected polygon, build the faces that form the sides of the extrusion. Filling some * of this data like the new edges or polygons could be easily split into separate loops, which diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc index a752abc2522..2d642ad13d5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc @@ -30,9 +30,8 @@ static void mesh_flip_faces(Mesh &mesh, const Field<bool> &selection_field) evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_as_mask(0); - mesh.mloop = (MLoop *)CustomData_duplicate_referenced_layer(&mesh.ldata, CD_MLOOP, mesh.totloop); - const Span<MPoly> polys{mesh.mpoly, mesh.totpoly}; - MutableSpan<MLoop> loops{mesh.mloop, mesh.totloop}; + const Span<MPoly> polys = mesh.polygons(); + MutableSpan<MLoop> loops = mesh.loops_for_write(); for (const int i : selection.index_range()) { const MPoly &poly = polys[selection[i]]; diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc index 3e9fcb10c8e..4b5ea1c8742 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc @@ -64,21 +64,20 @@ class AngleFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - Span<MVert> vertices{mesh.mvert, mesh.totvert}; - Span<MPoly> polys{mesh.mpoly, mesh.totpoly}; - Span<MLoop> loops{mesh.mloop, mesh.totloop}; + const Span<MVert> verts = mesh.vertices(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); Array<EdgeMapEntry> edge_map = create_edge_map(polys, loops, mesh.totedge); - auto angle_fn = - [edge_map = std::move(edge_map), vertices, polys, loops](const int i) -> float { + auto angle_fn = [edge_map = std::move(edge_map), verts, polys, loops](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } const MPoly &mpoly_1 = polys[edge_map[i].face_index_1]; const MPoly &mpoly_2 = polys[edge_map[i].face_index_2]; float3 normal_1, normal_2; - BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], vertices.data(), normal_1); - BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], vertices.data(), normal_2); + BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], verts.data(), normal_1); + BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], verts.data(), normal_2); return angle_normalized_v3v3(normal_1, normal_2); }; @@ -110,14 +109,14 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - const Span<MVert> vertices(mesh.mvert, mesh.totvert); - const Span<MEdge> edges(mesh.medge, mesh.totedge); - const Span<MPoly> polys(mesh.mpoly, mesh.totpoly); - const Span<MLoop> loops(mesh.mloop, mesh.totloop); + const Span<MVert> verts = mesh.vertices(); + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); Array<EdgeMapEntry> edge_map = create_edge_map(polys, loops, mesh.totedge); auto angle_fn = - [edge_map = std::move(edge_map), vertices, edges, polys, loops](const int i) -> float { + [edge_map = std::move(edge_map), verts, edges, polys, loops](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } @@ -126,21 +125,18 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { /* Find the normals of the 2 polys. */ float3 poly_1_normal, poly_2_normal; - BKE_mesh_calc_poly_normal( - &mpoly_1, &loops[mpoly_1.loopstart], vertices.data(), poly_1_normal); - BKE_mesh_calc_poly_normal( - &mpoly_2, &loops[mpoly_2.loopstart], vertices.data(), poly_2_normal); + BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], verts.data(), poly_1_normal); + BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], verts.data(), poly_2_normal); /* Find the centerpoint of the axis edge */ - const float3 edge_centerpoint = (float3(vertices[edges[i].v1].co) + - float3(vertices[edges[i].v2].co)) * + const float3 edge_centerpoint = (float3(verts[edges[i].v1].co) + + float3(verts[edges[i].v2].co)) * 0.5f; /* Get the centerpoint of poly 2 and subtract the edge centerpoint to get a tangent * normal for poly 2. */ float3 poly_center_2; - BKE_mesh_calc_poly_center( - &mpoly_2, &loops[mpoly_2.loopstart], vertices.data(), poly_center_2); + BKE_mesh_calc_poly_center(&mpoly_2, &loops[mpoly_2.loopstart], verts.data(), poly_center_2); const float3 poly_2_tangent = math::normalize(poly_center_2 - edge_centerpoint); const float concavity = math::dot(poly_1_normal, poly_2_tangent); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc index b532b55697b..716cbf589d9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_neighbors.cc @@ -28,9 +28,10 @@ class EdgeNeighborCountFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask UNUSED(mask)) const final { + const Span<MLoop> loops = mesh.loops(); Array<int> face_count(mesh.totedge, 0); - for (const int i : IndexRange(mesh.totloop)) { - face_count[mesh.mloop[i].e]++; + for (const MLoop &loop : loops) { + face_count[loop.e]++; } return bke::mesh_attributes(mesh).adapt_domain<int>( diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc index 426e7636d53..7fd2df7c552 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc @@ -31,7 +31,7 @@ static VArray<int> construct_edge_vertices_gvarray(const Mesh &mesh, const VertexNumber vertex, const eAttrDomain domain) { - const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MEdge> edges = mesh.edges(); if (domain == ATTR_DOMAIN_EDGE) { if (vertex == VERTEX_ONE) { return VArray<int>::ForFunc(edges.size(), @@ -79,19 +79,19 @@ static VArray<float3> construct_edge_positions_gvarray(const Mesh &mesh, const VertexNumber vertex, const eAttrDomain domain) { - const Span<MVert> vertices(mesh.mvert, mesh.totvert); - const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MVert> verts = mesh.vertices(); + const Span<MEdge> edges = mesh.edges(); if (vertex == VERTEX_ONE) { return bke::mesh_attributes(mesh).adapt_domain<float3>( - VArray<float3>::ForFunc( - edges.size(), [vertices, edges](const int i) { return vertices[edges[i].v1].co; }), + VArray<float3>::ForFunc(edges.size(), + [verts, edges](const int i) { return verts[edges[i].v1].co; }), ATTR_DOMAIN_EDGE, domain); } return bke::mesh_attributes(mesh).adapt_domain<float3>( VArray<float3>::ForFunc(edges.size(), - [vertices, edges](const int i) { return vertices[edges[i].v2].co; }), + [verts, edges](const int i) { return verts[edges[i].v2].co; }), ATTR_DOMAIN_EDGE, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc index 67b4be0d95d..7dfeaa8e8d9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc @@ -18,17 +18,17 @@ static void node_declare(NodeDeclarationBuilder &b) static VArray<float> construct_face_area_varray(const Mesh &mesh, const eAttrDomain domain) { - const Span<MVert> vertices(mesh.mvert, mesh.totvert); - const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); - const Span<MLoop> loops(mesh.mloop, mesh.totloop); + const Span<MVert> verts = mesh.vertices(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); - auto area_fn = [vertices, polygons, loops](const int i) -> float { - const MPoly &poly = polygons[i]; - return BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], vertices.data()); + auto area_fn = [verts, polys, loops](const int i) -> float { + const MPoly &poly = polys[i]; + return BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data()); }; return bke::mesh_attributes(mesh).adapt_domain<float>( - VArray<float>::ForFunc(polygons.size(), area_fn), ATTR_DOMAIN_FACE, domain); + VArray<float>::ForFunc(polys.size(), area_fn), ATTR_DOMAIN_FACE, domain); } class FaceAreaFieldInput final : public bke::MeshFieldInput { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index 57ab1223d44..b316639fd0a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -37,31 +37,30 @@ class PlanarFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask /*mask*/) const final { - const Span<MVert> vertices(mesh.mvert, mesh.totvert); - const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); - const Span<MLoop> loops(mesh.mloop, mesh.totloop); + const Span<MVert> verts = mesh.vertices(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + const Span<float3> poly_normals{(float3 *)BKE_mesh_poly_normals_ensure(&mesh), mesh.totpoly}; bke::MeshFieldContext context{mesh, ATTR_DOMAIN_FACE}; - fn::FieldEvaluator evaluator{context, polygons.size()}; + fn::FieldEvaluator evaluator{context, polys.size()}; evaluator.add(threshold_); evaluator.evaluate(); const VArray<float> thresholds = evaluator.get_evaluated<float>(0); - Span<float3> poly_normals{(float3 *)BKE_mesh_poly_normals_ensure(&mesh), polygons.size()}; - - auto planar_fn = [vertices, polygons, loops, thresholds, poly_normals](const int i) -> bool { - const MPoly &poly = polygons[i]; + auto planar_fn = [verts, polys, loops, thresholds, poly_normals](const int i) -> bool { + const MPoly &poly = polys[i]; if (poly.totloop <= 3) { return true; } const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); - float3 reference_normal = poly_normals[i]; + const float3 &reference_normal = poly_normals[i]; float min = FLT_MAX; float max = -FLT_MAX; for (const int i_loop : poly_loops.index_range()) { - const float3 vert = vertices[poly_loops[i_loop].v].co; + const float3 vert = verts[poly_loops[i_loop].v].co; float dot = math::dot(reference_normal, vert); if (dot > max) { max = dot; @@ -74,7 +73,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput { }; return bke::mesh_attributes(mesh).adapt_domain<bool>( - VArray<bool>::ForFunc(polygons.size(), planar_fn), ATTR_DOMAIN_FACE, domain); + VArray<bool>::ForFunc(polys.size(), planar_fn), ATTR_DOMAIN_FACE, domain); } uint64_t hash() const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc index c4cb81c5fe5..59d30b997a6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_neighbors.cc @@ -21,20 +21,19 @@ static void node_declare(NodeDeclarationBuilder &b) static VArray<int> construct_neighbor_count_varray(const Mesh &mesh, const eAttrDomain domain) { - const Span<MEdge> edges(mesh.medge, mesh.totedge); - const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); - const Span<MLoop> loops(mesh.mloop, mesh.totloop); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); - Array<int> edge_count(edges.size(), 0); - for (const int i : loops.index_range()) { - edge_count[loops[i].e]++; + Array<int> edge_count(mesh.totedge, 0); + for (const MLoop &loop : loops) { + edge_count[loop.e]++; } - Array<int> poly_count(polygons.size(), 0); - for (const int poly_i : polygons.index_range()) { - const MPoly &poly = polygons[poly_i]; + Array<int> poly_count(polys.size(), 0); + for (const int poly_index : polys.index_range()) { + const MPoly &poly = polys[poly_index]; for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - poly_count[poly_i] += edge_count[loop.e] - 1; + poly_count[poly_index] += edge_count[loop.e] - 1; } } @@ -71,10 +70,10 @@ class FaceNeighborCountFieldInput final : public bke::MeshFieldInput { static VArray<int> construct_vertex_count_varray(const Mesh &mesh, const eAttrDomain domain) { - const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); + const Span<MPoly> polys = mesh.polygons(); return bke::mesh_attributes(mesh).adapt_domain<int>( - VArray<int>::ForFunc(polygons.size(), - [polygons](const int i) -> float { return polygons[i].totloop; }), + VArray<int>::ForFunc(polys.size(), + [polys](const int i) -> float { return polys[i].totloop; }), ATTR_DOMAIN_FACE, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc index 5752535d149..53cb3d0a19f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_island.cc @@ -33,7 +33,7 @@ class IslandFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MEdge> edges = mesh.edges(); DisjointSet islands(mesh.totvert); for (const int i : edges.index_range()) { @@ -74,7 +74,7 @@ class IslandCountFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask UNUSED(mask)) const final { - const Span<MEdge> edges(mesh.medge, mesh.totedge); + const Span<MEdge> edges = mesh.edges(); DisjointSet islands(mesh.totvert); for (const int i : edges.index_range()) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc index 244d454b8d1..ab44a6c8515 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_vertex_neighbors.cc @@ -22,8 +22,7 @@ static void node_declare(NodeDeclarationBuilder &b) static VArray<int> construct_vertex_count_gvarray(const Mesh &mesh, const eAttrDomain domain) { - const Span<MEdge> edges(mesh.medge, mesh.totedge); - + const Span<MEdge> edges = mesh.edges(); if (domain == ATTR_DOMAIN_POINT) { Array<int> counts(mesh.totvert, 0); for (const int i : edges.index_range()) { @@ -63,8 +62,7 @@ class VertexCountFieldInput final : public bke::MeshFieldInput { static VArray<int> construct_face_count_gvarray(const Mesh &mesh, const eAttrDomain domain) { - const Span<MLoop> loops(mesh.mloop, mesh.totloop); - + const Span<MLoop> loops = mesh.loops(); if (domain == ATTR_DOMAIN_POINT) { Array<int> vertices(mesh.totvert, 0); for (const int i : loops.index_range()) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc index 8549bdfa87d..e13edc8f979 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc @@ -2,14 +2,12 @@ #include <queue> -#include "BKE_curves.hh" - #include "BLI_map.hh" #include "BLI_math_vec_types.hh" #include "BLI_set.hh" +#include "BLI_task.hh" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" +#include "BKE_mesh.h" #include "node_geometry_util.hh" @@ -30,7 +28,7 @@ struct EdgeVertMap { EdgeVertMap(const Mesh &mesh) { - const Span<MEdge> edges{mesh.medge, mesh.totedge}; + const Span<MEdge> edges = mesh.edges(); edges_by_vertex_map.reinitialize(mesh.totvert); for (const int edge_i : edges.index_range()) { const MEdge &edge = edges[edge_i]; @@ -47,8 +45,7 @@ static void shortest_paths(const Mesh &mesh, MutableSpan<int> r_next_index, MutableSpan<float> r_cost) { - const Span<MVert> verts{mesh.mvert, mesh.totvert}; - const Span<MEdge> edges{mesh.medge, mesh.totedge}; + const Span<MEdge> edges = mesh.edges(); Array<bool> visited(mesh.totvert, false); std::priority_queue<VertPriority, std::vector<VertPriority>, std::greater<VertPriority>> queue; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index 9e85547315c..ba3871adc76 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -109,10 +109,10 @@ static Mesh *create_circle_mesh(const float radius, circle_corner_total(fill_type, verts_num), circle_face_total(fill_type, verts_num)); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); /* Assign vertex coordinates. */ const float angle_delta = 2.0f * (M_PI / static_cast<float>(verts_num)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index cb79ef93de9..98ae1ef1275 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -657,7 +657,7 @@ static Mesh *create_vertex_mesh() { /* Returns a mesh with a single vertex at the origin. */ Mesh *mesh = BKE_mesh_new_nomain(1, 0, 0, 0, 0); - copy_v3_fl3(mesh->mvert[0].co, 0.0f, 0.0f, 0.0f); + copy_v3_fl3(mesh->vertices_for_write().first().co, 0.0f, 0.0f, 0.0f); return mesh; } @@ -689,10 +689,10 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); calculate_cone_vertices(verts, config); calculate_cone_edges(edges, config); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index 9baf0b3171e..656c5988bef 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -49,10 +49,10 @@ Mesh *create_grid_mesh(const int verts_x, 0, edges_x * edges_y * 4, edges_x * edges_y); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); { const float dx = edges_x == 0 ? 0.0f : size_x / edges_x; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc index a5edc6c4b3f..130fb8ae589 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc @@ -179,15 +179,15 @@ Mesh *create_line_mesh(const float3 start, const float3 delta, const int count) Mesh *mesh = BKE_mesh_new_nomain(count, count - 1, 0, 0, 0); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; + MutableSpan<MVert> vertices = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); threading::parallel_invoke( 1024 < count, [&]() { - threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { + threading::parallel_for(vertices.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - copy_v3_v3(verts[i].co, start + delta * i); + copy_v3_v3(vertices[i].co, start + delta * i); } }); }, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index 85facf1e758..48a95bfcb49 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -301,10 +301,10 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const sphere_corner_total(segments, rings), sphere_face_total(segments, rings)); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MEdge> edges = mesh->edges_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); threading::parallel_invoke( 1024 < segments * rings, diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc index dbcc5d15fd3..fc467a9424d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc @@ -147,14 +147,22 @@ static float4x4 create_single_axis_transform(const float3 ¢er, return transform; } -using GetVertexIndicesFn = - FunctionRef<void(const Mesh &mesh, int element_index, VectorSet<int> &r_vertex_indices)>; +using GetVertexIndicesFn = FunctionRef<void(Span<MEdge> edges, + Span<MPoly> polys, + Span<MLoop> loops, + int element_index, + VectorSet<int> &r_vertex_indices)>; static void scale_vertex_islands_uniformly(Mesh &mesh, const Span<ElementIsland> islands, const UniformScaleParams ¶ms, const GetVertexIndicesFn get_vertex_indices) { + MutableSpan<MVert> verts = mesh.vertices_for_write(); + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { for (const int island_index : range) { const ElementIsland &island = islands[island_index]; @@ -164,7 +172,7 @@ static void scale_vertex_islands_uniformly(Mesh &mesh, VectorSet<int> vertex_indices; for (const int poly_index : island.element_indices) { - get_vertex_indices(mesh, poly_index, vertex_indices); + get_vertex_indices(edges, polys, loops, poly_index, vertex_indices); center += params.centers[poly_index]; scale += params.scales[poly_index]; } @@ -175,7 +183,7 @@ static void scale_vertex_islands_uniformly(Mesh &mesh, center *= f; for (const int vert_index : vertex_indices) { - MVert &vert = mesh.mvert[vert_index]; + MVert &vert = verts[vert_index]; const float3 old_position = vert.co; const float3 new_position = transform_with_uniform_scale(old_position, center, scale); copy_v3_v3(vert.co, new_position); @@ -191,6 +199,11 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, const AxisScaleParams ¶ms, const GetVertexIndicesFn get_vertex_indices) { + MutableSpan<MVert> verts = mesh.vertices_for_write(); + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + threading::parallel_for(islands.index_range(), 256, [&](const IndexRange range) { for (const int island_index : range) { const ElementIsland &island = islands[island_index]; @@ -201,7 +214,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, VectorSet<int> vertex_indices; for (const int poly_index : island.element_indices) { - get_vertex_indices(mesh, poly_index, vertex_indices); + get_vertex_indices(edges, polys, loops, poly_index, vertex_indices); center += params.centers[poly_index]; scale += params.scales[poly_index]; axis += params.axis_vectors[poly_index]; @@ -219,7 +232,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, const float4x4 transform = create_single_axis_transform(center, axis, scale); for (const int vert_index : vertex_indices) { - MVert &vert = mesh.mvert[vert_index]; + MVert &vert = verts[vert_index]; const float3 old_position = vert.co; const float3 new_position = transform * old_position; copy_v3_v3(vert.co, new_position); @@ -232,11 +245,14 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, static Vector<ElementIsland> prepare_face_islands(const Mesh &mesh, const IndexMask face_selection) { + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + /* Use the disjoint set data structure to determine which vertices have to be scaled together. */ DisjointSet disjoint_set(mesh.totvert); for (const int poly_index : face_selection) { - const MPoly &poly = mesh.mpoly[poly_index]; - const Span<MLoop> poly_loops{mesh.mloop + poly.loopstart, poly.totloop}; + const MPoly &poly = polys[poly_index]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); for (const int loop_index : IndexRange(poly.totloop - 1)) { const int v1 = poly_loops[loop_index].v; const int v2 = poly_loops[loop_index + 1].v; @@ -252,8 +268,8 @@ static Vector<ElementIsland> prepare_face_islands(const Mesh &mesh, const IndexM /* Gather all of the face indices in each island into separate vectors. */ for (const int poly_index : face_selection) { - const MPoly &poly = mesh.mpoly[poly_index]; - const Span<MLoop> poly_loops{mesh.mloop + poly.loopstart, poly.totloop}; + const MPoly &poly = polys[poly_index]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); const int island_id = disjoint_set.find_root(poly_loops[0].v); const int island_index = island_ids.index_of_or_add(island_id); if (island_index == islands.size()) { @@ -266,10 +282,14 @@ static Vector<ElementIsland> prepare_face_islands(const Mesh &mesh, const IndexM return islands; } -static void get_face_vertices(const Mesh &mesh, int face_index, VectorSet<int> &r_vertex_indices) +static void get_face_vertices(const Span<MEdge> /*edges*/, + const Span<MPoly> polys, + const Span<MLoop> loops, + int face_index, + VectorSet<int> &r_vertex_indices) { - const MPoly &poly = mesh.mpoly[face_index]; - const Span<MLoop> poly_loops{mesh.mloop + poly.loopstart, poly.totloop}; + const MPoly &poly = polys[face_index]; + const Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop); for (const MLoop &loop : poly_loops) { r_vertex_indices.add(loop.v); } @@ -290,9 +310,6 @@ static AxisScaleParams evaluate_axis_scale_fields(FieldEvaluator &evaluator, static void scale_faces_on_axis(Mesh &mesh, const AxisScaleFields &fields) { - mesh.mvert = static_cast<MVert *>( - CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator{field_context, mesh.totpoly}; AxisScaleParams params = evaluate_axis_scale_fields(evaluator, fields); @@ -315,9 +332,6 @@ static UniformScaleParams evaluate_uniform_scale_fields(FieldEvaluator &evaluato static void scale_faces_uniformly(Mesh &mesh, const UniformScaleFields &fields) { - mesh.mvert = static_cast<MVert *>( - CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator evaluator{field_context, mesh.totpoly}; UniformScaleParams params = evaluate_uniform_scale_fields(evaluator, fields); @@ -328,10 +342,12 @@ static void scale_faces_uniformly(Mesh &mesh, const UniformScaleFields &fields) static Vector<ElementIsland> prepare_edge_islands(const Mesh &mesh, const IndexMask edge_selection) { + const Span<MEdge> edges = mesh.edges(); + /* Use the disjoint set data structure to determine which vertices have to be scaled together. */ DisjointSet disjoint_set(mesh.totvert); for (const int edge_index : edge_selection) { - const MEdge &edge = mesh.medge[edge_index]; + const MEdge &edge = edges[edge_index]; disjoint_set.join(edge.v1, edge.v2); } @@ -342,7 +358,7 @@ static Vector<ElementIsland> prepare_edge_islands(const Mesh &mesh, const IndexM /* Gather all of the edge indices in each island into separate vectors. */ for (const int edge_index : edge_selection) { - const MEdge &edge = mesh.medge[edge_index]; + const MEdge &edge = edges[edge_index]; const int island_id = disjoint_set.find_root(edge.v1); const int island_index = island_ids.index_of_or_add(island_id); if (island_index == islands.size()) { @@ -355,18 +371,19 @@ static Vector<ElementIsland> prepare_edge_islands(const Mesh &mesh, const IndexM return islands; } -static void get_edge_vertices(const Mesh &mesh, int edge_index, VectorSet<int> &r_vertex_indices) +static void get_edge_vertices(const Span<MEdge> edges, + const Span<MPoly> /*polygons*/, + const Span<MLoop> /*loops*/, + int edge_index, + VectorSet<int> &r_vertex_indices) { - const MEdge &edge = mesh.medge[edge_index]; + const MEdge &edge = edges[edge_index]; r_vertex_indices.add(edge.v1); r_vertex_indices.add(edge.v2); } static void scale_edges_uniformly(Mesh &mesh, const UniformScaleFields &fields) { - mesh.mvert = static_cast<MVert *>( - CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator evaluator{field_context, mesh.totedge}; UniformScaleParams params = evaluate_uniform_scale_fields(evaluator, fields); @@ -377,9 +394,6 @@ static void scale_edges_uniformly(Mesh &mesh, const UniformScaleFields &fields) static void scale_edges_on_axis(Mesh &mesh, const AxisScaleFields &fields) { - mesh.mvert = static_cast<MVert *>( - CustomData_duplicate_referenced_layer(&mesh.vdata, CD_MVERT, mesh.totvert)); - bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_EDGE}; FieldEvaluator evaluator{field_context, mesh.totedge}; AxisScaleParams params = evaluate_axis_scale_fields(evaluator, fields); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc index c6a2f89220a..3aee25b0693 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc @@ -12,6 +12,7 @@ #include "DNA_volume_types.h" #include "BKE_material.h" +#include "BKE_mesh.h" namespace blender::nodes::node_geo_set_material_cc { diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index d9c7c9422eb..ce453a8ef32 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -8,6 +8,7 @@ #include "DNA_meshdata_types.h" #include "BKE_curves.hh" +#include "BKE_mesh.h" #include "node_geometry_util.hh" @@ -35,14 +36,14 @@ static void set_computed_position_and_offset(GeometryComponent &component, switch (component.type()) { case GEO_COMPONENT_TYPE_MESH: { Mesh *mesh = static_cast<MeshComponent &>(component).get_for_write(); - MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); if (in_positions.is_same(positions.varray)) { devirtualize_varray(in_offsets, [&](const auto in_offsets) { threading::parallel_for( selection.index_range(), grain_size, [&](const IndexRange range) { for (const int i : selection.slice(range)) { const float3 offset = in_offsets[i]; - add_v3_v3(mverts[i].co, offset); + add_v3_v3(verts[i].co, offset); } }); }); @@ -54,7 +55,7 @@ static void set_computed_position_and_offset(GeometryComponent &component, selection.index_range(), grain_size, [&](const IndexRange range) { for (const int i : selection.slice(range)) { const float3 new_position = in_positions[i] + in_offsets[i]; - copy_v3_v3(mverts[i].co, new_position); + copy_v3_v3(verts[i].co, new_position); } }); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc index 539a1488f53..6be37a02bd5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transfer_attribute.cc @@ -10,6 +10,7 @@ #include "BKE_attribute_math.hh" #include "BKE_bvhutils.h" +#include "BKE_mesh.h" #include "BKE_mesh_runtime.h" #include "BKE_mesh_sample.hh" @@ -263,6 +264,10 @@ static void get_closest_mesh_corners(const Mesh &mesh, const MutableSpan<float> r_distances_sq, const MutableSpan<float3> r_positions) { + const Span<MVert> verts = mesh.vertices(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + BLI_assert(mesh.totloop > 0); Array<int> poly_indices(positions.size()); get_closest_mesh_polygons(mesh, positions, mask, poly_indices, {}, {}); @@ -270,16 +275,16 @@ static void get_closest_mesh_corners(const Mesh &mesh, for (const int i : mask) { const float3 position = positions[i]; const int poly_index = poly_indices[i]; - const MPoly &poly = mesh.mpoly[poly_index]; + const MPoly &poly = polys[poly_index]; /* Find the closest vertex in the polygon. */ float min_distance_sq = FLT_MAX; const MVert *closest_mvert; int closest_loop_index = 0; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const MLoop &loop = mesh.mloop[loop_index]; + const MLoop &loop = loops[loop_index]; const int vertex_index = loop.v; - const MVert &mvert = mesh.mvert[vertex_index]; + const MVert &mvert = verts[vertex_index]; const float distance_sq = math::distance_squared(position, float3(mvert.co)); if (distance_sq < min_distance_sq) { min_distance_sq = distance_sq; diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index a59704291cd..5900e234220 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -5,6 +5,8 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_mesh.h" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_uv_pack_islands_cc { @@ -35,8 +37,12 @@ static VArray<float3> construct_uv_gvarray(const Mesh &mesh, const float margin, const eAttrDomain domain) { + const Span<MVert> verts = mesh.vertices(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; - FieldEvaluator face_evaluator{face_context, mesh.totpoly}; + FieldEvaluator face_evaluator{face_context, polys.size()}; face_evaluator.add(selection_field); face_evaluator.evaluate(); const IndexMask selection = face_evaluator.get_evaluated_as_mask(0); @@ -50,14 +56,9 @@ static VArray<float3> construct_uv_gvarray(const Mesh &mesh, evaluator.add_with_destination(uv_field, uv.as_mutable_span()); evaluator.evaluate(); - const Span<MVert> vertices(mesh.mvert, mesh.totvert); - const Span<MEdge> edges(mesh.medge, mesh.totedge); - const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); - const Span<MLoop> loops(mesh.mloop, mesh.totloop); - ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); for (const int mp_index : selection) { - const MPoly &mp = polygons[mp_index]; + const MPoly &mp = polys[mp_index]; Array<ParamKey, 16> mp_vkeys(mp.totloop); Array<bool, 16> mp_pin(mp.totloop); Array<bool, 16> mp_select(mp.totloop); @@ -66,7 +67,7 @@ static VArray<float3> construct_uv_gvarray(const Mesh &mesh, for (const int i : IndexRange(mp.totloop)) { const MLoop &ml = loops[mp.loopstart + i]; mp_vkeys[i] = ml.v; - mp_co[i] = vertices[ml.v].co; + mp_co[i] = verts[ml.v].co; mp_uv[i] = uv[mp.loopstart + i]; mp_pin[i] = false; mp_select[i] = false; diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 786438ad62a..3095cac6a50 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -5,6 +5,8 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BKE_mesh.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -60,8 +62,13 @@ static VArray<float3> construct_uv_gvarray(const Mesh &mesh, const GeometryNodeUVUnwrapMethod method, const eAttrDomain domain) { + const Span<MVert> verts = mesh.vertices(); + const Span<MEdge> edges = mesh.edges(); + const Span<MPoly> polys = mesh.polygons(); + const Span<MLoop> loops = mesh.loops(); + bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; - FieldEvaluator face_evaluator{face_context, mesh.totpoly}; + FieldEvaluator face_evaluator{face_context, polys.size()}; face_evaluator.add(selection_field); face_evaluator.evaluate(); const IndexMask selection = face_evaluator.get_evaluated_as_mask(0); @@ -70,21 +77,16 @@ static VArray<float3> construct_uv_gvarray(const Mesh &mesh, } bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; - FieldEvaluator edge_evaluator{edge_context, mesh.totedge}; + FieldEvaluator edge_evaluator{edge_context, edges.size()}; edge_evaluator.add(seam_field); edge_evaluator.evaluate(); const IndexMask seam = edge_evaluator.get_evaluated_as_mask(0); - const Span<MVert> vertices(mesh.mvert, mesh.totvert); - const Span<MEdge> edges(mesh.medge, mesh.totedge); - const Span<MPoly> polygons(mesh.mpoly, mesh.totpoly); - const Span<MLoop> loops(mesh.mloop, mesh.totloop); - Array<float3> uv(loops.size(), float3(0)); ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); for (const int mp_index : selection) { - const MPoly &mp = polygons[mp_index]; + const MPoly &mp = polys[mp_index]; Array<ParamKey, 16> mp_vkeys(mp.totloop); Array<bool, 16> mp_pin(mp.totloop); Array<bool, 16> mp_select(mp.totloop); @@ -93,7 +95,7 @@ static VArray<float3> construct_uv_gvarray(const Mesh &mesh, for (const int i : IndexRange(mp.totloop)) { const MLoop &ml = loops[mp.loopstart + i]; mp_vkeys[i] = ml.v; - mp_co[i] = vertices[ml.v].co; + mp_co[i] = verts[ml.v].co; mp_uv[i] = uv[mp.loopstart + i]; mp_pin[i] = false; mp_select[i] = false; diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc index 91429560ac8..5788a744041 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc @@ -123,9 +123,9 @@ static Mesh *create_mesh_from_volume_grids(Span<openvdb::GridBase::ConstPtr> gri Mesh *mesh = BKE_mesh_new_nomain(vert_offset, 0, 0, loop_offset, poly_offset); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan<MVert> verts{mesh->mvert, mesh->totvert}; - MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop}; - MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; + MutableSpan<MVert> verts = mesh->vertices_for_write(); + MutableSpan<MPoly> polys = mesh->polygons_for_write(); + MutableSpan<MLoop> loops = mesh->loops_for_write(); for (const int i : grids.index_range()) { const bke::OpenVDBMeshData &data = mesh_data[i]; diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index ead255a6716..4ce2fcaae4a 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -1148,12 +1148,12 @@ static PyObject *C_BVHTree_FromObject(PyObject *UNUSED(cls), PyObject *args, PyO coords = MEM_mallocN(sizeof(*coords) * (size_t)coords_len, __func__); tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__); - MVert *mv = mesh->mvert; - for (int i = 0; i < mesh->totvert; i++, mv++) { - copy_v3_v3(coords[i], mv->co); + const MVert *verts = BKE_mesh_vertices(mesh); + for (int i = 0; i < mesh->totvert; i++) { + copy_v3_v3(coords[i], verts[i].co); } - mloop = mesh->mloop; + mloop = BKE_mesh_loops(mesh); } { diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index d6e612ee061..64875ada5db 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -459,7 +459,10 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval unsigned int mpoly_prev = UINT_MAX; float no[3]; - const MVert *mvert = CustomData_get_layer(&me->vdata, CD_MVERT); + const MVert *verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); + looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); triangles = MEM_callocN(sizeof(TriTessFace) * tottri, __func__); @@ -470,10 +473,10 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval if (precomputed_normals != NULL) { BKE_mesh_recalc_looptri_with_normals( - me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri, precomputed_normals); + loops, polys, verts, me->totloop, me->totpoly, looptri, precomputed_normals); } else { - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); } const TSpace *tspace = NULL; @@ -492,14 +495,14 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); for (i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; - const MPoly *mp = &me->mpoly[lt->poly]; - - triangles[i].mverts[0] = &mvert[me->mloop[lt->tri[0]].v]; - triangles[i].mverts[1] = &mvert[me->mloop[lt->tri[1]].v]; - triangles[i].mverts[2] = &mvert[me->mloop[lt->tri[2]].v]; - triangles[i].vert_normals[0] = vert_normals[me->mloop[lt->tri[0]].v]; - triangles[i].vert_normals[1] = vert_normals[me->mloop[lt->tri[1]].v]; - triangles[i].vert_normals[2] = vert_normals[me->mloop[lt->tri[2]].v]; + const MPoly *mp = &polys[lt->poly]; + + triangles[i].mverts[0] = &verts[loops[lt->tri[0]].v]; + triangles[i].mverts[1] = &verts[loops[lt->tri[1]].v]; + triangles[i].mverts[2] = &verts[loops[lt->tri[2]].v]; + triangles[i].vert_normals[0] = vert_normals[loops[lt->tri[0]].v]; + triangles[i].vert_normals[1] = vert_normals[loops[lt->tri[1]].v]; + triangles[i].vert_normals[2] = vert_normals[loops[lt->tri[2]].v]; triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0; if (tangent) { @@ -516,7 +519,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval if (calculate_normal) { if (lt->poly != mpoly_prev) { - BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, no); + BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts, no); mpoly_prev = lt->poly; } copy_v3_v3(triangles[i].normal, no); @@ -738,7 +741,10 @@ void RE_bake_pixels_populate(Mesh *me, const int tottri = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); - BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri); + const MVert *verts = BKE_mesh_vertices(me); + const MPoly *polys = BKE_mesh_polygons(me); + const MLoop *loops = BKE_mesh_loops(me); + BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); const int *material_indices = BKE_mesh_material_indices(me); diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c index e116f41321f..ecb7df979fb 100644 --- a/source/blender/render/intern/multires_bake.c +++ b/source/blender/render/intern/multires_bake.c @@ -485,10 +485,18 @@ static void do_multires_bake(MultiresBakeRender *bkr, Mesh *temp_mesh = BKE_mesh_new_nomain( dm->getNumVerts(dm), dm->getNumEdges(dm), 0, dm->getNumLoops(dm), dm->getNumPolys(dm)); - memcpy(temp_mesh->mvert, dm->getVertArray(dm), temp_mesh->totvert * sizeof(*temp_mesh->mvert)); - memcpy(temp_mesh->medge, dm->getEdgeArray(dm), temp_mesh->totedge * sizeof(*temp_mesh->medge)); - memcpy(temp_mesh->mpoly, dm->getPolyArray(dm), temp_mesh->totpoly * sizeof(*temp_mesh->mpoly)); - memcpy(temp_mesh->mloop, dm->getLoopArray(dm), temp_mesh->totloop * sizeof(*temp_mesh->mloop)); + memcpy(BKE_mesh_vertices_for_write(temp_mesh), + dm->getVertArray(dm), + temp_mesh->totvert * sizeof(MVert)); + memcpy(BKE_mesh_edges_for_write(temp_mesh), + dm->getEdgeArray(dm), + temp_mesh->totedge * sizeof(MEdge)); + memcpy(BKE_mesh_polygons_for_write(temp_mesh), + dm->getPolyArray(dm), + temp_mesh->totpoly * sizeof(MPoly)); + memcpy(BKE_mesh_loops_for_write(temp_mesh), + dm->getLoopArray(dm), + temp_mesh->totloop * sizeof(MLoop)); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(temp_mesh); const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(temp_mesh); diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index 92146155437..eae849e1968 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -491,8 +491,8 @@ static void generate_margin(ImBuf *ibuf, const float uv_offset[2]) { - MPoly *mpoly; - MLoop *mloop; + const MPoly *mpoly; + const MLoop *mloop; const MLoopUV *mloopuv; int totpoly, totloop, totedge; @@ -505,8 +505,8 @@ static void generate_margin(ImBuf *ibuf, totpoly = me->totpoly; totloop = me->totloop; totedge = me->totedge; - mpoly = me->mpoly; - mloop = me->mloop; + mpoly = me->polygons().data(); + mloop = me->loops().data(); if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) { mloopuv = static_cast<const MLoopUV *>(CustomData_get_layer(&me->ldata, CD_MLOOPUV)); @@ -520,7 +520,7 @@ static void generate_margin(ImBuf *ibuf, tottri = poly_to_tri_count(me->totpoly, me->totloop); looptri_mem = static_cast<MLoopTri *>(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); BKE_mesh_recalc_looptri( - me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri_mem); + mloop, mpoly, me->vertices().data(), me->totloop, me->totpoly, looptri_mem); looptri = looptri_mem; } else { diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index af49c301302..fdf61a1b994 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -269,7 +269,7 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, Mesh *mesh, float *data_color) { - const MLoop *mloop = mesh->mloop; + const MLoop *mloop = BKE_mesh_loops(mesh); const int totloop = mesh->totloop; char layername[MAX_CUSTOMDATA_LAYER_NAME]; int i; @@ -364,7 +364,7 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) { float *data_color; int i; - MVert *mvert = NULL, *mv; + const MVert *mvert = NULL, *mv; Mesh *mesh = ob->data; #if 0 /* UNUSED */ @@ -380,7 +380,7 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) } #endif - mvert = mesh->mvert; /* local object space */ + mvert = BKE_mesh_vertices(mesh); /* local object space */ pd->totpoints = mesh->totvert; if (pd->totpoints == 0) { return; |