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:
parent
d45f47a809
commit
f30ac938de
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++) {
|
||||
|
|
Loading…
Reference in New Issue