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/editors
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/editors')
-rw-r--r--source/blender/editors/armature/armature_skinning.c8
-rw-r--r--source/blender/editors/armature/meshlaplacian.c30
-rw-r--r--source/blender/editors/curves/intern/curves_ops.cc66
-rw-r--r--source/blender/editors/geometry/geometry_attributes.cc5
-rw-r--r--source/blender/editors/mesh/editface.cc101
-rw-r--r--source/blender/editors/mesh/editmesh_undo.c5
-rw-r--r--source/blender/editors/mesh/mesh_data.cc105
-rw-r--r--source/blender/editors/mesh/mesh_mirror.c13
-rw-r--r--source/blender/editors/mesh/meshtools.cc68
-rw-r--r--source/blender/editors/object/object_bake.c2
-rw-r--r--source/blender/editors/object/object_bake_api.c25
-rw-r--r--source/blender/editors/object/object_modifier.cc36
-rw-r--r--source/blender/editors/object/object_remesh.cc31
-rw-r--r--source/blender/editors/object/object_shapekey.c3
-rw-r--r--source/blender/editors/object/object_vgroup.cc126
-rw-r--r--source/blender/editors/physics/particle_edit.c23
-rw-r--r--source/blender/editors/physics/particle_object.c8
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_add.cc22
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_puff.cc15
-rw-r--r--source/blender/editors/sculpt_paint/curves_sculpt_slide.cc14
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c22
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c7
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.cc139
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc10
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c69
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c27
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_dyntopo.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_expand.c26
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c13
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_geodesic.c18
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c2
-rw-r--r--source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc28
-rw-r--r--source/blender/editors/space_view3d/drawobject.c25
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_select.cc21
-rw-r--r--source/blender/editors/transform/transform_snap_object.cc26
38 files changed, 622 insertions, 536 deletions
diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c
index 3a1e7419d3c..2cd4b53f7f4 100644
--- a/source/blender/editors/armature/armature_skinning.c
+++ b/source/blender/editors/armature/armature_skinning.c
@@ -21,6 +21,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_deform.h"
+#include "BKE_mesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
#include "BKE_modifier.h"
@@ -203,9 +204,9 @@ static void envelope_bone_weighting(Object *ob,
}
/* for each vertex in the mesh */
+ const MVert *mesh_verts = BKE_mesh_vertices(mesh);
for (int i = 0; i < mesh->totvert; i++) {
-
- if (use_mask && !(mesh->mvert[i].flag & SELECT)) {
+ if (use_mask && !(mesh_verts[i].flag & SELECT)) {
continue;
}
@@ -405,9 +406,10 @@ static void add_verts_to_dgroups(ReportList *reports,
}
/* transform verts to global space */
+ const MVert *mesh_verts = BKE_mesh_vertices(mesh);
for (int i = 0; i < mesh->totvert; i++) {
if (!vertsfilled) {
- copy_v3_v3(verts[i], mesh->mvert[i].co);
+ copy_v3_v3(verts[i], mesh_verts[i].co);
}
mul_m4_v3(ob->obmat, verts[i]);
}
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 7016511111e..2b3f8f4c853 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -645,14 +645,16 @@ void heat_bone_weighting(Object *ob,
{
LaplacianSystem *sys;
MLoopTri *mlooptri;
- MPoly *mp;
- MLoop *ml;
+ const MPoly *mp;
+ const MLoop *ml;
float solution, weight;
int *vertsflipped = NULL, *mask = NULL;
int a, tris_num, j, bbone, firstsegment, lastsegment;
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
- MVert *mvert = me->mvert;
+ const MVert *mesh_verts = BKE_mesh_vertices(me);
+ const MPoly *polys = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
@@ -667,16 +669,16 @@ void heat_bone_weighting(Object *ob,
/* (added selectedVerts content for vertex mask, they used to just equal 1) */
if (use_vert_sel) {
- for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
- for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
- mask[ml->v] = (mvert[ml->v].flag & SELECT) != 0;
+ for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
+ for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
+ mask[ml->v] = (mesh_verts[ml->v].flag & SELECT) != 0;
}
}
}
else if (use_face_sel) {
- for (a = 0, mp = me->mpoly; a < me->totpoly; mp++, a++) {
+ for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
if (mp->flag & ME_FACE_SEL) {
- for (j = 0, ml = me->mloop + mp->loopstart; j < mp->totloop; j++, ml++) {
+ for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
mask[ml->v] = 1;
}
}
@@ -690,10 +692,10 @@ void heat_bone_weighting(Object *ob,
sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop);
mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__);
- BKE_mesh_recalc_looptri(me->mloop, me->mpoly, me->mvert, me->totloop, me->totpoly, mlooptri);
+ BKE_mesh_recalc_looptri(loops, polys, mesh_verts, me->totloop, me->totpoly, mlooptri);
sys->heat.mlooptri = mlooptri;
- sys->heat.mloop = me->mloop;
+ sys->heat.mloop = loops;
sys->heat.verts_num = me->totvert;
sys->heat.verts = verts;
sys->heat.root = root;
@@ -1606,8 +1608,8 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
/* initialize data from 'cagedm' for reuse */
{
Mesh *me = mdb->cagemesh;
- mdb->cagemesh_cache.mpoly = me->mpoly;
- mdb->cagemesh_cache.mloop = me->mloop;
+ mdb->cagemesh_cache.mpoly = BKE_mesh_polygons(me);
+ mdb->cagemesh_cache.mloop = BKE_mesh_loops(me);
mdb->cagemesh_cache.looptri = BKE_mesh_runtime_looptri_ensure(me);
mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me);
}
@@ -1743,7 +1745,7 @@ void ED_mesh_deform_bind_callback(Object *object,
MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original(
object, &mmd->modifier);
MeshDeformBind mdb;
- MVert *mvert;
+ const MVert *mvert;
int a;
waitcursor(1);
@@ -1763,7 +1765,7 @@ void ED_mesh_deform_bind_callback(Object *object,
mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos");
copy_m4_m4(mdb.cagemat, cagemat);
- mvert = mdb.cagemesh->mvert;
+ mvert = BKE_mesh_vertices(mdb.cagemesh);
for (a = 0; a < mdb.cage_verts_num; a++) {
copy_v3_v3(mdb.cagecos[a], mvert[a].co);
}
diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index eec2c5d205d..6582ce6e6d7 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -139,7 +139,8 @@ using bke::CurvesGeometry;
namespace convert_to_particle_system {
-static int find_mface_for_root_position(const Mesh &mesh,
+static int find_mface_for_root_position(const Span<MVert> verts,
+ const MFace *mface,
const Span<int> possible_mface_indices,
const float3 &root_pos)
{
@@ -151,14 +152,14 @@ static int find_mface_for_root_position(const Mesh &mesh,
int mface_i;
float best_distance_sq = FLT_MAX;
for (const int possible_mface_i : possible_mface_indices) {
- const MFace &possible_mface = mesh.mface[possible_mface_i];
+ const MFace &possible_mface = mface[possible_mface_i];
{
float3 point_in_triangle;
closest_on_tri_to_point_v3(point_in_triangle,
root_pos,
- mesh.mvert[possible_mface.v1].co,
- mesh.mvert[possible_mface.v2].co,
- mesh.mvert[possible_mface.v3].co);
+ verts[possible_mface.v1].co,
+ verts[possible_mface.v2].co,
+ verts[possible_mface.v3].co);
const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle);
if (distance_sq < best_distance_sq) {
best_distance_sq = distance_sq;
@@ -170,9 +171,9 @@ static int find_mface_for_root_position(const Mesh &mesh,
float3 point_in_triangle;
closest_on_tri_to_point_v3(point_in_triangle,
root_pos,
- mesh.mvert[possible_mface.v1].co,
- mesh.mvert[possible_mface.v3].co,
- mesh.mvert[possible_mface.v4].co);
+ verts[possible_mface.v1].co,
+ verts[possible_mface.v3].co,
+ verts[possible_mface.v4].co);
const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle);
if (distance_sq < best_distance_sq) {
best_distance_sq = distance_sq;
@@ -186,25 +187,22 @@ static int find_mface_for_root_position(const Mesh &mesh,
/**
* \return Barycentric coordinates in the #MFace.
*/
-static float4 compute_mface_weights_for_position(const Mesh &mesh,
+static float4 compute_mface_weights_for_position(const Span<MVert> verts,
const MFace &mface,
const float3 &position)
{
float4 mface_weights;
if (mface.v4) {
float mface_verts_su[4][3];
- copy_v3_v3(mface_verts_su[0], mesh.mvert[mface.v1].co);
- copy_v3_v3(mface_verts_su[1], mesh.mvert[mface.v2].co);
- copy_v3_v3(mface_verts_su[2], mesh.mvert[mface.v3].co);
- copy_v3_v3(mface_verts_su[3], mesh.mvert[mface.v4].co);
+ copy_v3_v3(mface_verts_su[0], verts[mface.v1].co);
+ copy_v3_v3(mface_verts_su[1], verts[mface.v2].co);
+ copy_v3_v3(mface_verts_su[2], verts[mface.v3].co);
+ copy_v3_v3(mface_verts_su[3], verts[mface.v4].co);
interp_weights_poly_v3(mface_weights, mface_verts_su, 4, position);
}
else {
- interp_weights_tri_v3(mface_weights,
- mesh.mvert[mface.v1].co,
- mesh.mvert[mface.v2].co,
- mesh.mvert[mface.v3].co,
- position);
+ interp_weights_tri_v3(
+ mface_weights, verts[mface.v1].co, verts[mface.v2].co, verts[mface.v3].co, position);
mface_weights[3] = 0.0f;
}
return mface_weights;
@@ -287,6 +285,9 @@ static void try_convert_single_object(Object &curves_ob,
/* Prepare transformation matrices. */
const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob};
+ const MFace *mfaces = (const MFace *)CustomData_get_layer(&surface_me.fdata, CD_MFACE);
+ const Span<MVert> verts = surface_me.vertices();
+
for (const int new_hair_i : IndexRange(hair_num)) {
const int curve_i = new_hair_i;
const IndexRange points = curves.points_for_curve(curve_i);
@@ -305,11 +306,10 @@ static void try_convert_single_object(Object &curves_ob,
const int poly_i = looptri.poly;
const int mface_i = find_mface_for_root_position(
- surface_me, poly_to_mface_map[poly_i], root_pos_su);
- const MFace &mface = surface_me.mface[mface_i];
+ verts, mfaces, poly_to_mface_map[poly_i], root_pos_su);
+ const MFace &mface = mfaces[mface_i];
- const float4 mface_weights = compute_mface_weights_for_position(
- surface_me, mface, root_pos_su);
+ const float4 mface_weights = compute_mface_weights_for_position(verts, mface, root_pos_su);
ParticleData &particle = particles[new_hair_i];
const int num_keys = points.size();
@@ -541,8 +541,11 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
Curves &curves_id = *static_cast<Curves *>(curves_ob.data);
CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
- Mesh &surface_mesh = *static_cast<Mesh *>(surface_ob.data);
-
+ const Mesh &surface_mesh = *static_cast<const Mesh *>(surface_ob.data);
+ const Span<MVert> verts = surface_mesh.vertices();
+ const Span<MLoop> loops = surface_mesh.loops();
+ const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
+ BKE_mesh_runtime_looptri_len(&surface_mesh)};
VArraySpan<float2> surface_uv_map;
if (curves_id.surface_uv_map != nullptr) {
const bke::AttributeAccessor surface_attributes = bke::mesh_attributes(surface_mesh);
@@ -554,9 +557,6 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
MutableSpan<float3> positions_cu = curves.positions_for_write();
MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write();
- const Span<MLoopTri> surface_looptris = {BKE_mesh_runtime_looptri_ensure(&surface_mesh),
- BKE_mesh_runtime_looptri_len(&surface_mesh)};
-
const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob};
switch (attach_mode) {
@@ -603,9 +603,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
const float2 &uv0 = surface_uv_map[corner0];
const float2 &uv1 = surface_uv_map[corner1];
const float2 &uv2 = surface_uv_map[corner2];
- const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[corner0].v].co;
- const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[corner1].v].co;
- const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[corner2].v].co;
+ const float3 &p0_su = verts[loops[corner0].v].co;
+ const float3 &p1_su = verts[loops[corner1].v].co;
+ const float3 &p2_su = verts[loops[corner2].v].co;
float3 bary_coords;
interp_weights_tri_v3(bary_coords, p0_su, p1_su, p2_su, new_first_point_pos_su);
const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2);
@@ -639,9 +639,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
const MLoopTri &looptri = *lookup_result.looptri;
const float3 &bary_coords = lookup_result.bary_weights;
- const float3 &p0_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[0]].v].co;
- const float3 &p1_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[1]].v].co;
- const float3 &p2_su = surface_mesh.mvert[surface_mesh.mloop[looptri.tri[2]].v].co;
+ const float3 &p0_su = verts[loops[looptri.tri[0]].v].co;
+ const float3 &p1_su = verts[loops[looptri.tri[1]].v].co;
+ const float3 &p2_su = verts[loops[looptri.tri[2]].v].co;
float3 new_first_point_pos_su;
interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords);
diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc
index 2dcb7aa438f..eafe13f093d 100644
--- a/source/blender/editors/geometry/geometry_attributes.cc
+++ b/source/blender/editors/geometry/geometry_attributes.cc
@@ -471,11 +471,6 @@ static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- if (GS(id->name) == ID_ME) {
- Mesh *me = static_cast<Mesh *>(ob->data);
- BKE_mesh_update_customdata_pointers(me, true);
- }
-
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc
index 054c01626f8..6313c01011e 100644
--- a/source/blender/editors/mesh/editface.cc
+++ b/source/blender/editors/mesh/editface.cc
@@ -44,9 +44,7 @@ void paintface_flush_flags(bContext *C,
{
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
- MPoly *polys, *mp_orig;
const int *index_array = nullptr;
- int totpoly;
BLI_assert(flush_selection || flush_hidden);
@@ -75,11 +73,13 @@ void paintface_flush_flags(bContext *C,
Mesh *me_eval = (Mesh *)ob_eval->runtime.data_eval;
bke::MutableAttributeAccessor attributes_eval = bke::mesh_attributes_for_write(*me_eval);
bool updated = false;
+ const Span<MPoly> me_polys = me->polygons();
if (me_orig != nullptr && me_eval != nullptr && me_orig->totpoly == me->totpoly) {
/* Update the COW copy of the mesh. */
+ MutableSpan<MPoly> orig_polys = me_orig->polygons_for_write();
for (int i = 0; i < me->totpoly; i++) {
- me_orig->mpoly[i].flag = me->mpoly[i].flag;
+ orig_polys[i].flag = me_polys[i].flag;
}
if (flush_hidden) {
const VArray<bool> hide_poly_me = attributes_me.lookup_or_default<bool>(
@@ -92,15 +92,12 @@ void paintface_flush_flags(bContext *C,
/* Mesh polys => Final derived polys */
if ((index_array = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX))) {
- polys = me_eval->mpoly;
- totpoly = me_eval->totpoly;
-
+ MutableSpan<MPoly> eval_polys = me_orig->polygons_for_write();
/* loop over final derived polys */
- for (int i = 0; i < totpoly; i++) {
+ for (const int i : eval_polys.index_range()) {
if (index_array[i] != ORIGINDEX_NONE) {
/* Copy flags onto the final derived poly from the original mesh poly */
- mp_orig = me->mpoly + index_array[i];
- polys[i].flag = mp_orig->flag;
+ eval_polys[i].flag = me_polys[index_array[i]].flag;
}
}
const VArray<bool> hide_poly_orig = attributes_orig.lookup_or_default<bool>(
@@ -144,12 +141,13 @@ void paintface_hide(bContext *C, Object *ob, const bool unselected)
return;
}
+ MutableSpan<MPoly> polys = me->polygons_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
bke::SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_span<bool>(
".hide_poly", ATTR_DOMAIN_FACE);
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &me->mpoly[i];
+ MPoly *mpoly = &polys[i];
if (!hide_poly.span[i]) {
if (((mpoly->flag & ME_FACE_SEL) == 0) == unselected) {
hide_poly.span[i] = true;
@@ -176,13 +174,14 @@ void paintface_reveal(bContext *C, Object *ob, const bool select)
return;
}
+ MutableSpan<MPoly> polys = me->polygons_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
if (select) {
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &me->mpoly[i];
+ MPoly *mpoly = &polys[i];
if (hide_poly[i]) {
mpoly->flag |= ME_FACE_SEL;
}
@@ -207,25 +206,28 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
BLI_bitmap *edge_tag = BLI_BITMAP_NEW(me->totedge, __func__);
BLI_bitmap *poly_tag = BLI_BITMAP_NEW(me->totpoly, __func__);
+ const Span<MEdge> edges = me->edges();
+ MutableSpan<MPoly> polys = me->polygons_for_write();
+ const Span<MLoop> loops = me->loops();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
if (index != (uint)-1) {
/* only put face under cursor in array */
- MPoly *mp = &me->mpoly[index];
- BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
+ const MPoly *mp = &polys[index];
+ BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
BLI_BITMAP_ENABLE(poly_tag, index);
}
else {
/* fill array by selection */
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &me->mpoly[i];
+ MPoly *mp = &polys[i];
if (hide_poly[i]) {
/* pass */
}
else if (mp->flag & ME_FACE_SEL) {
- BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
+ BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
BLI_BITMAP_ENABLE(poly_tag, i);
}
}
@@ -236,7 +238,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
/* expand selection */
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &me->mpoly[i];
+ MPoly *mp = &polys[i];
if (hide_poly[i]) {
continue;
}
@@ -244,9 +246,9 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
if (!BLI_BITMAP_TEST(poly_tag, i)) {
mark = false;
- MLoop *ml = me->mloop + mp->loopstart;
+ const MLoop *ml = &loops[mp->loopstart];
for (int b = 0; b < mp->totloop; b++, ml++) {
- if ((me->medge[ml->e].flag & ME_SEAM) == 0) {
+ if ((edges[ml->e].flag & ME_SEAM) == 0) {
if (BLI_BITMAP_TEST(edge_tag, ml->e)) {
mark = true;
break;
@@ -256,7 +258,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
if (mark) {
BLI_BITMAP_ENABLE(poly_tag, i);
- BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, me->mloop + mp->loopstart);
+ BKE_mesh_poly_edgebitmap_insert(edge_tag, mp, &loops[mp->loopstart]);
do_it = true;
}
}
@@ -266,7 +268,7 @@ static void select_linked_tfaces_with_seams(Mesh *me, const uint index, const bo
MEM_freeN(edge_tag);
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &me->mpoly[i];
+ MPoly *mp = &polys[index];
if (BLI_BITMAP_TEST(poly_tag, i)) {
SET_FLAG_FROM_TEST(mp->flag, select, ME_FACE_SEL);
}
@@ -303,6 +305,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
return false;
}
+ MutableSpan<MPoly> polys = me->polygons_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
@@ -311,7 +314,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
action = SEL_SELECT;
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &me->mpoly[i];
+ MPoly *mpoly = &polys[i];
if (!hide_poly[i] && mpoly->flag & ME_FACE_SEL) {
action = SEL_DESELECT;
break;
@@ -322,7 +325,7 @@ bool paintface_deselect_all_visible(bContext *C, Object *ob, int action, bool fl
bool changed = false;
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mpoly = &me->mpoly[i];
+ MPoly *mpoly = &polys[i];
if (!hide_poly[i]) {
switch (action) {
case SEL_SELECT:
@@ -360,26 +363,28 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
float vec[3], bmat[3][3];
const Mesh *me = BKE_mesh_from_object(ob);
- if (!me || !me->mloopuv) {
+ if (!me || !CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
return ok;
}
- const MVert *mvert = me->mvert;
copy_m3_m4(bmat, ob->obmat);
+ const Span<MVert> verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
for (int i = 0; i < me->totpoly; i++) {
- MPoly *mp = &me->mpoly[i];
+ const MPoly *mp = &polys[i];
if (hide_poly[i] || !(mp->flag & ME_FACE_SEL)) {
continue;
}
- const MLoop *ml = me->mloop + mp->loopstart;
+ const MLoop *ml = &loops[mp->loopstart];
for (int b = 0; b < mp->totloop; b++, ml++) {
- mul_v3_m3v3(vec, bmat, mvert[ml->v].co);
+ mul_v3_m3v3(vec, bmat, verts[ml->v].co);
add_v3_v3v3(vec, vec, ob->obmat[3]);
minmax_v3v3_v3(r_min, r_max, vec);
}
@@ -404,13 +409,14 @@ bool paintface_mouse_select(bContext *C,
/* Get the face under the cursor */
Mesh *me = BKE_mesh_from_object(ob);
+ MutableSpan<MPoly> polys = me->polygons_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_poly = attributes.lookup_or_default<bool>(
".hide_poly", ATTR_DOMAIN_FACE, false);
if (ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
if (index < me->totpoly) {
- mpoly_sel = me->mpoly + index;
+ mpoly_sel = polys.data() + index;
if (!hide_poly[index]) {
found = true;
}
@@ -469,12 +475,10 @@ bool paintface_mouse_select(bContext *C,
void paintvert_flush_flags(Object *ob)
{
+ using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
Mesh *me_eval = BKE_object_get_evaluated_mesh(ob);
- MVert *mvert_eval, *mv;
const int *index_array = nullptr;
- int totvert;
- int i;
if (me == nullptr) {
return;
@@ -490,23 +494,21 @@ void paintvert_flush_flags(Object *ob)
index_array = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
- mvert_eval = me_eval->mvert;
- totvert = me_eval->totvert;
-
- mv = mvert_eval;
+ const Span<MVert> vertices = me->vertices_for_write();
+ MutableSpan<MVert> vertices_eval = me_eval->vertices_for_write();
if (index_array) {
int orig_index;
- for (i = 0; i < totvert; i++, mv++) {
+ for (const int i : vertices_eval.index_range()) {
orig_index = index_array[i];
if (orig_index != ORIGINDEX_NONE) {
- mv->flag = me->mvert[index_array[i]].flag;
+ vertices_eval[i].flag = vertices[index_array[i]].flag;
}
}
}
else {
- for (i = 0; i < totvert; i++, mv++) {
- mv->flag = me->mvert[i].flag;
+ for (const int i : vertices_eval.index_range()) {
+ vertices_eval[i].flag = vertices[i].flag;
}
}
@@ -527,6 +529,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
return false;
}
+ MutableSpan<MVert> verts = me->vertices_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
@@ -535,7 +538,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
action = SEL_SELECT;
for (int i = 0; i < me->totvert; i++) {
- MVert *mvert = &me->mvert[i];
+ MVert *mvert = &verts[i];
if (!hide_vert[i] && mvert->flag & SELECT) {
action = SEL_DESELECT;
break;
@@ -545,7 +548,7 @@ bool paintvert_deselect_all_visible(Object *ob, int action, bool flush_flags)
bool changed = false;
for (int i = 0; i < me->totvert; i++) {
- MVert *mvert = &me->mvert[i];
+ MVert *mvert = &verts[i];
if (!hide_vert[i]) {
switch (action) {
case SEL_SELECT:
@@ -591,8 +594,11 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
{
using namespace blender;
Mesh *me = BKE_mesh_from_object(ob);
-
- if (me == nullptr || me->dvert == nullptr) {
+ if (me == nullptr) {
+ return;
+ }
+ const Span<MDeformVert> dverts = me->deform_verts();
+ if (dverts.is_empty()) {
return;
}
@@ -600,13 +606,14 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
paintvert_deselect_all_visible(ob, SEL_DESELECT, false);
}
+ MutableSpan<MVert> verts = me->vertices_for_write();
bke::AttributeAccessor attributes = bke::mesh_attributes(*me);
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
for (int i = 0; i < me->totvert; i++) {
- MVert *mv = &me->mvert[i];
- MDeformVert *dv = &me->dvert[i];
+ MVert *mv = &verts[i];
+ const MDeformVert *dv = &dverts[i];
if (!hide_vert[i]) {
if (dv->dw == nullptr) {
/* if null weight then not grouped */
@@ -628,10 +635,10 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected)
return;
}
+ MutableSpan<MVert> verts = me->vertices_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
bke::SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_span<bool>(
".hide_vert", ATTR_DOMAIN_POINT);
- MutableSpan<MVert> verts(me->mvert, me->totvert);
for (const int i : verts.index_range()) {
MVert &vert = verts[i];
@@ -661,10 +668,10 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select)
return;
}
+ MutableSpan<MVert> verts = me->vertices_for_write();
bke::MutableAttributeAccessor attributes = bke::mesh_attributes_for_write(*me);
const VArray<bool> hide_vert = attributes.lookup_or_default<bool>(
".hide_vert", ATTR_DOMAIN_POINT, false);
- MutableSpan<MVert> verts(me->mvert, me->totvert);
for (const int i : verts.index_range()) {
MVert &vert = verts[i];
diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c
index 15e28381cb6..7bb1dc3723f 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -361,8 +361,6 @@ static void um_arraystore_compact_ex(UndoMesh *um, const UndoMesh *um_ref, bool
if (create) {
um_arraystore.users += 1;
}
-
- BKE_mesh_update_customdata_pointers(me, false);
}
/**
@@ -465,9 +463,6 @@ static void um_arraystore_expand(UndoMesh *um)
BLI_assert(me->totselect == (state_len / stride));
UNUSED_VARS_NDEBUG(stride);
}
-
- /* not essential, but prevents accidental dangling pointer access */
- BKE_mesh_update_customdata_pointers(me, false);
}
static void um_arraystore_free(UndoMesh *um)
diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc
index 1511da810cb..09673b3d7ad 100644
--- a/source/blender/editors/mesh/mesh_data.cc
+++ b/source/blender/editors/mesh/mesh_data.cc
@@ -18,6 +18,7 @@
#include "BLI_utildefines.h"
#include "BKE_attribute.h"
+#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
@@ -44,6 +45,8 @@
#include "mesh_intern.h" /* own include */
using blender::Array;
+using blender::MutableSpan;
+using blender::Span;
static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot)
{
@@ -128,7 +131,6 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer)
}
else {
CustomData_free_layer(data, type, tot, layer_index + n);
- BKE_mesh_update_customdata_pointers(me, true);
}
}
@@ -186,7 +188,7 @@ static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset)
mesh_uv_reset_array(fuv.data(), f->len);
}
-static void mesh_uv_reset_mface(MPoly *mp, MLoopUV *mloopuv)
+static void mesh_uv_reset_mface(const MPoly *mp, MLoopUV *mloopuv)
{
Array<float *, BM_DEFAULT_NGON_STACK_SIZE> fuv(mp->totloop);
@@ -223,8 +225,9 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum)
BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV));
MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, layernum);
+ const MPoly *polys = BKE_mesh_polygons(me);
for (int i = 0; i < me->totpoly; i++) {
- mesh_uv_reset_mface(&me->mpoly[i], mloopuv);
+ mesh_uv_reset_mface(&polys[i], mloopuv);
}
}
@@ -280,9 +283,13 @@ int ED_mesh_uv_add(
return -1;
}
- if (me->mloopuv && do_init) {
- CustomData_add_layer_named(
- &me->ldata, CD_MLOOPUV, CD_DUPLICATE, me->mloopuv, me->totloop, name);
+ if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) && do_init) {
+ CustomData_add_layer_named(&me->ldata,
+ CD_MLOOPUV,
+ CD_DUPLICATE,
+ CustomData_get_layer(&me->ldata, CD_MLOOPUV),
+ me->totloop,
+ name);
is_init = true;
}
else {
@@ -293,8 +300,6 @@ int ED_mesh_uv_add(
if (active_set || layernum_dst == 0) {
CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst);
}
-
- BKE_mesh_update_customdata_pointers(me, true);
}
/* don't overwrite our copied coords */
@@ -399,9 +404,13 @@ int ED_mesh_color_add(Mesh *me,
else {
layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR);
- if (me->mloopcol && do_init) {
- CustomData_add_layer_named(
- &me->ldata, CD_PROP_BYTE_COLOR, CD_DUPLICATE, me->mloopcol, me->totloop, name);
+ if (CustomData_get_active_layer(&me->ldata, CD_PROP_BYTE_COLOR) != -1 && do_init) {
+ CustomData_add_layer_named(&me->ldata,
+ CD_PROP_BYTE_COLOR,
+ CD_DUPLICATE,
+ CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR),
+ me->totloop,
+ name);
}
else {
CustomData_add_layer_named(
@@ -412,7 +421,7 @@ int ED_mesh_color_add(Mesh *me,
CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, layernum);
}
- BKE_mesh_update_customdata_pointers(me, true);
+ BKE_mesh_tessface_clear(me);
}
DEG_id_tag_update(&me->id, 0);
@@ -432,7 +441,7 @@ bool ED_mesh_color_ensure(Mesh *me, const char *name)
layer = me->ldata.layers + CustomData_get_layer_index(&me->ldata, CD_PROP_BYTE_COLOR);
BKE_id_attributes_active_color_set(&me->id, layer);
- BKE_mesh_update_customdata_pointers(me, true);
+ BKE_mesh_tessface_clear(me);
}
DEG_id_tag_update(&me->id, 0);
@@ -496,7 +505,7 @@ int ED_mesh_sculpt_color_add(Mesh *me,
CustomData_set_layer_active(&me->vdata, CD_PROP_COLOR, layernum);
}
- BKE_mesh_update_customdata_pointers(me, true);
+ BKE_mesh_tessface_clear(me);
}
DEG_id_tag_update(&me->id, 0);
@@ -767,15 +776,20 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator
/* Tag edges as sharp according to smooth threshold if needed,
* to preserve autosmooth shading. */
if (me->flag & ME_AUTOSMOOTH) {
- BKE_edges_sharp_from_angle_set(me->mvert,
- me->totvert,
- me->medge,
- me->totedge,
- me->mloop,
- me->totloop,
- me->mpoly,
+ const Span<MVert> verts = me->vertices();
+ MutableSpan<MEdge> edges = me->edges_for_write();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
+
+ BKE_edges_sharp_from_angle_set(verts.data(),
+ verts.size(),
+ edges.data(),
+ edges.size(),
+ loops.data(),
+ loops.size(),
+ polys.data(),
BKE_mesh_poly_normals_ensure(me),
- me->totpoly,
+ polys.size(),
me->smoothresh);
}
@@ -873,27 +887,22 @@ static void mesh_add_verts(Mesh *mesh, int len)
CustomData_free(&mesh->vdata, mesh->totvert);
mesh->vdata = vdata;
- BKE_mesh_update_customdata_pointers(mesh, false);
BKE_mesh_runtime_clear_cache(mesh);
- /* scan the input list and insert the new vertices */
+ const int old_vertex_num = mesh->totvert;
+ mesh->totvert = totvert;
- /* set default flags */
- MVert *mvert = &mesh->mvert[mesh->totvert];
- for (int i = 0; i < len; i++, mvert++) {
- mvert->flag |= SELECT;
+ MutableSpan<MVert> verts = mesh->vertices_for_write();
+ for (MVert &vert : verts.drop_front(old_vertex_num)) {
+ vert.flag = SELECT;
}
-
- /* set final vertex list size */
- mesh->totvert = totvert;
}
static void mesh_add_edges(Mesh *mesh, int len)
{
CustomData edata;
- MEdge *medge;
- int i, totedge;
+ int totedge;
if (len == 0) {
return;
@@ -911,17 +920,16 @@ static void mesh_add_edges(Mesh *mesh, int len)
CustomData_free(&mesh->edata, mesh->totedge);
mesh->edata = edata;
- BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */
BKE_mesh_runtime_clear_cache(mesh);
- /* set default flags */
- medge = &mesh->medge[mesh->totedge];
- for (i = 0; i < len; i++, medge++) {
- medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
- }
-
+ const int old_edges_num = mesh->totedge;
mesh->totedge = totedge;
+
+ MutableSpan<MEdge> edges = mesh->edges_for_write();
+ for (MEdge &edge : edges.drop_front(old_edges_num)) {
+ edge.flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
+ }
}
static void mesh_add_loops(Mesh *mesh, int len)
@@ -947,7 +955,6 @@ static void mesh_add_loops(Mesh *mesh, int len)
CustomData_free(&mesh->ldata, mesh->totloop);
mesh->ldata = ldata;
- BKE_mesh_update_customdata_pointers(mesh, true);
mesh->totloop = totloop;
}
@@ -955,8 +962,7 @@ static void mesh_add_loops(Mesh *mesh, int len)
static void mesh_add_polys(Mesh *mesh, int len)
{
CustomData pdata;
- MPoly *mpoly;
- int i, totpoly;
+ int totpoly;
if (len == 0) {
return;
@@ -974,17 +980,16 @@ static void mesh_add_polys(Mesh *mesh, int len)
CustomData_free(&mesh->pdata, mesh->totpoly);
mesh->pdata = pdata;
- BKE_mesh_update_customdata_pointers(mesh, true);
BKE_mesh_runtime_clear_cache(mesh);
- /* set default flags */
- mpoly = &mesh->mpoly[mesh->totpoly];
- for (i = 0; i < len; i++, mpoly++) {
- mpoly->flag = ME_FACE_SEL;
- }
-
+ const int old_polys_num = mesh->totpoly;
mesh->totpoly = totpoly;
+
+ MutableSpan<MPoly> polys = mesh->polygons_for_write();
+ for (MPoly &poly : polys.drop_front(old_polys_num)) {
+ poly.flag = ME_FACE_SEL;
+ }
}
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c
index 82e77a88a57..905eb5d43e1 100644
--- a/source/blender/editors/mesh/mesh_mirror.c
+++ b/source/blender/editors/mesh/mesh_mirror.c
@@ -55,11 +55,9 @@ void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *me_eva
}
}
else {
- MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
- int i;
-
- for (i = 0; i < totvert; i++, mvert++) {
- BLI_kdtree_3d_insert(MirrKdStore.tree, i, mvert->co);
+ const MVert *verts = BKE_mesh_vertices(me_eval ? me_eval : me);
+ for (int i = 0; i < totvert; i++) {
+ BLI_kdtree_3d_insert(MirrKdStore.tree, i, verts[i].co);
}
}
@@ -164,7 +162,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
BLI_assert(me == NULL);
}
const bool is_editmode = (em != NULL);
- MEdge *medge = NULL, *med;
+ const MEdge *medge = NULL, *med;
/* Edit-mode variables. */
BMEdge *eed;
@@ -210,8 +208,7 @@ void ED_mesh_mirrtopo_init(BMEditMesh *em,
}
else {
totedge = me->totedge;
- medge = me->medge;
-
+ medge = BKE_mesh_edges(me);
for (a = 0, med = medge; a < totedge; a++, med++) {
const uint i1 = med->v1, i2 = med->v2;
topo_hash[i1]++;
diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc
index 330560be026..88c204b56e9 100644
--- a/source/blender/editors/mesh/meshtools.cc
+++ b/source/blender/editors/mesh/meshtools.cc
@@ -55,6 +55,9 @@
#include "WM_api.h"
#include "WM_types.h"
+using blender::MutableSpan;
+using blender::Span;
+
/* * ********************** no editmode!!! *********** */
/*********************** JOIN ***************************/
@@ -691,9 +694,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me->ldata = ldata;
me->pdata = pdata;
- /* tessface data removed above, no need to update */
- BKE_mesh_update_customdata_pointers(me, false);
-
/* Tag normals dirty because vertex positions could be changed from the original. */
BKE_mesh_normals_tag_dirty(me);
@@ -906,13 +906,13 @@ static bool ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval)
static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *me_eval, int index)
{
Mesh *me = static_cast<Mesh *>(ob->data);
- MVert *mvert = me_eval ? me_eval->mvert : me->mvert;
+ const Span<MVert> verts = me_eval ? me_eval->vertices() : me->vertices();
+
float vec[3];
- mvert = &mvert[index];
- vec[0] = -mvert->co[0];
- vec[1] = mvert->co[1];
- vec[2] = mvert->co[2];
+ vec[0] = -verts[index].co[0];
+ vec[1] = verts[index].co[1];
+ vec[2] = verts[index].co[2];
return ED_mesh_mirror_spatial_table_lookup(ob, nullptr, me_eval, vec);
}
@@ -1128,8 +1128,8 @@ static bool mirror_facecmp(const void *a, const void *b)
int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
{
Mesh *me = static_cast<Mesh *>(ob->data);
- MVert *mv, *mvert;
- MFace mirrormf, *mf, *hashmf, *mface;
+ const MVert *mv;
+ MFace mirrormf, *mf, *hashmf;
GHash *fhash;
int *mirrorverts, *mirrorfaces;
@@ -1143,12 +1143,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval)
mirrorverts = static_cast<int *>(MEM_callocN(sizeof(int) * totvert, "MirrorVerts"));
mirrorfaces = static_cast<int *>(MEM_callocN(sizeof(int[2]) * totface, "MirrorFaces"));
- mvert = me_eval ? me_eval->mvert : me->mvert;
- mface = me_eval ? me_eval->mface : me->mface;
+ const Span<MVert> verts = me_eval ? me_eval->vertices() : me->vertices();
+ MFace *mface = (MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, CD_MFACE);
ED_mesh_mirror_spatial_table_begin(ob, em, me_eval);
- for (a = 0, mv = mvert; a < totvert; a++, mv++) {
+ for (a = 0, mv = verts.data(); a < totvert; a++, mv++) {
mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology);
}
@@ -1275,42 +1275,28 @@ bool ED_mesh_pick_face_vert(
const float mval_f[2] = {(float)mval[0], (float)mval[1]};
float len_best = FLT_MAX;
- MPoly *me_eval_mpoly;
- MLoop *me_eval_mloop;
- MVert *me_eval_mvert;
- uint me_eval_mpoly_len;
-
- me_eval_mpoly = me_eval->mpoly;
- me_eval_mloop = me_eval->mloop;
- me_eval_mvert = me_eval->mvert;
-
- me_eval_mpoly_len = me_eval->totpoly;
+ const Span<MVert> verts = me_eval->vertices();
+ const Span<MPoly> polys = me_eval->polygons();
+ const Span<MLoop> loops = me_eval->loops();
const int *index_mp_to_orig = (const int *)CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
/* tag all verts using this face */
if (index_mp_to_orig) {
- uint i;
-
- for (i = 0; i < me_eval_mpoly_len; i++) {
+ for (const int i : polys.index_range()) {
if (index_mp_to_orig[i] == poly_index) {
- ed_mesh_pick_face_vert__mpoly_find(region,
- mval_f,
- &me_eval_mpoly[i],
- me_eval_mvert,
- me_eval_mloop,
- &len_best,
- &v_idx_best);
+ ed_mesh_pick_face_vert__mpoly_find(
+ region, mval_f, &polys[i], verts.data(), loops.data(), &len_best, &v_idx_best);
}
}
}
else {
- if (poly_index < me_eval_mpoly_len) {
+ if (poly_index < polys.size()) {
ed_mesh_pick_face_vert__mpoly_find(region,
mval_f,
- &me_eval_mpoly[poly_index],
- me_eval_mvert,
- me_eval_mloop,
+ &polys[poly_index],
+ verts.data(),
+ loops.data(),
&len_best,
&v_idx_best);
}
@@ -1425,7 +1411,8 @@ bool ED_mesh_pick_vert(
}
/* setup data */
- data.mvert = me->mvert;
+ const Span<MVert> verts = me->vertices();
+ data.mvert = verts.data();
data.region = region;
data.mval_f = mval_f;
data.len_best = FLT_MAX;
@@ -1479,10 +1466,11 @@ MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index)
if (r_index) {
*r_index = index;
}
- if (index == -1 || me->dvert == nullptr) {
+ if (index == -1 || me->deform_verts().is_empty()) {
return nullptr;
}
- return me->dvert + index;
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
+ return &dverts[index];
}
MDeformVert *ED_mesh_active_dvert_get_only(Object *ob)
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 3170ce2c620..8d505bbca3e 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -155,7 +155,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op)
break;
}
- if (!me->mloopuv) {
+ if (!CustomData_has_layer(&me->ldata, CD_MLOOPUV)) {
BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
ok = false;
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 708f1d02656..2e07214a5b3 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -971,7 +971,8 @@ static bool bake_targets_init_vertex_colors(Main *bmain,
return true;
}
-static int find_original_loop(const Mesh *me_orig,
+static int find_original_loop(const MPoly *orig_polys,
+ const MLoop *orig_loops,
const int *vert_origindex,
const int *poly_origindex,
const int poly_eval,
@@ -987,8 +988,8 @@ static int find_original_loop(const Mesh *me_orig,
}
/* Find matching loop with original vertex in original polygon. */
- MPoly *mpoly_orig = me_orig->mpoly + poly_orig;
- MLoop *mloop_orig = me_orig->mloop + mpoly_orig->loopstart;
+ const MPoly *mpoly_orig = orig_polys + poly_orig;
+ const MLoop *mloop_orig = orig_loops + mpoly_orig->loopstart;
for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) {
if (mloop_orig->v == vert_orig) {
return mpoly_orig->loopstart + j;
@@ -1025,23 +1026,31 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets,
const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop);
MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
- BKE_mesh_recalc_looptri(
- me_eval->mloop, me_eval->mpoly, me_eval->mvert, me_eval->totloop, me_eval->totpoly, looptri);
+ const MLoop *loops = BKE_mesh_loops(me_eval);
+ BKE_mesh_recalc_looptri(loops,
+ BKE_mesh_polygons(me_eval),
+ BKE_mesh_vertices(me_eval),
+ me_eval->totloop,
+ me_eval->totpoly,
+ looptri);
/* For mapping back to original mesh in case there are modifiers. */
const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
+ const MPoly *orig_polys = BKE_mesh_polygons(me);
+ const MLoop *orig_loops = BKE_mesh_loops(me);
for (int i = 0; i < tottri; i++) {
const MLoopTri *lt = &looptri[i];
for (int j = 0; j < 3; j++) {
unsigned int l = lt->tri[j];
- unsigned int v = me_eval->mloop[l].v;
+ unsigned int v = loops[l].v;
/* Map back to original loop if there are modifiers. */
if (vert_origindex != NULL && poly_origindex != NULL) {
- l = find_original_loop(me, vert_origindex, poly_origindex, lt->poly, v);
+ l = find_original_loop(
+ orig_polys, orig_loops, vert_origindex, poly_origindex, lt->poly, v);
if (l == ORIGINDEX_NONE || l >= me->totloop) {
continue;
}
@@ -1135,7 +1144,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex");
memset(mcol, 0, sizeof(MPropCol) * me->totvert);
- MLoop *mloop = me->mloop;
+ const MLoop *mloop = BKE_mesh_loops(me);
for (int i = 0; i < totloop; i++, mloop++) {
const int v = mloop->v;
bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num);
diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc
index 58ddde75844..5e642a00727 100644
--- a/source/blender/editors/object/object_modifier.cc
+++ b/source/blender/editors/object/object_modifier.cc
@@ -94,6 +94,8 @@
#include "object_intern.h"
+using blender::Span;
+
static void modifier_skin_customdata_delete(struct Object *ob);
/* ------------------------------------------------------------------- */
@@ -587,14 +589,14 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList *UNUSED(reports),
me->totvert = verts_num;
me->totedge = edges_num;
- me->mvert = (MVert *)CustomData_add_layer(
- &me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num);
- me->medge = (MEdge *)CustomData_add_layer(
- &me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num);
- me->mface = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0);
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num);
+ CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0);
- MVert *mvert = me->mvert;
- MEdge *medge = me->medge;
+ blender::MutableSpan<MVert> verts = me->vertices_for_write();
+ blender::MutableSpan<MEdge> edges = me->edges_for_write();
+ MVert *mvert = verts.data();
+ MEdge *medge = edges.data();
/* copy coordinates */
cache = psys_eval->pathcache;
@@ -2591,8 +2593,8 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot)
}
static void skin_armature_bone_create(Object *skin_ob,
- MVert *mvert,
- MEdge *medge,
+ const MVert *mvert,
+ const MEdge *medge,
bArmature *arm,
BLI_bitmap *edges_visited,
const MeshElemMap *emap,
@@ -2637,12 +2639,15 @@ static void skin_armature_bone_create(Object *skin_ob,
static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob)
{
Mesh *me = static_cast<Mesh *>(skin_ob->data);
+ const Span<MVert> me_verts = me->vertices();
+ const Span<MEdge> me_edges = me->edges();
Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
Object *ob_eval = DEG_get_evaluated_object(depsgraph, skin_ob);
- Mesh *me_eval_deform = mesh_get_eval_deform(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
- MVert *mvert = me_eval_deform->mvert;
+ const Mesh *me_eval_deform = mesh_get_eval_deform(
+ depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH);
+ const Span<MVert> verts_eval = me_eval_deform->vertices();
/* add vertex weights to original mesh */
CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, me->totvert);
@@ -2660,7 +2665,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
CustomData_get_layer(&me->vdata, CD_MVERT_SKIN));
int *emap_mem;
MeshElemMap *emap;
- BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
+ BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me_edges.data(), me->totvert, me->totedge);
BLI_bitmap *edges_visited = BLI_BITMAP_NEW(me->totedge, "edge_visited");
@@ -2676,15 +2681,16 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain,
if (emap[v].count > 1) {
bone = ED_armature_ebone_add(arm, "Bone");
- copy_v3_v3(bone->head, me->mvert[v].co);
- copy_v3_v3(bone->tail, me->mvert[v].co);
+ copy_v3_v3(bone->head, me_verts[v].co);
+ copy_v3_v3(bone->tail, me_verts[v].co);
bone->head[1] = 1.0f;
bone->rad_head = bone->rad_tail = 0.25;
}
if (emap[v].count >= 1) {
- skin_armature_bone_create(skin_ob, mvert, me->medge, arm, edges_visited, emap, bone, v);
+ skin_armature_bone_create(
+ skin_ob, verts_eval.data(), me_edges.data(), arm, edges_visited, emap, bone, v);
}
}
}
diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc
index 812d9bbbc08..56cccd984b6 100644
--- a/source/blender/editors/object/object_remesh.cc
+++ b/source/blender/editors/object/object_remesh.cc
@@ -73,6 +73,9 @@
#include "object_intern.h" /* own include */
+using blender::IndexRange;
+using blender::Span;
+
/* TODO(sebpa): unstable, can lead to unrecoverable errors. */
// #define USE_MESH_CURVATURE
@@ -128,7 +131,8 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
}
/* Output mesh will be all smooth or all flat shading. */
- const bool smooth_normals = mesh->mpoly[0].flag & ME_SMOOTH;
+ const Span<MPoly> polygons = mesh->polygons();
+ const bool smooth_normals = polygons.first().flag & ME_SMOOTH;
float isovalue = 0.0f;
if (mesh->flag & ME_REMESH_REPROJECT_VOLUME) {
@@ -678,9 +682,11 @@ static bool mesh_is_manifold_consistent(Mesh *mesh)
* check that the direction of the faces are consistent and doesn't suddenly
* flip
*/
+ const Span<MVert> verts = mesh->vertices();
+ const Span<MEdge> edges = mesh->edges();
+ const Span<MLoop> loops = mesh->loops();
bool is_manifold_consistent = true;
- const MLoop *mloop = mesh->mloop;
char *edge_faces = (char *)MEM_callocN(mesh->totedge * sizeof(char), "remesh_manifold_check");
int *edge_vert = (int *)MEM_malloc_arrayN(
mesh->totedge, sizeof(uint), "remesh_consistent_check");
@@ -689,18 +695,17 @@ static bool mesh_is_manifold_consistent(Mesh *mesh)
edge_vert[i] = -1;
}
- for (uint loop_idx = 0; loop_idx < mesh->totloop; loop_idx++) {
- const MLoop *loop = &mloop[loop_idx];
- edge_faces[loop->e] += 1;
- if (edge_faces[loop->e] > 2) {
+ for (const MLoop &loop : loops) {
+ edge_faces[loop.e] += 1;
+ if (edge_faces[loop.e] > 2) {
is_manifold_consistent = false;
break;
}
- if (edge_vert[loop->e] == -1) {
- edge_vert[loop->e] = loop->v;
+ if (edge_vert[loop.e] == -1) {
+ edge_vert[loop.e] = loop.v;
}
- else if (edge_vert[loop->e] == loop->v) {
+ else if (edge_vert[loop.e] == loop.v) {
/* Mesh has flips in the surface so it is non consistent */
is_manifold_consistent = false;
break;
@@ -708,16 +713,16 @@ static bool mesh_is_manifold_consistent(Mesh *mesh)
}
if (is_manifold_consistent) {
- for (uint i = 0; i < mesh->totedge; i++) {
+ for (const int i : edges.index_range()) {
/* Check for wire edges. */
if (edge_faces[i] == 0) {
is_manifold_consistent = false;
break;
}
/* Check for zero length edges */
- MVert *v1 = &mesh->mvert[mesh->medge[i].v1];
- MVert *v2 = &mesh->mvert[mesh->medge[i].v2];
- if (compare_v3v3(v1->co, v2->co, 1e-4f)) {
+ const MVert &v1 = verts[edges[i].v1];
+ const MVert &v2 = verts[edges[i].v2];
+ if (compare_v3v3(v1.co, v2.co, 1e-4f)) {
is_manifold_consistent = false;
break;
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 0e3945bff15..0328f6a6230 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -114,14 +114,13 @@ static bool object_shape_key_mirror(
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
- MVert *mv;
int i1, i2;
float *fp1, *fp2;
float tvec[3];
ED_mesh_mirror_spatial_table_begin(ob, NULL, NULL);
- for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) {
+ for (i1 = 0; i1 < me->totvert; i1++) {
i2 = mesh_get_x_mirror_vert(ob, NULL, i1, use_topology);
if (i2 == i1) {
fp1 = ((float *)kb->data) + i1 * 3;
diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc
index 7727dbeadfd..310d73daa76 100644
--- a/source/blender/editors/object/object_vgroup.cc
+++ b/source/blender/editors/object/object_vgroup.cc
@@ -67,6 +67,9 @@
#include "object_intern.h"
+using blender::MutableSpan;
+using blender::Span;
+
static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob);
/* -------------------------------------------------------------------- */
@@ -196,9 +199,9 @@ bool ED_vgroup_parray_alloc(ID *id,
return true;
}
- if (me->dvert) {
- MVert *mvert = me->mvert;
- MDeformVert *dvert = me->dvert;
+ if (!me->deform_verts().is_empty()) {
+ const Span<MVert> verts = me->vertices();
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
*dvert_tot = me->totvert;
*dvert_arr = static_cast<MDeformVert **>(
@@ -206,12 +209,12 @@ bool ED_vgroup_parray_alloc(ID *id,
if (use_vert_sel) {
for (int i = 0; i < me->totvert; i++) {
- (*dvert_arr)[i] = (mvert[i].flag & SELECT) ? &dvert[i] : nullptr;
+ (*dvert_arr)[i] = (verts[i].flag & SELECT) ? &dverts[i] : nullptr;
}
}
else {
for (int i = 0; i < me->totvert; i++) {
- (*dvert_arr)[i] = me->dvert + i;
+ (*dvert_arr)[i] = &dverts[i];
}
}
@@ -548,9 +551,10 @@ static void ED_mesh_defvert_mirror_update_ob(Object *ob, int def_nr, int vidx)
vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology);
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
if ((vidx_mirr) >= 0 && (vidx_mirr != vidx)) {
- MDeformVert *dvert_src = &me->dvert[vidx];
- MDeformVert *dvert_dst = &me->dvert[vidx_mirr];
+ MDeformVert *dvert_src = &dverts[vidx];
+ MDeformVert *dvert_dst = &dverts[vidx_mirr];
mesh_defvert_mirror_update_internal(ob, dvert_dst, dvert_src, def_nr);
}
}
@@ -659,15 +663,15 @@ static void vgroup_copy_active_to_sel(Object *ob, eVGroupSelect subset_type)
}
}
else {
- MDeformVert *dv;
+ const Span<MVert> verts = me->vertices();
int v_act;
dvert_act = ED_mesh_active_dvert_get_ob(ob, &v_act);
if (dvert_act) {
- dv = me->dvert;
- for (i = 0; i < me->totvert; i++, dv++) {
- if ((me->mvert[i].flag & SELECT) && dv != dvert_act) {
- BKE_defvert_copy_subset(dv, dvert_act, vgroup_validmap, vgroup_tot);
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
+ for (i = 0; i < me->totvert; i++) {
+ if ((verts[i].flag & SELECT) && &dverts[i] != dvert_act) {
+ BKE_defvert_copy_subset(&dverts[i], dvert_act, vgroup_validmap, vgroup_tot);
if (me->symmetry & ME_SYMMETRY_X) {
ED_mesh_defvert_mirror_update_ob(ob, -1, i);
}
@@ -927,7 +931,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
{
- MDeformVert *dv = nullptr;
+ const MDeformVert *dv = nullptr;
/* get the deform vertices corresponding to the vertnum */
if (ob->type == OB_MESH) {
@@ -942,18 +946,19 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
BMVert *eve;
BM_mesh_elem_table_ensure(em->bm, BM_VERT);
eve = BM_vert_at_index(em->bm, vertnum);
- dv = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
+ dv = static_cast<const MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
}
else {
return 0.0f;
}
}
else {
- if (me->dvert) {
+ const Span<MDeformVert> dverts = me->deform_verts();
+ if (!dverts.is_empty()) {
if (vertnum >= me->totvert) {
return 0.0f;
}
- dv = &me->dvert[vertnum];
+ dv = &dverts[vertnum];
}
}
}
@@ -1044,19 +1049,18 @@ static void vgroup_select_verts(Object *ob, int select)
}
}
else {
- if (me->dvert) {
+ const Span<MDeformVert> dverts = me->deform_verts();
+ if (!dverts.is_empty()) {
const bool *hide_vert = (const bool *)CustomData_get_layer_named(
&me->vdata, CD_PROP_BOOL, ".hide_vert");
MVert *mv;
- MDeformVert *dv;
int i;
- mv = me->mvert;
- dv = me->dvert;
+ mv = me->vertices_for_write().data();
- for (i = 0; i < me->totvert; i++, mv++, dv++) {
+ for (i = 0; i < me->totvert; i++, mv++) {
if (hide_vert != nullptr && !hide_vert[i]) {
- if (BKE_defvert_find_index(dv, def_nr)) {
+ if (BKE_defvert_find_index(&dverts[i], def_nr)) {
if (select) {
mv->flag |= SELECT;
}
@@ -1214,7 +1218,8 @@ static bool vgroup_normalize(Object *ob)
* count is an int passed by reference so it can be assigned the value of the length here. */
static blender::Vector<int> getSurroundingVerts(Mesh *me, int vert)
{
- MPoly *mp = me->mpoly;
+ const MPoly *mp = me->polygons().data();
+ const MLoop *loops = me->loops().data();
int i = me->totpoly;
blender::Vector<int> verts;
@@ -1222,7 +1227,7 @@ static blender::Vector<int> getSurroundingVerts(Mesh *me, int vert)
while (i--) {
int j = mp->totloop;
int first_l = mp->totloop - 1;
- MLoop *ml = &me->mloop[mp->loopstart];
+ const MLoop *ml = &loops[mp->loopstart];
while (j--) {
/* XXX This assume a vert can only be once in a poly, even though
* it seems logical to me, not totally sure of that. */
@@ -1236,7 +1241,7 @@ static blender::Vector<int> getSurroundingVerts(Mesh *me, int vert)
else if (!j) {
/* We are on the last corner. */
a = (ml - 1)->v;
- b = me->mloop[mp->loopstart].v;
+ b = loops[mp->loopstart].v;
}
else {
a = (ml - 1)->v;
@@ -1348,8 +1353,8 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph,
Mesh *me_deform;
MDeformWeight *dw, *dw_eval;
MVert m;
- MDeformVert *dvert = me->dvert + index;
- MDeformVert *dvert_eval = mesh_eval->dvert + index;
+ MDeformVert *dvert = me->deform_verts_for_write().data() + index;
+ MDeformVert *dvert_eval = mesh_eval->deform_verts_for_write().data() + index;
int totweight = dvert->totweight;
float oldw = 0;
float oldPos[3] = {0};
@@ -1372,7 +1377,8 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph,
do {
wasChange = false;
me_deform = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
- m = me_deform->mvert[index];
+ const Span<MVert> verts = me_deform->vertices();
+ m = verts[index];
copy_v3_v3(oldPos, m.co);
distToStart = dot_v3v3(norm, oldPos) + d;
@@ -1414,7 +1420,7 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph,
}
dw_eval->weight = dw->weight;
me_deform = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
- m = me_deform->mvert[index];
+ m = verts[index];
getVerticalAndHorizontalChange(
norm, d, coord, oldPos, distToStart, m.co, changes, dists, i);
dw->weight = oldw;
@@ -1519,7 +1525,7 @@ static void vgroup_fix(
int i;
Mesh *me = static_cast<Mesh *>(ob->data);
- MVert *mvert = me->mvert;
+ MVert *mvert = me->vertices_for_write().data();
if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL)) {
return;
}
@@ -1534,9 +1540,10 @@ static void vgroup_fix(
Mesh *me_deform = mesh_get_eval_deform(
depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH);
+ const Span<MVert> verts_deform = me_deform->vertices();
k = count;
while (k--) {
- p[k] = me_deform->mvert[verts[k]];
+ p[k] = verts_deform[verts[k]];
}
if (count >= 3) {
@@ -1544,7 +1551,7 @@ static void vgroup_fix(
float coord[3];
float norm[3];
getSingleCoordinate(p, count, coord);
- m = me_deform->mvert[i];
+ m = verts_deform[i];
sub_v3_v3v3(norm, m.co, coord);
mag = normalize_v3(norm);
if (mag) { /* zeros fix */
@@ -1929,7 +1936,7 @@ static void vgroup_smooth_subset(Object *ob,
emap_mem = nullptr;
}
else {
- BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
+ BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->edges().data(), me->totvert, me->totedge);
}
weight_accum_prev = static_cast<float *>(
@@ -1968,11 +1975,13 @@ static void vgroup_smooth_subset(Object *ob,
}
}
else {
+ const Span<MVert> verts = me->vertices();
+ const blender::Span<MEdge> edges = me->edges();
for (int i = 0; i < dvert_tot; i++) {
- const MVert *v = &me->mvert[i];
+ const MVert *v = &verts[i];
if (IS_ME_VERT_WRITE(v)) {
for (int j = 0; j < emap[i].count; j++) {
- const MEdge *e = &me->medge[emap[i].indices[j]];
+ const MEdge *e = &edges[emap[i].indices[j]];
const int i_other = (e->v1 == i) ? e->v2 : e->v1;
if (IS_ME_VERT_READ(i_other)) {
STACK_PUSH(verts_used, i);
@@ -2041,12 +2050,13 @@ static void vgroup_smooth_subset(Object *ob,
}
else {
int j;
+ const blender::Span<MEdge> edges = me->edges();
/* checked already */
- BLI_assert(IS_ME_VERT_WRITE(&me->mvert[i]));
+ BLI_assert(IS_ME_VERT_WRITE(&me->vertices()[i]));
for (j = 0; j < emap[i].count; j++) {
- MEdge *e = &me->medge[emap[i].indices[j]];
+ const MEdge *e = &edges[emap[i].indices[j]];
const int i_other = (e->v1 == i ? e->v2 : e->v1);
if (IS_ME_VERT_READ(i_other)) {
WEIGHT_ACCUMULATE;
@@ -2366,7 +2376,7 @@ void ED_vgroup_mirror(Object *ob,
def_nr)
BMVert *eve, *eve_mirr;
- MDeformVert *dvert, *dvert_mirr;
+ MDeformVert *dvert_mirr;
char sel, sel_mirr;
int *flip_map = nullptr, flip_map_len;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
@@ -2424,7 +2434,8 @@ void ED_vgroup_mirror(Object *ob,
sel_mirr = BM_elem_flag_test(eve_mirr, BM_ELEM_SELECT);
if ((sel || sel_mirr) && (eve != eve_mirr)) {
- dvert = static_cast<MDeformVert *>(BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
+ MDeformVert *dvert = static_cast<MDeformVert *>(
+ BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
dvert_mirr = static_cast<MDeformVert *>(
BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset));
@@ -2447,11 +2458,11 @@ void ED_vgroup_mirror(Object *ob,
}
else {
/* object mode / weight paint */
- MVert *mv, *mv_mirr;
+ const MVert *mv, *mv_mirr;
int vidx, vidx_mirr;
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
- if (me->dvert == nullptr) {
+ if (me->deform_verts().is_empty()) {
goto cleanup;
}
@@ -2460,12 +2471,14 @@ void ED_vgroup_mirror(Object *ob,
}
BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__);
+ const MVert *verts = me->vertices().data();
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
- for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) {
+ for (vidx = 0, mv = verts; vidx < me->totvert; vidx++, mv++) {
if (!BLI_BITMAP_TEST(vert_tag, vidx)) {
if ((vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology)) != -1) {
if (vidx != vidx_mirr) {
- mv_mirr = &me->mvert[vidx_mirr];
+ mv_mirr = &verts[vidx_mirr];
if (!BLI_BITMAP_TEST(vert_tag, vidx_mirr)) {
if (use_vert_sel) {
@@ -2474,8 +2487,8 @@ void ED_vgroup_mirror(Object *ob,
}
if (sel || sel_mirr) {
- dvert = &me->dvert[vidx];
- dvert_mirr = &me->dvert[vidx_mirr];
+ MDeformVert *dvert = &dverts[vidx];
+ dvert_mirr = &dvert[vidx_mirr];
VGROUP_MIRR_OP;
totmirr++;
@@ -2528,7 +2541,7 @@ void ED_vgroup_mirror(Object *ob,
sel_mirr = bp_mirr->f1 & SELECT;
if (sel || sel_mirr) {
- dvert = &lt->dvert[i1];
+ MDeformVert *dvert = &lt->dvert[i1];
dvert_mirr = &lt->dvert[i2];
VGROUP_MIRR_OP;
@@ -2612,14 +2625,12 @@ static void vgroup_assign_verts(Object *ob, const float weight)
}
}
else {
- if (!me->dvert) {
- BKE_object_defgroup_data_create(&me->id);
- }
+ const Span<MVert> verts = me->vertices();
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
+ MDeformVert *dv = dverts.data();
- MVert *mv = me->mvert;
- MDeformVert *dv = me->dvert;
-
- for (int i = 0; i < me->totvert; i++, mv++, dv++) {
+ for (int i = 0; i < me->totvert; i++, dv++) {
+ const MVert *mv = &verts[i];
if (mv->flag & SELECT) {
MDeformWeight *dw;
dw = BKE_defvert_ensure_index(dv, def_nr);
@@ -2733,7 +2744,7 @@ static bool vertex_group_mesh_with_dvert_poll(bContext *C)
}
Mesh *me = static_cast<Mesh *>(ob->data);
- if (me->dvert == nullptr) {
+ if (me->deform_verts().is_empty()) {
CTX_wm_operator_poll_msg_set(C, "The active mesh object has no vertex group data");
return false;
}
@@ -4345,9 +4356,12 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
return;
}
- dv = me->dvert;
+ const Span<MVert> verts = me->vertices();
+ MutableSpan<MDeformVert> dverts = me->deform_verts_for_write();
+
+ dv = dverts.data();
for (i = 0; i < me->totvert; i++, dv++) {
- if ((me->mvert[i].flag & SELECT) && (dv != dvert_act)) {
+ if ((verts[i].flag & SELECT) && (dv != dvert_act)) {
BKE_defvert_copy_index(dv, def_nr, dvert_act, def_nr);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 167952ba1fb..7067d558d7a 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -1451,26 +1451,27 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part
vec = edit->emitter_cosnos;
nor = vec + 3;
+ const MVert *verts = BKE_mesh_vertices(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
-
+ MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
for (i = 0; i < totface; i++, vec += 6, nor += 6) {
- MFace *mface = &mesh->mface[i];
- MVert *mvert;
+ MFace *mface = &mfaces[i];
+ const MVert *mvert;
- mvert = &mesh->mvert[mface->v1];
+ mvert = &verts[mface->v1];
copy_v3_v3(vec, mvert->co);
copy_v3_v3(nor, vert_normals[mface->v1]);
- mvert = &mesh->mvert[mface->v2];
+ mvert = &verts[mface->v2];
add_v3_v3v3(vec, vec, mvert->co);
add_v3_v3(nor, vert_normals[mface->v2]);
- mvert = &mesh->mvert[mface->v3];
+ mvert = &verts[mface->v3];
add_v3_v3v3(vec, vec, mvert->co);
add_v3_v3(nor, vert_normals[mface->v3]);
if (mface->v4) {
- mvert = &mesh->mvert[mface->v4];
+ mvert = &verts[mface->v4];
add_v3_v3v3(vec, vec, mvert->co);
add_v3_v3(nor, vert_normals[mface->v4]);
@@ -3568,7 +3569,9 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg
}
if (newtotpart != psys->totpart) {
- MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface;
+ MFace *mtessface = use_dm_final_indices ?
+ (MFace *)CustomData_get_layer(&psmd_eval->mesh_final->fdata, CD_MFACE) :
+ (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE);
/* allocate new arrays and copy existing */
new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new");
@@ -4176,8 +4179,8 @@ static int particle_intersect_mesh(Depsgraph *depsgraph,
}
totface = mesh->totface;
- mface = mesh->mface;
- mvert = mesh->mvert;
+ mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE);
+ mvert = BKE_mesh_vertices_for_write(mesh);
/* lets intersect the faces */
for (i = 0; i < totface; i++, mface++) {
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 96aea0ededf..a9fa325c341 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -704,7 +704,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
PTCacheEditKey *ekey;
BVHTreeFromMesh bvhtree = {NULL};
MFace *mface = NULL, *mf;
- MEdge *medge = NULL, *me;
+ const MEdge *medge = NULL, *me;
MVert *mvert;
Mesh *mesh, *target_mesh;
int numverts;
@@ -750,7 +750,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
BKE_mesh_tessface_ensure(mesh);
numverts = mesh->totvert;
- mvert = mesh->mvert;
+ mvert = BKE_mesh_vertices_for_write(mesh);
/* convert to global coordinates */
for (int i = 0; i < numverts; i++) {
@@ -758,11 +758,11 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
}
if (mesh->totface != 0) {
- mface = mesh->mface;
+ mface = CustomData_get_layer(&mesh->fdata, CD_MFACE);
BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_FACES, 2);
}
else if (mesh->totedge != 0) {
- medge = mesh->medge;
+ medge = BKE_mesh_edges(mesh);
BKE_bvhtree_from_mesh_get(&bvhtree, mesh, BVHTREE_FROM_EDGES, 2);
}
else {
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
index f6539284f74..3b13575f7bb 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc
@@ -90,6 +90,8 @@ struct AddOperationExecutor {
Object *surface_ob_eval_ = nullptr;
Mesh *surface_eval_ = nullptr;
+ Span<MVert> surface_verts_eval_;
+ Span<MLoop> surface_loops_eval_;
Span<MLoopTri> surface_looptris_eval_;
VArraySpan<float2> surface_uv_map_eval_;
BVHTreeFromMesh surface_bvh_eval_;
@@ -140,6 +142,12 @@ struct AddOperationExecutor {
report_empty_evaluated_surface(stroke_extension.reports);
return;
}
+ surface_verts_eval_ = surface_eval_->vertices();
+ surface_loops_eval_ = surface_eval_->loops();
+ surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_),
+ BKE_mesh_runtime_looptri_len(surface_eval_)};
+ BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2);
+ BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); });
curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt;
brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint);
@@ -179,12 +187,6 @@ struct AddOperationExecutor {
/* Use a pointer cast to avoid overflow warnings. */
RandomNumberGenerator rng{*(uint32_t *)(&time)};
- BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2);
- BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_eval_); });
-
- surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_),
- BKE_mesh_runtime_looptri_len(surface_eval_)};
-
/* Sample points on the surface using one of multiple strategies. */
Vector<float2> sampled_uvs;
if (add_amount_ == 1) {
@@ -296,7 +298,7 @@ struct AddOperationExecutor {
const MLoopTri &looptri = surface_looptris_eval_[looptri_index];
const float3 brush_pos_su = ray_hit.co;
const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle(
- *surface_eval_, looptri, brush_pos_su);
+ surface_verts_eval_, surface_loops_eval_, looptri, brush_pos_su);
const float2 uv = bke::mesh_surface_sample::sample_corner_attrribute_with_bary_coords(
bary_coords, looptri, surface_uv_map_eval_);
@@ -421,9 +423,9 @@ struct AddOperationExecutor {
brush_radius_su,
[&](const int index, const float3 &UNUSED(co), const float UNUSED(dist_sq)) {
const MLoopTri &looptri = surface_looptris_eval_[index];
- const float3 v0_su = surface_eval_->mvert[surface_eval_->mloop[looptri.tri[0]].v].co;
- const float3 v1_su = surface_eval_->mvert[surface_eval_->mloop[looptri.tri[1]].v].co;
- const float3 v2_su = surface_eval_->mvert[surface_eval_->mloop[looptri.tri[2]].v].co;
+ const float3 v0_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[0]].v].co;
+ const float3 v1_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[1]].v].co;
+ const float3 v2_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[2]].v].co;
float3 normal_su;
normal_tri_v3(normal_su, v0_su, v1_su, v2_su);
if (math::dot(normal_su, view_direction_su) >= 0.0f) {
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
index 139e0d67e89..062bacc7add 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc
@@ -70,6 +70,8 @@ struct PuffOperationExecutor {
Object *surface_ob_ = nullptr;
Mesh *surface_ = nullptr;
+ Span<MVert> surface_verts_;
+ Span<MLoop> surface_loops_;
Span<MLoopTri> surface_looptris_;
Span<float3> corner_normals_su_;
BVHTreeFromMesh surface_bvh_;
@@ -117,11 +119,12 @@ struct PuffOperationExecutor {
reinterpret_cast<const float3 *>(CustomData_get_layer(&surface_->ldata, CD_NORMAL)),
surface_->totloop};
- BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2);
- BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); });
-
+ surface_verts_ = surface_->vertices();
+ surface_loops_ = surface_->loops();
surface_looptris_ = {BKE_mesh_runtime_looptri_ensure(surface_),
BKE_mesh_runtime_looptri_len(surface_)};
+ BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2);
+ BLI_SCOPED_DEFER([&]() { free_bvhtree_from_mesh(&surface_bvh_); });
if (stroke_extension.is_first) {
this->initialize_segment_lengths();
@@ -289,9 +292,9 @@ struct PuffOperationExecutor {
const MLoopTri &looptri = surface_looptris_[nearest.index];
const float3 closest_pos_su = nearest.co;
- const float3 &v0_su = surface_->mvert[surface_->mloop[looptri.tri[0]].v].co;
- const float3 &v1_su = surface_->mvert[surface_->mloop[looptri.tri[1]].v].co;
- const float3 &v2_su = surface_->mvert[surface_->mloop[looptri.tri[2]].v].co;
+ const float3 &v0_su = surface_verts_[surface_loops_[looptri.tri[0]].v].co;
+ const float3 &v1_su = surface_verts_[surface_loops_[looptri.tri[1]].v].co;
+ const float3 &v2_su = surface_verts_[surface_loops_[looptri.tri[2]].v].co;
float3 bary_coords;
interp_weights_tri_v3(bary_coords, v0_su, v1_su, v2_su, closest_pos_su);
const float3 normal_su = geometry::compute_surface_point_normal(
diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
index 007bff0b170..e65d81a4225 100644
--- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
+++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc
@@ -112,6 +112,8 @@ struct SlideOperationExecutor {
Object *surface_ob_eval_ = nullptr;
Mesh *surface_eval_ = nullptr;
+ Span<MVert> surface_verts_eval_;
+ Span<MLoop> surface_loops_eval_;
Span<MLoopTri> surface_looptris_eval_;
VArraySpan<float2> surface_uv_map_eval_;
BVHTreeFromMesh surface_bvh_eval_;
@@ -175,8 +177,8 @@ struct SlideOperationExecutor {
if (surface_orig_->totpoly == 0) {
report_empty_original_surface(stroke_extension.reports);
return;
- }
- surface_looptris_orig_ = {BKE_mesh_runtime_looptri_ensure(surface_orig_),
+ }
+ surface_looptris_orig_ = {BKE_mesh_runtime_looptri_ensure(surface_orig_),
BKE_mesh_runtime_looptri_len(surface_orig_)};
surface_uv_map_orig_ =
bke::mesh_attributes(*surface_orig_).lookup<float2>(uv_map_name, ATTR_DOMAIN_CORNER);
@@ -205,6 +207,8 @@ struct SlideOperationExecutor {
}
surface_looptris_eval_ = {BKE_mesh_runtime_looptri_ensure(surface_eval_),
BKE_mesh_runtime_looptri_len(surface_eval_)};
+ surface_verts_eval_ = surface_eval_->vertices();
+ surface_loops_eval_ = surface_eval_->loops();
surface_uv_map_eval_ =
bke::mesh_attributes(*surface_eval_).lookup<float2>(uv_map_name, ATTR_DOMAIN_CORNER);
if (surface_uv_map_eval_.is_empty()) {
@@ -319,8 +323,8 @@ struct SlideOperationExecutor {
{
const float4x4 brush_transform_inv = brush_transform.inverted();
- const Span<MVert> verts_orig_su{surface_orig_->mvert, surface_orig_->totvert};
- const Span<MLoop> loops_orig{surface_orig_->mloop, surface_orig_->totloop};
+ const Span<MVert> verts_orig_su = surface_orig_->vertices();
+ const Span<MLoop> loops_orig = surface_orig_->loops();
MutableSpan<float3> positions_orig_cu = curves_orig_->positions_for_write();
MutableSpan<float2> surface_uv_coords = curves_orig_->surface_uv_coords_for_write();
@@ -383,7 +387,7 @@ struct SlideOperationExecutor {
/* Compute the uv of the new surface position on the evaluated mesh. */
const MLoopTri &looptri_eval = surface_looptris_eval_[looptri_index_eval];
const float3 bary_weights_eval = bke::mesh_surface_sample::compute_bary_coord_in_triangle(
- *surface_eval_, looptri_eval, hit_pos_eval_su);
+ surface_verts_eval_, surface_loops_eval_, looptri_eval, hit_pos_eval_su);
const float2 uv = attribute_math::mix3(bary_weights_eval,
surface_uv_map_eval_[looptri_eval.tri[0]],
surface_uv_map_eval_[looptri_eval.tri[1]],
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index a1bb2bf41ea..f1e6c7bf8dd 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -4055,13 +4055,13 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p
}
ps->mat_array[totmat - 1] = NULL;
- ps->mvert_eval = ps->me_eval->mvert;
+ ps->mvert_eval = BKE_mesh_vertices(ps->me_eval);
ps->vert_normals = BKE_mesh_vertex_normals_ensure(ps->me_eval);
if (ps->do_mask_cavity) {
- ps->medge_eval = ps->me_eval->medge;
+ ps->medge_eval = BKE_mesh_edges(ps->me_eval);
}
- ps->mloop_eval = ps->me_eval->mloop;
- ps->mpoly_eval = ps->me_eval->mpoly;
+ ps->mloop_eval = BKE_mesh_loops(ps->me_eval);
+ ps->mpoly_eval = BKE_mesh_polygons(ps->me_eval);
ps->material_indices = (const int *)CustomData_get_layer_named(
&ps->me_eval->pdata, CD_PROP_INT32, "material_index");
@@ -4155,7 +4155,7 @@ static void proj_paint_face_lookup_init(const ProjPaintState *ps, ProjPaintFaceL
memset(face_lookup, 0, sizeof(*face_lookup));
if (ps->do_face_sel) {
face_lookup->index_mp_to_orig = CustomData_get_layer(&ps->me_eval->pdata, CD_ORIGINDEX);
- face_lookup->mpoly_orig = ((Mesh *)ps->ob->data)->mpoly;
+ face_lookup->mpoly_orig = BKE_mesh_polygons((Mesh *)ps->ob->data);
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index dcc6e734cf4..34c5fc3124c 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -1123,6 +1123,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
const float(*ob_imat)[4] = vc->obact->imat;
/* Write vertices coordinates for the front face. */
+ MVert *verts = BKE_mesh_vertices_for_write(trim_operation->mesh);
float depth_point[3];
madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front);
for (int i = 0; i < tot_screen_points; i++) {
@@ -1134,7 +1135,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
madd_v3_v3fl(new_point, shape_normal, depth_front);
}
- mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point);
+ mul_v3_m4v3(verts[i].co, ob_imat, new_point);
mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point);
}
@@ -1149,7 +1150,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point);
madd_v3_v3fl(new_point, shape_normal, depth_back);
}
- mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point);
+ mul_v3_m4v3(verts[i + tot_screen_points].co, ob_imat, new_point);
mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point);
}
@@ -1159,10 +1160,12 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris);
/* Write the front face triangle indices. */
- MPoly *mp = trim_operation->mesh->mpoly;
- MLoop *ml = trim_operation->mesh->mloop;
+ MPoly *polys = BKE_mesh_polygons_for_write(trim_operation->mesh);
+ MLoop *loops = BKE_mesh_loops_for_write(trim_operation->mesh);
+ MPoly *mp = polys;
+ MLoop *ml = loops;
for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) {
- mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
+ mp->loopstart = (int)(ml - loops);
mp->totloop = 3;
ml[0].v = r_tris[i][0];
ml[1].v = r_tris[i][1];
@@ -1171,7 +1174,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
/* Write the back face triangle indices. */
for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) {
- mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
+ mp->loopstart = (int)(ml - loops);
mp->totloop = 3;
ml[0].v = r_tris[i][0] + tot_screen_points;
ml[1].v = r_tris[i][1] + tot_screen_points;
@@ -1182,7 +1185,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
/* Write the indices for the lateral triangles. */
for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) {
- mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
+ mp->loopstart = (int)(ml - loops);
mp->totloop = 3;
int current_index = i;
int next_index = current_index + 1;
@@ -1195,7 +1198,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
}
for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) {
- mp->loopstart = (int)(ml - trim_operation->mesh->mloop);
+ mp->loopstart = (int)(ml - loops);
mp->totloop = 3;
int current_index = i;
int next_index = current_index + 1;
@@ -1330,8 +1333,9 @@ static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C),
{
SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation;
Mesh *trim_mesh = trim_operation->mesh;
+ MVert *verts = BKE_mesh_vertices_for_write(trim_mesh);
for (int i = 0; i < trim_mesh->totvert; i++) {
- flip_v3_v3(trim_mesh->mvert[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass);
+ flip_v3_v3(verts[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass);
}
sculpt_gesture_trim_normals_update(sgcontext);
sculpt_gesture_apply_trim(sgcontext);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index adf21154842..7336166d651 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -30,6 +30,7 @@
#include "BKE_image.h"
#include "BKE_layer.h"
#include "BKE_material.h"
+#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_paint.h"
#include "BKE_report.h"
@@ -287,8 +288,8 @@ static void imapaint_pick_uv(
const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval);
const int tottri = me_eval->runtime.looptris.len;
- const MVert *mvert = me_eval->mvert;
- const MLoop *mloop = me_eval->mloop;
+ const MVert *mvert = BKE_mesh_vertices(me_eval);
+ const MLoop *mloop = BKE_mesh_loops(me_eval);
const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
/* get the needed opengl matrices */
@@ -702,7 +703,7 @@ static int vert_select_ungrouped_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
Mesh *me = ob->data;
- if (BLI_listbase_is_empty(&me->vertex_group_names) || (me->dvert == NULL)) {
+ if (BLI_listbase_is_empty(&me->vertex_group_names) || (BKE_mesh_deform_verts(me) == NULL)) {
BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
return OPERATOR_CANCELLED;
}
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc
index ccaf8b1ba37..c1a2a326d14 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.cc
+++ b/source/blender/editors/sculpt_paint/paint_vertex.cc
@@ -773,6 +773,8 @@ struct WeightPaintGroupData {
* paint stroke update - campbell */
struct WeightPaintInfo {
+ MutableSpan<MDeformVert> dvert;
+
int defbase_tot;
/* both must add up to 'defbase_tot' */
@@ -815,7 +817,7 @@ static void do_weight_paint_vertex_single(
float paintweight)
{
Mesh *me = (Mesh *)ob->data;
- MDeformVert *dv = &me->dvert[index];
+ MDeformVert *dv = &wpi->dvert[index];
bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
MDeformWeight *dw;
@@ -875,7 +877,7 @@ static void do_weight_paint_vertex_single(
/* get the mirror def vars */
if (index_mirr != -1) {
- dv_mirr = &me->dvert[index_mirr];
+ dv_mirr = &wpi->dvert[index_mirr];
if (wp->flag & VP_FLAG_VGROUP_RESTRICT) {
dw_mirr = BKE_defvert_find_index(dv_mirr, vgroup_mirr);
@@ -915,9 +917,9 @@ static void do_weight_paint_vertex_single(
if (!brush_use_accumulate(wp)) {
MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
- MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index);
+ MDeformVert *dv_prev = defweight_prev_init(dvert_prev, wpi->dvert.data(), index);
if (index_mirr != -1) {
- defweight_prev_init(dvert_prev, me->dvert, index_mirr);
+ defweight_prev_init(dvert_prev, wpi->dvert.data(), index_mirr);
}
weight_prev = BKE_defvert_find_weight(dv_prev, wpi->active.index);
@@ -1028,7 +1030,7 @@ static void do_weight_paint_vertex_multi(
float paintweight)
{
Mesh *me = (Mesh *)ob->data;
- MDeformVert *dv = &me->dvert[index];
+ MDeformVert *dv = &wpi->dvert[index];
bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
/* mirror vars */
@@ -1044,7 +1046,7 @@ static void do_weight_paint_vertex_multi(
index_mirr = mesh_get_x_mirror_vert(ob, nullptr, index, topology);
if (!ELEM(index_mirr, -1, index)) {
- dv_mirr = &me->dvert[index_mirr];
+ dv_mirr = &wpi->dvert[index_mirr];
}
else {
index_mirr = -1;
@@ -1071,9 +1073,9 @@ static void do_weight_paint_vertex_multi(
if (!brush_use_accumulate(wp)) {
MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
- MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index);
+ MDeformVert *dv_prev = defweight_prev_init(dvert_prev, wpi->dvert.data(), index);
if (index_mirr != -1) {
- defweight_prev_init(dvert_prev, me->dvert, index_mirr);
+ defweight_prev_init(dvert_prev, wpi->dvert.data(), index_mirr);
}
oldw = BKE_defvert_multipaint_collective_weight(
@@ -1235,6 +1237,8 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
}
Mesh *me = (Mesh *)ob->data;
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
if (gmap->vert_to_loop == nullptr) {
gmap->vert_map_mem = nullptr;
@@ -1243,15 +1247,15 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
gmap->vert_to_poly = nullptr;
BKE_mesh_vert_loop_map_create(&gmap->vert_to_loop,
&gmap->vert_map_mem,
- me->mpoly,
- me->mloop,
+ polys.data(),
+ loops.data(),
me->totvert,
me->totpoly,
me->totloop);
BKE_mesh_vert_poly_map_create(&gmap->vert_to_poly,
&gmap->poly_map_mem,
- me->mpoly,
- me->mloop,
+ polys.data(),
+ loops.data(),
me->totvert,
me->totpoly,
me->totloop);
@@ -1900,7 +1904,7 @@ static void do_wpaint_precompute_weight_cb_ex(void *__restrict userdata,
const TaskParallelTLS *__restrict UNUSED(tls))
{
SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata;
- const MDeformVert *dv = &data->me->dvert[n];
+ const MDeformVert *dv = &data->wpi->dvert[n];
data->wpd->precomputed_weight[n] = wpaint_get_active_weight(dv, data->wpi);
}
@@ -1961,10 +1965,9 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v :
- vd.vert_indices[vd.i];
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const char v_flag = data->me->mvert[v_index].flag;
+ const char v_flag = ss->mvert[v_index].flag;
/* If the vertex is selected */
if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
/* Get the average poly weight */
@@ -1972,12 +1975,12 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata,
float weight_final = 0.0f;
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
const int p_index = gmap->vert_to_poly[v_index].indices[j];
- const MPoly *mp = &data->me->mpoly[p_index];
+ const MPoly *mp = &ss->mpoly[p_index];
total_hit_loops += mp->totloop;
for (int k = 0; k < mp->totloop; k++) {
const int l_index = mp->loopstart + k;
- const MLoop *ml = &data->me->mloop[l_index];
+ const MLoop *ml = &ss->mloop[l_index];
weight_final += data->wpd->precomputed_weight[ml->v];
}
}
@@ -2057,10 +2060,9 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v :
- vd.vert_indices[vd.i];
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv_curr = &data->me->mvert[v_index];
+ const MVert *mv_curr = &ss->mvert[v_index];
/* If the vertex is selected */
if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) {
@@ -2082,12 +2084,12 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata,
float weight_final = 0.0;
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
const int p_index = gmap->vert_to_poly[v_index].indices[j];
- const MPoly *mp = &data->me->mpoly[p_index];
- const MLoop *ml_other = &data->me->mloop[mp->loopstart];
+ const MPoly *mp = &ss->mpoly[p_index];
+ const MLoop *ml_other = &ss->mloop[mp->loopstart];
for (int k = 0; k < mp->totloop; k++, ml_other++) {
const uint v_other_index = ml_other->v;
if (v_other_index != v_index) {
- const MVert *mv_other = &data->me->mvert[v_other_index];
+ const MVert *mv_other = &ss->mvert[v_other_index];
/* Get the direction from the selected vert to the neighbor. */
float other_dir[3];
@@ -2164,11 +2166,10 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata,
/* NOTE: grids are 1:1 with corners (aka loops).
* For multires, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v :
- vd.vert_indices[vd.i];
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const char v_flag = data->me->mvert[v_index].flag;
+ const char v_flag = ss->mvert[v_index].flag;
/* If the vertex is selected */
if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
float brush_strength = cache->bstrength;
@@ -2232,13 +2233,12 @@ static void do_wpaint_brush_calc_average_weight_cb_ex(
1.0f;
if (angle_cos > 0.0 &&
BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) {
- const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v :
- vd.vert_indices[vd.i];
- const char v_flag = data->me->mvert[v_index].flag;
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
+ const char v_flag = ss->mvert[v_index].flag;
/* If the vertex is selected. */
if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
- const MDeformVert *dv = &data->me->dvert[v_index];
+ const MDeformVert *dv = &data->wpi->dvert[v_index];
accum->len += 1;
accum->value += wpaint_get_active_weight(dv, data->wpi);
}
@@ -2510,7 +2510,11 @@ static void wpaint_stroke_update_step(bContext *C,
/* load projection matrix */
mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
+ Mesh *mesh = static_cast<Mesh *>(ob->data);
+
/* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */
+ wpi.dvert = mesh->deform_verts_for_write();
+
wpi.defbase_tot = wpd->defbase_tot;
wpi.defbase_sel = wpd->defbase_sel;
wpi.defbase_tot_sel = wpd->defbase_tot_sel;
@@ -2532,7 +2536,7 @@ static void wpaint_stroke_update_step(bContext *C,
/* *** done setting up WeightPaintInfo *** */
if (wpd->precomputed_weight) {
- precompute_weight_values(C, ob, brush, wpd, &wpi, (Mesh *)ob->data);
+ precompute_weight_values(C, ob, brush, wpd, &wpi, mesh);
}
wpaint_do_symmetrical_brush_actions(C, ob, wp, sd, wpd, &wpi);
@@ -2545,9 +2549,9 @@ static void wpaint_stroke_update_step(bContext *C,
mul_v3_m4v3(loc_world, ob->obmat, ss->cache->true_location);
paint_last_stroke_update(scene, loc_world);
- BKE_mesh_batch_cache_dirty_tag((Mesh *)ob->data, BKE_MESH_BATCH_DIRTY_ALL);
+ BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL);
- DEG_id_tag_update((ID *)ob->data, 0);
+ DEG_id_tag_update(&mesh->id, 0);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
swap_m4m4(wpd->vc.rv3d->persmat, mat);
@@ -2980,10 +2984,10 @@ static void do_vpaint_brush_blur_loops(bContext *C,
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v :
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv = &me->mvert[v_index];
+ const MVert *mv = &ss->mvert[v_index];
/* If the vertex is selected for painting. */
if (!use_vert_sel || mv->flag & SELECT) {
@@ -3006,7 +3010,7 @@ static void do_vpaint_brush_blur_loops(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
int p_index = gmap->vert_to_poly[v_index].indices[j];
- const MPoly *mp = &me->mpoly[p_index];
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
total_hit_loops += mp->totloop;
for (int k = 0; k < mp->totloop; k++) {
@@ -3040,8 +3044,8 @@ static void do_vpaint_brush_blur_loops(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
const int p_index = gmap->vert_to_poly[v_index].indices[j];
const int l_index = gmap->vert_to_loop[v_index].indices[j];
- BLI_assert(me->mloop[l_index].v == v_index);
- const MPoly *mp = &me->mpoly[p_index];
+ BLI_assert(ss->mloop[l_index].v == v_index);
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
@@ -3122,10 +3126,10 @@ static void do_vpaint_brush_blur_verts(bContext *C,
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v :
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv = &me->mvert[v_index];
+ const MVert *mv = &ss->mvert[v_index];
/* If the vertex is selected for painting. */
if (!use_vert_sel || mv->flag & SELECT) {
@@ -3148,12 +3152,12 @@ static void do_vpaint_brush_blur_verts(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
int p_index = gmap->vert_to_poly[v_index].indices[j];
- const MPoly *mp = &me->mpoly[p_index];
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
total_hit_loops += mp->totloop;
for (int k = 0; k < mp->totloop; k++) {
const uint l_index = mp->loopstart + k;
- const uint v_index = me->mloop[l_index].v;
+ const uint v_index = ss->mloop[l_index].v;
Color *col = lcol + v_index;
@@ -3184,9 +3188,9 @@ static void do_vpaint_brush_blur_verts(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
const int p_index = gmap->vert_to_poly[v_index].indices[j];
- BLI_assert(me->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index);
+ BLI_assert(ss->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index);
- const MPoly *mp = &me->mpoly[p_index];
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
@@ -3273,10 +3277,10 @@ static void do_vpaint_brush_smear(bContext *C,
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
/* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v :
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv_curr = &me->mvert[v_index];
+ const MVert *mv_curr = &ss->mvert[v_index];
/* if the vertex is selected for painting. */
if (!use_vert_sel || mv_curr->flag & SELECT) {
@@ -3305,15 +3309,15 @@ static void do_vpaint_brush_smear(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
const int p_index = gmap->vert_to_poly[v_index].indices[j];
const int l_index = gmap->vert_to_loop[v_index].indices[j];
- BLI_assert(me->mloop[l_index].v == v_index);
+ BLI_assert(ss->mloop[l_index].v == v_index);
UNUSED_VARS_NDEBUG(l_index);
- const MPoly *mp = &me->mpoly[p_index];
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
- const MLoop *ml_other = &me->mloop[mp->loopstart];
+ const MLoop *ml_other = &ss->mloop[mp->loopstart];
for (int k = 0; k < mp->totloop; k++, ml_other++) {
const uint v_other_index = ml_other->v;
if (v_other_index != v_index) {
- const MVert *mv_other = &me->mvert[v_other_index];
+ const MVert *mv_other = &ss->mvert[v_other_index];
/* Get the direction from the
* selected vert to the neighbor. */
@@ -3359,10 +3363,10 @@ static void do_vpaint_brush_smear(bContext *C,
else {
const int l_index = gmap->vert_to_loop[v_index].indices[j];
elem_index = l_index;
- BLI_assert(me->mloop[l_index].v == v_index);
+ BLI_assert(ss->mloop[l_index].v == v_index);
}
- const MPoly *mp = &me->mpoly[p_index];
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
/* Get the previous element color */
Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */
@@ -3435,11 +3439,11 @@ static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd,
BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
/* Test to see if the vertex coordinates are within the spherical brush region. */
if (sculpt_brush_test_sq_fn(&test, vd.co)) {
- const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v :
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
if (BKE_brush_curve_strength(brush, 0.0, cache->radius) > 0.0) {
/* If the vertex is selected for painting. */
- const MVert *mv = &me->mvert[v_index];
+ const MVert *mv = &ss->mvert[v_index];
if (!use_vert_sel || mv->flag & SELECT) {
accum2->len += gmap->vert_to_loop[v_index].count;
/* if a vertex is within the brush region, then add its color to the blend. */
@@ -3555,10 +3559,10 @@ static void vpaint_do_draw(bContext *C,
/* NOTE: Grids are 1:1 with corners (aka loops).
* For grid based pbvh, take the vert whose loop corresponds to the current grid.
* Otherwise, take the current vert. */
- const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v :
+ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v :
vd.vert_indices[vd.i];
const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f;
- const MVert *mv = &me->mvert[v_index];
+ const MVert *mv = &ss->mvert[v_index];
/* If the vertex is selected for painting. */
if (!use_vert_sel || mv->flag & SELECT) {
@@ -3612,8 +3616,8 @@ static void vpaint_do_draw(bContext *C,
for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
const int p_index = gmap->vert_to_poly[v_index].indices[j];
const int l_index = gmap->vert_to_loop[v_index].indices[j];
- BLI_assert(me->mloop[l_index].v == v_index);
- const MPoly *mp = &me->mpoly[p_index];
+ BLI_assert(ss->mloop[l_index].v == v_index);
+ const MPoly *mp = &ss->mpoly[p_index];
if (!use_face_sel || mp->flag & ME_FACE_SEL) {
Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */
@@ -4084,27 +4088,30 @@ static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, CustomDataLay
}
else {
Color *color_layer = static_cast<Color *>(layer->data);
+ const Span<MVert> verts = me->vertices();
+ const Span<MPoly> polys = me->polygons();
+ const Span<MLoop> loops = me->loops();
- const MPoly *mp = me->mpoly;
- for (int i = 0; i < me->totpoly; i++, mp++) {
- if (use_face_sel && !(mp->flag & ME_FACE_SEL)) {
+ for (const int i : polys.index_range()) {
+ const MPoly &poly = polys[i];
+ if (use_face_sel && !(poly.flag & ME_FACE_SEL)) {
continue;
}
int j = 0;
do {
- uint vidx = me->mloop[mp->loopstart + j].v;
+ uint vidx = loops[poly.loopstart + j].v;
- if (!(use_vert_sel && !(me->mvert[vidx].flag & SELECT))) {
+ if (!(use_vert_sel && !(verts[vidx].flag & SELECT))) {
if constexpr (domain == ATTR_DOMAIN_CORNER) {
- color_layer[mp->loopstart + j] = paintcol;
+ color_layer[poly.loopstart + j] = paintcol;
}
else {
color_layer[vidx] = paintcol;
}
}
j++;
- } while (j < mp->totloop);
+ } while (j < poly.totloop);
}
/* remove stale me->mcol, will be added later */
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
index 8b726c7b942..7aa0adfc3d4 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
+++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc
@@ -50,7 +50,7 @@ static bool vertex_weight_paint_mode_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
Mesh *me = BKE_mesh_from_object(ob);
return (ob && (ELEM(ob->mode, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT))) &&
- (me && me->totpoly && me->dvert);
+ (me && me->totpoly && !me->deform_verts().is_empty());
}
static void tag_object_after_update(Object *object)
@@ -159,15 +159,15 @@ static IndexMask get_selected_indices(const Mesh &mesh,
Vector<int64_t> &indices)
{
using namespace blender;
- Span<MVert> verts(mesh.mvert, mesh.totvert);
- Span<MPoly> faces(mesh.mpoly, mesh.totpoly);
+ Span<MVert> verts = mesh.vertices();
+ Span<MPoly> polys = mesh.polygons();
bke::AttributeAccessor attributes = bke::mesh_attributes(mesh);
if (mesh.editflag & ME_EDIT_PAINT_FACE_SEL) {
const VArray<bool> selection = attributes.adapt_domain(
- VArray<bool>::ForFunc(faces.size(),
- [&](const int i) { return faces[i].flag & ME_FACE_SEL; }),
+ VArray<bool>::ForFunc(polys.size(),
+ [&](const int i) { return polys[i].flag & ME_FACE_SEL; }),
ATTR_DOMAIN_FACE,
domain);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
index d98660d8939..f40a287adf6 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c
@@ -168,8 +168,9 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
+ const MDeformVert *dvert = BKE_mesh_deform_verts(me);
- if (me && me->dvert && vc.v3d && vc.rv3d && (me->vertex_group_active_index != 0)) {
+ if (me && dvert && vc.v3d && vc.rv3d && (me->vertex_group_active_index != 0)) {
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int v_idx_best = -1;
uint index;
@@ -200,7 +201,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
ToolSettings *ts = vc.scene->toolsettings;
Brush *brush = BKE_paint_brush(&ts->wpaint->paint);
const int vgroup_active = me->vertex_group_active_index - 1;
- float vgroup_weight = BKE_defvert_find_weight(&me->dvert[v_idx_best], vgroup_active);
+ float vgroup_weight = BKE_defvert_find_weight(&dvert[v_idx_best], vgroup_active);
const int defbase_tot = BLI_listbase_count(&me->vertex_group_names);
bool use_lock_relative = ts->wpaint_lock_relative;
bool *defbase_locked = NULL, *defbase_unlocked = NULL;
@@ -232,7 +233,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
bool is_normalized = ts->auto_normalize || use_lock_relative;
vgroup_weight = BKE_defvert_multipaint_collective_weight(
- &me->dvert[v_idx_best], defbase_tot, defbase_sel, defbase_tot_sel, is_normalized);
+ &dvert[v_idx_best], defbase_tot, defbase_sel, defbase_tot_sel, is_normalized);
}
MEM_freeN(defbase_sel);
@@ -243,7 +244,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
defbase_tot, defbase_locked, defbase_unlocked, defbase_locked, defbase_unlocked);
vgroup_weight = BKE_defvert_lock_relative_weight(
- vgroup_weight, &me->dvert[v_idx_best], defbase_tot, defbase_locked, defbase_unlocked);
+ vgroup_weight, &dvert[v_idx_best], defbase_tot, defbase_locked, defbase_unlocked);
}
MEM_SAFE_FREE(defbase_locked);
@@ -316,8 +317,11 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
+ const MPoly *polys = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
+ const MDeformVert *dverts = BKE_mesh_deform_verts(me);
- if (me && me->dvert && vc.v3d && vc.rv3d && me->vertex_group_names.first) {
+ if (me && dverts && vc.v3d && vc.rv3d && me->vertex_group_names.first) {
const int defbase_tot = BLI_listbase_count(&me->vertex_group_names);
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
@@ -334,17 +338,17 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
if (use_vert_sel) {
if (ED_mesh_pick_vert(C, vc.obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, true, &index)) {
- MDeformVert *dvert = &me->dvert[index];
+ const MDeformVert *dvert = &dverts[index];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
}
}
else {
if (ED_mesh_pick_face(C, vc.obact, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
- const MPoly *mp = &me->mpoly[index];
+ const MPoly *mp = &polys[index];
uint fidx = mp->totloop - 1;
do {
- MDeformVert *dvert = &me->dvert[me->mloop[mp->loopstart + fidx].v];
+ const MDeformVert *dvert = &dverts[loops[mp->loopstart + fidx].v];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
} while (fidx--);
}
@@ -441,7 +445,12 @@ static bool weight_paint_set(Object *ob, float paintweight)
/* mutually exclusive, could be made into a */
const short paint_selmode = ME_EDIT_PAINT_SEL_MODE(me);
- if (me->totpoly == 0 || me->dvert == NULL || !me->mpoly) {
+ const MVert *verts = BKE_mesh_vertices(me);
+ const MPoly *polys = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
+ MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me);
+
+ if (me->totpoly == 0 || dvert == NULL) {
return false;
}
@@ -453,9 +462,9 @@ static bool weight_paint_set(Object *ob, float paintweight)
}
struct WPaintPrev wpp;
- wpaint_prev_create(&wpp, me->dvert, me->totvert);
+ wpaint_prev_create(&wpp, dvert, me->totvert);
- for (index = 0, mp = me->mpoly; index < me->totpoly; index++, mp++) {
+ for (index = 0, mp = polys; index < me->totpoly; index++, mp++) {
uint fidx = mp->totloop - 1;
if ((paint_selmode == SCE_SELECT_FACE) && !(mp->flag & ME_FACE_SEL)) {
@@ -463,14 +472,14 @@ static bool weight_paint_set(Object *ob, float paintweight)
}
do {
- uint vidx = me->mloop[mp->loopstart + fidx].v;
+ uint vidx = loops[mp->loopstart + fidx].v;
- if (!me->dvert[vidx].flag) {
- if ((paint_selmode == SCE_SELECT_VERTEX) && !(me->mvert[vidx].flag & SELECT)) {
+ if (!dvert[vidx].flag) {
+ if ((paint_selmode == SCE_SELECT_VERTEX) && !(verts[vidx].flag & SELECT)) {
continue;
}
- dw = BKE_defvert_ensure_index(&me->dvert[vidx], vgroup_active);
+ dw = BKE_defvert_ensure_index(&dvert[vidx], vgroup_active);
if (dw) {
dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + vidx, vgroup_active);
dw_prev->weight = dw->weight; /* set the undo weight */
@@ -482,11 +491,11 @@ static bool weight_paint_set(Object *ob, float paintweight)
if (j >= 0) {
/* copy, not paint again */
if (vgroup_mirror != -1) {
- dw = BKE_defvert_ensure_index(me->dvert + j, vgroup_mirror);
+ dw = BKE_defvert_ensure_index(dvert + j, vgroup_mirror);
dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + j, vgroup_mirror);
}
else {
- dw = BKE_defvert_ensure_index(me->dvert + j, vgroup_active);
+ dw = BKE_defvert_ensure_index(dvert + j, vgroup_active);
dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + j, vgroup_active);
}
dw_prev->weight = dw->weight; /* set the undo weight */
@@ -494,14 +503,14 @@ static bool weight_paint_set(Object *ob, float paintweight)
}
}
}
- me->dvert[vidx].flag = 1;
+ dvert[vidx].flag = 1;
}
} while (fidx--);
}
{
- MDeformVert *dv = me->dvert;
+ MDeformVert *dv = dvert;
for (index = me->totvert; index != 0; index--, dv++) {
dv->flag = 0;
}
@@ -574,6 +583,7 @@ typedef struct WPGradient_userData {
struct ARegion *region;
Scene *scene;
Mesh *me;
+ MDeformVert *dvert;
Brush *brush;
const float *sco_start; /* [2] */
const float *sco_end; /* [2] */
@@ -593,7 +603,6 @@ typedef struct WPGradient_userData {
static void gradientVert_update(WPGradient_userData *grad_data, int index)
{
- Mesh *me = grad_data->me;
WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index];
/* Optionally restrict to assigned vertices only. */
@@ -617,7 +626,7 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index)
alpha = BKE_brush_curve_strength_clamped(grad_data->brush, alpha, 1.0f);
if (alpha != 0.0f) {
- MDeformVert *dv = &me->dvert[index];
+ MDeformVert *dv = &grad_data->dvert[index];
MDeformWeight *dw = BKE_defvert_ensure_index(dv, grad_data->def_nr);
// dw->weight = alpha; // testing
int tool = grad_data->brush->blend;
@@ -631,7 +640,7 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index)
vs->flag |= VGRAD_STORE_IS_MODIFIED;
}
else {
- MDeformVert *dv = &me->dvert[index];
+ MDeformVert *dv = &grad_data->dvert[index];
if (vs->flag & VGRAD_STORE_DW_EXIST) {
/* normally we NULL check, but in this case we know it exists */
MDeformWeight *dw = BKE_defvert_find_index(dv, grad_data->def_nr);
@@ -669,10 +678,9 @@ static void gradientVertInit__mapFunc(void *userData,
const float UNUSED(no[3]))
{
WPGradient_userData *grad_data = userData;
- Mesh *me = grad_data->me;
WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index];
- if (grad_data->use_select && !(me->mvert[index].flag & SELECT)) {
+ if (grad_data->use_select && !(grad_data->dvert[index].flag & SELECT)) {
copy_v2_fl(vs->sco, FLT_MAX);
return;
}
@@ -693,7 +701,7 @@ static void gradientVertInit__mapFunc(void *userData,
return;
}
- MDeformVert *dv = &me->dvert[index];
+ MDeformVert *dv = &grad_data->dvert[index];
const MDeformWeight *dw = BKE_defvert_find_index(dv, grad_data->def_nr);
if (dw) {
vs->weight_orig = dw->weight;
@@ -727,8 +735,9 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven
if (vert_cache != NULL) {
Mesh *me = ob->data;
if (vert_cache->wpp.wpaint_prev) {
- BKE_defvert_array_free_elems(me->dvert, me->totvert);
- BKE_defvert_array_copy(me->dvert, vert_cache->wpp.wpaint_prev, me->totvert);
+ MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me);
+ BKE_defvert_array_free_elems(dvert, me->totvert);
+ BKE_defvert_array_copy(dvert, vert_cache->wpp.wpaint_prev, me->totvert);
wpaint_prev_destroy(&vert_cache->wpp);
}
MEM_freeN(vert_cache);
@@ -753,6 +762,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
Mesh *me = ob->data;
+ MDeformVert *dverts = BKE_mesh_deform_verts_for_write(me);
int x_start = RNA_int_get(op->ptr, "xstart");
int y_start = RNA_int_get(op->ptr, "ystart");
int x_end = RNA_int_get(op->ptr, "xend");
@@ -774,7 +784,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
data.is_init = true;
wpaint_prev_create(
- &((WPGradient_vertStoreBase *)gesture->user_data.data)->wpp, me->dvert, me->totvert);
+ &((WPGradient_vertStoreBase *)gesture->user_data.data)->wpp, dverts, me->totvert);
/* On initialization only, convert face -> vert sel. */
if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
@@ -797,6 +807,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
data.region = region;
data.scene = scene;
data.me = ob->data;
+ data.dvert = dverts;
data.sco_start = sco_start;
data.sco_end = sco_end;
data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end);
@@ -851,7 +862,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
const int vgroup_num = BLI_listbase_count(&me->vertex_group_names);
bool *vgroup_validmap = BKE_object_defgroup_validmap_get(ob, vgroup_num);
if (vgroup_validmap != NULL) {
- MDeformVert *dvert = me->dvert;
+ MDeformVert *dvert = dverts;
for (int i = 0; i < me->totvert; i++) {
if ((data.vert_cache->elem[i].flag & VGRAD_STORE_IS_MODIFIED) != 0) {
BKE_defvert_normalize_lock_single(&dvert[i], vgroup_validmap, vgroup_num, data.def_nr);
diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
index 5a63af4149a..ac16631f115 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_utils.c
@@ -59,7 +59,7 @@ bool ED_wpaint_ensure_data(bContext *C,
}
/* if nothing was added yet, we make dverts and a vertex deform group */
- if (!me->dvert) {
+ if (BKE_mesh_deform_verts(me) == NULL) {
BKE_object_defgroup_data_create(&me->id);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index a56755edf92..74fd2f904e5 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -600,10 +600,10 @@ void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss)
{
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
for (int i = 0; i < ss->totfaces; i++) {
- MPoly *poly = &ss->mpoly[i];
+ const MPoly *poly = &ss->mpoly[i];
bool poly_visible = true;
for (int l = 0; l < poly->totloop; l++) {
- MLoop *loop = &ss->mloop[poly->loopstart + l];
+ const MLoop *loop = &ss->mloop[poly->loopstart + l];
if (!SCULPT_vertex_visible_get(ss, BKE_pbvh_make_vref(loop->v))) {
poly_visible = false;
}
@@ -644,9 +644,9 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss
MeshElemMap *vert_map = &ss->pmap[v1];
int p1 = -1, p2 = -1;
for (int i = 0; i < ss->pmap[v1].count; i++) {
- MPoly *p = &ss->mpoly[vert_map->indices[i]];
+ const MPoly *p = &ss->mpoly[vert_map->indices[i]];
for (int l = 0; l < p->totloop; l++) {
- MLoop *loop = &ss->mloop[p->loopstart + l];
+ const MLoop *loop = &ss->mloop[p->loopstart + l];
if (loop->v == v2) {
if (p1 == -1) {
p1 = vert_map->indices[i];
@@ -3162,10 +3162,10 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3])
/* Modifying of basis key should update mesh. */
if (kb == me->key->refkey) {
- MVert *mvert = me->mvert;
+ MVert *verts = BKE_mesh_vertices_for_write(me);
- for (a = 0; a < me->totvert; a++, mvert++) {
- copy_v3_v3(mvert->co, vertCos[a]);
+ for (a = 0; a < me->totvert; a++) {
+ copy_v3_v3(verts[a].co, vertCos[a]);
}
BKE_mesh_tag_coords_changed(me);
}
@@ -3589,8 +3589,9 @@ static void sculpt_flush_pbvhvert_deform(Object *ob, PBVHVertexIter *vd)
copy_v3_v3(ss->deform_cos[index], vd->co);
copy_v3_v3(ss->orig_cos[index], newco);
+ MVert *verts = BKE_mesh_vertices_for_write(me);
if (!ss->shapekey_active) {
- copy_v3_v3(me->mvert[index].co, newco);
+ copy_v3_v3(verts[index].co, newco);
}
}
@@ -5908,21 +5909,25 @@ void SCULPT_boundary_info_ensure(Object *object)
}
Mesh *base_mesh = BKE_mesh_from_object(object);
+ const MEdge *edges = BKE_mesh_edges(base_mesh);
+ const MPoly *polys = BKE_mesh_polygons(base_mesh);
+ const MLoop *loops = BKE_mesh_loops(base_mesh);
+
ss->vertex_info.boundary = BLI_BITMAP_NEW(base_mesh->totvert, "Boundary info");
int *adjacent_faces_edge_count = MEM_calloc_arrayN(
base_mesh->totedge, sizeof(int), "Adjacent face edge count");
for (int p = 0; p < base_mesh->totpoly; p++) {
- MPoly *poly = &base_mesh->mpoly[p];
+ const MPoly *poly = &polys[p];
for (int l = 0; l < poly->totloop; l++) {
- MLoop *loop = &base_mesh->mloop[l + poly->loopstart];
+ const MLoop *loop = &loops[l + poly->loopstart];
adjacent_faces_edge_count[loop->e]++;
}
}
for (int e = 0; e < base_mesh->totedge; e++) {
if (adjacent_faces_edge_count[e] < 2) {
- MEdge *edge = &base_mesh->medge[e];
+ const MEdge *edge = &edges[e];
BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v1, true);
BLI_BITMAP_SET(ss->vertex_info.boundary, edge->v2, true);
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 000b69cc2ba..ad8a1cde9dc 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -210,8 +210,6 @@ static void SCULPT_dynamic_topology_disable_ex(
&geometry->ldata, &me->ldata, CD_MASK_MESH.lmask, CD_DUPLICATE, geometry->totloop);
CustomData_copy(
&geometry->pdata, &me->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly);
-
- BKE_mesh_update_customdata_pointers(me, false);
}
else {
BKE_sculptsession_bm_to_me(ob, true);
diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c
index 75cc966c0b2..63d5c14a931 100644
--- a/source/blender/editors/sculpt_paint/sculpt_expand.c
+++ b/source/blender/editors/sculpt_paint/sculpt_expand.c
@@ -690,7 +690,6 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
}
/* Propagate the falloff increasing the value by 1 each time a new vertex is visited. */
- Mesh *mesh = ob->data;
while (!BLI_gsqueue_is_empty(queue)) {
PBVHVertRef v_next;
BLI_gsqueue_pop(queue, &v_next);
@@ -698,9 +697,9 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR
int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next);
for (int j = 0; j < ss->pmap[v_next_i].count; j++) {
- MPoly *p = &ss->mpoly[ss->pmap[v_next_i].indices[j]];
+ const MPoly *p = &ss->mpoly[ss->pmap[v_next_i].indices[j]];
for (int l = 0; l < p->totloop; l++) {
- const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(mesh->mloop[p->loopstart + l].v);
+ const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(ss->mloop[p->loopstart + l].v);
if (BLI_BITMAP_TEST(visited_vertices, neighbor_v.i)) {
continue;
}
@@ -777,11 +776,11 @@ static void sculpt_expand_grids_to_faces_falloff(SculptSession *ss,
Mesh *mesh,
ExpandCache *expand_cache)
{
-
+ const MPoly *polys = BKE_mesh_polygons(mesh);
const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh);
for (int p = 0; p < mesh->totpoly; p++) {
- MPoly *poly = &mesh->mpoly[p];
+ const MPoly *poly = &polys[p];
float accum = 0.0f;
for (int l = 0; l < poly->totloop; l++) {
const int grid_loop_index = (poly->loopstart + l) * key->grid_area;
@@ -795,11 +794,14 @@ static void sculpt_expand_grids_to_faces_falloff(SculptSession *ss,
static void sculpt_expand_vertex_to_faces_falloff(Mesh *mesh, ExpandCache *expand_cache)
{
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
+
for (int p = 0; p < mesh->totpoly; p++) {
- MPoly *poly = &mesh->mpoly[p];
+ const MPoly *poly = &polys[p];
float accum = 0.0f;
for (int l = 0; l < poly->totloop; l++) {
- MLoop *loop = &mesh->mloop[l + poly->loopstart];
+ const MLoop *loop = &loops[l + poly->loopstart];
accum += expand_cache->vert_falloff[loop->v];
}
expand_cache->face_falloff[p] = accum / poly->totloop;
@@ -1093,10 +1095,10 @@ static void sculpt_expand_snap_initialize_from_enabled(SculptSession *ss,
}
for (int p = 0; p < totface; p++) {
- MPoly *poly = &ss->mpoly[p];
+ const MPoly *poly = &ss->mpoly[p];
bool any_disabled = false;
for (int l = 0; l < poly->totloop; l++) {
- MLoop *loop = &ss->mloop[l + poly->loopstart];
+ const MLoop *loop = &ss->mloop[l + poly->loopstart];
if (!BLI_BITMAP_TEST(enabled_vertices, loop->v)) {
any_disabled = true;
break;
@@ -1938,6 +1940,8 @@ static void sculpt_expand_delete_face_set_id(int *r_face_sets,
{
const int totface = ss->totfaces;
MeshElemMap *pmap = ss->pmap;
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
/* Check that all the face sets IDs in the mesh are not equal to `delete_id`
* before attempting to delete it. */
@@ -1972,9 +1976,9 @@ static void sculpt_expand_delete_face_set_id(int *r_face_sets,
while (BLI_LINKSTACK_SIZE(queue)) {
const int f_index = POINTER_AS_INT(BLI_LINKSTACK_POP(queue));
int other_id = delete_id;
- const MPoly *c_poly = &mesh->mpoly[f_index];
+ const MPoly *c_poly = &polys[f_index];
for (int l = 0; l < c_poly->totloop; l++) {
- const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l];
+ const MLoop *c_loop = &loops[c_poly->loopstart + l];
const MeshElemMap *vert_map = &pmap[c_loop->v];
for (int i = 0; i < vert_map->count; i++) {
diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c
index a2a34566bb6..c8e546ecef3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_face_set.c
+++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c
@@ -1096,13 +1096,16 @@ static void sculpt_face_set_grow(Object *ob,
const bool modify_hidden)
{
Mesh *mesh = BKE_mesh_from_object(ob);
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
+
for (int p = 0; p < mesh->totpoly; p++) {
if (!modify_hidden && prev_face_sets[p] <= 0) {
continue;
}
- const MPoly *c_poly = &mesh->mpoly[p];
+ const MPoly *c_poly = &polys[p];
for (int l = 0; l < c_poly->totloop; l++) {
- const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l];
+ const MLoop *c_loop = &loops[c_poly->loopstart + l];
const MeshElemMap *vert_map = &ss->pmap[c_loop->v];
for (int i = 0; i < vert_map->count; i++) {
const int neighbor_face_index = vert_map->indices[i];
@@ -1124,14 +1127,16 @@ static void sculpt_face_set_shrink(Object *ob,
const bool modify_hidden)
{
Mesh *mesh = BKE_mesh_from_object(ob);
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
for (int p = 0; p < mesh->totpoly; p++) {
if (!modify_hidden && prev_face_sets[p] <= 0) {
continue;
}
if (abs(prev_face_sets[p]) == active_face_set_id) {
- const MPoly *c_poly = &mesh->mpoly[p];
+ const MPoly *c_poly = &polys[p];
for (int l = 0; l < c_poly->totloop; l++) {
- const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l];
+ const MLoop *c_loop = &loops[c_poly->loopstart + l];
const MeshElemMap *vert_map = &ss->pmap[c_loop->v];
for (int i = 0; i < vert_map->count; i++) {
const int neighbor_face_index = vert_map->indices[i];
diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
index ecf8c4586ae..4b871da1d02 100644
--- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c
+++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c
@@ -37,7 +37,6 @@
#include "DEG_depsgraph.h"
#include "WM_api.h"
-#include "WM_message.h"
#include "WM_toolsystem.h"
#include "WM_types.h"
@@ -108,8 +107,10 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
const float limit_radius_sq = limit_radius * limit_radius;
- MEdge *edges = mesh->medge;
MVert *verts = SCULPT_mesh_deformed_mverts_get(ss);
+ const MEdge *edges = BKE_mesh_edges(mesh);
+ const MPoly *polys = BKE_mesh_polygons(mesh);
+ const MLoop *loops = BKE_mesh_loops(mesh);
float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "distances");
BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag");
@@ -117,16 +118,15 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
if (!ss->epmap) {
BKE_mesh_edge_poly_map_create(&ss->epmap,
&ss->epmap_mem,
- mesh->medge,
+ edges,
mesh->totedge,
- mesh->mpoly,
+ polys,
mesh->totpoly,
- mesh->mloop,
+ loops,
mesh->totloop);
}
if (!ss->vemap) {
- BKE_mesh_vert_edge_map_create(
- &ss->vemap, &ss->vemap_mem, mesh->medge, mesh->totvert, mesh->totedge);
+ BKE_mesh_vert_edge_map_create(&ss->vemap, &ss->vemap_mem, edges, mesh->totvert, mesh->totedge);
}
/* Both contain edge indices encoded as *void. */
@@ -202,10 +202,10 @@ static float *SCULPT_geodesic_mesh_create(Object *ob,
if (ss->face_sets[poly] <= 0) {
continue;
}
- const MPoly *mpoly = &mesh->mpoly[poly];
+ const MPoly *mpoly = &polys[poly];
for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) {
- const MLoop *mloop = &mesh->mloop[loop_index + mpoly->loopstart];
+ const MLoop *mloop = &loops[loop_index + mpoly->loopstart];
const int v_other = mloop->v;
if (ELEM(v_other, v1, v2)) {
continue;
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index e667f9ce2fc..07dbb5964bf 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -627,8 +627,6 @@ static void sculpt_undo_geometry_restore_data(SculptUndoNodeGeometry *geometry,
CustomData_copy(
&geometry->pdata, &mesh->pdata, CD_MASK_MESH.pmask, CD_DUPLICATE, geometry->totpoly);
- BKE_mesh_update_customdata_pointers(mesh, false);
-
BKE_mesh_runtime_clear_cache(mesh);
}
diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
index 68f172169f4..3c79e66f436 100644
--- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
+++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc
@@ -168,45 +168,49 @@ std::unique_ptr<ColumnValues> GeometryDataSource::get_column_values(
else if (G.debug_value == 4001 && component_->type() == GEO_COMPONENT_TYPE_MESH) {
const MeshComponent &component = static_cast<const MeshComponent &>(*component_);
if (const Mesh *mesh = component.get_for_read()) {
+ const Span<MEdge> edges = mesh->edges();
+ const Span<MPoly> polys = mesh->polygons();
+ const Span<MLoop> loops = mesh->loops();
+
if (domain_ == ATTR_DOMAIN_EDGE) {
if (STREQ(column_id.name, "Vertex 1")) {
return std::make_unique<ColumnValues>(
- column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) {
- return mesh->medge[index].v1;
+ column_id.name, VArray<int>::ForFunc(edges.size(), [edges](int64_t index) {
+ return edges[index].v1;
}));
}
if (STREQ(column_id.name, "Vertex 2")) {
return std::make_unique<ColumnValues>(
- column_id.name, VArray<int>::ForFunc(mesh->totedge, [mesh](int64_t index) {
- return mesh->medge[index].v2;
+ column_id.name, VArray<int>::ForFunc(edges.size(), [edges](int64_t index) {
+ return edges[index].v2;
}));
}
}
else if (domain_ == ATTR_DOMAIN_FACE) {
if (STREQ(column_id.name, "Corner Start")) {
return std::make_unique<ColumnValues>(
- column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) {
- return mesh->mpoly[index].loopstart;
+ column_id.name, VArray<int>::ForFunc(polys.size(), [polys](int64_t index) {
+ return polys[index].loopstart;
}));
}
if (STREQ(column_id.name, "Corner Size")) {
return std::make_unique<ColumnValues>(
- column_id.name, VArray<int>::ForFunc(mesh->totpoly, [mesh](int64_t index) {
- return mesh->mpoly[index].totloop;
+ column_id.name, VArray<int>::ForFunc(polys.size(), [polys](int64_t index) {
+ return polys[index].totloop;
}));
}
}
else if (domain_ == ATTR_DOMAIN_CORNER) {
if (STREQ(column_id.name, "Vertex")) {
return std::make_unique<ColumnValues>(
- column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) {
- return mesh->mloop[index].v;
+ column_id.name, VArray<int>::ForFunc(loops.size(), [loops](int64_t index) {
+ return loops[index].v;
}));
}
if (STREQ(column_id.name, "Edge")) {
return std::make_unique<ColumnValues>(
- column_id.name, VArray<int>::ForFunc(mesh->totloop, [mesh](int64_t index) {
- return mesh->mloop[index].e;
+ column_id.name, VArray<int>::ForFunc(loops.size(), [loops](int64_t index) {
+ return loops[index].e;
}));
}
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 8add6886584..2019ff28e33 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -16,6 +16,7 @@
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_global.h"
+#include "BKE_mesh.h"
#include "BKE_object.h"
#include "DEG_depsgraph.h"
@@ -67,9 +68,9 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
if (facemap_data) {
GPU_blend(GPU_BLEND_ALPHA);
- const MVert *mvert = me->mvert;
- const MPoly *mpoly = me->mpoly;
- const MLoop *mloop = me->mloop;
+ const MVert *verts = BKE_mesh_vertices(me);
+ const MPoly *polys = BKE_mesh_polygons(me);
+ const MLoop *loops = BKE_mesh_loops(me);
int mpoly_len = me->totpoly;
int mloop_len = me->totloop;
@@ -95,12 +96,12 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
int i;
if (me->runtime.looptris.array) {
const MLoopTri *mlt = me->runtime.looptris.array;
- for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
+ for (mp = polys, i = 0; i < mpoly_len; i++, mp++) {
if (facemap_data[i] == facemap) {
for (int j = 2; j < mp->totloop; j++) {
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[0]].v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[1]].v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[mloop[mlt->tri[2]].v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[0]].v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[1]].v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[2]].v].co);
vbo_len_used += 3;
mlt++;
}
@@ -112,15 +113,15 @@ void ED_draw_object_facemap(Depsgraph *depsgraph,
}
else {
/* No tessellation data, fan-fill. */
- for (mp = mpoly, i = 0; i < mpoly_len; i++, mp++) {
+ for (mp = polys, i = 0; i < mpoly_len; i++, mp++) {
if (facemap_data[i] == facemap) {
- const MLoop *ml_start = &mloop[mp->loopstart];
+ const MLoop *ml_start = &loops[mp->loopstart];
const MLoop *ml_a = ml_start + 1;
const MLoop *ml_b = ml_start + 2;
for (int j = 2; j < mp->totloop; j++) {
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_start->v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_a->v].co);
- copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), mvert[ml_b->v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_start->v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_a->v].co);
+ copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_b->v].co);
vbo_len_used += 3;
ml_a++;
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 6256eeb9621..4d5068c45ad 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -23,6 +23,7 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_editmesh.h"
+#include "BKE_mesh.h"
#include "BKE_mesh_iterators.h"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
@@ -205,6 +206,7 @@ typedef struct foreachScreenObjectVert_userData {
void (*func)(void *userData, MVert *mv, const float screen_co[2], int index);
void *userData;
ViewContext vc;
+ MVert *verts;
const bool *hide_vert;
eV3DProjTest clip_flag;
} foreachScreenObjectVert_userData;
@@ -266,7 +268,7 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData,
if (data->hide_vert && data->hide_vert[index]) {
return;
}
- struct MVert *mv = &((Mesh *)(data->vc.obact->data))->mvert[index];
+ MVert *mv = &data->verts[index];
float screen_co[2];
@@ -299,6 +301,7 @@ void meshobject_foreachScreenVert(
data.func = func;
data.userData = userData;
data.clip_flag = clip_flag;
+ data.verts = BKE_mesh_vertices_for_write((Mesh *)vc->obact->data);
data.hide_vert = (const bool *)CustomData_get_layer_named(
&me->vdata, CD_PROP_BOOL, ".hide_vert");
diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc
index f757cb45eec..714eff79777 100644
--- a/source/blender/editors/space_view3d/view3d_select.cc
+++ b/source/blender/editors/space_view3d/view3d_select.cc
@@ -334,7 +334,8 @@ static bool edbm_backbuf_check_and_select_verts_obmode(Mesh *me,
EditSelectBuf_Cache *esel,
const eSelectOp sel_op)
{
- MVert *mv = me->mvert;
+ MVert *verts = BKE_mesh_vertices_for_write(me);
+ MVert *mv = verts;
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
@@ -363,22 +364,22 @@ static bool edbm_backbuf_check_and_select_faces_obmode(Mesh *me,
EditSelectBuf_Cache *esel,
const eSelectOp sel_op)
{
- MPoly *mpoly = me->mpoly;
+ MPoly *polygons = BKE_mesh_polygons_for_write(me);
bool changed = false;
const BLI_bitmap *select_bitmap = esel->select_bitmap;
- if (mpoly) {
+ if (polygons) {
const bool *hide_poly = (const bool *)CustomData_get_layer_named(
- &me->pdata, CD_PROP_BOOL, ".hide_poly");
+ &me->vdata, CD_PROP_BOOL, ".hide_poly");
- for (int index = 0; index < me->totpoly; index++, mpoly++) {
+ for (int index = 0; index < me->totpoly; index++) {
if (!(hide_poly && hide_poly[index])) {
- const bool is_select = mpoly->flag & ME_FACE_SEL;
+ const bool is_select = polygons[index].flag & ME_FACE_SEL;
const bool is_inside = BLI_BITMAP_TEST_BOOL(select_bitmap, index);
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
if (sel_op_result != -1) {
- SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL);
+ SET_FLAG_FROM_TEST(polygons[index].flag, sel_op_result, ME_FACE_SEL);
changed = true;
}
}
@@ -2813,13 +2814,15 @@ static bool ed_wpaint_vertex_select_pick(bContext *C,
Mesh *me = static_cast<Mesh *>(obact->data); /* already checked for nullptr */
uint index = 0;
+ MVert *verts = BKE_mesh_vertices_for_write(me);
+
MVert *mv;
bool changed = false;
bool found = ED_mesh_pick_vert(C, obact, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, use_zbuf, &index);
if (params->sel_op == SEL_OP_SET) {
- if ((found && params->select_passthrough) && (me->mvert[index].flag & SELECT)) {
+ if ((found && params->select_passthrough) && (verts[index].flag & SELECT)) {
found = false;
}
else if (found || params->deselect_all) {
@@ -2829,7 +2832,7 @@ static bool ed_wpaint_vertex_select_pick(bContext *C,
}
if (found) {
- mv = &me->mvert[index];
+ mv = &verts[index];
switch (params->sel_op) {
case SEL_OP_ADD: {
mv->flag |= SELECT;
diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc
index 6808f06bdd3..e4c152bc630 100644
--- a/source/blender/editors/transform/transform_snap_object.cc
+++ b/source/blender/editors/transform/transform_snap_object.cc
@@ -47,6 +47,7 @@
using blender::float3;
using blender::float4x4;
using blender::Map;
+using blender::Span;
/* -------------------------------------------------------------------- */
/** \name Internal Data Types
@@ -243,6 +244,11 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx,
SnapData_Mesh *sod;
bool init = false;
+ const Span<MVert> verts = me_eval->vertices();
+ const Span<MEdge> edges = me_eval->edges();
+ const Span<MPoly> polys = me_eval->polygons();
+ const Span<MLoop> loops = me_eval->loops();
+
if (std::unique_ptr<SnapData_Mesh> *sod_p = sctx->mesh_caches.lookup_ptr(ob_eval)) {
sod = sod_p->get();
bool is_dirty = false;
@@ -264,16 +270,16 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx,
else if (sod->treedata_mesh.looptri != me_eval->runtime.looptris.array) {
is_dirty = true;
}
- else if (sod->treedata_mesh.vert != me_eval->mvert) {
+ else if (sod->treedata_mesh.vert != verts.data()) {
is_dirty = true;
}
- else if (sod->treedata_mesh.loop != me_eval->mloop) {
+ else if (sod->treedata_mesh.loop != loops.data()) {
is_dirty = true;
}
- else if (sod->treedata_mesh.edge != me_eval->medge) {
+ else if (sod->treedata_mesh.edge != edges.data()) {
is_dirty = true;
}
- else if (sod->poly != me_eval->mpoly) {
+ else if (sod->poly != polys.data()) {
is_dirty = true;
}
@@ -303,16 +309,16 @@ static SnapData_Mesh *snap_object_data_mesh_get(SnapObjectContext *sctx,
use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI,
4);
- BLI_assert(sod->treedata_mesh.vert == me_eval->mvert);
- BLI_assert(!me_eval->mvert || sod->treedata_mesh.vert_normals);
- BLI_assert(sod->treedata_mesh.loop == me_eval->mloop);
- BLI_assert(!me_eval->mpoly || sod->treedata_mesh.looptri);
+ BLI_assert(sod->treedata_mesh.vert == verts.data());
+ BLI_assert(!verts.data() || sod->treedata_mesh.vert_normals);
+ BLI_assert(sod->treedata_mesh.loop == loops.data());
+ BLI_assert(!polys.data() || sod->treedata_mesh.looptri);
sod->has_looptris = sod->treedata_mesh.tree != nullptr;
/* Required for snapping with occlusion. */
- sod->treedata_mesh.edge = me_eval->medge;
- sod->poly = me_eval->mpoly;
+ sod->treedata_mesh.edge = edges.data();
+ sod->poly = polys.data();
/* Start assuming that it has each of these element types. */
sod->has_loose_edge = true;