Fix: Curves: Don't treat non-bezier curves as selected when handles are
The `retrieve_selected_points` function would treat points of non-bezier curves as selected if the handles were selected. And because the attributes `.selected_handle_left` and `.selected_handle_right` are created initialized to true for all points. The `retrieve_all_selected_points` would return that all points were selected. Only points of bezier curves should be used when getting the selection mask for handles. Pull Request: https://projects.blender.org/blender/blender/pulls/144824
This commit is contained in:
committed by
casey-bianco-davis
parent
899a8bcdac
commit
346d5b7407
@@ -469,6 +469,10 @@ IndexMask curve_to_point_selection(OffsetIndices<int> points_by_curve,
|
||||
const IndexMask &curve_selection,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
IndexMask curve_type_point_selection(const bke::CurvesGeometry &curves,
|
||||
CurveType curve_type,
|
||||
IndexMaskMemory &memory);
|
||||
|
||||
void fill_points(OffsetIndices<int> points_by_curve,
|
||||
const IndexMask &curve_selection,
|
||||
GPointer value,
|
||||
|
||||
@@ -24,6 +24,19 @@ IndexMask curve_to_point_selection(OffsetIndices<int> points_by_curve,
|
||||
return IndexMask::from_initializers(point_ranges, memory);
|
||||
}
|
||||
|
||||
IndexMask curve_type_point_selection(const bke::CurvesGeometry &curves,
|
||||
const CurveType curve_type,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return curve_to_point_selection(curves.points_by_curve(),
|
||||
indices_for_type(curves.curve_types(),
|
||||
curves.curve_type_counts(),
|
||||
curve_type,
|
||||
curves.curves_range(),
|
||||
memory),
|
||||
memory);
|
||||
}
|
||||
|
||||
void fill_points(const OffsetIndices<int> points_by_curve,
|
||||
const IndexMask &curve_selection,
|
||||
const GPointer value,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_curves_utils.hh"
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
@@ -43,8 +44,17 @@ void transverts_from_curves_positions_create(bke::CurvesGeometry &curves,
|
||||
|
||||
IndexMaskMemory memory;
|
||||
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);
|
||||
if (selection_names.size() == 1) {
|
||||
selection[0] = ed::curves::retrieve_selected_points(curves, memory);
|
||||
}
|
||||
else {
|
||||
const IndexMask bezier_points = bke::curves::curve_type_point_selection(
|
||||
curves, CURVE_TYPE_BEZIER, memory);
|
||||
|
||||
for (const int i : selection_names.index_range()) {
|
||||
selection[i] = ed::curves::retrieve_selected_points(
|
||||
curves, selection_names[i], bezier_points, memory);
|
||||
}
|
||||
}
|
||||
|
||||
if (skip_handles) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_crazyspace.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_curves_utils.hh"
|
||||
|
||||
#include "ED_curves.hh"
|
||||
#include "ED_select_utils.hh"
|
||||
@@ -78,13 +79,18 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, IndexMaskMemory &mem
|
||||
|
||||
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory)
|
||||
{
|
||||
return retrieve_selected_points(curves, ".selection", memory);
|
||||
return IndexMask::from_bools(
|
||||
*curves.attributes().lookup_or_default<bool>(".selection", bke::AttrDomain::Point, true),
|
||||
memory);
|
||||
}
|
||||
|
||||
IndexMask retrieve_all_selected_points(const bke::CurvesGeometry &curves,
|
||||
const int handle_display,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
const IndexMask bezier_points = bke::curves::curve_type_point_selection(
|
||||
curves, CURVE_TYPE_BEZIER, memory);
|
||||
|
||||
Vector<IndexMask> selection_by_attribute;
|
||||
for (const StringRef selection_name : ed::curves::get_curves_selection_attribute_names(curves)) {
|
||||
if (selection_name != ".selection" && handle_display == CURVE_HANDLE_NONE) {
|
||||
@@ -92,18 +98,24 @@ IndexMask retrieve_all_selected_points(const bke::CurvesGeometry &curves,
|
||||
}
|
||||
|
||||
selection_by_attribute.append(
|
||||
ed::curves::retrieve_selected_points(curves, selection_name, memory));
|
||||
ed::curves::retrieve_selected_points(curves, selection_name, bezier_points, memory));
|
||||
}
|
||||
return IndexMask::from_union(selection_by_attribute, memory);
|
||||
}
|
||||
|
||||
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves,
|
||||
StringRef attribute_name,
|
||||
const IndexMask &bezier_points,
|
||||
IndexMaskMemory &memory)
|
||||
{
|
||||
return IndexMask::from_bools(
|
||||
*curves.attributes().lookup_or_default<bool>(attribute_name, bke::AttrDomain::Point, true),
|
||||
memory);
|
||||
const VArray<bool> selected = *curves.attributes().lookup_or_default<bool>(
|
||||
attribute_name, bke::AttrDomain::Point, true);
|
||||
|
||||
if (attribute_name == ".selection") {
|
||||
return IndexMask::from_bools(selected, memory);
|
||||
}
|
||||
|
||||
return IndexMask::from_bools(bezier_points, selected, memory);
|
||||
}
|
||||
|
||||
IndexMask retrieve_selected_points(const Curves &curves_id, IndexMaskMemory &memory)
|
||||
|
||||
@@ -3222,11 +3222,14 @@ static wmOperatorStatus grease_pencil_reproject_exec(bContext *C, wmOperator *op
|
||||
const IndexMask editable_points = retrieve_editable_points(
|
||||
*object, info.drawing, info.layer_index, memory);
|
||||
|
||||
const IndexMask bezier_points = bke::curves::curve_type_point_selection(
|
||||
curves, CURVE_TYPE_BEZIER, memory);
|
||||
|
||||
for (const StringRef selection_name :
|
||||
ed::curves::get_curves_selection_attribute_names(curves))
|
||||
{
|
||||
const IndexMask selected_points = ed::curves::retrieve_selected_points(
|
||||
curves, selection_name, memory);
|
||||
curves, selection_name, bezier_points, memory);
|
||||
const IndexMask points_to_reproject = IndexMask::from_intersection(
|
||||
editable_points, selected_points, memory);
|
||||
|
||||
@@ -3448,11 +3451,14 @@ static wmOperatorStatus grease_pencil_snap_to_grid_exec(bContext *C, wmOperator
|
||||
continue;
|
||||
}
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask bezier_points = bke::curves::curve_type_point_selection(
|
||||
curves, CURVE_TYPE_BEZIER, memory);
|
||||
|
||||
for (const StringRef selection_name : ed::curves::get_curves_selection_attribute_names(curves))
|
||||
{
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selected_points = ed::curves::retrieve_selected_points(
|
||||
curves, selection_name, memory);
|
||||
curves, selection_name, bezier_points, memory);
|
||||
|
||||
const Layer &layer = grease_pencil.layer(drawing_info.layer_index);
|
||||
const float4x4 layer_to_world = layer.to_world_space(object);
|
||||
|
||||
@@ -233,10 +233,16 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, IndexMaskMemory &mem
|
||||
* or points in curves with a selection factor greater than zero).
|
||||
*/
|
||||
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, IndexMaskMemory &memory);
|
||||
IndexMask retrieve_selected_points(const Curves &curves_id, IndexMaskMemory &memory);
|
||||
/**
|
||||
* Find points that are selected, for a given attribute_name, requires mask of all Bezier points.
|
||||
* Note: When retrieving ".selection_handle_left" or ".selection_handle_right" all non-Bezier
|
||||
* points will be deselected even if the raw attribute is selected.
|
||||
*/
|
||||
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves,
|
||||
StringRef attribute_name,
|
||||
const IndexMask &bezier_points,
|
||||
IndexMaskMemory &memory);
|
||||
IndexMask retrieve_selected_points(const Curves &curves_id, IndexMaskMemory &memory);
|
||||
|
||||
/**
|
||||
* Find points that are selected (a selection factor greater than zero) or have
|
||||
|
||||
@@ -350,7 +350,7 @@ static CurvesPointSelectionStatus init_curves_point_selection_status(
|
||||
const Span<float3> positions = curves.positions();
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selection = retrieve_selected_points(curves, ".selection", memory);
|
||||
const IndexMask selection = retrieve_selected_points(curves, memory);
|
||||
|
||||
CurvesPointSelectionStatus status = threading::parallel_reduce(
|
||||
curves.curves_range(),
|
||||
@@ -386,11 +386,15 @@ static CurvesPointSelectionStatus init_curves_point_selection_status(
|
||||
return status;
|
||||
}
|
||||
|
||||
const IndexMask bezier_points = bke::curves::curve_type_point_selection(
|
||||
curves, CURVE_TYPE_BEZIER, memory);
|
||||
|
||||
auto add_handles = [&](StringRef selection_attribute, std::optional<Span<float3>> positions) {
|
||||
if (!positions) {
|
||||
return;
|
||||
}
|
||||
const IndexMask selection = retrieve_selected_points(curves, selection_attribute, memory);
|
||||
const IndexMask selection = retrieve_selected_points(
|
||||
curves, selection_attribute, bezier_points, memory);
|
||||
if (selection.is_empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -428,7 +432,7 @@ static bool apply_to_curves_point_selection(const int tot,
|
||||
const MutableSpan<float> tilt = median.tilt ? curves.tilt_for_write() : MutableSpan<float>{};
|
||||
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selection = retrieve_selected_points(curves, ".selection", memory);
|
||||
const IndexMask selection = retrieve_selected_points(curves, memory);
|
||||
const bool update_location = math::length_manhattan(float3(median.location)) > 0;
|
||||
MutableSpan<float3> positions = update_location && !selection.is_empty() ?
|
||||
curves.positions_for_write() :
|
||||
@@ -468,8 +472,12 @@ static bool apply_to_curves_point_selection(const int tot,
|
||||
return changed;
|
||||
}
|
||||
|
||||
const IndexMask bezier_points = bke::curves::curve_type_point_selection(
|
||||
curves, CURVE_TYPE_BEZIER, memory);
|
||||
|
||||
auto apply_to_handles = [&](StringRef selection_attribute, StringRef handles_attribute) {
|
||||
const IndexMask selection = retrieve_selected_points(curves, selection_attribute, memory);
|
||||
const IndexMask selection = retrieve_selected_points(
|
||||
curves, selection_attribute, bezier_points, memory);
|
||||
if (selection.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -302,12 +302,6 @@ static void createTransCurvesVerts(bContext *C, TransInfo *t)
|
||||
curves);
|
||||
std::array<IndexMask, 3> selection_per_attribute;
|
||||
|
||||
for (const int attribute_i : selection_attribute_names.index_range()) {
|
||||
const StringRef &selection_name = selection_attribute_names[attribute_i];
|
||||
selection_per_attribute[attribute_i] = ed::curves::retrieve_selected_points(
|
||||
curves, selection_name, curves_transform_data->memory);
|
||||
}
|
||||
|
||||
bezier_curves[i] = bke::curves::indices_for_type(curves.curve_types(),
|
||||
curves.curve_type_counts(),
|
||||
CURVE_TYPE_BEZIER,
|
||||
@@ -317,6 +311,12 @@ static void createTransCurvesVerts(bContext *C, TransInfo *t)
|
||||
const IndexMask bezier_points = bke::curves::curve_to_point_selection(
|
||||
curves.points_by_curve(), bezier_curves[i], curves_transform_data->memory);
|
||||
|
||||
for (const int attribute_i : selection_attribute_names.index_range()) {
|
||||
const StringRef &selection_name = selection_attribute_names[attribute_i];
|
||||
selection_per_attribute[attribute_i] = ed::curves::retrieve_selected_points(
|
||||
curves, selection_name, bezier_points, curves_transform_data->memory);
|
||||
}
|
||||
|
||||
/* Alter selection as in legacy curves bezt_select_to_transform_triple_flag(). */
|
||||
if (!bezier_points.is_empty()) {
|
||||
update_handle_types_for_transform(t->mode, selection_per_attribute, bezier_points, curves);
|
||||
|
||||
@@ -92,16 +92,6 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
|
||||
const IndexMask editable_strokes = ed::greasepencil::retrieve_editable_strokes(
|
||||
*object, info.drawing, info.layer_index, curves_transform_data->memory);
|
||||
|
||||
for (const int attribute_i : selection_attribute_names.index_range()) {
|
||||
const StringRef &selection_name = selection_attribute_names[attribute_i];
|
||||
selection_per_attribute[attribute_i] = ed::curves::retrieve_selected_points(
|
||||
curves, selection_name, curves_transform_data->memory);
|
||||
|
||||
/* Make sure only editable points are used. */
|
||||
selection_per_attribute[attribute_i] = IndexMask::from_intersection(
|
||||
selection_per_attribute[attribute_i], editable_points, curves_transform_data->memory);
|
||||
}
|
||||
|
||||
bezier_curves[layer_offset] = bke::curves::indices_for_type(curves.curve_types(),
|
||||
curves.curve_type_counts(),
|
||||
CURVE_TYPE_BEZIER,
|
||||
@@ -111,6 +101,16 @@ static void createTransGreasePencilVerts(bContext *C, TransInfo *t)
|
||||
const IndexMask bezier_points = IndexMask::from_ranges(
|
||||
points_by_curve, bezier_curves[layer_offset], curves_transform_data->memory);
|
||||
|
||||
for (const int attribute_i : selection_attribute_names.index_range()) {
|
||||
const StringRef &selection_name = selection_attribute_names[attribute_i];
|
||||
selection_per_attribute[attribute_i] = ed::curves::retrieve_selected_points(
|
||||
curves, selection_name, bezier_points, curves_transform_data->memory);
|
||||
|
||||
/* Make sure only editable points are used. */
|
||||
selection_per_attribute[attribute_i] = IndexMask::from_intersection(
|
||||
selection_per_attribute[attribute_i], editable_points, curves_transform_data->memory);
|
||||
}
|
||||
|
||||
/* Alter selection as in legacy curves bezt_select_to_transform_triple_flag(). */
|
||||
if (!bezier_points.is_empty()) {
|
||||
if (curves::update_handle_types_for_transform(
|
||||
|
||||
Reference in New Issue
Block a user