Page MenuHome

Crash when modifier "Array-Fit Curve-Relative Offset" nears zero
Closed, ResolvedPublicBUG


System Information
Operating system: Linux-5.5.5-200.fc31.x86_64-x86_64-with-fedora-31-Thirty_One 64 Bits
Graphics card: GeForce RTX 2070/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 440.59

Blender Version
Broken: version: 2.82 (sub 7), branch: master, commit date: 2020-02-12 16:20, hash: rB77d23b0bd76f
Worked: Never (2.8+)

Short description of error
Crash when modifier Array-Fit Curve-Relative Offset nears zero

Exact steps for others to reproduce the error
Add object
Add curve
Add "Array" modifier to object
Choose "Fit Curve"
Select curve as "Fit Curve, Curve"
Leave Y&Z "Relative Offset" at zero
Reduce X "Relative Offset" slowly to near zero

Event Timeline

Richard Antalik (ISS) changed the task status from Needs Triage to Confirmed.Apr 1 2020, 5:43 PM

Fixing this specific case is relatively easy. But it's quite hard to find a general rule that works for all the use cases. The issue is that when the relative offset becomes too small, the amount of objects increases a lot. When it says 0.0 in the ui, it's actually some number very close to zero due to floating point precision issues. There is already a check for that in place, but it does not work here, because the objects are so large. Also the number of vertices overflows here.

This is a potential fix, but it will fail in other cases as well most likely...

diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index ff5bf3d0ee4..b6f25bb9fb6 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;
@@ -478,10 +477,15 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
   if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) {
     float dist = len_v3(offset[3]);
+    const float eps = 1e-6f;
     if (dist > eps) {
       /* this gives length = first copy start to last copy end
        * add a tiny offset for floating point rounding errors */
-      count = (length + eps) / dist + 1;
+      float count_f = (length + eps) / dist + 1;
+      if (count_f > 10000000) {
+        count_f = 1.0f;
+      }
+      count = (int)count_f;
     else {
       /* if the offset has no translation, just make one copy */
Bastien Montagne (mont29) changed the subtype of this task from "Report" to "Bug".

@Jacques Lucke (JacquesLucke) Think this is the good direction, but will rather check on (estimated) total amount of generated vertices instead, that should be more robust in general cases... Also will add an error message when falling back to a single copy, so that user knows what is hapening.