[Bf-blender-cvs] [a0652430d0f] blender-v2.83-release: Array modifier: limit maximum amount of generated geometry.

Bastien Montagne noreply at git.blender.org
Thu Apr 23 14:48:54 CEST 2020


Commit: a0652430d0f824adb26de9d2ae22f80fec721f4e
Author: Bastien Montagne
Date:   Thu Apr 23 14:47:06 2020 +0200
Branches: blender-v2.83-release
https://developer.blender.org/rBa0652430d0f824adb26de9d2ae22f80fec721f4e

Array modifier: limit maximum amount of generated geometry.

Fixes T75278: Crash when modifier "Array-Fit Curve-Relative Offset"
nears zero.

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

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

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

diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index ff5bf3d0ee4..bad1d7d3cf9 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -353,7 +353,6 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
                                    const ModifierEvalContext *ctx,
                                    Mesh *mesh)
 {
-  const float eps = 1e-6f;
   const MVert *src_mvert;
   MVert *mv, *mv_prev, *result_dm_verts;
 
@@ -473,21 +472,52 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
     }
   }
 
+  /* About 67 million vertices max seems a decent limit for now. */
+  const size_t max_num_vertices = 1 << 26;
+
   /* calculate the maximum number of copies which will fit within the
    * prescribed length */
   if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) {
+    const float float_epsilon = 1e-6f;
+    bool offset_is_too_small = false;
     float dist = len_v3(offset[3]);
 
-    if (dist > eps) {
+    if (dist > float_epsilon) {
       /* this gives length = first copy start to last copy end
        * add a tiny offset for floating point rounding errors */
-      count = (length + eps) / dist + 1;
+      count = (length + float_epsilon) / dist + 1;
+
+      /* Ensure we keep things to a reasonable level, in terms of rough total amount of generated
+       * vertices.
+       */
+      if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts +
+           (size_t)end_cap_nverts) > max_num_vertices) {
+        count = 1;
+        offset_is_too_small = true;
+      }
     }
     else {
       /* if the offset has no translation, just make one copy */
       count = 1;
+      offset_is_too_small = true;
+    }
+
+    if (offset_is_too_small) {
+      modifier_setError(
+          &amd->modifier,
+          "The offset is too small, we cannot generate the amount of geometry it would require");
     }
   }
+  /* Ensure we keep things to a reasonable level, in terms of rough total amount of generated
+   * vertices.
+   */
+  else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts +
+            (size_t)end_cap_nverts) > max_num_vertices) {
+    count = 1;
+    modifier_setError(&amd->modifier,
+                      "The amount of copies is too high, we cannot generate the amount of "
+                      "geometry it would require");
+  }
 
   if (count < 1) {
     count = 1;



More information about the Bf-blender-cvs mailing list