[Bf-blender-cvs] [70ca15670d9] master: Curves: Edit mode selection operators
Falk David
noreply at git.blender.org
Fri Jan 20 16:41:12 CET 2023
Commit: 70ca15670d9f6d7179d1fe150939582c91174c29
Author: Falk David
Date: Fri Jan 20 16:40:51 2023 +0100
Branches: master
https://developer.blender.org/rB70ca15670d9f6d7179d1fe150939582c91174c29
Curves: Edit mode selection operators
This adds the following operators to edit mode:
- `select_all`
- `select_random`
- `select_end`
Differential Revision: https://developer.blender.org/D17047
===================================================================
M release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py
M release/scripts/presets/keyconfig/keymap_data/blender_default.py
M release/scripts/startup/bl_ui/space_view3d.py
M source/blender/editors/curves/intern/curves_ops.cc
M source/blender/editors/curves/intern/curves_selection.cc
M source/blender/editors/include/ED_curves.h
M source/blender/editors/sculpt_paint/curves_sculpt_ops.cc
M source/blender/editors/space_api/spacetypes.c
M source/blender/editors/space_view3d/space_view3d.cc
===================================================================
diff --git a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py
index 7172d7809f2..f183877749c 100644
--- a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py
+++ b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py
@@ -55,6 +55,7 @@ _km_hierarchy = [
('Curve', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_CURVE'),
]),
+ ('Curves', 'EMPTY', 'WINDOW', []),
('Armature', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_ARMATURE'),
]),
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 19093e51ec5..4149377581c 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -5615,6 +5615,14 @@ def km_curves(params):
{"items": items},
)
+ items.extend([
+ ("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}),
+ ("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}),
+ ("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
+ ("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
+ *_template_items_select_actions(params, "curves.select_all"),
+ ])
+
return keymap
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 3bb009dd2ad..938399485d3 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -718,7 +718,7 @@ class VIEW3D_HT_header(Header):
if object_mode == 'PARTICLE_EDIT':
row = layout.row()
row.prop(tool_settings.particle_edit, "select_mode", text="", expand=True)
- elif object_mode == 'SCULPT_CURVES' and obj.type == 'CURVES':
+ elif object_mode in {'EDIT', 'SCULPT_CURVES'} and obj.type == 'CURVES':
curves = obj.data
row = layout.row(align=True)
@@ -2044,7 +2044,13 @@ class VIEW3D_MT_select_edit_curves(Menu):
bl_label = "Select"
def draw(self, _context):
- pass
+ layout = self.layout
+
+ layout.operator("curves.select_all", text="All").action = 'SELECT'
+ layout.operator("curves.select_all", text="None").action = 'DESELECT'
+ layout.operator("curves.select_all", text="Invert").action = 'INVERT'
+ layout.operator("curves.select_random", text="Random")
+ layout.operator("curves.select_end", text="Endpoints")
class VIEW3D_MT_select_sculpt_curves(Menu):
@@ -2057,7 +2063,7 @@ class VIEW3D_MT_select_sculpt_curves(Menu):
layout.operator("curves.select_all", text="None").action = 'DESELECT'
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
layout.operator("sculpt_curves.select_random", text="Random")
- layout.operator("sculpt_curves.select_end", text="Endpoints")
+ layout.operator("curves.select_end", text="Endpoints")
layout.operator("sculpt_curves.select_grow", text="Grow")
diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc
index 24aa362b973..d0a68774c71 100644
--- a/source/blender/editors/curves/intern/curves_ops.cc
+++ b/source/blender/editors/curves/intern/curves_ops.cc
@@ -7,7 +7,10 @@
#include <atomic>
#include "BLI_array_utils.hh"
+#include "BLI_devirtualize_parameters.hh"
#include "BLI_index_mask_ops.hh"
+#include "BLI_kdtree.h"
+#include "BLI_rand.hh"
#include "BLI_utildefines.h"
#include "BLI_vector_set.hh"
@@ -15,6 +18,7 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
+#include "ED_view3d.h"
#include "WM_api.h"
@@ -48,6 +52,9 @@
#include "RNA_enum_types.h"
#include "RNA_prototypes.h"
+#include "UI_interface.h"
+#include "UI_resources.h"
+
#include "GEO_reverse_uv_sampler.hh"
/**
@@ -820,113 +827,133 @@ static void CURVES_OT_set_selection_domain(wmOperatorType *ot)
RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE));
}
-static bool contains(const VArray<bool> &varray, const bool value)
+static bool has_anything_selected(const Span<Curves *> curves_ids)
+{
+ return std::any_of(curves_ids.begin(), curves_ids.end(), [](const Curves *curves_id) {
+ return has_anything_selected(CurvesGeometry::wrap(curves_id->geometry));
+ });
+}
+
+static int select_all_exec(bContext *C, wmOperator *op)
{
- const CommonVArrayInfo info = varray.common_info();
- if (info.type == CommonVArrayInfo::Type::Single) {
- return *static_cast<const bool *>(info.data) == value;
+ int action = RNA_enum_get(op->ptr, "action");
+
+ VectorSet<Curves *> unique_curves = get_unique_editable_curves(*C);
+
+ if (action == SEL_TOGGLE) {
+ action = has_anything_selected(unique_curves) ? SEL_DESELECT : SEL_SELECT;
}
- if (info.type == CommonVArrayInfo::Type::Span) {
- const Span<bool> span(static_cast<const bool *>(info.data), varray.size());
- return threading::parallel_reduce(
- span.index_range(),
- 4096,
- false,
- [&](const IndexRange range, const bool init) {
- return init || span.slice(range).contains(value);
- },
- [&](const bool a, const bool b) { return a || b; });
+
+ for (Curves *curves_id : unique_curves) {
+ /* (De)select all the curves. */
+ select_all(CurvesGeometry::wrap(curves_id->geometry),
+ eAttrDomain(curves_id->selection_domain),
+ action);
+
+ /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
+ * attribute for now. */
+ DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id);
}
- return threading::parallel_reduce(
- varray.index_range(),
- 2048,
- false,
- [&](const IndexRange range, const bool init) {
- if (init) {
- return init;
- }
- /* Alternatively, this could use #materialize to retrieve many values at once. */
- for (const int64_t i : range) {
- if (varray[i] == value) {
- return true;
- }
- }
- return false;
- },
- [&](const bool a, const bool b) { return a || b; });
+
+ return OPERATOR_FINISHED;
}
-bool has_anything_selected(const Curves &curves_id)
+static void CURVES_OT_select_all(wmOperatorType *ot)
{
- const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry);
- const VArray<bool> selection = curves.attributes().lookup<bool>(".selection");
- return !selection || contains(selection, true);
+ ot->name = "(De)select All";
+ ot->idname = "CURVES_OT_select_all";
+ ot->description = "(De)select all control points";
+
+ ot->exec = select_all_exec;
+ ot->poll = editable_curves_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ WM_operator_properties_select_all(ot);
}
-static bool has_anything_selected(const Span<Curves *> curves_ids)
+static int select_random_exec(bContext *C, wmOperator *op)
{
- return std::any_of(curves_ids.begin(), curves_ids.end(), [](const Curves *curves_id) {
- return has_anything_selected(*curves_id);
- });
+ VectorSet<Curves *> unique_curves = curves::get_unique_editable_curves(*C);
+
+ const int seed = RNA_int_get(op->ptr, "seed");
+ const float probability = RNA_float_get(op->ptr, "probability");
+
+ for (Curves *curves_id : unique_curves) {
+ CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry);
+ select_random(curves, eAttrDomain(curves_id->selection_domain), uint32_t(seed), probability);
+
+ /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
+ * attribute for now. */
+ DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY);
+ WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id);
+ }
+ return OPERATOR_FINISHED;
}
-namespace select_all {
+static void select_random_ui(bContext * /*C*/, wmOperator *op)
+{
+ uiLayout *layout = op->layout;
-static void invert_selection(MutableSpan<float> selection)
+ uiItemR(layout, op->ptr, "seed", 0, nullptr, ICON_NONE);
+ uiItemR(layout, op->ptr, "probability", UI_ITEM_R_SLIDER, "Probability", ICON_NONE);
+}
+
+static void CURVES_OT_select_random(wmOperatorType *ot)
{
- threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) {
- for (const int i : range) {
- selection[i] = 1.0f - selection[i];
- }
- });
+ ot->name = "Select Random";
+ ot->idname = __func__;
+ ot->description = "Randomizes existing selection or create new random selection";
+
+ ot->exec = select_random_exec;
+ ot->poll = curves::editable_curves_poll;
+ ot->ui = select_random_ui;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_int(ot->srna,
+ "seed",
+ 0,
+ INT32_MIN,
+ INT32_MAX,
+ "Seed",
+ "Source of randomness",
+ INT32_MIN,
+ INT32_MAX);
+ RNA_def_float(ot->srna,
+ "probability",
+ 0.5f,
+ 0.0f,
+ 1.0f,
+ "Probability",
+ "Chance of every point or curve being included in the selection",
+ 0.0f,
+ 1.0f);
}
-static void invert_selection(GMutableSpan selection)
+static bool select_end_poll(bContext *C)
{
- if (selection.type().is<bool>()) {
- array_utils::invert_booleans(selection.typed<bool>());
+ if (!curves::editable_curves_poll(C)) {
+ return false;
}
- else if (selection.type().is<float>()) {
- invert_selection(selection.typed<float>());
+ const Curves *curves_id = static_cast<const Curves *>(CTX_data_active_object(C)->data);
+ if (curves_id->selection_domain != ATTR_DOMAIN_POINT) {
+ CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode");
+ return false
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list