From 2f1b9432beae01916ec0c691a4b5f32a4112eec0 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 16 Feb 2024 18:25:43 +0100 Subject: [PATCH] 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 --- .../blender/editors/curves/intern/curves_ops.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index d65cc6d9e85..c685ee546b2 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -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 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 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();