From 3589c5489a7d6548eb1397c1124a498823ef43f3 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 4 Mar 2025 09:35:12 +0100 Subject: [PATCH] Fix: Cursor snapping does not work for Curves bezier handles For this to work, we have to take into account handles in TransVert as well. Behavior is the same as in legacy curves (meaning that if the control point itself is selected, the handles are ignores). Part of #133448 (same thing for grease pencil, which I plan to also make part of TransVert, but better solve for Curves first, so we can share code here). Pull Request: https://projects.blender.org/blender/blender/pulls/134945 --- .../editors/curves/intern/curves_data.cc | 46 ++++++++++++++----- source/blender/editors/include/ED_curves.hh | 4 +- source/blender/editors/util/ed_transverts.cc | 3 +- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/curves/intern/curves_data.cc b/source/blender/editors/curves/intern/curves_data.cc index f5ae554f01d..fa73bf394dd 100644 --- a/source/blender/editors/curves/intern/curves_data.cc +++ b/source/blender/editors/curves/intern/curves_data.cc @@ -22,22 +22,44 @@ Vector> get_curves_positions_for_write(bke::CurvesGeometry & return positions_per_attribute; } -void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, TransVertStore *tvs) +void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, + TransVertStore *tvs, + const bool skip_handles) { + const Span selection_names = ed::curves::get_curves_selection_attribute_names(curves); + IndexMaskMemory memory; - IndexMask selection = retrieve_selected_points(curves, memory); - MutableSpan positions = curves.positions_for_write(); + std::array selection; + for (const int i : selection_names.index_range()) { + selection[i] = ed::curves::retrieve_selected_points(curves, selection_names[i], memory); + } - tvs->transverts = static_cast( - MEM_calloc_arrayN(selection.size(), sizeof(TransVert), __func__)); - tvs->transverts_tot = selection.size(); + if (skip_handles) { + /* When the control point is selected, both handles are ignored. */ + selection[1] = IndexMask::from_difference(selection[1], selection[0], memory); + selection[2] = IndexMask::from_difference(selection[2], selection[0], memory); + } - selection.foreach_index(GrainSize(1024), [&](const int64_t i, const int64_t pos) { - TransVert &tv = tvs->transverts[pos]; - tv.loc = positions[i]; - tv.flag = SELECT; - copy_v3_v3(tv.oldloc, tv.loc); - }); + const int size = selection[0].size() + selection[1].size() + selection[2].size(); + if (size == 0) { + return; + } + + tvs->transverts = static_cast(MEM_calloc_arrayN(size, sizeof(TransVert), __func__)); + tvs->transverts_tot = size; + + int offset = 0; + const Vector> positions = ed::curves::get_curves_positions_for_write(curves); + for (const int attribute_i : positions.index_range()) { + selection[attribute_i].foreach_index(GrainSize(1024), [&](const int64_t i, const int64_t pos) { + TransVert &tv = tvs->transverts[pos + offset]; + tv.loc = positions[attribute_i][i]; + tv.flag = SELECT; + copy_v3_v3(tv.oldloc, tv.loc); + }); + + offset += selection[attribute_i].size(); + } } float (*point_normals_array_create(const Curves *curves_id))[3] diff --git a/source/blender/editors/include/ED_curves.hh b/source/blender/editors/include/ED_curves.hh index 7aedb3fa870..28013696328 100644 --- a/source/blender/editors/include/ED_curves.hh +++ b/source/blender/editors/include/ED_curves.hh @@ -118,7 +118,9 @@ void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); * `ED_transverts_create_from_obedit` in `view3d_snap.cc`). * \note The `TransVert` elements in \a tvs are expected to write to the positions of \a curves. */ -void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, TransVertStore *tvs); +void transverts_from_curves_positions_create(bke::CurvesGeometry &curves, + TransVertStore *tvs, + const bool skip_handles); /* -------------------------------------------------------------------- */ /** \name Poll Functions diff --git a/source/blender/editors/util/ed_transverts.cc b/source/blender/editors/util/ed_transverts.cc index 709dfd06327..f164ab42a9c 100644 --- a/source/blender/editors/util/ed_transverts.cc +++ b/source/blender/editors/util/ed_transverts.cc @@ -504,7 +504,8 @@ void ED_transverts_create_from_obedit(TransVertStore *tvs, const Object *obedit, } else if (obedit->type == OB_CURVES) { Curves *curves_id = static_cast(obedit->data); - blender::ed::curves::transverts_from_curves_positions_create(curves_id->geometry.wrap(), tvs); + blender::ed::curves::transverts_from_curves_positions_create( + curves_id->geometry.wrap(), tvs, ((mode & TM_SKIP_HANDLES) != 0)); } if (!tvs->transverts_tot && tvs->transverts) {