From 6dcda1b9aaafc0bd03889fa5281bb27ee487d36f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 May 2022 19:51:56 +1000 Subject: Screw Modifier: avoid unnecessary normal calculation Normals were being allocated, calculated & freed when the spin modified merged was enabled. --- source/blender/modifiers/intern/MOD_screw.c | 125 +++++++++++++++------------- 1 file changed, 68 insertions(+), 57 deletions(-) (limited to 'source/blender/modifiers') diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 2082d9f3bba..6642eecd33f 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -375,6 +375,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); } + /* The `screw_ofs` cannot change from now on. */ + const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f); + /* Only calculate normals if `do_remove_doubles` since removing doubles frees the normals. */ + const bool do_normal_create = (ltmd->flag & MOD_SCREW_NORMAL_CALC) && + (do_remove_doubles == false); + result = BKE_mesh_new_nomain_from_template( mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); @@ -383,7 +389,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * medge_orig = mesh->medge; mvert_new = result->mvert; - float(*vert_normals_new)[3] = BKE_mesh_vertex_normals_for_write(result); mpoly_new = result->mpoly; mloop_new = result->mloop; medge_new = result->medge; @@ -472,7 +477,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } + float(*vert_normals_new)[3] = do_normal_create ? BKE_mesh_vertex_normals_for_write(result) : + NULL; + if (ltmd->flag & MOD_SCREW_NORMAL_CALC) { + /* * Normal Calculation (for face flipping) * Sort edge verts for correct face flipping @@ -766,68 +775,69 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * * calculate vertex normals that can be propagated on lathing * use edge connectivity work this out */ - if (SV_IS_VALID(vc->v[0])) { - if (SV_IS_VALID(vc->v[1])) { - /* 2 edges connected. */ - /* make 2 connecting vert locations relative to the middle vert */ - sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); - sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co); - /* normalize so both edges have the same influence, no matter their length */ - normalize_v3(tmp_vec1); - normalize_v3(tmp_vec2); - - /* vc_no_tmp1 - this line is the average direction of both connecting edges - * - * Use the edge order to make the subtraction, flip the normal the right way - * edge should be there but check just in case... */ - if (vc->e[0]->v1 == i) { - sub_v3_v3(tmp_vec1, tmp_vec2); - } - else { - sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1); - } - } - else { - /* only 1 edge connected - same as above except - * don't need to average edge direction */ - if (vc->e[0]->v2 == i) { - sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); + if (do_normal_create) { + if (SV_IS_VALID(vc->v[0])) { + if (SV_IS_VALID(vc->v[1])) { + /* 2 edges connected. */ + /* make 2 connecting vert locations relative to the middle vert */ + sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + sub_v3_v3v3(tmp_vec2, mvert_new[vc->v[1]].co, mvert_new[i].co); + /* normalize so both edges have the same influence, no matter their length */ + normalize_v3(tmp_vec1); + normalize_v3(tmp_vec2); + + /* vc_no_tmp1 - this line is the average direction of both connecting edges + * + * Use the edge order to make the subtraction, flip the normal the right way + * edge should be there but check just in case... */ + if (vc->e[0]->v1 == i) { + sub_v3_v3(tmp_vec1, tmp_vec2); + } + else { + sub_v3_v3v3(tmp_vec1, tmp_vec2, tmp_vec1); + } } else { - sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + /* only 1 edge connected - same as above except + * don't need to average edge direction */ + if (vc->e[0]->v2 == i) { + sub_v3_v3v3(tmp_vec1, mvert_new[i].co, mvert_new[vc->v[0]].co); + } + else { + sub_v3_v3v3(tmp_vec1, mvert_new[vc->v[0]].co, mvert_new[i].co); + } } - } - /* tmp_vec2 - is a line 90d from the pivot to the vec - * This is used so the resulting normal points directly away from the middle */ - cross_v3_v3v3(tmp_vec2, axis_vec, vc->co); + /* tmp_vec2 - is a line 90d from the pivot to the vec + * This is used so the resulting normal points directly away from the middle */ + cross_v3_v3v3(tmp_vec2, axis_vec, vc->co); - if (UNLIKELY(is_zero_v3(tmp_vec2))) { - /* we're _on_ the axis, so copy it based on our winding */ - if (vc->e[0]->v2 == i) { - negate_v3_v3(vc->no, axis_vec); + if (UNLIKELY(is_zero_v3(tmp_vec2))) { + /* we're _on_ the axis, so copy it based on our winding */ + if (vc->e[0]->v2 == i) { + negate_v3_v3(vc->no, axis_vec); + } + else { + copy_v3_v3(vc->no, axis_vec); + } } else { - copy_v3_v3(vc->no, axis_vec); + /* edge average vector and right angle to the pivot make the normal */ + cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2); } } else { - /* edge average vector and right angle to the pivot make the normal */ - cross_v3_v3v3(vc->no, tmp_vec1, tmp_vec2); + copy_v3_v3(vc->no, vc->co); } - } - else { - copy_v3_v3(vc->no, vc->co); - } - - /* we won't be looping on this data again so copy normals here */ - if ((angle < 0.0f) != do_flip) { - negate_v3(vc->no); - } - normalize_v3(vc->no); - copy_v3_v3(vert_normals_new[i], vc->no); + /* we won't be looping on this data again so copy normals here */ + if ((angle < 0.0f) != do_flip) { + negate_v3(vc->no); + } + normalize_v3(vc->no); + copy_v3_v3(vert_normals_new[i], vc->no); + } /* Done with normals */ } } @@ -846,7 +856,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * for (step = 1; step < step_tot; step++) { const uint varray_stride = totvert * step; float step_angle; - float nor_tx[3]; float mat[4][4]; /* Rotation Matrix */ step_angle = (angle / (float)(step_tot - (!close))) * (float)step; @@ -872,10 +881,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { /* set normal */ if (vert_connect) { - mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no); - - /* set the normal now its transformed */ - copy_v3_v3(vert_normals_new[mv_new - mvert_new], nor_tx); + if (do_normal_create) { + /* set the normal now its transformed */ + float nor_tx[3]; + mul_v3_m3v3(nor_tx, mat3, vert_connect[j].no); + copy_v3_v3(vert_normals_new[mv_new - mvert_new], nor_tx); + } } /* set location */ @@ -1118,11 +1129,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_freeN(vert_loop_map); } - if ((ltmd->flag & MOD_SCREW_NORMAL_CALC)) { + if (do_normal_create) { BKE_mesh_vertex_normals_clear_dirty(result); } - if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) { + if (do_remove_doubles) { result = mesh_remove_doubles_on_axis(result, mvert_new, totvert, -- cgit v1.2.3