Array modifier: limit maximum amount of generated geometry.

Fixes T75278: Crash when modifier "Array-Fit Curve-Relative Offset"
nears zero.
This commit is contained in:
Bastien Montagne 2020-04-23 14:47:06 +02:00
parent 3a0af215b9
commit a0652430d0
Notes: blender-bot 2023-02-13 23:00:23 +01:00
Referenced by issue #75278, Crash when modifier "Array-Fit Curve-Relative Offset" nears zero
1 changed files with 33 additions and 3 deletions

View File

@ -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,20 +472,51 @@ 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) {