From 405d7adf9455a55a9f1ca7decafd58ff3c28fe49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Fri, 8 Mar 2024 16:33:33 +0100 Subject: [PATCH 1/3] Fix #117997: Crash trying to copy vertex group attributes as spans. Grease Pencil provides custom vertex group attributes as VArrays that are a view on the `MDeformVert` buffer. These attributes are not spans, which the curve conversion code was expecting. Non-span VArrays must be materialized first. --- .../blenkernel/intern/curve_to_mesh_convert.cc | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 98e85c8c370..ce514060ba2 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -376,12 +376,24 @@ static GSpan evaluate_attribute(const GVArray &src, const CurvesGeometry &curves, Vector &buffer) { - if (curves.is_single_type(CURVE_TYPE_POLY) && src.is_span()) { - return src.get_internal_span(); + if (src.is_span()) { + if (curves.is_single_type(CURVE_TYPE_POLY)) { + return src.get_internal_span(); + } + + buffer.reinitialize(curves.evaluated_points_num() * src.type().size()); + GMutableSpan eval{src.type(), buffer.data(), curves.evaluated_points_num()}; + curves.ensure_can_interpolate_to_evaluated(); + curves.interpolate_to_evaluated(src.get_internal_span(), eval); + return eval; } + + GArray src_buffer(src.type(), src.size()); + src.materialize_to_uninitialized(src_buffer.data()); buffer.reinitialize(curves.evaluated_points_num() * src.type().size()); GMutableSpan eval{src.type(), buffer.data(), curves.evaluated_points_num()}; - curves.interpolate_to_evaluated(src.get_internal_span(), eval); + curves.ensure_can_interpolate_to_evaluated(); + curves.interpolate_to_evaluated(src_buffer, eval); return eval; } -- 2.30.2 From 400776a86878580284d3a421463facc3e964a0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 11 Mar 2024 10:35:10 +0100 Subject: [PATCH 2/3] Move `ensure` calls to a higher level. --- source/blender/blenkernel/intern/curve_to_mesh_convert.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index ce514060ba2..5933bd068c1 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -383,7 +383,6 @@ static GSpan evaluate_attribute(const GVArray &src, buffer.reinitialize(curves.evaluated_points_num() * src.type().size()); GMutableSpan eval{src.type(), buffer.data(), curves.evaluated_points_num()}; - curves.ensure_can_interpolate_to_evaluated(); curves.interpolate_to_evaluated(src.get_internal_span(), eval); return eval; } @@ -392,7 +391,6 @@ static GSpan evaluate_attribute(const GVArray &src, src.materialize_to_uninitialized(src_buffer.data()); buffer.reinitialize(curves.evaluated_points_num() * src.type().size()); GMutableSpan eval{src.type(), buffer.data(), curves.evaluated_points_num()}; - curves.ensure_can_interpolate_to_evaluated(); curves.interpolate_to_evaluated(src_buffer, eval); return eval; } @@ -855,6 +853,9 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, Vector eval_buffer; + /* Make sure curve attributes can be interpolated. */ + main.ensure_can_interpolate_to_evaluated(); + build_mesh_positions(curves_info, offsets, eval_buffer, *mesh); mesh->tag_overlapping_none(); @@ -921,6 +922,9 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, return true; }); + /* Make sure profile attributes can be interpolated. */ + profile.ensure_can_interpolate_to_evaluated(); + const AttributeAccessor profile_attributes = profile.attributes(); profile_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { if (main_attributes.contains(id)) { -- 2.30.2 From 55241327634cfa625e51bd2710e106d54b67b55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 11 Mar 2024 11:17:22 +0100 Subject: [PATCH 3/3] Add back fast path for poly curves. --- .../blenkernel/intern/curve_to_mesh_convert.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 5933bd068c1..b4fd7364698 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -376,19 +376,24 @@ static GSpan evaluate_attribute(const GVArray &src, const CurvesGeometry &curves, Vector &buffer) { - if (src.is_span()) { - if (curves.is_single_type(CURVE_TYPE_POLY)) { + /* Poly curves evaluated points match the curve points, no need to interpolate. */ + if (curves.is_single_type(CURVE_TYPE_POLY)) { + if (src.is_span()) { return src.get_internal_span(); } + buffer.reinitialize(curves.points_num() * src.type().size()); + src.materialize(buffer.data()); + GMutableSpan eval{src.type(), buffer.data(), curves.points_num()}; + return eval; + } + if (src.is_span()) { buffer.reinitialize(curves.evaluated_points_num() * src.type().size()); GMutableSpan eval{src.type(), buffer.data(), curves.evaluated_points_num()}; curves.interpolate_to_evaluated(src.get_internal_span(), eval); return eval; } - - GArray src_buffer(src.type(), src.size()); - src.materialize_to_uninitialized(src_buffer.data()); + GVArraySpan src_buffer(src); buffer.reinitialize(curves.evaluated_points_num() * src.type().size()); GMutableSpan eval{src.type(), buffer.data(), curves.evaluated_points_num()}; curves.interpolate_to_evaluated(src_buffer, eval); -- 2.30.2