Cleanup: Reduce unnecessary mesh position copying

Continuation of #103789 to remove/reduce the copying of mesh position
data.

Pull Request: https://projects.blender.org/blender/blender/pulls/111313
This commit is contained in:
Jesse Yurkovich 2023-08-22 03:51:53 +02:00 committed by Jesse Yurkovich
parent d45f47a809
commit f30ac938de
3 changed files with 45 additions and 56 deletions

View File

@ -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<float3> 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<float3 *>(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<float3> 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<float3>(reinterpret_cast<float3 *>(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<float(*)[3]>(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<float3> mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh)
static MutableSpan<float3> mesh_wrapper_vert_coords_ensure_for_write(Mesh *mesh)
{
switch (mesh->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_BMESH:

View File

@ -779,8 +779,9 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph,
Mesh *mesh_temp = reinterpret_cast<Mesh *>(
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<float(*)[3]>(
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;
}

View File

@ -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<blender::float3> positions = mesh->vert_positions();
const blender::OffsetIndices faces = mesh->faces();
const Span<float3> positions = mesh->vert_positions();
const OffsetIndices faces = mesh->faces();
const Span<int> corner_verts = mesh->corner_verts();
float(*mloop_uv)[2] = static_cast<float(*)[2]>(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<float3> 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++) {