Mesh: Remove unnecessary mesh position copying

Remove unnecessary mesh position copying in the following places:
1. hair dynamics
2. shrinkwrap remesh target project
3. normal projection calculation in shrinkwrap (hidden copying)
4. multires modifier: reshape from object
5. vertex weight proximity modifier remesh

See #103789.

Pull Request: https://projects.blender.org/blender/blender/pulls/108721
This commit is contained in:
Chao Li
2023-06-09 18:38:35 +02:00
committed by Hans Goudey
parent d651ee69bd
commit b3356b1799
4 changed files with 35 additions and 48 deletions
@@ -70,15 +70,8 @@ bool multiresModifier_reshapeFromObject(Depsgraph *depsgraph,
return false;
}
int num_deformed_verts;
float(*deformed_verts)[3] = BKE_mesh_vert_coords_alloc(src_mesh_eval, &num_deformed_verts);
const bool result = multiresModifier_reshapeFromVertcos(
depsgraph, dst, mmd, deformed_verts, num_deformed_verts);
MEM_freeN(deformed_verts);
return result;
return multiresModifier_reshapeFromVertcos(
depsgraph, dst, mmd, BKE_mesh_vert_positions(src_mesh_eval), src_mesh_eval->totvert);
}
/** \} */
@@ -3449,7 +3449,6 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
EffectorWeights *clmd_effweights;
int totpoint;
int totedge;
float(*deformedVerts)[3];
bool realloc_roots;
if (!psys->clmd) {
@@ -3505,12 +3504,14 @@ static void do_hair_dynamics(ParticleSimulationData *sim)
psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
BKE_id_copy_ex(NULL, &psys->hair_in_mesh->id, (ID **)&psys->hair_out_mesh, LIB_ID_COPY_LOCALIZE);
deformedVerts = BKE_mesh_vert_coords_alloc(psys->hair_out_mesh, NULL);
clothModifier_do(
psys->clmd, sim->depsgraph, sim->scene, sim->ob, psys->hair_in_mesh, deformedVerts);
BKE_mesh_vert_coords_apply(psys->hair_out_mesh, deformedVerts);
MEM_freeN(deformedVerts);
clothModifier_do(psys->clmd,
sim->depsgraph,
sim->scene,
sim->ob,
psys->hair_in_mesh,
BKE_mesh_vert_positions_for_write(psys->hair_out_mesh));
BKE_mesh_tag_positions_changed(psys->hair_out_mesh);
/* restore cloth effector weights */
psys->clmd->sim_parms->effector_weights = clmd_effweights;
+7 -12
View File
@@ -513,7 +513,7 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
const float proj_limit_squared = calc->smd->projLimit * calc->smd->projLimit;
float *co = calc->vertexCos[i];
float tmp_co[3], tmp_no[3];
const float *tmp_co, *tmp_no;
float weight = BKE_defvert_array_find_weight_safe(calc->dvert, i, calc->vgroup);
if (calc->invert_vgroup) {
@@ -530,12 +530,12 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata,
/* These coordinates are deformed by vertexCos only for normal projection
* (to get correct normals) for other cases calc->verts contains undeformed coordinates and
* vertexCos should be used */
copy_v3_v3(tmp_co, calc->vert_positions[i]);
copy_v3_v3(tmp_no, calc->vert_normals[i]);
tmp_co = calc->vert_positions[i];
tmp_no = calc->vert_normals[i];
}
else {
copy_v3_v3(tmp_co, co);
copy_v3_v3(tmp_no, proj_axis);
tmp_co = co;
tmp_no = proj_axis;
}
hit->index = -1;
@@ -1568,7 +1568,6 @@ void BKE_shrinkwrap_mesh_nearest_surface_deform(bContext *C, Object *ob_source,
void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object *ob_target)
{
ShrinkwrapModifierData ssmd = {{nullptr}};
int totvert;
ssmd.target = ob_target;
ssmd.shrinkType = MOD_SHRINKWRAP_PROJECT;
@@ -1581,13 +1580,11 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
const float projLimitTolerance = 5.0f;
ssmd.projLimit = target_me->remesh_voxel_size * projLimitTolerance;
float(*vertexCos)[3] = BKE_mesh_vert_coords_alloc(src_me, &totvert);
ShrinkwrapCalcData calc = NULL_ShrinkwrapCalcData;
calc.smd = &ssmd;
calc.numVerts = src_me->totvert;
calc.vertexCos = vertexCos;
calc.vertexCos = BKE_mesh_vert_positions_for_write(src_me);
calc.vert_normals = src_me->vert_normals();
calc.vgroup = -1;
calc.target = target_me;
@@ -1602,7 +1599,5 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object
BKE_shrinkwrap_free_tree(&tree);
}
BKE_mesh_vert_coords_apply(src_me, vertexCos);
MEM_freeN(vertexCos);
BKE_mesh_tag_positions_changed(src_me);
}
@@ -72,7 +72,9 @@
struct Vert2GeomData {
/* Read-only data */
float (*v_cos)[3];
const float (*v_cos)[3];
const int *indices;
const SpaceTransform *loc2trgt;
@@ -106,7 +108,7 @@ static void vert2geom_task_cb_ex(void *__restrict userdata,
int i;
/* Convert the vertex to tree coordinates. */
copy_v3_v3(tmp_co, data->v_cos[iter]);
copy_v3_v3(tmp_co, data->v_cos[data->indices ? data->indices[iter] : iter]);
BLI_space_transform_apply(data->loc2trgt, tmp_co);
for (i = 0; i < ARRAY_SIZE(data->dist); i++) {
@@ -145,7 +147,8 @@ static void vert2geom_task_cb_ex(void *__restrict userdata,
* Find nearest vertex and/or edge and/or face, for each vertex (adapted from shrinkwrap.c).
*/
static void get_vert2geom_distance(int verts_num,
float (*v_cos)[3],
const float (*v_cos)[3],
const int *indices,
float *dist_v,
float *dist_e,
float *dist_f,
@@ -185,6 +188,7 @@ static void get_vert2geom_distance(int verts_num,
}
data.v_cos = v_cos;
data.indices = indices;
data.loc2trgt = loc2trgt;
data.treeData[0] = &treeData_v;
data.treeData[1] = &treeData_e;
@@ -215,8 +219,12 @@ static void get_vert2geom_distance(int verts_num,
* Returns the real distance between a vertex and another reference object.
* Note that it works in final world space (i.e. with constraints etc. applied).
*/
static void get_vert2ob_distance(
int verts_num, float (*v_cos)[3], float *dist, Object *ob, Object *obr)
static void get_vert2ob_distance(int verts_num,
const float (*v_cos)[3],
const int *indices,
float *dist,
Object *ob,
Object *obr)
{
/* Vertex and ref object coordinates. */
float v_wco[3];
@@ -224,7 +232,7 @@ static void get_vert2ob_distance(
while (i-- > 0) {
/* Get world-coordinates of the vertex (constraints and anim included). */
mul_v3_m4v3(v_wco, ob->object_to_world, v_cos[i]);
mul_v3_m4v3(v_wco, ob->object_to_world, v_cos[indices ? indices[i] : i]);
/* Return distance between both coordinates. */
dist[i] = len_v3v3(v_wco, obr->object_to_world[3]);
}
@@ -421,7 +429,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md;
MDeformWeight **dw, **tdw;
float(*v_cos)[3] = nullptr; /* The vertices coordinates. */
const float(*v_cos)[3] = nullptr; /* The vertices coordinates. */
Object *ob = ctx->object;
Object *obr = nullptr; /* Our target object. */
int defgrp_index;
@@ -516,16 +524,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(tidx);
/* Get our vertex coordinates. */
if (index_num != verts_num) {
const float(*tv_cos)[3] = BKE_mesh_vert_positions(mesh);
v_cos = static_cast<float(*)[3]>(MEM_malloc_arrayN(index_num, sizeof(float[3]), __func__));
for (i = 0; i < index_num; i++) {
copy_v3_v3(v_cos[i], tv_cos[indices[i]]);
}
}
else {
v_cos = BKE_mesh_vert_coords_alloc(mesh, nullptr);
}
v_cos = BKE_mesh_vert_positions(mesh);
/* Compute wanted distances. */
if (wmd->proximity_mode == MOD_WVG_PROXIMITY_OBJECT) {
@@ -562,7 +561,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
get_vert2geom_distance(
index_num, v_cos, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
index_num, v_cos, indices, dists_v, dists_e, dists_f, target_mesh, &loc2trgt);
for (i = 0; i < index_num; i++) {
new_w[i] = dists_v ? dists_v[i] : FLT_MAX;
if (dists_e) {
@@ -579,11 +578,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Else, fall back to default obj2vert behavior. */
else {
get_vert2ob_distance(index_num, v_cos, new_w, ob, obr);
get_vert2ob_distance(index_num, v_cos, indices, new_w, ob, obr);
}
}
else {
get_vert2ob_distance(index_num, v_cos, new_w, ob, obr);
get_vert2ob_distance(index_num, v_cos, indices, new_w, ob, obr);
}
}
@@ -632,7 +631,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
MEM_freeN(org_w);
MEM_freeN(new_w);
MEM_freeN(dw);
MEM_freeN(v_cos);
MEM_SAFE_FREE(indices);
#ifdef USE_TIMEIT