Fix #136237: Limit max material index to MAXMAT

Due to !133498 layers containing incorrect material indices could lead to generating
to many GPU resources crashing Blender. As there is a maximum number of material slots
we can limit it.

This is just a safeguard for incorrect values in material_index attribute layer. Working with
this material index attributes should automatically limit, but I leave that to the modeling
module.

Pull Request: https://projects.blender.org/blender/blender/pulls/136302
This commit is contained in:
Jeroen Bakker
2025-03-31 13:24:39 +02:00
parent e5987569d3
commit ee8e993181
5 changed files with 18 additions and 3 deletions

View File

@@ -309,7 +309,11 @@ class CurvesGeometry : public ::CurvesGeometry {
void count_memory(MemoryCounter &memory) const;
/** Get the largest material index used by the curves or `nullopt` if there are none. */
/**
* Get the largest material index used by the geometry or `nullopt` if there are none.
* The returned value is clamped between 0 and MAXMAT even if the stored material indices may be
* out of that range.
*/
std::optional<int> material_index_max() const;
private:

View File

@@ -5484,7 +5484,7 @@ std::optional<int> Curve::material_index_max() const
LISTBASE_FOREACH (const Nurb *, nurb, &this->nurb) {
max_index = std::max<int>(max_index, nurb->mat_nr);
}
return max_index;
return clamp_i(max_index, 0, MAXMAT);
}
/* **** Depsgraph evaluation **** */

View File

@@ -23,6 +23,7 @@
#include "BLO_read_write.hh"
#include "DNA_curves_types.h"
#include "DNA_material_types.h"
#include "BKE_attribute.hh"
#include "BKE_attribute_math.hh"
@@ -1245,6 +1246,9 @@ std::optional<int> CurvesGeometry::material_index_max() const
this->attributes()
.lookup_or_default<int>("material_index", blender::bke::AttrDomain::Curve, 0)
.varray);
if (r_max_material_index.has_value()) {
r_max_material_index = std::clamp(*r_max_material_index, 0, MAXMAT);
}
});
return this->runtime->max_material_index_cache.data();
}

View File

@@ -1391,6 +1391,9 @@ std::optional<int> Mesh::material_index_max() const
this->attributes()
.lookup_or_default<int>("material_index", blender::bke::AttrDomain::Face, 0)
.varray);
if (value.has_value()) {
value = std::clamp(*value, 0, MAXMAT);
}
});
return this->runtime->max_material_index.data();
}

View File

@@ -351,10 +351,14 @@ std::optional<int> PointCloud::material_index_max() const
if (this->totpoint == 0) {
return std::nullopt;
}
return blender::bounds::max<int>(
std::optional<int> max_material_index = blender::bounds::max<int>(
this->attributes()
.lookup_or_default<int>("material_index", blender::bke::AttrDomain::Point, 0)
.varray);
if (max_material_index.has_value()) {
max_material_index = std::clamp(*max_material_index, 0, MAXMAT);
}
return max_material_index;
}
void PointCloud::count_memory(blender::MemoryCounter &memory) const