Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-09-05 19:56:34 +0300
committerHans Goudey <h.goudey@me.com>2022-09-05 19:56:34 +0300
commit05952aa94d33eeb504fa63618ba35c2bcc8bd19b (patch)
treec9ec37adf20c3c37ccaab44869220dcbe8e987a3 /source/blender/blenkernel
parent63cfc8f9f6d623f33b50c5c07976af2b22845713 (diff)
Mesh: Remove redundant custom data pointers
For copy-on-write, we want to share attribute arrays between meshes where possible. Mutable pointers like `Mesh.mvert` make that difficult by making ownership vague. They also make code more complex by adding redundancy. The simplest solution is just removing them and retrieving layers from `CustomData` as needed. Similar changes have already been applied to curves and point clouds (e9f82d3dc7ee, 410a6efb747f). Removing use of the pointers generally makes code more obvious and more reusable. Mesh data is now accessed with a C++ API (`Mesh::edges()` or `Mesh::edges_for_write()`), and a C API (`BKE_mesh_edges(mesh)`). The CoW changes this commit makes possible are described in T95845 and T95842, and started in D14139 and D14140. The change also simplifies the ongoing mesh struct-of-array refactors from T95965. **RNA/Python Access Performance** Theoretically, accessing mesh elements with the RNA API may become slower, since the layer needs to be found on every random access. However, overhead is already high enough that this doesn't make a noticible differenc, and performance is actually improved in some cases. Random access can be up to 10% faster, but other situations might be a bit slower. Generally using `foreach_get/set` are the best way to improve performance. See the differential revision for more discussion about Python performance. Cycles has been updated to use raw pointers and the internal Blender mesh types, mostly because there is no sense in having this overhead when it's already compiled with Blender. In my tests this roughly halves the Cycles mesh creation time (0.19s to 0.10s for a 1 million face grid). Differential Revision: https://developer.blender.org/D15488
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_deform.h8
-rw-r--r--source/blender/blenkernel/BKE_mesh.h142
-rw-r--r--source/blender/blenkernel/BKE_mesh_mapping.h16
-rw-r--r--source/blender/blenkernel/BKE_mesh_remap.h16
-rw-r--r--source/blender/blenkernel/BKE_mesh_sample.hh3
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_shrinkwrap.h6
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.cc23
-rw-r--r--source/blender/blenkernel/intern/armature_deform.c9
-rw-r--r--source/blender/blenkernel/intern/bvhutils.cc36
-rw-r--r--source/blender/blenkernel/intern/cloth.c23
-rw-r--r--source/blender/blenkernel/intern/constraint.c3
-rw-r--r--source/blender/blenkernel/intern/crazyspace.cc25
-rw-r--r--source/blender/blenkernel/intern/curve_to_mesh_convert.cc8
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c62
-rw-r--r--source/blender/blenkernel/intern/deform.c16
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c59
-rw-r--r--source/blender/blenkernel/intern/effect.c3
-rw-r--r--source/blender/blenkernel/intern/fluid.c69
-rw-r--r--source/blender/blenkernel/intern/geometry_component_mesh.cc194
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc37
-rw-r--r--source/blender/blenkernel/intern/key.c42
-rw-r--r--source/blender/blenkernel/intern/lattice_deform.c3
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.cc289
-rw-r--r--source/blender/blenkernel/intern/mesh_boolean_convert.cc83
-rw-r--r--source/blender/blenkernel/intern/mesh_calc_edges.cc14
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.cc100
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.cc95
-rw-r--r--source/blender/blenkernel/intern/mesh_fair.cc27
-rw-r--r--source/blender/blenkernel/intern/mesh_iterators.c33
-rw-r--r--source/blender/blenkernel/intern/mesh_legacy_convert.cc95
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c23
-rw-r--r--source/blender/blenkernel/intern/mesh_merge.c90
-rw-r--r--source/blender/blenkernel/intern/mesh_merge_customdata.cc9
-rw-r--r--source/blender/blenkernel/intern/mesh_mirror.c38
-rw-r--r--source/blender/blenkernel/intern/mesh_normals.cc81
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c88
-rw-r--r--source/blender/blenkernel/intern/mesh_remesh_voxel.cc57
-rw-r--r--source/blender/blenkernel/intern/mesh_runtime.cc50
-rw-r--r--source/blender/blenkernel/intern/mesh_sample.cc58
-rw-r--r--source/blender/blenkernel/intern/mesh_tangent.c12
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.cc141
-rw-r--r--source/blender/blenkernel/intern/mesh_wrapper.cc10
-rw-r--r--source/blender/blenkernel/intern/multires.c19
-rw-r--r--source/blender/blenkernel/intern/multires_reshape.h8
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_apply_base.c31
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_smooth.c12
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_subdivide.c20
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_util.c23
-rw-r--r--source/blender/blenkernel/intern/multires_reshape_vertcos.c3
-rw-r--r--source/blender/blenkernel/intern/multires_unsubdivide.c21
-rw-r--r--source/blender/blenkernel/intern/object.cc33
-rw-r--r--source/blender/blenkernel/intern/object_deform.c17
-rw-r--r--source/blender/blenkernel/intern/object_dupli.cc8
-rw-r--r--source/blender/blenkernel/intern/paint.cc56
-rw-r--r--source/blender/blenkernel/intern/particle.c46
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c38
-rw-r--r--source/blender/blenkernel/intern/particle_system.c8
-rw-r--r--source/blender/blenkernel/intern/pbvh_pixels.cc4
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c22
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c23
-rw-r--r--source/blender/blenkernel/intern/softbody.c38
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg_mask.c7
-rw-r--r--source/blender/blenkernel/intern/subdiv_ccg_material.c10
-rw-r--r--source/blender/blenkernel/intern/subdiv_converter_mesh.c36
-rw-r--r--source/blender/blenkernel/intern/subdiv_displacement_multires.c7
-rw-r--r--source/blender/blenkernel/intern/subdiv_eval.c12
-rw-r--r--source/blender/blenkernel/intern/subdiv_foreach.c85
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.cc125
-rw-r--r--source/blender/blenkernel/intern/volume_to_mesh.cc6
73 files changed, 1587 insertions, 1337 deletions
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 6af38b14ea4..f5ffd1190b1 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -79,7 +79,7 @@ typedef struct Cloth {
int last_frame;
float initial_mesh_volume; /* Initial volume of the mesh. Used for pressure */
float average_acceleration[3]; /* Moving average of overall acceleration. */
- struct MEdge *edges; /* Used for hair collisions. */
+ const struct MEdge *edges; /* Used for hair collisions. */
struct EdgeSet *sew_edge_graph; /* Sewing edges represented using a GHash */
} Cloth;
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index a21d9141ac0..f58a5502788 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -240,23 +240,23 @@ void BKE_defvert_extract_vgroup_to_vertweights(const struct MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_edgeweights(const struct MDeformVert *dvert,
int defgroup,
int num_verts,
- struct MEdge *edges,
+ const struct MEdge *edges,
int num_edges,
bool invert_vgroup,
float *r_weights);
void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert,
int defgroup,
int num_verts,
- struct MLoop *loops,
+ const struct MLoop *loops,
int num_loops,
bool invert_vgroup,
float *r_weights);
void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert,
int defgroup,
int num_verts,
- struct MLoop *loops,
+ const struct MLoop *loops,
int num_loops,
- struct MPoly *polys,
+ const struct MPoly *polys,
int num_polys,
bool invert_vgroup,
float *r_weights);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index ec6799ee995..eb54861e79c 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -6,12 +6,15 @@
* \ingroup bke
*/
+#include "BLI_compiler_attrs.h"
+#include "BLI_compiler_compat.h"
+#include "BLI_utildefines.h"
+
#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
#include "BKE_customdata.h"
#include "BKE_mesh_types.h"
-#include "BLI_compiler_attrs.h"
-#include "BLI_utildefines.h"
struct BLI_Stack;
struct BMesh;
@@ -148,7 +151,6 @@ void BKE_mesh_copy_parameters_for_eval(struct Mesh *me_dst, const struct Mesh *m
* when a new mesh is based on an existing mesh.
*/
void BKE_mesh_copy_parameters(struct Mesh *me_dst, const struct Mesh *me_src);
-void BKE_mesh_update_customdata_pointers(struct Mesh *me, bool do_ensure_tess_cd);
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
struct Mesh *BKE_mesh_new_nomain(
@@ -517,9 +519,9 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
int numVerts,
struct MEdge *medges,
int numEdges,
- struct MLoop *mloops,
+ const struct MLoop *mloops,
int numLoops,
- struct MPoly *mpolys,
+ const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
float split_angle);
@@ -637,12 +639,12 @@ void BKE_lnor_space_custom_normal_to_data(MLoopNorSpace *lnor_space,
void BKE_mesh_normals_loop_split(const struct MVert *mverts,
const float (*vert_normals)[3],
int numVerts,
- struct MEdge *medges,
+ const struct MEdge *medges,
int numEdges,
- struct MLoop *mloops,
+ const struct MLoop *mloops,
float (*r_loopnors)[3],
int numLoops,
- struct MPoly *mpolys,
+ const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
bool use_split_normals,
@@ -656,10 +658,10 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts,
int numVerts,
struct MEdge *medges,
int numEdges,
- struct MLoop *mloops,
+ const struct MLoop *mloops,
float (*r_custom_loopnors)[3],
int numLoops,
- struct MPoly *mpolys,
+ const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
short (*r_clnors_data)[2]);
@@ -669,9 +671,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(const struct MVert *mverts,
int numVerts,
struct MEdge *medges,
int numEdges,
- struct MLoop *mloops,
+ const struct MLoop *mloops,
int numLoops,
- struct MPoly *mpolys,
+ const struct MPoly *mpolys,
const float (*polynors)[3],
int numPolys,
short (*r_clnors_data)[2]);
@@ -796,19 +798,21 @@ void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip);
* \param mloop: the full loops array.
* \param ldata: the loops custom data.
*/
-void BKE_mesh_polygon_flip_ex(struct MPoly *mpoly,
+void BKE_mesh_polygon_flip_ex(const struct MPoly *mpoly,
struct MLoop *mloop,
struct CustomData *ldata,
float (*lnors)[3],
struct MDisps *mdisp,
bool use_loop_mdisp_flip);
-void BKE_mesh_polygon_flip(struct MPoly *mpoly, struct MLoop *mloop, struct CustomData *ldata);
+void BKE_mesh_polygon_flip(const struct MPoly *mpoly,
+ struct MLoop *mloop,
+ struct CustomData *ldata);
/**
* Flip (invert winding of) all polygons (used to inverse their normals).
*
* \note Invalidates tessellation, caller must handle that.
*/
-void BKE_mesh_polygons_flip(struct MPoly *mpoly,
+void BKE_mesh_polygons_flip(const struct MPoly *mpoly,
struct MLoop *mloop,
struct CustomData *ldata,
int totpoly);
@@ -1022,6 +1026,10 @@ char *BKE_mesh_debug_info(const struct Mesh *me)
void BKE_mesh_debug_print(const struct Mesh *me) ATTR_NONNULL(1);
#endif
+/* -------------------------------------------------------------------- */
+/** \name Inline Mesh Data Access
+ * \{ */
+
/**
* \return The material index for each polygon. May be null.
* \note In C++ code, prefer using the attribute API (#MutableAttributeAccessor)/
@@ -1046,6 +1054,110 @@ BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh)
&mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, NULL, mesh->totpoly, "material_index");
}
+BLI_INLINE const MVert *BKE_mesh_vertices(const Mesh *mesh)
+{
+ return (const MVert *)CustomData_get_layer(&mesh->vdata, CD_MVERT);
+}
+BLI_INLINE MVert *BKE_mesh_vertices_for_write(Mesh *mesh)
+{
+ return (MVert *)CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
+}
+
+BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh)
+{
+ return (const MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE);
+}
+BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh)
+{
+ return (MEdge *)CustomData_duplicate_referenced_layer(&mesh->edata, CD_MEDGE, mesh->totedge);
+}
+
+BLI_INLINE const MPoly *BKE_mesh_polygons(const Mesh *mesh)
+{
+ return (const MPoly *)CustomData_get_layer(&mesh->pdata, CD_MPOLY);
+}
+BLI_INLINE MPoly *BKE_mesh_polygons_for_write(Mesh *mesh)
+{
+ return (MPoly *)CustomData_duplicate_referenced_layer(&mesh->pdata, CD_MPOLY, mesh->totpoly);
+}
+
+BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh)
+{
+ return (const MLoop *)CustomData_get_layer(&mesh->ldata, CD_MLOOP);
+}
+BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh)
+{
+ return (MLoop *)CustomData_duplicate_referenced_layer(&mesh->ldata, CD_MLOOP, mesh->totloop);
+}
+
+BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh)
+{
+ return (const MDeformVert *)CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);
+}
+BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh)
+{
+ MDeformVert *dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
+ &mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
+ if (dvert) {
+ return dvert;
+ }
+ return (MDeformVert *)CustomData_add_layer(
+ &mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, mesh->totvert);
+}
+
#ifdef __cplusplus
}
#endif
+
+#ifdef __cplusplus
+
+# include "BLI_span.hh"
+
+inline blender::Span<MVert> Mesh::vertices() const
+{
+ return {BKE_mesh_vertices(this), this->totvert};
+}
+inline blender::MutableSpan<MVert> Mesh::vertices_for_write()
+{
+ return {BKE_mesh_vertices_for_write(this), this->totvert};
+}
+
+inline blender::Span<MEdge> Mesh::edges() const
+{
+ return {BKE_mesh_edges(this), this->totedge};
+}
+inline blender::MutableSpan<MEdge> Mesh::edges_for_write()
+{
+ return {BKE_mesh_edges_for_write(this), this->totedge};
+}
+
+inline blender::Span<MPoly> Mesh::polygons() const
+{
+ return {BKE_mesh_polygons(this), this->totpoly};
+}
+inline blender::MutableSpan<MPoly> Mesh::polygons_for_write()
+{
+ return {BKE_mesh_polygons_for_write(this), this->totpoly};
+}
+
+inline blender::Span<MLoop> Mesh::loops() const
+{
+ return {BKE_mesh_loops(this), this->totloop};
+}
+inline blender::MutableSpan<MLoop> Mesh::loops_for_write()
+{
+ return {BKE_mesh_loops_for_write(this), this->totloop};
+}
+
+inline blender::Span<MDeformVert> Mesh::deform_verts() const
+{
+ return {BKE_mesh_deform_verts(this), this->totvert};
+}
+inline blender::MutableSpan<MDeformVert> Mesh::deform_verts_for_write()
+{
+ return {BKE_mesh_deform_verts_for_write(this), this->totvert};
+}
+
+#endif
+
+/** \} */
diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h
index abe590b6806..cf9763d50a4 100644
--- a/source/blender/blenkernel/BKE_mesh_mapping.h
+++ b/source/blender/blenkernel/BKE_mesh_mapping.h
@@ -248,13 +248,13 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store,
int num_innercut_items,
int *innercut_item_indices);
-typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts,
+typedef bool (*MeshRemapIslandsCalc)(const struct MVert *verts,
int totvert,
- struct MEdge *edges,
+ const struct MEdge *edges,
int totedge,
- struct MPoly *polys,
+ const struct MPoly *polys,
int totpoly,
- struct MLoop *loops,
+ const struct MLoop *loops,
int totloop,
struct MeshIslandStore *r_island_store);
@@ -265,13 +265,13 @@ typedef bool (*MeshRemapIslandsCalc)(struct MVert *verts,
* Calculate 'generic' UV islands, i.e. based only on actual geometry data (edge seams),
* not some UV layers coordinates.
*/
-bool BKE_mesh_calc_islands_loop_poly_edgeseam(struct MVert *verts,
+bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts,
int totvert,
- struct MEdge *edges,
+ const struct MEdge *edges,
int totedge,
- struct MPoly *polys,
+ const struct MPoly *polys,
int totpoly,
- struct MLoop *loops,
+ const struct MLoop *loops,
int totloop,
MeshIslandStore *r_island_store);
diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h
index ee0179c7a77..efbf542c831 100644
--- a/source/blender/blenkernel/BKE_mesh_remap.h
+++ b/source/blender/blenkernel/BKE_mesh_remap.h
@@ -199,13 +199,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode,
float max_dist,
float ray_radius,
struct Mesh *mesh_dst,
- struct MVert *verts_dst,
+ const struct MVert *verts_dst,
int numverts_dst,
- struct MEdge *edges_dst,
+ const struct MEdge *edges_dst,
int numedges_dst,
- struct MLoop *loops_dst,
+ const struct MLoop *loops_dst,
int numloops_dst,
- struct MPoly *polys_dst,
+ const struct MPoly *polys_dst,
int numpolys_dst,
struct CustomData *ldata_dst,
bool use_split_nors_dst,
@@ -220,10 +220,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode,
const struct SpaceTransform *space_transform,
float max_dist,
float ray_radius,
- struct Mesh *mesh_dst,
- struct MVert *verts_dst,
- struct MLoop *loops_dst,
- struct MPoly *polys_dst,
+ const struct Mesh *mesh_dst,
+ const struct MVert *verts_dst,
+ const struct MLoop *loops_dst,
+ const struct MPoly *polys_dst,
int numpolys_dst,
struct Mesh *me_src,
struct MeshPairRemap *r_map);
diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh
index fb01083f334..94dc52d5ec9 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.hh
+++ b/source/blender/blenkernel/BKE_mesh_sample.hh
@@ -127,7 +127,8 @@ int sample_surface_points_projected(
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions);
-float3 compute_bary_coord_in_triangle(const Mesh &mesh,
+float3 compute_bary_coord_in_triangle(Span<MVert> verts,
+ Span<MLoop> loops,
const MLoopTri &looptri,
const float3 &position);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 92b1aacc300..2197fa3af1e 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -500,8 +500,8 @@ typedef struct SculptSession {
/* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */
struct MVert *mvert;
- struct MPoly *mpoly;
- struct MLoop *mloop;
+ const struct MPoly *mpoly;
+ const struct MLoop *mloop;
/* These contain the vertex and poly counts of the final mesh. */
int totvert, totpoly;
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 5f8b2fafdd3..a797aef73f6 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -579,7 +579,7 @@ void psys_get_texture(struct ParticleSimulationData *sim,
* Interpolate a location on a face based on face coordinates.
*/
void psys_interpolate_face(struct Mesh *mesh,
- struct MVert *mvert,
+ const struct MVert *mvert,
const float (*vert_normals)[3],
struct MFace *mface,
struct MTFace *tface,
diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h
index 3e06bd84805..3fe1ee10eb9 100644
--- a/source/blender/blenkernel/BKE_shrinkwrap.h
+++ b/source/blender/blenkernel/BKE_shrinkwrap.h
@@ -29,7 +29,8 @@ extern "C" {
struct BVHTree;
struct MDeformVert;
struct Mesh;
-struct ModifierEvalContext;
+ struct ModifierEvalContext;
+struct MPoly;
struct Object;
struct ShrinkwrapGpencilModifierData;
struct ShrinkwrapModifierData;
@@ -72,6 +73,7 @@ typedef struct ShrinkwrapTreeData {
BVHTree *bvh;
BVHTreeFromMesh treeData;
+ const struct MPoly *polys;
const float (*pnors)[3];
const float (*clnors)[3];
ShrinkwrapBoundaryData *boundary;
@@ -104,7 +106,7 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd,
struct Scene *scene,
struct Object *ob,
struct Mesh *mesh,
- struct MDeformVert *dvert,
+ const struct MDeformVert *dvert,
int defgrp_index,
float (*vertexCos)[3],
int numVerts);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc
index 7ef6eaa64cd..46a8caafa70 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.cc
+++ b/source/blender/blenkernel/intern/DerivedMesh.cc
@@ -68,6 +68,8 @@
using blender::float3;
using blender::IndexRange;
+using blender::Span;
+using blender::VArray;
/* very slow! enable for testing only! */
//#define USE_MODIFIER_VALIDATE
@@ -585,7 +587,6 @@ static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orc
if (!(layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer))) {
CustomData_add_layer(&mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert);
- BKE_mesh_update_customdata_pointers(mesh, false);
layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer);
}
@@ -2002,9 +2003,9 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to
MEM_freeN(userData.vertex_visit);
}
else {
- MVert *mv = me_eval->mvert;
- for (int i = 0; i < totcos; i++, mv++) {
- copy_v3_v3(r_cos[i], mv->co);
+ const Span<MVert> verts = me_eval->vertices();
+ for (int i = 0; i < totcos; i++) {
+ copy_v3_v3(r_cos[i], verts[i].co);
}
}
}
@@ -2017,9 +2018,11 @@ static void mesh_init_origspace(Mesh *mesh)
CD_ORIGSPACE_MLOOP);
const int numpoly = mesh->totpoly;
// const int numloop = mesh->totloop;
- MVert *mv = mesh->mvert;
- MLoop *ml = mesh->mloop;
- MPoly *mp = mesh->mpoly;
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MPoly> polys = mesh->polygons();
+ const Span<MLoop> loops = mesh->loops();
+
+ const MPoly *mp = polys.data();
int i, j, k;
blender::Vector<blender::float2, 64> vcos_2d;
@@ -2033,19 +2036,19 @@ static void mesh_init_origspace(Mesh *mesh)
}
}
else {
- MLoop *l = &ml[mp->loopstart];
+ const MLoop *l = &loops[mp->loopstart];
float p_nor[3], co[3];
float mat[3][3];
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
- BKE_mesh_calc_poly_normal(mp, l, mv, p_nor);
+ BKE_mesh_calc_poly_normal(mp, l, verts.data(), p_nor);
axis_dominant_v3_to_m3(mat, p_nor);
vcos_2d.resize(mp->totloop);
for (j = 0; j < mp->totloop; j++, l++) {
- mul_v3_m3v3(co, mat, mv[l->v].co);
+ mul_v3_m3v3(co, mat, verts[l->v].co);
copy_v2_v2(vcos_2d[j], co);
for (k = 0; k < 2; k++) {
diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c
index cc1bfcc087c..84bb1af011a 100644
--- a/source/blender/blenkernel/intern/armature_deform.c
+++ b/source/blender/blenkernel/intern/armature_deform.c
@@ -35,6 +35,7 @@
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_lattice.h"
+#include "BKE_mesh.h"
#include "DEG_depsgraph_build.h"
@@ -406,8 +407,8 @@ static void armature_vert_task(void *__restrict userdata,
if (data->use_dverts || data->armature_def_nr != -1) {
if (data->me_target) {
BLI_assert(i < data->me_target->totvert);
- if (data->me_target->dvert != NULL) {
- dvert = data->me_target->dvert + i;
+ if (data->dverts != NULL) {
+ dvert = data->dverts + i;
}
else {
dvert = NULL;
@@ -488,7 +489,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
target_data_id = me_target == NULL ? (const ID *)ob_target->data : &me_target->id;
if (em_target == NULL) {
const Mesh *me = (const Mesh *)target_data_id;
- dverts = me->dvert;
+ dverts = BKE_mesh_deform_verts(me);
if (dverts) {
dverts_len = me->totvert;
}
@@ -523,7 +524,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
use_dverts = (cd_dvert_offset != -1);
}
else if (me_target) {
- use_dverts = (me_target->dvert != NULL);
+ use_dverts = (BKE_mesh_deform_verts(me_target) != NULL);
}
else if (dverts) {
use_dverts = true;
diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc
index d0b57b45d35..d33ff933004 100644
--- a/source/blender/blenkernel/intern/bvhutils.cc
+++ b/source/blender/blenkernel/intern/bvhutils.cc
@@ -15,6 +15,7 @@
#include "BLI_linklist.h"
#include "BLI_math.h"
+#include "BLI_span.hh"
#include "BLI_task.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
@@ -27,6 +28,7 @@
#include "MEM_guardedalloc.h"
+using blender::Span;
using blender::VArray;
/* -------------------------------------------------------------------- */
@@ -1229,14 +1231,17 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
looptri_len = BKE_mesh_runtime_looptri_len(mesh);
}
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MEdge> edges = mesh->edges();
+ const Span<MLoop> loops = mesh->loops();
/* Setup BVHTreeFromMesh */
bvhtree_from_mesh_setup_data(nullptr,
bvh_cache_type,
- mesh->mvert,
- mesh->medge,
- mesh->mface,
- mesh->mloop,
+ verts.data(),
+ edges.data(),
+ (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
+ loops.data(),
looptri,
BKE_mesh_vertex_normals_ensure(mesh),
data);
@@ -1260,31 +1265,38 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
switch (bvh_cache_type) {
case BVHTREE_FROM_LOOSEVERTS:
mask = loose_verts_map_get(
- mesh->medge, mesh->totedge, mesh->mvert, mesh->totvert, &mask_bits_act_len);
+ edges.data(), mesh->totedge, verts.data(), mesh->totvert, &mask_bits_act_len);
ATTR_FALLTHROUGH;
case BVHTREE_FROM_VERTS:
data->tree = bvhtree_from_mesh_verts_create_tree(
- 0.0f, tree_type, 6, mesh->mvert, mesh->totvert, mask, mask_bits_act_len);
+ 0.0f, tree_type, 6, verts.data(), mesh->totvert, mask, mask_bits_act_len);
break;
case BVHTREE_FROM_LOOSEEDGES:
- mask = loose_edges_map_get(mesh->medge, mesh->totedge, &mask_bits_act_len);
+ mask = loose_edges_map_get(edges.data(), mesh->totedge, &mask_bits_act_len);
ATTR_FALLTHROUGH;
case BVHTREE_FROM_EDGES:
data->tree = bvhtree_from_mesh_edges_create_tree(
- mesh->mvert, mesh->medge, mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6);
+ verts.data(), edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6);
break;
case BVHTREE_FROM_FACES:
BLI_assert(!(mesh->totface == 0 && mesh->totpoly != 0));
data->tree = bvhtree_from_mesh_faces_create_tree(
- 0.0f, tree_type, 6, mesh->mvert, mesh->mface, mesh->totface, nullptr, -1);
+ 0.0f,
+ tree_type,
+ 6,
+ verts.data(),
+ (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
+ mesh->totface,
+ nullptr,
+ -1);
break;
case BVHTREE_FROM_LOOPTRI_NO_HIDDEN: {
blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh);
mask = looptri_no_hidden_map_get(
- mesh->mpoly,
+ mesh->polygons().data(),
attributes.lookup_or_default(".hide_poly", ATTR_DOMAIN_FACE, false),
looptri_len,
&mask_bits_act_len);
@@ -1294,8 +1306,8 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data,
data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f,
tree_type,
6,
- mesh->mvert,
- mesh->mloop,
+ verts.data(),
+ loops.data(),
looptri,
looptri_len,
mask,
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 8622174231c..ef3d71cdacf 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -97,7 +97,7 @@ static BVHTree *bvhtree_build_from_cloth(ClothModifierData *clmd, float epsilon)
}
}
else {
- MEdge *edges = cloth->edges;
+ const MEdge *edges = cloth->edges;
for (int i = 0; i < cloth->primitive_num; i++) {
float co[2][3];
@@ -177,7 +177,7 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, bool moving, bool self)
}
else {
if (verts) {
- MEdge *edges = cloth->edges;
+ const MEdge *edges = cloth->edges;
for (i = 0; i < cloth->primitive_num; i++) {
float co[2][3];
@@ -258,7 +258,7 @@ static int do_step_cloth(
cloth = clmd->clothObject;
verts = cloth->verts;
- mvert = result->mvert;
+ mvert = BKE_mesh_vertices_for_write(result);
vert_mass_changed = verts->mass != clmd->sim_parms->mass;
/* force any pinned verts to their constrained location. */
@@ -713,7 +713,6 @@ static bool cloth_from_object(
Object *ob, ClothModifierData *clmd, Mesh *mesh, float UNUSED(framenr), int first)
{
int i = 0;
- MVert *mvert = NULL;
ClothVertex *verts = NULL;
const float(*shapekey_rest)[3] = NULL;
const float tnull[3] = {0, 0, 0};
@@ -755,7 +754,7 @@ static bool cloth_from_object(
shapekey_rest = CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO);
}
- mvert = mesh->mvert;
+ MVert *mvert = BKE_mesh_vertices_for_write(mesh);
verts = clmd->clothObject->verts;
@@ -824,7 +823,7 @@ static bool cloth_from_object(
static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh)
{
- const MLoop *mloop = mesh->mloop;
+ const MLoop *mloop = BKE_mesh_loops(mesh);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh);
const unsigned int mvert_num = mesh->totvert;
const unsigned int looptri_num = mesh->runtime.looptris.len;
@@ -859,7 +858,7 @@ static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mes
}
BKE_mesh_runtime_verttri_from_looptri(clmd->clothObject->tri, mloop, looptri, looptri_num);
- clmd->clothObject->edges = mesh->medge;
+ clmd->clothObject->edges = BKE_mesh_edges(mesh);
/* Free the springs since they can't be correct if the vertices
* changed.
@@ -1150,7 +1149,7 @@ static void cloth_update_springs(ClothModifierData *clmd)
static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh)
{
unsigned int i = 0;
- MVert *mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
ClothVertex *verts = clmd->clothObject->verts;
/* vertex count is already ensured to match */
@@ -1165,7 +1164,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh)
{
Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false);
ClothVertex *verts = clmd->clothObject->verts;
- MVert *mvert = new_mesh->mvert;
+ MVert *mvert = BKE_mesh_vertices_for_write(mesh);
/* vertex count is already ensured to match */
for (unsigned i = 0; i < mesh->totvert; i++, verts++) {
@@ -1459,9 +1458,9 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh)
unsigned int numedges = (unsigned int)mesh->totedge;
unsigned int numpolys = (unsigned int)mesh->totpoly;
float shrink_factor;
- const MEdge *medge = mesh->medge;
- const MPoly *mpoly = mesh->mpoly;
- const MLoop *mloop = mesh->mloop;
+ const MEdge *medge = BKE_mesh_edges(mesh);
+ const MPoly *mpoly = BKE_mesh_polygons(mesh);
+ const MLoop *mloop = BKE_mesh_loops(mesh);
int index2 = 0; /* our second vertex index */
LinkNodePair *edgelist = NULL;
EdgeSet *edgeset = NULL;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 071fa5fe6bf..50b620c42bb 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -531,6 +531,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
if (me_eval) {
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
const MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT);
+ const MVert *verts = BKE_mesh_vertices(me_eval);
int numVerts = me_eval->totvert;
/* check that dvert is a valid pointers (just in case) */
@@ -539,7 +540,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[
/* get the average of all verts with that are in the vertex-group */
for (int i = 0; i < numVerts; i++) {
const MDeformVert *dv = &dvert[i];
- const MVert *mv = &me_eval->mvert[i];
+ const MVert *mv = &verts[i];
const MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup);
if (dw && dw->weight > 0.0f) {
diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc
index fdd269bd9c8..17fb9fdb03e 100644
--- a/source/blender/blenkernel/intern/crazyspace.cc
+++ b/source/blender/blenkernel/intern/crazyspace.cc
@@ -182,19 +182,22 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me,
float (*mappedcos)[3],
float (*quats)[4])
{
+ using namespace blender;
+ using namespace blender::bke;
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__);
/* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
- MVert *mvert = me->mvert;
- MPoly *mp = me->mpoly;
- MLoop *mloop = me->mloop;
+ const Span<MVert> verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
- for (int i = 0; i < me->totpoly; i++, mp++) {
- MLoop *ml_next = &mloop[mp->loopstart];
- MLoop *ml_curr = &ml_next[mp->totloop - 1];
- MLoop *ml_prev = &ml_next[mp->totloop - 2];
+ for (int i = 0; i < me->totpoly; i++) {
+ const MPoly *poly = &polys[i];
+ const MLoop *ml_next = &loops[poly->loopstart];
+ const MLoop *ml_curr = &ml_next[poly->totloop - 1];
+ const MLoop *ml_prev = &ml_next[poly->totloop - 2];
- for (int j = 0; j < mp->totloop; j++) {
+ for (int j = 0; j < poly->totloop; j++) {
if (!BLI_BITMAP_TEST(vert_tag, ml_curr->v)) {
const float *co_prev, *co_curr, *co_next; /* orig */
const float *vd_prev, *vd_curr, *vd_next; /* deform */
@@ -210,9 +213,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me,
co_next = origcos[ml_next->v];
}
else {
- co_prev = mvert[ml_prev->v].co;
- co_curr = mvert[ml_curr->v].co;
- co_next = mvert[ml_next->v].co;
+ co_prev = verts[ml_prev->v].co;
+ co_curr = verts[ml_curr->v].co;
+ co_next = verts[ml_next->v].co;
}
set_crazy_vertex_quat(
diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
index 7f051b683b4..47cd8495b18 100644
--- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
+++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc
@@ -640,10 +640,10 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main,
offsets.vert.last(), offsets.edge.last(), 0, offsets.loop.last(), offsets.poly.last());
mesh->flag |= ME_AUTOSMOOTH;
mesh->smoothresh = DEG2RADF(180.0f);
- MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
- MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
- MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop);
- MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ MutableSpan<MPoly> polys = mesh->polygons_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) {
fill_mesh_topology(info.vert_range.start(),
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 02b5175f65f..4c8b7a590ed 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -256,13 +256,14 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src,
{
if (dtdata_type == DT_TYPE_LNOR) {
/* Compute custom normals into regular loop normals, which will be used for the transfer. */
- MVert *verts_dst = me_dst->mvert;
+
+ const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
- MEdge *edges_dst = me_dst->medge;
+ const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
- MPoly *polys_dst = me_dst->mpoly;
+ const MPoly *polys_dst = BKE_mesh_polygons(me_dst);
const int num_polys_dst = me_dst->totpoly;
- MLoop *loops_dst = me_dst->mloop;
+ const MLoop *loops_dst = BKE_mesh_loops(me_dst);
const int num_loops_dst = me_dst->totloop;
CustomData *ldata_dst = &me_dst->ldata;
@@ -318,13 +319,13 @@ static void data_transfer_dtdata_type_postprocess(Object *UNUSED(ob_src),
}
/* Bake edited destination loop normals into custom normals again. */
- MVert *verts_dst = me_dst->mvert;
+ const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
- MEdge *edges_dst = me_dst->medge;
+ MEdge *edges_dst = BKE_mesh_edges_for_write(me_dst);
const int num_edges_dst = me_dst->totedge;
- MPoly *polys_dst = me_dst->mpoly;
+ MPoly *polys_dst = BKE_mesh_polygons_for_write(me_dst);
const int num_polys_dst = me_dst->totpoly;
- MLoop *loops_dst = me_dst->mloop;
+ MLoop *loops_dst = BKE_mesh_loops_for_write(me_dst);
const int num_loops_dst = me_dst->totloop;
CustomData *ldata_dst = &me_dst->ldata;
@@ -946,8 +947,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
- me_src->mvert,
- me_dst->mvert,
+ BKE_mesh_vertices(me_src),
+ BKE_mesh_vertices_for_write(me_dst),
me_src->totvert,
me_dst->totvert,
elem_size,
@@ -979,9 +980,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
me_dst != ob_dst->data,
fromlayers,
tolayers);
-
- /* Mesh stores its dvert in a specific pointer too. :( */
- me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
return ret;
}
if (cddata_type == CD_FAKE_SHAPEKEY) {
@@ -1034,8 +1032,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
- me_src->medge,
- me_dst->medge,
+ BKE_mesh_edges(me_src),
+ BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
@@ -1066,8 +1064,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
- me_src->medge,
- me_dst->medge,
+ BKE_mesh_edges(me_src),
+ BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
@@ -1090,8 +1088,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
- me_src->medge,
- me_dst->medge,
+ BKE_mesh_edges(me_src),
+ BKE_mesh_edges_for_write(me_dst),
me_src->totedge,
me_dst->totedge,
elem_size,
@@ -1184,8 +1182,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map,
mix_mode,
mix_factor,
mix_weights,
- me_src->mpoly,
- me_dst->mpoly,
+ BKE_mesh_polygons(me_src),
+ BKE_mesh_polygons_for_write(me_dst),
me_src->totpoly,
me_dst->totpoly,
elem_size,
@@ -1432,7 +1430,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
BKE_mesh_remap_find_best_match_from_mesh(
- me_dst->mvert, me_dst->totvert, me_src, space_transform);
+ BKE_mesh_vertices(me_dst), me_dst->totvert, me_src, space_transform);
}
/* Check all possible data types.
@@ -1460,7 +1458,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
if (DT_DATATYPE_IS_VERT(dtdata_type)) {
- MVert *verts_dst = me_dst->mvert;
+ MVert *verts_dst = BKE_mesh_vertices_for_write(me_dst);
const int num_verts_dst = me_dst->totvert;
if (!geom_map_init[VDATA]) {
@@ -1542,9 +1540,9 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
- MVert *verts_dst = me_dst->mvert;
+ const MVert *verts_dst = BKE_mesh_vertices_for_write(me_dst);
const int num_verts_dst = me_dst->totvert;
- MEdge *edges_dst = me_dst->medge;
+ const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
if (!geom_map_init[EDATA]) {
@@ -1621,13 +1619,13 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
- MVert *verts_dst = me_dst->mvert;
+ const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
- MEdge *edges_dst = me_dst->medge;
+ const MEdge *edges_dst = BKE_mesh_edges(me_dst);
const int num_edges_dst = me_dst->totedge;
- MPoly *polys_dst = me_dst->mpoly;
+ const MPoly *polys_dst = BKE_mesh_polygons(me_dst);
const int num_polys_dst = me_dst->totpoly;
- MLoop *loops_dst = me_dst->mloop;
+ const MLoop *loops_dst = BKE_mesh_loops(me_dst);
const int num_loops_dst = me_dst->totloop;
CustomData *ldata_dst = &me_dst->ldata;
@@ -1716,11 +1714,11 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
}
}
if (DT_DATATYPE_IS_POLY(dtdata_type)) {
- MVert *verts_dst = me_dst->mvert;
+ const MVert *verts_dst = BKE_mesh_vertices(me_dst);
const int num_verts_dst = me_dst->totvert;
- MPoly *polys_dst = me_dst->mpoly;
+ const MPoly *polys_dst = BKE_mesh_polygons(me_dst);
const int num_polys_dst = me_dst->totpoly;
- MLoop *loops_dst = me_dst->mloop;
+ const MLoop *loops_dst = BKE_mesh_loops(me_dst);
const int num_loops_dst = me_dst->totloop;
if (!geom_map_init[PDATA]) {
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index d904744995d..f928079f3ea 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -1030,7 +1030,7 @@ void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
const int defgroup,
const int num_verts,
- MEdge *edges,
+ const MEdge *edges,
const int num_edges,
const bool invert_vgroup,
float *r_weights)
@@ -1043,7 +1043,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
while (i--) {
- MEdge *me = &edges[i];
+ const MEdge *me = &edges[i];
r_weights[i] = (tmp_weights[me->v1] + tmp_weights[me->v2]) * 0.5f;
}
@@ -1058,7 +1058,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
const int defgroup,
const int num_verts,
- MLoop *loops,
+ const MLoop *loops,
const int num_loops,
const bool invert_vgroup,
float *r_weights)
@@ -1071,7 +1071,7 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
while (i--) {
- MLoop *ml = &loops[i];
+ const MLoop *ml = &loops[i];
r_weights[i] = tmp_weights[ml->v];
}
@@ -1086,9 +1086,9 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert,
void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
const int defgroup,
const int num_verts,
- MLoop *loops,
+ const MLoop *loops,
const int UNUSED(num_loops),
- MPoly *polys,
+ const MPoly *polys,
const int num_polys,
const bool invert_vgroup,
float *r_weights)
@@ -1101,8 +1101,8 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert,
dvert, defgroup, num_verts, invert_vgroup, tmp_weights);
while (i--) {
- MPoly *mp = &polys[i];
- MLoop *ml = &loops[mp->loopstart];
+ const MPoly *mp = &polys[i];
+ const MLoop *ml = &loops[mp->loopstart];
int j = mp->totloop;
float w = 0.0f;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 8a41b2294f5..9c09ebb6973 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -1402,24 +1402,24 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
/* For vertex format, count every vertex that is connected by an edge */
int numOfEdges = mesh->totedge;
int numOfPolys = mesh->totpoly;
- struct MEdge *edge = mesh->medge;
- struct MPoly *mpoly = mesh->mpoly;
- struct MLoop *mloop = mesh->mloop;
+ const MEdge *edges = BKE_mesh_edges(mesh);
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
/* count number of edges per vertex */
for (int i = 0; i < numOfEdges; i++) {
- ad->n_num[edge[i].v1]++;
- ad->n_num[edge[i].v2]++;
+ ad->n_num[edges[i].v1]++;
+ ad->n_num[edges[i].v2]++;
- temp_data[edge[i].v1]++;
- temp_data[edge[i].v2]++;
+ temp_data[edges[i].v1]++;
+ temp_data[edges[i].v2]++;
}
/* also add number of vertices to temp_data
* to locate points on "mesh edge" */
for (int i = 0; i < numOfPolys; i++) {
- for (int j = 0; j < mpoly[i].totloop; j++) {
- temp_data[mloop[mpoly[i].loopstart + j].v]++;
+ for (int j = 0; j < polys[i].totloop; j++) {
+ temp_data[loops[polys[i].loopstart + j].v]++;
}
}
@@ -1444,15 +1444,15 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
/* and now add neighbor data using that info */
for (int i = 0; i < numOfEdges; i++) {
/* first vertex */
- int index = edge[i].v1;
+ int index = edges[i].v1;
n_pos = ad->n_index[index] + temp_data[index];
- ad->n_target[n_pos] = edge[i].v2;
+ ad->n_target[n_pos] = edges[i].v2;
temp_data[index]++;
/* second vertex */
- index = edge[i].v2;
+ index = edges[i].v2;
n_pos = ad->n_index[index] + temp_data[index];
- ad->n_target[n_pos] = edge[i].v1;
+ ad->n_target[n_pos] = edges[i].v1;
temp_data[index]++;
}
}
@@ -1604,7 +1604,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
Tex *tex = surface->init_texture;
- const MLoop *mloop = mesh->mloop;
+ const MLoop *mloop = BKE_mesh_loops(mesh);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
@@ -1660,7 +1660,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* for vertex surface, just copy colors from mcol */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
- const MLoop *mloop = mesh->mloop;
+ const MLoop *mloop = BKE_mesh_loops(mesh);
const int totloop = mesh->totloop;
const MLoopCol *col = CustomData_get_layer_named(
&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername);
@@ -1811,7 +1811,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh
/* displace paint */
if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
- MVert *mvert = result->mvert;
+ MVert *mvert = BKE_mesh_vertices_for_write(result);
DynamicPaintModifierApplyData data = {
.surface = surface,
@@ -1913,9 +1913,9 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
/* vertex color paint */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
- MLoop *mloop = result->mloop;
+ const MLoop *mloop = BKE_mesh_loops(result);
const int totloop = result->totloop;
- MPoly *mpoly = result->mpoly;
+ const MPoly *mpoly = BKE_mesh_polygons(result);
const int totpoly = result->totpoly;
/* paint is stored on dry and wet layers, so mix final color first */
@@ -1989,8 +1989,6 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) {
dvert = CustomData_add_layer(
&result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, sData->total_points);
- /* Make the dvert layer easily accessible from the mesh data. */
- result->dvert = dvert;
}
if (defgrp_index != -1 && dvert) {
for (int i = 0; i < sData->total_points; i++) {
@@ -2012,7 +2010,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
/* wave simulation */
else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
- MVert *mvert = result->mvert;
+ MVert *mvert = BKE_mesh_vertices_for_write(result);
DynamicPaintModifierApplyData data = {
.surface = surface,
@@ -2823,7 +2821,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
return setError(canvas, N_("Cannot bake non-'image sequence' formats"));
}
- mloop = mesh->mloop;
+ mloop = BKE_mesh_loops(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
@@ -2963,7 +2961,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map,
&vert_to_looptri_map_mem,
- mesh->mvert,
+ BKE_mesh_vertices_for_write(mesh),
mesh->totvert,
mlooptri,
tottri,
@@ -3783,7 +3781,8 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
eModifierType_DynamicPaint);
mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false);
numOfVerts_p = mesh_p->totvert;
- mvert_p = mesh_p->mvert;
+
+ mvert_p = BKE_mesh_vertices_for_write(mesh_p);
copy_m4_m4(prev_obmat, ob->obmat);
/* current frame mesh */
@@ -3799,7 +3798,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph,
eModifierType_DynamicPaint);
mesh_c = dynamicPaint_brush_mesh_get(brush);
numOfVerts_c = mesh_c->totvert;
- mvert_c = mesh_c->mvert;
+ mvert_c = BKE_mesh_vertices_for_write(mesh_c);
(*brushVel) = (struct Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f),
"Dynamic Paint brush velocity");
@@ -4270,10 +4269,10 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
VolumeGrid *grid = bData->grid;
mesh = BKE_mesh_copy_for_eval(brush_mesh, false);
- mvert = mesh->mvert;
+ mvert = BKE_mesh_vertices_for_write(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
- mloop = mesh->mloop;
+ mloop = BKE_mesh_loops(mesh);
numOfVerts = mesh->totvert;
/* Transform collider vertices to global space
@@ -4759,7 +4758,7 @@ static bool dynamicPaint_paintSinglePoint(
}
const Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush);
- const MVert *mvert = brush_mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(brush_mesh);
/*
* Loop through every surface point
@@ -5862,7 +5861,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
Mesh *mesh = dynamicPaint_canvas_mesh_get(surface->canvas);
- MVert *mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
int numOfVerts = mesh->totvert;
@@ -6022,7 +6021,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface,
const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0;
int canvasNumOfVerts = mesh->totvert;
- MVert *mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
Vec3f *canvas_verts;
if (bData) {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 7722c2fa004..f2fce3edb88 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -700,9 +700,10 @@ bool get_effector_data(EffectorCache *eff,
else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) {
/* TODO: hair and points object support */
const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob);
+ const MVert *verts = BKE_mesh_vertices(me_eval);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval);
if (me_eval != NULL) {
- copy_v3_v3(efd->loc, me_eval->mvert[*efd->index].co);
+ copy_v3_v3(efd->loc, verts[*efd->index].co);
copy_v3_v3(efd->nor, vert_normals[*efd->index]);
mul_m4_v3(eff->ob->obmat, efd->loc);
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 74ff10cc32c..24c61a792eb 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -403,7 +403,8 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds,
size_t i;
float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
float size[3];
- MVert *verts = me->mvert;
+
+ MVert *verts = BKE_mesh_vertices_for_write(me);
float scale = 0.0;
int res;
@@ -994,9 +995,7 @@ static void obstacles_from_mesh(Object *coll_ob,
{
if (fes->mesh) {
Mesh *me = NULL;
- MVert *mvert = NULL;
const MLoopTri *looptri;
- const MLoop *mloop;
BVHTreeFromMesh tree_data = {NULL};
int numverts, i;
@@ -1008,13 +1007,9 @@ static void obstacles_from_mesh(Object *coll_ob,
int min[3], max[3], res[3];
/* Duplicate vertices to modify. */
- if (me->mvert) {
- me->mvert = MEM_dupallocN(me->mvert);
- CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
- }
+ MVert *verts = MEM_dupallocN(BKE_mesh_vertices(me));
- mvert = me->mvert;
- mloop = me->mloop;
+ const MLoop *mloop = BKE_mesh_loops(me);
looptri = BKE_mesh_runtime_looptri_ensure(me);
numverts = me->totvert;
@@ -1041,11 +1036,11 @@ static void obstacles_from_mesh(Object *coll_ob,
float co[3];
/* Vertex position. */
- mul_m4_v3(coll_ob->obmat, mvert[i].co);
- manta_pos_to_cell(fds, mvert[i].co);
+ mul_m4_v3(coll_ob->obmat, verts[i].co);
+ manta_pos_to_cell(fds, verts[i].co);
/* Vertex velocity. */
- add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift);
+ add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift);
if (has_velocity) {
sub_v3_v3v3(&vert_vel[i * 3], co, &fes->verts_old[i * 3]);
mul_v3_fl(&vert_vel[i * 3], 1.0f / dt);
@@ -1053,7 +1048,7 @@ static void obstacles_from_mesh(Object *coll_ob,
copy_v3_v3(&fes->verts_old[i * 3], co);
/* Calculate emission map bounds. */
- bb_boundInsert(bb, mvert[i].co);
+ bb_boundInsert(bb, verts[i].co);
}
/* Set emission map.
@@ -1075,7 +1070,7 @@ static void obstacles_from_mesh(Object *coll_ob,
ObstaclesFromDMData data = {
.fes = fes,
- .mvert = mvert,
+ .mvert = verts,
.mloop = mloop,
.mlooptri = looptri,
.tree = &tree_data,
@@ -1098,9 +1093,7 @@ static void obstacles_from_mesh(Object *coll_ob,
if (vert_vel) {
MEM_freeN(vert_vel);
}
- if (me->mvert) {
- MEM_freeN(me->mvert);
- }
+ MEM_SAFE_FREE(verts);
BKE_id_free(NULL, me);
}
}
@@ -2080,16 +2073,12 @@ static void emit_from_mesh(
Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, true);
/* Duplicate vertices to modify. */
- if (me->mvert) {
- me->mvert = MEM_dupallocN(me->mvert);
- CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
- }
+ MVert *verts = MEM_dupallocN(BKE_mesh_vertices(me));
- MVert *mvert = me->mvert;
- const MLoop *mloop = me->mloop;
+ const MLoop *mloop = BKE_mesh_loops(me);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me);
const int numverts = me->totvert;
- const MDeformVert *dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
+ const MDeformVert *dvert = BKE_mesh_deform_verts(me);
const MLoopUV *mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ffs->uvlayer_name);
if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
@@ -2109,12 +2098,11 @@ static void emit_from_mesh(
/* Transform mesh vertices to domain grid space for fast lookups.
* This is valid because the mesh is copied above. */
- BKE_mesh_vertex_normals_ensure(me);
- float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me);
+ float(*vert_normals)[3] = MEM_dupallocN(BKE_mesh_vertex_normals_ensure(me));
for (i = 0; i < numverts; i++) {
/* Vertex position. */
- mul_m4_v3(flow_ob->obmat, mvert[i].co);
- manta_pos_to_cell(fds, mvert[i].co);
+ mul_m4_v3(flow_ob->obmat, verts[i].co);
+ manta_pos_to_cell(fds, verts[i].co);
/* Vertex normal. */
mul_mat3_m4_v3(flow_ob->obmat, vert_normals[i]);
@@ -2124,7 +2112,7 @@ static void emit_from_mesh(
/* Vertex velocity. */
if (ffs->flags & FLUID_FLOW_INITVELOCITY) {
float co[3];
- add_v3fl_v3fl_v3i(co, mvert[i].co, fds->shift);
+ add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift);
if (has_velocity) {
sub_v3_v3v3(&vert_vel[i * 3], co, &ffs->verts_old[i * 3]);
mul_v3_fl(&vert_vel[i * 3], 1.0 / dt);
@@ -2133,7 +2121,7 @@ static void emit_from_mesh(
}
/* Calculate emission map bounds. */
- bb_boundInsert(bb, mvert[i].co);
+ bb_boundInsert(bb, verts[i].co);
}
mul_m4_v3(flow_ob->obmat, flow_center);
manta_pos_to_cell(fds, flow_center);
@@ -2158,7 +2146,7 @@ static void emit_from_mesh(
EmitFromDMData data = {
.fds = fds,
.ffs = ffs,
- .mvert = mvert,
+ .mvert = verts,
.vert_normals = vert_normals,
.mloop = mloop,
.mlooptri = mlooptri,
@@ -2186,9 +2174,8 @@ static void emit_from_mesh(
if (vert_vel) {
MEM_freeN(vert_vel);
}
- if (me->mvert) {
- MEM_freeN(me->mvert);
- }
+ MEM_SAFE_FREE(verts);
+ MEM_SAFE_FREE(vert_normals);
BKE_id_free(NULL, me);
}
}
@@ -3241,7 +3228,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
* If there are no faces in original mesh, keep materials and flags unchanged. */
MPoly *mpoly;
MPoly mp_example = {0};
- mpoly = orgmesh->mpoly;
+ mpoly = BKE_mesh_polygons_for_write(orgmesh);
if (mpoly) {
mp_example = *mpoly;
}
@@ -3273,9 +3260,9 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
if (!me) {
return NULL;
}
- mverts = me->mvert;
- mpolys = me->mpoly;
- mloops = me->mloop;
+ mverts = BKE_mesh_vertices_for_write(me);
+ mpolys = BKE_mesh_polygons_for_write(me);
+ mloops = BKE_mesh_loops_for_write(me);
/* Get size (dimension) but considering scaling. */
copy_v3_v3(cell_size_scaled, fds->cell_size);
@@ -3409,9 +3396,9 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
}
result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces);
- mverts = result->mvert;
- mpolys = result->mpoly;
- mloops = result->mloop;
+ mverts = BKE_mesh_vertices_for_write(result);
+ mpolys = BKE_mesh_polygons_for_write(result);
+ mloops = BKE_mesh_loops_for_write(result);
if (num_verts) {
/* Volume bounds. */
diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc
index ff55409d5fc..f5f667a02eb 100644
--- a/source/blender/blenkernel/intern/geometry_component_mesh.cc
+++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc
@@ -134,8 +134,8 @@ VArray<float3> mesh_normals_varray(const Mesh &mesh,
* instead of the GeometryComponent API to avoid calculating unnecessary values and to
* allow normalizing the result more simply. */
Span<float3> vert_normals{(float3 *)BKE_mesh_vertex_normals_ensure(&mesh), mesh.totvert};
+ const Span<MEdge> edges = mesh.edges();
Array<float3> edge_normals(mask.min_array_size());
- Span<MEdge> edges{mesh.medge, mesh.totedge};
for (const int i : mask) {
const MEdge &edge = edges[i];
edge_normals[i] = math::normalize(
@@ -175,11 +175,13 @@ static void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
+ const Span<MLoop> loops = mesh.loops();
+
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int loop_index : IndexRange(mesh.totloop)) {
const T value = old_values[loop_index];
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const int point_index = loop.v;
mixer.mix_in(point_index, value);
}
@@ -193,11 +195,13 @@ void adapt_mesh_domain_corner_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
+ const Span<MLoop> loops = mesh.loops();
+
Array<bool> loose_verts(mesh.totvert, true);
r_values.fill(true);
for (const int loop_index : IndexRange(mesh.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const int point_index = loop.v;
loose_verts[point_index] = false;
@@ -235,12 +239,14 @@ static GVArray adapt_mesh_domain_corner_to_point(const Mesh &mesh, const GVArray
*/
static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray &varray)
{
+ const Span<MLoop> loops = mesh.loops();
+
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
new_varray = VArray<T>::ForFunc(mesh.totloop,
- [&mesh, varray = varray.typed<T>()](const int64_t loop_index) {
- const int vertex_index = mesh.mloop[loop_index].v;
+ [loops, varray = varray.typed<T>()](const int64_t loop_index) {
+ const int vertex_index = loops[loop_index].v;
return varray[vertex_index];
});
});
@@ -249,15 +255,17 @@ static GVArray adapt_mesh_domain_point_to_corner(const Mesh &mesh, const GVArray
static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray &varray)
{
+ const Span<MPoly> polys = mesh.polygons();
+
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
if constexpr (std::is_same_v<T, bool>) {
new_varray = VArray<T>::ForFunc(
- mesh.totpoly, [&mesh, varray = varray.typed<bool>()](const int face_index) {
+ polys.size(), [polys, varray = varray.typed<bool>()](const int face_index) {
/* A face is selected if all of its corners were selected. */
- const MPoly &poly = mesh.mpoly[face_index];
+ const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
if (!varray[loop_index]) {
return false;
@@ -268,10 +276,10 @@ static GVArray adapt_mesh_domain_corner_to_face(const Mesh &mesh, const GVArray
}
else {
new_varray = VArray<T>::ForFunc(
- mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
+ polys.size(), [polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
- const MPoly &poly = mesh.mpoly[face_index];
+ const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const T value = varray[loop_index];
mixer.mix_in(0, value);
@@ -291,17 +299,20 @@ static void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
+
attribute_math::DefaultMixer<T> mixer(r_values);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
/* For every edge, mix values from the two adjacent corners (the current and next corner). */
for (const int i : IndexRange(poly.totloop)) {
const int next_i = (i + 1) % poly.totloop;
const int loop_i = poly.loopstart + i;
const int next_loop_i = poly.loopstart + next_i;
- const MLoop &loop = mesh.mloop[loop_i];
+ const MLoop &loop = loops[loop_i];
const int edge_index = loop.e;
mixer.mix_in(edge_index, old_values[loop_i]);
mixer.mix_in(edge_index, old_values[next_loop_i]);
@@ -318,19 +329,21 @@ void adapt_mesh_domain_corner_to_edge_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
/* It may be possible to rely on the #ME_LOOSEEDGE flag, but that seems error-prone. */
Array<bool> loose_edges(mesh.totedge, true);
r_values.fill(true);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
for (const int i : IndexRange(poly.totloop)) {
const int next_i = (i + 1) % poly.totloop;
const int loop_i = poly.loopstart + i;
const int next_loop_i = poly.loopstart + next_i;
- const MLoop &loop = mesh.mloop[loop_i];
+ const MLoop &loop = loops[loop_i];
const int edge_index = loop.e;
loose_edges[edge_index] = false;
@@ -371,13 +384,16 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
+
attribute_math::DefaultMixer<T> mixer(r_values);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
const T value = old_values[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const int point_index = loop.v;
mixer.mix_in(point_index, value);
}
@@ -393,13 +409,15 @@ void adapt_mesh_domain_face_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const int vert_index = loop.v;
r_values[vert_index] = true;
}
@@ -428,10 +446,11 @@ void adapt_mesh_domain_face_to_corner_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
+ const Span<MPoly> polys = mesh.polygons();
- threading::parallel_for(IndexRange(mesh.totpoly), 1024, [&](const IndexRange range) {
+ threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) {
for (const int poly_index : range) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ const MPoly &poly = polys[poly_index];
MutableSpan<T> poly_corner_values = r_values.slice(poly.loopstart, poly.totloop);
poly_corner_values.fill(old_values[poly_index]);
}
@@ -458,13 +477,16 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
+
attribute_math::DefaultMixer<T> mixer(r_values);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
const T value = old_values[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
mixer.mix_in(loop.e, value);
}
}
@@ -478,13 +500,15 @@ void adapt_mesh_domain_face_to_edge_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totedge);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
if (old_values[poly_index]) {
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const int edge_index = loop.e;
r_values[edge_index] = true;
}
@@ -508,17 +532,20 @@ static GVArray adapt_mesh_domain_face_to_edge(const Mesh &mesh, const GVArray &v
static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &varray)
{
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
+
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
if constexpr (!std::is_void_v<attribute_math::DefaultMixer<T>>) {
if constexpr (std::is_same_v<T, bool>) {
new_varray = VArray<T>::ForFunc(
- mesh.totpoly, [&mesh, varray = varray.typed<bool>()](const int face_index) {
+ mesh.totpoly, [loops, polys, varray = varray.typed<bool>()](const int face_index) {
/* A face is selected if all of its vertices were selected. */
- const MPoly &poly = mesh.mpoly[face_index];
+ const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
if (!varray[loop.v]) {
return false;
}
@@ -528,12 +555,12 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &
}
else {
new_varray = VArray<T>::ForFunc(
- mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
+ mesh.totpoly, [loops, polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
- const MPoly &poly = mesh.mpoly[face_index];
+ const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const T value = varray[loop.v];
mixer.mix_in(0, value);
}
@@ -548,6 +575,8 @@ static GVArray adapt_mesh_domain_point_to_face(const Mesh &mesh, const GVArray &
static GVArray adapt_mesh_domain_point_to_edge(const Mesh &mesh, const GVArray &varray)
{
+ const Span<MEdge> edges = mesh.edges();
+
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
@@ -555,17 +584,17 @@ static GVArray adapt_mesh_domain_point_to_edge(const Mesh &mesh, const GVArray &
if constexpr (std::is_same_v<T, bool>) {
/* An edge is selected if both of its vertices were selected. */
new_varray = VArray<bool>::ForFunc(
- mesh.totedge, [&mesh, varray = varray.typed<bool>()](const int edge_index) {
- const MEdge &edge = mesh.medge[edge_index];
+ edges.size(), [edges, varray = varray.typed<bool>()](const int edge_index) {
+ const MEdge &edge = edges[edge_index];
return varray[edge.v1] && varray[edge.v2];
});
}
else {
new_varray = VArray<T>::ForFunc(
- mesh.totedge, [&mesh, varray = varray.typed<T>()](const int edge_index) {
+ edges.size(), [edges, varray = varray.typed<T>()](const int edge_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
- const MEdge &edge = mesh.medge[edge_index];
+ const MEdge &edge = edges[edge_index];
mixer.mix_in(0, varray[edge.v1]);
mixer.mix_in(0, varray[edge.v2]);
mixer.finalize();
@@ -583,16 +612,19 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
+
attribute_math::DefaultMixer<T> mixer(r_values);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
/* For every corner, mix the values from the adjacent edges on the face. */
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
- const MLoop &loop = mesh.mloop[loop_index];
- const MLoop &loop_prev = mesh.mloop[loop_index_prev];
+ const MLoop &loop = loops[loop_index];
+ const MLoop &loop_prev = loops[loop_index_prev];
mixer.mix_in(loop_index, old_values[loop.e]);
mixer.mix_in(loop_index, old_values[loop_prev.e]);
}
@@ -608,15 +640,17 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totloop);
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
r_values.fill(false);
- for (const int poly_index : IndexRange(mesh.totpoly)) {
- const MPoly &poly = mesh.mpoly[poly_index];
+ for (const int poly_index : polys.index_range()) {
+ const MPoly &poly = polys[poly_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
const int loop_index_prev = loop_index - 1 + (loop_index == poly.loopstart) * poly.totloop;
- const MLoop &loop = mesh.mloop[loop_index];
- const MLoop &loop_prev = mesh.mloop[loop_index_prev];
+ const MLoop &loop = loops[loop_index];
+ const MLoop &loop_prev = loops[loop_index_prev];
if (old_values[loop.e] && old_values[loop_prev.e]) {
r_values[loop_index] = true;
}
@@ -644,10 +678,12 @@ static void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
MutableSpan<T> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
+ const Span<MEdge> edges = mesh.edges();
+
attribute_math::DefaultMixer<T> mixer(r_values);
for (const int edge_index : IndexRange(mesh.totedge)) {
- const MEdge &edge = mesh.medge[edge_index];
+ const MEdge &edge = edges[edge_index];
const T value = old_values[edge_index];
mixer.mix_in(edge.v1, value);
mixer.mix_in(edge.v2, value);
@@ -663,10 +699,11 @@ void adapt_mesh_domain_edge_to_point_impl(const Mesh &mesh,
MutableSpan<bool> r_values)
{
BLI_assert(r_values.size() == mesh.totvert);
+ const Span<MEdge> edges = mesh.edges();
r_values.fill(false);
- for (const int edge_index : IndexRange(mesh.totedge)) {
- const MEdge &edge = mesh.medge[edge_index];
+ for (const int edge_index : edges.index_range()) {
+ const MEdge &edge = edges[edge_index];
if (old_values[edge_index]) {
r_values[edge.v1] = true;
r_values[edge.v2] = true;
@@ -690,6 +727,9 @@ static GVArray adapt_mesh_domain_edge_to_point(const Mesh &mesh, const GVArray &
static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &varray)
{
+ const Span<MPoly> polys = mesh.polygons();
+ const Span<MLoop> loops = mesh.loops();
+
GVArray new_varray;
attribute_math::convert_to_static_type(varray.type(), [&](auto dummy) {
using T = decltype(dummy);
@@ -697,10 +737,10 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
if constexpr (std::is_same_v<T, bool>) {
/* A face is selected if all of its edges are selected. */
new_varray = VArray<bool>::ForFunc(
- mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
- const MPoly &poly = mesh.mpoly[face_index];
+ polys.size(), [loops, polys, varray = varray.typed<T>()](const int face_index) {
+ const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
if (!varray[loop.e]) {
return false;
}
@@ -710,12 +750,12 @@ static GVArray adapt_mesh_domain_edge_to_face(const Mesh &mesh, const GVArray &v
}
else {
new_varray = VArray<T>::ForFunc(
- mesh.totpoly, [&mesh, varray = varray.typed<T>()](const int face_index) {
+ polys.size(), [loops, polys, varray = varray.typed<T>()](const int face_index) {
T return_value;
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
- const MPoly &poly = mesh.mpoly[face_index];
+ const MPoly &poly = polys[face_index];
for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) {
- const MLoop &loop = mesh.mloop[loop_index];
+ const MLoop &loop = loops[loop_index];
const T value = varray[loop.e];
mixer.mix_in(0, value);
}
@@ -878,8 +918,15 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
const int dvert_index_;
public:
- VArrayImpl_For_VertexWeights(MDeformVert *dverts, const int totvert, const int dvert_index)
- : VMutableArrayImpl<float>(totvert), dverts_(dverts), dvert_index_(dvert_index)
+ VArrayImpl_For_VertexWeights(MutableSpan<MDeformVert> dverts, const int dvert_index)
+ : VMutableArrayImpl<float>(dverts.size()), dverts_(dverts.data()), dvert_index_(dvert_index)
+ {
+ }
+
+ VArrayImpl_For_VertexWeights(Span<MDeformVert> dverts, const int dvert_index)
+ : VMutableArrayImpl<float>(dverts.size()),
+ dverts_(const_cast<MDeformVert *>(dverts.data())),
+ dvert_index_(dvert_index)
{
}
@@ -977,12 +1024,12 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
if (vertex_group_index < 0) {
return {};
}
- if (mesh->dvert == nullptr) {
+ const Span<MDeformVert> dverts = mesh->deform_verts();
+ if (dverts.is_empty()) {
static const float default_value = 0.0f;
return {VArray<float>::ForSingle(default_value, mesh->totvert), ATTR_DOMAIN_POINT};
}
- return {VArray<float>::For<VArrayImpl_For_VertexWeights>(
- mesh->dvert, mesh->totvert, vertex_group_index),
+ return {VArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, vertex_group_index),
ATTR_DOMAIN_POINT};
}
@@ -1002,16 +1049,8 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
if (vertex_group_index < 0) {
return {};
}
- if (mesh->dvert == nullptr) {
- BKE_object_defgroup_data_create(&mesh->id);
- }
- else {
- /* Copy the data layer if it is shared with some other mesh. */
- mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
- &mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
- }
- return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(
- mesh->dvert, mesh->totvert, vertex_group_index),
+ MutableSpan<MDeformVert> dverts = mesh->deform_verts_for_write();
+ return {VMutableArray<float>::For<VArrayImpl_For_VertexWeights>(dverts, vertex_group_index),
ATTR_DOMAIN_POINT};
}
@@ -1034,15 +1073,11 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
}
BLI_remlink(&mesh->vertex_group_names, group);
MEM_freeN(group);
- if (mesh->dvert == nullptr) {
+ if (mesh->deform_verts().is_empty()) {
return true;
}
- /* Copy the data layer if it is shared with some other mesh. */
- mesh->dvert = (MDeformVert *)CustomData_duplicate_referenced_layer(
- &mesh->vdata, CD_MDEFORMVERT, mesh->totvert);
-
- for (MDeformVert &dvert : MutableSpan(mesh->dvert, mesh->totvert)) {
+ for (MDeformVert &dvert : mesh->deform_verts_for_write()) {
MDeformWeight *weight = BKE_defvert_find_index(&dvert, index);
BKE_defvert_remove_group(&dvert, weight);
for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) {
@@ -1123,10 +1158,7 @@ class NormalAttributeProvider final : public BuiltinAttributeProvider {
*/
static ComponentAttributeProviders create_attribute_providers_for_mesh()
{
- static auto update_custom_data_pointers = [](void *owner) {
- Mesh *mesh = static_cast<Mesh *>(owner);
- BKE_mesh_update_customdata_pointers(mesh, false);
- };
+ static auto update_custom_data_pointers = [](void * /*owner*/) {};
#define MAKE_MUTABLE_CUSTOM_DATA_GETTER(NAME) \
[](void *owner) -> CustomData * { \
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index 0a75b0f5339..9f231c8f5f2 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -2464,6 +2464,9 @@ static void gpencil_generate_edgeloops(Object *ob,
if (me->totedge == 0) {
return;
}
+ const Span<MVert> verts = me->vertices();
+ const Span<MEdge> edges = me->edges();
+ const Span<MDeformVert> dverts = me->deform_verts();
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me);
/* Arrays for all edge vertices (forward and backward) that form a edge loop.
@@ -2476,15 +2479,15 @@ static void gpencil_generate_edgeloops(Object *ob,
GpEdge *gp_edges = (GpEdge *)MEM_callocN(sizeof(GpEdge) * me->totedge, __func__);
GpEdge *gped = nullptr;
for (int i = 0; i < me->totedge; i++) {
- MEdge *ed = &me->medge[i];
+ const MEdge *ed = &edges[i];
gped = &gp_edges[i];
- MVert *mv1 = &me->mvert[ed->v1];
+ const MVert *mv1 = &verts[ed->v1];
copy_v3_v3(gped->n1, vert_normals[ed->v1]);
gped->v1 = ed->v1;
copy_v3_v3(gped->v1_co, mv1->co);
- MVert *mv2 = &me->mvert[ed->v2];
+ const MVert *mv2 = &verts[ed->v2];
copy_v3_v3(gped->n2, vert_normals[ed->v2]);
gped->v2 = ed->v2;
copy_v3_v3(gped->v2_co, mv2->co);
@@ -2540,8 +2543,7 @@ static void gpencil_generate_edgeloops(Object *ob,
gpf_stroke, MAX2(stroke_mat_index, 0), array_len + 1, thickness * thickness, false);
/* Create dvert data. */
- MDeformVert *me_dvert = me->dvert;
- if (use_vgroups && me_dvert) {
+ if (use_vgroups && !dverts.is_empty()) {
gps_stroke->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * (array_len + 1),
"gp_stroke_dverts");
}
@@ -2550,7 +2552,7 @@ static void gpencil_generate_edgeloops(Object *ob,
float fpt[3];
for (int i = 0; i < array_len + 1; i++) {
int vertex_index = i == 0 ? gp_edges[stroke[0]].v1 : gp_edges[stroke[i - 1]].v2;
- MVert *mv = &me->mvert[vertex_index];
+ const MVert *mv = &verts[vertex_index];
/* Add segment. */
bGPDspoint *pt = &gps_stroke->points[i];
@@ -2563,9 +2565,9 @@ static void gpencil_generate_edgeloops(Object *ob,
pt->strength = 1.0f;
/* Copy vertex groups from mesh. Assuming they already exist in the same order. */
- if (use_vgroups && me_dvert) {
+ if (use_vgroups && !dverts.is_empty()) {
MDeformVert *dv = &gps_stroke->dvert[i];
- MDeformVert *src_dv = &me_dvert[vertex_index];
+ const MDeformVert *src_dv = &dverts[vertex_index];
dv->totweight = src_dv->totweight;
dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
"gp_stroke_dverts_dw");
@@ -2674,8 +2676,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
/* Use evaluated data to get mesh with all modifiers on top. */
Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh);
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
- const MPoly *mpoly = me_eval->mpoly;
- const MLoop *mloop = me_eval->mloop;
+ const Span<MVert> verts = me_eval->vertices();
+ const Span<MPoly> polys = me_eval->polygons();
+ const Span<MLoop> loops = me_eval->loops();
int mpoly_len = me_eval->totpoly;
char element_name[200];
@@ -2715,7 +2718,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
const VArray<int> mesh_material_indices = mesh_attributes(*me_eval).lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
for (i = 0; i < mpoly_len; i++) {
- const MPoly *mp = &mpoly[i];
+ const MPoly *mp = &polys[i];
/* Find material. */
int mat_idx = 0;
@@ -2739,16 +2742,16 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
gps_fill->flag |= GP_STROKE_CYCLIC;
/* Create dvert data. */
- MDeformVert *me_dvert = me_eval->dvert;
- if (use_vgroups && me_dvert) {
+ const Span<MDeformVert> dverts = me_eval->deform_verts();
+ if (use_vgroups && !dverts.is_empty()) {
gps_fill->dvert = (MDeformVert *)MEM_callocN(sizeof(MDeformVert) * mp->totloop,
"gp_fill_dverts");
}
/* Add points to strokes. */
for (int j = 0; j < mp->totloop; j++) {
- const MLoop *ml = &mloop[mp->loopstart + j];
- const MVert *mv = &me_eval->mvert[ml->v];
+ const MLoop *ml = &loops[mp->loopstart + j];
+ const MVert *mv = &verts[ml->v];
bGPDspoint *pt = &gps_fill->points[j];
copy_v3_v3(&pt->x, mv->co);
@@ -2757,9 +2760,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain,
pt->strength = 1.0f;
/* Copy vertex groups from mesh. Assuming they already exist in the same order. */
- if (use_vgroups && me_dvert) {
+ if (use_vgroups && !dverts.is_empty()) {
MDeformVert *dv = &gps_fill->dvert[j];
- MDeformVert *src_dv = &me_dvert[ml->v];
+ const MDeformVert *src_dv = &dverts[ml->v];
dv->totweight = src_dv->totweight;
dv->dw = (MDeformWeight *)MEM_callocN(sizeof(MDeformWeight) * dv->totweight,
"gp_fill_dverts_dw");
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 461a6f15ca1..a09f1e70d06 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1258,7 +1258,7 @@ static void do_key(const int start,
static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cache)
{
- MDeformVert *dvert = NULL;
+ const MDeformVert *dvert = NULL;
BMEditMesh *em = NULL;
BMIter iter;
BMVert *eve;
@@ -1272,7 +1272,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac
/* gather dvert and totvert */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
- dvert = me->dvert;
+ dvert = BKE_mesh_deform_verts(me);
totvert = me->totvert;
if (me->edit_mesh && me->edit_mesh->bm->totvert == totvert) {
@@ -1602,8 +1602,9 @@ float *BKE_key_evaluate_object_ex(
switch (GS(obdata->name)) {
case ID_ME: {
Mesh *mesh = (Mesh *)obdata;
+ MVert *verts = BKE_mesh_vertices_for_write(mesh);
const int totvert = min_ii(tot, mesh->totvert);
- keyblock_data_convert_to_mesh((const float(*)[3])out, mesh->mvert, totvert);
+ keyblock_data_convert_to_mesh((const float(*)[3])out, verts, totvert);
break;
}
case ID_LT: {
@@ -2168,7 +2169,6 @@ void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nu
void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb)
{
- MVert *mvert;
float(*fp)[3];
int a, tot;
@@ -2179,7 +2179,7 @@ void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb)
return;
}
- mvert = me->mvert;
+ const MVert *mvert = BKE_mesh_vertices(me);
fp = kb->data;
for (a = 0; a < tot; a++, fp++, mvert++) {
copy_v3_v3(*fp, mvert->co);
@@ -2227,8 +2227,11 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
return;
}
- MVert *mvert = MEM_dupallocN(mesh->mvert);
- BKE_keyblock_convert_to_mesh(kb, mvert, mesh->totvert);
+ MVert *verts = MEM_dupallocN(BKE_mesh_vertices(mesh));
+ BKE_keyblock_convert_to_mesh(kb, verts, mesh->totvert);
+ const MEdge *edges = BKE_mesh_edges(mesh);
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
const bool loop_normals_needed = r_loopnors != NULL;
const bool vert_normals_needed = r_vertnors != NULL || loop_normals_needed;
@@ -2249,35 +2252,30 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
}
if (poly_normals_needed) {
- BKE_mesh_calc_normals_poly(mvert,
- mesh->totvert,
- mesh->mloop,
- mesh->totloop,
- mesh->mpoly,
- mesh->totpoly,
- poly_normals);
+ BKE_mesh_calc_normals_poly(
+ verts, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals);
}
if (vert_normals_needed) {
- BKE_mesh_calc_normals_poly_and_vertex(mvert,
+ BKE_mesh_calc_normals_poly_and_vertex(verts,
mesh->totvert,
- mesh->mloop,
+ loops,
mesh->totloop,
- mesh->mpoly,
+ polys,
mesh->totpoly,
poly_normals,
vert_normals);
}
if (loop_normals_needed) {
short(*clnors)[2] = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* May be NULL. */
- BKE_mesh_normals_loop_split(mvert,
+ BKE_mesh_normals_loop_split(verts,
vert_normals,
mesh->totvert,
- mesh->medge,
+ edges,
mesh->totedge,
- mesh->mloop,
+ loops,
r_loopnors,
mesh->totloop,
- mesh->mpoly,
+ polys,
poly_normals,
mesh->totpoly,
(mesh->flag & ME_AUTOSMOOTH) != 0,
@@ -2293,7 +2291,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb,
if (free_poly_normals) {
MEM_freeN(poly_normals);
}
- MEM_freeN(mvert);
+ MEM_freeN(verts);
}
/************************* raw coords ************************/
diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c
index 40a9d4befdb..3a1c42b9178 100644
--- a/source/blender/blenkernel/intern/lattice_deform.c
+++ b/source/blender/blenkernel/intern/lattice_deform.c
@@ -30,6 +30,7 @@
#include "BKE_editmesh.h"
#include "BKE_key.h"
#include "BKE_lattice.h"
+#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
@@ -363,7 +364,7 @@ static void lattice_deform_coords_impl(const Object *ob_lattice,
dvert = ((Lattice *)ob_target->data)->dvert;
}
else {
- dvert = ((Mesh *)ob_target->data)->dvert;
+ dvert = BKE_mesh_deform_verts((Mesh *)ob_target->data);
}
}
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index bfa11b74782..3917c020759 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -1485,8 +1485,6 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob)
mesh->totloop = loop_offset;
- BKE_mesh_update_customdata_pointers(mesh, false);
-
BKE_mesh_calc_edges(mesh, false, false);
return mesh;
diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc
index b44a956eec4..c0379c50de4 100644
--- a/source/blender/blenkernel/intern/mesh.cc
+++ b/source/blender/blenkernel/intern/mesh.cc
@@ -66,6 +66,7 @@
using blender::float3;
using blender::MutableSpan;
+using blender::Span;
using blender::VArray;
using blender::Vector;
@@ -146,8 +147,6 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
mesh_tessface_clear_intern(mesh_dst, false);
}
- BKE_mesh_update_customdata_pointers(mesh_dst, do_tessface);
-
mesh_dst->cd_flag = mesh_src->cd_flag;
mesh_dst->edit_mesh = nullptr;
@@ -234,29 +233,32 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
/* Do not store actual geometry data in case this is a library override ID. */
if (ID_IS_OVERRIDE_LIBRARY(mesh) && !is_undo) {
- mesh->mvert = nullptr;
mesh->totvert = 0;
memset(&mesh->vdata, 0, sizeof(mesh->vdata));
- mesh->medge = nullptr;
mesh->totedge = 0;
memset(&mesh->edata, 0, sizeof(mesh->edata));
- mesh->mloop = nullptr;
mesh->totloop = 0;
memset(&mesh->ldata, 0, sizeof(mesh->ldata));
- mesh->mpoly = nullptr;
mesh->totpoly = 0;
memset(&mesh->pdata, 0, sizeof(mesh->pdata));
}
else {
Set<std::string> names_to_skip;
if (!BLO_write_is_undo(writer)) {
+
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
/* When converting to the old mesh format, don't save redundant attributes. */
names_to_skip.add_multiple_new({".hide_vert", ".hide_edge", ".hide_poly"});
+
+ /* Set deprecated mesh data pointers for forward compatibility. */
+ mesh->mvert = const_cast<MVert *>(mesh->vertices().data());
+ mesh->medge = const_cast<MEdge *>(mesh->edges().data());
+ mesh->mpoly = const_cast<MPoly *>(mesh->polygons().data());
+ mesh->mloop = const_cast<MLoop *>(mesh->loops().data());
}
CustomData_blend_write_prepare(mesh->vdata, vert_layers, names_to_skip);
@@ -295,17 +297,16 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
Mesh *mesh = (Mesh *)id;
BLO_read_pointer_array(reader, (void **)&mesh->mat);
+ /* Deprecated pointers to custom data layers are read here for backward compatibility
+ * with files where these were owning pointers rather than a view into custom data. */
BLO_read_data_address(reader, &mesh->mvert);
BLO_read_data_address(reader, &mesh->medge);
BLO_read_data_address(reader, &mesh->mface);
- BLO_read_data_address(reader, &mesh->mloop);
- BLO_read_data_address(reader, &mesh->mpoly);
- BLO_read_data_address(reader, &mesh->tface);
BLO_read_data_address(reader, &mesh->mtface);
- BLO_read_data_address(reader, &mesh->mcol);
BLO_read_data_address(reader, &mesh->dvert);
- BLO_read_data_address(reader, &mesh->mloopcol);
- BLO_read_data_address(reader, &mesh->mloopuv);
+ BLO_read_data_address(reader, &mesh->tface);
+ BLO_read_data_address(reader, &mesh->mcol);
+
BLO_read_data_address(reader, &mesh->mselect);
/* animdata */
@@ -468,6 +469,8 @@ static int customdata_compare(
CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR |
CD_MASK_MDEFORMVERT;
const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic;
+ const Span<MLoop> loops_1 = m1->loops();
+ const Span<MLoop> loops_2 = m2->loops();
for (int i = 0; i < c1->totlayer; i++) {
l1 = &c1->layers[i];
@@ -543,15 +546,14 @@ static int customdata_compare(
int ptot = m1->totpoly;
for (j = 0; j < ptot; j++, p1++, p2++) {
- MLoop *lp1, *lp2;
int k;
if (p1->totloop != p2->totloop) {
return MESHCMP_POLYMISMATCH;
}
- lp1 = m1->mloop + p1->loopstart;
- lp2 = m2->mloop + p2->loopstart;
+ const MLoop *lp1 = &loops_1[p1->loopstart];
+ const MLoop *lp2 = &loops_2[p2->loopstart];
for (k = 0; k < p1->totloop; k++, lp1++, lp2++) {
if (lp1->v != lp2->v) {
@@ -762,47 +764,6 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
return nullptr;
}
-static void mesh_ensure_tessellation_customdata(Mesh *me)
-{
- if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
- /* Pass, otherwise this function clears 'mface' before
- * versioning 'mface -> mpoly' code kicks in T30583.
- *
- * Callers could also check but safer to do here - campbell */
- }
- else {
- const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
- const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
-
- const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
- const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL);
-
- if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) {
- BKE_mesh_tessface_clear(me);
-
- BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface);
-
- /* TODO: add some `--debug-mesh` option. */
- if (G.debug & G_DEBUG) {
- /* NOTE(@campbellbarton): this warning may be un-called for if we are initializing the mesh
- * for the first time from #BMesh, rather than giving a warning about this we could be
- * smarter and check if there was any data to begin with, for now just print the warning
- * with some info to help troubleshoot what's going on. */
- printf(
- "%s: warning! Tessellation uvs or vcol data got out of sync, "
- "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
- "CD_PROP_BYTE_COLOR: "
- "%d\n",
- __func__,
- tottex_tessface,
- tottex_original,
- totcol_tessface,
- totcol_original);
- }
- }
- }
-}
-
void BKE_mesh_ensure_skin_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
@@ -874,43 +835,6 @@ bool BKE_mesh_clear_facemap_customdata(struct Mesh *me)
return changed;
}
-/**
- * This ensures grouped custom-data (e.g. #CD_MLOOPUV and #CD_MTFACE, or
- * #CD_PROP_BYTE_COLOR and #CD_MCOL) have the same relative active/render/clone/mask indices.
- *
- * NOTE(@campbellbarton): that for undo mesh data we want to skip 'ensure_tess_cd' call since
- * we don't want to store memory for #MFace data when its only used for older
- * versions of the mesh.
- */
-static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
-{
- if (do_ensure_tess_cd) {
- mesh_ensure_tessellation_customdata(me);
- }
-
- CustomData_bmesh_update_active_layers(&me->fdata, &me->ldata);
-}
-
-void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
-{
- mesh_update_linked_customdata(me, do_ensure_tess_cd);
-
- me->mvert = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT);
- me->dvert = (MDeformVert *)CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
-
- me->medge = (MEdge *)CustomData_get_layer(&me->edata, CD_MEDGE);
-
- me->mface = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
- me->mcol = (MCol *)CustomData_get_layer(&me->fdata, CD_MCOL);
- me->mtface = (MTFace *)CustomData_get_layer(&me->fdata, CD_MTFACE);
-
- me->mpoly = (MPoly *)CustomData_get_layer(&me->pdata, CD_MPOLY);
- me->mloop = (MLoop *)CustomData_get_layer(&me->ldata, CD_MLOOP);
-
- me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR);
- me->mloopuv = (MLoopUV *)CustomData_get_layer(&me->ldata, CD_MLOOPUV);
-}
-
bool BKE_mesh_has_custom_loop_normals(Mesh *me)
{
if (me->edit_mesh) {
@@ -954,8 +878,6 @@ static void mesh_clear_geometry(Mesh *mesh)
mesh->totpoly = 0;
mesh->act_face = -1;
mesh->totselect = 0;
-
- BKE_mesh_update_customdata_pointers(mesh, false);
}
void BKE_mesh_clear_geometry(Mesh *mesh)
@@ -974,9 +896,6 @@ static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
CustomData_reset(&mesh->fdata);
}
- mesh->mface = nullptr;
- mesh->mtface = nullptr;
- mesh->mcol = nullptr;
mesh->totface = 0;
}
@@ -1029,7 +948,6 @@ Mesh *BKE_mesh_new_nomain(
mesh->totpoly = polys_len;
mesh_ensure_cdlayers_primary(mesh, true);
- BKE_mesh_update_customdata_pointers(mesh, false);
return mesh;
}
@@ -1115,7 +1033,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
/* The destination mesh should at least have valid primary CD layers,
* even in cases where the source mesh does not. */
mesh_ensure_cdlayers_primary(me_dst, do_tessface);
- BKE_mesh_update_customdata_pointers(me_dst, false);
/* Expect that normals aren't copied at all, since the destination mesh is new. */
BLI_assert(BKE_mesh_vertex_normals_are_dirty(me_dst));
@@ -1338,11 +1255,12 @@ float (*BKE_mesh_orco_verts_get(Object *ob))[3]
/* Get appropriate vertex coordinates */
float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(me->totvert, sizeof(*vcos), "orco mesh");
- MVert *mvert = tme->mvert;
+ const Span<MVert> verts = tme->vertices();
+
int totvert = min_ii(tme->totvert, me->totvert);
- for (int a = 0; a < totvert; a++, mvert++) {
- copy_v3_v3(vcos[a], mvert->co);
+ for (int a = 0; a < totvert; a++) {
+ copy_v3_v3(vcos[a], verts[a].co);
}
return vcos;
@@ -1512,14 +1430,15 @@ void BKE_mesh_material_remap(Mesh *me, const uint *remap, uint remap_len)
void BKE_mesh_smooth_flag_set(Mesh *me, const bool use_smooth)
{
+ MutableSpan<MPoly> polys = me->polygons_for_write();
if (use_smooth) {
- for (int i = 0; i < me->totpoly; i++) {
- me->mpoly[i].flag |= ME_SMOOTH;
+ for (MPoly &poly : polys) {
+ poly.flag |= ME_SMOOTH;
}
}
else {
- for (int i = 0; i < me->totpoly; i++) {
- me->mpoly[i].flag &= ~ME_SMOOTH;
+ for (MPoly &poly : polys) {
+ poly.flag &= ~ME_SMOOTH;
}
}
}
@@ -1575,9 +1494,12 @@ int BKE_mesh_edge_other_vert(const MEdge *e, int v)
void BKE_mesh_looptri_get_real_edges(const Mesh *mesh, const MLoopTri *looptri, int r_edges[3])
{
+ const Span<MEdge> edges = mesh->edges();
+ const Span<MLoop> loops = mesh->loops();
+
for (int i = 2, i_next = 0; i_next < 3; i = i_next++) {
- const MLoop *l1 = &mesh->mloop[looptri->tri[i]], *l2 = &mesh->mloop[looptri->tri[i_next]];
- const MEdge *e = &mesh->medge[l1->e];
+ const MLoop *l1 = &loops[looptri->tri[i]], *l2 = &loops[looptri->tri[i_next]];
+ const MEdge *e = &edges[l1->e];
bool is_real = (l1->v == e->v1 && l2->v == e->v2) || (l1->v == e->v2 && l2->v == e->v1);
@@ -1596,15 +1518,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
float3 min;
float3 max;
};
+ const Span<MVert> verts = me->vertices();
const Result minmax = threading::parallel_reduce(
- IndexRange(me->totvert),
+ verts.index_range(),
1024,
Result{float3(FLT_MAX), float3(-FLT_MAX)},
- [&](IndexRange range, const Result &init) {
+ [verts](IndexRange range, const Result &init) {
Result result = init;
for (const int i : range) {
- math::min_max(float3(me->mvert[i].co), result.min, result.max);
+ math::min_max(float3(verts[i].co), result.min, result.max);
}
return result;
},
@@ -1620,22 +1543,16 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
{
- int i;
- MVert *mvert = (MVert *)CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert);
- float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer(
- &me->ldata, CD_NORMAL, me->totloop);
-
- /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
- BKE_mesh_update_customdata_pointers(me, false);
+ MutableSpan<MVert> verts = me->vertices_for_write();
- for (i = 0; i < me->totvert; i++, mvert++) {
- mul_m4_v3(mat, mvert->co);
+ for (MVert &vert : verts) {
+ mul_m4_v3(mat, vert.co);
}
if (do_keys && me->key) {
LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
float *fp = (float *)kb->data;
- for (i = kb->totelem; i--; fp += 3) {
+ for (int i = kb->totelem; i--; fp += 3) {
mul_m4_v3(mat, fp);
}
}
@@ -1644,12 +1561,14 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
/* don't update normals, caller can do this explicitly.
* We do update loop normals though, those may not be auto-generated
* (see e.g. STL import script)! */
+ float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer(
+ &me->ldata, CD_NORMAL, me->totloop);
if (lnors) {
float m3[3][3];
copy_m3_m4(m3, mat);
normalize_m3(m3);
- for (i = 0; i < me->totloop; i++, lnors++) {
+ for (int i = 0; i < me->totloop; i++, lnors++) {
mul_m3_v3(m3, *lnors);
}
}
@@ -1658,15 +1577,12 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys)
void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
{
- CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert);
- /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */
- BKE_mesh_update_customdata_pointers(me, false);
-
- int i = me->totvert;
- for (MVert *mvert = me->mvert; i--; mvert++) {
- add_v3_v3(mvert->co, offset);
+ MutableSpan<MVert> verts = me->vertices_for_write();
+ for (MVert &vert : verts) {
+ add_v3_v3(vert.co, offset);
}
+ int i;
if (do_keys && me->key) {
LISTBASE_FOREACH (KeyBlock *, kb, &me->key->block) {
float *fp = (float *)kb->data;
@@ -1689,25 +1605,24 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
return;
}
- MVert *mv;
- MEdge *med;
- int i;
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MEdge> edges = mesh->edges();
- for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
- if (mv->bweight != 0) {
+ for (const MVert &vert : verts) {
+ if (vert.bweight != 0) {
mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
break;
}
}
- for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
- if (med->bweight != 0) {
+ for (const MEdge &edge : edges) {
+ if (edge.bweight != 0) {
mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
break;
}
}
- if (med->crease != 0) {
+ if (edge.crease != 0) {
mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
break;
@@ -1733,6 +1648,9 @@ void BKE_mesh_mselect_validate(Mesh *me)
if (me->totselect == 0) {
return;
}
+ const Span<MVert> verts = me->vertices();
+ const Span<MEdge> edges = me->edges();
+ const Span<MPoly> polys = me->polygons();
mselect_src = me->mselect;
mselect_dst = (MSelect *)MEM_malloc_arrayN(
@@ -1742,21 +1660,21 @@ void BKE_mesh_mselect_validate(Mesh *me)
int index = mselect_src[i_src].index;
switch (mselect_src[i_src].type) {
case ME_VSEL: {
- if (me->mvert[index].flag & SELECT) {
+ if (verts[index].flag & SELECT) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_ESEL: {
- if (me->medge[index].flag & SELECT) {
+ if (edges[index].flag & SELECT) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
break;
}
case ME_FSEL: {
- if (me->mpoly[index].flag & SELECT) {
+ if (polys[index].flag & SELECT) {
mselect_dst[i_dst] = mselect_src[i_src];
i_dst++;
}
@@ -1842,10 +1760,10 @@ void BKE_mesh_count_selected_items(const Mesh *mesh, int r_count[3])
void BKE_mesh_vert_coords_get(const Mesh *mesh, float (*vert_coords)[3])
{
- const MVert *mv = mesh->mvert;
- for (int i = 0; i < mesh->totvert; i++, mv++) {
- copy_v3_v3(vert_coords[i], mv->co);
- }
+ blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*mesh);
+ VArray<float3> positions = attributes.lookup_or_default(
+ "position", ATTR_DOMAIN_POINT, float3(0));
+ positions.materialize({(float3 *)vert_coords, mesh->totvert});
}
float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3]
@@ -1860,12 +1778,9 @@ float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3]
void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3])
{
- /* This will just return the pointer if it wasn't a referenced layer. */
- MVert *mv = (MVert *)CustomData_duplicate_referenced_layer(
- &mesh->vdata, CD_MVERT, mesh->totvert);
- mesh->mvert = mv;
- for (int i = 0; i < mesh->totvert; i++, mv++) {
- copy_v3_v3(mv->co, vert_coords[i]);
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ for (const int i : verts.index_range()) {
+ copy_v3_v3(verts[i].co, vert_coords[i]);
}
BKE_mesh_tag_coords_changed(mesh);
}
@@ -1874,12 +1789,9 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh,
const float (*vert_coords)[3],
const float mat[4][4])
{
- /* This will just return the pointer if it wasn't a referenced layer. */
- MVert *mv = (MVert *)CustomData_duplicate_referenced_layer(
- &mesh->vdata, CD_MVERT, mesh->totvert);
- mesh->mvert = mv;
- for (int i = 0; i < mesh->totvert; i++, mv++) {
- mul_v3_m4v3(mv->co, mat, vert_coords[i]);
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ for (const int i : verts.index_range()) {
+ mul_v3_m4v3(verts[i].co, mat, vert_coords[i]);
}
BKE_mesh_tag_coords_changed(mesh);
}
@@ -1915,17 +1827,22 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh,
/* may be nullptr */
clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
- BKE_mesh_normals_loop_split(mesh->mvert,
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MEdge> edges = mesh->edges();
+ const Span<MPoly> polys = mesh->polygons();
+ const Span<MLoop> loops = mesh->loops();
+
+ BKE_mesh_normals_loop_split(verts.data(),
BKE_mesh_vertex_normals_ensure(mesh),
- mesh->totvert,
- mesh->medge,
- mesh->totedge,
- mesh->mloop,
+ verts.size(),
+ edges.data(),
+ edges.size(),
+ loops.data(),
r_corner_normals,
- mesh->totloop,
- mesh->mpoly,
+ loops.size(),
+ polys.data(),
BKE_mesh_poly_normals_ensure(mesh),
- mesh->totpoly,
+ polys.size(),
use_split_normals,
split_angle,
r_lnors_spacearr,
@@ -1971,14 +1888,14 @@ static int split_faces_prepare_new_verts(Mesh *mesh,
const int loops_len = mesh->totloop;
int verts_len = mesh->totvert;
- MLoop *mloop = mesh->mloop;
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
BKE_mesh_vertex_normals_ensure(mesh);
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
BLI_bitmap *verts_used = BLI_BITMAP_NEW(verts_len, __func__);
BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_len, __func__);
- MLoop *ml = mloop;
+ MLoop *ml = loops.data();
MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX);
@@ -2005,7 +1922,7 @@ static int split_faces_prepare_new_verts(Mesh *mesh,
const int ml_fan_idx = POINTER_AS_INT(lnode->link);
BLI_BITMAP_ENABLE(done_loops, ml_fan_idx);
if (vert_used) {
- mloop[ml_fan_idx].v = new_vert_idx;
+ loops[ml_fan_idx].v = new_vert_idx;
}
}
}
@@ -2040,23 +1957,23 @@ static int split_faces_prepare_new_verts(Mesh *mesh,
/* Detect needed new edges, and update accordingly loops' edge indices.
* WARNING! Leaves mesh in invalid state. */
-static int split_faces_prepare_new_edges(const Mesh *mesh,
+static int split_faces_prepare_new_edges(Mesh *mesh,
SplitFaceNewEdge **new_edges,
MemArena *memarena)
{
const int num_polys = mesh->totpoly;
int num_edges = mesh->totedge;
- MEdge *medge = mesh->medge;
- MLoop *mloop = mesh->mloop;
- const MPoly *mpoly = mesh->mpoly;
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
+ const Span<MPoly> polys = mesh->polygons();
BLI_bitmap *edges_used = BLI_BITMAP_NEW(num_edges, __func__);
EdgeHash *edges_hash = BLI_edgehash_new_ex(__func__, num_edges);
- const MPoly *mp = mpoly;
+ const MPoly *mp = polys.data();
for (int poly_idx = 0; poly_idx < num_polys; poly_idx++, mp++) {
- MLoop *ml_prev = &mloop[mp->loopstart + mp->totloop - 1];
- MLoop *ml = &mloop[mp->loopstart];
+ MLoop *ml_prev = &loops[mp->loopstart + mp->totloop - 1];
+ MLoop *ml = &loops[mp->loopstart];
for (int loop_idx = 0; loop_idx < mp->totloop; loop_idx++, ml++) {
void **eval;
if (!BLI_edgehash_ensure_p(edges_hash, ml_prev->v, ml->v, &eval)) {
@@ -2080,8 +1997,8 @@ static int split_faces_prepare_new_edges(const Mesh *mesh,
}
else {
/* We can re-use original edge. */
- medge[edge_idx].v1 = ml_prev->v;
- medge[edge_idx].v2 = ml->v;
+ edges[edge_idx].v1 = ml_prev->v;
+ edges[edge_idx].v2 = ml->v;
*eval = POINTER_FROM_INT(edge_idx);
BLI_BITMAP_ENABLE(edges_used, edge_idx);
}
@@ -2107,7 +2024,6 @@ static void split_faces_split_new_verts(Mesh *mesh,
const int num_new_verts)
{
const int verts_len = mesh->totvert - num_new_verts;
- MVert *mvert = mesh->mvert;
float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh);
/* Normals were already calculated at the beginning of this operation, we rely on that to update
@@ -2115,8 +2031,7 @@ static void split_faces_split_new_verts(Mesh *mesh,
BLI_assert(!BKE_mesh_vertex_normals_are_dirty(mesh));
/* Remember new_verts is a single linklist, so its items are in reversed order... */
- MVert *new_mv = &mvert[mesh->totvert - 1];
- for (int i = mesh->totvert - 1; i >= verts_len; i--, new_mv--, new_verts = new_verts->next) {
+ for (int i = mesh->totvert - 1; i >= verts_len; i--, new_verts = new_verts->next) {
BLI_assert(new_verts->new_index == i);
BLI_assert(new_verts->new_index != new_verts->orig_index);
CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1);
@@ -2132,10 +2047,10 @@ static void split_faces_split_new_edges(Mesh *mesh,
const int num_new_edges)
{
const int num_edges = mesh->totedge - num_new_edges;
- MEdge *medge = mesh->medge;
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
/* Remember new_edges is a single linklist, so its items are in reversed order... */
- MEdge *new_med = &medge[mesh->totedge - 1];
+ MEdge *new_med = &edges[mesh->totedge - 1];
for (int i = mesh->totedge - 1; i >= num_edges; i--, new_med--, new_edges = new_edges->next) {
BLI_assert(new_edges->new_index == i);
BLI_assert(new_edges->new_index != new_edges->orig_index);
@@ -2163,14 +2078,6 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
SplitFaceNewVert *new_verts = nullptr;
SplitFaceNewEdge *new_edges = nullptr;
- /* Ensure we own the layers, we need to do this before split_faces_prepare_new_verts as it will
- * directly assign new indices to existing edges and loops. */
- CustomData_duplicate_referenced_layers(&mesh->vdata, mesh->totvert);
- CustomData_duplicate_referenced_layers(&mesh->edata, mesh->totedge);
- CustomData_duplicate_referenced_layers(&mesh->ldata, mesh->totloop);
- /* Update pointers in case we duplicated referenced layers. */
- BKE_mesh_update_customdata_pointers(mesh, false);
-
/* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */
const int num_new_verts = split_faces_prepare_new_verts(
mesh, &lnors_spacearr, &new_verts, memarena);
@@ -2191,8 +2098,6 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
mesh->totedge += num_new_edges;
CustomData_realloc(&mesh->edata, mesh->totedge);
}
- /* Update pointers to a newly allocated memory. */
- BKE_mesh_update_customdata_pointers(mesh, false);
/* Update normals manually to avoid recalculation after this operation. */
mesh->runtime.vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime.vert_normals,
diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
index fb4a9248d8d..d5671b53267 100644
--- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc
@@ -162,9 +162,10 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index,
int orig_mesh_index = input_mesh_for_imesh_face(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
+ const Span<MPoly> polys = me->polygons();
int index_in_mesh = orig_index - mesh_poly_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totpoly);
- const MPoly *mp = &me->mpoly[index_in_mesh];
+ const MPoly *mp = &polys[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -188,9 +189,10 @@ const MVert *MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index,
int orig_mesh_index = input_mesh_for_imesh_vert(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
+ const Span<MVert> verts = me->vertices();
int index_in_mesh = orig_index - mesh_vert_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totvert);
- const MVert *mv = &me->mvert[index_in_mesh];
+ const MVert *mv = &verts[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -208,9 +210,10 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index,
int orig_mesh_index = input_mesh_for_imesh_edge(orig_index);
BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size());
const Mesh *me = meshes[orig_mesh_index];
+ const Span<MEdge> edges = me->edges();
int index_in_mesh = orig_index - mesh_edge_offset[orig_mesh_index];
BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totedge);
- const MEdge *medge = &me->medge[index_in_mesh];
+ const MEdge *medge = &edges[index_in_mesh];
if (r_orig_mesh) {
*r_orig_mesh = me;
}
@@ -306,17 +309,19 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
bool need_face_flip = r_info->has_negative_transform[mi] != r_info->has_negative_transform[0];
Vector<Vert *> verts(me->totvert);
- Span<MVert> mverts = Span(me->mvert, me->totvert);
+ const Span<MVert> mesh_verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
/* Allocate verts
* Skip the matrix multiplication for each point when there is no transform for a mesh,
* for example when the first mesh is already in the target space. (Note the logic
* directly above, which uses an identity matrix with a null input transform). */
if (obmats[mi] == nullptr) {
- threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) {
+ threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) {
float3 co;
for (int i : range) {
- co = float3(mverts[i].co);
+ co = float3(mesh_verts[i].co);
mpq3 mco = mpq3(co.x, co.y, co.z);
double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d());
verts[i] = new Vert(mco, dco, NO_INDEX, i);
@@ -324,26 +329,26 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
});
}
else {
- threading::parallel_for(mverts.index_range(), 2048, [&](IndexRange range) {
+ threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) {
float3 co;
for (int i : range) {
- co = r_info->to_target_transform[mi] * float3(mverts[i].co);
+ co = r_info->to_target_transform[mi] * float3(mesh_verts[i].co);
mpq3 mco = mpq3(co.x, co.y, co.z);
double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d());
verts[i] = new Vert(mco, dco, NO_INDEX, i);
}
});
}
- for (int i : mverts.index_range()) {
+ for (int i : mesh_verts.index_range()) {
r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]);
++v;
}
- for (const MPoly &poly : Span(me->mpoly, me->totpoly)) {
+ for (const MPoly &poly : polys) {
int flen = poly.totloop;
face_vert.resize(flen);
face_edge_orig.resize(flen);
- const MLoop *l = &me->mloop[poly.loopstart];
+ const MLoop *l = &loops[poly.loopstart];
for (int i = 0; i < flen; ++i) {
int mverti = r_info->mesh_vert_offset[mi] + l->v;
const Vert *fv = r_info->mesh_to_imesh_vert[mverti];
@@ -479,14 +484,16 @@ static int fill_orig_loops(const Face *f,
const Mesh *orig_me,
int orig_me_index,
MeshesToIMeshInfo &mim,
- Array<int> &orig_loops)
+ MutableSpan<int> r_orig_loops)
{
- orig_loops.fill(-1);
+ r_orig_loops.fill(-1);
+ const Span<MLoop> orig_loops = orig_me->loops();
+
int orig_mplen = orig_mp->totloop;
if (f->size() != orig_mplen) {
return 0;
}
- BLI_assert(orig_loops.size() == orig_mplen);
+ BLI_assert(r_orig_loops.size() == orig_mplen);
/* We'll look for the case where the first vertex in f has an original vertex
* that is the same as one in orig_me (after correcting for offset in mim meshes).
* Then see that loop and any subsequent ones have the same start and end vertex.
@@ -508,7 +515,7 @@ static int fill_orig_loops(const Face *f,
int offset = -1;
for (int i = 0; i < orig_mplen; ++i) {
int loop_i = i + orig_mp->loopstart;
- if (orig_me->mloop[loop_i].v == first_orig_v_in_orig_me) {
+ if (orig_loops[loop_i].v == first_orig_v_in_orig_me) {
offset = i;
break;
}
@@ -519,7 +526,7 @@ static int fill_orig_loops(const Face *f,
int num_orig_loops_found = 0;
for (int mp_loop_index = 0; mp_loop_index < orig_mplen; ++mp_loop_index) {
int orig_mp_loop_index = (mp_loop_index + offset) % orig_mplen;
- MLoop *l = &orig_me->mloop[orig_mp->loopstart + orig_mp_loop_index];
+ const MLoop *l = &orig_loops[orig_mp->loopstart + orig_mp_loop_index];
int fv_orig = f->vert[mp_loop_index]->orig;
if (fv_orig != NO_INDEX) {
fv_orig -= orig_me_vert_offset;
@@ -528,7 +535,8 @@ static int fill_orig_loops(const Face *f,
}
}
if (l->v == fv_orig) {
- MLoop *lnext = &orig_me->mloop[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
+ const MLoop *lnext =
+ &orig_loops[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
int fvnext_orig = f->vert[(mp_loop_index + 1) % orig_mplen]->orig;
if (fvnext_orig != NO_INDEX) {
fvnext_orig -= orig_me_vert_offset;
@@ -537,7 +545,7 @@ static int fill_orig_loops(const Face *f,
}
}
if (lnext->v == fvnext_orig) {
- orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index;
+ r_orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index;
++num_orig_loops_found;
}
}
@@ -555,19 +563,18 @@ static void get_poly2d_cos(const Mesh *me,
const float4x4 &trans_mat,
float r_axis_mat[3][3])
{
- int n = mp->totloop;
+ const Span<MVert> verts = me->vertices();
+ const Span<MLoop> loops = me->loops();
+ const Span<MLoop> poly_loops = loops.slice(mp->loopstart, mp->totloop);
/* Project coordinates to 2d in cos_2d, using normal as projection axis. */
float axis_dominant[3];
- BKE_mesh_calc_poly_normal(mp, &me->mloop[mp->loopstart], me->mvert, axis_dominant);
+ BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts.data(), axis_dominant);
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
- MLoop *ml = &me->mloop[mp->loopstart];
- const MVert *mverts = me->mvert;
- for (int i = 0; i < n; ++i) {
- float3 co = mverts[ml->v].co;
+ for (const int i : poly_loops.index_range()) {
+ float3 co = verts[poly_loops[i].v].co;
co = trans_mat * co;
mul_v2_m3v3(cos_2d[i], r_axis_mat, co);
- ++ml;
}
}
@@ -602,6 +609,8 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
get_poly2d_cos(orig_me, orig_mp, cos_2d, mim.to_target_transform[orig_me_index], axis_mat);
}
CustomData *target_cd = &dest_mesh->ldata;
+ const Span<MVert> dst_vertices = dest_mesh->vertices();
+ const Span<MLoop> dst_loops = dest_mesh->loops();
for (int i = 0; i < mp->totloop; ++i) {
int loop_index = mp->loopstart + i;
int orig_loop_index = norig > 0 ? orig_loops[i] : -1;
@@ -611,7 +620,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
* The coordinate needs to be projected into 2d, just like the interpolating polygon's
* coordinates were. The `dest_mesh` coordinates are already in object 0 local space. */
float co[2];
- mul_v2_m3v3(co, axis_mat, dest_mesh->mvert[dest_mesh->mloop[loop_index].v].co);
+ mul_v2_m3v3(co, axis_mat, dst_vertices[dst_loops[loop_index].v].co);
interp_weights_poly_v2(weights.data(), cos_2d, orig_mp->totloop, co);
}
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
@@ -714,9 +723,10 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
merge_vertex_loop_poly_customdata_layers(result, mim);
/* Set the vertex coordinate values and other data. */
+ MutableSpan<MVert> vertices = result->vertices_for_write();
for (int vi : im->vert_index_range()) {
const Vert *v = im->vert(vi);
- MVert *mv = &result->mvert[vi];
+ MVert *mv = &vertices[vi];
copy_v3fl_v3db(mv->co, v->co);
if (v->orig != NO_INDEX) {
const Mesh *orig_me;
@@ -732,7 +742,9 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
bke::mesh_attributes_for_write(*result).lookup_or_add_for_write_only_span<int>(
"material_index", ATTR_DOMAIN_FACE);
int cur_loop_index = 0;
- MLoop *l = result->mloop;
+ MutableSpan<MLoop> dst_loops = result->loops_for_write();
+ MutableSpan<MPoly> dst_polys = result->polygons_for_write();
+ MLoop *l = dst_loops.data();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
const Mesh *orig_me;
@@ -740,7 +752,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
int orig_me_index;
const MPoly *orig_mp = mim.input_mpoly_for_orig_index(
f->orig, &orig_me, &orig_me_index, &index_in_orig_me);
- MPoly *mp = &result->mpoly[fi];
+ MPoly *mp = &dst_polys[fi];
mp->totloop = f->size();
mp->loopstart = cur_loop_index;
for (int j : f->index_range()) {
@@ -772,17 +784,18 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
/* Now that the MEdges are populated, we can copy over the required attributes and custom layers.
*/
+ MutableSpan<MEdge> edges = result->edges_for_write();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
- MPoly *mp = &result->mpoly[fi];
+ const MPoly *mp = &dst_polys[fi];
for (int j : f->index_range()) {
if (f->edge_orig[j] != NO_INDEX) {
const Mesh *orig_me;
int index_in_orig_me;
const MEdge *orig_medge = mim.input_medge_for_orig_index(
f->edge_orig[j], &orig_me, &index_in_orig_me);
- int e_index = result->mloop[mp->loopstart + j].e;
- MEdge *medge = &result->medge[e_index];
+ int e_index = dst_loops[mp->loopstart + j].e;
+ MEdge *medge = &edges[e_index];
copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me);
}
}
@@ -844,12 +857,14 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
/* Store intersecting edge indices. */
if (r_intersecting_edges != nullptr) {
+ const Span<MPoly> polys = result->polygons();
+ const Span<MLoop> loops = result->loops();
for (int fi : m_out.face_index_range()) {
const Face &face = *m_out.face(fi);
- const MPoly &poly = result->mpoly[fi];
+ const MPoly &poly = polys[fi];
for (int corner_i : face.index_range()) {
if (face.is_intersect[corner_i]) {
- int e_index = result->mloop[poly.loopstart + corner_i].e;
+ int e_index = loops[poly.loopstart + corner_i].e;
r_intersecting_edges->append(e_index);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_calc_edges.cc b/source/blender/blenkernel/intern/mesh_calc_edges.cc
index 31e20750cf2..8a8960fb8a7 100644
--- a/source/blender/blenkernel/intern/mesh_calc_edges.cc
+++ b/source/blender/blenkernel/intern/mesh_calc_edges.cc
@@ -80,9 +80,10 @@ static void add_existing_edges_to_hash_maps(Mesh *mesh,
uint32_t parallel_mask)
{
/* Assume existing edges are valid. */
+ const Span<MEdge> edges = mesh->edges();
threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) {
const int task_index = &edge_map - edge_maps.data();
- for (const MEdge &edge : Span(mesh->medge, mesh->totedge)) {
+ for (const MEdge &edge : edges) {
OrderedEdge ordered_edge{edge.v1, edge.v2};
/* Only add the edge when it belongs into this map. */
if (task_index == (parallel_mask & ordered_edge.hash2())) {
@@ -96,10 +97,11 @@ static void add_polygon_edges_to_hash_maps(Mesh *mesh,
MutableSpan<EdgeMap> edge_maps,
uint32_t parallel_mask)
{
- const Span<MLoop> loops{mesh->mloop, mesh->totloop};
+ const Span<MPoly> polys = mesh->polygons();
+ const Span<MLoop> loops = mesh->loops();
threading::parallel_for_each(edge_maps, [&](EdgeMap &edge_map) {
const int task_index = &edge_map - edge_maps.data();
- for (const MPoly &poly : Span(mesh->mpoly, mesh->totpoly)) {
+ for (const MPoly &poly : polys) {
Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
const MLoop *prev_loop = &poly_loops.last();
for (const MLoop &next_loop : poly_loops) {
@@ -157,10 +159,11 @@ static void update_edge_indices_in_poly_loops(Mesh *mesh,
Span<EdgeMap> edge_maps,
uint32_t parallel_mask)
{
- const MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop};
+ const Span<MPoly> polys = mesh->polygons();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
threading::parallel_for(IndexRange(mesh->totpoly), 100, [&](IndexRange range) {
for (const int poly_index : range) {
- MPoly &poly = mesh->mpoly[poly_index];
+ const MPoly &poly = polys[poly_index];
MutableSpan<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
MLoop *prev_loop = &poly_loops.last();
@@ -242,7 +245,6 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
CustomData_reset(&mesh->edata);
CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge);
mesh->totedge = new_totedge;
- mesh->medge = new_edges.data();
/* Explicitly clear edge maps, because that way it can be parallelized. */
clear_hash_tables(edge_maps);
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 393d54bb03e..e56c248e81a 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -81,8 +81,8 @@ static void make_edges_mdata_extend(Mesh &mesh)
const MPoly *mp;
int i;
- Span<MPoly> polys(mesh.mpoly, mesh.totpoly);
- MutableSpan<MLoop> loops(mesh.mloop, mesh.totloop);
+ const Span<MPoly> polys = mesh.polygons();
+ MutableSpan<MLoop> loops = mesh.loops_for_write();
const int eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(mesh.totpoly));
EdgeHash *eh = BLI_edgehash_new_ex(__func__, eh_reserve);
@@ -96,20 +96,18 @@ static void make_edges_mdata_extend(Mesh &mesh)
#ifdef DEBUG
/* ensure that there's no overlap! */
if (totedge_new) {
- MEdge *medge = mesh.medge;
- for (i = 0; i < totedge; i++, medge++) {
- BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false);
+ for (const MEdge &edge : mesh.edges()) {
+ BLI_assert(BLI_edgehash_haskey(eh, edge.v1, edge.v2) == false);
}
}
#endif
if (totedge_new) {
CustomData_realloc(&mesh.edata, totedge + totedge_new);
- BKE_mesh_update_customdata_pointers(&mesh, false);
-
- MEdge *medge = mesh.medge + totedge;
mesh.totedge += totedge_new;
+ MutableSpan<MEdge> edges = mesh.edges_for_write();
+ MEdge *medge = &edges[totedge];
EdgeHashIterator *ehi;
uint e_index = totedge;
@@ -123,7 +121,7 @@ static void make_edges_mdata_extend(Mesh &mesh)
}
BLI_edgehashIterator_free(ehi);
- for (i = 0, mp = mesh.mpoly; i < mesh.totpoly; i++, mp++) {
+ for (i = 0, mp = polys.data(); i < mesh.totpoly; i++, mp++) {
MLoop *l = &loops[mp->loopstart];
MLoop *l_prev = (l + (mp->totloop - 1));
int j;
@@ -186,10 +184,10 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba
}
Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
- MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
- MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
- MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
- MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop);
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ MutableSpan<MPoly> polys = mesh->polygons_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
MVert *mvert = verts.data();
MEdge *medge = edges.data();
@@ -434,7 +432,7 @@ Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob)
struct EdgeLink {
struct EdgeLink *next, *prev;
- void *edge;
+ const void *edge;
};
struct VertLink {
@@ -458,10 +456,13 @@ static void appendPolyLineVert(ListBase *lb, uint index)
void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
{
- MVert *mvert = me->mvert;
- MEdge *med, *medge = me->medge;
- MPoly *mp, *mpoly = me->mpoly;
- MLoop *mloop = me->mloop;
+ const Span<MVert> verts = me->vertices();
+ const Span<MEdge> mesh_edges = me->edges();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
+
+ const MEdge *med;
+ const MPoly *mp;
int medge_len = me->totedge;
int mpoly_len = me->totpoly;
@@ -475,8 +476,8 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
/* get boundary edges */
edge_users = (int *)MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
- for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
- MLoop *ml = &mloop[mp->loopstart];
+ for (i = 0, mp = polys.data(); i < mpoly_len; i++, mp++) {
+ const MLoop *ml = &loops[mp->loopstart];
int j;
for (j = 0; j < mp->totloop; j++, ml++) {
edge_users[ml->e]++;
@@ -484,7 +485,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
}
/* create edges from all faces (so as to find edges not in any faces) */
- med = medge;
+ med = mesh_edges.data();
for (i = 0; i < medge_len; i++, med++) {
if (edge_users[i] == edge_users_test) {
EdgeLink *edl = MEM_cnew<EdgeLink>("EdgeLink");
@@ -587,7 +588,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed
/* add points */
vl = (VertLink *)polyline.first;
for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
- copy_v3_v3(bp->vec, mvert[vl->index].co);
+ copy_v3_v3(bp->vec, verts[vl->index].co);
bp->f1 = SELECT;
bp->radius = bp->weight = 1.0;
}
@@ -682,19 +683,16 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
&pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint);
/* Convert the Position attribute to a mesh vertex. */
- me->mvert = (MVert *)CustomData_add_layer(
- &me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
- CustomData_update_typemap(&me->vdata);
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert);
const int layer_idx = CustomData_get_named_layer_index(
&me->vdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION);
CustomDataLayer *pos_layer = &me->vdata.layers[layer_idx];
float(*positions)[3] = (float(*)[3])pos_layer->data;
- MVert *mvert;
- mvert = me->mvert;
- for (int i = 0; i < me->totvert; i++, mvert++) {
- copy_v3_v3(mvert->co, positions[i]);
+ MutableSpan<MVert> verts = me->vertices_for_write();
+ for (int i = 0; i < me->totvert; i++) {
+ copy_v3_v3(verts[i].co, positions[i]);
}
/* Delete Position attribute since it is now in vertex coordinates. */
@@ -703,9 +701,9 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me)
void BKE_mesh_edges_set_draw_render(Mesh *mesh)
{
- MEdge *med = mesh->medge;
- for (int i = 0; i < mesh->totedge; i++, med++) {
- med->flag |= ME_EDGEDRAW | ME_EDGERENDER;
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ for (int i = 0; i < mesh->totedge; i++) {
+ edges[i].flag |= ME_EDGEDRAW | ME_EDGERENDER;
}
}
@@ -1171,7 +1169,8 @@ Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
if (build_shapekey_layers && me->key &&
(kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) {
- BKE_keyblock_convert_to_mesh(kb, me->mvert, me->totvert);
+ MutableSpan<MVert> verts = me->vertices_for_write();
+ BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert);
}
Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE);
@@ -1274,10 +1273,9 @@ static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int act
kb->data = kbcos = (float(*)[3])MEM_malloc_arrayN(kb->totelem, sizeof(float[3]), __func__);
if (kb->uid == actshape_uid) {
- MVert *mvert = mesh_src->mvert;
-
- for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) {
- copy_v3_v3(*kbcos, mvert->co);
+ const Span<MVert> verts = mesh_src->vertices();
+ for (j = 0; j < mesh_src->totvert; j++, kbcos++) {
+ copy_v3_v3(*kbcos, verts[j].co);
}
}
else {
@@ -1306,6 +1304,7 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
const CustomData_MeshMasks *mask,
bool take_ownership)
{
+ using namespace blender::bke;
BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN);
/* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
@@ -1385,30 +1384,30 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
CustomData_add_layer(&tmp.vdata,
CD_MVERT,
CD_ASSIGN,
- (alloctype == CD_ASSIGN) ? mesh_src->mvert :
- MEM_dupallocN(mesh_src->mvert),
+ (alloctype == CD_ASSIGN) ? mesh_src->vertices_for_write().data() :
+ MEM_dupallocN(mesh_src->vertices().data()),
totvert);
}
if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
CustomData_add_layer(&tmp.edata,
CD_MEDGE,
CD_ASSIGN,
- (alloctype == CD_ASSIGN) ? mesh_src->medge :
- MEM_dupallocN(mesh_src->medge),
+ (alloctype == CD_ASSIGN) ? mesh_src->edges_for_write().data() :
+ MEM_dupallocN(mesh_src->edges().data()),
totedge);
}
if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
CustomData_add_layer(&tmp.ldata,
CD_MLOOP,
CD_ASSIGN,
- (alloctype == CD_ASSIGN) ? mesh_src->mloop :
- MEM_dupallocN(mesh_src->mloop),
+ (alloctype == CD_ASSIGN) ? mesh_src->loops_for_write().data() :
+ MEM_dupallocN(mesh_src->loops().data()),
tmp.totloop);
CustomData_add_layer(&tmp.pdata,
CD_MPOLY,
CD_ASSIGN,
- (alloctype == CD_ASSIGN) ? mesh_src->mpoly :
- MEM_dupallocN(mesh_src->mpoly),
+ (alloctype == CD_ASSIGN) ? mesh_src->polygons_for_write().data() :
+ MEM_dupallocN(mesh_src->polygons().data()),
tmp.totpoly);
}
@@ -1425,9 +1424,6 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src,
}
}
- /* yes, must be before _and_ after tessellate */
- BKE_mesh_update_customdata_pointers(&tmp, false);
-
CustomData_free(&mesh_dst->vdata, mesh_dst->totvert);
CustomData_free(&mesh_dst->edata, mesh_dst->totedge);
CustomData_free(&mesh_dst->fdata, mesh_dst->totface);
@@ -1481,7 +1477,6 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
int a, totvert = mesh_src->totvert;
float *fp;
- MVert *mvert;
if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) {
return;
@@ -1494,9 +1489,8 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
kb->totelem = totvert;
fp = (float *)kb->data;
- mvert = mesh_src->mvert;
-
- for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
- copy_v3_v3(fp, mvert->co);
+ const Span<MVert> verts = mesh_src->vertices();
+ for (a = 0; a < kb->totelem; a++, fp += 3) {
+ copy_v3_v3(fp, verts[a].co);
}
}
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc
index 9dba8eab340..7e52b96cc92 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.cc
+++ b/source/blender/blenkernel/intern/mesh_evaluate.cc
@@ -205,18 +205,13 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const
float BKE_mesh_calc_area(const Mesh *me)
{
- MVert *mvert = me->mvert;
- MLoop *mloop = me->mloop;
- MPoly *mpoly = me->mpoly;
+ const Span<MVert> verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
- MPoly *mp;
- int i = me->totpoly;
- float total_area = 0;
-
- for (mp = mpoly; i--; mp++) {
- MLoop *ml_start = &mloop[mp->loopstart];
-
- total_area += BKE_mesh_calc_poly_area(mp, ml_start, mvert);
+ float total_area = 0.0f;
+ for (const MPoly &poly : polys) {
+ total_area += BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data());
}
return total_area;
}
@@ -405,11 +400,10 @@ void BKE_mesh_poly_edgebitmap_insert(uint *edge_bitmap, const MPoly *mp, const M
bool BKE_mesh_center_median(const Mesh *me, float r_cent[3])
{
- int i = me->totvert;
- const MVert *mvert;
+ const Span<MVert> verts = me->vertices();
zero_v3(r_cent);
- for (mvert = me->mvert; i--; mvert++) {
- add_v3_v3(r_cent, mvert->co);
+ for (const MVert &vert : verts) {
+ add_v3_v3(r_cent, vert.co);
}
/* otherwise we get NAN for 0 verts */
if (me->totvert) {
@@ -420,18 +414,17 @@ bool BKE_mesh_center_median(const Mesh *me, float r_cent[3])
bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3])
{
- int i = me->totpoly;
int tot = 0;
- const MPoly *mpoly = me->mpoly;
- const MLoop *mloop = me->mloop;
- const MVert *mvert = me->mvert;
+ const Span<MVert> verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
zero_v3(r_cent);
- for (; i--; mpoly++) {
- int loopend = mpoly->loopstart + mpoly->totloop;
- for (int j = mpoly->loopstart; j < loopend; j++) {
- add_v3_v3(r_cent, mvert[mloop[j].v].co);
+ for (const MPoly &poly : polys) {
+ int loopend = poly.loopstart + poly.totloop;
+ for (int j = poly.loopstart; j < loopend; j++) {
+ add_v3_v3(r_cent, verts[loops[j].v].co);
}
- tot += mpoly->totloop;
+ tot += poly.totloop;
}
/* otherwise we get NAN for 0 verts */
if (me->totpoly) {
@@ -455,17 +448,19 @@ bool BKE_mesh_center_bounds(const Mesh *me, float r_cent[3])
bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
{
int i = me->totpoly;
- MPoly *mpoly;
+ const MPoly *mpoly;
float poly_area;
float total_area = 0.0f;
float poly_cent[3];
+ const MVert *verts = BKE_mesh_vertices(me);
+ const MPoly *polys = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
zero_v3(r_cent);
/* calculate a weighted average of polygon centroids */
- for (mpoly = me->mpoly; i--; mpoly++) {
- poly_area = mesh_calc_poly_area_centroid(
- mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
+ for (mpoly = polys; i--; mpoly++) {
+ poly_area = mesh_calc_poly_area_centroid(mpoly, loops + mpoly->loopstart, verts, poly_cent);
madd_v3_v3fl(r_cent, poly_cent, poly_area);
total_area += poly_area;
@@ -486,10 +481,13 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3])
bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
{
int i = me->totpoly;
- MPoly *mpoly;
+ const MPoly *mpoly;
float poly_volume;
float total_volume = 0.0f;
float poly_cent[3];
+ const MVert *verts = BKE_mesh_vertices(me);
+ const MPoly *polys = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
/* Use an initial center to avoid numeric instability of geometry far away from the center. */
float init_cent[3];
@@ -498,9 +496,9 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3])
zero_v3(r_cent);
/* calculate a weighted average of polyhedron centroids */
- for (mpoly = me->mpoly; i--; mpoly++) {
+ for (mpoly = polys; i--; mpoly++) {
poly_volume = mesh_calc_poly_volume_centroid_with_reference_center(
- mpoly, me->mloop + mpoly->loopstart, me->mvert, init_cent, poly_cent);
+ mpoly, loops + mpoly->loopstart, verts, init_cent, poly_cent);
/* poly_cent is already volume-weighted, so no need to multiply by the volume */
add_v3_v3(r_cent, poly_cent);
@@ -670,7 +668,7 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
}
}
-void BKE_mesh_polygon_flip_ex(MPoly *mpoly,
+void BKE_mesh_polygon_flip_ex(const MPoly *mpoly,
MLoop *mloop,
CustomData *ldata,
float (*lnors)[3],
@@ -713,16 +711,16 @@ void BKE_mesh_polygon_flip_ex(MPoly *mpoly,
}
}
-void BKE_mesh_polygon_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata)
+void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata)
{
MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS);
BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true);
}
-void BKE_mesh_polygons_flip(MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
+void BKE_mesh_polygons_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly)
{
MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS);
- MPoly *mp;
+ const MPoly *mp;
int i;
for (mp = mpoly, i = 0; i < totpoly; mp++, i++) {
@@ -748,9 +746,9 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
return;
}
const VArraySpan<bool> hide_vert_span{hide_vert};
- const Span<MEdge> edges(me->medge, me->totedge);
- const Span<MPoly> polys(me->mpoly, me->totpoly);
- const Span<MLoop> loops(me->mloop, me->totloop);
+ const Span<MEdge> edges = me->edges();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
/* Hide edges when either of their vertices are hidden. */
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -788,8 +786,8 @@ void BKE_mesh_flush_hidden_from_polys(Mesh *me)
return;
}
const VArraySpan<bool> hide_poly_span{hide_poly};
- const Span<MPoly> polys(me->mpoly, me->totpoly);
- const Span<MLoop> loops(me->mloop, me->totloop);
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -859,8 +857,13 @@ void BKE_mesh_flush_select_from_polys_ex(MVert *mvert,
}
void BKE_mesh_flush_select_from_polys(Mesh *me)
{
- BKE_mesh_flush_select_from_polys_ex(
- me->mvert, me->totvert, me->mloop, me->medge, me->totedge, me->mpoly, me->totpoly);
+ BKE_mesh_flush_select_from_polys_ex(me->vertices_for_write().data(),
+ me->totvert,
+ me->loops().data(),
+ me->edges_for_write().data(),
+ me->totedge,
+ me->polygons().data(),
+ me->totpoly);
}
static void mesh_flush_select_from_verts(const Span<MVert> verts,
@@ -906,12 +909,12 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
{
const blender::bke::AttributeAccessor attributes = blender::bke::mesh_attributes(*me);
mesh_flush_select_from_verts(
- {me->mvert, me->totvert},
- {me->mloop, me->totloop},
+ me->vertices(),
+ me->loops(),
attributes.lookup_or_default<bool>(".hide_edge", ATTR_DOMAIN_EDGE, false),
attributes.lookup_or_default<bool>(".hide_poly", ATTR_DOMAIN_FACE, false),
- {me->medge, me->totedge},
- {me->mpoly, me->totpoly});
+ me->edges_for_write(),
+ me->polygons_for_write());
}
/** \} */
diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc
index 8936d7b0ba6..0fe58366449 100644
--- a/source/blender/blenkernel/intern/mesh_fair.cc
+++ b/source/blender/blenkernel/intern/mesh_fair.cc
@@ -27,6 +27,8 @@
#include "eigen_capi.h"
using blender::Map;
+using blender::MutableSpan;
+using blender::Span;
using blender::Vector;
using std::array;
@@ -193,13 +195,14 @@ class MeshFairingContext : public FairingContext {
totvert_ = mesh->totvert;
totloop_ = mesh->totloop;
- medge_ = mesh->medge;
- mpoly_ = mesh->mpoly;
- mloop_ = mesh->mloop;
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ medge_ = mesh->edges();
+ mpoly_ = mesh->polygons();
+ mloop_ = mesh->loops();
BKE_mesh_vert_loop_map_create(&vlmap_,
&vlmap_mem_,
- mesh->mpoly,
- mesh->mloop,
+ mpoly_.data(),
+ mloop_.data(),
mesh->totvert,
mesh->totpoly,
mesh->totloop);
@@ -213,14 +216,14 @@ class MeshFairingContext : public FairingContext {
}
else {
for (int i = 0; i < mesh->totvert; i++) {
- co_[i] = mesh->mvert[i].co;
+ co_[i] = verts[i].co;
}
}
loop_to_poly_map_.reserve(mesh->totloop);
for (int i = 0; i < mesh->totpoly; i++) {
- for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
- loop_to_poly_map_[l + mesh->mpoly[i].loopstart] = i;
+ for (int l = 0; l < mpoly_[i].totloop; l++) {
+ loop_to_poly_map_[l + mpoly_[i].loopstart] = i;
}
}
}
@@ -244,7 +247,7 @@ class MeshFairingContext : public FairingContext {
int other_vertex_index_from_loop(const int loop, const uint v) override
{
- MEdge *e = &medge_[mloop_[loop].e];
+ const MEdge *e = &medge_[mloop_[loop].e];
if (e->v1 == v) {
return e->v2;
}
@@ -253,9 +256,9 @@ class MeshFairingContext : public FairingContext {
protected:
Mesh *mesh_;
- MLoop *mloop_;
- MPoly *mpoly_;
- MEdge *medge_;
+ Span<MLoop> mloop_;
+ Span<MPoly> mpoly_;
+ Span<MEdge> medge_;
Vector<int> loop_to_poly_map_;
};
diff --git a/source/blender/blenkernel/intern/mesh_iterators.c b/source/blender/blenkernel/intern/mesh_iterators.c
index 77e62918441..352ad8e9042 100644
--- a/source/blender/blenkernel/intern/mesh_iterators.c
+++ b/source/blender/blenkernel/intern/mesh_iterators.c
@@ -65,7 +65,7 @@ void BKE_mesh_foreach_mapped_vert(
}
}
else {
- const MVert *mv = mesh->mvert;
+ const MVert *mv = BKE_mesh_vertices(mesh);
const int *index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
BKE_mesh_vertex_normals_ensure(mesh) :
@@ -120,8 +120,8 @@ void BKE_mesh_foreach_mapped_edge(
}
}
else {
- const MVert *mv = mesh->mvert;
- const MEdge *med = mesh->medge;
+ const MVert *mv = BKE_mesh_vertices(mesh);
+ const MEdge *med = BKE_mesh_edges(mesh);
const int *index = CustomData_get_layer(&mesh->edata, CD_ORIGINDEX);
if (index) {
@@ -188,9 +188,9 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh,
CustomData_get_layer(&mesh->ldata, CD_NORMAL) :
NULL;
- const MVert *mv = mesh->mvert;
- const MLoop *ml = mesh->mloop;
- const MPoly *mp = mesh->mpoly;
+ const MVert *mv = BKE_mesh_vertices(mesh);
+ const MLoop *ml = BKE_mesh_loops(mesh);
+ const MPoly *mp = BKE_mesh_polygons(mesh);
const int *v_index = CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX);
const int *f_index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
int p_idx, i;
@@ -261,8 +261,9 @@ void BKE_mesh_foreach_mapped_face_center(
}
}
else {
- const MVert *mvert = mesh->mvert;
- const MPoly *mp = mesh->mpoly;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
+ const MPoly *mp = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
float _no_buf[3];
float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : NULL;
@@ -275,7 +276,7 @@ void BKE_mesh_foreach_mapped_face_center(
continue;
}
float cent[3];
- ml = &mesh->mloop[mp->loopstart];
+ ml = &loops[mp->loopstart];
BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(mp, ml, mvert, no);
@@ -286,7 +287,7 @@ void BKE_mesh_foreach_mapped_face_center(
else {
for (int i = 0; i < mesh->totpoly; i++, mp++) {
float cent[3];
- ml = &mesh->mloop[mp->loopstart];
+ ml = &loops[mp->loopstart];
BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
if (flag & MESH_FOREACH_USE_NORMAL) {
BKE_mesh_calc_poly_normal(mp, ml, mvert, no);
@@ -303,7 +304,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
void *userData,
MeshForeachFlag flag)
{
- const MPoly *mp = mesh->mpoly;
+ const MVert *verts = BKE_mesh_vertices(mesh);
+ const MPoly *mp = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
const MLoop *ml;
const MVert *mv;
const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ?
@@ -319,9 +322,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
if (orig == ORIGINDEX_NONE) {
continue;
}
- ml = &mesh->mloop[mp->loopstart];
+ ml = &loops[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
- mv = &mesh->mvert[ml->v];
+ mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
func(userData,
orig,
@@ -333,9 +336,9 @@ void BKE_mesh_foreach_mapped_subdiv_face_center(
}
else {
for (int i = 0; i < mesh->totpoly; i++, mp++) {
- ml = &mesh->mloop[mp->loopstart];
+ ml = &loops[mp->loopstart];
for (int j = 0; j < mp->totloop; j++, ml++) {
- mv = &mesh->mvert[ml->v];
+ mv = &verts[ml->v];
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
func(userData, i, mv->co, (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : NULL);
}
diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
index 58096081ad1..c2a4b0176c6 100644
--- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc
@@ -23,6 +23,7 @@
#include "BKE_attribute.hh"
#include "BKE_customdata.h"
+#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_mesh_legacy_convert.h"
#include "BKE_multires.h"
@@ -165,9 +166,7 @@ static void convert_mfaces_to_mpolys(ID *id,
MEdge *medge,
MFace *mface,
int *r_totloop,
- int *r_totpoly,
- MLoop **r_mloop,
- MPoly **r_mpoly)
+ int *r_totpoly)
{
MFace *mf;
MLoop *ml, *mloop;
@@ -185,8 +184,7 @@ static void convert_mfaces_to_mpolys(ID *id,
CustomData_free(pdata, totpoly_i);
totpoly = totface_i;
- mpoly = (MPoly *)MEM_calloc_arrayN((size_t)totpoly, sizeof(MPoly), "mpoly converted");
- CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, totpoly);
+ mpoly = (MPoly *)CustomData_add_layer(pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly);
int *material_indices = static_cast<int *>(
CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index"));
if (material_indices == nullptr) {
@@ -203,9 +201,7 @@ static void convert_mfaces_to_mpolys(ID *id,
totloop += mf->v4 ? 4 : 3;
}
- mloop = (MLoop *)MEM_calloc_arrayN((size_t)totloop, sizeof(MLoop), "mloop converted");
-
- CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop);
+ mloop = (MLoop *)CustomData_add_layer(ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, totloop);
CustomData_to_bmeshpoly(fdata, ldata, totloop);
@@ -277,12 +273,51 @@ static void convert_mfaces_to_mpolys(ID *id,
*r_totpoly = totpoly;
*r_totloop = totloop;
- *r_mpoly = mpoly;
- *r_mloop = mloop;
#undef ME_FGON
}
+static void mesh_ensure_tessellation_customdata(Mesh *me)
+{
+ if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
+ /* Pass, otherwise this function clears 'mface' before
+ * versioning 'mface -> mpoly' code kicks in T30583.
+ *
+ * Callers could also check but safer to do here - campbell */
+ }
+ else {
+ const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
+ const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
+
+ const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+ const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL);
+
+ if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) {
+ BKE_mesh_tessface_clear(me);
+
+ BKE_mesh_add_mface_layers(&me->fdata, &me->ldata, me->totface);
+
+ /* TODO: add some `--debug-mesh` option. */
+ if (G.debug & G_DEBUG) {
+ /* NOTE(campbell): this warning may be un-called for if we are initializing the mesh for
+ * the first time from #BMesh, rather than giving a warning about this we could be smarter
+ * and check if there was any data to begin with, for now just print the warning with
+ * some info to help troubleshoot what's going on. */
+ printf(
+ "%s: warning! Tessellation uvs or vcol data got out of sync, "
+ "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != "
+ "CD_PROP_BYTE_COLOR: "
+ "%d\n",
+ __func__,
+ tottex_tessface,
+ tottex_original,
+ totcol_tessface,
+ totcol_original);
+ }
+ }
+ }
+}
+
void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
{
convert_mfaces_to_mpolys(&mesh->id,
@@ -293,14 +328,12 @@ void BKE_mesh_convert_mfaces_to_mpolys(Mesh *mesh)
mesh->totface,
mesh->totloop,
mesh->totpoly,
- mesh->medge,
- mesh->mface,
+ mesh->edges_for_write().data(),
+ (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
&mesh->totloop,
- &mesh->totpoly,
- &mesh->mloop,
- &mesh->mpoly);
+ &mesh->totpoly);
- BKE_mesh_update_customdata_pointers(mesh, true);
+ mesh_ensure_tessellation_customdata(mesh);
}
/**
@@ -352,16 +385,14 @@ void BKE_mesh_do_versions_convert_mfaces_to_mpolys(Mesh *mesh)
mesh->totface,
mesh->totloop,
mesh->totpoly,
- mesh->medge,
- mesh->mface,
+ mesh->edges_for_write().data(),
+ (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE),
&mesh->totloop,
- &mesh->totpoly,
- &mesh->mloop,
- &mesh->mpoly);
+ &mesh->totpoly);
CustomData_bmesh_do_versions_update_active_layers(&mesh->fdata, &mesh->ldata);
- BKE_mesh_update_customdata_pointers(mesh, true);
+ mesh_ensure_tessellation_customdata(mesh);
}
/** \} */
@@ -793,12 +824,12 @@ void BKE_mesh_tessface_calc(Mesh *mesh)
mesh->totface = mesh_tessface_calc(&mesh->fdata,
&mesh->ldata,
&mesh->pdata,
- mesh->mvert,
+ BKE_mesh_vertices_for_write(mesh),
mesh->totface,
mesh->totloop,
mesh->totpoly);
- BKE_mesh_update_customdata_pointers(mesh, true);
+ mesh_ensure_tessellation_customdata(mesh);
}
void BKE_mesh_tessface_ensure(struct Mesh *mesh)
@@ -896,7 +927,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
using namespace blender::bke;
const AttributeAccessor attributes = mesh_attributes(*mesh);
- MutableSpan<MVert> verts(mesh->mvert, mesh->totvert);
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) {
@@ -905,7 +936,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
}
});
- MutableSpan<MEdge> edges(mesh->medge, mesh->totedge);
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
const VArray<bool> hide_edge = attributes.lookup_or_default<bool>(
".hide_edge", ATTR_DOMAIN_EDGE, false);
threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) {
@@ -914,7 +945,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh)
}
});
- MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ MutableSpan<MPoly> polys = mesh->polygons_for_write();
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
@@ -930,7 +961,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
- const Span<MVert> verts(mesh->mvert, mesh->totvert);
+ const Span<MVert> verts = mesh->vertices();
if (std::any_of(
verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag & ME_HIDE; })) {
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -943,7 +974,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
hide_vert.finish();
}
- const Span<MEdge> edges(mesh->medge, mesh->totedge);
+ const Span<MEdge> edges = mesh->edges();
if (std::any_of(
edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_HIDE; })) {
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -956,7 +987,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh)
hide_edge.finish();
}
- const Span<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ const Span<MPoly> polys = mesh->polygons();
if (std::any_of(
polys.begin(), polys.end(), [](const MPoly &poly) { return poly.flag & ME_HIDE; })) {
SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
@@ -980,7 +1011,7 @@ void BKE_mesh_legacy_convert_material_indices_to_mpoly(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
const AttributeAccessor attributes = mesh_attributes(*mesh);
- MutableSpan<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ MutableSpan<MPoly> polys = mesh->polygons_for_write();
const VArray<int> material_indices = attributes.lookup_or_default<int>(
"material_index", ATTR_DOMAIN_FACE, 0);
threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) {
@@ -995,7 +1026,7 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh)
using namespace blender;
using namespace blender::bke;
MutableAttributeAccessor attributes = mesh_attributes_for_write(*mesh);
- const Span<MPoly> polys(mesh->mpoly, mesh->totpoly);
+ const Span<MPoly> polys = mesh->polygons();
if (std::any_of(
polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr != 0; })) {
SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_only_span<int>(
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 798fe087ea8..f57effd49f4 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -976,13 +976,13 @@ static bool mesh_check_island_boundary_uv(const MPoly *UNUSED(mp),
return (me->flag & ME_SEAM) != 0;
}
-static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
+static bool mesh_calc_islands_loop_poly_uv(const MVert *UNUSED(verts),
const int UNUSED(totvert),
- MEdge *edges,
+ const MEdge *edges,
const int totedge,
- MPoly *polys,
+ const MPoly *polys,
const int totpoly,
- MLoop *loops,
+ const MLoop *loops,
const int totloop,
const MLoopUV *luvs,
MeshIslandStore *r_island_store)
@@ -1073,16 +1073,13 @@ static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
}
for (p_idx = 0; p_idx < totpoly; p_idx++) {
- MPoly *mp;
-
if (poly_groups[p_idx] != grp_idx) {
continue;
}
-
- mp = &polys[p_idx];
+ const MPoly *mp = &polys[p_idx];
poly_indices[num_pidx++] = p_idx;
for (l_idx = mp->loopstart, pl_idx = 0; pl_idx < mp->totloop; l_idx++, pl_idx++) {
- MLoop *ml = &loops[l_idx];
+ const MLoop *ml = &loops[l_idx];
loop_indices[num_lidx++] = l_idx;
if (num_edge_borders && BLI_BITMAP_TEST(edge_borders, ml->e) &&
(edge_border_count[ml->e] < 2)) {
@@ -1126,13 +1123,13 @@ static bool mesh_calc_islands_loop_poly_uv(MVert *UNUSED(verts),
return true;
}
-bool BKE_mesh_calc_islands_loop_poly_edgeseam(MVert *verts,
+bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts,
const int totvert,
- MEdge *edges,
+ const MEdge *edges,
const int totedge,
- MPoly *polys,
+ const MPoly *polys,
const int totpoly,
- MLoop *loops,
+ const MLoop *loops,
const int totloop,
MeshIslandStore *r_island_store)
{
diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c
index 4459e2514bc..18fbaaccb92 100644
--- a/source/blender/blenkernel/intern/mesh_merge.c
+++ b/source/blender/blenkernel/intern/mesh_merge.c
@@ -32,9 +32,9 @@
* and may be called again with direct_reverse=-1 for reverse order.
* \return 1 if polys are identical, 0 if polys are different.
*/
-static int cddm_poly_compare(MLoop *mloop_array,
- MPoly *mpoly_source,
- MPoly *mpoly_target,
+static int cddm_poly_compare(const MLoop *mloop_array,
+ const MPoly *mpoly_source,
+ const MPoly *mpoly_target,
const int *vtargetmap,
const int direct_reverse)
{
@@ -44,7 +44,7 @@ static int cddm_poly_compare(MLoop *mloop_array,
bool compare_completed = false;
bool same_loops = false;
- MLoop *mloop_source, *mloop_target;
+ const MLoop *mloop_source, *mloop_target;
BLI_assert(ELEM(direct_reverse, 1, -1));
@@ -203,10 +203,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
const int totedge = mesh->totedge;
const int totloop = mesh->totloop;
const int totpoly = mesh->totpoly;
+ const MVert *src_verts = BKE_mesh_vertices(mesh);
+ const MEdge *src_edges = BKE_mesh_edges(mesh);
+ const MPoly *src_polys = BKE_mesh_polygons(mesh);
+ const MLoop *src_loops = BKE_mesh_loops(mesh);
const int totvert_final = totvert - tot_vtargetmap;
- MVert *mv, *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__);
+ const MVert *mv;
+ MVert *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__);
int *oldv = MEM_malloc_arrayN(totvert_final, sizeof(*oldv), __func__);
int *newv = MEM_malloc_arrayN(totvert, sizeof(*newv), __func__);
STACK_DECLARE(mvert);
@@ -215,13 +220,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* NOTE: create (totedge + totloop) elements because partially invalid polys due to merge may
* require generating new edges, and while in 99% cases we'll still end with less final edges
* than totedge, cases can be forged that would end requiring more. */
- MEdge *med, *medge = MEM_malloc_arrayN((totedge + totloop), sizeof(*medge), __func__);
+ const MEdge *med;
+ MEdge *medge = MEM_malloc_arrayN((totedge + totloop), sizeof(*medge), __func__);
int *olde = MEM_malloc_arrayN((totedge + totloop), sizeof(*olde), __func__);
int *newe = MEM_malloc_arrayN((totedge + totloop), sizeof(*newe), __func__);
STACK_DECLARE(medge);
STACK_DECLARE(olde);
- MLoop *ml, *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__);
+ const MLoop *ml;
+ MLoop *mloop = MEM_malloc_arrayN(totloop, sizeof(*mloop), __func__);
int *oldl = MEM_malloc_arrayN(totloop, sizeof(*oldl), __func__);
#ifdef USE_LOOPS
int *newl = MEM_malloc_arrayN(totloop, sizeof(*newl), __func__);
@@ -229,7 +236,8 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
STACK_DECLARE(mloop);
STACK_DECLARE(oldl);
- MPoly *mp, *mpoly = MEM_malloc_arrayN(totpoly, sizeof(*medge), __func__);
+ const MPoly *mp;
+ MPoly *mpoly = MEM_malloc_arrayN(totpoly, sizeof(*medge), __func__);
int *oldp = MEM_malloc_arrayN(totpoly, sizeof(*oldp), __func__);
STACK_DECLARE(mpoly);
STACK_DECLARE(oldp);
@@ -254,7 +262,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
STACK_INIT(mpoly, totpoly);
/* fill newv with destination vertex indices */
- mv = mesh->mvert;
+ mv = src_verts;
c = 0;
for (i = 0; i < totvert; i++, mv++) {
if (vtargetmap[i] == -1) {
@@ -281,7 +289,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
*/
/* now go through and fix edges and faces */
- med = mesh->medge;
+ med = src_edges;
c = 0;
for (i = 0; i < totedge; i++, med++) {
const uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
@@ -316,12 +324,12 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Duplicates allowed because our compare function is not pure equality */
BLI_gset_flag_set(poly_gset, GHASH_FLAG_ALLOW_DUPES);
- mp = mesh->mpoly;
+ mp = src_polys;
mpgh = poly_keys;
for (i = 0; i < totpoly; i++, mp++, mpgh++) {
mpgh->poly_index = i;
mpgh->totloops = mp->totloop;
- ml = mesh->mloop + mp->loopstart;
+ ml = src_loops + mp->loopstart;
mpgh->hash_sum = mpgh->hash_xor = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
mpgh->hash_sum += ml->v;
@@ -333,17 +341,17 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Can we optimize by reusing an old `pmap`? How do we know an old `pmap` is stale? */
/* When called by `MOD_array.c` the `cddm` has just been created, so it has no valid `pmap`. */
BKE_mesh_vert_poly_map_create(
- &poly_map, &poly_map_mem, mesh->mpoly, mesh->mloop, totvert, totpoly, totloop);
+ &poly_map, &poly_map_mem, src_polys, src_loops, totvert, totpoly, totloop);
} /* done preparing for fast poly compare */
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__);
- mp = mesh->mpoly;
- mv = mesh->mvert;
+ mp = src_polys;
+ mv = src_verts;
for (i = 0; i < totpoly; i++, mp++) {
MPoly *mp_new;
- ml = mesh->mloop + mp->loopstart;
+ ml = src_loops + mp->loopstart;
/* check faces with all vertices merged */
bool all_vertices_merged = true;
@@ -376,7 +384,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Use poly_gset for fast (although not 100% certain) identification of same poly */
/* First, make up a poly_summary structure */
- ml = mesh->mloop + mp->loopstart;
+ ml = src_loops + mp->loopstart;
pkey.hash_sum = pkey.hash_xor = 0;
pkey.totloops = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
@@ -394,17 +402,17 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
*/
/* Consider current loop again */
- ml = mesh->mloop + mp->loopstart;
+ ml = src_loops + mp->loopstart;
/* Consider the target of the loop's first vert */
v_target = vtargetmap[ml->v];
/* Now see if v_target belongs to a poly that shares all vertices with source poly,
* in same order, or reverse order */
for (i_poly = 0; i_poly < poly_map[v_target].count; i_poly++) {
- MPoly *target_poly = mesh->mpoly + *(poly_map[v_target].indices + i_poly);
+ const MPoly *target_poly = src_polys + *(poly_map[v_target].indices + i_poly);
- if (cddm_poly_compare(mesh->mloop, mp, target_poly, vtargetmap, +1) ||
- cddm_poly_compare(mesh->mloop, mp, target_poly, vtargetmap, -1)) {
+ if (cddm_poly_compare(src_loops, mp, target_poly, vtargetmap, +1) ||
+ cddm_poly_compare(src_loops, mp, target_poly, vtargetmap, -1)) {
found = true;
break;
}
@@ -422,7 +430,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
* or they were all merged, but targets do not make up an identical poly,
* the poly is retained.
*/
- ml = mesh->mloop + mp->loopstart;
+ ml = src_loops + mp->loopstart;
c = 0;
MLoop *last_valid_ml = NULL;
@@ -434,9 +442,9 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
const uint mlv = (vtargetmap[ml->v] != -1) ? vtargetmap[ml->v] : ml->v;
#ifndef NDEBUG
{
- MLoop *next_ml = mesh->mloop + mp->loopstart + ((j + 1) % mp->totloop);
+ const MLoop *next_ml = src_loops + mp->loopstart + ((j + 1) % mp->totloop);
uint next_mlv = (vtargetmap[next_ml->v] != -1) ? vtargetmap[next_ml->v] : next_ml->v;
- med = mesh->medge + ml->e;
+ med = src_edges + ml->e;
uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
uint v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
BLI_assert((mlv == v1 && next_mlv == v2) || (mlv == v2 && next_mlv == v1));
@@ -461,7 +469,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
else {
const int new_eidx = STACK_SIZE(medge);
STACK_PUSH(olde, olde[last_valid_ml->e]);
- STACK_PUSH(medge, mesh->medge[last_valid_ml->e]);
+ STACK_PUSH(medge, src_edges[last_valid_ml->e]);
medge[new_eidx].v1 = last_valid_ml->v;
medge[new_eidx].v2 = ml->v;
/* DO NOT change newe mapping,
@@ -515,7 +523,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
else {
const int new_eidx = STACK_SIZE(medge);
STACK_PUSH(olde, olde[last_valid_ml->e]);
- STACK_PUSH(medge, mesh->medge[last_valid_ml->e]);
+ STACK_PUSH(medge, src_edges[last_valid_ml->e]);
medge[new_eidx].v1 = last_valid_ml->v;
medge[new_eidx].v2 = first_valid_ml->v;
/* DO NOT change newe mapping,
@@ -566,25 +574,25 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
mesh, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly));
/* Update edge indices and copy customdata. */
- med = medge;
- for (i = 0; i < result->totedge; i++, med++) {
- BLI_assert(newv[med->v1] != -1);
- med->v1 = newv[med->v1];
- BLI_assert(newv[med->v2] != -1);
- med->v2 = newv[med->v2];
+ MEdge *new_med = medge;
+ for (i = 0; i < result->totedge; i++, new_med++) {
+ BLI_assert(newv[new_med->v1] != -1);
+ new_med->v1 = newv[new_med->v1];
+ BLI_assert(newv[new_med->v2] != -1);
+ new_med->v2 = newv[new_med->v2];
/* Can happen in case vtargetmap contains some double chains, we do not support that. */
- BLI_assert(med->v1 != med->v2);
+ BLI_assert(new_med->v1 != new_med->v2);
CustomData_copy_data(&mesh->edata, &result->edata, olde[i], i, 1);
}
/* Update loop indices and copy customdata. */
- ml = mloop;
- for (i = 0; i < result->totloop; i++, ml++) {
+ MLoop *new_ml = mloop;
+ for (i = 0; i < result->totloop; i++, new_ml++) {
/* Edge remapping has already be done in main loop handling part above. */
- BLI_assert(newv[ml->v] != -1);
- ml->v = newv[ml->v];
+ BLI_assert(newv[new_ml->v] != -1);
+ new_ml->v = newv[new_ml->v];
CustomData_copy_data(&mesh->ldata, &result->ldata, oldl[i], i, 1);
}
@@ -603,16 +611,16 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
/* Copy over data. #CustomData_add_layer can do this, need to look it up. */
if (STACK_SIZE(mvert)) {
- memcpy(result->mvert, mvert, sizeof(MVert) * STACK_SIZE(mvert));
+ memcpy(BKE_mesh_vertices_for_write(result), mvert, sizeof(MVert) * STACK_SIZE(mvert));
}
if (STACK_SIZE(medge)) {
- memcpy(result->medge, medge, sizeof(MEdge) * STACK_SIZE(medge));
+ memcpy(BKE_mesh_edges_for_write(result), medge, sizeof(MEdge) * STACK_SIZE(medge));
}
if (STACK_SIZE(mloop)) {
- memcpy(result->mloop, mloop, sizeof(MLoop) * STACK_SIZE(mloop));
+ memcpy(BKE_mesh_loops_for_write(result), mloop, sizeof(MLoop) * STACK_SIZE(mloop));
}
if (STACK_SIZE(mpoly)) {
- memcpy(result->mpoly, mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
+ memcpy(BKE_mesh_polygons_for_write(result), mpoly, sizeof(MPoly) * STACK_SIZE(mpoly));
}
MEM_freeN(mvert);
diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc
index 7bc429954b0..b253d3f9c46 100644
--- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc
+++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc
@@ -113,8 +113,13 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
int *vert_map_mem;
struct MeshElemMap *vert_to_loop;
- BKE_mesh_vert_loop_map_create(
- &vert_to_loop, &vert_map_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
+ BKE_mesh_vert_loop_map_create(&vert_to_loop,
+ &vert_map_mem,
+ BKE_mesh_polygons(me),
+ BKE_mesh_loops(me),
+ me->totvert,
+ me->totpoly,
+ me->totloop);
Vector<MLoopUV *> mloopuv_layers;
mloopuv_layers.reserve(mloopuv_layers_num);
diff --git a/source/blender/blenkernel/intern/mesh_mirror.c b/source/blender/blenkernel/intern/mesh_mirror.c
index 715a1c9daf9..534c8241820 100644
--- a/source/blender/blenkernel/intern/mesh_mirror.c
+++ b/source/blender/blenkernel/intern/mesh_mirror.c
@@ -211,14 +211,18 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* Subsurf for eg won't have mesh data in the custom-data arrays.
* now add mvert/medge/mpoly layers. */
if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) {
- memcpy(result->mvert, mesh->mvert, sizeof(*result->mvert) * mesh->totvert);
+ memcpy(BKE_mesh_vertices_for_write(result),
+ BKE_mesh_vertices(mesh),
+ sizeof(MVert) * mesh->totvert);
}
if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) {
- memcpy(result->medge, mesh->medge, sizeof(*result->medge) * mesh->totedge);
+ memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge);
}
if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
- memcpy(result->mloop, mesh->mloop, sizeof(*result->mloop) * mesh->totloop);
- memcpy(result->mpoly, mesh->mpoly, sizeof(*result->mpoly) * mesh->totpoly);
+ memcpy(BKE_mesh_loops_for_write(result), BKE_mesh_loops(mesh), sizeof(MLoop) * mesh->totloop);
+ memcpy(BKE_mesh_polygons_for_write(result),
+ BKE_mesh_polygons(mesh),
+ sizeof(MPoly) * mesh->totpoly);
}
/* Copy custom-data to new geometry,
@@ -237,7 +241,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* mirror vertex coordinates */
- mv_prev = result->mvert;
+ mv_prev = BKE_mesh_vertices_for_write(result);
mv = mv_prev + maxVerts;
for (i = 0; i < maxVerts; i++, mv++, mv_prev++) {
mul_m4_v3(mtx, mv->co);
@@ -304,15 +308,15 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* adjust mirrored edge vertex indices */
- me = result->medge + maxEdges;
+ me = BKE_mesh_edges_for_write(result) + maxEdges;
for (i = 0; i < maxEdges; i++, me++) {
me->v1 += maxVerts;
me->v2 += maxVerts;
}
/* adjust mirrored poly loopstart indices, and reverse loop order (normals) */
- mp = result->mpoly + maxPolys;
- ml = result->mloop;
+ mp = BKE_mesh_polygons_for_write(result) + maxPolys;
+ ml = BKE_mesh_loops_for_write(result);
for (i = 0; i < maxPolys; i++, mp++) {
MLoop *ml2;
int j, e;
@@ -341,7 +345,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
}
/* adjust mirrored loop vertex and edge indices */
- ml = result->mloop + maxLoops;
+ ml = BKE_mesh_loops_for_write(result) + maxLoops;
for (i = 0; i < maxLoops; i++, ml++) {
ml->v += maxVerts;
ml->e += maxEdges;
@@ -405,15 +409,15 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* calculate custom normals into loop_normals, then mirror first half into second half */
- BKE_mesh_normals_loop_split(result->mvert,
+ BKE_mesh_normals_loop_split(BKE_mesh_vertices(result),
BKE_mesh_vertex_normals_ensure(result),
result->totvert,
- result->medge,
+ BKE_mesh_edges(result),
result->totedge,
- result->mloop,
+ BKE_mesh_loops(result),
loop_normals,
totloop,
- result->mpoly,
+ BKE_mesh_polygons(result),
BKE_mesh_poly_normals_ensure(result),
totpoly,
true,
@@ -423,9 +427,10 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
NULL);
/* mirroring has to account for loops being reversed in polys in second half */
- mp = result->mpoly;
+ MPoly *result_polys = BKE_mesh_polygons_for_write(result);
+ mp = result_polys;
for (i = 0; i < maxPolys; i++, mp++) {
- MPoly *mpmirror = result->mpoly + maxPolys + i;
+ MPoly *mpmirror = result_polys + maxPolys + i;
int j;
for (j = mp->loopstart; j < mp->loopstart + mp->totloop; j++) {
@@ -446,8 +451,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* handle vgroup stuff */
if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) {
- MDeformVert *dvert = (MDeformVert *)CustomData_get_layer(&result->vdata, CD_MDEFORMVERT) +
- maxVerts;
+ MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result) + maxVerts;
int *flip_map = NULL, flip_map_len = 0;
flip_map = BKE_object_defgroup_flip_map(ob, &flip_map_len, false);
diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc
index f90a2e1b887..7217cbf5880 100644
--- a/source/blender/blenkernel/intern/mesh_normals.cc
+++ b/source/blender/blenkernel/intern/mesh_normals.cc
@@ -37,6 +37,7 @@
#include "atomic_ops.h"
+using blender::MutableSpan;
using blender::Span;
// #define DEBUG_TIME
@@ -368,16 +369,19 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3]
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
+ const Span<MVert> verts = mesh_mutable.vertices();
+ const Span<MPoly> polys = mesh_mutable.polygons();
+ const Span<MLoop> loops = mesh_mutable.loops();
vert_normals = BKE_mesh_vertex_normals_for_write(&mesh_mutable);
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
- BKE_mesh_calc_normals_poly_and_vertex(mesh_mutable.mvert,
- mesh_mutable.totvert,
- mesh_mutable.mloop,
- mesh_mutable.totloop,
- mesh_mutable.mpoly,
- mesh_mutable.totpoly,
+ BKE_mesh_calc_normals_poly_and_vertex(verts.data(),
+ verts.size(),
+ loops.data(),
+ loops.size(),
+ polys.data(),
+ polys.size(),
poly_normals,
vert_normals);
@@ -413,15 +417,18 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3]
/* Isolate task because a mutex is locked and computing normals is multi-threaded. */
blender::threading::isolate_task([&]() {
Mesh &mesh_mutable = *const_cast<Mesh *>(mesh);
+ const Span<MVert> verts = mesh_mutable.vertices();
+ const Span<MPoly> polys = mesh_mutable.polygons();
+ const Span<MLoop> loops = mesh_mutable.loops();
poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable);
- BKE_mesh_calc_normals_poly(mesh_mutable.mvert,
- mesh_mutable.totvert,
- mesh_mutable.mloop,
- mesh_mutable.totloop,
- mesh_mutable.mpoly,
- mesh_mutable.totpoly,
+ BKE_mesh_calc_normals_poly(verts.data(),
+ verts.size(),
+ loops.data(),
+ loops.size(),
+ polys.data(),
+ polys.size(),
poly_normals);
BKE_mesh_poly_normals_clear_dirty(&mesh_mutable);
@@ -940,9 +947,9 @@ void BKE_edges_sharp_from_angle_set(const struct MVert *mverts,
const int UNUSED(numVerts),
struct MEdge *medges,
const int numEdges,
- struct MLoop *mloops,
+ const struct MLoop *mloops,
const int numLoops,
- struct MPoly *mpolys,
+ const struct MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
const float split_angle)
@@ -1600,12 +1607,12 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common
void BKE_mesh_normals_loop_split(const MVert *mverts,
const float (*vert_normals)[3],
const int UNUSED(numVerts),
- MEdge *medges,
+ const MEdge *medges,
const int numEdges,
- MLoop *mloops,
+ const MLoop *mloops,
float (*r_loopnors)[3],
const int numLoops,
- MPoly *mpolys,
+ const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
const bool use_split_normals,
@@ -1628,7 +1635,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts,
int mp_index;
for (mp_index = 0; mp_index < numPolys; mp_index++) {
- MPoly *mp = &mpolys[mp_index];
+ const MPoly *mp = &mpolys[mp_index];
int ml_index = mp->loopstart;
const int ml_index_end = ml_index + mp->totloop;
const bool is_poly_flat = ((mp->flag & ME_SMOOTH) == 0);
@@ -1755,10 +1762,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
const int numVerts,
MEdge *medges,
const int numEdges,
- MLoop *mloops,
+ const MLoop *mloops,
float (*r_custom_loopnors)[3],
const int numLoops,
- MPoly *mpolys,
+ const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
short (*r_clnors_data)[2],
@@ -1852,12 +1859,12 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
}
LinkNode *loops = lnors_spacearr.lspacearr[i]->loops;
- MLoop *prev_ml = nullptr;
+ const MLoop *prev_ml = nullptr;
const float *org_nor = nullptr;
while (loops) {
const int lidx = POINTER_AS_INT(loops->link);
- MLoop *ml = &mloops[lidx];
+ const MLoop *ml = &mloops[lidx];
const int nidx = lidx;
float *nor = r_custom_loopnors[nidx];
@@ -1889,7 +1896,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts,
loops = lnors_spacearr.lspacearr[i]->loops;
if (loops && org_nor) {
const int lidx = POINTER_AS_INT(loops->link);
- MLoop *ml = &mloops[lidx];
+ const MLoop *ml = &mloops[lidx];
const int nidx = lidx;
float *nor = r_custom_loopnors[nidx];
@@ -1992,10 +1999,10 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts,
const int numVerts,
MEdge *medges,
const int numEdges,
- MLoop *mloops,
+ const MLoop *mloops,
float (*r_custom_loopnors)[3],
const int numLoops,
- MPoly *mpolys,
+ const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
short (*r_clnors_data)[2])
@@ -2021,9 +2028,9 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(const MVert *mverts,
const int numVerts,
MEdge *medges,
const int numEdges,
- MLoop *mloops,
+ const MLoop *mloops,
const int numLoops,
- MPoly *mpolys,
+ const MPoly *mpolys,
const float (*polynors)[3],
const int numPolys,
short (*r_clnors_data)[2])
@@ -2056,18 +2063,22 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const
clnors = (short(*)[2])CustomData_add_layer(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, numloops);
}
+ const Span<MVert> verts = mesh->vertices();
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ const Span<MPoly> polys = mesh->polygons();
+ const Span<MLoop> loops = mesh->loops();
- mesh_normals_loop_custom_set(mesh->mvert,
+ mesh_normals_loop_custom_set(verts.data(),
BKE_mesh_vertex_normals_ensure(mesh),
- mesh->totvert,
- mesh->medge,
- mesh->totedge,
- mesh->mloop,
+ verts.size(),
+ edges.data(),
+ edges.size(),
+ loops.data(),
r_custom_nors,
- mesh->totloop,
- mesh->mpoly,
+ loops.size(),
+ polys.data(),
BKE_mesh_poly_normals_ensure(mesh),
- mesh->totpoly,
+ polys.size(),
clnors,
use_vertices);
}
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index 4c6ee0ae3ee..cdb8bc96dda 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -377,7 +377,7 @@ void BKE_mesh_remap_item_define_invalid(MeshPairRemap *map, const int index)
}
static int mesh_remap_interp_poly_data_get(const MPoly *mp,
- MLoop *mloops,
+ const MLoop *mloops,
const float (*vcos_src)[3],
const float point[3],
size_t *buff_size,
@@ -388,7 +388,7 @@ static int mesh_remap_interp_poly_data_get(const MPoly *mp,
const bool do_weights,
int *r_closest_index)
{
- MLoop *ml;
+ const MLoop *ml;
float(*vco)[3];
float ref_dist_sq = FLT_MAX;
int *index;
@@ -520,7 +520,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
}
}
else if (ELEM(mode, MREMAP_MODE_VERT_EDGE_NEAREST, MREMAP_MODE_VERT_EDGEINTERP_NEAREST)) {
- MEdge *edges_src = me_src->medge;
+ const MEdge *edges_src = BKE_mesh_edges(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2);
@@ -536,7 +536,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
- MEdge *me = &edges_src[nearest.index];
+ const MEdge *me = &edges_src[nearest.index];
const float *v1cos = vcos_src[me->v1];
const float *v2cos = vcos_src[me->v2];
@@ -573,8 +573,8 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
MREMAP_MODE_VERT_POLY_NEAREST,
MREMAP_MODE_VERT_POLYINTERP_NEAREST,
MREMAP_MODE_VERT_POLYINTERP_VNORPROJ)) {
- MPoly *polys_src = me_src->mpoly;
- MLoop *loops_src = me_src->mloop;
+ const MPoly *polys_src = BKE_mesh_polygons(me_src);
+ const MLoop *loops_src = BKE_mesh_loops(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst);
@@ -599,7 +599,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_raycast(
&treedata, &rayhit, tmp_co, tmp_no, ray_radius, max_dist, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[rayhit.index];
- MPoly *mp_src = &polys_src[lt->poly];
+ const MPoly *mp_src = &polys_src[lt->poly];
const int sources_num = mesh_remap_interp_poly_data_get(mp_src,
loops_src,
(const float(*)[3])vcos_src,
@@ -634,7 +634,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[nearest.index];
- MPoly *mp = &polys_src[lt->poly];
+ const MPoly *mp = &polys_src[lt->poly];
if (mode == MREMAP_MODE_VERT_POLY_NEAREST) {
int index;
@@ -726,7 +726,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
if (mode == MREMAP_MODE_EDGE_VERT_NEAREST) {
const int num_verts_src = me_src->totvert;
const int num_edges_src = me_src->totedge;
- MEdge *edges_src = me_src->medge;
+ const MEdge *edges_src = BKE_mesh_edges(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
MeshElemMap *vert_to_edge_src_map;
@@ -797,7 +797,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
k = vert_to_edge_src_map[vidx_src].count;
for (; k--; eidx_src++) {
- MEdge *e_src = &edges_src[*eidx_src];
+ const MEdge *e_src = &edges_src[*eidx_src];
const float *other_co_src = vcos_src[BKE_mesh_edge_other_vert(e_src, vidx_src)];
const float *other_co_dst =
verts_dst[BKE_mesh_edge_other_vert(e_dst, (int)vidx_dst)].co;
@@ -873,9 +873,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
}
}
else if (mode == MREMAP_MODE_EDGE_POLY_NEAREST) {
- MEdge *edges_src = me_src->medge;
- MPoly *polys_src = me_src->mpoly;
- MLoop *loops_src = me_src->mloop;
+ const MEdge *edges_src = BKE_mesh_edges(me_src);
+ const MPoly *polys_src = BKE_mesh_polygons(me_src);
+ const MLoop *loops_src = BKE_mesh_loops(me_src);
float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL);
BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_LOOPTRI, 2);
@@ -891,14 +891,14 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
if (mesh_remap_bvhtree_query_nearest(
&treedata, &nearest, tmp_co, max_dist_sq, &hit_dist)) {
const MLoopTri *lt = &treedata.looptri[nearest.index];
- MPoly *mp_src = &polys_src[lt->poly];
- MLoop *ml_src = &loops_src[mp_src->loopstart];
+ const MPoly *mp_src = &polys_src[lt->poly];
+ const MLoop *ml_src = &loops_src[mp_src->loopstart];
int nloops = mp_src->totloop;
float best_dist_sq = FLT_MAX;
int best_eidx_src = -1;
for (; nloops--; ml_src++) {
- MEdge *med_src = &edges_src[ml_src->e];
+ const MEdge *med_src = &edges_src[ml_src->e];
float *co1_src = vcos_src[med_src->v1];
float *co2_src = vcos_src[med_src->v2];
float co_src[3];
@@ -1041,9 +1041,9 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode,
static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
const int island_index,
BLI_AStarGraph *as_graph,
- MVert *verts,
- MPoly *polys,
- MLoop *loops,
+ const MVert *verts,
+ const MPoly *polys,
+ const MLoop *loops,
const int edge_idx,
BLI_bitmap *done_edges,
MeshElemMap *edge_to_poly_map,
@@ -1058,7 +1058,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
for (i = 0; i < edge_to_poly_map[edge_idx].count; i++) {
const int pidx = edge_to_poly_map[edge_idx].indices[i];
- MPoly *mp = &polys[pidx];
+ const MPoly *mp = &polys[pidx];
const int pidx_isld = islands ? poly_island_index_map[pidx] : pidx;
void *custom_data = is_edge_innercut ? POINTER_FROM_INT(edge_idx) : POINTER_FROM_INT(-1);
@@ -1099,11 +1099,11 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands,
static void mesh_island_to_astar_graph(MeshIslandStore *islands,
const int island_index,
- MVert *verts,
+ const MVert *verts,
MeshElemMap *edge_to_poly_map,
const int numedges,
- MLoop *loops,
- MPoly *polys,
+ const MLoop *loops,
+ const MPoly *polys,
const int numpolys,
BLI_AStarGraph *r_as_graph)
{
@@ -1153,7 +1153,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
for (pidx_isld = node_num; pidx_isld--;) {
const int pidx = islands ? island_poly_map->indices[pidx_isld] : pidx_isld;
- MPoly *mp = &polys[pidx];
+ const MPoly *mp = &polys[pidx];
int pl_idx, l_idx;
if (poly_status[pidx_isld] == POLY_COMPLETE) {
@@ -1161,7 +1161,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands,
}
for (pl_idx = 0, l_idx = mp->loopstart; pl_idx < mp->totloop; pl_idx++, l_idx++) {
- MLoop *ml = &loops[l_idx];
+ const MLoop *ml = &loops[l_idx];
if (BLI_BITMAP_TEST(done_edges, ml->e)) {
continue;
@@ -1229,13 +1229,13 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
const float max_dist,
const float ray_radius,
Mesh *mesh_dst,
- MVert *verts_dst,
+ const MVert *verts_dst,
const int numverts_dst,
- MEdge *edges_dst,
+ const MEdge *edges_dst,
const int numedges_dst,
- MLoop *loops_dst,
+ const MLoop *loops_dst,
const int numloops_dst,
- MPoly *polys_dst,
+ const MPoly *polys_dst,
const int numpolys_dst,
CustomData *ldata_dst,
const bool use_split_nors_dst,
@@ -1302,14 +1302,14 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
/* Unlike above, those are one-to-one mappings, simpler! */
int *loop_to_poly_map_src = NULL;
- MVert *verts_src = me_src->mvert;
+ const MVert *verts_src = BKE_mesh_vertices(me_src);
const int num_verts_src = me_src->totvert;
float(*vcos_src)[3] = NULL;
- MEdge *edges_src = me_src->medge;
+ const MEdge *edges_src = BKE_mesh_edges(me_src);
const int num_edges_src = me_src->totedge;
- MLoop *loops_src = me_src->mloop;
+ const MLoop *loops_src = BKE_mesh_loops(me_src);
const int num_loops_src = me_src->totloop;
- MPoly *polys_src = me_src->mpoly;
+ const MPoly *polys_src = BKE_mesh_polygons(me_src);
const int num_polys_src = me_src->totpoly;
const MLoopTri *looptri_src = NULL;
int num_looptri_src = 0;
@@ -1319,8 +1319,10 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode,
int *indices_interp = NULL;
float *weights_interp = NULL;
- MLoop *ml_src, *ml_dst;
- MPoly *mp_src, *mp_dst;
+ const MLoop *ml_src;
+ const MLoop *ml_dst;
+ const MPoly *mp_src;
+ const MPoly *mp_dst;
int tindex, pidx_dst, lidx_dst, plidx_dst, pidx_src, lidx_src, plidx_src;
IslandResult **islands_res;
@@ -2148,10 +2150,10 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
const SpaceTransform *space_transform,
const float max_dist,
const float ray_radius,
- Mesh *mesh_dst,
- MVert *verts_dst,
- MLoop *loops_dst,
- MPoly *polys_dst,
+ const Mesh *mesh_dst,
+ const MVert *verts_dst,
+ const MLoop *loops_dst,
+ const MPoly *polys_dst,
const int numpolys_dst,
Mesh *me_src,
MeshPairRemap *r_map)
@@ -2188,7 +2190,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
nearest.index = -1;
for (i = 0; i < numpolys_dst; i++) {
- MPoly *mp = &polys_dst[i];
+ const MPoly *mp = &polys_dst[i];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
@@ -2213,7 +2215,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
BLI_assert(poly_nors_dst);
for (i = 0; i < numpolys_dst; i++) {
- MPoly *mp = &polys_dst[i];
+ const MPoly *mp = &polys_dst[i];
BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co);
copy_v3_v3(tmp_no, poly_nors_dst[i]);
@@ -2259,7 +2261,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
/* For each dst poly, we sample some rays from it (2D grid in pnor space)
* and use their hits to interpolate from source polys. */
/* NOTE: dst poly is early-converted into src space! */
- MPoly *mp = &polys_dst[i];
+ const MPoly *mp = &polys_dst[i];
int tot_rays, done_rays = 0;
float poly_area_2d_inv, done_area = 0.0f;
@@ -2302,7 +2304,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode,
INIT_MINMAX2(poly_dst_2d_min, poly_dst_2d_max);
for (j = 0; j < mp->totloop; j++) {
- MLoop *ml = &loops_dst[j + mp->loopstart];
+ const MLoop *ml = &loops_dst[j + mp->loopstart];
copy_v3_v3(tmp_co, verts_dst[ml->v].co);
if (space_transform) {
BLI_space_transform_apply(space_transform, tmp_co);
diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
index 5a4fd0d7d96..1b583b6a851 100644
--- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
+++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc
@@ -61,14 +61,15 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
void (*update_cb)(void *, float progress, int *cancel),
void *update_cb_data)
{
- /* Ensure that the triangulated mesh data is up to data */
+ const Span<MVert> input_verts = input_mesh->vertices();
+ const Span<MLoop> input_loops = input_mesh->loops();
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh);
/* Gather the required data for export to the internal quadriflow mesh format. */
MVertTri *verttri = (MVertTri *)MEM_callocN(
sizeof(*verttri) * BKE_mesh_runtime_looptri_len(input_mesh), "remesh_looptri");
BKE_mesh_runtime_verttri_from_looptri(
- verttri, input_mesh->mloop, looptri, BKE_mesh_runtime_looptri_len(input_mesh));
+ verttri, input_loops.data(), looptri, BKE_mesh_runtime_looptri_len(input_mesh));
const int totfaces = BKE_mesh_runtime_looptri_len(input_mesh);
const int totverts = input_mesh->totvert;
@@ -76,7 +77,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
Array<int> faces(totfaces * 3);
for (const int i : IndexRange(totverts)) {
- verts[i] = input_mesh->mvert[i].co;
+ verts[i] = input_verts[i].co;
}
for (const int i : IndexRange(totfaces)) {
@@ -123,20 +124,23 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh,
/* Construct the new output mesh */
Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, 0, qrd.out_totfaces * 4, qrd.out_totfaces);
+ MutableSpan<MVert> mesh_verts = mesh->vertices_for_write();
+ MutableSpan<MPoly> polys = mesh->polygons_for_write();
+ MutableSpan<MLoop> loops = mesh->loops_for_write();
for (const int i : IndexRange(qrd.out_totverts)) {
- copy_v3_v3(mesh->mvert[i].co, &qrd.out_verts[i * 3]);
+ copy_v3_v3(mesh_verts[i].co, &qrd.out_verts[i * 3]);
}
for (const int i : IndexRange(qrd.out_totfaces)) {
- MPoly &poly = mesh->mpoly[i];
+ MPoly &poly = polys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
- mesh->mloop[loopstart].v = qrd.out_faces[loopstart];
- mesh->mloop[loopstart + 1].v = qrd.out_faces[loopstart + 1];
- mesh->mloop[loopstart + 2].v = qrd.out_faces[loopstart + 2];
- mesh->mloop[loopstart + 3].v = qrd.out_faces[loopstart + 3];
+ loops[loopstart].v = qrd.out_faces[loopstart];
+ loops[loopstart + 1].v = qrd.out_faces[loopstart + 1];
+ loops[loopstart + 2].v = qrd.out_faces[loopstart + 2];
+ loops[loopstart + 3].v = qrd.out_faces[loopstart + 3];
}
BKE_mesh_calc_edges(mesh, false, false);
@@ -186,7 +190,8 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh,
static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
const float voxel_size)
{
- Span<MLoop> mloop{mesh->mloop, mesh->totloop};
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MLoop> loops = mesh->loops();
Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh),
BKE_mesh_runtime_looptri_len(mesh)};
@@ -194,14 +199,14 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh,
std::vector<openvdb::Vec3I> triangles(looptris.size());
for (const int i : IndexRange(mesh->totvert)) {
- const float3 co = mesh->mvert[i].co;
+ const float3 co = verts[i].co;
points[i] = openvdb::Vec3s(co.x, co.y, co.z);
}
for (const int i : IndexRange(looptris.size())) {
const MLoopTri &loop_tri = looptris[i];
triangles[i] = openvdb::Vec3I(
- mloop[loop_tri.tri[0]].v, mloop[loop_tri.tri[1]].v, mloop[loop_tri.tri[2]].v);
+ loops[loop_tri.tri[0]].v, loops[loop_tri.tri[1]].v, loops[loop_tri.tri[2]].v);
}
openvdb::math::Transform::Ptr transform = openvdb::math::Transform::createLinearTransform(
@@ -225,34 +230,34 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set
Mesh *mesh = BKE_mesh_new_nomain(
vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size());
- MutableSpan<MVert> mverts{mesh->mvert, mesh->totvert};
- MutableSpan<MLoop> mloops{mesh->mloop, mesh->totloop};
- MutableSpan<MPoly> mpolys{mesh->mpoly, mesh->totpoly};
+ MutableSpan<MVert> mesh_verts = mesh->vertices_for_write();
+ MutableSpan<MPoly> mesh_polys = mesh->polygons_for_write();
+ MutableSpan<MLoop> mesh_loops = mesh->loops_for_write();
- for (const int i : mverts.index_range()) {
- copy_v3_v3(mverts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z()));
+ for (const int i : mesh_verts.index_range()) {
+ copy_v3_v3(mesh_verts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z()));
}
for (const int i : IndexRange(quads.size())) {
- MPoly &poly = mpolys[i];
+ MPoly &poly = mesh_polys[i];
const int loopstart = i * 4;
poly.loopstart = loopstart;
poly.totloop = 4;
- mloops[loopstart].v = quads[i][0];
- mloops[loopstart + 1].v = quads[i][3];
- mloops[loopstart + 2].v = quads[i][2];
- mloops[loopstart + 3].v = quads[i][1];
+ mesh_loops[loopstart].v = quads[i][0];
+ mesh_loops[loopstart + 1].v = quads[i][3];
+ mesh_loops[loopstart + 2].v = quads[i][2];
+ mesh_loops[loopstart + 3].v = quads[i][1];
}
const int triangle_loop_start = quads.size() * 4;
for (const int i : IndexRange(tris.size())) {
- MPoly &poly = mpolys[quads.size() + i];
+ MPoly &poly = mesh_polys[quads.size() + i];
const int loopstart = triangle_loop_start + i * 3;
poly.loopstart = loopstart;
poly.totloop = 3;
- mloops[loopstart].v = tris[i][2];
- mloops[loopstart + 1].v = tris[i][1];
- mloops[loopstart + 2].v = tris[i][0];
+ mesh_loops[loopstart].v = tris[i][2];
+ mesh_loops[loopstart + 1].v = tris[i][1];
+ mesh_loops[loopstart + 2].v = tris[i][0];
}
BKE_mesh_calc_edges(mesh, false, false);
diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc
index 4521c519f45..6ce47edf730 100644
--- a/source/blender/blenkernel/intern/mesh_runtime.cc
+++ b/source/blender/blenkernel/intern/mesh_runtime.cc
@@ -23,6 +23,9 @@
#include "BKE_shrinkwrap.h"
#include "BKE_subdiv_ccg.h"
+using blender::MutableSpan;
+using blender::Span;
+
/* -------------------------------------------------------------------- */
/** \name Mesh Runtime Struct Utils
* \{ */
@@ -147,10 +150,13 @@ void BKE_mesh_runtime_looptri_recalc(Mesh *mesh)
{
mesh_ensure_looptri_data(mesh);
BLI_assert(mesh->totpoly == 0 || mesh->runtime.looptris.array_wip != nullptr);
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MPoly> polys = mesh->polygons();
+ const Span<MLoop> loops = mesh->loops();
- BKE_mesh_recalc_looptri(mesh->mloop,
- mesh->mpoly,
- mesh->mvert,
+ BKE_mesh_recalc_looptri(loops.data(),
+ polys.data(),
+ verts.data(),
mesh->totloop,
mesh->totpoly,
mesh->runtime.looptris.array_wip);
@@ -272,7 +278,7 @@ void BKE_mesh_tag_coords_changed_uniformly(Mesh *mesh)
const bool poly_normals_were_dirty = BKE_mesh_poly_normals_are_dirty(mesh);
BKE_mesh_tag_coords_changed(mesh);
- /* The normals didn't change, since all vertices moved by the same amount. */
+ /* The normals didn't change, since all verts moved by the same amount. */
if (!vert_normals_were_dirty) {
BKE_mesh_poly_normals_clear_dirty(mesh);
}
@@ -324,6 +330,11 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
printf("MESH: %s\n", me_eval->id.name + 2);
}
+ MutableSpan<MVert> verts = me_eval->vertices_for_write();
+ MutableSpan<MEdge> edges = me_eval->edges_for_write();
+ MutableSpan<MPoly> polys = me_eval->polygons_for_write();
+ MutableSpan<MLoop> loops = me_eval->loops_for_write();
+
is_valid &= BKE_mesh_validate_all_customdata(
&me_eval->vdata,
me_eval->totvert,
@@ -338,21 +349,22 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
do_fixes,
&changed);
- is_valid &= BKE_mesh_validate_arrays(me_eval,
- me_eval->mvert,
- me_eval->totvert,
- me_eval->medge,
- me_eval->totedge,
- me_eval->mface,
- me_eval->totface,
- me_eval->mloop,
- me_eval->totloop,
- me_eval->mpoly,
- me_eval->totpoly,
- me_eval->dvert,
- do_verbose,
- do_fixes,
- &changed);
+ is_valid &= BKE_mesh_validate_arrays(
+ me_eval,
+ verts.data(),
+ verts.size(),
+ edges.data(),
+ edges.size(),
+ static_cast<MFace *>(CustomData_get_layer(&me_eval->fdata, CD_MFACE)),
+ me_eval->totface,
+ loops.data(),
+ loops.size(),
+ polys.data(),
+ polys.size(),
+ me_eval->deform_verts_for_write().data(),
+ do_verbose,
+ do_fixes,
+ &changed);
BLI_assert(changed == false);
diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc
index e54f2e6d687..f37246ced94 100644
--- a/source/blender/blenkernel/intern/mesh_sample.cc
+++ b/source/blender/blenkernel/intern/mesh_sample.cc
@@ -2,6 +2,7 @@
#include "BKE_attribute_math.hh"
#include "BKE_bvhutils.h"
+#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_sample.hh"
@@ -20,6 +21,7 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const IndexMask mask,
const MutableSpan<T> dst)
{
+ const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -28,9 +30,9 @@ BLI_NOINLINE static void sample_point_attribute(const Mesh &mesh,
const MLoopTri &looptri = looptris[looptri_index];
const float3 &bary_coord = bary_coords[i];
- const int v0_index = mesh.mloop[looptri.tri[0]].v;
- const int v1_index = mesh.mloop[looptri.tri[1]].v;
- const int v2_index = mesh.mloop[looptri.tri[2]].v;
+ const int v0_index = loops[looptri.tri[0]].v;
+ const int v1_index = loops[looptri.tri[1]].v;
+ const int v2_index = loops[looptri.tri[2]].v;
const T v0 = src[v0_index];
const T v1 = src[v1_index];
@@ -157,6 +159,8 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
}
bary_coords_.reinitialize(mask_.min_array_size());
+ const Span<MVert> verts = mesh_->vertices();
+ const Span<MLoop> loops = mesh_->loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
BKE_mesh_runtime_looptri_len(mesh_)};
@@ -164,14 +168,14 @@ Span<float3> MeshAttributeInterpolator::ensure_barycentric_coords()
const int looptri_index = looptri_indices_[i];
const MLoopTri &looptri = looptris[looptri_index];
- const int v0_index = mesh_->mloop[looptri.tri[0]].v;
- const int v1_index = mesh_->mloop[looptri.tri[1]].v;
- const int v2_index = mesh_->mloop[looptri.tri[2]].v;
+ const int v0_index = loops[looptri.tri[0]].v;
+ const int v1_index = loops[looptri.tri[1]].v;
+ const int v2_index = loops[looptri.tri[2]].v;
interp_weights_tri_v3(bary_coords_[i],
- mesh_->mvert[v0_index].co,
- mesh_->mvert[v1_index].co,
- mesh_->mvert[v2_index].co,
+ verts[v0_index].co,
+ verts[v1_index].co,
+ verts[v2_index].co,
positions_[i]);
}
return bary_coords_;
@@ -185,6 +189,8 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
}
nearest_weights_.reinitialize(mask_.min_array_size());
+ const Span<MVert> verts = mesh_->vertices();
+ const Span<MLoop> loops = mesh_->loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(mesh_),
BKE_mesh_runtime_looptri_len(mesh_)};
@@ -192,13 +198,13 @@ Span<float3> MeshAttributeInterpolator::ensure_nearest_weights()
const int looptri_index = looptri_indices_[i];
const MLoopTri &looptri = looptris[looptri_index];
- const int v0_index = mesh_->mloop[looptri.tri[0]].v;
- const int v1_index = mesh_->mloop[looptri.tri[1]].v;
- const int v2_index = mesh_->mloop[looptri.tri[2]].v;
+ const int v0_index = loops[looptri.tri[0]].v;
+ const int v1_index = loops[looptri.tri[1]].v;
+ const int v2_index = loops[looptri.tri[2]].v;
- const float d0 = len_squared_v3v3(positions_[i], mesh_->mvert[v0_index].co);
- const float d1 = len_squared_v3v3(positions_[i], mesh_->mvert[v1_index].co);
- const float d2 = len_squared_v3v3(positions_[i], mesh_->mvert[v2_index].co);
+ const float d0 = len_squared_v3v3(positions_[i], verts[v0_index].co);
+ const float d1 = len_squared_v3v3(positions_[i], verts[v1_index].co);
+ const float d2 = len_squared_v3v3(positions_[i], verts[v2_index].co);
nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1));
}
@@ -257,6 +263,8 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng,
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions)
{
+ const Span<MVert> verts = mesh.vertices();
+ const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -270,9 +278,9 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng,
for (const int looptri_index : looptri_indices_to_sample) {
const MLoopTri &looptri = looptris[looptri_index];
- const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
- const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
- const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
+ const float3 &v0 = verts[loops[looptri.tri[0]].v].co;
+ const float3 &v1 = verts[loops[looptri.tri[1]].v].co;
+ const float3 &v2 = verts[loops[looptri.tri[2]].v].co;
const float looptri_area = area_tri_v3(v0, v1, v2);
@@ -353,6 +361,8 @@ int sample_surface_points_projected(
Vector<int> &r_looptri_indices,
Vector<float3> &r_positions)
{
+ const Span<MVert> verts = mesh.vertices();
+ const Span<MLoop> loops = mesh.loops();
const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
BKE_mesh_runtime_looptri_len(&mesh)};
@@ -394,7 +404,8 @@ int sample_surface_points_projected(
const int looptri_index = ray_hit.index;
const float3 pos = ray_hit.co;
- const float3 bary_coords = compute_bary_coord_in_triangle(mesh, looptris[looptri_index], pos);
+ const float3 bary_coords = compute_bary_coord_in_triangle(
+ verts, loops, looptris[looptri_index], pos);
r_positions.append(pos);
r_bary_coords.append(bary_coords);
@@ -404,13 +415,14 @@ int sample_surface_points_projected(
return point_count;
}
-float3 compute_bary_coord_in_triangle(const Mesh &mesh,
+float3 compute_bary_coord_in_triangle(const Span<MVert> verts,
+ const Span<MLoop> loops,
const MLoopTri &looptri,
const float3 &position)
{
- const float3 &v0 = mesh.mvert[mesh.mloop[looptri.tri[0]].v].co;
- const float3 &v1 = mesh.mvert[mesh.mloop[looptri.tri[1]].v].co;
- const float3 &v2 = mesh.mvert[mesh.mloop[looptri.tri[2]].v].co;
+ const float3 &v0 = verts[loops[looptri.tri[0]].v].co;
+ const float3 &v1 = verts[loops[looptri.tri[1]].v].co;
+ const float3 &v2 = verts[loops[looptri.tri[2]].v].co;
float3 bary_coords;
interp_weights_tri_v3(bary_coords, v0, v1, v2, position);
return bary_coords;
diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c
index 497f9ff3cbd..8e3f98b9b95 100644
--- a/source/blender/blenkernel/intern/mesh_tangent.c
+++ b/source/blender/blenkernel/intern/mesh_tangent.c
@@ -179,14 +179,14 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh,
return;
}
- BKE_mesh_calc_loop_tangent_single_ex(mesh->mvert,
+ BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_vertices(mesh),
mesh->totvert,
- mesh->mloop,
+ BKE_mesh_loops(mesh),
r_looptangents,
loopnors,
loopuvs,
mesh->totloop,
- mesh->mpoly,
+ BKE_mesh_polygons(mesh),
mesh->totpoly,
reports);
}
@@ -719,10 +719,10 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval,
/* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */
short tangent_mask = 0;
- BKE_mesh_calc_loop_tangent_ex(me_eval->mvert,
- me_eval->mpoly,
+ BKE_mesh_calc_loop_tangent_ex(BKE_mesh_vertices(me_eval),
+ BKE_mesh_polygons(me_eval),
(uint)me_eval->totpoly,
- me_eval->mloop,
+ BKE_mesh_loops(me_eval),
me_eval->runtime.looptris.array,
(uint)me_eval->runtime.looptris.len,
&me_eval->ldata,
diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index c30f3661103..dafc2384282 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -33,6 +33,9 @@
#include "MEM_guardedalloc.h"
+using blender::MutableSpan;
+using blender::Span;
+
/* loop v/e are unsigned, so using max uint_32 value as invalid marker... */
#define INVALID_LOOP_EDGE_MARKER 4294967295u
@@ -1064,19 +1067,23 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
do_verbose,
true,
&changed);
+ MutableSpan<MVert> verts = me->vertices_for_write();
+ MutableSpan<MEdge> edges = me->edges_for_write();
+ MutableSpan<MPoly> polys = me->polygons_for_write();
+ MutableSpan<MLoop> loops = me->loops_for_write();
BKE_mesh_validate_arrays(me,
- me->mvert,
- me->totvert,
- me->medge,
- me->totedge,
- me->mface,
+ verts.data(),
+ verts.size(),
+ edges.data(),
+ edges.size(),
+ (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
- me->mloop,
- me->totloop,
- me->mpoly,
- me->totpoly,
- me->dvert,
+ loops.data(),
+ loops.size(),
+ polys.data(),
+ polys.size(),
+ me->deform_verts_for_write().data(),
do_verbose,
true,
&changed);
@@ -1113,18 +1120,23 @@ bool BKE_mesh_is_valid(Mesh *me)
do_fixes,
&changed);
+ MutableSpan<MVert> verts = me->vertices_for_write();
+ MutableSpan<MEdge> edges = me->edges_for_write();
+ MutableSpan<MPoly> polys = me->polygons_for_write();
+ MutableSpan<MLoop> loops = me->loops_for_write();
+
is_valid &= BKE_mesh_validate_arrays(me,
- me->mvert,
- me->totvert,
- me->medge,
- me->totedge,
- me->mface,
+ verts.data(),
+ verts.size(),
+ edges.data(),
+ edges.size(),
+ (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
- me->mloop,
- me->totloop,
- me->mpoly,
- me->totpoly,
- me->dvert,
+ loops.data(),
+ loops.size(),
+ polys.data(),
+ polys.size(),
+ me->deform_verts_for_write().data(),
do_verbose,
do_fixes,
&changed);
@@ -1170,11 +1182,12 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
/* NOTE: We need to keep this for edge creation (for now?), and some old `readfile.c` code. */
MFace *f;
int a, b;
+ MFace *mfaces = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
- for (a = b = 0, f = me->mface; a < me->totface; a++, f++) {
+ for (a = b = 0, f = mfaces; a < me->totface; a++, f++) {
if (f->v3) {
if (a != b) {
- memcpy(&me->mface[b], f, sizeof(me->mface[b]));
+ memcpy(&mfaces[b], f, sizeof(mfaces[b]));
CustomData_copy_data(&me->fdata, &me->fdata, a, b, 1);
}
b++;
@@ -1188,13 +1201,16 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
void BKE_mesh_strip_loose_polysloops(Mesh *me)
{
+ MutableSpan<MPoly> polys = me->polygons_for_write();
+ MutableSpan<MLoop> loops = me->loops_for_write();
+
MPoly *p;
MLoop *l;
int a, b;
/* New loops idx! */
int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__);
- for (a = b = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
+ for (a = b = 0, p = polys.data(); a < me->totpoly; a++, p++) {
bool invalid = false;
int i = p->loopstart;
int stop = i + p->totloop;
@@ -1203,7 +1219,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
invalid = true;
}
else {
- l = &me->mloop[i];
+ l = &loops[i];
i = stop - i;
/* If one of the poly's loops is invalid, the whole poly is invalid! */
for (; i--; l++) {
@@ -1216,7 +1232,7 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
if (p->totloop >= 3 && !invalid) {
if (a != b) {
- memcpy(&me->mpoly[b], p, sizeof(me->mpoly[b]));
+ memcpy(&polys[b], p, sizeof(polys[b]));
CustomData_copy_data(&me->pdata, &me->pdata, a, b, 1);
}
b++;
@@ -1228,10 +1244,10 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
}
/* And now, get rid of invalid loops. */
- for (a = b = 0, l = me->mloop; a < me->totloop; a++, l++) {
+ for (a = b = 0, l = loops.data(); a < me->totloop; a++, l++) {
if (l->e != INVALID_LOOP_EDGE_MARKER) {
if (a != b) {
- memcpy(&me->mloop[b], l, sizeof(me->mloop[b]));
+ memcpy(&loops[b], l, sizeof(loops[b]));
CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1);
}
new_idx[a] = b;
@@ -1250,8 +1266,8 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
/* And now, update polys' start loop index. */
/* NOTE: At this point, there should never be any poly using a striped loop! */
- for (a = 0, p = me->mpoly; a < me->totpoly; a++, p++) {
- p->loopstart = new_idx[p->loopstart];
+ for (const int i : polys.index_range()) {
+ polys[i].loopstart = new_idx[polys[i].loopstart];
}
MEM_freeN(new_idx);
@@ -1260,14 +1276,14 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
void BKE_mesh_strip_loose_edges(Mesh *me)
{
MEdge *e;
- MLoop *l;
int a, b;
uint *new_idx = (uint *)MEM_mallocN(sizeof(int) * me->totedge, __func__);
+ MutableSpan<MEdge> edges = me->edges_for_write();
- for (a = b = 0, e = me->medge; a < me->totedge; a++, e++) {
+ for (a = b = 0, e = edges.data(); a < me->totedge; a++, e++) {
if (e->v1 != e->v2) {
if (a != b) {
- memcpy(&me->medge[b], e, sizeof(me->medge[b]));
+ memcpy(&edges[b], e, sizeof(edges[b]));
CustomData_copy_data(&me->edata, &me->edata, a, b, 1);
}
new_idx[a] = b;
@@ -1285,8 +1301,9 @@ void BKE_mesh_strip_loose_edges(Mesh *me)
/* And now, update loops' edge indices. */
/* XXX We hope no loop was pointing to a striped edge!
* Else, its e will be set to INVALID_LOOP_EDGE_MARKER :/ */
- for (a = 0, l = me->mloop; a < me->totloop; a++, l++) {
- l->e = new_idx[l->e];
+ MutableSpan<MLoop> loops = me->loops_for_write();
+ for (MLoop &loop : loops) {
+ loop.e = new_idx[loop.e];
}
MEM_freeN(new_idx);
@@ -1344,10 +1361,10 @@ static int vergedgesort(const void *v1, const void *v2)
/* Create edges based on known verts and faces,
* this function is only used when loading very old blend files */
-static void mesh_calc_edges_mdata(MVert *UNUSED(allvert),
- MFace *allface,
+static void mesh_calc_edges_mdata(const MVert *UNUSED(allvert),
+ const MFace *allface,
MLoop *allloop,
- MPoly *allpoly,
+ const MPoly *allpoly,
int UNUSED(totvert),
int totface,
int UNUSED(totloop),
@@ -1356,8 +1373,8 @@ static void mesh_calc_edges_mdata(MVert *UNUSED(allvert),
MEdge **r_medge,
int *r_totedge)
{
- MPoly *mpoly;
- MFace *mface;
+ const MPoly *mpoly;
+ const MFace *mface;
MEdge *medge, *med;
EdgeHash *hash;
struct EdgeSort *edsort, *ed;
@@ -1480,28 +1497,29 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
{
MEdge *medge;
int totedge = 0;
-
- mesh_calc_edges_mdata(me->mvert,
- me->mface,
- me->mloop,
- me->mpoly,
- me->totvert,
+ const Span<MVert> verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ MutableSpan<MLoop> loops = me->loops_for_write();
+
+ mesh_calc_edges_mdata(verts.data(),
+ (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
+ loops.data(),
+ polys.data(),
+ verts.size(),
me->totface,
- me->totloop,
- me->totpoly,
+ loops.size(),
+ polys.size(),
use_old,
&medge,
&totedge);
if (totedge == 0) {
/* flag that mesh has edges */
- me->medge = medge;
me->totedge = 0;
return;
}
medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
- me->medge = medge;
me->totedge = totedge;
BKE_mesh_strip_loose_faces(me);
@@ -1509,18 +1527,18 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
void BKE_mesh_calc_edges_loose(Mesh *mesh)
{
- MEdge *med = mesh->medge;
- for (int i = 0; i < mesh->totedge; i++, med++) {
- med->flag |= ME_LOOSEEDGE;
+ const Span<MLoop> loops = mesh->loops();
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+
+ for (const int i : edges.index_range()) {
+ edges[i].flag |= ME_LOOSEEDGE;
}
- MLoop *ml = mesh->mloop;
- for (int i = 0; i < mesh->totloop; i++, ml++) {
- mesh->medge[ml->e].flag &= ~ME_LOOSEEDGE;
+ for (const int i : loops.index_range()) {
+ edges[loops[i].e].flag &= ~ME_LOOSEEDGE;
}
- med = mesh->medge;
- for (int i = 0; i < mesh->totedge; i++, med++) {
- if (med->flag & ME_LOOSEEDGE) {
- med->flag |= ME_EDGEDRAW;
+ for (const int i : edges.index_range()) {
+ if (edges[i].flag & ME_LOOSEEDGE) {
+ edges[i].flag |= ME_EDGEDRAW;
}
}
}
@@ -1529,8 +1547,9 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
{
const int numFaces = mesh->totface;
EdgeSet *eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces));
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
- MFace *mf = mesh->mface;
+ MFace *mf = mfaces;
for (int i = 0; i < numFaces; i++, mf++) {
BLI_edgeset_add(eh, mf->v1, mf->v2);
BLI_edgeset_add(eh, mf->v2, mf->v3);
@@ -1570,8 +1589,6 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
mesh->edata = edgeData;
mesh->totedge = numEdges;
- mesh->medge = (MEdge *)CustomData_get_layer(&mesh->edata, CD_MEDGE);
-
BLI_edgeset_free(eh);
}
diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc
index 19d4444aa2f..fe28fc37d45 100644
--- a/source/blender/blenkernel/intern/mesh_wrapper.cc
+++ b/source/blender/blenkernel/intern/mesh_wrapper.cc
@@ -46,6 +46,8 @@
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_query.h"
+using blender::Span;
+
Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em,
const CustomData_MeshMasks *cd_mask_extra,
const float (*vert_coords)[3],
@@ -195,9 +197,9 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me,
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD: {
BLI_assert(vert_coords_len <= me->totvert);
- const MVert *mvert = me->mvert;
+ const Span<MVert> verts = me->vertices();
for (int i = 0; i < vert_coords_len; i++) {
- copy_v3_v3(vert_coords[i], mvert[i].co);
+ copy_v3_v3(vert_coords[i], verts[i].co);
}
return;
}
@@ -233,9 +235,9 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me,
case ME_WRAPPER_TYPE_MDATA:
case ME_WRAPPER_TYPE_SUBD: {
BLI_assert(vert_coords_len == me->totvert);
- const MVert *mvert = me->mvert;
+ const Span<MVert> verts = me->vertices();
for (int i = 0; i < vert_coords_len; i++) {
- mul_v3_m4v3(vert_coords[i], mat, mvert[i].co);
+ mul_v3_m4v3(vert_coords[i], mat, verts[i].co);
}
return;
}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 5c382a4e864..20b7ed7b4b2 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -183,6 +183,7 @@ static BLI_bitmap *multires_mdisps_downsample_hidden(const BLI_bitmap *old_hidde
static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int level)
{
+ const MPoly *polys = BKE_mesh_polygons(me);
const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
BLI_bitmap **grid_hidden = ccgdm->gridHidden;
int *gridOffset;
@@ -191,7 +192,7 @@ static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm, Mesh *me, int
gridOffset = ccgdm->dm.getGridOffset(&ccgdm->dm);
for (i = 0; i < me->totpoly; i++) {
- for (j = 0; j < me->mpoly[i].totloop; j++) {
+ for (j = 0; j < polys[i].totloop; j++) {
int g = gridOffset[i] + j;
const MDisps *md = &mdisps[g];
BLI_bitmap *gh = md->hidden;
@@ -466,15 +467,16 @@ void multires_force_external_reload(Object *object)
static int get_levels_from_disps(Object *ob)
{
Mesh *me = ob->data;
+ const MPoly *polys = BKE_mesh_polygons(me);
MDisps *mdisp, *md;
int i, j, totlvl = 0;
mdisp = CustomData_get_layer(&me->ldata, CD_MDISPS);
for (i = 0; i < me->totpoly; i++) {
- md = mdisp + me->mpoly[i].loopstart;
+ md = mdisp + polys[i].loopstart;
- for (j = 0; j < me->mpoly[i].totloop; j++, md++) {
+ for (j = 0; j < polys[i].totloop; j++, md++) {
if (md->totdisp == 0) {
continue;
}
@@ -633,6 +635,7 @@ static void multires_grid_paint_mask_downsample(GridPaintMask *gpm, int level)
static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
{
Mesh *me = (Mesh *)ob->data;
+ const MPoly *polys = BKE_mesh_polygons(me);
int levels = mmd->totlvl - lvl;
MDisps *mdisps;
GridPaintMask *gpm;
@@ -652,8 +655,8 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
int i, j;
for (i = 0; i < me->totpoly; i++) {
- for (j = 0; j < me->mpoly[i].totloop; j++) {
- int g = me->mpoly[i].loopstart + j;
+ for (j = 0; j < polys[i].totloop; j++) {
+ int g = polys[i].loopstart + j;
MDisps *mdisp = &mdisps[g];
float(*disps)[3], (*ndisps)[3], (*hdisps)[3];
int totdisp = multires_grid_tot[lvl];
@@ -828,7 +831,7 @@ typedef struct MultiresThreadedData {
CCGElem **gridData, **subGridData;
CCGKey *key;
CCGKey *sub_key;
- MPoly *mpoly;
+ const MPoly *mpoly;
MDisps *mdisps;
GridPaintMask *grid_paint_mask;
int *gridOffset;
@@ -846,7 +849,7 @@ static void multires_disp_run_cb(void *__restrict userdata,
CCGElem **gridData = tdata->gridData;
CCGElem **subGridData = tdata->subGridData;
CCGKey *key = tdata->key;
- MPoly *mpoly = tdata->mpoly;
+ const MPoly *mpoly = tdata->mpoly;
MDisps *mdisps = tdata->mdisps;
GridPaintMask *grid_paint_mask = tdata->grid_paint_mask;
int *gridOffset = tdata->gridOffset;
@@ -939,7 +942,7 @@ static void multiresModifier_disp_run(
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGElem **gridData, **subGridData;
CCGKey key;
- MPoly *mpoly = me->mpoly;
+ const MPoly *mpoly = BKE_mesh_polygons(me);
MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
GridPaintMask *grid_paint_mask = NULL;
int *gridOffset;
diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h
index c4f320b86d8..5e2822ad5df 100644
--- a/source/blender/blenkernel/intern/multires_reshape.h
+++ b/source/blender/blenkernel/intern/multires_reshape.h
@@ -14,8 +14,12 @@
struct Depsgraph;
struct GridPaintMask;
struct MDisps;
+struct MEdge;
struct Mesh;
+struct MLoop;
+struct MPoly;
struct MultiresModifierData;
+struct MVert;
struct Object;
struct Subdiv;
struct SubdivCCG;
@@ -30,6 +34,10 @@ typedef struct MultiresReshapeContext {
/* Base mesh from original object.
* NOTE: Does NOT include any leading modifiers in it. */
struct Mesh *base_mesh;
+ const struct MVert *base_verts;
+ const struct MEdge *base_edges;
+ const struct MPoly *base_polys;
+ const struct MLoop *base_loops;
/* Subdivision surface created for multires modifier.
*
diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
index f7d29806353..73f7197dcc9 100644
--- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c
+++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c
@@ -30,11 +30,14 @@
void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context)
{
Mesh *base_mesh = reshape_context->base_mesh;
- const MLoop *mloop = base_mesh->mloop;
- MVert *mvert = base_mesh->mvert;
+ MVert *base_verts = BKE_mesh_vertices_for_write(base_mesh);
+ /* Update the context in case the vertices were duplicated. */
+ reshape_context->base_verts = base_verts;
+
+ const MLoop *mloop = reshape_context->base_loops;
for (int loop_index = 0; loop_index < base_mesh->totloop; ++loop_index) {
const MLoop *loop = &mloop[loop_index];
- MVert *vert = &mvert[loop->v];
+ MVert *vert = &base_verts[loop->v];
GridCoord grid_coord;
grid_coord.grid_index = loop_index;
@@ -66,13 +69,15 @@ static float v3_dist_from_plane(const float v[3], const float center[3], const f
void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context)
{
Mesh *base_mesh = reshape_context->base_mesh;
-
+ MVert *base_verts = BKE_mesh_vertices_for_write(base_mesh);
+ /* Update the context in case the vertices were duplicated. */
+ reshape_context->base_verts = base_verts;
MeshElemMap *pmap;
int *pmap_mem;
BKE_mesh_vert_poly_map_create(&pmap,
&pmap_mem,
- base_mesh->mpoly,
- base_mesh->mloop,
+ reshape_context->base_polys,
+ reshape_context->base_loops,
base_mesh->totvert,
base_mesh->totpoly,
base_mesh->totloop);
@@ -80,7 +85,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
float(*origco)[3] = MEM_calloc_arrayN(
base_mesh->totvert, sizeof(float[3]), "multires apply base origco");
for (int i = 0; i < base_mesh->totvert; i++) {
- copy_v3_v3(origco[i], base_mesh->mvert[i].co);
+ copy_v3_v3(origco[i], base_verts[i].co);
}
for (int i = 0; i < base_mesh->totvert; i++) {
@@ -94,11 +99,11 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find center. */
int tot = 0;
for (int j = 0; j < pmap[i].count; j++) {
- const MPoly *p = &base_mesh->mpoly[pmap[i].indices[j]];
+ const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]];
/* This double counts, not sure if that's bad or good. */
for (int k = 0; k < p->totloop; k++) {
- const int vndx = base_mesh->mloop[p->loopstart + k].v;
+ const int vndx = reshape_context->base_loops[p->loopstart + k].v;
if (vndx != i) {
add_v3_v3(center, origco[vndx]);
tot++;
@@ -109,7 +114,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
/* Find normal. */
for (int j = 0; j < pmap[i].count; j++) {
- const MPoly *p = &base_mesh->mpoly[pmap[i].indices[j]];
+ const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]];
MPoly fake_poly;
MLoop *fake_loops;
float(*fake_co)[3];
@@ -122,7 +127,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
fake_co = MEM_malloc_arrayN(p->totloop, sizeof(float[3]), "fake_co");
for (int k = 0; k < p->totloop; k++) {
- const int vndx = base_mesh->mloop[p->loopstart + k].v;
+ const int vndx = reshape_context->base_loops[p->loopstart + k].v;
fake_loops[k].v = k;
@@ -143,10 +148,10 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape
normalize_v3(avg_no);
/* Push vertex away from the plane. */
- const float dist = v3_dist_from_plane(base_mesh->mvert[i].co, center, avg_no);
+ const float dist = v3_dist_from_plane(base_verts[i].co, center, avg_no);
copy_v3_v3(push, avg_no);
mul_v3_fl(push, dist);
- add_v3_v3(base_mesh->mvert[i].co, push);
+ add_v3_v3(base_verts[i].co, push);
}
MEM_freeN(origco);
diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.c
index 8246de12ebf..97c85ae526c 100644
--- a/source/blender/blenkernel/intern/multires_reshape_smooth.c
+++ b/source/blender/blenkernel/intern/multires_reshape_smooth.c
@@ -643,8 +643,7 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context,
const int face_index = multires_reshape_grid_to_face_index(reshape_context,
grid_coord.grid_index);
- const Mesh *base_mesh = reshape_context->base_mesh;
- const MPoly *base_poly = &base_mesh->mpoly[face_index];
+ const MPoly *base_poly = &reshape_context->base_polys[face_index];
const int num_corners = base_poly->totloop;
const int start_grid_index = reshape_context->face_start_grid_index[face_index];
const int corner = grid_coord.grid_index - start_grid_index;
@@ -834,8 +833,7 @@ static void foreach_edge(const struct SubdivForeachContext *foreach_context,
return;
}
/* Edges without crease are to be ignored as well. */
- const Mesh *base_mesh = reshape_context->base_mesh;
- const MEdge *base_edge = &base_mesh->medge[coarse_edge_index];
+ const MEdge *base_edge = &reshape_context->base_edges[coarse_edge_index];
const char crease = get_effective_crease_char(reshape_smooth_context, base_edge);
if (crease == 0) {
return;
@@ -847,9 +845,9 @@ static void geometry_init_loose_information(MultiresReshapeSmoothContext *reshap
{
const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context;
const Mesh *base_mesh = reshape_context->base_mesh;
- const MPoly *base_mpoly = base_mesh->mpoly;
- const MLoop *base_mloop = base_mesh->mloop;
- const MEdge *base_edge = base_mesh->medge;
+ const MPoly *base_mpoly = reshape_context->base_polys;
+ const MLoop *base_mloop = reshape_context->base_loops;
+ const MEdge *base_edge = reshape_context->base_edges;
reshape_smooth_context->non_loose_base_edge_map = BLI_BITMAP_NEW(base_mesh->totedge,
"non_loose_base_edge_map");
diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.c
index cecb57f4de4..0a630a4343e 100644
--- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c
+++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.c
@@ -28,12 +28,16 @@
static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
{
+ const MVert *verts = BKE_mesh_vertices(mesh);
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
+
MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
const int totpoly = mesh->totpoly;
for (int p = 0; p < totpoly; p++) {
- MPoly *poly = &mesh->mpoly[p];
+ const MPoly *poly = &polys[p];
float poly_center[3];
- BKE_mesh_calc_poly_center(poly, &mesh->mloop[poly->loopstart], mesh->mvert, poly_center);
+ BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], verts, poly_center);
for (int l = 0; l < poly->totloop; l++) {
const int loop_index = poly->loopstart + l;
@@ -44,14 +48,14 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
int prev_loop_index = l - 1 >= 0 ? loop_index - 1 : loop_index + poly->totloop - 1;
int next_loop_index = l + 1 < poly->totloop ? loop_index + 1 : poly->loopstart;
- MLoop *loop = &mesh->mloop[loop_index];
- MLoop *loop_next = &mesh->mloop[next_loop_index];
- MLoop *loop_prev = &mesh->mloop[prev_loop_index];
+ const MLoop *loop = &loops[loop_index];
+ const MLoop *loop_next = &loops[next_loop_index];
+ const MLoop *loop_prev = &loops[prev_loop_index];
copy_v3_v3(disps[0], poly_center);
- mid_v3_v3v3(disps[1], mesh->mvert[loop->v].co, mesh->mvert[loop_next->v].co);
- mid_v3_v3v3(disps[2], mesh->mvert[loop->v].co, mesh->mvert[loop_prev->v].co);
- copy_v3_v3(disps[3], mesh->mvert[loop->v].co);
+ mid_v3_v3v3(disps[1], verts[loop->v].co, verts[loop_next->v].co);
+ mid_v3_v3v3(disps[2], verts[loop->v].co, verts[loop_prev->v].co);
+ copy_v3_v3(disps[3], verts[loop->v].co);
}
}
}
diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c
index 34aa90aa554..43768ef158a 100644
--- a/source/blender/blenkernel/intern/multires_reshape_util.c
+++ b/source/blender/blenkernel/intern/multires_reshape_util.c
@@ -66,7 +66,7 @@ static void context_zero(MultiresReshapeContext *reshape_context)
static void context_init_lookup(MultiresReshapeContext *reshape_context)
{
const Mesh *base_mesh = reshape_context->base_mesh;
- const MPoly *mpoly = base_mesh->mpoly;
+ const MPoly *mpoly = reshape_context->base_polys;
const int num_faces = base_mesh->totpoly;
reshape_context->face_start_grid_index = MEM_malloc_arrayN(
@@ -152,6 +152,10 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
+ reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
+ reshape_context->base_edges = BKE_mesh_edges(base_mesh);
+ reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
+ reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd);
reshape_context->need_free_subdiv = true;
@@ -185,6 +189,10 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
+ reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
+ reshape_context->base_edges = BKE_mesh_edges(base_mesh);
+ reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
+ reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = multires_reshape_create_subdiv(depsgraph, object, mmd);
reshape_context->need_free_subdiv = true;
@@ -212,6 +220,10 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co
context_zero(reshape_context);
reshape_context->base_mesh = base_mesh;
+ reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
+ reshape_context->base_edges = BKE_mesh_edges(base_mesh);
+ reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
+ reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = subdiv_ccg->subdiv;
reshape_context->need_free_subdiv = false;
@@ -255,6 +267,10 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape
reshape_context->mmd = mmd;
reshape_context->base_mesh = base_mesh;
+ reshape_context->base_verts = BKE_mesh_vertices(base_mesh);
+ reshape_context->base_edges = BKE_mesh_edges(base_mesh);
+ reshape_context->base_polys = BKE_mesh_polygons(base_mesh);
+ reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->subdiv = subdiv;
reshape_context->need_free_subdiv = false;
@@ -344,7 +360,7 @@ int multires_reshape_grid_to_corner(const MultiresReshapeContext *reshape_contex
bool multires_reshape_is_quad_face(const MultiresReshapeContext *reshape_context, int face_index)
{
- const MPoly *base_poly = &reshape_context->base_mesh->mpoly[face_index];
+ const MPoly *base_poly = &reshape_context->base_polys[face_index];
return (base_poly->totloop == 4);
}
@@ -636,8 +652,7 @@ static void foreach_grid_face_coordinate_task(void *__restrict userdata_v,
const MultiresReshapeContext *reshape_context = data->reshape_context;
- const Mesh *base_mesh = data->reshape_context->base_mesh;
- const MPoly *mpoly = base_mesh->mpoly;
+ const MPoly *mpoly = reshape_context->base_polys;
const int grid_size = data->grid_size;
const float grid_size_1_inv = 1.0f / (((float)grid_size) - 1.0f);
diff --git a/source/blender/blenkernel/intern/multires_reshape_vertcos.c b/source/blender/blenkernel/intern/multires_reshape_vertcos.c
index e50f5e71bf7..7cf853e0374 100644
--- a/source/blender/blenkernel/intern/multires_reshape_vertcos.c
+++ b/source/blender/blenkernel/intern/multires_reshape_vertcos.c
@@ -52,8 +52,7 @@ static void multires_reshape_vertcos_foreach_vertex(const SubdivForeachContext *
const int face_index = multires_reshape_grid_to_face_index(reshape_context,
grid_coord.grid_index);
- const Mesh *base_mesh = reshape_context->base_mesh;
- const MPoly *base_poly = &base_mesh->mpoly[face_index];
+ const MPoly *base_poly = &reshape_context->base_polys[face_index];
const int num_corners = base_poly->totloop;
const int start_grid_index = reshape_context->face_start_grid_index[face_index];
const int corner = grid_coord.grid_index - start_grid_index;
diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c
index 27a1f84579e..26ae914d67e 100644
--- a/source/blender/blenkernel/intern/multires_unsubdivide.c
+++ b/source/blender/blenkernel/intern/multires_unsubdivide.c
@@ -639,9 +639,10 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
int grid_x,
int grid_y)
{
-
Mesh *original_mesh = context->original_mesh;
- MPoly *poly = &original_mesh->mpoly[BM_elem_index_get(f)];
+ const MPoly *polys = BKE_mesh_polygons(original_mesh);
+ const MLoop *loops = BKE_mesh_loops(original_mesh);
+ const MPoly *poly = &polys[BM_elem_index_get(f)];
const int corner_vertex_index = BM_elem_index_get(v);
@@ -650,7 +651,7 @@ static void store_grid_data(MultiresUnsubdivideContext *context,
int loop_offset = 0;
for (int i = 0; i < poly->totloop; i++) {
const int loop_index = poly->loopstart + i;
- MLoop *l = &original_mesh->mloop[loop_index];
+ const MLoop *l = &loops[loop_index];
if (l->v == corner_vertex_index) {
loop_offset = i;
break;
@@ -918,8 +919,9 @@ static void multires_unsubdivide_add_original_index_datalayers(Mesh *mesh)
static void multires_unsubdivide_prepare_original_bmesh_for_extract(
MultiresUnsubdivideContext *context)
{
-
Mesh *original_mesh = context->original_mesh;
+ const MPoly *original_polys = BKE_mesh_polygons(original_mesh);
+
Mesh *base_mesh = context->base_mesh;
BMesh *bm_original_mesh = context->bm_original_mesh = get_bmesh_from_mesh(original_mesh);
@@ -949,7 +951,7 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
context->loop_to_face_map = MEM_calloc_arrayN(original_mesh->totloop, sizeof(int), "loop map");
for (int i = 0; i < original_mesh->totpoly; i++) {
- MPoly *poly = &original_mesh->mpoly[i];
+ const MPoly *poly = &original_polys[i];
for (int l = 0; l < poly->totloop; l++) {
int original_loop_index = l + poly->loopstart;
context->loop_to_face_map[original_loop_index] = i;
@@ -963,16 +965,19 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract(
*/
static bool multires_unsubdivide_flip_grid_x_axis(Mesh *mesh, int poly, int loop, int v_x)
{
- MPoly *p = &mesh->mpoly[poly];
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
+
+ const MPoly *p = &polys[poly];
- MLoop *l_first = &mesh->mloop[p->loopstart];
+ const MLoop *l_first = &loops[p->loopstart];
if ((loop == (p->loopstart + (p->totloop - 1))) && l_first->v == v_x) {
return true;
}
int next_l_index = loop + 1;
if (next_l_index < p->loopstart + p->totloop) {
- MLoop *l_next = &mesh->mloop[next_l_index];
+ const MLoop *l_next = &loops[next_l_index];
if (l_next->v == v_x) {
return true;
}
diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc
index 0389fa2f1c6..ec21d0b127b 100644
--- a/source/blender/blenkernel/intern/object.cc
+++ b/source/blender/blenkernel/intern/object.cc
@@ -145,6 +145,8 @@
#include "atomic_ops.h"
using blender::float3;
+using blender::MutableSpan;
+using blender::Span;
static CLG_LogRef LOG = {"bke.object"};
@@ -3189,6 +3191,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
BKE_object_get_evaluated_mesh(par);
if (me_eval) {
+ const MVert *verts = BKE_mesh_vertices(me_eval);
int count = 0;
int numVerts = me_eval->totvert;
@@ -3222,14 +3225,14 @@ static void give_parvert(Object *par, int nr, float vec[3])
/* Get the average of all verts with (original index == nr). */
for (int i = 0; i < numVerts; i++) {
if (index[i] == nr) {
- add_v3_v3(vec, me_eval->mvert[i].co);
+ add_v3_v3(vec, verts[i].co);
count++;
}
}
}
else {
if (nr < numVerts) {
- add_v3_v3(vec, me_eval->mvert[nr].co);
+ add_v3_v3(vec, verts[nr].co);
count++;
}
}
@@ -3243,7 +3246,7 @@ static void give_parvert(Object *par, int nr, float vec[3])
else {
/* use first index if its out of range */
if (me_eval->totvert) {
- copy_v3_v3(vec, me_eval->mvert[0].co);
+ copy_v3_v3(vec, verts[0].co);
}
}
}
@@ -4127,10 +4130,10 @@ void BKE_object_foreach_display_point(Object *ob,
float3 co;
if (mesh_eval != nullptr) {
- const MVert *mv = mesh_eval->mvert;
+ const MVert *verts = BKE_mesh_vertices(mesh_eval);
const int totvert = mesh_eval->totvert;
- for (int i = 0; i < totvert; i++, mv++) {
- mul_v3_m4v3(co, obmat, mv->co);
+ for (int i = 0; i < totvert; i++) {
+ mul_v3_m4v3(co, obmat, verts[i].co);
func_cb(co, user_data);
}
}
@@ -4754,7 +4757,8 @@ bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb)
switch (ob->type) {
case OB_MESH: {
Mesh *mesh = (Mesh *)ob->data;
- BKE_keyblock_convert_to_mesh(key->refkey, mesh->mvert, mesh->totvert);
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ BKE_keyblock_convert_to_mesh(key->refkey, verts.data(), mesh->totvert);
break;
}
case OB_CURVES_LEGACY:
@@ -5250,32 +5254,31 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot)
const int *index;
if (me_eval && (index = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX))) {
- MVert *mvert = me_eval->mvert;
- uint totvert = me_eval->totvert;
+ const Span<MVert> verts = me->vertices();
/* Tree over-allocates in case where some verts have #ORIGINDEX_NONE. */
tot = 0;
- tree = BLI_kdtree_3d_new(totvert);
+ tree = BLI_kdtree_3d_new(verts.size());
/* We don't how many verts from the DM we can use. */
- for (i = 0; i < totvert; i++) {
+ for (i = 0; i < verts.size(); i++) {
if (index[i] != ORIGINDEX_NONE) {
float co[3];
- mul_v3_m4v3(co, ob->obmat, mvert[i].co);
+ mul_v3_m4v3(co, ob->obmat, verts[i].co);
BLI_kdtree_3d_insert(tree, index[i], co);
tot++;
}
}
}
else {
- MVert *mvert = me->mvert;
+ const Span<MVert> verts = me->vertices();
- tot = me->totvert;
+ tot = verts.size();
tree = BLI_kdtree_3d_new(tot);
for (i = 0; i < tot; i++) {
float co[3];
- mul_v3_m4v3(co, ob->obmat, mvert[i].co);
+ mul_v3_m4v3(co, ob->obmat, verts[i].co);
BLI_kdtree_3d_insert(tree, i, co);
}
}
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
index 08d98775e34..4c59b4a5210 100644
--- a/source/blender/blenkernel/intern/object_deform.c
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -114,10 +114,7 @@ bDeformGroup *BKE_object_defgroup_add(Object *ob)
MDeformVert *BKE_object_defgroup_data_create(ID *id)
{
if (GS(id->name) == ID_ME) {
- Mesh *me = (Mesh *)id;
- me->dvert = CustomData_add_layer(
- &me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, me->totvert);
- return me->dvert;
+ return BKE_mesh_deform_verts_for_write((Mesh *)id);
}
if (GS(id->name) == ID_LT) {
Lattice *lt = (Lattice *)id;
@@ -165,12 +162,12 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele
}
}
else {
- if (me->dvert) {
- MVert *mv;
+ if (BKE_mesh_deform_verts(me)) {
+ const MVert *mv;
int i;
- mv = me->mvert;
- dv = me->dvert;
+ mv = BKE_mesh_vertices(me);
+ dv = BKE_mesh_deform_verts_for_write(me);
for (i = 0; i < me->totvert; i++, mv++, dv++) {
if (dv->dw && (!use_selection || (mv->flag & SELECT))) {
@@ -265,7 +262,6 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
- me->dvert = NULL;
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
@@ -413,7 +409,6 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
- me->dvert = NULL;
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
@@ -502,7 +497,7 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t
switch (GS(id->name)) {
case ID_ME: {
Mesh *me = (Mesh *)id;
- *dvert_arr = me->dvert;
+ *dvert_arr = BKE_mesh_deform_verts_for_write(me);
*dvert_tot = me->totvert;
return true;
}
diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc
index 228bc682ddd..d42404922e3 100644
--- a/source/blender/blenkernel/intern/object_dupli.cc
+++ b/source/blender/blenkernel/intern/object_dupli.cc
@@ -628,7 +628,7 @@ static void make_duplis_verts(const DupliContext *ctx)
VertexDupliData_Mesh vdd{};
vdd.params = vdd_params;
vdd.totvert = me_eval->totvert;
- vdd.mvert = me_eval->mvert;
+ vdd.mvert = me_eval->vertices().data();
vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval);
vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO);
@@ -1178,9 +1178,9 @@ static void make_duplis_faces(const DupliContext *ctx)
FaceDupliData_Mesh fdd{};
fdd.params = fdd_params;
fdd.totface = me_eval->totpoly;
- fdd.mpoly = me_eval->mpoly;
- fdd.mloop = me_eval->mloop;
- fdd.mvert = me_eval->mvert;
+ fdd.mpoly = me_eval->polygons().data();
+ fdd.mloop = me_eval->loops().data();
+ fdd.mvert = me_eval->vertices().data();
fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n(
&me_eval->ldata, CD_MLOOPUV, uv_idx) :
nullptr;
diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc
index 4c3da5eabc4..10dfa3f59e7 100644
--- a/source/blender/blenkernel/intern/paint.cc
+++ b/source/blender/blenkernel/intern/paint.cc
@@ -64,6 +64,9 @@
#include "bmesh.h"
+using blender::MutableSpan;
+using blender::Span;
+
static void palette_init_data(ID *id)
{
Palette *palette = (Palette *)id;
@@ -1624,7 +1627,7 @@ static void sculpt_update_object(Depsgraph *depsgraph,
Scene *scene = DEG_get_input_scene(depsgraph);
Sculpt *sd = scene->toolsettings->sculpt;
SculptSession *ss = ob->sculpt;
- const Mesh *me = BKE_object_get_original_mesh(ob);
+ Mesh *me = BKE_object_get_original_mesh(ob);
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob);
const bool use_face_sets = (ob->mode & OB_MODE_SCULPT) != 0;
@@ -1664,17 +1667,17 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* These are assigned to the base mesh in Multires. This is needed because Face Sets operators
* and tools use the Face Sets data from the base mesh when Multires is active. */
- ss->mvert = me->mvert;
- ss->mpoly = me->mpoly;
- ss->mloop = me->mloop;
+ ss->mvert = BKE_mesh_vertices_for_write(me);
+ ss->mpoly = BKE_mesh_polygons(me);
+ ss->mloop = BKE_mesh_loops(me);
}
else {
ss->totvert = me->totvert;
ss->totpoly = me->totpoly;
ss->totfaces = me->totpoly;
- ss->mvert = me->mvert;
- ss->mpoly = me->mpoly;
- ss->mloop = me->mloop;
+ ss->mvert = BKE_mesh_vertices_for_write(me);
+ ss->mpoly = BKE_mesh_polygons(me);
+ ss->mloop = BKE_mesh_loops(me);
ss->multires.active = false;
ss->multires.modifier = nullptr;
ss->multires.level = 0;
@@ -1724,8 +1727,13 @@ static void sculpt_update_object(Depsgraph *depsgraph,
BKE_pbvh_face_sets_color_set(ss->pbvh, me->face_sets_color_seed, me->face_sets_color_default);
if (need_pmap && ob->type == OB_MESH && !ss->pmap) {
- BKE_mesh_vert_poly_map_create(
- &ss->pmap, &ss->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
+ BKE_mesh_vert_poly_map_create(&ss->pmap,
+ &ss->pmap_mem,
+ BKE_mesh_polygons(me),
+ BKE_mesh_loops(me),
+ me->totvert,
+ me->totpoly,
+ me->totloop);
if (ss->pbvh) {
BKE_pbvh_pmap_set(ss->pbvh, ss->pmap);
@@ -1743,7 +1751,8 @@ static void sculpt_update_object(Depsgraph *depsgraph,
/* If the fully evaluated mesh has the same topology as the deform-only version, use it.
* This matters because 'deform eval' is very restrictive and excludes even modifiers that
* simply recompute vertex weights. */
- if (me_eval_deform->mpoly == me_eval->mpoly && me_eval_deform->mloop == me_eval->mloop &&
+ if (me_eval_deform->polygons().data() == me_eval->polygons().data() &&
+ me_eval_deform->loops().data() == me_eval->loops().data() &&
me_eval_deform->totvert == me_eval->totvert) {
me_eval_deform = me_eval;
}
@@ -1921,7 +1930,7 @@ void BKE_sculpt_color_layer_create_if_needed(Object *object)
CustomDataLayer *layer = orig_me->vdata.layers +
CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR);
- BKE_mesh_update_customdata_pointers(orig_me, true);
+ BKE_mesh_tessface_clear(orig_me);
BKE_id_attributes_active_color_set(&orig_me->id, layer);
DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES);
@@ -1944,6 +1953,8 @@ void BKE_sculpt_update_object_for_edit(
int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
{
Mesh *me = static_cast<Mesh *>(ob->data);
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
int ret = 0;
const float *paint_mask = static_cast<const float *>(
@@ -1972,12 +1983,12 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
/* if vertices already have mask, copy into multires data */
if (paint_mask) {
for (i = 0; i < me->totpoly; i++) {
- const MPoly *p = &me->mpoly[i];
+ const MPoly *p = &polys[i];
float avg = 0;
/* mask center */
for (j = 0; j < p->totloop; j++) {
- const MLoop *l = &me->mloop[p->loopstart + j];
+ const MLoop *l = &loops[p->loopstart + j];
avg += paint_mask[l->v];
}
avg /= (float)p->totloop;
@@ -1985,9 +1996,9 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
/* fill in multires mask corner */
for (j = 0; j < p->totloop; j++) {
GridPaintMask *gpm = &gmask[p->loopstart + j];
- const MLoop *l = &me->mloop[p->loopstart + j];
- const MLoop *prev = ME_POLY_LOOP_PREV(me->mloop, p, j);
- const MLoop *next = ME_POLY_LOOP_NEXT(me->mloop, p, j);
+ const MLoop *l = &loops[p->loopstart + j];
+ const MLoop *prev = ME_POLY_LOOP_PREV(loops, p, j);
+ const MLoop *next = ME_POLY_LOOP_NEXT(loops, p, j);
gpm->data[0] = avg;
gpm->data[1] = (paint_mask[l->v] + paint_mask[next->v]) * 0.5f;
@@ -2234,18 +2245,23 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool
PBVH *pbvh = BKE_pbvh_new();
BKE_pbvh_respect_hide_set(pbvh, respect_hide);
+ MutableSpan<MVert> verts = me->vertices_for_write();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
+
MLoopTri *looptri = static_cast<MLoopTri *>(
MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__));
- BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+ BKE_mesh_recalc_looptri(
+ loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri);
BKE_sculpt_sync_face_set_visibility(me, nullptr);
BKE_pbvh_build_mesh(pbvh,
me,
- me->mpoly,
- me->mloop,
- me->mvert,
+ polys.data(),
+ loops.data(),
+ verts.data(),
me->totvert,
&me->vdata,
&me->ldata,
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 9ccd6562649..8db83031e17 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1399,7 +1399,8 @@ static void init_particle_interpolation(Object *ob,
pind->dietime = (key + pa->totkey - 1)->time;
if (pind->mesh) {
- pind->mvert[0] = &pind->mesh->mvert[pa->hair_index];
+ MVert *verts = BKE_mesh_vertices_for_write(pind->mesh);
+ pind->mvert[0] = &verts[pa->hair_index];
pind->mvert[1] = pind->mvert[0] + 1;
}
}
@@ -1664,7 +1665,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach
/************************************************/
void psys_interpolate_face(Mesh *mesh,
- MVert *mvert,
+ const MVert *mvert,
const float (*vert_normals)[3],
MFace *mface,
MTFace *tface,
@@ -1676,7 +1677,7 @@ void psys_interpolate_face(Mesh *mesh,
float vtan[3],
float orco[3])
{
- float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0;
+ const float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0;
float e1[3], e2[3], s1, s2, t1, t2;
float *uv1, *uv2, *uv3, *uv4;
float n1[3], n2[3], n3[3], n4[3];
@@ -1852,7 +1853,8 @@ static float psys_interpolate_value_from_verts(
return values[index];
case PART_FROM_FACE:
case PART_FROM_VOLUME: {
- MFace *mf = &mesh->mface[index];
+ MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ MFace *mf = &mfaces[index];
return interpolate_particle_value(
values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4);
}
@@ -1941,7 +1943,7 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final,
index_mf_to_mpoly_deformed = NULL;
- mtessface_final = mesh_final->mface;
+ mtessface_final = CustomData_get_layer(&mesh_final->fdata, CD_MFACE);
osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE);
if (osface_final == NULL) {
@@ -2061,7 +2063,8 @@ static int psys_map_index_on_dm(Mesh *mesh,
/* modify the original weights to become
* weights for the derived mesh face */
OrigSpaceFace *osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE);
- const MFace *mface = &mesh->mface[i];
+ const MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ const MFace *mface = &mfaces[i];
if (osface == NULL) {
mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f;
@@ -2117,7 +2120,8 @@ void psys_particle_on_dm(Mesh *mesh_final,
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh_final);
if (from == PART_FROM_VERT) {
- copy_v3_v3(vec, mesh_final->mvert[mapindex].co);
+ const MVert *vertices = BKE_mesh_vertices(mesh_final);
+ copy_v3_v3(vec, vertices[mapindex].co);
if (nor) {
copy_v3_v3(nor, vert_normals[mapindex]);
@@ -2143,9 +2147,10 @@ void psys_particle_on_dm(Mesh *mesh_final,
MTFace *mtface;
MVert *mvert;
- mface = &mesh_final->mface[mapindex];
- mvert = mesh_final->mvert;
- mtface = mesh_final->mtface;
+ MFace *mfaces = CustomData_get_layer(&mesh_final->fdata, CD_MFACE);
+ mface = &mfaces[mapindex];
+ mvert = BKE_mesh_vertices_for_write(mesh_final);
+ mtface = CustomData_get_layer(&mesh_final->fdata, CD_MTFACE);
if (mtface) {
mtface += mapindex;
@@ -2634,7 +2639,7 @@ float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup)
/* hair dynamics pinning vgroup */
}
else if (psys->vgroup[vgroup]) {
- MDeformVert *dvert = mesh->dvert;
+ const MDeformVert *dvert = BKE_mesh_deform_verts(mesh);
if (dvert) {
int totvert = mesh->totvert, i;
vg = MEM_callocN(sizeof(float) * totvert, "vg_cache");
@@ -3848,7 +3853,8 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
return;
}
- mface = &mesh->mface[i];
+ MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ mface = &mfaces[i];
const OrigSpaceFace *osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE);
if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) {
@@ -3863,9 +3869,10 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4]
}
}
else {
- copy_v3_v3(v[0], mesh->mvert[mface->v1].co);
- copy_v3_v3(v[1], mesh->mvert[mface->v2].co);
- copy_v3_v3(v[2], mesh->mvert[mface->v3].co);
+ const MVert *verts = BKE_mesh_vertices(mesh);
+ copy_v3_v3(v[0], verts[mface->v1].co);
+ copy_v3_v3(v[1], verts[mface->v2].co);
+ copy_v3_v3(v[2], verts[mface->v3].co);
}
triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat);
@@ -4155,6 +4162,7 @@ static int get_particle_uv(Mesh *mesh,
float *texco,
bool from_vert)
{
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mf;
const MTFace *tf;
int i;
@@ -4162,10 +4170,6 @@ static int get_particle_uv(Mesh *mesh,
tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name);
if (tf == NULL) {
- tf = mesh->mtface;
- }
-
- if (tf == NULL) {
return 0;
}
@@ -4186,7 +4190,7 @@ static int get_particle_uv(Mesh *mesh,
}
else {
if (from_vert) {
- mf = mesh->mface;
+ mf = mfaces;
/* This finds the first face to contain the emitting vertex,
* this is not ideal, but is mostly fine as UV seams generally
@@ -4199,7 +4203,7 @@ static int get_particle_uv(Mesh *mesh,
}
}
else {
- mf = &mesh->mface[i];
+ mf = &mfaces[i];
}
psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco);
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index da769515f08..e19b25b2da1 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -97,7 +97,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
{
ParticleData *pa = NULL;
float min[3], max[3], delta[3], d;
- MVert *mv, *mvert = mesh->mvert;
+ MVert *mv, *mvert = BKE_mesh_vertices_for_write(mesh);
int totvert = mesh->totvert, from = psys->part->from;
int i, j, k, p, res = psys->part->grid_res, size[3], axis;
@@ -181,7 +181,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys)
int amax = from == PART_FROM_FACE ? 3 : 1;
totface = mesh->totface;
- mface = mface_array = mesh->mface;
+ mface = mface_array = CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (a = 0; a < amax; a++) {
if (a == 0) {
@@ -464,7 +464,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i
ParticleThreadContext *ctx = thread->ctx;
MFace *mface;
- mface = ctx->mesh->mface;
+ mface = CustomData_get_layer(&ctx->mesh->fdata, CD_MFACE);
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
@@ -525,10 +525,11 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i
int i;
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
MFace *mface;
pa->num = i = ctx->index[p];
- mface = &mesh->mface[i];
+ mface = &mfaces[i];
switch (distr) {
case PART_DISTR_JIT:
@@ -575,10 +576,11 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */
MFace *mface;
- MVert *mvert = mesh->mvert;
+ MVert *mvert = BKE_mesh_vertices_for_write(mesh);
pa->num = i = ctx->index[p];
- mface = &mesh->mface[i];
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ mface = &mfaces[i];
switch (distr) {
case PART_DISTR_JIT:
@@ -619,8 +621,8 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa,
min_d = FLT_MAX;
intersect = 0;
-
- for (i = 0, mface = mesh->mface; i < tot; i++, mface++) {
+ mface = CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ for (i = 0; i < tot; i++, mface++) {
if (i == pa->num) {
continue;
}
@@ -689,7 +691,8 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i
return;
}
- mf = &mesh->mface[ctx->index[p]];
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ mf = &mfaces[ctx->index[p]];
randu = BLI_rng_get_float(thread->rng);
randv = BLI_rng_get_float(thread->rng);
@@ -989,7 +992,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
BKE_mesh_orco_ensure(ob, mesh);
if (from == PART_FROM_VERT) {
- MVert *mv = mesh->mvert;
+ MVert *mv = BKE_mesh_vertices_for_write(mesh);
const float(*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO);
int totvert = mesh->totvert;
@@ -1042,8 +1045,9 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO);
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < totelem; i++) {
- MFace *mf = &mesh->mface[i];
+ MFace *mf = &mfaces[i];
if (orcodata) {
/* Transform orcos from normalized 0..1 to object space. */
@@ -1059,14 +1063,15 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
}
}
else {
- v1 = &mesh->mvert[mf->v1];
- v2 = &mesh->mvert[mf->v2];
- v3 = &mesh->mvert[mf->v3];
+ MVert *verts = BKE_mesh_vertices_for_write(mesh);
+ v1 = &verts[mf->v1];
+ v2 = &verts[mf->v2];
+ v3 = &verts[mf->v3];
copy_v3_v3(co1, v1->co);
copy_v3_v3(co2, v2->co);
copy_v3_v3(co3, v3->co);
if (mf->v4) {
- v4 = &mesh->mvert[mf->v4];
+ v4 = &verts[mf->v4];
copy_v3_v3(co4, v4->co);
}
}
@@ -1105,8 +1110,9 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
}
}
else { /* PART_FROM_FACE / PART_FROM_VOLUME */
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < totelem; i++) {
- MFace *mf = &mesh->mface[i];
+ MFace *mf = &mfaces[i];
tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
if (mf->v4) {
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 254cea0bd8b..14c4691413d 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3322,12 +3322,10 @@ static void hair_create_input_mesh(ParticleSimulationData *sim,
mesh = *r_mesh;
if (!mesh) {
*r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0);
- CustomData_add_layer(&mesh->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, mesh->totvert);
- BKE_mesh_update_customdata_pointers(mesh, false);
}
- mvert = mesh->mvert;
- medge = mesh->medge;
- dvert = mesh->dvert;
+ mvert = BKE_mesh_vertices_for_write(mesh);
+ medge = BKE_mesh_edges_for_write(mesh);
+ dvert = BKE_mesh_deform_verts_for_write(mesh);
if (psys->clmd->hairdata == NULL) {
psys->clmd->hairdata = MEM_mallocN(sizeof(ClothHairData) * totpoint, "hair data");
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 49397797c0d..f733f3145ec 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -2,6 +2,7 @@
* Copyright 2022 Blender Foundation. All rights reserved. */
#include "BKE_customdata.h"
+#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_pbvh.h"
#include "BKE_pbvh_pixels.hh"
@@ -291,7 +292,8 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
for (PBVHNode *node : nodes_to_update) {
NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data);
- init_triangles(pbvh, node, node_data, mesh->mloop);
+ const Span<MLoop> loops = mesh->loops();
+ init_triangles(pbvh, node, node_data, loops.data());
}
EncodePixelsUserData user_data;
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index e5fb61bfa2f..fb078a299b5 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -364,7 +364,7 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob,
if (ob->type == OB_MESH && ob->data) {
mesh = rigidbody_get_mesh(ob);
- mvert = (mesh) ? mesh->mvert : NULL;
+ mvert = (mesh) ? BKE_mesh_vertices_for_write(mesh) : NULL;
totvert = (mesh) ? mesh->totvert : 0;
}
else {
@@ -390,11 +390,9 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
if (ob->type == OB_MESH) {
Mesh *mesh = NULL;
- MVert *mvert;
const MLoopTri *looptri;
int totvert;
int tottri;
- const MLoop *mloop;
mesh = rigidbody_get_mesh(ob);
@@ -403,11 +401,11 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
return NULL;
}
- mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
- mloop = mesh->mloop;
+ const MLoop *mloop = BKE_mesh_loops(mesh);
/* sanity checking - potential case when no data will be present */
if ((totvert == 0) || (tottri == 0)) {
@@ -670,21 +668,19 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
case RB_SHAPE_TRIMESH: {
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
- MVert *mvert;
const MLoopTri *lt = NULL;
int totvert, tottri = 0;
- const MLoop *mloop = NULL;
/* ensure mesh validity, then grab data */
if (mesh == NULL) {
return;
}
- mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
totvert = mesh->totvert;
lt = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
- mloop = mesh->mloop;
+ const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
@@ -746,21 +742,19 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
case RB_SHAPE_TRIMESH: {
if (ob->type == OB_MESH) {
Mesh *mesh = rigidbody_get_mesh(ob);
- MVert *mvert;
const MLoopTri *looptri;
int totvert, tottri;
- const MLoop *mloop;
/* ensure mesh validity, then grab data */
if (mesh == NULL) {
return;
}
- mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
totvert = mesh->totvert;
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
tottri = mesh->runtime.looptris.len;
- mloop = mesh->mloop;
+ const MLoop *mloop = BKE_mesh_loops(mesh);
if (totvert > 0 && tottri > 0) {
BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
@@ -1677,7 +1671,7 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO
if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
Mesh *mesh = ob->runtime.mesh_deform_eval;
if (mesh) {
- MVert *mvert = mesh->mvert;
+ MVert *mvert = BKE_mesh_vertices_for_write(mesh);
int totvert = mesh->totvert;
const BoundBox *bb = BKE_object_boundbox_get(ob);
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index 82cc250c6d1..bea2f8f3c4f 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -64,9 +64,9 @@ typedef struct ShrinkwrapCalcData {
float (*vertexCos)[3]; /* vertexs being shrinkwraped */
int numVerts;
- struct MDeformVert *dvert; /* Pointer to mdeform array */
- int vgroup; /* Vertex group num */
- bool invert_vgroup; /* invert vertex group influence */
+ const struct MDeformVert *dvert; /* Pointer to mdeform array */
+ int vgroup; /* Vertex group num */
+ bool invert_vgroup; /* invert vertex group influence */
struct Mesh *target; /* mesh we are shrinking to */
struct SpaceTransform local2target; /* transform to move between local and target space */
@@ -113,6 +113,7 @@ bool BKE_shrinkwrap_init_tree(
}
data->mesh = mesh;
+ data->polys = BKE_mesh_polygons(mesh);
if (shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX) {
data->bvh = BKE_bvhtree_from_mesh_get(&data->treeData, mesh, BVHTREE_FROM_VERTS, 2);
@@ -191,9 +192,9 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata,
static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(struct Mesh *mesh)
{
- const MLoop *mloop = mesh->mloop;
- const MEdge *medge = mesh->medge;
- const MVert *mvert = mesh->mvert;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
+ const MEdge *medge = BKE_mesh_edges(mesh);
+ const MLoop *mloop = BKE_mesh_loops(mesh);
/* Count faces per edge (up to 2). */
char *edge_mode = MEM_calloc_arrayN((size_t)mesh->totedge, sizeof(char), __func__);
@@ -937,7 +938,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree,
int eidx)
{
const BVHTreeFromMesh *data = &tree->treeData;
- const MEdge *edge = &tree->mesh->medge[eidx];
+ const MEdge *edge = &data->edge[eidx];
const float *vedge_co[2] = {data->vert[edge->v1].co, data->vert[edge->v2].co};
#ifdef TRACE_TARGET_PROJECT
@@ -1179,7 +1180,7 @@ void BKE_shrinkwrap_compute_smooth_normal(const struct ShrinkwrapTreeData *tree,
const float(*vert_normals)[3] = tree->treeData.vert_normals;
/* Interpolate smooth normals if enabled. */
- if ((tree->mesh->mpoly[tri->poly].flag & ME_SMOOTH) != 0) {
+ if ((tree->polys[tri->poly].flag & ME_SMOOTH) != 0) {
const uint32_t vert_indices[3] = {treeData->loop[tri->tri[0]].v,
treeData->loop[tri->tri[1]].v,
treeData->loop[tri->tri[2]].v};
@@ -1369,7 +1370,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
struct Scene *scene,
Object *ob,
Mesh *mesh,
- MDeformVert *dvert,
+ const MDeformVert *dvert,
const int defgrp_index,
float (*vertexCos)[3],
int numVerts)
@@ -1411,7 +1412,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd,
if (mesh != NULL && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) {
/* Setup arrays to get vertexs positions, normals and deform weights */
- calc.vert = mesh->mvert;
+ calc.vert = BKE_mesh_vertices_for_write(mesh);
calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
/* Using vertexs positions/normals as if a subsurface was applied */
@@ -1574,7 +1575,7 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
calc.vgroup = -1;
calc.target = target_me;
calc.keepDist = ssmd.keepDist;
- calc.vert = src_me->mvert;
+ calc.vert = BKE_mesh_vertices_for_write(src_me);
BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob_target, ob_target);
ShrinkwrapTreeData tree;
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index afb8d5cb9f8..a426782af04 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -567,7 +567,7 @@ static void ccd_update_deflector_hash(Depsgraph *depsgraph,
static int count_mesh_quads(Mesh *me)
{
int a, result = 0;
- const MPoly *mp = me->mpoly;
+ const MPoly *mp = BKE_mesh_polygons(me);
if (mp) {
for (a = me->totpoly; a > 0; a--, mp++) {
@@ -591,8 +591,8 @@ static void add_mesh_quad_diag_springs(Object *ob)
nofquads = count_mesh_quads(me);
if (nofquads) {
- const MLoop *mloop = me->mloop;
- const MPoly *mp = me->mpoly;
+ const MLoop *mloop = BKE_mesh_loops(me);
+ const MPoly *mp = BKE_mesh_polygons(me);
BodySpring *bs;
/* resize spring-array to hold additional quad springs */
@@ -2632,6 +2632,7 @@ static void springs_from_mesh(Object *ob)
BodyPoint *bp;
int a;
float scale = 1.0f;
+ const MVert *vertices = BKE_mesh_vertices(me);
sb = ob->soft;
if (me && sb) {
@@ -2642,7 +2643,7 @@ static void springs_from_mesh(Object *ob)
if (me->totvert) {
bp = ob->soft->bpoint;
for (a = 0; a < me->totvert; a++, bp++) {
- copy_v3_v3(bp->origS, me->mvert[a].co);
+ copy_v3_v3(bp->origS, vertices[a].co);
mul_m4_v3(ob->obmat, bp->origS);
}
}
@@ -2663,7 +2664,7 @@ static void mesh_to_softbody(Object *ob)
{
SoftBody *sb;
Mesh *me = ob->data;
- MEdge *medge = me->medge;
+ const MEdge *medge = BKE_mesh_edges(me);
BodyPoint *bp;
BodySpring *bs;
int a, totedge;
@@ -2683,10 +2684,11 @@ static void mesh_to_softbody(Object *ob)
sb = ob->soft;
bp = sb->bpoint;
- defgroup_index = me->dvert ? (sb->vertgroup - 1) : -1;
- defgroup_index_mass = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1;
- defgroup_index_spring = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) :
- -1;
+ const MDeformVert *dvert = BKE_mesh_deform_verts(me);
+
+ defgroup_index = dvert ? (sb->vertgroup - 1) : -1;
+ defgroup_index_mass = dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1;
+ defgroup_index_spring = dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) : -1;
for (a = 0; a < me->totvert; a++, bp++) {
/* get scalar values needed *per vertex* from vertex group functions,
@@ -2699,7 +2701,7 @@ static void mesh_to_softbody(Object *ob)
BLI_assert(bp->goal == sb->defgoal);
}
if ((ob->softflag & OB_SB_GOAL) && (defgroup_index != -1)) {
- bp->goal *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index);
+ bp->goal *= BKE_defvert_find_weight(&dvert[a], defgroup_index);
}
/* to proof the concept
@@ -2707,11 +2709,11 @@ static void mesh_to_softbody(Object *ob)
*/
if (defgroup_index_mass != -1) {
- bp->mass *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_mass);
+ bp->mass *= BKE_defvert_find_weight(&dvert[a], defgroup_index_mass);
}
if (defgroup_index_spring != -1) {
- bp->springweight *= BKE_defvert_find_weight(&me->dvert[a], defgroup_index_spring);
+ bp->springweight *= BKE_defvert_find_weight(&dvert[a], defgroup_index_spring);
}
}
@@ -2753,19 +2755,23 @@ static void mesh_faces_to_scratch(Object *ob)
MLoopTri *looptri, *lt;
BodyFace *bodyface;
int a;
+ const MVert *vertices = BKE_mesh_vertices(me);
+ const MPoly *polygons = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
+
/* Allocate and copy faces. */
sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop);
looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__);
- BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, looptri);
+ BKE_mesh_recalc_looptri(loops, polygons, vertices, me->totloop, me->totpoly, looptri);
bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface,
"SB_body_Faces");
for (a = 0; a < sb->scratch->totface; a++, lt++, bodyface++) {
- bodyface->v1 = me->mloop[lt->tri[0]].v;
- bodyface->v2 = me->mloop[lt->tri[1]].v;
- bodyface->v3 = me->mloop[lt->tri[2]].v;
+ bodyface->v1 = loops[lt->tri[0]].v;
+ bodyface->v2 = loops[lt->tri[1]].v;
+ bodyface->v3 = loops[lt->tri[2]].v;
zero_v3(bodyface->ext_force);
bodyface->ext_force[0] = bodyface->ext_force[1] = bodyface->ext_force[2] = 0.0f;
bodyface->flag = 0;
diff --git a/source/blender/blenkernel/intern/subdiv_ccg_mask.c b/source/blender/blenkernel/intern/subdiv_ccg_mask.c
index 1290f1e0834..95bbbfeb17e 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg_mask.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg_mask.c
@@ -17,6 +17,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
+#include "BKE_mesh.h"
#include "BKE_subdiv.h"
#include "MEM_guardedalloc.h"
@@ -102,7 +103,7 @@ static void free_mask_data(SubdivCCGMaskEvaluator *mask_evaluator)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
- const MPoly *mpoly = mesh->mpoly;
+ const MPoly *mpoly = BKE_mesh_polygons(mesh);
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[poly_index];
num_ptex_faces += (poly->totloop == 4) ? 1 : poly->totloop;
@@ -113,7 +114,7 @@ static int count_num_ptex_faces(const Mesh *mesh)
static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh)
{
GridPaintMaskData *data = mask_evaluator->user_data;
- const MPoly *mpoly = mesh->mpoly;
+ const MPoly *mpoly = BKE_mesh_polygons(mesh);
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = MEM_malloc_arrayN(
@@ -141,7 +142,7 @@ static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const
static void mask_init_data(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh)
{
GridPaintMaskData *data = mask_evaluator->user_data;
- data->mpoly = mesh->mpoly;
+ data->mpoly = BKE_mesh_polygons(mesh);
data->grid_paint_mask = CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
mask_data_init_mapping(mask_evaluator, mesh);
}
diff --git a/source/blender/blenkernel/intern/subdiv_ccg_material.c b/source/blender/blenkernel/intern/subdiv_ccg_material.c
index 9095a628418..e84a5b6ca46 100644
--- a/source/blender/blenkernel/intern/subdiv_ccg_material.c
+++ b/source/blender/blenkernel/intern/subdiv_ccg_material.c
@@ -5,7 +5,7 @@
* \ingroup bke
*/
-#include "BKE_customdata.h"
+#include "BKE_mesh.h"
#include "BKE_subdiv_ccg.h"
#include "MEM_guardedalloc.h"
@@ -15,6 +15,7 @@
typedef struct CCGMaterialFromMeshData {
const Mesh *mesh;
+ const MPoly *polys;
const int *material_indices;
} CCGMaterialFromMeshData;
@@ -22,10 +23,8 @@ static DMFlagMat subdiv_ccg_material_flags_eval(
SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator, const int coarse_face_index)
{
CCGMaterialFromMeshData *data = (CCGMaterialFromMeshData *)material_flags_evaluator->user_data;
- const Mesh *mesh = data->mesh;
- BLI_assert(coarse_face_index < mesh->totpoly);
- const MPoly *mpoly = mesh->mpoly;
- const MPoly *poly = &mpoly[coarse_face_index];
+ BLI_assert(coarse_face_index < data->mesh->totpoly);
+ const MPoly *poly = &data->polys[coarse_face_index];
DMFlagMat material_flags;
material_flags.flag = poly->flag;
material_flags.mat_nr = data->material_indices ? data->material_indices[coarse_face_index] : 0;
@@ -46,6 +45,7 @@ void BKE_subdiv_ccg_material_flags_init_from_mesh(
data->mesh = mesh;
data->material_indices = (const int *)CustomData_get_layer_named(
&mesh->pdata, CD_PROP_INT32, "material_index");
+ data->polys = BKE_mesh_polygons(mesh);
material_flags_evaluator->eval_material_flags = subdiv_ccg_material_flags_eval;
material_flags_evaluator->free = subdiv_ccg_material_flags_free;
material_flags_evaluator->user_data = data;
diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
index 9c6d507d42c..f908e1af4ac 100644
--- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c
@@ -16,6 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
+#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_subdiv.h"
@@ -33,6 +34,11 @@
typedef struct ConverterStorage {
SubdivSettings settings;
const Mesh *mesh;
+ const MVert *verts;
+ const MEdge *edges;
+ const MPoly *polys;
+ const MLoop *loops;
+
/* CustomData layer for vertex sharpnesses. */
const float *cd_vertex_crease;
/* Indexed by loop index, value denotes index of face-varying vertex
@@ -116,7 +122,7 @@ static int get_num_vertices(const OpenSubdiv_Converter *converter)
static int get_num_face_vertices(const OpenSubdiv_Converter *converter, int manifold_face_index)
{
ConverterStorage *storage = converter->user_data;
- return storage->mesh->mpoly[manifold_face_index].totloop;
+ return storage->polys[manifold_face_index].totloop;
}
static void get_face_vertices(const OpenSubdiv_Converter *converter,
@@ -124,8 +130,8 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter,
int *manifold_face_vertices)
{
ConverterStorage *storage = converter->user_data;
- const MPoly *poly = &storage->mesh->mpoly[manifold_face_index];
- const MLoop *mloop = storage->mesh->mloop;
+ const MPoly *poly = &storage->polys[manifold_face_index];
+ const MLoop *mloop = storage->loops;
for (int corner = 0; corner < poly->totloop; corner++) {
manifold_face_vertices[corner] =
storage->manifold_vertex_index[mloop[poly->loopstart + corner].v];
@@ -138,7 +144,7 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter,
{
ConverterStorage *storage = converter->user_data;
const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index];
- const MEdge *edge = &storage->mesh->medge[edge_index];
+ const MEdge *edge = &storage->edges[edge_index];
manifold_edge_vertices[0] = storage->manifold_vertex_index[edge->v1];
manifold_edge_vertices[1] = storage->manifold_vertex_index[edge->v2];
}
@@ -155,7 +161,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manif
return 0.0f;
}
const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index];
- const MEdge *medge = storage->mesh->medge;
+ const MEdge *medge = storage->edges;
return BKE_subdiv_crease_to_sharpness_char(medge[edge_index].crease);
}
@@ -193,8 +199,6 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
{
ConverterStorage *storage = converter->user_data;
const Mesh *mesh = storage->mesh;
- const MPoly *mpoly = mesh->mpoly;
- const MLoop *mloop = mesh->mloop;
const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index);
const int num_poly = mesh->totpoly;
const int num_vert = mesh->totvert;
@@ -205,9 +209,9 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
mesh->totloop, sizeof(int), "loop uv vertex index");
}
UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(
- mpoly,
+ storage->polys,
(const bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"),
- mloop,
+ storage->loops,
mloopuv,
num_poly,
num_vert,
@@ -222,7 +226,7 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la
if (uv_vert->separate) {
storage->num_uv_coordinates++;
}
- const MPoly *mp = &mpoly[uv_vert->poly_index];
+ const MPoly *mp = &storage->polys[uv_vert->poly_index];
const int global_loop_index = mp->loopstart + uv_vert->loop_of_poly_index;
storage->loop_uv_indices[global_loop_index] = storage->num_uv_coordinates;
uv_vert = uv_vert->next;
@@ -250,7 +254,7 @@ static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter,
const int corner)
{
ConverterStorage *storage = converter->user_data;
- const MPoly *mp = &storage->mesh->mpoly[face_index];
+ const MPoly *mp = &storage->polys[face_index];
return storage->loop_uv_indices[mp->loopstart + corner];
}
@@ -344,9 +348,9 @@ static void initialize_manifold_index_array(const BLI_bitmap *used_map,
static void initialize_manifold_indices(ConverterStorage *storage)
{
const Mesh *mesh = storage->mesh;
- const MEdge *medge = mesh->medge;
- const MLoop *mloop = mesh->mloop;
- const MPoly *mpoly = mesh->mpoly;
+ const MEdge *medge = storage->edges;
+ const MLoop *mloop = storage->loops;
+ const MPoly *mpoly = storage->polys;
/* Set bits of elements which are not loose. */
BLI_bitmap *vert_used_map = BLI_BITMAP_NEW(mesh->totvert, "vert used map");
BLI_bitmap *edge_used_map = BLI_BITMAP_NEW(mesh->totedge, "edge used map");
@@ -389,6 +393,10 @@ static void init_user_data(OpenSubdiv_Converter *converter,
ConverterStorage *user_data = MEM_mallocN(sizeof(ConverterStorage), __func__);
user_data->settings = *settings;
user_data->mesh = mesh;
+ user_data->verts = BKE_mesh_vertices(mesh);
+ user_data->edges = BKE_mesh_edges(mesh);
+ user_data->polys = BKE_mesh_polygons(mesh);
+ user_data->loops = BKE_mesh_loops(mesh);
user_data->cd_vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE);
user_data->loop_uv_indices = NULL;
initialize_manifold_indices(user_data);
diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.c
index 0decb57bb38..54078dea8da 100644
--- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c
+++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.c
@@ -18,6 +18,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
+#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_subdiv_eval.h"
@@ -360,7 +361,7 @@ static void free_displacement(SubdivDisplacement *displacement)
static int count_num_ptex_faces(const Mesh *mesh)
{
int num_ptex_faces = 0;
- const MPoly *mpoly = mesh->mpoly;
+ const MPoly *mpoly = BKE_mesh_polygons(mesh);
for (int poly_index = 0; poly_index < mesh->totpoly; poly_index++) {
const MPoly *poly = &mpoly[poly_index];
num_ptex_faces += (poly->totloop == 4) ? 1 : poly->totloop;
@@ -371,7 +372,7 @@ static int count_num_ptex_faces(const Mesh *mesh)
static void displacement_data_init_mapping(SubdivDisplacement *displacement, const Mesh *mesh)
{
MultiresDisplacementData *data = displacement->user_data;
- const MPoly *mpoly = mesh->mpoly;
+ const MPoly *mpoly = BKE_mesh_polygons(mesh);
const int num_ptex_faces = count_num_ptex_faces(mesh);
/* Allocate memory. */
data->ptex_poly_corner = MEM_malloc_arrayN(
@@ -406,7 +407,7 @@ static void displacement_init_data(SubdivDisplacement *displacement,
data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl);
data->mesh = mesh;
data->mmd = mmd;
- data->mpoly = mesh->mpoly;
+ data->mpoly = BKE_mesh_polygons(mesh);
data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
data->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv);
data->is_initialized = false;
diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c
index 841b47818f1..91b64145396 100644
--- a/source/blender/blenkernel/intern/subdiv_eval.c
+++ b/source/blender/blenkernel/intern/subdiv_eval.c
@@ -16,6 +16,7 @@
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
+#include "BKE_mesh.h"
#include "BKE_subdiv.h"
#include "MEM_guardedalloc.h"
@@ -80,9 +81,9 @@ static void set_coarse_positions(Subdiv *subdiv,
const Mesh *mesh,
const float (*coarse_vertex_cos)[3])
{
- const MVert *mvert = mesh->mvert;
- const MLoop *mloop = mesh->mloop;
- const MPoly *mpoly = mesh->mpoly;
+ const MVert *mvert = BKE_mesh_vertices(mesh);
+ const MPoly *mpoly = BKE_mesh_polygons(mesh);
+ const MLoop *mloop = BKE_mesh_loops(mesh);
/* Mark vertices which needs new coordinates. */
/* TODO(sergey): This is annoying to calculate this on every update,
* maybe it's better to cache this mapping. Or make it possible to have
@@ -125,6 +126,7 @@ static void set_coarse_positions(Subdiv *subdiv,
typedef struct FaceVaryingDataFromUVContext {
OpenSubdiv_TopologyRefiner *topology_refiner;
const Mesh *mesh;
+ const MPoly *polys;
const MLoopUV *mloopuv;
float (*buffer)[2];
int layer_index;
@@ -137,8 +139,7 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata,
FaceVaryingDataFromUVContext *ctx = userdata;
OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner;
const int layer_index = ctx->layer_index;
- const Mesh *mesh = ctx->mesh;
- const MPoly *mpoly = &mesh->mpoly[face_index];
+ const MPoly *mpoly = &ctx->polys[face_index];
const MLoopUV *mluv = &ctx->mloopuv[mpoly->loopstart];
/* TODO(sergey): OpenSubdiv's C-API converter can change winding of
@@ -171,6 +172,7 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv,
ctx.layer_index = layer_index;
ctx.mloopuv = mluv;
ctx.mesh = mesh;
+ ctx.polys = BKE_mesh_polygons(mesh);
ctx.buffer = buffer;
TaskParallelSettings parallel_range_settings;
diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.c
index 80364561d01..ac402ceaca0 100644
--- a/source/blender/blenkernel/intern/subdiv_foreach.c
+++ b/source/blender/blenkernel/intern/subdiv_foreach.c
@@ -158,8 +158,8 @@ static void subdiv_foreach_ctx_count(SubdivForeachTaskContext *ctx)
const int num_inner_vertices_per_noquad_patch = (no_quad_patch_resolution - 2) *
(no_quad_patch_resolution - 2);
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
ctx->num_subdiv_vertices = coarse_mesh->totvert;
ctx->num_subdiv_edges = coarse_mesh->totedge * (num_subdiv_vertices_per_coarse_edge + 1);
/* Calculate extra vertices and edges created by non-loose geometry. */
@@ -225,7 +225,7 @@ static void subdiv_foreach_ctx_init_offsets(SubdivForeachTaskContext *ctx)
ctx->edge_inner_offset = ctx->edge_boundary_offset +
coarse_mesh->totedge * num_subdiv_edges_per_coarse_edge;
/* "Indexed" offsets. */
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
int vertex_offset = 0;
int edge_offset = 0;
int polygon_offset = 0;
@@ -301,8 +301,9 @@ static void subdiv_foreach_corner_vertices_regular_do(
{
const float weights[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}};
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
@@ -342,8 +343,9 @@ static void subdiv_foreach_corner_vertices_special_do(
bool check_usage)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const int coarse_poly_index = coarse_poly - coarse_mpoly;
int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
@@ -407,7 +409,7 @@ static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx,
return;
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (coarse_poly->totloop == 4) {
@@ -432,11 +434,11 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct
const float inv_resolution_1 = 1.0f / (float)resolution_1;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
- const int poly_index = coarse_poly - coarse_mesh->mpoly;
+ const int poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_index = ctx->face_ptex_offset[poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
const MLoop *coarse_loop = &coarse_mloop[coarse_poly->loopstart + corner];
@@ -499,11 +501,11 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct
const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1);
const float inv_ptex_resolution_1 = 1.0f / (float)(num_vertices_per_ptex_edge - 1);
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
- const int poly_index = coarse_poly - coarse_mesh->mpoly;
+ const int poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_start_index = ctx->face_ptex_offset[poly_index];
int ptex_face_index = ptex_face_start_index;
for (int corner = 0; corner < coarse_poly->totloop; corner++, ptex_face_index++) {
@@ -595,7 +597,7 @@ static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, vo
return;
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (coarse_poly->totloop == 4) {
@@ -616,7 +618,8 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx,
const int resolution = ctx->settings->resolution;
const float inv_resolution_1 = 1.0f / (float)(resolution - 1);
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index];
int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index;
@@ -644,7 +647,8 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx,
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const float inv_ptex_face_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1);
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const int coarse_poly_index = coarse_poly - coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const int coarse_poly_index = coarse_poly - coarse_mpoly;
int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index];
const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index];
int subdiv_vertex_index = ctx->vertices_inner_offset + start_vertex_index;
@@ -691,7 +695,7 @@ static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx, void *tls, const int poly_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (ctx->foreach_context->vertex_inner != NULL) {
subdiv_foreach_inner_vertices(ctx, tls, coarse_poly);
@@ -775,9 +779,9 @@ static void subdiv_foreach_edges_all_patches_regular(SubdivForeachTaskContext *c
const MPoly *coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int poly_index = coarse_poly - coarse_mpoly;
const int resolution = ctx->settings->resolution;
const int start_vertex_index = ctx->vertices_inner_offset +
@@ -856,9 +860,9 @@ static void subdiv_foreach_edges_all_patches_special(SubdivForeachTaskContext *c
const MPoly *coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int poly_index = coarse_poly - coarse_mpoly;
const int resolution = ctx->settings->resolution;
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
@@ -984,7 +988,7 @@ static void subdiv_foreach_edges_all_patches(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_edges(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
subdiv_foreach_edges_all_patches(ctx, tls, coarse_poly);
}
@@ -994,7 +998,7 @@ static void subdiv_foreach_boundary_edges(SubdivForeachTaskContext *ctx,
int coarse_edge_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
const MEdge *coarse_edge = &coarse_medge[coarse_edge_index];
const int resolution = ctx->settings->resolution;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
@@ -1125,9 +1129,9 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx,
const int resolution = ctx->settings->resolution;
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_inner_resolution = ptex_resolution - 2;
@@ -1319,9 +1323,9 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
const int resolution = ctx->settings->resolution;
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MEdge *coarse_medge = BKE_mesh_edges(coarse_mesh);
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
const int coarse_poly_index = coarse_poly - coarse_mpoly;
const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution);
const int ptex_face_inner_resolution = ptex_face_resolution - 2;
@@ -1654,7 +1658,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx,
static void subdiv_foreach_loops(SubdivForeachTaskContext *ctx, void *tls, int poly_index)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
if (coarse_poly->totloop == 4) {
subdiv_foreach_loops_regular(ctx, tls, coarse_poly);
@@ -1676,7 +1680,7 @@ static void subdiv_foreach_polys(SubdivForeachTaskContext *ctx, void *tls, int p
const int start_poly_index = ctx->subdiv_polygon_offset[poly_index];
/* Base/coarse mesh information. */
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
const int num_ptex_faces_per_poly = num_ptex_faces_per_poly_get(coarse_poly);
const int ptex_resolution = ptex_face_resolution_get(coarse_poly, resolution);
@@ -1731,7 +1735,8 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat
const float inv_resolution_1 = 1.0f / (float)resolution_1;
const int num_subdiv_vertices_per_coarse_edge = resolution - 2;
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
+ const MEdge *coarse_edges = BKE_mesh_edges(coarse_mesh);
+ const MEdge *coarse_edge = &coarse_edges[coarse_edge_index];
/* Subdivision vertices which corresponds to edge's v1 and v2. */
const int subdiv_v1_index = ctx->vertices_corner_offset + coarse_edge->v1;
const int subdiv_v2_index = ctx->vertices_corner_offset + coarse_edge->v2;
@@ -1768,7 +1773,7 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct
return;
}
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
subdiv_foreach_corner_vertices(ctx, tls, coarse_poly);
@@ -1779,8 +1784,8 @@ static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ct
static void subdiv_foreach_mark_non_loose_geometry(SubdivForeachTaskContext *ctx)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
+ const MPoly *coarse_mpoly = BKE_mesh_polygons(coarse_mesh);
+ const MLoop *coarse_mloop = BKE_mesh_loops(coarse_mesh);
for (int poly_index = 0; poly_index < coarse_mesh->totpoly; poly_index++) {
const MPoly *coarse_poly = &coarse_mpoly[poly_index];
for (int corner = 0; corner < coarse_poly->totloop; corner++) {
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc
index da22ee6fd47..c222fc46800 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.cc
+++ b/source/blender/blenkernel/intern/subdiv_mesh.cc
@@ -32,8 +32,18 @@
struct SubdivMeshContext {
const SubdivToMeshSettings *settings;
const Mesh *coarse_mesh;
+ const MVert *coarse_verts;
+ const MEdge *coarse_edges;
+ const MPoly *coarse_polys;
+ const MLoop *coarse_loops;
+
Subdiv *subdiv;
Mesh *subdiv_mesh;
+ MVert *subdiv_verts;
+ MEdge *subdiv_edges;
+ MPoly *subdiv_polys;
+ MLoop *subdiv_loops;
+
/* Cached custom data arrays for faster access. */
int *vert_origindex;
int *edge_origindex;
@@ -63,6 +73,10 @@ static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx)
static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
{
Mesh *subdiv_mesh = ctx->subdiv_mesh;
+ ctx->subdiv_verts = BKE_mesh_vertices_for_write(subdiv_mesh);
+ ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh);
+ ctx->subdiv_polys = BKE_mesh_polygons_for_write(subdiv_mesh);
+ ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh);
/* Pointers to original indices layers. */
ctx->vert_origindex = static_cast<int *>(
CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX));
@@ -115,7 +129,7 @@ static void loops_of_ptex_get(const SubdivMeshContext *ctx,
const MPoly *coarse_poly,
const int ptex_of_poly_index)
{
- const MLoop *coarse_mloop = ctx->coarse_mesh->mloop;
+ const MLoop *coarse_mloop = ctx->coarse_loops;
const int first_ptex_loop_index = coarse_poly->loopstart + ptex_of_poly_index;
/* Loop which look in the (opposite) V direction of the current
* ptex face.
@@ -171,7 +185,7 @@ static void vertex_interpolation_init(const SubdivMeshContext *ctx,
const MPoly *coarse_poly)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
+ const MLoop *coarse_mloop = ctx->coarse_loops;
if (coarse_poly->totloop == 4) {
vertex_interpolation->vertex_data = &coarse_mesh->vdata;
vertex_interpolation->vertex_indices[0] = coarse_mloop[coarse_poly->loopstart + 0].v;
@@ -223,8 +237,7 @@ static void vertex_interpolation_from_corner(const SubdivMeshContext *ctx,
}
else {
const CustomData *vertex_data = &ctx->coarse_mesh->vdata;
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
+ const MLoop *coarse_mloop = ctx->coarse_loops;
LoopsOfPtex loops_of_ptex;
loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
/* Ptex face corner corresponds to a poly loop with same index. */
@@ -358,8 +371,7 @@ static void loop_interpolation_from_corner(const SubdivMeshContext *ctx,
}
else {
const CustomData *loop_data = &ctx->coarse_mesh->ldata;
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MLoop *coarse_mloop = coarse_mesh->mloop;
+ const MLoop *coarse_mloop = ctx->coarse_loops;
LoopsOfPtex loops_of_ptex;
loops_of_ptex_get(ctx, &loops_of_ptex, coarse_poly, corner);
/* Ptex face corner corresponds to a poly loop with same index. */
@@ -466,7 +478,7 @@ static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx,
{
/* Accumulate displacement. */
Subdiv *subdiv = ctx->subdiv;
- const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
+ const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
float dummy_P[3], dPdu[3], dPdv[3], D[3];
BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
@@ -520,9 +532,8 @@ static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx,
MVert *subdiv_vertex)
{
const Mesh *coarse_mesh = ctx->coarse_mesh;
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- const int coarse_vertex_index = coarse_vertex - coarse_mesh->mvert;
- const int subdiv_vertex_index = subdiv_vertex - subdiv_mesh->mvert;
+ const int coarse_vertex_index = coarse_vertex - ctx->coarse_verts;
+ const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts;
CustomData_copy_data(
&coarse_mesh->vdata, &ctx->subdiv_mesh->vdata, coarse_vertex_index, subdiv_vertex_index, 1);
}
@@ -533,7 +544,7 @@ static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx,
const float u,
const float v)
{
- const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_mesh->mvert;
+ const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts;
const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v};
CustomData_interp(vertex_interpolation->vertex_data,
&ctx->subdiv_mesh->vdata,
@@ -554,7 +565,7 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
const MVert *coarse_vert,
MVert *subdiv_vert)
{
- const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
+ const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
/* Displacement is accumulated in subdiv vertex position.
* Needs to be backed up before copying data from original vertex. */
float D[3] = {0.0f, 0.0f, 0.0f};
@@ -582,7 +593,7 @@ static void evaluate_vertex_and_apply_displacement_interpolate(
VerticesForInterpolation *vertex_interpolation,
MVert *subdiv_vert)
{
- const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
+ const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts;
/* Displacement is accumulated in subdiv vertex position.
* Needs to be backed up before copying data from original vertex. */
float D[3] = {0.0f, 0.0f, 0.0f};
@@ -609,9 +620,7 @@ static void subdiv_mesh_vertex_displacement_every_corner_or_edge(
const int subdiv_vertex_index)
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MVert *subdiv_mvert = subdiv_mesh->mvert;
- MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
+ MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert);
}
@@ -656,12 +665,8 @@ static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_contex
{
BLI_assert(coarse_vertex_index != ORIGINDEX_NONE);
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MVert *coarse_mvert = coarse_mesh->mvert;
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MVert *subdiv_mvert = subdiv_mesh->mvert;
- const MVert *coarse_vert = &coarse_mvert[coarse_vertex_index];
- MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
+ const MVert *coarse_vert = &ctx->coarse_verts[coarse_vertex_index];
+ MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
evaluate_vertex_and_apply_displacement_copy(
ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert);
}
@@ -706,12 +711,8 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MVert *subdiv_mvert = subdiv_mesh->mvert;
- MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
+ const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
+ MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
evaluate_vertex_and_apply_displacement_interpolate(
ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vert);
@@ -755,12 +756,9 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
Subdiv *subdiv = ctx->subdiv;
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
+ const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MVert *subdiv_mvert = subdiv_mesh->mvert;
- MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
+ MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co);
@@ -778,7 +776,7 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
MEdge *subdiv_edge,
const MEdge *coarse_edge)
{
- const int subdiv_edge_index = subdiv_edge - ctx->subdiv_mesh->medge;
+ const int subdiv_edge_index = subdiv_edge - ctx->subdiv_edges;
if (coarse_edge == nullptr) {
subdiv_edge->crease = 0;
subdiv_edge->bweight = 0;
@@ -791,7 +789,7 @@ static void subdiv_copy_edge_data(SubdivMeshContext *ctx,
}
return;
}
- const int coarse_edge_index = coarse_edge - ctx->coarse_mesh->medge;
+ const int coarse_edge_index = coarse_edge - ctx->coarse_edges;
CustomData_copy_data(
&ctx->coarse_mesh->edata, &ctx->subdiv_mesh->edata, coarse_edge_index, subdiv_edge_index, 1);
subdiv_edge->flag |= ME_EDGERENDER;
@@ -806,13 +804,11 @@ static void subdiv_mesh_edge(const SubdivForeachContext *foreach_context,
const int subdiv_v2)
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MEdge *subdiv_medge = subdiv_mesh->medge;
+ MEdge *subdiv_medge = ctx->subdiv_edges;
MEdge *subdiv_edge = &subdiv_medge[subdiv_edge_index];
const MEdge *coarse_edge = nullptr;
if (coarse_edge_index != ORIGINDEX_NONE) {
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_medge = coarse_mesh->medge;
+ const MEdge *coarse_medge = ctx->coarse_edges;
coarse_edge = &coarse_medge[coarse_edge_index];
}
subdiv_copy_edge_data(ctx, subdiv_edge, coarse_edge);
@@ -832,7 +828,7 @@ static void subdiv_interpolate_loop_data(const SubdivMeshContext *ctx,
const float u,
const float v)
{
- const int subdiv_loop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
+ const int subdiv_loop_index = subdiv_loop - ctx->subdiv_loops;
const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v};
CustomData_interp(loop_interpolation->loop_data,
&ctx->subdiv_mesh->ldata,
@@ -854,7 +850,7 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx,
return;
}
Subdiv *subdiv = ctx->subdiv;
- const int mloop_index = subdiv_loop - ctx->subdiv_mesh->mloop;
+ const int mloop_index = subdiv_loop - ctx->subdiv_loops;
for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) {
MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index];
BKE_subdiv_eval_face_varying(subdiv, layer_index, ptex_face_index, u, v, subdiv_loopuv->uv);
@@ -903,12 +899,9 @@ static void subdiv_mesh_loop(const SubdivForeachContext *foreach_context,
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
SubdivMeshTLS *tls = static_cast<SubdivMeshTLS *>(tls_v);
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
+ const MPoly *coarse_mpoly = ctx->coarse_polys;
const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MLoop *subdiv_mloop = subdiv_mesh->mloop;
- MLoop *subdiv_loop = &subdiv_mloop[subdiv_loop_index];
+ MLoop *subdiv_loop = &ctx->subdiv_loops[subdiv_loop_index];
subdiv_mesh_ensure_loop_interpolation(ctx, tls, coarse_poly, coarse_corner);
subdiv_interpolate_loop_data(ctx, subdiv_loop, &tls->loop_interpolation, u, v);
subdiv_eval_uv_layer(ctx, subdiv_loop, ptex_face_index, u, v);
@@ -926,8 +919,8 @@ static void subdiv_copy_poly_data(const SubdivMeshContext *ctx,
MPoly *subdiv_poly,
const MPoly *coarse_poly)
{
- const int coarse_poly_index = coarse_poly - ctx->coarse_mesh->mpoly;
- const int subdiv_poly_index = subdiv_poly - ctx->subdiv_mesh->mpoly;
+ const int coarse_poly_index = coarse_poly - ctx->coarse_polys;
+ const int subdiv_poly_index = subdiv_poly - ctx->subdiv_polys;
CustomData_copy_data(
&ctx->coarse_mesh->pdata, &ctx->subdiv_mesh->pdata, coarse_poly_index, subdiv_poly_index, 1);
}
@@ -941,12 +934,8 @@ static void subdiv_mesh_poly(const SubdivForeachContext *foreach_context,
{
BLI_assert(coarse_poly_index != ORIGINDEX_NONE);
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MPoly *coarse_mpoly = coarse_mesh->mpoly;
- const MPoly *coarse_poly = &coarse_mpoly[coarse_poly_index];
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MPoly *subdiv_mpoly = subdiv_mesh->mpoly;
- MPoly *subdiv_poly = &subdiv_mpoly[subdiv_poly_index];
+ const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index];
+ MPoly *subdiv_poly = &ctx->subdiv_polys[subdiv_poly_index];
subdiv_copy_poly_data(ctx, subdiv_poly, coarse_poly);
subdiv_poly->loopstart = start_loop_index;
subdiv_poly->totloop = num_loops;
@@ -964,12 +953,8 @@ static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context
const int subdiv_vertex_index)
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
- const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MVert *coarse_mvert = coarse_mesh->mvert;
- const MVert *coarse_vertex = &coarse_mvert[coarse_vertex_index];
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MVert *subdiv_mvert = subdiv_mesh->mvert;
- MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
+ const MVert *coarse_vertex = &ctx->coarse_verts[coarse_vertex_index];
+ MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index];
subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex);
}
@@ -980,12 +965,12 @@ static void find_edge_neighbors(const Mesh *coarse_mesh,
const MEdge *edge,
const MEdge *neighbors[2])
{
- const MEdge *coarse_medge = coarse_mesh->medge;
+ const blender::Span<MEdge> coarse_edges = coarse_mesh->edges();
neighbors[0] = nullptr;
neighbors[1] = nullptr;
int neighbor_counters[2] = {0, 0};
for (int edge_index = 0; edge_index < coarse_mesh->totedge; edge_index++) {
- const MEdge *current_edge = &coarse_medge[edge_index];
+ const MEdge *current_edge = &coarse_edges[edge_index];
if (current_edge == edge) {
continue;
}
@@ -1014,7 +999,7 @@ static void points_for_loose_edges_interpolation_get(const Mesh *coarse_mesh,
const MEdge *neighbors[2],
float points_r[4][3])
{
- const MVert *coarse_mvert = coarse_mesh->mvert;
+ const MVert *coarse_mvert = BKE_mesh_vertices(coarse_mesh);
/* Middle points corresponds to the edge. */
copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co);
copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co);
@@ -1053,7 +1038,7 @@ void BKE_subdiv_mesh_interpolate_position_on_edge(const Mesh *coarse_mesh,
float pos_r[3])
{
if (is_simple) {
- const MVert *coarse_mvert = coarse_mesh->mvert;
+ const MVert *coarse_mvert = BKE_mesh_vertices(coarse_mesh);
const MVert *vert_1 = &coarse_mvert[coarse_edge->v1];
const MVert *vert_2 = &coarse_mvert[coarse_edge->v2];
interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u);
@@ -1103,9 +1088,7 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
{
SubdivMeshContext *ctx = static_cast<SubdivMeshContext *>(foreach_context->user_data);
const Mesh *coarse_mesh = ctx->coarse_mesh;
- const MEdge *coarse_edge = &coarse_mesh->medge[coarse_edge_index];
- Mesh *subdiv_mesh = ctx->subdiv_mesh;
- MVert *subdiv_mvert = subdiv_mesh->mvert;
+ const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index];
const bool is_simple = ctx->subdiv->settings.is_simple;
/* Interpolate custom data when not an end point.
* This data has already been copied from the original vertex by #subdiv_mesh_vertex_loose. */
@@ -1113,7 +1096,7 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach
subdiv_mesh_vertex_of_loose_edge_interpolate(ctx, coarse_edge, u, subdiv_vertex_index);
}
/* Interpolate coordinate. */
- MVert *subdiv_vertex = &subdiv_mvert[subdiv_vertex_index];
+ MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index];
BKE_subdiv_mesh_interpolate_position_on_edge(
coarse_mesh, coarse_edge, is_simple, u, subdiv_vertex->co);
/* Reset flags and such. */
@@ -1179,7 +1162,13 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
/* Initialize subdivision mesh creation context. */
SubdivMeshContext subdiv_context = {0};
subdiv_context.settings = settings;
+
subdiv_context.coarse_mesh = coarse_mesh;
+ subdiv_context.coarse_verts = BKE_mesh_vertices(coarse_mesh);
+ subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh);
+ subdiv_context.coarse_polys = BKE_mesh_polygons(coarse_mesh);
+ subdiv_context.coarse_loops = BKE_mesh_loops(coarse_mesh);
+
subdiv_context.subdiv = subdiv;
subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr);
/* Multi-threaded traversal/evaluation. */
diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc
index ef75d3d2482..2005959d360 100644
--- a/source/blender/blenkernel/intern/volume_to_mesh.cc
+++ b/source/blender/blenkernel/intern/volume_to_mesh.cc
@@ -178,9 +178,9 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid,
0,
0,
0,
- {mesh->mvert, mesh->totvert},
- {mesh->mpoly, mesh->totpoly},
- {mesh->mloop, mesh->totloop});
+ mesh->vertices_for_write(),
+ mesh->polygons_for_write(),
+ mesh->loops_for_write());
BKE_mesh_calc_edges(mesh, false, false);