Fix: Geometry Nodes: Sample curve crash with invalid curve indices #110099

Closed
Iliya Katushenock wants to merge 3 commits from mod_moder:tmp_fix_sample_curves_crash into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
1 changed files with 30 additions and 24 deletions

View File

@ -404,35 +404,41 @@ class SampleCurveFunction : public mf::MultiFunction {
else {
fill_invalid(mask);
}
return;
mod_moder marked this conversation as resolved Outdated

Small naming thing--

  • mask_valids -> mask_valid
  • mask_invalids -> mask_invalid
Small naming thing-- - `mask_valids` -> `mask_valid` - `mask_invalids` -> `mask_invalid`
}
else {
Vector<int> invalid_indices;
VectorSet<int> used_curves;
devirtualize_varray(curve_indices, [&](const auto curve_indices) {
mask.foreach_index([&](const int i) {
const int curve_i = curve_indices[i];
if (curves.curves_range().contains(curve_i)) {
used_curves.add(curve_i);
}
else {
invalid_indices.append(i);
}
});
IndexMaskMemory memory;
IndexMask mask_valid;
IndexMask mask_invalid;
VectorSet<int> used_curves;
devirtualize_varray(curve_indices, [&](const auto curve_indices) {
const IndexRange curves_range = curves.curves_range();
mask_valid = IndexMask::from_predicate(mask, GrainSize(1024), memory, [&](const int index) {
mod_moder marked this conversation as resolved Outdated

Maybe it's better to build this with IndexMask::complement(), so it can be skipped if all the indices were valid

Maybe it's better to build this with `IndexMask::complement()`, so it can be skipped if all the indices were valid

Yeah, i was try, but complement use range as univers instead of mask. So it can't be used in this case.

Yeah, i was try, but `complement` use range as univers instead of mask. So it can't be used in this case.
const int curve_index = curve_indices[index];
return curves_range.contains(curve_index);
});
mask_invalid = IndexMask::from_predicate(
mask, GrainSize(1024), memory, [&](const int index) {
const int curve_index = curve_indices[index];
return !curves_range.contains(curve_index);
});
mask_valid.foreach_index([&](const int i) {
const int curve_i = curve_indices[i];
used_curves.add(curve_i);
});
});
IndexMaskMemory memory;
Array<IndexMask> mask_by_curve(used_curves.size());
IndexMask::from_groups<int>(
mask,
memory,
[&](const int i) { return used_curves.index_of(curve_indices[i]); },
mask_by_curve);
Array<IndexMask> mask_by_curve(used_curves.size());
IndexMask::from_groups<int>(
mask_valid,
memory,
[&](const int i) { return used_curves.index_of(curve_indices[i]); },
mask_by_curve);
for (const int i : mask_by_curve.index_range()) {
sample_curve(used_curves[i], mask_by_curve[i]);
}
fill_invalid(IndexMask::from_indices<int>(invalid_indices, memory));
for (const int i : mask_by_curve.index_range()) {
sample_curve(used_curves[i], mask_by_curve[i]);
}
fill_invalid(mask_invalid);
}
private: