Blender V4.5
object_modes.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11
12#include "DNA_object_enums.h"
13#include "DNA_object_types.h"
14#include "DNA_scene_types.h"
15
16#include "BLI_time.h"
17#include "BLI_utildefines.h"
18
19#include "BKE_context.hh"
20#include "BKE_layer.hh"
21#include "BKE_library.hh"
22#include "BKE_modifier.hh"
23#include "BKE_object.hh"
24#include "BKE_paint.hh"
25#include "BKE_report.hh"
26
27#include "BLI_math_vector.h"
28
29#include "WM_api.hh"
30#include "WM_types.hh"
31
32#include "RNA_access.hh"
33#include "RNA_define.hh"
34
35#include "DEG_depsgraph.hh"
37
38#include "ED_armature.hh"
39#include "ED_gpencil_legacy.hh"
40#include "ED_outliner.hh"
41#include "ED_paint.hh"
42#include "ED_physics.hh"
43#include "ED_sculpt.hh"
44#include "ED_undo.hh"
45#include "ED_view3d.hh"
46
47#include "WM_toolsystem.hh"
48
49#include "ED_object.hh" /* own include */
50#include "object_intern.hh"
51
52namespace blender::ed::object {
53
54/* -------------------------------------------------------------------- */
57
58static const char *object_mode_op_string(eObjectMode mode)
59{
60 if (mode & OB_MODE_EDIT) {
61 return "OBJECT_OT_editmode_toggle";
62 }
63 if (mode == OB_MODE_SCULPT) {
64 return "SCULPT_OT_sculptmode_toggle";
65 }
66 if (mode == OB_MODE_VERTEX_PAINT) {
67 return "PAINT_OT_vertex_paint_toggle";
68 }
69 if (mode == OB_MODE_WEIGHT_PAINT) {
70 return "PAINT_OT_weight_paint_toggle";
71 }
72 if (mode == OB_MODE_TEXTURE_PAINT) {
73 return "PAINT_OT_texture_paint_toggle";
74 }
75 if (mode == OB_MODE_PARTICLE_EDIT) {
76 return "PARTICLE_OT_particle_edit_toggle";
77 }
78 if (mode == OB_MODE_POSE) {
79 return "OBJECT_OT_posemode_toggle";
80 }
81 if (mode == OB_MODE_PAINT_GREASE_PENCIL) {
82 return "GREASE_PENCIL_OT_paintmode_toggle";
83 }
84 if (mode == OB_MODE_SCULPT_GREASE_PENCIL) {
85 return "GREASE_PENCIL_OT_sculptmode_toggle";
86 }
87 if (mode == OB_MODE_WEIGHT_GREASE_PENCIL) {
88 return "GREASE_PENCIL_OT_weightmode_toggle";
89 }
90 if (mode == OB_MODE_VERTEX_GREASE_PENCIL) {
91 return "GREASE_PENCIL_OT_vertexmode_toggle";
92 }
93 if (mode == OB_MODE_SCULPT_CURVES) {
94 return "CURVES_OT_sculptmode_toggle";
95 }
96 return nullptr;
97}
98
99bool mode_compat_test(const Object *ob, eObjectMode mode)
100{
101 if (mode == OB_MODE_OBJECT) {
102 return true;
103 }
104
105 switch (ob->type) {
106 case OB_MESH:
109 {
110 return true;
111 }
112 if (mode & OB_MODE_PARTICLE_EDIT) {
114 return true;
115 }
116 }
117 break;
118 case OB_CURVES_LEGACY:
119 case OB_SURF:
120 case OB_FONT:
121 case OB_MBALL:
122 case OB_POINTCLOUD:
123 case OB_LATTICE:
124 if (mode & OB_MODE_EDIT) {
125 return true;
126 }
127 break;
128 case OB_ARMATURE:
129 if (mode & (OB_MODE_EDIT | OB_MODE_POSE)) {
130 return true;
131 }
132 break;
133 case OB_CURVES:
134 if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT_CURVES)) {
135 return true;
136 }
137 break;
138 case OB_GREASE_PENCIL:
141 {
142 return true;
143 }
144 break;
145 }
146
147 return false;
148}
149
151{
152 bool ok;
153 if (!ELEM(ob->mode, mode, OB_MODE_OBJECT)) {
154 const char *opstring = object_mode_op_string(eObjectMode(ob->mode));
155
156 WM_operator_name_call(C, opstring, WM_OP_EXEC_REGION_WIN, nullptr, nullptr);
157 ok = ELEM(ob->mode, mode, OB_MODE_OBJECT);
158 if (!ok) {
159 wmOperatorType *ot = WM_operatortype_find(opstring, false);
160 BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name);
161 }
162 }
163 else {
164 ok = true;
165 }
166
167 return ok;
168}
169
171
172/* -------------------------------------------------------------------- */
179
180bool mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportList *reports)
181{
183 const Scene *scene = CTX_data_scene(C);
184 ViewLayer *view_layer = CTX_data_view_layer(C);
185
186 BKE_view_layer_synced_ensure(scene, view_layer);
188 if (ob == nullptr) {
189 return (mode == OB_MODE_OBJECT);
190 }
191
192 if (ob->mode == mode) {
193 return true;
194 }
195
196 if (!mode_compat_test(ob, mode)) {
197 return false;
198 }
199
200 const char *opstring = object_mode_op_string((mode == OB_MODE_OBJECT) ? eObjectMode(ob->mode) :
201 mode);
202 if (opstring == nullptr) {
204 RPT_ERROR,
205 "Unable to set invalid object mode %d",
206 int((mode == OB_MODE_OBJECT) ? ob->mode : mode));
207 return false;
208 }
209 wmOperatorType *ot = WM_operatortype_find(opstring, false);
210
211 if (!use_undo) {
212 wm->op_undo_depth++;
213 }
214 WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_REGION_WIN, nullptr, nullptr);
215 if (!use_undo) {
216 wm->op_undo_depth--;
217 }
218
219 if (ob->mode != mode) {
220 BKE_reportf(reports, RPT_ERROR, "Unable to execute '%s', error changing modes", ot->name);
221 return false;
222 }
223
224 return true;
225}
226
228{
229 /* Don't do undo push by default, since this may be called by lower level code. */
230 return mode_set_ex(C, mode, true, nullptr);
231}
232
238 Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, bool only_test)
239{
240 BLI_assert((bmain == nullptr) == only_test);
241 if (ob->mode & OB_MODE_EDIT) {
243 if (only_test) {
244 return true;
245 }
246 editmode_exit_ex(bmain, scene, ob, EM_FREEDATA);
247 }
248 }
249 else if (ob->mode & OB_MODE_VERTEX_PAINT) {
250 if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) {
251 if (only_test) {
252 return true;
253 }
255 }
256 }
257 else if (ob->mode & OB_MODE_WEIGHT_PAINT) {
258 if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) {
259 if (only_test) {
260 return true;
261 }
263 }
264 }
265 else if (ob->mode & OB_MODE_SCULPT) {
266 if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) {
267 if (only_test) {
268 return true;
269 }
270 sculpt_paint::object_sculpt_mode_exit(*bmain, *depsgraph, *scene, *ob);
271 }
272 }
273 else if (ob->mode & OB_MODE_POSE) {
274 if (ob->pose != nullptr) {
275 if (only_test) {
276 return true;
277 }
279 }
280 }
281 else if (ob->mode & OB_MODE_TEXTURE_PAINT) {
282 if (only_test) {
283 return true;
284 }
285 ED_object_texture_paint_mode_exit_ex(*bmain, *scene, *ob);
286 }
287 else if (ob->mode & OB_MODE_PARTICLE_EDIT) {
288 if (only_test) {
289 return true;
290 }
292 }
293 else if (ob->type == OB_GREASE_PENCIL) {
294 BLI_assert((ob->mode & OB_MODE_OBJECT) == 0);
295 if (only_test) {
296 return true;
297 }
298 ob->restore_mode = ob->mode;
301
302 /* Inform all evaluated versions that we changed the mode. */
304 }
305 else {
306 if (only_test) {
307 return false;
308 }
310 }
311
312 return false;
313}
314
315/* When locked, it's almost impossible to select the pose-object
316 * then the mesh-object to enter weight paint mode.
317 * Even when the object mode is not locked this is inconvenient - so allow in either case.
318 *
319 * In this case move our pose object in/out of pose mode.
320 * This is in fits with the convention of selecting multiple objects and entering a mode.
321 */
323 Main *bmain,
324 Object *ob_arm,
325 const bool is_mode_set)
326{
327 View3D *v3d = CTX_wm_view3d(C);
328 const Scene *scene = CTX_data_scene(C);
329 ViewLayer *view_layer = CTX_data_view_layer(C);
330
331 if (ob_arm != nullptr) {
332 BKE_view_layer_synced_ensure(scene, view_layer);
333 const Base *base_arm = BKE_view_layer_base_find(view_layer, ob_arm);
334 if (base_arm && BASE_VISIBLE(v3d, base_arm)) {
335 if (is_mode_set) {
336 if ((ob_arm->mode & OB_MODE_POSE) != 0) {
337 ED_object_posemode_exit_ex(bmain, ob_arm);
338 }
339 }
340 else {
341 /* Only check selected status when entering weight-paint mode
342 * because we may have multiple armature objects.
343 * Selecting one will de-select the other, which would leave it in pose-mode
344 * when exiting weight paint mode. While usable, this looks like inconsistent
345 * behavior from a user perspective. */
346 if (base_arm->flag & BASE_SELECTED) {
347 if ((ob_arm->mode & OB_MODE_POSE) == 0) {
348 ED_object_posemode_enter_ex(bmain, ob_arm);
349 }
350 }
351 }
352 }
353 }
354}
355
356void posemode_set_for_weight_paint(bContext *C, Main *bmain, Object *ob, const bool is_mode_set)
357{
358 VirtualModifierData virtual_modifier_data;
359 ModifierData *md = BKE_modifiers_get_virtual_modifierlist(ob, &virtual_modifier_data);
360 for (; md; md = md->next) {
361 if (md->type == eModifierType_Armature) {
362 ArmatureModifierData *amd = reinterpret_cast<ArmatureModifierData *>(md);
363 Object *ob_arm = amd->object;
364 ed_object_posemode_set_for_weight_paint_ex(C, bmain, ob_arm, is_mode_set);
365 }
368 md);
369 Object *ob_arm = amd->object;
370 ed_object_posemode_set_for_weight_paint_ex(C, bmain, ob_arm, is_mode_set);
371 }
372 }
373}
374
375void mode_generic_exit(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
376{
377 ed_object_mode_generic_exit_ex(bmain, depsgraph, scene, ob, false);
378}
379
380bool mode_generic_has_data(Depsgraph *depsgraph, const Object *ob)
381{
382 return ed_object_mode_generic_exit_ex(nullptr, depsgraph, nullptr, (Object *)ob, true);
383}
384
386
387/* -------------------------------------------------------------------- */
393
395{
396 if (!CTX_wm_region_view3d(C)) {
397 return false;
398 }
399 const Object *ob = CTX_data_active_object(C);
400 return ob && (ob->mode != OB_MODE_OBJECT);
401}
402
403/* Update the viewport rotation origin to the mouse cursor. */
405 Scene *scene,
406 const int mval[2])
407{
408 float global_loc[3];
409 if (!ED_view3d_autodist_simple(region, mval, global_loc, 0, nullptr)) {
410 return;
411 }
413 copy_v3_v3(ups->average_stroke_accum, global_loc);
414 ups->average_stroke_counter = 1;
415 ups->last_stroke_valid = true;
416}
417
419{
420 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
421 Object *ob_dst_eval = DEG_get_evaluated(depsgraph, ob_dst);
422 ob_dst_eval->runtime->overlay_mode_transfer_start_time = BLI_time_now_seconds();
423}
424
426 wmOperator *op,
427 Scene *scene,
428 Object * /*ob_src*/,
429 Object *ob_dst,
430 const eObjectMode mode_dst)
431{
432 ViewLayer *view_layer = CTX_data_view_layer(C);
433
434 /* Undo is handled manually here, such that the entry in the user-visible undo history is named
435 * from the expected mode toggle operator name, and not the 'Transfer Mode' operator itself.
436 *
437 * The undo grouping is needed to ensure that only one step is visible, even though there may be
438 * two undo steps stored when executed successfully (moving source object to Object mode, and
439 * then target object to the previous mode of source object). */
441
442 const bool mode_transferred = mode_set_ex(C, OB_MODE_OBJECT, true, op->reports);
443 if (mode_transferred) {
444 BKE_view_layer_synced_ensure(scene, view_layer);
445 Base *base_dst = BKE_view_layer_base_find(view_layer, ob_dst);
446 BKE_view_layer_base_deselect_all(scene, view_layer);
447 BKE_view_layer_base_select_and_set_active(view_layer, base_dst);
448
449 /* Not entirely clear why, but this extra undo step (the two calls to #mode_set_ex should
450 * already create their own) is required. Otherwise some mode switching does not work as
451 * expected on undo/redo (see #130420 with Sculpt mode). */
452 ED_undo_push(C, "Change Active");
453
454 mode_set_ex(C, mode_dst, true, op->reports);
455
456 if (RNA_boolean_get(op->ptr, "use_flash_on_transfer")) {
458 }
459 }
460
462
463 return mode_transferred;
464}
465
467 wmOperator *op,
468 const wmEvent *event)
469{
470 Scene *scene = CTX_data_scene(C);
471 ARegion *region = CTX_wm_region(C);
473 const eObjectMode mode_src = eObjectMode(ob_src->mode);
474
475 Base *base_dst = ED_view3d_give_base_under_cursor(C, event->mval);
476 if (!base_dst) {
477 BKE_reportf(op->reports, RPT_ERROR, "No target object to transfer the mode to");
478 return OPERATOR_CANCELLED;
479 }
480
481 Object *ob_dst = base_dst->object;
482
483 if (ob_src == ob_dst) {
484 return OPERATOR_CANCELLED;
485 }
486
487 BLI_assert(ob_dst->id.orig_id == nullptr);
488 if (!ID_IS_EDITABLE(ob_dst) || !ID_IS_EDITABLE(ob_src)) {
490 RPT_ERROR,
491 "Unable to transfer mode, the source and/or target objects are not editable");
492 return OPERATOR_CANCELLED;
493 }
494 if (ID_IS_OVERRIDE_LIBRARY(ob_dst) && !ELEM(mode_src, OB_MODE_OBJECT, OB_MODE_POSE)) {
496 op->reports,
497 RPT_ERROR,
498 "Current mode of source object '%s' is not compatible with target liboverride object '%s'",
499 ob_src->id.name + 2,
500 ob_dst->id.name + 2);
501 return OPERATOR_CANCELLED;
502 }
503 if (!mode_compat_test(ob_dst, mode_src)) {
505 RPT_ERROR,
506 "Current mode of source object '%s' is not compatible with target object '%s'",
507 ob_src->id.name + 2,
508 ob_dst->id.name + 2);
509 return OPERATOR_CANCELLED;
510 }
511
512 const bool mode_transferred = object_transfer_mode_to_base(
513 C, op, scene, ob_src, ob_dst, mode_src);
514 if (!mode_transferred) {
515 /* Error report should have been set by #object_transfer_mode_to_base call here. */
516 return OPERATOR_CANCELLED;
517 }
518
522
524 if (mode_src & OB_MODE_ALL_PAINT) {
526 }
527
528 return OPERATOR_FINISHED;
529}
530
532{
533 /* identifiers */
534 ot->name = "Transfer Mode";
535 ot->idname = "OBJECT_OT_transfer_mode";
536 ot->description =
537 "Switches the active object and assigns the same mode to a new one under the mouse cursor, "
538 "leaving the active mode in the current one";
539
540 /* API callbacks. */
543
544 /* Undo push is handled by the operator, see #object_transfer_mode_to_base for details. */
546
548
550 "use_flash_on_transfer",
551 true,
552 "Flash On Transfer",
553 "Flash the target object when transferring the mode");
554}
555
557
558} // namespace blender::ed::object
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer)
Object * BKE_view_layer_active_object_get(const ViewLayer *view_layer)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
void BKE_view_layer_base_select_and_set_active(ViewLayer *view_layer, Base *selbase)
ModifierData * BKE_modifiers_get_virtual_modifierlist(const Object *ob, VirtualModifierData *data)
General operations, lookup, etc. for blender objects.
bool BKE_object_is_in_editmode(const Object *ob)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert(a)
Definition BLI_assert.h:46
MINLINE void copy_v3_v3(float r[3], const float a[3])
Platform independent time functions.
double BLI_time_now_seconds(void)
Definition time.cc:65
#define ELEM(...)
void DEG_id_tag_update(ID *id, unsigned int flags)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
@ ID_RECALC_SELECT
Definition DNA_ID.h:1009
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ eModifierType_GreasePencilArmature
@ eModifierType_Armature
#define OB_MODE_ALL_PAINT
#define OB_MODE_ALL_MODE_DATA
eObjectMode
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT
@ OB_MODE_WEIGHT_PAINT
@ OB_MODE_SCULPT
@ OB_MODE_SCULPT_CURVES
@ OB_MODE_PAINT_GREASE_PENCIL
@ OB_MODE_SCULPT_GREASE_PENCIL
@ OB_MODE_POSE
@ OB_MODE_TEXTURE_PAINT
@ OB_MODE_OBJECT
@ OB_MODE_WEIGHT_GREASE_PENCIL
@ OB_MODE_VERTEX_PAINT
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_MBALL
@ OB_SURF
@ OB_FONT
@ OB_GREASE_PENCIL
@ OB_ARMATURE
@ OB_MESH
@ OB_POINTCLOUD
@ OB_CURVES_LEGACY
@ OB_CURVES
#define BASE_SELECTED(v3d, base)
#define BASE_VISIBLE(v3d, base)
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_outliner_select_sync_from_object_tag(bContext *C)
void ED_object_wpaintmode_exit_ex(Object &ob)
void ED_object_vpaintmode_exit_ex(Object &ob)
void ED_object_texture_paint_mode_exit_ex(Main &bmain, Scene &scene, Object &ob)
bool ED_object_particle_edit_mode_supported(const Object *ob)
void ED_object_particle_edit_mode_exit_ex(Scene *scene, Object *ob)
void ED_undo_push(bContext *C, const char *str)
Definition ed_undo.cc:99
void ED_undo_group_begin(bContext *C)
Definition ed_undo.cc:87
void ED_undo_group_end(bContext *C)
Definition ed_undo.cc:93
bool ED_view3d_autodist_simple(ARegion *region, const int mval[2], float mouse_worldloc[3], int margin, const float *force_depth)
Base * ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
#define C
Definition RandGen.cpp:29
#define ND_OB_SELECT
Definition WM_types.hh:439
#define NC_SCENE
Definition WM_types.hh:375
@ OPTYPE_DEPENDS_ON_CURSOR
Definition WM_types.hh:218
@ OPTYPE_REGISTER
Definition WM_types.hh:180
ReportList * reports
Definition WM_types.hh:1025
@ WM_OP_EXEC_REGION_WIN
Definition WM_types.hh:246
#define ID_IS_EDITABLE(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
DEG_id_tag_update_ex(cb_data->bmain, cb_data->owner_id, ID_RECALC_TAG_FOR_UNDO|ID_RECALC_SYNC_TO_EVAL)
bool mode_generic_has_data(Depsgraph *depsgraph, const Object *ob)
static void object_overlay_mode_transfer_animation_start(bContext *C, Object *ob_dst)
static wmOperatorStatus object_transfer_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool ed_object_mode_generic_exit_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, bool only_test)
bool mode_set_ex(bContext *C, eObjectMode mode, bool use_undo, ReportList *reports)
void mode_generic_exit(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob)
static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Scene *scene, Object *, Object *ob_dst, const eObjectMode mode_dst)
bool mode_compat_test(const Object *ob, eObjectMode mode)
static void ed_object_posemode_set_for_weight_paint_ex(bContext *C, Main *bmain, Object *ob_arm, const bool is_mode_set)
void posemode_set_for_weight_paint(bContext *C, Main *bmain, Object *ob, bool is_mode_set)
bool mode_compat_set(bContext *C, Object *ob, eObjectMode mode, ReportList *reports)
static const char * object_mode_op_string(eObjectMode mode)
static bool object_transfer_mode_poll(bContext *C)
bool mode_set(bContext *C, eObjectMode mode)
bool editmode_exit_ex(Main *bmain, Scene *scene, Object *obedit, int flag)
static void object_transfer_mode_reposition_view_pivot(ARegion *region, Scene *scene, const int mval[2])
void OBJECT_OT_transfer_mode(wmOperatorType *ot)
void object_sculpt_mode_exit(Main &bmain, Depsgraph &depsgraph, Scene &scene, Object &ob)
bool ED_object_posemode_enter_ex(Main *bmain, Object *ob)
Definition pose_edit.cc:77
bool ED_object_posemode_exit_ex(Main *bmain, Object *ob)
Definition pose_edit.cc:112
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
short flag
struct Object * object
struct ID * orig_id
Definition DNA_ID.h:466
char name[66]
Definition DNA_ID.h:415
struct ModifierData * next
struct bPose * pose
ObjectRuntimeHandle * runtime
struct SculptSession * sculpt
struct ToolSettings * toolsettings
eObjectMode mode_type
Definition BKE_paint.hh:511
struct UnifiedPaintSettings unified_paint_settings
int mval[2]
Definition WM_types.hh:760
const char * name
Definition WM_types.hh:1030
wmOperatorStatus(*) invoke(bContext *C, wmOperator *op, const wmEvent *event) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1062
const char * idname
Definition WM_types.hh:1032
bool(*) poll(bContext *C) ATTR_WARN_UNUSED_RESULT
Definition WM_types.hh:1086
const char * description
Definition WM_types.hh:1036
StructRNA * srna
Definition WM_types.hh:1124
struct ReportList * reports
struct PointerRNA * ptr
@ WM_CURSOR_EYEDROPPER
Definition wm_cursors.hh:36
wmOperatorStatus WM_operator_name_call_ptr(bContext *C, wmOperatorType *ot, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
wmOperatorStatus WM_operator_name_call(bContext *C, const char *opstring, wmOperatorCallContext context, PointerRNA *properties, const wmEvent *event)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
void WM_toolsystem_update_from_context_view3d(bContext *C)