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
This commit is contained in:
Philipp Oeser
2025-03-04 09:35:12 +01:00
committed by Philipp Oeser
parent a50144e55c
commit 3589c5489a
3 changed files with 39 additions and 14 deletions
@@ -22,22 +22,44 @@ Vector<MutableSpan<float3>> 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<StringRef> selection_names = ed::curves::get_curves_selection_attribute_names(curves);
IndexMaskMemory memory;
IndexMask selection = retrieve_selected_points(curves, memory);
MutableSpan<float3> positions = curves.positions_for_write();
std::array<IndexMask, 3> 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<TransVert *>(
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<TransVert *>(MEM_calloc_arrayN(size, sizeof(TransVert), __func__));
tvs->transverts_tot = size;
int offset = 0;
const Vector<MutableSpan<float3>> 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]
+3 -1
View File
@@ -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
+2 -1
View File
@@ -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<Curves *>(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) {