Fix #106999: Converting curves to particle system can lead to crash

So this happens on curves with only a single point in them.
If these are converted to the old particle system, we would end up with
a particle with only one key (invalid hair), then going to particle
editmode would crash.

The old particle system took care of this (e.g. when deleting keys in
`PARTICLE_OT_delete`)
See the following comment:
`/* We can't have elements with less than two keys. */`

So to resolve, only convert curves with multiple (>1) points in the
process.

Pull Request: https://projects.blender.org/blender/blender/pulls/118392
This commit is contained in:
Philipp Oeser 2024-02-16 18:25:43 +01:00 committed by Philipp Oeser
parent f573a3bad3
commit 2f1b9432be

@ -280,7 +280,15 @@ static void try_convert_single_object(Object &curves_ob,
*r_could_not_convert_some_curves = true;
}
const int hair_num = curves.curves_num();
const OffsetIndices<int> points_by_curve = curves.points_by_curve();
IndexMaskMemory memory;
const IndexMask multi_point_curves = IndexMask::from_predicate(
curves.curves_range(), GrainSize(4096), memory, [&](const int curve_i) {
return points_by_curve[curve_i].size() > 1;
});
const int hair_num = multi_point_curves.size();
if (hair_num == 0) {
return;
}
@ -327,11 +335,9 @@ static void try_convert_single_object(Object &curves_ob,
const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob};
const MFace *mfaces = (const MFace *)CustomData_get_layer(&surface_me.fdata_legacy, CD_MFACE);
const OffsetIndices points_by_curve = curves.points_by_curve();
const Span<float3> positions = surface_me.vert_positions();
for (const int new_hair_i : IndexRange(hair_num)) {
const int curve_i = new_hair_i;
multi_point_curves.foreach_index([&](const int curve_i, const int new_hair_i) {
const IndexRange points = points_by_curve[curve_i];
const float3 &root_pos_cu = positions_cu[points.first()];
@ -382,7 +388,7 @@ static void try_convert_single_object(Object &curves_ob,
key.time = 100.0f * key_fac;
key.weight = 1.0f - key_fac;
}
}
});
particle_system->particles = particles.data();
particle_system->totpart = particles.size();