Blender V4.3
blenkernel/intern/context.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
9#include <cstddef>
10#include <cstdlib>
11#include <cstring>
12
13#include "MEM_guardedalloc.h"
14
17#include "DNA_linestyle_types.h"
18#include "DNA_object_types.h"
19#include "DNA_scene_types.h"
20#include "DNA_screen_types.h"
21#include "DNA_space_types.h"
22#include "DNA_view3d_types.h"
24#include "DNA_workspace_types.h"
25
26#include "DEG_depsgraph.hh"
27
28#include "BLI_listbase.h"
29#include "BLI_string.h"
30#include "BLI_threads.h"
31#include "BLI_utildefines.h"
32
33#include "BLT_translation.hh"
34
35#include "BKE_context.hh"
36#include "BKE_layer.hh"
37#include "BKE_main.hh"
38#include "BKE_scene.hh"
39#include "BKE_screen.hh"
40#include "BKE_sound.h"
41#include "BKE_wm_runtime.hh"
42#include "BKE_workspace.hh"
43
44#include "RE_engine.h"
45
46#include "RNA_access.hh"
47#include "RNA_prototypes.hh"
48
49#include "CLG_log.h"
50
51#ifdef WITH_PYTHON
52# include "BPY_extern.hh"
53#endif
54
55using blender::Vector;
56
57static CLG_LogRef LOG = {"bke.context"};
58
59/* struct */
60
104
105/* context */
106
108{
109 bContext *C = MEM_cnew<bContext>(__func__);
110
111 return C;
112}
113
115{
116 bContext *newC = MEM_cnew<bContext>(__func__);
117 *newC = *C;
118
119 memset(&newC->wm.operator_poll_msg_dyn_params, 0, sizeof(newC->wm.operator_poll_msg_dyn_params));
120
121 return newC;
122}
123
125{
126 /* This may contain a dynamically allocated message, free. */
128
129 MEM_freeN(C);
130}
131
132/* store */
133
137static bContextStore *ctx_store_extend(Vector<std::unique_ptr<bContextStore>> &contexts)
138{
139 /* ensure we have a context to put the entry in, if it was already used
140 * we have to copy the context to ensure */
141 if (contexts.is_empty()) {
142 contexts.append(std::make_unique<bContextStore>());
143 }
144 else if (contexts.last()->used) {
145 auto new_ctx = std::make_unique<bContextStore>(bContextStore{contexts.last()->entries, false});
146 contexts.append(std::move(new_ctx));
147 }
148
149 return contexts.last().get();
150}
151
152bContextStore *CTX_store_add(Vector<std::unique_ptr<bContextStore>> &contexts,
153 const blender::StringRefNull name,
154 const PointerRNA *ptr)
155{
156 bContextStore *ctx = ctx_store_extend(contexts);
157 ctx->entries.append(bContextStoreEntry{name, *ptr});
158 return ctx;
159}
160
161bContextStore *CTX_store_add(Vector<std::unique_ptr<bContextStore>> &contexts,
162 const blender::StringRefNull name,
164{
165 bContextStore *ctx = ctx_store_extend(contexts);
166 ctx->entries.append(bContextStoreEntry{name, std::string{str}});
167 return ctx;
168}
169
170bContextStore *CTX_store_add_all(Vector<std::unique_ptr<bContextStore>> &contexts,
171 const bContextStore *context)
172{
173 bContextStore *ctx = ctx_store_extend(contexts);
174 for (const bContextStoreEntry &src_entry : context->entries) {
175 ctx->entries.append(src_entry);
176 }
177 return ctx;
178}
179
181{
182 return C->wm.store;
183}
184
186{
187 C->wm.store = store;
188}
189
191 const blender::StringRefNull name,
192 const StructRNA *type)
193{
194 for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) {
195 if (entry->name == name && std::holds_alternative<PointerRNA>(entry->value)) {
196 const PointerRNA &ptr = std::get<PointerRNA>(entry->value);
197 if (!type || RNA_struct_is_a(ptr.type, type)) {
198 return &ptr;
199 }
200 }
201 }
202 return nullptr;
203}
204
205std::optional<blender::StringRefNull> CTX_store_string_lookup(const bContextStore *store,
206 const blender::StringRefNull name)
207{
208 for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) {
209 if (entry->name == name && std::holds_alternative<std::string>(entry->value)) {
210 return std::get<std::string>(entry->value);
211 }
212 }
213 return {};
214}
215
216/* is python initialized? */
217
219{
220 return C->data.py_init;
221}
222void CTX_py_init_set(bContext *C, bool value)
223{
224 C->data.py_init = value;
225}
226
228{
229 return C->data.py_context;
230}
232{
233 return C->data.py_context_orig;
234}
235
236void CTX_py_state_push(bContext *C, bContext_PyState *pystate, void *value)
237{
238 pystate->py_context = C->data.py_context;
239 pystate->py_context_orig = C->data.py_context_orig;
240
241 C->data.py_context = value;
242 C->data.py_context_orig = value;
243}
245{
246 C->data.py_context = pystate->py_context;
247 C->data.py_context_orig = pystate->py_context_orig;
248}
249
250/* data context utility functions */
251
261
263 const char *member,
264 const StructRNA *member_type,
265 void *fall_through)
266{
267#ifdef WITH_PYTHON
268 if (UNLIKELY(C && CTX_py_dict_get(C))) {
269 bContextDataResult result{};
270 BPY_context_member_get((bContext *)C, member, &result);
271
272 if (result.ptr.data) {
273 if (RNA_struct_is_a(result.ptr.type, member_type)) {
274 return result.ptr.data;
275 }
276
277 CLOG_WARN(&LOG,
278 "PyContext '%s' is a '%s', expected a '%s'",
279 member,
280 RNA_struct_identifier(result.ptr.type),
281 RNA_struct_identifier(member_type));
282 }
283 }
284#else
285 UNUSED_VARS(C, member, member_type);
286#endif
287
288 /* don't allow UI context access from non-main threads */
289 if (!BLI_thread_is_main()) {
290 return nullptr;
291 }
292
293 return fall_through;
294}
295
296static eContextResult ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
297{
298 bScreen *screen;
299 ScrArea *area;
300 ARegion *region;
301 int done = 0, recursion = C->data.recursion;
302 int ret = 0;
303
304 *result = {};
305#ifdef WITH_PYTHON
306 if (CTX_py_dict_get(C)) {
307 if (BPY_context_member_get(C, member, result)) {
308 return CTX_RESULT_OK;
309 }
310 }
311#endif
312
313 /* don't allow UI context access from non-main threads */
314 if (!BLI_thread_is_main()) {
316 }
317
318 /* we check recursion to ensure that we do not get infinite
319 * loops requesting data from ourselves in a context callback */
320
321 /* Ok, this looks evil...
322 * if (ret) done = -(-ret | -done);
323 *
324 * Values in order of importance
325 * (0, -1, 1) - Where 1 is highest priority
326 */
327 if (done != 1 && recursion < 1 && C->wm.store) {
328 C->data.recursion = 1;
329
330 const PointerRNA *ptr = CTX_store_ptr_lookup(C->wm.store, member, nullptr);
331
332 if (ptr) {
333 result->ptr = *ptr;
334 done = 1;
335 }
336 else {
337 std::optional<blender::StringRefNull> str = CTX_store_string_lookup(C->wm.store, member);
338
339 if (str) {
340 result->str = *str;
341 result->type = CTX_DATA_TYPE_STRING;
342 done = 1;
343 }
344 }
345 }
346 if (done != 1 && recursion < 2 && (region = CTX_wm_region(C))) {
347 C->data.recursion = 2;
348 if (region->type && region->type->context) {
349 ret = region->type->context(C, member, result);
350 if (ret) {
351 done = -(-ret | -done);
352 }
353 }
354 }
355 if (done != 1 && recursion < 3 && (area = CTX_wm_area(C))) {
356 C->data.recursion = 3;
357 if (area->type && area->type->context) {
358 ret = area->type->context(C, member, result);
359 if (ret) {
360 done = -(-ret | -done);
361 }
362 }
363 }
364
365 if (done != 1 && recursion < 4 && (screen = CTX_wm_screen(C))) {
366 bContextDataCallback cb = reinterpret_cast<bContextDataCallback>(screen->context);
367 C->data.recursion = 4;
368 if (cb) {
369 ret = cb(C, member, result);
370 if (ret) {
371 done = -(-ret | -done);
372 }
373 }
374 }
375
376 C->data.recursion = recursion;
377
378 return eContextResult(done);
379}
380
381static void *ctx_data_pointer_get(const bContext *C, const char *member)
382{
384 if (C && ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
385 BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
386 return result.ptr.data;
387 }
388
389 return nullptr;
390}
391
392static bool ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
393{
394 /* if context is nullptr, pointer must be nullptr too and that is a valid return */
395 if (C == nullptr) {
396 *pointer = nullptr;
397 return true;
398 }
399
401 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
402 BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
403 *pointer = result.ptr.data;
404 return true;
405 }
406
407 *pointer = nullptr;
408 return false;
409}
410
412 const char *member,
413 Vector<PointerRNA> *list)
414{
416 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
417 BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
418 *list = std::move(result.list);
419 return true;
420 }
421
422 list->clear();
423 return false;
424}
425
427 const char *member,
428 Vector<PointerRNA> *list)
429{
430 Vector<PointerRNA> ctx_object_list;
431 if ((ctx_data_collection_get(C, member, &ctx_object_list) == false) ||
432 ctx_object_list.is_empty())
433 {
434 list->clear();
435 return false;
436 }
437
438 bContextDataResult result{};
439
440 Scene *scene = CTX_data_scene(C);
441 ViewLayer *view_layer = CTX_data_view_layer(C);
442 BKE_view_layer_synced_ensure(scene, view_layer);
443
444 bool ok = false;
445
446 for (PointerRNA &ctx_object : ctx_object_list) {
447 Object *ob = static_cast<Object *>(ctx_object.data);
448 Base *base = BKE_view_layer_base_find(view_layer, ob);
449 if (base != nullptr) {
450 CTX_data_list_add(&result, &scene->id, &RNA_ObjectBase, base);
451 ok = true;
452 }
453 }
455
456 *list = std::move(result.list);
457 return ok;
458}
459
460PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
461{
463 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
464 BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
465 return result.ptr;
466 }
467
468 return PointerRNA_NULL;
469}
470
471PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
472{
474
475 if (ptr.data) {
476 if (RNA_struct_is_a(ptr.type, type)) {
477 return ptr;
478 }
479
480 CLOG_WARN(&LOG,
481 "member '%s' is '%s', not '%s'",
482 member,
485 }
486
487 return PointerRNA_NULL;
488}
489
491{
493
494 if (ptr.data && RNA_struct_is_a(ptr.type, type)) {
495 return ptr;
496 }
497
498 return PointerRNA_NULL;
499}
500
502{
504 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
505 BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
506 return result.list;
507 }
508 return {};
509}
510
512 const char *propname)
513{
514 for (PointerRNA &ptr : collection_pointers) {
515 ptr = RNA_pointer_get(&ptr, propname);
516 }
517}
518
519std::optional<blender::StringRefNull> CTX_data_string_get(const bContext *C, const char *member)
520{
522 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
523 BLI_assert(result.type == CTX_DATA_TYPE_STRING);
524 return result.str;
525 }
526
527 return {};
528}
529
530int /*eContextResult*/ CTX_data_get(const bContext *C,
531 const char *member,
532 PointerRNA *r_ptr,
533 Vector<PointerRNA> *r_lb,
534 PropertyRNA **r_prop,
535 int *r_index,
536 blender::StringRef *r_str,
537 short *r_type)
538{
540 eContextResult ret = ctx_data_get((bContext *)C, member, &result);
541
542 if (ret == CTX_RESULT_OK) {
543 *r_ptr = result.ptr;
544 *r_lb = result.list;
545 *r_prop = result.prop;
546 *r_index = result.index;
547 *r_str = result.str;
548 *r_type = result.type;
549 }
550 else {
551 *r_ptr = {};
552 r_lb->clear();
553 *r_str = "";
554 *r_type = 0;
555 }
556
557 return ret;
558}
559
560static void data_dir_add(ListBase *lb, const char *member, const bool use_all)
561{
562 LinkData *link;
563
564 if ((use_all == false) && STREQ(member, "scene")) { /* exception */
565 return;
566 }
567
568 if (BLI_findstring(lb, member, offsetof(LinkData, data))) {
569 return;
570 }
571
572 link = MEM_cnew<LinkData>(__func__);
573 link->data = (void *)member;
574 BLI_addtail(lb, link);
575}
576
578 const bool use_store,
579 const bool use_rna,
580 const bool use_all)
581{
582 bContextDataResult result{};
583 ListBase lb;
584 bScreen *screen;
585 ScrArea *area;
586 ARegion *region;
587 int a;
588
589 memset(&lb, 0, sizeof(lb));
590
591 if (use_rna) {
592 char name_buf[256], *name;
593 int namelen;
594
595 PropertyRNA *iterprop;
596 PointerRNA ctx_ptr = RNA_pointer_create(nullptr, &RNA_Context, (void *)C);
597
598 iterprop = RNA_struct_iterator_property(ctx_ptr.type);
599
600 RNA_PROP_BEGIN (&ctx_ptr, itemptr, iterprop) {
601 name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), &namelen);
602 data_dir_add(&lb, name, use_all);
603 if (name != name_buf) {
604 MEM_freeN(name);
605 }
606 }
608 }
609 if (use_store && C->wm.store) {
610 for (const bContextStoreEntry &entry : C->wm.store->entries) {
611 data_dir_add(&lb, entry.name.c_str(), use_all);
612 }
613 }
614 if ((region = CTX_wm_region(C)) && region->type && region->type->context) {
615 region->type->context(C, "", &result);
616
617 if (result.dir) {
618 for (a = 0; result.dir[a]; a++) {
619 data_dir_add(&lb, result.dir[a], use_all);
620 }
621 }
622 }
623 if ((area = CTX_wm_area(C)) && area->type && area->type->context) {
624 area->type->context(C, "", &result);
625
626 if (result.dir) {
627 for (a = 0; result.dir[a]; a++) {
628 data_dir_add(&lb, result.dir[a], use_all);
629 }
630 }
631 }
632 if ((screen = CTX_wm_screen(C)) && screen->context) {
633 bContextDataCallback cb = reinterpret_cast<bContextDataCallback>(screen->context);
634 cb(C, "", &result);
635
636 if (result.dir) {
637 for (a = 0; result.dir[a]; a++) {
638 data_dir_add(&lb, result.dir[a], use_all);
639 }
640 }
641 }
642
643 return lb;
644}
645
647{
648 return CTX_data_dir_get_ex(C, true, false, false);
649}
650
651bool CTX_data_equals(const char *member, const char *str)
652{
653 return STREQ(member, str);
654}
655
656bool CTX_data_dir(const char *member)
657{
658 return member[0] == '\0';
659}
660
662{
663 result->ptr = RNA_id_pointer_create(id);
664}
665
666void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
667{
668 result->ptr = RNA_pointer_create(id, type, data);
669}
670
672{
673 result->ptr = *ptr;
674}
675
677{
678 result->list.append(RNA_id_pointer_create(id));
679}
680
681void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
682{
683 result->list.append(RNA_pointer_create(id, type, data));
684}
685
687{
688 result->list.append(*ptr);
689}
690
692 bool (*func)(const bContext *, blender::Vector<PointerRNA> *))
693{
695 if (func(C, &list)) {
696 return list.size();
697 }
698 return 0;
699}
700
701void CTX_data_prop_set(bContextDataResult *result, PropertyRNA *prop, int index)
702{
703 result->prop = prop;
704 result->index = index;
705}
706
707void CTX_data_dir_set(bContextDataResult *result, const char **dir)
708{
709 result->dir = dir;
710}
711
712void CTX_data_type_set(bContextDataResult *result, short type)
713{
714 result->type = type;
715}
716
718{
719 return result->type;
720}
721
722/* window manager context */
723
725{
726 return C->wm.manager;
727}
728
730{
731 return C->wm.manager->runtime->is_interface_locked;
732}
733
735{
736 return static_cast<wmWindow *>(
737 ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window));
738}
739
741{
742 return static_cast<WorkSpace *>(
743 ctx_wm_python_context_get(C, "workspace", &RNA_WorkSpace, C->wm.workspace));
744}
745
747{
748 return static_cast<bScreen *>(ctx_wm_python_context_get(C, "screen", &RNA_Screen, C->wm.screen));
749}
750
752{
753 return static_cast<ScrArea *>(ctx_wm_python_context_get(C, "area", &RNA_Area, C->wm.area));
754}
755
757{
758 ScrArea *area = CTX_wm_area(C);
759 return (area) ? static_cast<SpaceLink *>(area->spacedata.first) : nullptr;
760}
761
763{
764 return static_cast<ARegion *>(ctx_wm_python_context_get(C, "region", &RNA_Region, C->wm.region));
765}
766
768{
769 ARegion *region = CTX_wm_region(C);
770 return (region) ? region->regiondata : nullptr;
771}
772
774{
775 return C->wm.region_popup;
776}
777
779{
780 return C->wm.gizmo_group;
781}
782
784{
785 return C->wm.manager ? C->wm.manager->message_bus : nullptr;
786}
787
789{
790 if (C->wm.manager) {
791 return &(C->wm.manager->runtime->reports);
792 }
793
794 return nullptr;
795}
796
798{
799 ScrArea *area = CTX_wm_area(C);
800 if (area && area->spacetype == SPACE_VIEW3D) {
801 return static_cast<View3D *>(area->spacedata.first);
802 }
803 return nullptr;
804}
805
807{
808 ScrArea *area = CTX_wm_area(C);
809 ARegion *region = CTX_wm_region(C);
810
811 if (area && area->spacetype == SPACE_VIEW3D) {
812 if (region && region->regiontype == RGN_TYPE_WINDOW) {
813 return static_cast<RegionView3D *>(region->regiondata);
814 }
815 }
816 return nullptr;
817}
818
820{
821 ScrArea *area = CTX_wm_area(C);
822 if (area && area->spacetype == SPACE_TEXT) {
823 return static_cast<SpaceText *>(area->spacedata.first);
824 }
825 return nullptr;
826}
827
829{
830 ScrArea *area = CTX_wm_area(C);
831 if (area && area->spacetype == SPACE_CONSOLE) {
832 return static_cast<SpaceConsole *>(area->spacedata.first);
833 }
834 return nullptr;
835}
836
838{
839 ScrArea *area = CTX_wm_area(C);
840 if (area && area->spacetype == SPACE_IMAGE) {
841 return static_cast<SpaceImage *>(area->spacedata.first);
842 }
843 return nullptr;
844}
845
847{
848 ScrArea *area = CTX_wm_area(C);
849 if (area && area->spacetype == SPACE_PROPERTIES) {
850 return static_cast<SpaceProperties *>(area->spacedata.first);
851 }
852 return nullptr;
853}
854
856{
857 ScrArea *area = CTX_wm_area(C);
858 if (area && area->spacetype == SPACE_FILE) {
859 return static_cast<SpaceFile *>(area->spacedata.first);
860 }
861 return nullptr;
862}
863
865{
866 ScrArea *area = CTX_wm_area(C);
867 if (area && area->spacetype == SPACE_SEQ) {
868 return static_cast<SpaceSeq *>(area->spacedata.first);
869 }
870 return nullptr;
871}
872
874{
875 ScrArea *area = CTX_wm_area(C);
876 if (area && area->spacetype == SPACE_OUTLINER) {
877 return static_cast<SpaceOutliner *>(area->spacedata.first);
878 }
879 return nullptr;
880}
881
883{
884 ScrArea *area = CTX_wm_area(C);
885 if (area && area->spacetype == SPACE_NLA) {
886 return static_cast<SpaceNla *>(area->spacedata.first);
887 }
888 return nullptr;
889}
890
892{
893 ScrArea *area = CTX_wm_area(C);
894 if (area && area->spacetype == SPACE_NODE) {
895 return static_cast<SpaceNode *>(area->spacedata.first);
896 }
897 return nullptr;
898}
899
901{
902 ScrArea *area = CTX_wm_area(C);
903 if (area && area->spacetype == SPACE_GRAPH) {
904 return static_cast<SpaceGraph *>(area->spacedata.first);
905 }
906 return nullptr;
907}
908
910{
911 ScrArea *area = CTX_wm_area(C);
912 if (area && area->spacetype == SPACE_ACTION) {
913 return static_cast<SpaceAction *>(area->spacedata.first);
914 }
915 return nullptr;
916}
917
919{
920 ScrArea *area = CTX_wm_area(C);
921 if (area && area->spacetype == SPACE_INFO) {
922 return static_cast<SpaceInfo *>(area->spacedata.first);
923 }
924 return nullptr;
925}
926
928{
929 ScrArea *area = CTX_wm_area(C);
930 if (area && area->spacetype == SPACE_USERPREF) {
931 return static_cast<SpaceUserPref *>(area->spacedata.first);
932 }
933 return nullptr;
934}
935
937{
938 ScrArea *area = CTX_wm_area(C);
939 if (area && area->spacetype == SPACE_CLIP) {
940 return static_cast<SpaceClip *>(area->spacedata.first);
941 }
942 return nullptr;
943}
944
946{
947 ScrArea *area = CTX_wm_area(C);
948 if (area && area->spacetype == SPACE_TOPBAR) {
949 return static_cast<SpaceTopBar *>(area->spacedata.first);
950 }
951 return nullptr;
952}
953
955{
956 ScrArea *area = CTX_wm_area(C);
957 if (area && area->spacetype == SPACE_SPREADSHEET) {
958 return static_cast<SpaceSpreadsheet *>(area->spacedata.first);
959 }
960 return nullptr;
961}
962
964{
965 C->wm.manager = wm;
966 C->wm.window = nullptr;
967 C->wm.screen = nullptr;
968 C->wm.area = nullptr;
969 C->wm.region = nullptr;
970}
971
972#ifdef WITH_PYTHON
973# define PYCTX_REGION_MEMBERS "region", "region_data"
974# define PYCTX_AREA_MEMBERS "area", "space_data", PYCTX_REGION_MEMBERS
975# define PYCTX_SCREEN_MEMBERS "screen", PYCTX_AREA_MEMBERS
976# define PYCTX_WINDOW_MEMBERS "window", "scene", "workspace", PYCTX_SCREEN_MEMBERS
977#endif
978
980{
981 C->wm.window = win;
982 if (win) {
983 C->data.scene = win->scene;
984 }
985 C->wm.workspace = (win) ? BKE_workspace_active_get(win->workspace_hook) : nullptr;
986 C->wm.screen = (win) ? BKE_workspace_active_screen_get(win->workspace_hook) : nullptr;
987 C->wm.area = nullptr;
988 C->wm.region = nullptr;
989
990#ifdef WITH_PYTHON
991 if (C->data.py_context != nullptr) {
992 const char *members[] = {PYCTX_WINDOW_MEMBERS};
994 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
995 }
996#endif
997}
998
1000{
1001 C->wm.screen = screen;
1002 C->wm.area = nullptr;
1003 C->wm.region = nullptr;
1004
1005#ifdef WITH_PYTHON
1006 if (C->data.py_context != nullptr) {
1007 const char *members[] = {PYCTX_SCREEN_MEMBERS};
1009 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1010 }
1011#endif
1012}
1013
1015{
1016 C->wm.area = area;
1017 C->wm.region = nullptr;
1018
1019#ifdef WITH_PYTHON
1020 if (C->data.py_context != nullptr) {
1021 const char *members[] = {PYCTX_AREA_MEMBERS};
1023 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1024 }
1025#endif
1026}
1027
1029{
1030 C->wm.region = region;
1031
1032#ifdef WITH_PYTHON
1033 if (C->data.py_context != nullptr) {
1034 const char *members[] = {PYCTX_REGION_MEMBERS};
1036 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1037 }
1038#endif
1039}
1040
1042{
1043 BLI_assert(region_popup == nullptr || region_popup->regiontype == RGN_TYPE_TEMPORARY);
1044 C->wm.region_popup = region_popup;
1045}
1046
1048{
1049 C->wm.gizmo_group = gzgroup;
1050}
1051
1053{
1054 bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params;
1055 if (params->free_fn != nullptr) {
1056 params->free_fn(C, params->user_data);
1057 }
1058 params->get_fn = nullptr;
1059 params->free_fn = nullptr;
1060 params->user_data = nullptr;
1061
1062 C->wm.operator_poll_msg = nullptr;
1063}
1065{
1067
1068 C->wm.operator_poll_msg = msg;
1069}
1070
1072{
1074
1075 C->wm.operator_poll_msg_dyn_params = *params;
1076}
1077
1078const char *CTX_wm_operator_poll_msg_get(bContext *C, bool *r_free)
1079{
1080 bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params;
1081 if (params->get_fn != nullptr) {
1082 char *msg = params->get_fn(C, params->user_data);
1083 if (msg != nullptr) {
1084 *r_free = true;
1085 }
1086 return msg;
1087 }
1088
1089 *r_free = false;
1090 return IFACE_(C->wm.operator_poll_msg);
1091}
1092
1093/* data context */
1094
1096{
1097 Main *bmain;
1098 if (ctx_data_pointer_verify(C, "blend_data", (void **)&bmain)) {
1099 return bmain;
1100 }
1101
1102 return C->data.main;
1103}
1104
1106{
1107 C->data.main = bmain;
1108 BKE_sound_init_main(bmain);
1109}
1110
1112{
1113 Scene *scene;
1114 if (ctx_data_pointer_verify(C, "scene", (void **)&scene)) {
1115 return scene;
1116 }
1117
1118 return C->data.scene;
1119}
1120
1122{
1123 ViewLayer *view_layer;
1124
1125 if (ctx_data_pointer_verify(C, "view_layer", (void **)&view_layer)) {
1126 return view_layer;
1127 }
1128
1129 wmWindow *win = CTX_wm_window(C);
1130 Scene *scene = CTX_data_scene(C);
1131 if (win) {
1132 view_layer = BKE_view_layer_find(scene, win->view_layer_name);
1133 if (view_layer) {
1134 return view_layer;
1135 }
1136 }
1137
1138 return BKE_view_layer_default_view(scene);
1139}
1140
1142{
1143 Scene *scene = CTX_data_scene(C);
1144 return RE_engines_find(scene->r.engine);
1145}
1146
1148{
1149 ViewLayer *view_layer = CTX_data_view_layer(C);
1150 LayerCollection *layer_collection;
1151
1152 if (ctx_data_pointer_verify(C, "layer_collection", (void **)&layer_collection)) {
1153 if (BKE_view_layer_has_collection(view_layer, layer_collection->collection)) {
1154 return layer_collection;
1155 }
1156 }
1157
1158 /* fallback */
1159 return BKE_layer_collection_get_active(view_layer);
1160}
1161
1163{
1164 Collection *collection;
1165 if (ctx_data_pointer_verify(C, "collection", (void **)&collection)) {
1166 return collection;
1167 }
1168
1169 LayerCollection *layer_collection = CTX_data_layer_collection(C);
1170 if (layer_collection) {
1171 return layer_collection->collection;
1172 }
1173
1174 /* fallback */
1175 Scene *scene = CTX_data_scene(C);
1176 return scene->master_collection;
1177}
1178
1180 const Object *ob,
1181 const eObjectMode object_mode)
1182{
1183 // Object *obedit = CTX_data_edit_object(C);
1184 if (obedit) {
1185 switch (obedit->type) {
1186 case OB_MESH:
1187 return CTX_MODE_EDIT_MESH;
1188 case OB_CURVES_LEGACY:
1189 return CTX_MODE_EDIT_CURVE;
1190 case OB_SURF:
1191 return CTX_MODE_EDIT_SURFACE;
1192 case OB_FONT:
1193 return CTX_MODE_EDIT_TEXT;
1194 case OB_ARMATURE:
1196 case OB_MBALL:
1198 case OB_LATTICE:
1199 return CTX_MODE_EDIT_LATTICE;
1200 case OB_CURVES:
1201 return CTX_MODE_EDIT_CURVES;
1202 case OB_GREASE_PENCIL:
1204 case OB_POINTCLOUD:
1206 }
1207 }
1208 else {
1209 // Object *ob = CTX_data_active_object(C);
1210 if (ob) {
1211 if (object_mode & OB_MODE_POSE) {
1212 return CTX_MODE_POSE;
1213 }
1214 if (object_mode & OB_MODE_SCULPT) {
1215 return CTX_MODE_SCULPT;
1216 }
1217 if (object_mode & OB_MODE_WEIGHT_PAINT) {
1218 return CTX_MODE_PAINT_WEIGHT;
1219 }
1220 if (object_mode & OB_MODE_VERTEX_PAINT) {
1221 return CTX_MODE_PAINT_VERTEX;
1222 }
1223 if (object_mode & OB_MODE_TEXTURE_PAINT) {
1225 }
1226 if (object_mode & OB_MODE_PARTICLE_EDIT) {
1227 return CTX_MODE_PARTICLE;
1228 }
1229 if (object_mode & OB_MODE_PAINT_GREASE_PENCIL) {
1230 if (ob->type == OB_GPENCIL_LEGACY) {
1232 }
1233 if (ob->type == OB_GREASE_PENCIL) {
1235 }
1236 }
1237 if (object_mode & OB_MODE_EDIT_GPENCIL_LEGACY) {
1239 }
1240 if (object_mode & OB_MODE_SCULPT_GREASE_PENCIL) {
1241 if (ob->type == OB_GPENCIL_LEGACY) {
1243 }
1244 if (ob->type == OB_GREASE_PENCIL) {
1246 }
1247 }
1248 if (object_mode & OB_MODE_WEIGHT_GREASE_PENCIL) {
1249 if (ob->type == OB_GPENCIL_LEGACY) {
1251 }
1252 if (ob->type == OB_GREASE_PENCIL) {
1254 }
1255 }
1256 if (object_mode & OB_MODE_VERTEX_GREASE_PENCIL) {
1257 if (ob->type == OB_GPENCIL_LEGACY) {
1259 }
1260 if (ob->type == OB_GREASE_PENCIL) {
1262 }
1263 }
1264 if (object_mode & OB_MODE_SCULPT_CURVES) {
1266 }
1267 }
1268 }
1269
1270 return CTX_MODE_OBJECT;
1271}
1272
1274{
1275 Object *obedit = CTX_data_edit_object(C);
1276 Object *obact = obedit ? nullptr : CTX_data_active_object(C);
1277 return CTX_data_mode_enum_ex(obedit, obact, obact ? eObjectMode(obact->mode) : OB_MODE_OBJECT);
1278}
1279
1285static const char *data_mode_strings[] = {
1286 "mesh_edit",
1287 "curve_edit",
1288 "surface_edit",
1289 "text_edit",
1290 "armature_edit",
1291 "mball_edit",
1292 "lattice_edit",
1293 "curves_edit",
1294 "grease_pencil_edit",
1295 "point_cloud_edit",
1296 "posemode",
1297 "sculpt_mode",
1298 "weightpaint",
1299 "vertexpaint",
1300 "imagepaint",
1301 "particlemode",
1302 "objectmode",
1303 "greasepencil_paint",
1304 "greasepencil_edit",
1305 "greasepencil_sculpt",
1306 "greasepencil_weight",
1307 "greasepencil_vertex",
1308 "curves_sculpt",
1309 "grease_pencil_paint",
1310 "grease_pencil_sculpt",
1311 "grease_pencil_weight",
1312 "grease_pencil_vertex",
1313 nullptr,
1314};
1316 "Must have a string for each context mode")
1317const char *CTX_data_mode_string(const bContext *C)
1318{
1320}
1321
1323{
1324 C->data.scene = scene;
1325
1326#ifdef WITH_PYTHON
1327 if (C->data.py_context != nullptr) {
1328 const char *members[] = {"scene"};
1329 BPY_context_dict_clear_members_array(&C->data.py_context, C->data.py_context_orig, members, 1);
1330 }
1331#endif
1332}
1333
1335{
1336 Scene *scene = CTX_data_scene(C);
1337
1338 if (scene) {
1339 return scene->toolsettings;
1340 }
1341
1342 return nullptr;
1343}
1344
1346{
1347 return ctx_data_collection_get(C, "selected_ids", list);
1348}
1349
1351{
1352 return ctx_data_collection_get(C, "selected_nodes", list);
1353}
1354
1356{
1357 return ctx_data_collection_get(C, "selected_editable_objects", list);
1358}
1359
1361{
1362 return ctx_data_base_collection_get(C, "selected_editable_objects", list);
1363}
1364
1366{
1367 return ctx_data_collection_get(C, "editable_objects", list);
1368}
1369
1371{
1372 return ctx_data_base_collection_get(C, "editable_objects", list);
1373}
1374
1376{
1377 return ctx_data_collection_get(C, "selected_objects", list);
1378}
1379
1381{
1382 return ctx_data_base_collection_get(C, "selected_objects", list);
1383}
1384
1386{
1387 return ctx_data_collection_get(C, "visible_objects", list);
1388}
1389
1391{
1392 return ctx_data_base_collection_get(C, "visible_objects", list);
1393}
1394
1396{
1397 return ctx_data_collection_get(C, "selectable_objects", list);
1398}
1399
1401{
1402 return ctx_data_base_collection_get(C, "selectable_objects", list);
1403}
1404
1406{
1407 return static_cast<Object *>(ctx_data_pointer_get(C, "active_object"));
1408}
1409
1411{
1413
1414 if (ob == nullptr) {
1415 return nullptr;
1416 }
1417 const Scene *scene = CTX_data_scene(C);
1418 ViewLayer *view_layer = CTX_data_view_layer(C);
1419 BKE_view_layer_synced_ensure(scene, view_layer);
1420 return BKE_view_layer_base_find(view_layer, ob);
1421}
1422
1424{
1425 return static_cast<Object *>(ctx_data_pointer_get(C, "edit_object"));
1426}
1427
1429{
1430 return static_cast<Image *>(ctx_data_pointer_get(C, "edit_image"));
1431}
1432
1434{
1435 return static_cast<Text *>(ctx_data_pointer_get(C, "edit_text"));
1436}
1437
1439{
1440 return static_cast<MovieClip *>(ctx_data_pointer_get(C, "edit_movieclip"));
1441}
1442
1444{
1445 return static_cast<Mask *>(ctx_data_pointer_get(C, "edit_mask"));
1446}
1447
1449{
1450 return static_cast<EditBone *>(ctx_data_pointer_get(C, "active_bone"));
1451}
1452
1454{
1455 return static_cast<CacheFile *>(ctx_data_pointer_get(C, "edit_cachefile"));
1456}
1457
1459{
1460 return ctx_data_collection_get(C, "selected_bones", list);
1461}
1462
1464{
1465 return ctx_data_collection_get(C, "selected_editable_bones", list);
1466}
1467
1469{
1470 return ctx_data_collection_get(C, "visible_bones", list);
1471}
1472
1474{
1475 return ctx_data_collection_get(C, "editable_bones", list);
1476}
1477
1479{
1480 return static_cast<bPoseChannel *>(ctx_data_pointer_get(C, "active_pose_bone"));
1481}
1482
1484{
1485 return ctx_data_collection_get(C, "selected_pose_bones", list);
1486}
1487
1490{
1491 return ctx_data_collection_get(C, "selected_pose_bones_from_active_object", list);
1492}
1493
1495{
1496 return ctx_data_collection_get(C, "visible_pose_bones", list);
1497}
1498
1500{
1501 return static_cast<AssetLibraryReference *>(ctx_data_pointer_get(C, "asset_library_reference"));
1502}
1503
1504static AssetHandle ctx_wm_asset_handle(const bContext *C, bool *r_is_valid)
1505{
1506 AssetHandle *asset_handle_p =
1507 (AssetHandle *)CTX_data_pointer_get_type(C, "asset_handle", &RNA_AssetHandle).data;
1508 if (asset_handle_p) {
1509 *r_is_valid = true;
1510 return *asset_handle_p;
1511 }
1512
1513 /* If the asset handle was not found in context directly, try if there's an active file with
1514 * asset data there instead. Not nice to have this here, would be better to have this in
1515 * `ED_asset.hh`, but we can't include that in BKE. Even better would be not needing this at all
1516 * and being able to have editors return this in the usual `context` callback. But that would
1517 * require returning a non-owning pointer, which we don't have in the Asset Browser (yet). */
1518 FileDirEntry *file =
1519 (FileDirEntry *)CTX_data_pointer_get_type(C, "active_file", &RNA_FileSelectEntry).data;
1520 if (file && file->asset) {
1521 *r_is_valid = true;
1522 return AssetHandle{file};
1523 }
1524
1525 *r_is_valid = false;
1526 return AssetHandle{nullptr};
1527}
1528
1530{
1531 if (auto *asset = static_cast<blender::asset_system::AssetRepresentation *>(
1532 ctx_data_pointer_get(C, "asset")))
1533 {
1534 return asset;
1535 }
1536
1537 /* Expose the asset representation from the asset-handle.
1538 * TODO(Julian): #AssetHandle should be properly replaced by #AssetRepresentation. */
1539 bool is_valid;
1540 if (AssetHandle handle = ctx_wm_asset_handle(C, &is_valid); is_valid) {
1541 return handle.file_data->asset;
1542 }
1543
1544 return nullptr;
1545}
1546
1548{
1549 Main *bmain = CTX_data_main(C);
1550 Scene *scene = CTX_data_scene(C);
1551 ViewLayer *view_layer = CTX_data_view_layer(C);
1552 Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
1553 /* Dependency graph might have been just allocated, and hence it will not be marked.
1554 * This confuses redo system due to the lack of flushing changes back to the original data.
1555 * In the future we would need to check whether the CTX_wm_window(C) is in editing mode (as an
1556 * opposite of playback-preview-only) and set active flag based on that. */
1558 return depsgraph;
1559}
1560
1562{
1563 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1564 /* TODO(sergey): Assert that the dependency graph is fully evaluated.
1565 * Note that first the depsgraph and scene post-evaluation hooks needs to run extra round of
1566 * updates first to make check here really reliable. */
1567 return depsgraph;
1568}
1569
1571{
1572 Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1573 Main *bmain = CTX_data_main(C);
1575 return depsgraph;
1576}
1577
1579{
1580 Scene *scene = CTX_data_scene(C);
1581 ViewLayer *view_layer = CTX_data_view_layer(C);
1582 return BKE_scene_get_depsgraph(scene, view_layer);
1583}
const char * CTX_data_mode_string(const bContext *C)
eContextObjectMode
@ CTX_MODE_VERTEX_GPENCIL_LEGACY
@ CTX_MODE_WEIGHT_GPENCIL_LEGACY
@ CTX_MODE_EDIT_POINT_CLOUD
@ CTX_MODE_SCULPT_GPENCIL_LEGACY
@ CTX_MODE_PAINT_GREASE_PENCIL
@ CTX_MODE_PAINT_GPENCIL_LEGACY
@ CTX_MODE_EDIT_CURVE
@ CTX_MODE_PAINT_TEXTURE
@ CTX_MODE_EDIT_SURFACE
@ CTX_MODE_SCULPT_GREASE_PENCIL
@ CTX_MODE_PARTICLE
@ CTX_MODE_SCULPT
@ CTX_MODE_OBJECT
@ CTX_MODE_EDIT_MESH
@ CTX_MODE_EDIT_GREASE_PENCIL
@ CTX_MODE_SCULPT_CURVES
@ CTX_MODE_EDIT_TEXT
@ CTX_MODE_EDIT_CURVES
@ CTX_MODE_EDIT_ARMATURE
@ CTX_MODE_EDIT_LATTICE
@ CTX_MODE_WEIGHT_GREASE_PENCIL
@ CTX_MODE_VERTEX_GREASE_PENCIL
@ CTX_MODE_PAINT_VERTEX
@ CTX_MODE_EDIT_METABALL
@ CTX_MODE_PAINT_WEIGHT
@ CTX_MODE_EDIT_GPENCIL_LEGACY
@ CTX_MODE_POSE
#define CTX_MODE_NUM
int(*)(const bContext *C, const char *member, bContextDataResult *result) bContextDataCallback
eContextResult
@ CTX_RESULT_MEMBER_NOT_FOUND
@ CTX_RESULT_OK
@ CTX_DATA_TYPE_POINTER
@ CTX_DATA_TYPE_COLLECTION
@ CTX_DATA_TYPE_STRING
bool BKE_view_layer_has_collection(const ViewLayer *view_layer, const Collection *collection)
LayerCollection * BKE_layer_collection_get_active(ViewLayer *view_layer)
void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer)
ViewLayer * BKE_view_layer_default_view(const Scene *scene)
ViewLayer * BKE_view_layer_find(const Scene *scene, const char *layer_name)
Base * BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob)
void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain)
Definition scene.cc:2573
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3377
Depsgraph * BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
Definition scene.cc:3364
void BKE_sound_init_main(struct Main *bmain)
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:613
WorkSpace * BKE_workspace_active_get(WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:562
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:87
#define BLI_assert(a)
Definition BLI_assert.h:50
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
int BLI_thread_is_main(void)
Definition threads.cc:179
#define ARRAY_SIZE(arr)
#define UNUSED_VARS(...)
#define UNLIKELY(x)
#define STREQ(a, b)
#define IFACE_(msgid)
void BPY_context_dict_clear_members_array(void **dict_p, void *dict_orig, const char *context_members[], uint context_members_len)
int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:181
void DEG_make_active(Depsgraph *depsgraph)
Definition depsgraph.cc:331
Object groups, one object can be in many groups at once.
eObjectMode
@ OB_MODE_VERTEX_GREASE_PENCIL
@ OB_MODE_PARTICLE_EDIT
@ OB_MODE_EDIT_GPENCIL_LEGACY
@ 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_GPENCIL_LEGACY
@ OB_CURVES
@ RGN_TYPE_TEMPORARY
@ RGN_TYPE_WINDOW
@ SPACE_TEXT
@ SPACE_CLIP
@ SPACE_ACTION
@ SPACE_CONSOLE
@ SPACE_OUTLINER
@ SPACE_TOPBAR
@ SPACE_NODE
@ SPACE_SPREADSHEET
@ SPACE_USERPREF
@ SPACE_FILE
@ SPACE_PROPERTIES
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
@ SPACE_INFO
Read Guarded memory(de)allocation.
#define RNA_PROP_END
#define RNA_PROP_BEGIN(sptr, itemptr, prop)
constexpr PointerRNA PointerRNA_NULL
Definition RNA_types.hh:45
#define C
Definition RandGen.cpp:29
bContextStore * CTX_store_add_all(Vector< std::unique_ptr< bContextStore > > &contexts, const bContextStore *context)
short CTX_data_type_get(bContextDataResult *result)
SpaceGraph * CTX_wm_space_graph(const bContext *C)
Image * CTX_data_edit_image(const bContext *C)
bool CTX_data_selectable_bases(const bContext *C, blender::Vector< PointerRNA > *list)
Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
void CTX_data_main_set(bContext *C, Main *bmain)
PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
void CTX_wm_gizmo_group_set(bContext *C, wmGizmoGroup *gzgroup)
void CTX_py_state_push(bContext *C, bContext_PyState *pystate, void *value)
WorkSpace * CTX_wm_workspace(const bContext *C)
const PointerRNA * CTX_store_ptr_lookup(const bContextStore *store, const blender::StringRefNull name, const StructRNA *type)
bool CTX_data_visible_bones(const bContext *C, blender::Vector< PointerRNA > *list)
bool CTX_wm_interface_locked(const bContext *C)
SpaceText * CTX_wm_space_text(const bContext *C)
void CTX_data_dir_set(bContextDataResult *result, const char **dir)
bool CTX_data_selected_bones(const bContext *C, blender::Vector< PointerRNA > *list)
bPoseChannel * CTX_data_active_pose_bone(const bContext *C)
PointerRNA CTX_data_pointer_get_type_silent(const bContext *C, const char *member, StructRNA *type)
SpaceUserPref * CTX_wm_space_userpref(const bContext *C)
SpaceTopBar * CTX_wm_space_topbar(const bContext *C)
void CTX_data_id_list_add(bContextDataResult *result, ID *id)
SpaceImage * CTX_wm_space_image(const bContext *C)
bool CTX_data_equals(const char *member, const char *str)
ReportList * CTX_wm_reports(const bContext *C)
bScreen * CTX_wm_screen(const bContext *C)
SpaceNla * CTX_wm_space_nla(const bContext *C)
bool CTX_data_visible_bases(const bContext *C, blender::Vector< PointerRNA > *list)
bool CTX_data_visible_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Mask * CTX_data_edit_mask(const bContext *C)
bool CTX_py_init_get(bContext *C)
void CTX_data_prop_set(bContextDataResult *result, PropertyRNA *prop, int index)
static AssetHandle ctx_wm_asset_handle(const bContext *C, bool *r_is_valid)
void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
LayerCollection * CTX_data_layer_collection(const bContext *C)
bool CTX_data_selected_pose_bones_from_active_object(const bContext *C, blender::Vector< PointerRNA > *list)
SpaceOutliner * CTX_wm_space_outliner(const bContext *C)
bContextStore * CTX_store_add(Vector< std::unique_ptr< bContextStore > > &contexts, const blender::StringRefNull name, const PointerRNA *ptr)
static void * ctx_wm_python_context_get(const bContext *C, const char *member, const StructRNA *member_type, void *fall_through)
static eContextResult ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
CacheFile * CTX_data_edit_cachefile(const bContext *C)
MovieClip * CTX_data_edit_movieclip(const bContext *C)
bool CTX_data_dir(const char *member)
static void data_dir_add(ListBase *lb, const char *member, const bool use_all)
void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
void * CTX_wm_region_data(const bContext *C)
static const char * data_mode_strings[]
void CTX_py_state_pop(bContext *C, bContext_PyState *pystate)
SpaceAction * CTX_wm_space_action(const bContext *C)
SpaceConsole * CTX_wm_space_console(const bContext *C)
void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
ARegion * CTX_wm_region_popup(const bContext *C)
void CTX_wm_operator_poll_msg_clear(bContext *C)
void CTX_py_init_set(bContext *C, bool value)
SpaceFile * CTX_wm_space_file(const bContext *C)
PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
SpaceNode * CTX_wm_space_node(const bContext *C)
bContext * CTX_copy(const bContext *C)
SpaceProperties * CTX_wm_space_properties(const bContext *C)
void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
bool CTX_data_editable_bones(const bContext *C, blender::Vector< PointerRNA > *list)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
static bool ctx_data_base_collection_get(const bContext *C, const char *member, Vector< PointerRNA > *list)
static bContextStore * ctx_store_extend(Vector< std::unique_ptr< bContextStore > > &contexts)
static void * ctx_data_pointer_get(const bContext *C, const char *member)
void CTX_free(bContext *C)
Object * CTX_data_active_object(const bContext *C)
Vector< PointerRNA > CTX_data_collection_get(const bContext *C, const char *member)
ListBase CTX_data_dir_get(const bContext *C)
const AssetLibraryReference * CTX_wm_asset_library_ref(const bContext *C)
void CTX_wm_operator_poll_msg_set_dynamic(bContext *C, const bContextPollMsgDyn_Params *params)
Text * CTX_data_edit_text(const bContext *C)
blender::asset_system::AssetRepresentation * CTX_wm_asset(const bContext *C)
RenderEngineType * CTX_data_engine_type(const bContext *C)
SpaceLink * CTX_wm_space_data(const bContext *C)
void CTX_wm_screen_set(bContext *C, bScreen *screen)
void CTX_data_scene_set(bContext *C, Scene *scene)
Scene * CTX_data_scene(const bContext *C)
static bool ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
ListBase CTX_data_dir_get_ex(const bContext *C, const bool use_store, const bool use_rna, const bool use_all)
int ctx_data_list_count(const bContext *C, bool(*func)(const bContext *, blender::Vector< PointerRNA > *))
SpaceSeq * CTX_wm_space_seq(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
bool CTX_data_selectable_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Base * CTX_data_active_base(const bContext *C)
enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, const Object *ob, const eObjectMode object_mode)
void CTX_wm_window_set(bContext *C, wmWindow *win)
bool CTX_data_selected_objects(const bContext *C, blender::Vector< PointerRNA > *list)
Main * CTX_data_main(const bContext *C)
bool CTX_data_selected_editable_objects(const bContext *C, blender::Vector< PointerRNA > *list)
bool CTX_data_visible_pose_bones(const bContext *C, blender::Vector< PointerRNA > *list)
bool CTX_data_editable_objects(const bContext *C, blender::Vector< PointerRNA > *list)
bool CTX_data_editable_bases(const bContext *C, blender::Vector< PointerRNA > *list)
void * CTX_py_dict_get_orig(const bContext *C)
static bool ctx_data_collection_get(const bContext *C, const char *member, Vector< PointerRNA > *list)
const bContextStore * CTX_store_get(const bContext *C)
void CTX_data_list_add_ptr(bContextDataResult *result, const PointerRNA *ptr)
static CLG_LogRef LOG
bool CTX_data_selected_nodes(const bContext *C, blender::Vector< PointerRNA > *list)
const char * CTX_wm_operator_poll_msg_get(bContext *C, bool *r_free)
void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr)
void CTX_store_set(bContext *C, const bContextStore *store)
wmGizmoGroup * CTX_wm_gizmo_group(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
bool CTX_data_selected_editable_bases(const bContext *C, blender::Vector< PointerRNA > *list)
SpaceInfo * CTX_wm_space_info(const bContext *C)
bool CTX_data_selected_pose_bones(const bContext *C, blender::Vector< PointerRNA > *list)
void CTX_data_collection_remap_property(blender::MutableSpan< PointerRNA > collection_pointers, const char *propname)
void CTX_wm_area_set(bContext *C, ScrArea *area)
SpaceClip * CTX_wm_space_clip(const bContext *C)
bool CTX_data_selected_bases(const bContext *C, blender::Vector< PointerRNA > *list)
EditBone * CTX_data_active_bone(const bContext *C)
std::optional< blender::StringRefNull > CTX_store_string_lookup(const bContextStore *store, const blender::StringRefNull name)
void CTX_wm_region_set(bContext *C, ARegion *region)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
Collection * CTX_data_collection(const bContext *C)
bool CTX_data_selected_editable_bones(const bContext *C, blender::Vector< PointerRNA > *list)
void * CTX_py_dict_get(const bContext *C)
Depsgraph * CTX_data_depsgraph_on_load(const bContext *C)
SpaceSpreadsheet * CTX_wm_space_spreadsheet(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
int CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, Vector< PointerRNA > *r_lb, PropertyRNA **r_prop, int *r_index, blender::StringRef *r_str, short *r_type)
bContext * CTX_create()
std::optional< blender::StringRefNull > CTX_data_string_get(const bContext *C, const char *member)
wmMsgBus * CTX_wm_message_bus(const bContext *C)
void CTX_data_type_set(bContextDataResult *result, short type)
void CTX_wm_region_popup_set(bContext *C, ARegion *region_popup)
View3D * CTX_wm_view3d(const bContext *C)
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
bool CTX_data_selected_ids(const bContext *C, blender::Vector< PointerRNA > *list)
int64_t size() const
void append(const T &value)
bool is_empty() const
const Depsgraph * depsgraph
#define offsetof(t, d)
#define str(s)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
RenderEngineType * RE_engines_find(const char *idname)
static char ** members
Definition makesdna.cc:69
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
return ret
bool RNA_struct_is_a(const StructRNA *type, const StructRNA *srna)
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
char * RNA_struct_name_get_alloc(PointerRNA *ptr, char *fixedbuf, int fixedlen, int *r_len)
const char * RNA_struct_identifier(const StructRNA *type)
PointerRNA RNA_pointer_create(ID *id, StructRNA *type, void *data)
PropertyRNA * RNA_struct_iterator_property(StructRNA *type)
PointerRNA RNA_id_pointer_create(ID *id)
Definition DNA_ID.h:413
struct Collection * collection
void * data
StructRNA * type
Definition RNA_types.hh:41
void * data
Definition RNA_types.hh:42
PropertyType type
blender::StringRefNull str
blender::Vector< bContextStoreEntry > entries
const char * operator_poll_msg
bContextPollMsgDyn_Params operator_poll_msg_dyn_params
const bContextStore * store
struct bContext::@80 data
wmGizmoGroup * gizmo_group
struct bContext::@79 wm
wmWindowManager * manager
WindowManagerRuntimeHandle * runtime
struct Scene * scene
struct WorkSpaceInstanceHook * workspace_hook
PointerRNA * ptr
Definition wm_files.cc:4126