Blender V5.0
eyedropper_color.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13
14#include "MEM_guardedalloc.h"
15
16#include "DNA_material_types.h"
17#include "DNA_scene_types.h"
18#include "DNA_screen_types.h"
19#include "DNA_space_types.h"
20
21#include "BLI_listbase.h"
22#include "BLI_math_vector.h"
23#include "BLI_string.h"
24#include "BLI_string_ref.hh"
25
26#include "BKE_context.hh"
27#include "BKE_cryptomatte.h"
28#include "BKE_image.hh"
29#include "BKE_material.hh"
30#include "BKE_report.hh"
31#include "BKE_screen.hh"
32
33#include "BLT_translation.hh"
34
35#include "NOD_composite.hh"
36
37#include "RNA_access.hh"
38#include "RNA_define.hh"
39#include "RNA_path.hh"
40#include "RNA_prototypes.hh"
41
43#include "IMB_imbuf_types.hh"
44
45#include "WM_api.hh"
46#include "WM_types.hh"
47
48#include "interface_intern.hh"
49
50#include "ED_clip.hh"
51#include "ED_image.hh"
52#include "ED_node.hh"
53#include "ED_screen.hh"
54#include "ED_view3d.hh"
55
56#include "RE_pipeline.h"
57
58#include "eyedropper_intern.hh"
59
60struct Eyedropper {
61 const ColorManagedDisplay *display = nullptr;
62
64 PropertyRNA *prop = nullptr;
65 int index = 0;
66 bool is_undo = false;
67
68 bool is_set = false;
69 float init_col[3] = {}; /* for resetting on cancel */
70
71 bool accum_start = false; /* has mouse been pressed */
72 float accum_col[3] = {};
73 int accum_tot = 0;
74
75 wmWindow *cb_win = nullptr;
76 int cb_win_event_xy[2] = {};
77 void *draw_handle_sample_text = nullptr;
79
80 bNode *crypto_node = nullptr;
83};
84
85static void eyedropper_draw_cb(const wmWindow * /*window*/, void *arg)
86{
87 Eyedropper *eye = static_cast<Eyedropper *>(arg);
89}
90
92{
93 Eyedropper *eye = MEM_new<Eyedropper>(__func__);
94
95 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "prop_data_path");
96 if (prop && RNA_property_is_set(op->ptr, prop)) {
97 std::string prop_data_path = RNA_string_get(op->ptr, "prop_data_path");
98 if (prop_data_path.empty()) {
99 MEM_delete(eye);
100 return false;
101 }
102 PointerRNA ctx_ptr = RNA_pointer_create_discrete(nullptr, &RNA_Context, C);
103 if (!RNA_path_resolve(&ctx_ptr, prop_data_path.c_str(), &eye->ptr, &eye->prop)) {
104 BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", prop_data_path.c_str());
105 MEM_delete(eye);
106 return false;
107 }
108 eye->is_undo = true;
109 }
110 else {
111 uiBut *but = UI_context_active_but_prop_get(C, &eye->ptr, &eye->prop, &eye->index);
112 if (but != nullptr) {
114 }
115 }
116
117 const enum PropertySubType prop_subtype = eye->prop ? RNA_property_subtype(eye->prop) :
119
120 if ((eye->ptr.data == nullptr) || (eye->prop == nullptr) ||
121 (RNA_property_editable(&eye->ptr, eye->prop) == false) ||
122 (RNA_property_array_length(&eye->ptr, eye->prop) < 3) ||
123 (RNA_property_type(eye->prop) != PROP_FLOAT) ||
124 (ELEM(prop_subtype, PROP_COLOR, PROP_COLOR_GAMMA) == 0))
125 {
126 MEM_delete(eye);
127 return false;
128 }
129 op->customdata = eye;
130
131 float col[4];
133 if (eye->ptr.type == &RNA_CompositorNodeCryptomatteV2) {
134 eye->crypto_node = (bNode *)eye->ptr.data;
136 eye->cb_win = CTX_wm_window(C);
138 }
139
140 if (prop_subtype != PROP_COLOR) {
141 Scene *scene = CTX_data_scene(C);
142 const char *display_device;
143
144 display_device = scene->display_settings.display_device;
145 eye->display = IMB_colormanagement_display_get_named(display_device);
146
147 /* store initial color */
148 if (eye->display) {
150 }
151 }
152 copy_v3_v3(eye->init_col, col);
153
154 return true;
155}
156
158{
159 Eyedropper *eye = static_cast<Eyedropper *>(op->customdata);
160 wmWindow *window = CTX_wm_window(C);
162
163 ED_workspace_status_text(C, nullptr);
164
165 if (eye->draw_handle_sample_text) {
167 eye->draw_handle_sample_text = nullptr;
168 }
169
170 if (eye->cryptomatte_session) {
172 eye->cryptomatte_session = nullptr;
173 }
174
175 if (eye->viewport_session) {
176 MEM_delete(eye->viewport_session);
177 eye->viewport_session = nullptr;
178 }
179
180 op->customdata = nullptr;
181 MEM_delete(eye);
182}
183
184/* *** eyedropper_color_ helper functions *** */
185
187 const char *type_name,
188 const int mval[2],
189 float r_col[3])
190{
191 int material_slot = 0;
192 Object *object = ED_view3d_give_material_slot_under_cursor(C, mval, &material_slot);
193 if (!object) {
194 return false;
195 }
196
197 const ID *id = nullptr;
198 if (blender::StringRef(type_name).endswith(RE_PASSNAME_CRYPTOMATTE_OBJECT)) {
199 id = &object->id;
200 }
201 else if (blender::StringRef(type_name).endswith(RE_PASSNAME_CRYPTOMATTE_MATERIAL)) {
202 Material *material = BKE_object_material_get(object, material_slot);
203 if (!material) {
204 return false;
205 }
206 id = &material->id;
207 }
208
209 if (!id) {
210 return false;
211 }
212
213 const char *name = &id->name[2];
214 const int name_length = BLI_strnlen(name, MAX_NAME - 2);
215 uint32_t cryptomatte_hash = BKE_cryptomatte_hash(name, name_length);
216 r_col[0] = BKE_cryptomatte_hash_to_float(cryptomatte_hash);
217 return true;
218}
219
221 const char *prefix,
222 const float fpos[2],
223 float r_col[3])
224{
225 if (!render_layer) {
226 return false;
227 }
228
229 const int render_layer_name_len = STRNLEN(render_layer->name);
230 if (strncmp(prefix, render_layer->name, render_layer_name_len) != 0) {
231 return false;
232 }
233
234 const int prefix_len = strlen(prefix);
235 if (prefix_len <= render_layer_name_len + 1) {
236 return false;
237 }
238
239 /* RenderResult from images can have no render layer name. */
240 const char *render_pass_name_prefix = render_layer_name_len ?
241 prefix + 1 + render_layer_name_len :
242 prefix;
243
244 LISTBASE_FOREACH (RenderPass *, render_pass, &render_layer->passes) {
245 if (STRPREFIX(render_pass->name, render_pass_name_prefix) &&
246 !STREQLEN(render_pass->name, render_pass_name_prefix, sizeof(render_pass->name)))
247 {
248 BLI_assert(render_pass->channels == 4);
249
250 /* Pass was allocated but not rendered yet. */
251 if (!render_pass->ibuf) {
252 return false;
253 }
254
255 const int x = int(fpos[0] * render_pass->rectx);
256 const int y = int(fpos[1] * render_pass->recty);
257 const int offset = 4 * (y * render_pass->rectx + x);
258 zero_v3(r_col);
259 r_col[0] = render_pass->ibuf->float_buffer.data[offset];
260 return true;
261 }
262 }
263
264 return false;
265}
266
268 const char *prefix,
269 const float fpos[2],
270 float r_col[3])
271{
272 bool success = false;
273 Scene *scene = (Scene *)node->id;
274 BLI_assert(GS(scene->id.name) == ID_SCE);
275 Render *re = RE_GetSceneRender(scene);
276
277 if (re) {
279 if (rr) {
280 LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
281 RenderLayer *render_layer = RE_GetRenderLayer(rr, view_layer->name);
282 success = eyedropper_cryptomatte_sample_renderlayer_fl(render_layer, prefix, fpos, r_col);
283 if (success) {
284 break;
285 }
286 }
287 }
289 }
290 return success;
291}
292
294 const bNode *node,
295 NodeCryptomatte *crypto,
296 const char *prefix,
297 const float fpos[2],
298 float r_col[3])
299{
300 bool success = false;
301 Image *image = (Image *)node->id;
302 BLI_assert((image == nullptr) || (GS(image->id.name) == ID_IM));
303
304 /* Compute the effective frame number of the image if it was animated. */
305 Scene *scene = CTX_data_scene(C);
306 ImageUser image_user_for_frame = crypto->iuser;
307 BKE_image_user_frame_calc(image, &image_user_for_frame, scene->r.cfra);
308
309 if (image && image->type == IMA_TYPE_MULTILAYER) {
310 ImBuf *ibuf = BKE_image_acquire_ibuf(image, &image_user_for_frame, nullptr);
311 if (image->rr) {
312 LISTBASE_FOREACH (RenderLayer *, render_layer, &image->rr->layers) {
313 success = eyedropper_cryptomatte_sample_renderlayer_fl(render_layer, prefix, fpos, r_col);
314 if (success) {
315 break;
316 }
317 }
318 }
319 BKE_image_release_ibuf(image, ibuf, nullptr);
320 }
321 return success;
322}
323
325 Eyedropper *eye,
326 const int event_xy[2],
327 float r_col[3])
328{
329 bNode *node = eye->crypto_node;
330 NodeCryptomatte *crypto = node ? ((NodeCryptomatte *)node->storage) : nullptr;
331
332 if (!crypto) {
333 return false;
334 }
335
336 ScrArea *area = nullptr;
337
338 int event_xy_win[2];
339 wmWindow *win = WM_window_find_under_cursor(CTX_wm_window(C), event_xy, event_xy_win);
340 if (win) {
342 area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event_xy_win);
343 }
344
345 eye->cb_win_event_xy[0] = event_xy_win[0];
346 eye->cb_win_event_xy[1] = event_xy_win[1];
347
348 if (win && win != eye->cb_win && eye->draw_handle_sample_text) {
350 eye->cb_win = win;
353 }
354
355 if (!area || !ELEM(area->spacetype, SPACE_IMAGE, SPACE_NODE, SPACE_CLIP, SPACE_VIEW3D)) {
356 return false;
357 }
358
359 ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, event_xy_win);
360
361 if (!region) {
362 return false;
363 }
364
365 const int mval[2] = {
366 event_xy_win[0] - region->winrct.xmin,
367 event_xy_win[1] - region->winrct.ymin,
368 };
369 float fpos[2] = {-1.0f, -1.0};
370 switch (area->spacetype) {
371 case SPACE_IMAGE: {
372 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
373 ED_space_image_get_position(sima, region, mval, fpos);
374 break;
375 }
376 case SPACE_NODE: {
377 Main *bmain = CTX_data_main(C);
378 SpaceNode *snode = static_cast<SpaceNode *>(area->spacedata.first);
379 ED_space_node_get_position(bmain, snode, region, mval, fpos);
380 break;
381 }
382 case SPACE_CLIP: {
383 SpaceClip *sc = static_cast<SpaceClip *>(area->spacedata.first);
384 ED_space_clip_get_position(sc, region, mval, fpos);
385 break;
386 }
387 default: {
388 break;
389 }
390 }
391
392 if (area->spacetype != SPACE_VIEW3D &&
393 (fpos[0] < 0.0f || fpos[1] < 0.0f || fpos[0] >= 1.0f || fpos[1] >= 1.0f))
394 {
395 return false;
396 }
397
398 /* CMP_NODE_CRYPTOMATTE_SOURCE_RENDER and CMP_NODE_CRYPTOMATTE_SOURCE_IMAGE require a referenced
399 * image/scene to work properly. */
400 if (!node->id) {
401 return false;
402 }
403
404 ED_region_tag_redraw(region);
405
406 /* TODO(jbakker): Migrate this file to cc and use std::string as return param. */
407 char prefix[MAX_NAME + 1];
408 ntreeCompositCryptomatteLayerPrefix(node, prefix, sizeof(prefix) - 1);
409 prefix[MAX_NAME] = '\0';
410
411 if (area->spacetype == SPACE_VIEW3D) {
412 wmWindow *win_prev = CTX_wm_window(C);
413 ScrArea *area_prev = CTX_wm_area(C);
414 ARegion *region_prev = CTX_wm_region(C);
415
416 CTX_wm_window_set(C, win);
417 CTX_wm_area_set(C, area);
418 CTX_wm_region_set(C, region);
419
420 const bool success = eyedropper_cryptomatte_sample_view3d_fl(C, prefix, mval, r_col);
421
422 CTX_wm_window_set(C, win_prev);
423 CTX_wm_area_set(C, area_prev);
424 CTX_wm_region_set(C, region_prev);
425
426 return success;
427 }
429 return eyedropper_cryptomatte_sample_render_fl(node, prefix, fpos, r_col);
430 }
432 return eyedropper_cryptomatte_sample_image_fl(C, node, crypto, prefix, fpos, r_col);
433 }
434 return false;
435}
436
438 Eyedropper *eye,
439 const int event_xy[2],
440 float r_col[3])
441{
442 ScrArea *area = nullptr;
443
444 int event_xy_win[2];
445 wmWindow *win = WM_window_find_under_cursor(CTX_wm_window(C), event_xy, event_xy_win);
446 if (win) {
448 area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, event_xy_win);
449 }
450
451 if (area) {
452 ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, event_xy_win);
453 if (region) {
454 const int mval[2] = {
455 event_xy_win[0] - region->winrct.xmin,
456 event_xy_win[1] - region->winrct.ymin,
457 };
458 if (area->spacetype == SPACE_IMAGE) {
459 SpaceImage *sima = static_cast<SpaceImage *>(area->spacedata.first);
460 if (ED_space_image_color_sample(sima, region, mval, r_col, nullptr)) {
461 return true;
462 }
463 }
464 else if (area->spacetype == SPACE_NODE) {
465 SpaceNode *snode = static_cast<SpaceNode *>(area->spacedata.first);
466 Main *bmain = CTX_data_main(C);
467 if (ED_space_node_color_sample(bmain, snode, region, mval, r_col)) {
468 return true;
469 }
470 }
471 else if (area->spacetype == SPACE_CLIP) {
472 SpaceClip *sc = static_cast<SpaceClip *>(area->spacedata.first);
473 if (ED_space_clip_color_sample(sc, region, mval, r_col)) {
474 return true;
475 }
476 }
477 else if (eye != nullptr && area->spacetype == SPACE_VIEW3D) {
478 /* Viewport color picking involves a fairly expensive operation to copy the GPU viewport
479 * back to the CPU, so to support smooth dragging with the eyedropper, we keep the copy
480 * around for the entire operation. */
481 if (eye->viewport_session == nullptr) {
482 eye->viewport_session = MEM_new<ViewportColorSampleSession>("viewport_session");
483 eye->viewport_session->init(region);
484 }
485 if (eye->viewport_session->sample(mval, r_col)) {
486 return true;
487 }
488 }
489 }
490 }
491
492 /* Other areas within a Blender window. */
493 if (win) {
494 if (!WM_window_pixels_read_sample(C, win, event_xy_win, r_col)) {
495 WM_window_pixels_read_sample_from_offscreen(C, win, event_xy_win, r_col);
496 }
497 const char *display_device = CTX_data_scene(C)->display_settings.display_device;
498 const ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
500 return true;
501 }
502
503 /* Outside the Blender window if we support it. */
507 return true;
508 }
509 }
510
511 zero_v3(r_col);
512 return false;
513}
514
515/* sets the sample color RGB, maintaining A */
516static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
517{
518 float col_conv[4];
519
520 /* to maintain alpha */
521 RNA_property_float_get_array_at_most(&eye->ptr, eye->prop, col_conv, ARRAY_SIZE(col_conv));
522
523 /* convert from linear rgb space to display space */
524 if (eye->display) {
525 copy_v3_v3(col_conv, col);
527 }
528 else {
529 copy_v3_v3(col_conv, col);
530 }
531
532 RNA_property_float_set_array_at_most(&eye->ptr, eye->prop, col_conv, ARRAY_SIZE(col_conv));
533 eye->is_set = true;
534
535 RNA_property_update(C, &eye->ptr, eye->prop);
536}
537
538static void eyedropper_color_sample(bContext *C, Eyedropper *eye, const int event_xy[2])
539{
540 /* Accumulate color. */
541 float col[3];
542 if (eye->crypto_node) {
543 if (!eyedropper_cryptomatte_sample_fl(C, eye, event_xy, col)) {
544 return;
545 }
546 }
547 else {
548 if (!eyedropper_color_sample_fl(C, eye, event_xy, col)) {
549 return;
550 }
551 }
552
553 if (!eye->crypto_node) {
554 add_v3_v3(eye->accum_col, col);
555 eye->accum_tot++;
556 }
557 else {
558 copy_v3_v3(eye->accum_col, col);
559 eye->accum_tot = 1;
560 }
561
562 /* Apply to property. */
563 float accum_col[3];
564 if (eye->accum_tot > 1) {
565 mul_v3_v3fl(accum_col, eye->accum_col, 1.0f / float(eye->accum_tot));
566 }
567 else {
568 copy_v3_v3(accum_col, eye->accum_col);
569 }
570 eyedropper_color_set(C, eye, accum_col);
571}
572
574 Eyedropper *eye,
575 const int event_xy[2])
576{
577 float col[3];
578 eye->sample_text[0] = '\0';
579
580 if (eye->cryptomatte_session) {
581 if (eyedropper_cryptomatte_sample_fl(C, eye, event_xy, col)) {
583 eye->cryptomatte_session, col[0], eye->sample_text, sizeof(eye->sample_text));
584 eye->sample_text[sizeof(eye->sample_text) - 1] = '\0';
585 }
586 }
587}
588
590{
591 Eyedropper *eye = static_cast<Eyedropper *>(op->customdata);
592 if (eye->is_set) {
593 eyedropper_color_set(C, eye, eye->init_col);
594 }
595 eyedropper_exit(C, op);
596}
597
598/* main modal status check */
600{
601 Eyedropper *eye = (Eyedropper *)op->customdata;
602
603 /* handle modal keymap */
604 if (event->type == EVT_MODAL_MAP) {
605 switch (event->val) {
606 case EYE_MODAL_CANCEL:
607 eyedropper_cancel(C, op);
608 return OPERATOR_CANCELLED;
610 const bool is_undo = eye->is_undo;
611 if (eye->accum_tot == 0) {
612 eyedropper_color_sample(C, eye, event->xy);
613 }
614 eyedropper_exit(C, op);
615 /* Could support finished & undo-skip. */
616 return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
617 }
619 /* enable accum and make first sample */
620 eye->accum_start = true;
621 eyedropper_color_sample(C, eye, event->xy);
622 break;
624 eye->accum_tot = 0;
625 zero_v3(eye->accum_col);
626 eyedropper_color_sample(C, eye, event->xy);
627 break;
628 }
629 }
630 else if (ISMOUSE_MOTION(event->type)) {
631 if (eye->accum_start) {
632 /* button is pressed so keep sampling */
633 eyedropper_color_sample(C, eye, event->xy);
635 status.item(TIP_("Drag to continue sampling, release when done"), ICON_MOUSE_MOVE);
636 }
637 else {
639 status.opmodal(IFACE_("Confirm"), op->type, EYE_MODAL_SAMPLE_CONFIRM);
640 status.opmodal(IFACE_("Cancel"), op->type, EYE_MODAL_CANCEL);
641#ifdef __APPLE__
642 status.item(TIP_("Press 'Enter' to sample outside of a Blender window"), ICON_INFO);
643#endif
644 }
645
646 if (eye->draw_handle_sample_text) {
648 }
649 }
650
652}
653
654/* Modal Operator init */
656{
657 /* init */
658 if (eyedropper_init(C, op)) {
659 wmWindow *win = CTX_wm_window(C);
660 /* Workaround for de-activating the button clearing the cursor, see #76794 */
663
664 /* add temp handler */
666
668 }
670}
671
672/* Repeat operator */
674{
675 /* init */
676 if (eyedropper_init(C, op)) {
677
678 /* do something */
679
680 /* cleanup */
681 eyedropper_exit(C, op);
682
683 return OPERATOR_FINISHED;
684 }
686}
687
689{
690 /* Actual test for active button happens later, since we don't
691 * know which one is active until mouse over. */
692 return (CTX_wm_window(C) != nullptr);
693}
694
696{
697 /* identifiers */
698 ot->name = "Eyedropper";
699 ot->idname = "UI_OT_eyedropper_color";
700 ot->description = "Sample a color from the Blender window to store in a property";
701
702 /* API callbacks. */
703 ot->invoke = eyedropper_invoke;
704 ot->modal = eyedropper_modal;
705 ot->cancel = eyedropper_cancel;
706 ot->exec = eyedropper_exec;
707 ot->poll = eyedropper_poll;
708
709 /* flags */
711
712 /* Paths relative to the context. */
713 PropertyRNA *prop;
714 prop = RNA_def_string(ot->srna,
715 "prop_data_path",
716 nullptr,
717 0,
718 "Data Path",
719 "Path of property to be set with the depth");
721}
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
void CTX_wm_window_set(bContext *C, wmWindow *win)
Main * CTX_data_main(const bContext *C)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
ARegion * CTX_wm_region(const bContext *C)
float BKE_cryptomatte_hash_to_float(uint32_t cryptomatte_hash)
uint32_t BKE_cryptomatte_hash(const char *name, int name_len)
bool BKE_cryptomatte_find_name(const struct CryptomatteSession *session, float encoded_hash, char *r_name, int name_maxncpy)
void BKE_cryptomatte_free(struct CryptomatteSession *session)
ImBuf * BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **r_lock)
void BKE_image_user_frame_calc(Image *ima, ImageUser *iuser, int cfra)
void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
General operations, lookup, etc. for materials.
Material * BKE_object_material_get(Object *ob, short act)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
@ RPT_ERROR
Definition BKE_report.hh:39
ARegion * BKE_area_find_region_xy(const ScrArea *area, int regiontype, const int xy[2]) ATTR_NONNULL(3)
Definition screen.cc:875
ScrArea ScrArea * BKE_screen_find_area_xy(const bScreen *screen, int spacetype, const int xy[2]) ATTR_NONNULL(1
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
int char char int int int int size_t BLI_strnlen(const char *str, size_t maxlen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.cc:913
#define STRNLEN(str)
Definition BLI_string.h:613
#define STRPREFIX(a, b)
#define ARRAY_SIZE(arr)
#define STREQLEN(a, b, n)
#define ELEM(...)
#define TIP_(msgid)
#define IFACE_(msgid)
@ ID_IM
@ ID_SCE
#define MAX_NAME
Definition DNA_defs.h:50
@ IMA_TYPE_MULTILAYER
@ CMP_NODE_CRYPTOMATTE_SOURCE_IMAGE
@ CMP_NODE_CRYPTOMATTE_SOURCE_RENDER
#define RE_PASSNAME_CRYPTOMATTE_MATERIAL
#define RE_PASSNAME_CRYPTOMATTE_OBJECT
@ RGN_TYPE_WINDOW
@ SPACE_CLIP
@ SPACE_NODE
@ SPACE_IMAGE
@ SPACE_VIEW3D
#define SPACE_TYPE_ANY
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
bool ED_space_clip_get_position(const SpaceClip *sc, const ARegion *region, const int mval[2], float r_fpos[2])
bool ED_space_clip_color_sample(const SpaceClip *sc, const ARegion *region, const int mval[2], float r_col[3])
bool ED_space_image_get_position(SpaceImage *sima, ARegion *region, const int mval[2], float r_fpos[2])
bool ED_space_image_color_sample(SpaceImage *sima, ARegion *region, const int mval[2], float r_col[3], bool *r_is_data)
bool ED_space_node_get_position(Main *bmain, SpaceNode *snode, ARegion *region, const int mval[2], float fpos[2])
Definition node_view.cc:473
bool ED_space_node_color_sample(Main *bmain, SpaceNode *snode, ARegion *region, const int mval[2], float r_col[3])
Definition node_view.cc:500
void ED_workspace_status_text(bContext *C, const char *str)
Definition area.cc:1024
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:618
Object * ED_view3d_give_material_slot_under_cursor(bContext *C, const int mval[2], int *r_material_slot)
BLI_INLINE void IMB_colormanagement_srgb_to_scene_linear_v3(float scene_linear[3], const float srgb[3])
void IMB_colormanagement_display_to_scene_linear_v3(float pixel[3], const ColorManagedDisplay *display, const ColorManagedDisplaySpace display_space=DISPLAY_SPACE_DRAW)
const ColorManagedDisplay * IMB_colormanagement_display_get_named(const char *name)
void IMB_colormanagement_scene_linear_to_display_v3(float pixel[3], const ColorManagedDisplay *display, const ColorManagedDisplaySpace display_space=DISPLAY_SPACE_DRAW)
Read Guarded memory(de)allocation.
@ PROP_FLOAT
Definition RNA_types.hh:164
@ PROP_SKIP_SAVE
Definition RNA_types.hh:344
@ PROP_HIDDEN
Definition RNA_types.hh:338
PropertySubType
Definition RNA_types.hh:232
@ PROP_COLOR
Definition RNA_types.hh:260
@ PROP_COLOR_GAMMA
Definition RNA_types.hh:272
#define C
Definition RandGen.cpp:29
@ UI_BUT_UNDO
uiBut * UI_context_active_but_prop_get(const bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
void UI_context_active_but_clear(bContext *C, wmWindow *win, ARegion *region)
bool UI_but_flag_is_set(uiBut *but, int flag)
blender::ocio::Display ColorManagedDisplay
@ WM_CAPABILITY_DESKTOP_SAMPLE
Definition WM_api.hh:197
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_UNDO
Definition WM_types.hh:182
bool init(ARegion *region)
bool sample(const int mval[2], float r_col[3])
static wmOperatorStatus eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *)
static void eyedropper_color_sample_text_update(bContext *C, Eyedropper *eye, const int event_xy[2])
static bool eyedropper_init(bContext *C, wmOperator *op)
static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
static void eyedropper_cancel(bContext *C, wmOperator *op)
static void eyedropper_exit(bContext *C, wmOperator *op)
static bool eyedropper_cryptomatte_sample_renderlayer_fl(RenderLayer *render_layer, const char *prefix, const float fpos[2], float r_col[3])
static void eyedropper_color_sample(bContext *C, Eyedropper *eye, const int event_xy[2])
static bool eyedropper_cryptomatte_sample_image_fl(bContext *C, const bNode *node, NodeCryptomatte *crypto, const char *prefix, const float fpos[2], float r_col[3])
bool eyedropper_color_sample_fl(bContext *C, Eyedropper *eye, const int event_xy[2], float r_col[3])
static bool eyedropper_cryptomatte_sample_fl(bContext *C, Eyedropper *eye, const int event_xy[2], float r_col[3])
static wmOperatorStatus eyedropper_exec(bContext *C, wmOperator *op)
static void eyedropper_draw_cb(const wmWindow *, void *arg)
static bool eyedropper_cryptomatte_sample_render_fl(const bNode *node, const char *prefix, const float fpos[2], float r_col[3])
void UI_OT_eyedropper_color(wmOperatorType *ot)
static bool eyedropper_poll(bContext *C)
static wmOperatorStatus eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
static bool eyedropper_cryptomatte_sample_view3d_fl(bContext *C, const char *type_name, const int mval[2], float r_col[3])
@ EYE_MODAL_SAMPLE_BEGIN
@ EYE_MODAL_SAMPLE_RESET
@ EYE_MODAL_CANCEL
@ EYE_MODAL_SAMPLE_CONFIRM
void eyedropper_draw_cursor_text_region(const int xy[2], const char *name)
#define GS(x)
uint col
void ntreeCompositCryptomatteLayerPrefix(const bNode *node, char *r_prefix, size_t prefix_maxncpy)
CryptomatteSession * ntreeCompositCryptomatteSession(bNode *node)
const char * name
const int status
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
PropertyType RNA_property_type(PropertyRNA *prop)
void RNA_property_float_get_array_at_most(PointerRNA *ptr, PropertyRNA *prop, float *values, int values_num)
void RNA_property_update(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_float_set_array_at_most(PointerRNA *ptr, PropertyRNA *prop, const float *values, int values_num)
std::string RNA_string_get(PointerRNA *ptr, const char *name)
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
bool RNA_property_editable(const PointerRNA *ptr, PropertyRNA *prop)
PropertySubType RNA_property_subtype(PropertyRNA *prop)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
PropertyRNA * RNA_def_string(StructOrFunctionRNA *cont_, const char *identifier, const char *default_value, const int maxlen, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
bool RNA_path_resolve(const PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition rna_path.cc:532
RenderResult * RE_AcquireResultRead(Render *re)
RenderLayer * RE_GetRenderLayer(RenderResult *rr, const char *name)
void RE_ReleaseResult(Render *re)
Render * RE_GetSceneRender(const Scene *scene)
bNode * crypto_node
int cb_win_event_xy[2]
char sample_text[MAX_NAME]
const ColorManagedDisplay * display
float accum_col[3]
ViewportColorSampleSession * viewport_session
float init_col[3]
PropertyRNA * prop
PointerRNA ptr
CryptomatteSession * cryptomatte_session
void * draw_handle_sample_text
wmWindow * cb_win
Definition DNA_ID.h:414
char name[258]
Definition DNA_ID.h:432
struct RenderResult * rr
void * first
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
ListBase passes
Definition RE_pipeline.h:94
char name[RE_MAXNAME]
Definition RE_pipeline.h:89
ListBase layers
struct RenderData r
ListBase view_layers
ColorManagedDisplaySettings display_settings
ListBase spacedata
int16_t custom1
struct ID * id
void * storage
int ymin
int xmin
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
int xy[2]
Definition WM_types.hh:761
struct ReportList * reports
struct wmOperatorType * type
struct PointerRNA * ptr
void WM_cursor_modal_set(wmWindow *win, int val)
void WM_cursor_modal_restore(wmWindow *win)
@ WM_CURSOR_EYEDROPPER
Definition wm_cursors.hh:36
void * WM_draw_cb_activate(wmWindow *win, void(*draw)(const wmWindow *win, void *customdata), void *customdata)
Definition wm_draw.cc:635
bool WM_window_pixels_read_sample_from_offscreen(bContext *C, wmWindow *win, const int pos[2], float r_col[3])
Definition wm_draw.cc:1448
void WM_draw_cb_exit(wmWindow *win, void *handle)
Definition wm_draw.cc:648
bool WM_desktop_cursor_sample_read(float r_col[3])
Definition wm_draw.cc:1501
bool WM_window_pixels_read_sample(bContext *C, wmWindow *win, const int pos[2], float r_col[3])
Definition wm_draw.cc:1492
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
#define ISMOUSE_MOTION(event_type)
@ EVT_MODAL_MAP
wmOperatorType * ot
Definition wm_files.cc:4237
wmWindow * WM_window_find_under_cursor(wmWindow *win, const int event_xy[2], int r_event_xy_other[2])
eWM_CapabilitiesFlag WM_capabilities_flag()
bScreen * WM_window_get_active_screen(const wmWindow *win)