diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 07b6b0f22ed..05a2018a2f5 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -27,6 +27,7 @@ #include "BLI_math_geom.h" #include "BLI_math_matrix.h" #include "BLI_math_vector_types.hh" +#include "BLI_span.hh" #include "BLI_task.h" #include "BLI_task.hh" #include "BLI_utildefines.h" @@ -71,6 +72,7 @@ using blender::float3; using blender::IndexRange; +using blender::MutableSpan; using blender::Span; using blender::VArray; using blender::bke::GeometryOwnershipType; @@ -400,47 +402,51 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer) return mesh; } +static MutableSpan orco_coord_layer_ensure(Mesh *mesh, const eCustomDataType layer) +{ + void *data = CustomData_get_layer_for_write(&mesh->vert_data, layer, mesh->totvert); + if (!data) { + data = CustomData_add_layer(&mesh->vert_data, layer, CD_CONSTRUCT, mesh->totvert); + } + return MutableSpan(reinterpret_cast(data), mesh->totvert); +} + static void add_orco_mesh( Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orco, const eCustomDataType layer) { - float(*orco)[3], (*layerorco)[3]; - int totvert, free; - - totvert = mesh->totvert; + const int totvert = mesh->totvert; + MutableSpan layer_orco; if (mesh_orco) { - free = 1; + layer_orco = orco_coord_layer_ensure(mesh, layer); if (mesh_orco->totvert == totvert) { - orco = BKE_mesh_vert_coords_alloc(mesh_orco, nullptr); + layer_orco.copy_from(mesh_orco->vert_positions()); } else { - orco = BKE_mesh_vert_coords_alloc(mesh, nullptr); + layer_orco.copy_from(mesh->vert_positions()); } } else { /* TODO(sybren): totvert should potentially change here, as ob->data * or em may have a different number of vertices than dm. */ - orco = get_orco_coords(ob, em, layer, &free); - } - - if (orco) { - if (layer == CD_ORCO) { - BKE_mesh_orco_verts_transform((Mesh *)ob->data, orco, totvert, 0); + int free = 0; + float(*orco)[3] = get_orco_coords(ob, em, layer, &free); + if (orco) { + layer_orco = orco_coord_layer_ensure(mesh, layer); + layer_orco.copy_from(Span(reinterpret_cast(orco), totvert)); } - - layerorco = (float(*)[3])CustomData_get_layer_for_write( - &mesh->vert_data, layer, mesh->totvert); - if (!layerorco) { - layerorco = (float(*)[3])CustomData_add_layer( - &mesh->vert_data, eCustomDataType(layer), CD_SET_DEFAULT, mesh->totvert); - } - - memcpy(layerorco, orco, sizeof(float[3]) * totvert); if (free) { MEM_freeN(orco); } } + + if (!layer_orco.is_empty()) { + if (layer == CD_ORCO) { + BKE_mesh_orco_verts_transform( + (Mesh *)ob->data, reinterpret_cast(layer_orco.data()), totvert, 0); + } + } } static bool mesh_has_modifier_final_normals(const Mesh *mesh_input, @@ -1129,7 +1135,7 @@ static void editbmesh_calc_modifier_final_normals_or_defer( editbmesh_calc_modifier_final_normals(mesh_final, final_datamask); } -static blender::MutableSpan mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh) +static MutableSpan mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh) { switch (mesh->runtime->wrapper_type) { case ME_WRAPPER_TYPE_BMESH: diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index b86c37c1401..b14594ba5da 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -779,8 +779,9 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, Mesh *mesh_temp = reinterpret_cast( BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE)); - int numVerts = 0; - float(*deformedVerts)[3] = nullptr; + const int numVerts = mesh_temp->totvert; + float(*deformedVerts)[3] = reinterpret_cast( + mesh_temp->vert_positions_for_write().data()); if (use_virtual_modifiers) { VirtualModifierData virtual_modifier_data; @@ -799,31 +800,21 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, continue; } - if (deformedVerts == nullptr) { - deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); - } mti_virt->deform_verts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts); } } Mesh *result = nullptr; if (mti->type == eModifierTypeType_OnlyDeform) { - if (deformedVerts == nullptr) { - deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); - } result = mesh_temp; mti->deform_verts(md_eval, &mectx, result, deformedVerts, numVerts); - BKE_mesh_vert_coords_apply(result, deformedVerts); + BKE_mesh_tag_positions_changed(result); if (build_shapekey_layers) { add_shapekey_layers(*result, *me); } } else { - if (deformedVerts != nullptr) { - BKE_mesh_vert_coords_apply(mesh_temp, deformedVerts); - } - if (build_shapekey_layers) { add_shapekey_layers(*mesh_temp, *me); } @@ -846,10 +837,6 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, } } - if (deformedVerts != nullptr) { - MEM_freeN(deformedVerts); - } - return result; } diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index b60bee7241f..1c8aa2db953 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -98,8 +98,6 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, Mesh *mesh) { using namespace blender; - float(*coords)[3], (*co)[3]; - int i, verts_num; Projector projectors[MOD_UVPROJECT_MAXPROJECTORS]; int projectors_num = 0; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; @@ -109,7 +107,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, float scay = umd->scaley ? umd->scaley : 1.0f; int free_uci = 0; - for (i = 0; i < umd->projectors_num; i++) { + for (int i = 0; i < umd->projectors_num; i++) { if (umd->projectors[i] != nullptr) { projectors[projectors_num++].ob = umd->projectors[i]; } @@ -128,7 +126,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, CustomData_validate_layer_name(&mesh->loop_data, CD_PROP_FLOAT2, umd->uvlayer_name, uvname); /* calculate a projection matrix and normal for each projector */ - for (i = 0; i < projectors_num; i++) { + for (int i = 0; i < projectors_num; i++) { float tmpmat[4][4]; float offsetmat[4][4]; Camera *cam = nullptr; @@ -182,30 +180,30 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, mul_mat3_m4_v3(projectors[i].ob->object_to_world, projectors[i].normal); } - const blender::Span positions = mesh->vert_positions(); - const blender::OffsetIndices faces = mesh->faces(); + const Span positions = mesh->vert_positions(); + const OffsetIndices faces = mesh->faces(); const Span corner_verts = mesh->corner_verts(); float(*mloop_uv)[2] = static_cast(CustomData_get_layer_named_for_write( &mesh->loop_data, CD_PROP_FLOAT2, uvname, corner_verts.size())); - coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num); + Array coords(positions.size()); /* Convert coords to world-space. */ - for (i = 0, co = coords; i < verts_num; i++, co++) { - mul_m4_v3(ob->object_to_world, *co); + for (int64_t i = 0; i < positions.size(); i++) { + mul_v3_m4v3(coords[i], ob->object_to_world, positions[i]); } /* if only one projector, project coords to UVs */ if (projectors_num == 1 && projectors[0].uci == nullptr) { - for (i = 0, co = coords; i < verts_num; i++, co++) { - mul_project_m4_v3(projectors[0].projmat, *co); + for (int64_t i = 0; i < coords.size(); i++) { + mul_project_m4_v3(projectors[0].projmat, coords[i]); } } /* apply coords as UVs */ for (const int i : faces.index_range()) { - const blender::IndexRange face = faces[i]; + const IndexRange face = faces[i]; if (projectors_num == 1) { if (projectors[0].uci) { for (const int corner : face) { @@ -229,8 +227,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, float best_dot; /* get the untransformed face normal */ - const blender::float3 face_no = blender::bke::mesh::face_normal_calc( - positions, corner_verts.slice(face)); + const float3 face_no = blender::bke::mesh::face_normal_calc(positions, + corner_verts.slice(face)); /* find the projector which the face points at most directly * (projector normal with largest dot product is best) @@ -262,8 +260,6 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, } } - MEM_freeN(coords); - if (free_uci) { int j; for (j = 0; j < projectors_num; j++) {