Blender V5.0
operators.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9
10#include "BKE_attribute.hh"
11#include "BKE_context.hh"
12#include "BKE_lib_id.hh"
13
14#include "ED_pointcloud.hh"
15#include "ED_screen.hh"
16#include "ED_select_utils.hh"
17
20
21#include "DEG_depsgraph.hh"
22
23#include "RNA_access.hh"
24#include "RNA_define.hh"
25
26#include "UI_interface.hh"
28
29#include "WM_api.hh"
30
32
33static bool object_has_editable_pointcloud(const Main &bmain, const Object &object)
34{
35 if (object.type != OB_POINTCLOUD) {
36 return false;
37 }
38 if (object.mode != OB_MODE_EDIT) {
39 return false;
40 }
41 if (!BKE_id_is_editable(&bmain, static_cast<const ID *>(object.data))) {
42 return false;
43 }
44 return true;
45}
46
48 const bool check_editable,
49 const bool check_edit_mode)
50{
52 if (object == nullptr || object->type != OB_POINTCLOUD) {
53 return false;
54 }
55 if (check_editable) {
57 return false;
58 }
59 }
60 if (check_edit_mode) {
61 if ((object->mode & OB_MODE_EDIT) == 0) {
62 return false;
63 }
64 }
65 return true;
66}
67
69{
70 return pointcloud_poll_impl(C, false, false);
71}
72
77
79{
80 VectorSet<PointCloud *> unique_points;
81
82 const Main &bmain = *CTX_data_main(&C);
83
85 if (object && object_has_editable_pointcloud(bmain, *object)) {
86 unique_points.add_new(static_cast<PointCloud *>(object->data));
87 }
88
89 CTX_DATA_BEGIN (&C, Object *, object, selected_objects) {
90 if (object_has_editable_pointcloud(bmain, *object)) {
91 unique_points.add(static_cast<PointCloud *>(object->data));
92 }
93 }
95
96 return unique_points;
97}
98
99static bool has_anything_selected(const Span<PointCloud *> pointclouds)
100{
101 return std::any_of(pointclouds.begin(), pointclouds.end(), [](const PointCloud *pointcloud) {
102 return has_anything_selected(*pointcloud);
103 });
104}
105
107{
108 int action = RNA_enum_get(op->ptr, "action");
109
111
112 if (action == SEL_TOGGLE) {
113 action = has_anything_selected(unique_pointcloud) ? SEL_DESELECT : SEL_SELECT;
114 }
115
116 for (PointCloud *pointcloud : unique_pointcloud) {
117 /* (De)select all the curves. */
118 select_all(*pointcloud, action);
119
120 /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
121 * attribute for now. */
124 }
125
126 return OPERATOR_FINISHED;
127}
128
130{
131 ot->name = "(De)select All";
132 ot->idname = "POINTCLOUD_OT_select_all";
133 ot->description = "(De)select all point cloud";
134
135 ot->exec = select_all_exec;
137
139
141}
142
144{
145 const int seed = RNA_int_get(op->ptr, "seed");
146 const float probability = RNA_float_get(op->ptr, "probability");
147
149 IndexMaskMemory memory;
150 const IndexMask inv_random_elements = random_mask(
151 pointcloud->totpoint, seed, probability, memory)
152 .complement(IndexRange(pointcloud->totpoint),
153 memory);
154 const bool was_anything_selected = has_anything_selected(*pointcloud);
157 if (!was_anything_selected) {
159 }
160
161 pointcloud::fill_selection_false(selection.span, inv_random_elements);
162 selection.finish();
163
164 /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic
165 * attribute for now. */
168 }
169 return OPERATOR_FINISHED;
170}
171
172static void select_random_ui(bContext * /*C*/, wmOperator *op)
173{
174 uiLayout *layout = op->layout;
175
176 layout->prop(op->ptr, "seed", UI_ITEM_NONE, std::nullopt, ICON_NONE);
177 layout->prop(op->ptr, "probability", UI_ITEM_R_SLIDER, std::nullopt, ICON_NONE);
178}
179
181{
182 ot->name = "Select Random";
183 ot->idname = __func__;
184 ot->description = "Randomizes existing selection or create new random selection";
185
186 ot->exec = select_random_exec;
188 ot->ui = select_random_ui;
189
191
192 RNA_def_int(ot->srna,
193 "seed",
194 0,
195 INT32_MIN,
196 INT32_MAX,
197 "Seed",
198 "Source of randomness",
199 INT32_MIN,
200 INT32_MAX);
201 RNA_def_float(ot->srna,
202 "probability",
203 0.5f,
204 0.0f,
205 1.0f,
206 "Probability",
207 "Chance of every point being included in the selection",
208 0.0f,
209 1.0f);
210}
211
213
225
226} // namespace pointcloud_delete
227
229{
230 ot->name = "Delete";
231 ot->idname = __func__;
232 ot->description = "Remove selected points";
233
236
238}
239
249
251{
253 wmOperatorTypeMacro *otmacro;
254
255 ot = WM_operatortype_append_macro("POINTCLOUD_OT_duplicate_move",
256 "Duplicate",
257 "Make copies of selected elements and move them",
259 WM_operatortype_macro_define(ot, "POINTCLOUD_OT_duplicate");
260 otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
261 RNA_boolean_set(otmacro->ptr, "use_proportional_edit", false);
262 RNA_boolean_set(otmacro->ptr, "mirror", false);
263}
264
266{
267 /* Only set in editmode point cloud, by space_view3d listener. */
268 wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Point Cloud", SPACE_EMPTY, RGN_TYPE_WINDOW);
270}
271
272} // namespace blender::ed::pointcloud
#define CTX_DATA_BEGIN(C, Type, instance, member)
Object * CTX_data_active_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
#define CTX_DATA_END
bool BKE_id_is_editable(const Main *bmain, const ID *id)
Definition lib_id.cc:2523
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ OB_MODE_EDIT
@ OB_POINTCLOUD
@ RGN_TYPE_WINDOW
@ SPACE_EMPTY
@ OPERATOR_FINISHED
bool ED_operator_object_active_editable_ex(bContext *C, const Object *ob)
@ SEL_SELECT
@ SEL_DESELECT
@ SEL_TOGGLE
#define C
Definition RandGen.cpp:29
@ UI_ITEM_R_SLIDER
#define UI_ITEM_NONE
#define NC_GEOM
Definition WM_types.hh:393
#define ND_DATA
Definition WM_types.hh:509
@ OPTYPE_UNDO
Definition WM_types.hh:182
@ OPTYPE_REGISTER
Definition WM_types.hh:180
BMesh const char void * data
static unsigned long seed
Definition btSoftBody.h:39
constexpr const T * end() const
Definition BLI_span.hh:224
constexpr const T * begin() const
Definition BLI_span.hh:220
bool add(const Key &key)
void add_new(const Key &key)
IndexMask complement(const IndexMask &universe, IndexMaskMemory &memory) const
#define INT32_MAX
#define INT32_MIN
static wmOperatorStatus delete_exec(bContext *C, wmOperator *)
Definition operators.cc:214
static wmOperatorStatus select_all_exec(bContext *C, wmOperator *op)
Definition operators.cc:106
bool editable_pointcloud_in_edit_mode_poll(bContext *C)
Definition operators.cc:73
static wmOperatorStatus select_random_exec(bContext *C, wmOperator *op)
Definition operators.cc:143
static void POINTCLOUD_OT_delete(wmOperatorType *ot)
Definition operators.cc:228
static void POINTCLOUD_OT_select_random(wmOperatorType *ot)
Definition operators.cc:180
void fill_selection_true(GMutableSpan span)
Definition selection.cc:71
static bool editable_pointcloud_poll(bContext *C)
Definition operators.cc:68
bool remove_selection(PointCloud &pointcloud)
Definition edit.cc:32
static void select_random_ui(bContext *, wmOperator *op)
Definition operators.cc:172
void POINTCLOUD_OT_duplicate(wmOperatorType *ot)
Definition duplicate.cc:60
static bool pointcloud_poll_impl(bContext *C, const bool check_editable, const bool check_edit_mode)
Definition operators.cc:47
void POINTCLOUD_OT_attribute_set(wmOperatorType *ot)
void keymap_pointcloud(wmKeyConfig *keyconf)
Definition operators.cc:265
bke::GSpanAttributeWriter ensure_selection_attribute(PointCloud &pointcloud, bke::AttrType create_type)
Definition selection.cc:31
void fill_selection_false(GMutableSpan selection, const IndexMask &mask)
Definition selection.cc:61
static bool object_has_editable_pointcloud(const Main &bmain, const Object &object)
Definition operators.cc:33
bool has_anything_selected(const PointCloud &pointcloud)
Definition selection.cc:25
void select_all(PointCloud &pointcloud, int action)
Definition selection.cc:128
VectorSet< PointCloud * > get_unique_editable_pointclouds(const bContext &C)
Definition operators.cc:78
static void POINTCLOUD_OT_select_all(wmOperatorType *ot)
Definition operators.cc:129
void POINTCLOUD_OT_separate(wmOperatorType *ot)
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
int RNA_int_get(PointerRNA *ptr, const char *name)
float RNA_float_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
Definition DNA_ID.h:414
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)
bool(* poll)(struct bContext *)
struct uiLayout * layout
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * ot
Definition wm_files.cc:4237
wmKeyMap * WM_keymap_ensure(wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid)
Definition wm_keymap.cc:895
void WM_operator_properties_select_all(wmOperatorType *ot)
wmOperatorTypeMacro * WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
void WM_operatortype_append(void(*opfunc)(wmOperatorType *))
wmOperatorType * WM_operatortype_append_macro(const char *idname, const char *name, const char *description, int flag)