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_geom.h"
|
||||||
#include "BLI_math_matrix.h"
|
#include "BLI_math_matrix.h"
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
#include "BLI_span.hh"
|
||||||
#include "BLI_task.h"
|
#include "BLI_task.h"
|
||||||
#include "BLI_task.hh"
|
#include "BLI_task.hh"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
@ -71,6 +72,7 @@
|
||||||
|
|
||||||
using blender::float3;
|
using blender::float3;
|
||||||
using blender::IndexRange;
|
using blender::IndexRange;
|
||||||
|
using blender::MutableSpan;
|
||||||
using blender::Span;
|
using blender::Span;
|
||||||
using blender::VArray;
|
using blender::VArray;
|
||||||
using blender::bke::GeometryOwnershipType;
|
using blender::bke::GeometryOwnershipType;
|
||||||
|
@ -400,47 +402,51 @@ static Mesh *create_orco_mesh(Object *ob, Mesh *me, BMEditMesh *em, int layer)
|
||||||
return mesh;
|
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(
|
static void add_orco_mesh(
|
||||||
Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orco, const eCustomDataType layer)
|
Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orco, const eCustomDataType layer)
|
||||||
{
|
{
|
||||||
float(*orco)[3], (*layerorco)[3];
|
const int totvert = mesh->totvert;
|
||||||
int totvert, free;
|
|
||||||
|
|
||||||
totvert = mesh->totvert;
|
|
||||||
|
|
||||||
|
MutableSpan<float3> layer_orco;
|
||||||
if (mesh_orco) {
|
if (mesh_orco) {
|
||||||
free = 1;
|
layer_orco = orco_coord_layer_ensure(mesh, layer);
|
||||||
|
|
||||||
if (mesh_orco->totvert == totvert) {
|
if (mesh_orco->totvert == totvert) {
|
||||||
orco = BKE_mesh_vert_coords_alloc(mesh_orco, nullptr);
|
layer_orco.copy_from(mesh_orco->vert_positions());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
orco = BKE_mesh_vert_coords_alloc(mesh, nullptr);
|
layer_orco.copy_from(mesh->vert_positions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* TODO(sybren): totvert should potentially change here, as ob->data
|
/* TODO(sybren): totvert should potentially change here, as ob->data
|
||||||
* or em may have a different number of vertices than dm. */
|
* or em may have a different number of vertices than dm. */
|
||||||
orco = get_orco_coords(ob, em, layer, &free);
|
int free = 0;
|
||||||
}
|
float(*orco)[3] = get_orco_coords(ob, em, layer, &free);
|
||||||
|
|
||||||
if (orco) {
|
if (orco) {
|
||||||
if (layer == CD_ORCO) {
|
layer_orco = orco_coord_layer_ensure(mesh, layer);
|
||||||
BKE_mesh_orco_verts_transform((Mesh *)ob->data, orco, totvert, 0);
|
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) {
|
if (free) {
|
||||||
MEM_freeN(orco);
|
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,
|
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);
|
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) {
|
switch (mesh->runtime->wrapper_type) {
|
||||||
case ME_WRAPPER_TYPE_BMESH:
|
case ME_WRAPPER_TYPE_BMESH:
|
||||||
|
|
|
@ -779,8 +779,9 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph,
|
||||||
|
|
||||||
Mesh *mesh_temp = reinterpret_cast<Mesh *>(
|
Mesh *mesh_temp = reinterpret_cast<Mesh *>(
|
||||||
BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE));
|
BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE));
|
||||||
int numVerts = 0;
|
const int numVerts = mesh_temp->totvert;
|
||||||
float(*deformedVerts)[3] = nullptr;
|
float(*deformedVerts)[3] = reinterpret_cast<float(*)[3]>(
|
||||||
|
mesh_temp->vert_positions_for_write().data());
|
||||||
|
|
||||||
if (use_virtual_modifiers) {
|
if (use_virtual_modifiers) {
|
||||||
VirtualModifierData virtual_modifier_data;
|
VirtualModifierData virtual_modifier_data;
|
||||||
|
@ -799,31 +800,21 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deformedVerts == nullptr) {
|
|
||||||
deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts);
|
|
||||||
}
|
|
||||||
mti_virt->deform_verts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts);
|
mti_virt->deform_verts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh *result = nullptr;
|
Mesh *result = nullptr;
|
||||||
if (mti->type == eModifierTypeType_OnlyDeform) {
|
if (mti->type == eModifierTypeType_OnlyDeform) {
|
||||||
if (deformedVerts == nullptr) {
|
|
||||||
deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts);
|
|
||||||
}
|
|
||||||
result = mesh_temp;
|
result = mesh_temp;
|
||||||
mti->deform_verts(md_eval, &mectx, result, deformedVerts, numVerts);
|
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) {
|
if (build_shapekey_layers) {
|
||||||
add_shapekey_layers(*result, *me);
|
add_shapekey_layers(*result, *me);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (deformedVerts != nullptr) {
|
|
||||||
BKE_mesh_vert_coords_apply(mesh_temp, deformedVerts);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (build_shapekey_layers) {
|
if (build_shapekey_layers) {
|
||||||
add_shapekey_layers(*mesh_temp, *me);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,8 +98,6 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
||||||
Mesh *mesh)
|
Mesh *mesh)
|
||||||
{
|
{
|
||||||
using namespace blender;
|
using namespace blender;
|
||||||
float(*coords)[3], (*co)[3];
|
|
||||||
int i, verts_num;
|
|
||||||
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
|
Projector projectors[MOD_UVPROJECT_MAXPROJECTORS];
|
||||||
int projectors_num = 0;
|
int projectors_num = 0;
|
||||||
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
|
char uvname[MAX_CUSTOMDATA_LAYER_NAME];
|
||||||
|
@ -109,7 +107,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
||||||
float scay = umd->scaley ? umd->scaley : 1.0f;
|
float scay = umd->scaley ? umd->scaley : 1.0f;
|
||||||
int free_uci = 0;
|
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) {
|
if (umd->projectors[i] != nullptr) {
|
||||||
projectors[projectors_num++].ob = umd->projectors[i];
|
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);
|
CustomData_validate_layer_name(&mesh->loop_data, CD_PROP_FLOAT2, umd->uvlayer_name, uvname);
|
||||||
|
|
||||||
/* calculate a projection matrix and normal for each projector */
|
/* 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 tmpmat[4][4];
|
||||||
float offsetmat[4][4];
|
float offsetmat[4][4];
|
||||||
Camera *cam = nullptr;
|
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);
|
mul_mat3_m4_v3(projectors[i].ob->object_to_world, projectors[i].normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
const blender::Span<blender::float3> positions = mesh->vert_positions();
|
const Span<float3> positions = mesh->vert_positions();
|
||||||
const blender::OffsetIndices faces = mesh->faces();
|
const OffsetIndices faces = mesh->faces();
|
||||||
const Span<int> corner_verts = mesh->corner_verts();
|
const Span<int> corner_verts = mesh->corner_verts();
|
||||||
|
|
||||||
float(*mloop_uv)[2] = static_cast<float(*)[2]>(CustomData_get_layer_named_for_write(
|
float(*mloop_uv)[2] = static_cast<float(*)[2]>(CustomData_get_layer_named_for_write(
|
||||||
&mesh->loop_data, CD_PROP_FLOAT2, uvname, corner_verts.size()));
|
&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. */
|
/* Convert coords to world-space. */
|
||||||
for (i = 0, co = coords; i < verts_num; i++, co++) {
|
for (int64_t i = 0; i < positions.size(); i++) {
|
||||||
mul_m4_v3(ob->object_to_world, *co);
|
mul_v3_m4v3(coords[i], ob->object_to_world, positions[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if only one projector, project coords to UVs */
|
/* if only one projector, project coords to UVs */
|
||||||
if (projectors_num == 1 && projectors[0].uci == nullptr) {
|
if (projectors_num == 1 && projectors[0].uci == nullptr) {
|
||||||
for (i = 0, co = coords; i < verts_num; i++, co++) {
|
for (int64_t i = 0; i < coords.size(); i++) {
|
||||||
mul_project_m4_v3(projectors[0].projmat, *co);
|
mul_project_m4_v3(projectors[0].projmat, coords[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply coords as UVs */
|
/* apply coords as UVs */
|
||||||
for (const int i : faces.index_range()) {
|
for (const int i : faces.index_range()) {
|
||||||
const blender::IndexRange face = faces[i];
|
const IndexRange face = faces[i];
|
||||||
if (projectors_num == 1) {
|
if (projectors_num == 1) {
|
||||||
if (projectors[0].uci) {
|
if (projectors[0].uci) {
|
||||||
for (const int corner : face) {
|
for (const int corner : face) {
|
||||||
|
@ -229,8 +227,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
||||||
float best_dot;
|
float best_dot;
|
||||||
|
|
||||||
/* get the untransformed face normal */
|
/* get the untransformed face normal */
|
||||||
const blender::float3 face_no = blender::bke::mesh::face_normal_calc(
|
const float3 face_no = blender::bke::mesh::face_normal_calc(positions,
|
||||||
positions, corner_verts.slice(face));
|
corner_verts.slice(face));
|
||||||
|
|
||||||
/* find the projector which the face points at most directly
|
/* find the projector which the face points at most directly
|
||||||
* (projector normal with largest dot product is best)
|
* (projector normal with largest dot product is best)
|
||||||
|
@ -262,8 +260,6 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MEM_freeN(coords);
|
|
||||||
|
|
||||||
if (free_uci) {
|
if (free_uci) {
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < projectors_num; j++) {
|
for (j = 0; j < projectors_num; j++) {
|
||||||
|
|
Loading…
Reference in New Issue