[Bf-blender-cvs] [6dcda1b9aaa] master: Screw Modifier: avoid unnecessary normal calculation

Campbell Barton noreply at git.blender.org
Thu May 12 11:57:42 CEST 2022


Commit: 6dcda1b9aaafc0bd03889fa5281bb27ee487d36f
Author: Campbell Barton
Date:   Thu May 12 19:51:56 2022 +1000
Branches: master
https://developer.blender.org/rB6dcda1b9aaafc0bd03889fa5281bb27ee487d36f

Screw Modifier: avoid unnecessary normal calculation

Normals were being allocated, calculated & freed when the spin modified
merged was enabled.

===================================================================

M	source/blender/modifiers/intern/MOD_screw.c

===================================================================

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,



More information about the Bf-blender-cvs mailing list