diff options
Diffstat (limited to 'source/blender/blenkernel')
73 files changed, 1591 insertions, 1334 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..5c307eb7dcd 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -11,8 +11,15 @@ #include "BKE_customdata.h" #include "BKE_mesh_types.h" #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" + struct BLI_Stack; struct BMesh; struct BMeshCreateParams; @@ -148,7 +155,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 +523,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 +643,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 +662,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 +675,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 +802,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 +1030,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 +1058,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..43a1a850348 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -29,7 +29,9 @@ extern "C" { struct BVHTree; struct MDeformVert; struct Mesh; +struct MEdge; struct ModifierEvalContext; +struct MPoly; struct Object; struct ShrinkwrapGpencilModifierData; struct ShrinkwrapModifierData; @@ -72,6 +74,7 @@ typedef struct ShrinkwrapTreeData { BVHTree *bvh; BVHTreeFromMesh treeData; + const struct MPoly *polys; const float (*pnors)[3]; const float (*clnors)[3]; ShrinkwrapBoundaryData *boundary; @@ -104,7 +107,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..0a704b7322a 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,9 @@ 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; + const MDeformVert *dverts = BKE_mesh_deform_verts(data->me_target); + if (dverts != NULL) { + dvert = dverts + i; } else { dvert = NULL; @@ -488,7 +490,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 +525,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..f9d648d082a 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -531,6 +531,8 @@ 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 +541,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); |