Blender V5.0
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
8
9#include <cstddef>
10#include <cstdlib>
11#include <cstring>
12
13#include <fmt/format.h>
14
15#include "MEM_guardedalloc.h"
16
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_threads.h"
30#include "BLI_utildefines.h"
31
32#include "BLT_translation.hh"
33
34#include "BKE_context.hh"
35#include "BKE_layer.hh"
36#include "BKE_main.hh"
37#include "BKE_scene.hh"
38#include "BKE_screen.hh"
39#include "BKE_sound.h"
40#include "BKE_wm_runtime.hh"
41#include "BKE_workspace.hh"
42
43#include "RE_engine.h"
44
45#include "RNA_access.hh"
46#include "RNA_prototypes.hh"
47
48#include "CLG_log.h"
49
50/* Logging. */
52
53#ifdef WITH_PYTHON
54# include "BPY_extern.hh"
55#endif
56
57using blender::Vector;
58
59static CLG_LogRef LOG = {"context"};
60
61/* struct */
62
108
109/* context */
110
112{
113 bContext *C = MEM_callocN<bContext>(__func__);
114
115 return C;
116}
117
119{
120 bContext *newC = MEM_callocN<bContext>(__func__);
121 *newC = *C;
122
123 memset(&newC->wm.operator_poll_msg_dyn_params, 0, sizeof(newC->wm.operator_poll_msg_dyn_params));
124
125 return newC;
126}
127
129{
130 /* This may contain a dynamically allocated message, free. */
132
133 MEM_freeN(C);
134}
135
136/* store */
137
141static bContextStore *ctx_store_extend(Vector<std::unique_ptr<bContextStore>> &contexts)
142{
143 /* ensure we have a context to put the entry in, if it was already used
144 * we have to copy the context to ensure */
145 if (contexts.is_empty()) {
146 contexts.append(std::make_unique<bContextStore>());
147 }
148 else if (contexts.last()->used) {
149 auto new_ctx = std::make_unique<bContextStore>(bContextStore{contexts.last()->entries, false});
150 contexts.append(std::move(new_ctx));
151 }
152
153 return contexts.last().get();
154}
155
156bContextStore *CTX_store_add(Vector<std::unique_ptr<bContextStore>> &contexts,
158 const PointerRNA *ptr)
159{
160 bContextStore *ctx = ctx_store_extend(contexts);
162 return ctx;
163}
164
165bContextStore *CTX_store_add(Vector<std::unique_ptr<bContextStore>> &contexts,
168{
169 bContextStore *ctx = ctx_store_extend(contexts);
170 ctx->entries.append(bContextStoreEntry{name, std::string{str}});
171 return ctx;
172}
173
174bContextStore *CTX_store_add(Vector<std::unique_ptr<bContextStore>> &contexts,
176 const int64_t value)
177{
178 bContextStore *ctx = ctx_store_extend(contexts);
180 return ctx;
181}
182
183bContextStore *CTX_store_add_all(Vector<std::unique_ptr<bContextStore>> &contexts,
184 const bContextStore *context)
185{
186 bContextStore *ctx = ctx_store_extend(contexts);
187 for (const bContextStoreEntry &src_entry : context->entries) {
188 ctx->entries.append(src_entry);
189 }
190 return ctx;
191}
192
194{
195 return C->wm.store;
196}
197
199{
200 C->wm.store = store;
201}
202
205 const StructRNA *type)
206{
207 for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) {
208 if (entry->name == name && std::holds_alternative<PointerRNA>(entry->value)) {
209 const PointerRNA &ptr = std::get<PointerRNA>(entry->value);
210 if (!type || RNA_struct_is_a(ptr.type, type)) {
211 return &ptr;
212 }
213 }
214 }
215 return nullptr;
216}
217
218template<typename T>
220{
221 for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) {
222 if (entry->name == name && std::holds_alternative<T>(entry->value)) {
223 return &std::get<T>(entry->value);
224 }
225 }
226 return nullptr;
227}
228
229std::optional<blender::StringRefNull> CTX_store_string_lookup(const bContextStore *store,
231{
232 if (const std::string *value = ctx_store_lookup_impl<std::string>(store, name)) {
233 return *value;
234 }
235 return {};
236}
237
238std::optional<int64_t> CTX_store_int_lookup(const bContextStore *store,
240{
241 if (const int64_t *value = ctx_store_lookup_impl<int64_t>(store, name)) {
242 return *value;
243 }
244 return {};
245}
246
247/* is python initialized? */
248
250{
251 return C->data.py_init;
252}
253void CTX_py_init_set(bContext *C, bool value)
254{
255 C->data.py_init = value;
256}
257
259{
260 return C->data.py_context;
261}
263{
264 return C->data.py_context_orig;
265}
266
267void CTX_py_state_push(bContext *C, bContext_PyState *pystate, void *value)
268{
269 pystate->py_context = C->data.py_context;
270 pystate->py_context_orig = C->data.py_context_orig;
271
272 C->data.py_context = value;
273 C->data.py_context_orig = value;
274}
276{
277 C->data.py_context = pystate->py_context;
278 C->data.py_context_orig = pystate->py_context_orig;
279}
280
281/* data context utility functions */
282
293
296{
297 switch (result.type) {
299 if (result.ptr.data) {
300 const char *rna_type_name = result.ptr.type ? RNA_struct_identifier(result.ptr.type) :
301 "Unknown";
302 /* Try to get the name property if it exists. */
303 std::string member_name;
304 if (result.ptr.type) {
305 PropertyRNA *name_prop = RNA_struct_name_property(result.ptr.type);
306 if (name_prop) {
307 char name_buf[256];
308 PointerRNA ptr_copy = result.ptr; /* Make a non-const copy. */
310 &ptr_copy, name_prop, name_buf, sizeof(name_buf), nullptr);
311 if (name && name[0] != '\0') {
312 member_name = name;
313 if (name != name_buf) {
315 }
316 }
317 }
318 }
319 /* Format like PyRNA: '<Type("name") at 0xAddress>' or '<Type at 0xAddress>'. */
320 if (!member_name.empty()) {
321 return fmt::format("<{}(\"{}\") at 0x{:x}>",
322 rna_type_name,
323 member_name,
324 reinterpret_cast<uintptr_t>(result.ptr.data));
325 }
326 else {
327 return fmt::format(
328 "<{} at 0x{:x}>", rna_type_name, reinterpret_cast<uintptr_t>(result.ptr.data));
329 }
330 }
331 else {
332 return "None";
333 }
334
336 return fmt::format("[{} item(s)]", result.list.size());
337
339 if (!result.str.is_empty()) {
340 return "\"" + result.str + "\"";
341 }
342 else {
343 return "\"\"";
344 }
345
347 if (result.prop && result.ptr.data) {
348 const char *prop_name = RNA_property_identifier(result.prop);
349 const char *rna_type_name = result.ptr.type ? RNA_struct_identifier(result.ptr.type) :
350 "Unknown";
351 if (result.index >= 0) {
352 return fmt::format("<Property({}.{}[{}])>", rna_type_name, prop_name, result.index);
353 }
354 else {
355 return fmt::format("<Property({}.{})>", rna_type_name, prop_name);
356 }
357 }
358 else {
359 return "<Property(None)>";
360 }
361
363 if (result.int_value.has_value()) {
364 return std::to_string(result.int_value.value());
365 }
366 else {
367 return "None";
368 }
369 }
370 /* Unhandled context type. Update if new types are added. */
372 return "<UNKNOWN>";
373}
374
377 const char *member,
379{
380 const bool use_logging = CLOG_CHECK(BKE_LOG_CONTEXT, CLG_LEVEL_TRACE) ||
382
383 if (!use_logging) {
384 return;
385 }
386
387 std::string value_repr = ctx_result_brief_repr(result);
388 const char *value_desc = value_repr.c_str();
389
390#ifdef WITH_PYTHON
391 /* Get current Python location if available and Python is properly initialized. */
392 std::optional<std::string> python_location;
393 if (C && CTX_py_init_get(C)) {
394 python_location = BPY_python_current_file_and_line();
395 }
396 const char *location = python_location ? python_location->c_str() : "unknown:0";
397#else
398 const char *location = "unknown:0";
399#endif
400
401 /* Use TRACE level when available, otherwise force output when Python logging is enabled. */
402 const char *format = "%s: %s=%s";
404 CLOG_TRACE(BKE_LOG_CONTEXT, format, location, member, value_desc);
405 }
406 else if (C && CTX_member_logging_get(C)) {
407 /* Force output at TRACE level even if not enabled via command line. */
408 CLOG_AT_LEVEL_NOCHECK(BKE_LOG_CONTEXT, CLG_LEVEL_TRACE, format, location, member, value_desc);
409 }
410}
411
413 const char *member,
414 const StructRNA *member_type,
415 void *fall_through)
416{
417 void *return_data = nullptr;
418 bool found_member = false;
419
420#ifdef WITH_PYTHON
421 if (UNLIKELY(C && CTX_py_dict_get(C))) {
423 if (BPY_context_member_get((bContext *)C, member, &result)) {
424 found_member = true;
425
426 if (result.ptr.data) {
427 if (RNA_struct_is_a(result.ptr.type, member_type)) {
428 return_data = result.ptr.data;
429 }
430 else {
431 CLOG_WARN(&LOG,
432 "PyContext '%s' is a '%s', expected a '%s'",
433 member,
435 RNA_struct_identifier(member_type));
436 }
437 }
438
439 /* Log context member access directly without storing a copy. */
441 }
442 }
443#else
444 UNUSED_VARS(C, member, member_type);
445#endif
446
447 /* If no member was found, use the fallback value and create a simple result for logging. */
448 if (!found_member) {
449 bContextDataResult fallback_result{};
450 fallback_result.ptr.data = fall_through;
451 fallback_result.ptr.type = const_cast<StructRNA *>(
452 member_type); /* Use the expected RNA type */
453 fallback_result.type = ContextDataType::Pointer;
454 return_data = fall_through;
455
456 /* Log fallback context member access. */
457 ctx_member_log_access(C, member, fallback_result);
458 }
459
460 /* Don't allow UI context access from non-main threads. */
461 if (!BLI_thread_is_main()) {
462 return nullptr;
463 }
464
465 return return_data;
466}
467
469{
470 bScreen *screen;
471 ScrArea *area;
472 ARegion *region;
473 int done = 0, recursion = C->data.recursion;
474 int ret = 0;
475
476 *result = {};
477
478 /* NOTE: We'll log access when we have actual results. */
479
480#ifdef WITH_PYTHON
481 if (CTX_py_dict_get(C)) {
482 if (BPY_context_member_get(C, member, result)) {
483 /* Log the Python context result if we're in a temp_override. */
484 ctx_member_log_access(C, member, *result);
485 return CTX_RESULT_OK;
486 }
487 }
488#endif
489
490 /* Don't allow UI context access from non-main threads. */
491 if (!BLI_thread_is_main()) {
493 }
494
495 /* we check recursion to ensure that we do not get infinite
496 * loops requesting data from ourselves in a context callback */
497
498 /* Ok, this looks evil...
499 * if (ret) done = -(-ret | -done);
500 *
501 * Values in order of importance
502 * (0, -1, 1) - Where 1 is highest priority
503 */
504 if (done != 1 && recursion < 1 && C->wm.store) {
505 C->data.recursion = 1;
506
507 if (const PointerRNA *ptr = CTX_store_ptr_lookup(C->wm.store, member, nullptr)) {
508 result->ptr = *ptr;
509 done = 1;
510 }
511 else if (std::optional<blender::StringRefNull> str = CTX_store_string_lookup(C->wm.store,
512 member))
513 {
514 result->str = *str;
516 done = 1;
517 }
518 else if (std::optional<int64_t> int_value = CTX_store_int_lookup(C->wm.store, member)) {
519 result->int_value = int_value;
521 done = 1;
522 }
523 }
524 if (done != 1 && recursion < 2 && (region = CTX_wm_region(C))) {
525 C->data.recursion = 2;
526 if (region->runtime->type && region->runtime->type->context) {
527 ret = region->runtime->type->context(C, member, result);
528 if (ret) {
529 done = -(-ret | -done);
530 }
531 }
532 }
533 if (done != 1 && recursion < 3 && (area = CTX_wm_area(C))) {
534 C->data.recursion = 3;
535 if (area->type && area->type->context) {
536 ret = area->type->context(C, member, result);
537 if (ret) {
538 done = -(-ret | -done);
539 }
540 }
541 }
542
543 if (done != 1 && recursion < 4 && (screen = CTX_wm_screen(C))) {
544 bContextDataCallback cb = reinterpret_cast<bContextDataCallback>(screen->context);
545 C->data.recursion = 4;
546 if (cb) {
547 ret = cb(C, member, result);
548 if (ret) {
549 done = -(-ret | -done);
550 }
551 }
552 }
553
554 C->data.recursion = recursion;
555
556 eContextResult final_result = eContextResult(done);
557
558 /* Log context result if we're in a temp_override and we got a successful or no-data result. */
559 if (ELEM(final_result, CTX_RESULT_OK, CTX_RESULT_NO_DATA)) {
560 ctx_member_log_access(C, member, *result);
561 }
562
563 return final_result;
564}
565
566static void *ctx_data_pointer_get(const bContext *C, const char *member)
567{
569 if (C && ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
571 return result.ptr.data;
572 }
573
574 return nullptr;
575}
576
577static bool ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
578{
579 /* if context is nullptr, pointer must be nullptr too and that is a valid return */
580 if (C == nullptr) {
581 *pointer = nullptr;
582 return true;
583 }
584
586 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
588 *pointer = result.ptr.data;
589 return true;
590 }
591
592 *pointer = nullptr;
593 return false;
594}
595
597 const char *member,
598 Vector<PointerRNA> *list)
599{
601 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
603 *list = std::move(result.list);
604 return true;
605 }
606
607 list->clear();
608 return false;
609}
610
612 const char *member,
613 Vector<PointerRNA> *list)
614{
615 Vector<PointerRNA> ctx_object_list;
616 if ((ctx_data_collection_get(C, member, &ctx_object_list) == false) ||
617 ctx_object_list.is_empty())
618 {
619 list->clear();
620 return false;
621 }
622
624
625 Scene *scene = CTX_data_scene(C);
626 ViewLayer *view_layer = CTX_data_view_layer(C);
627 BKE_view_layer_synced_ensure(scene, view_layer);
628
629 bool ok = false;
630
631 for (PointerRNA &ctx_object : ctx_object_list) {
632 Object *ob = static_cast<Object *>(ctx_object.data);
633 Base *base = BKE_view_layer_base_find(view_layer, ob);
634 if (base != nullptr) {
635 CTX_data_list_add(&result, &scene->id, &RNA_ObjectBase, base);
636 ok = true;
637 }
638 }
640
641 *list = std::move(result.list);
642 return ok;
643}
644
645PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
646{
648 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
650 return result.ptr;
651 }
652
653 return PointerRNA_NULL;
654}
655
656PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
657{
659
660 if (ptr.data) {
661 if (RNA_struct_is_a(ptr.type, type)) {
662 return ptr;
663 }
664
665 CLOG_WARN(&LOG,
666 "member '%s' is '%s', not '%s'",
667 member,
670 }
671
672 return PointerRNA_NULL;
673}
674
676{
678
679 if (ptr.data && RNA_struct_is_a(ptr.type, type)) {
680 return ptr;
681 }
682
683 return PointerRNA_NULL;
684}
685
687{
689 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
691 return result.list;
692 }
693 return {};
694}
695
697 const char *propname)
698{
699 for (PointerRNA &ptr : collection_pointers) {
700 ptr = RNA_pointer_get(&ptr, propname);
701 }
702}
703
704std::optional<blender::StringRefNull> CTX_data_string_get(const bContext *C, const char *member)
705{
707 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
709 return result.str;
710 }
711
712 return {};
713}
714
715std::optional<int64_t> CTX_data_int_get(const bContext *C, const char *member)
716{
718 if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
720 return result.int_value;
721 }
722
723 return {};
724}
725
726int /*eContextResult*/ CTX_data_get(const bContext *C,
727 const char *member,
728 PointerRNA *r_ptr,
729 Vector<PointerRNA> *r_lb,
730 PropertyRNA **r_prop,
731 int *r_index,
732 blender::StringRef *r_str,
733 std::optional<int64_t> *r_int_value,
734 ContextDataType *r_type)
735{
738
739 if (ret == CTX_RESULT_OK) {
740 *r_ptr = result.ptr;
741 *r_lb = result.list;
742 *r_prop = result.prop;
743 *r_index = result.index;
744 *r_str = result.str;
745 *r_int_value = result.int_value;
746 *r_type = result.type;
747 }
748 else {
749 *r_ptr = {};
750 r_lb->clear();
751 *r_str = "";
752 *r_int_value = {};
753 *r_type = ContextDataType::Pointer;
754 }
755
756 return ret;
757}
758
759static void data_dir_add(ListBase *lb, const char *member, const bool use_all)
760{
761 LinkData *link;
762
763 if ((use_all == false) && STREQ(member, "scene")) { /* exception */
764 return;
765 }
766
767 if (BLI_findstring(lb, member, offsetof(LinkData, data))) {
768 return;
769 }
770
771 link = MEM_callocN<LinkData>(__func__);
772 link->data = (void *)member;
773 BLI_addtail(lb, link);
774}
775
777 const bool use_store,
778 const bool use_rna,
779 const bool use_all)
780{
782 ListBase lb;
783 bScreen *screen;
784 ScrArea *area;
785 ARegion *region;
786 int a;
787
788 memset(&lb, 0, sizeof(lb));
789
790 if (use_rna) {
791 char name_buf[256], *name;
792 int namelen;
793
794 PropertyRNA *iterprop;
795 PointerRNA ctx_ptr = RNA_pointer_create_discrete(nullptr, &RNA_Context, (void *)C);
796
797 iterprop = RNA_struct_iterator_property(ctx_ptr.type);
798
799 RNA_PROP_BEGIN (&ctx_ptr, itemptr, iterprop) {
800 name = RNA_struct_name_get_alloc(&itemptr, name_buf, sizeof(name_buf), &namelen);
801 data_dir_add(&lb, name, use_all);
802 if (name != name_buf) {
804 }
805 }
807 }
808 if (use_store && C->wm.store) {
809 for (const bContextStoreEntry &entry : C->wm.store->entries) {
810 data_dir_add(&lb, entry.name.c_str(), use_all);
811 }
812 }
813 if ((region = CTX_wm_region(C)) && region->runtime->type && region->runtime->type->context) {
814 region->runtime->type->context(C, "", &result);
815
816 if (result.dir) {
817 for (a = 0; result.dir[a]; a++) {
818 data_dir_add(&lb, result.dir[a], use_all);
819 }
820 }
821 }
822 if ((area = CTX_wm_area(C)) && area->type && area->type->context) {
823 area->type->context(C, "", &result);
824
825 if (result.dir) {
826 for (a = 0; result.dir[a]; a++) {
827 data_dir_add(&lb, result.dir[a], use_all);
828 }
829 }
830 }
831 if ((screen = CTX_wm_screen(C)) && screen->context) {
832 bContextDataCallback cb = reinterpret_cast<bContextDataCallback>(screen->context);
833 cb(C, "", &result);
834
835 if (result.dir) {
836 for (a = 0; result.dir[a]; a++) {
837 data_dir_add(&lb, result.dir[a], use_all);
838 }
839 }
840 }
841
842 return lb;
843}
844
846{
847 return CTX_data_dir_get_ex(C, true, false, false);
848}
849
850bool CTX_data_equals(const char *member, const char *str)
851{
852 return STREQ(member, str);
853}
854
855bool CTX_data_dir(const char *member)
856{
857 return member[0] == '\0';
858}
859
864
866{
867 result->ptr = RNA_pointer_create_discrete(id, type, data);
868}
869
874
879
881{
882 result->list.append(RNA_pointer_create_discrete(id, type, data));
883}
884
886{
887 result->list.append(*ptr);
888}
889
891 bool (*func)(const bContext *, blender::Vector<PointerRNA> *))
892{
894 if (func(C, &list)) {
895 return list.size();
896 }
897 return 0;
898}
899
901{
902 result->prop = prop;
903 result->index = index;
904}
905
907{
908 result->dir = dir;
909}
910
912{
913 result->type = type;
914}
915
920
921/* window manager context */
922
924{
925 return C->wm.manager;
926}
927
929{
930 return C->wm.manager->runtime->is_interface_locked;
931}
932
934{
935 return static_cast<wmWindow *>(
936 ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window));
937}
938
940{
941 return static_cast<WorkSpace *>(
942 ctx_wm_python_context_get(C, "workspace", &RNA_WorkSpace, C->wm.workspace));
943}
944
946{
947 return static_cast<bScreen *>(ctx_wm_python_context_get(C, "screen", &RNA_Screen, C->wm.screen));
948}
949
951{
952 return static_cast<ScrArea *>(ctx_wm_python_context_get(C, "area", &RNA_Area, C->wm.area));
953}
954
956{
957 ScrArea *area = CTX_wm_area(C);
958 return (area) ? static_cast<SpaceLink *>(area->spacedata.first) : nullptr;
959}
960
962{
963 return static_cast<ARegion *>(ctx_wm_python_context_get(C, "region", &RNA_Region, C->wm.region));
964}
965
967{
968 ARegion *region = CTX_wm_region(C);
969 return (region) ? region->regiondata : nullptr;
970}
971
973{
974 return C->wm.region_popup;
975}
976
978{
979 return C->wm.gizmo_group;
980}
981
983{
984 return C->wm.manager ? C->wm.manager->runtime->message_bus : nullptr;
985}
986
988{
989 if (C->wm.manager) {
990 return &(C->wm.manager->runtime->reports);
991 }
992
993 return nullptr;
994}
995
997{
998 ScrArea *area = CTX_wm_area(C);
999 if (area && area->spacetype == SPACE_VIEW3D) {
1000 return static_cast<View3D *>(area->spacedata.first);
1001 }
1002 return nullptr;
1003}
1004
1006{
1007 ScrArea *area = CTX_wm_area(C);
1008 ARegion *region = CTX_wm_region(C);
1009
1010 if (area && area->spacetype == SPACE_VIEW3D) {
1011 if (region && region->regiontype == RGN_TYPE_WINDOW) {
1012 return static_cast<RegionView3D *>(region->regiondata);
1013 }
1014 }
1015 return nullptr;
1016}
1017
1019{
1020 ScrArea *area = CTX_wm_area(C);
1021 if (area && area->spacetype == SPACE_TEXT) {
1022 return static_cast<SpaceText *>(area->spacedata.first);
1023 }
1024 return nullptr;
1025}
1026
1028{
1029 ScrArea *area = CTX_wm_area(C);
1030 if (area && area->spacetype == SPACE_CONSOLE) {
1031 return static_cast<SpaceConsole *>(area->spacedata.first);
1032 }
1033 return nullptr;
1034}
1035
1037{
1038 ScrArea *area = CTX_wm_area(C);
1039 if (area && area->spacetype == SPACE_IMAGE) {
1040 return static_cast<SpaceImage *>(area->spacedata.first);
1041 }
1042 return nullptr;
1043}
1044
1046{
1047 ScrArea *area = CTX_wm_area(C);
1048 if (area && area->spacetype == SPACE_PROPERTIES) {
1049 return static_cast<SpaceProperties *>(area->spacedata.first);
1050 }
1051 return nullptr;
1052}
1053
1055{
1056 ScrArea *area = CTX_wm_area(C);
1057 if (area && area->spacetype == SPACE_FILE) {
1058 return static_cast<SpaceFile *>(area->spacedata.first);
1059 }
1060 return nullptr;
1061}
1062
1064{
1065 ScrArea *area = CTX_wm_area(C);
1066 if (area && area->spacetype == SPACE_SEQ) {
1067 return static_cast<SpaceSeq *>(area->spacedata.first);
1068 }
1069 return nullptr;
1070}
1071
1073{
1074 ScrArea *area = CTX_wm_area(C);
1075 if (area && area->spacetype == SPACE_OUTLINER) {
1076 return static_cast<SpaceOutliner *>(area->spacedata.first);
1077 }
1078 return nullptr;
1079}
1080
1082{
1083 ScrArea *area = CTX_wm_area(C);
1084 if (area && area->spacetype == SPACE_NLA) {
1085 return static_cast<SpaceNla *>(area->spacedata.first);
1086 }
1087 return nullptr;
1088}
1089
1091{
1092 ScrArea *area = CTX_wm_area(C);
1093 if (area && area->spacetype == SPACE_NODE) {
1094 return static_cast<SpaceNode *>(area->spacedata.first);
1095 }
1096 return nullptr;
1097}
1098
1100{
1101 ScrArea *area = CTX_wm_area(C);
1102 if (area && area->spacetype == SPACE_GRAPH) {
1103 return static_cast<SpaceGraph *>(area->spacedata.first);
1104 }
1105 return nullptr;
1106}
1107
1109{
1110 ScrArea *area = CTX_wm_area(C);
1111 if (area && area->spacetype == SPACE_ACTION) {
1112 return static_cast<SpaceAction *>(area->spacedata.first);
1113 }
1114 return nullptr;
1115}
1116
1118{
1119 ScrArea *area = CTX_wm_area(C);
1120 if (area && area->spacetype == SPACE_INFO) {
1121 return static_cast<SpaceInfo *>(area->spacedata.first);
1122 }
1123 return nullptr;
1124}
1125
1127{
1128 ScrArea *area = CTX_wm_area(C);
1129 if (area && area->spacetype == SPACE_USERPREF) {
1130 return static_cast<SpaceUserPref *>(area->spacedata.first);
1131 }
1132 return nullptr;
1133}
1134
1136{
1137 ScrArea *area = CTX_wm_area(C);
1138 if (area && area->spacetype == SPACE_CLIP) {
1139 return static_cast<SpaceClip *>(area->spacedata.first);
1140 }
1141 return nullptr;
1142}
1143
1145{
1146 ScrArea *area = CTX_wm_area(C);
1147 if (area && area->spacetype == SPACE_TOPBAR) {
1148 return static_cast<SpaceTopBar *>(area->spacedata.first);
1149 }
1150 return nullptr;
1151}
1152
1154{
1155 ScrArea *area = CTX_wm_area(C);
1156 if (area && area->spacetype == SPACE_SPREADSHEET) {
1157 return static_cast<SpaceSpreadsheet *>(area->spacedata.first);
1158 }
1159 return nullptr;
1160}
1161
1163{
1164 C->wm.manager = wm;
1165 C->wm.window = nullptr;
1166 C->wm.screen = nullptr;
1167 C->wm.area = nullptr;
1168 C->wm.region = nullptr;
1169}
1170
1171#ifdef WITH_PYTHON
1172# define PYCTX_REGION_MEMBERS "region", "region_data"
1173# define PYCTX_AREA_MEMBERS "area", "space_data", PYCTX_REGION_MEMBERS
1174# define PYCTX_SCREEN_MEMBERS "screen", PYCTX_AREA_MEMBERS
1175# define PYCTX_WINDOW_MEMBERS "window", "scene", "workspace", PYCTX_SCREEN_MEMBERS
1176#endif
1177
1179{
1180 C->wm.window = win;
1181 if (win) {
1182 C->data.scene = win->scene;
1183 }
1184 C->wm.workspace = (win) ? BKE_workspace_active_get(win->workspace_hook) : nullptr;
1185 C->wm.screen = (win) ? BKE_workspace_active_screen_get(win->workspace_hook) : nullptr;
1186 C->wm.area = nullptr;
1187 C->wm.region = nullptr;
1188
1189#ifdef WITH_PYTHON
1190 if (C->data.py_context != nullptr) {
1191 const char *members[] = {PYCTX_WINDOW_MEMBERS};
1193 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1194 }
1195#endif
1196}
1197
1199{
1200 C->wm.screen = screen;
1201 C->wm.area = nullptr;
1202 C->wm.region = nullptr;
1203
1204#ifdef WITH_PYTHON
1205 if (C->data.py_context != nullptr) {
1206 const char *members[] = {PYCTX_SCREEN_MEMBERS};
1208 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1209 }
1210#endif
1211}
1212
1214{
1215 C->wm.area = area;
1216 C->wm.region = nullptr;
1217
1218#ifdef WITH_PYTHON
1219 if (C->data.py_context != nullptr) {
1220 const char *members[] = {PYCTX_AREA_MEMBERS};
1222 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1223 }
1224#endif
1225}
1226
1228{
1229 C->wm.region = region;
1230
1231#ifdef WITH_PYTHON
1232 if (C->data.py_context != nullptr) {
1233 const char *members[] = {PYCTX_REGION_MEMBERS};
1235 &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members));
1236 }
1237#endif
1238}
1239
1241{
1242 BLI_assert(region_popup == nullptr || region_popup->regiontype == RGN_TYPE_TEMPORARY);
1243 C->wm.region_popup = region_popup;
1244}
1245
1247{
1248 C->wm.gizmo_group = gzgroup;
1249}
1250
1252{
1253 bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params;
1254 if (params->free_fn != nullptr) {
1255 params->free_fn(C, params->user_data);
1256 }
1257 params->get_fn = nullptr;
1258 params->free_fn = nullptr;
1259 params->user_data = nullptr;
1260
1261 C->wm.operator_poll_msg = nullptr;
1262}
1264{
1266
1267 C->wm.operator_poll_msg = msg;
1268}
1269
1271{
1273
1274 C->wm.operator_poll_msg_dyn_params = *params;
1275}
1276
1277const char *CTX_wm_operator_poll_msg_get(bContext *C, bool *r_free)
1278{
1279 bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params;
1280 if (params->get_fn != nullptr) {
1281 char *msg = params->get_fn(C, params->user_data);
1282 if (msg != nullptr) {
1283 *r_free = true;
1284 }
1285 return msg;
1286 }
1287
1288 *r_free = false;
1289 return IFACE_(C->wm.operator_poll_msg);
1290}
1291
1292/* data context */
1293
1295{
1296 Main *bmain;
1297 if (ctx_data_pointer_verify(C, "blend_data", (void **)&bmain)) {
1298 return bmain;
1299 }
1300
1301 return C->data.main;
1302}
1303
1305{
1306 C->data.main = bmain;
1308}
1309
1311{
1312 Scene *scene;
1313 if (ctx_data_pointer_verify(C, "scene", (void **)&scene)) {
1314 return scene;
1315 }
1316
1317 return C->data.scene;
1318}
1319
1321{
1322 Scene *scene;
1323 if (ctx_data_pointer_verify(C, "sequencer_scene", (void **)&scene)) {
1324 return scene;
1325 }
1326 WorkSpace *workspace = CTX_wm_workspace(C);
1327 if (workspace) {
1328 return workspace->sequencer_scene;
1329 }
1330 return nullptr;
1331}
1332
1334{
1335 ViewLayer *view_layer;
1336
1337 if (ctx_data_pointer_verify(C, "view_layer", (void **)&view_layer)) {
1338 return view_layer;
1339 }
1340
1341 wmWindow *win = CTX_wm_window(C);
1342 Scene *scene = CTX_data_scene(C);
1343 if (win) {
1344 view_layer = BKE_view_layer_find(scene, win->view_layer_name);
1345 if (view_layer) {
1346 return view_layer;
1347 }
1348 }
1349
1350 return BKE_view_layer_default_view(scene);
1351}
1352
1354{
1355 Scene *scene = CTX_data_scene(C);
1356 return RE_engines_find(scene->r.engine);
1357}
1358
1360{
1361 ViewLayer *view_layer = CTX_data_view_layer(C);
1362 LayerCollection *layer_collection;
1363
1364 if (ctx_data_pointer_verify(C, "layer_collection", (void **)&layer_collection)) {
1365 if (BKE_view_layer_has_collection(view_layer, layer_collection->collection)) {
1366 return layer_collection;
1367 }
1368 }
1369
1370 /* fallback */
1371 return BKE_layer_collection_get_active(view_layer);
1372}
1373
1375{
1376 Collection *collection;
1377 if (ctx_data_pointer_verify(C, "collection", (void **)&collection)) {
1378 return collection;
1379 }
1380
1381 LayerCollection *layer_collection = CTX_data_layer_collection(C);
1382 if (layer_collection) {
1383 return layer_collection->collection;
1384 }
1385
1386 /* fallback */
1387 Scene *scene = CTX_data_scene(C);
1388 return scene->master_collection;
1389}
1390
1392 const Object *ob,
1393 const eObjectMode object_mode)
1394{
1395 // Object *obedit = CTX_data_edit_object(C);
1396 if (obedit) {
1397 switch (obedit->type) {
1398 case OB_MESH:
1399 return CTX_MODE_EDIT_MESH;
1400 case OB_CURVES_LEGACY:
1401 return CTX_MODE_EDIT_CURVE;
1402 case OB_SURF:
1403 return CTX_MODE_EDIT_SURFACE;
1404 case OB_FONT:
1405 return CTX_MODE_EDIT_TEXT;
1406 case OB_ARMATURE:
1408 case OB_MBALL:
1410 case OB_LATTICE:
1411 return CTX_MODE_EDIT_LATTICE;
1412 case OB_CURVES:
1413 return CTX_MODE_EDIT_CURVES;
1414 case OB_GREASE_PENCIL:
1416 case OB_POINTCLOUD:
1418 }
1419 }
1420 else {
1421 // Object *ob = CTX_data_active_object(C);
1422 if (ob) {
1423 if (object_mode & OB_MODE_POSE) {
1424 return CTX_MODE_POSE;
1425 }
1426 if (object_mode & OB_MODE_SCULPT) {
1427 return CTX_MODE_SCULPT;
1428 }
1429 if (object_mode & OB_MODE_WEIGHT_PAINT) {
1430 return CTX_MODE_PAINT_WEIGHT;
1431 }
1432 if (object_mode & OB_MODE_VERTEX_PAINT) {
1433 return CTX_MODE_PAINT_VERTEX;
1434 }
1435 if (object_mode & OB_MODE_TEXTURE_PAINT) {
1437 }
1438 if (object_mode & OB_MODE_PARTICLE_EDIT) {
1439 return CTX_MODE_PARTICLE;
1440 }
1441 if (object_mode & OB_MODE_PAINT_GREASE_PENCIL) {
1442 if (ob->type == OB_GREASE_PENCIL) {
1444 }
1445 }
1446 if (object_mode & OB_MODE_EDIT_GPENCIL_LEGACY) {
1448 }
1449 if (object_mode & OB_MODE_SCULPT_GREASE_PENCIL) {
1450 if (ob->type == OB_GREASE_PENCIL) {
1452 }
1453 }
1454 if (object_mode & OB_MODE_WEIGHT_GREASE_PENCIL) {
1455 if (ob->type == OB_GREASE_PENCIL) {
1457 }
1458 }
1459 if (object_mode & OB_MODE_VERTEX_GREASE_PENCIL) {
1460 if (ob->type == OB_GREASE_PENCIL) {
1462 }
1463 }
1464 if (object_mode & OB_MODE_SCULPT_CURVES) {
1466 }
1467 }
1468 }
1469
1470 return CTX_MODE_OBJECT;
1471}
1472
1474{
1475 Object *obedit = CTX_data_edit_object(C);
1476 Object *obact = obedit ? nullptr : CTX_data_active_object(C);
1477 return CTX_data_mode_enum_ex(obedit, obact, obact ? eObjectMode(obact->mode) : OB_MODE_OBJECT);
1478}
1479
1485static const char *data_mode_strings[] = {
1486 "mesh_edit",
1487 "curve_edit",
1488 "surface_edit",
1489 "text_edit",
1490 "armature_edit",
1491 "mball_edit",
1492 "lattice_edit",
1493 "curves_edit",
1494 "grease_pencil_edit",
1495 "pointcloud_edit",
1496 "posemode",
1497 "sculpt_mode",
1498 "weightpaint",
1499 "vertexpaint",
1500 "imagepaint",
1501 "particlemode",
1502 "objectmode",
1503 "greasepencil_paint",
1504 "greasepencil_edit",
1505 "greasepencil_sculpt",
1506 "greasepencil_weight",
1507 "greasepencil_vertex",
1508 "curves_sculpt",
1509 "grease_pencil_paint",
1510 "grease_pencil_sculpt",
1511 "grease_pencil_weight",
1512 "grease_pencil_vertex",
1513 nullptr,
1514};
1516 "Must have a string for each context mode")
1517const char *CTX_data_mode_string(const bContext *C)
1518{
1520}
1521
1523{
1524 C->data.scene = scene;
1525
1526#ifdef WITH_PYTHON
1527 if (C->data.py_context != nullptr) {
1528 const char *members[] = {"scene"};
1529 BPY_context_dict_clear_members_array(&C->data.py_context, C->data.py_context_orig, members, 1);
1530 }
1531#endif
1532}
1533
1535{
1536 ToolSettings *toolsettings;
1537 if (ctx_data_pointer_verify(C, "tool_settings", (void **)&toolsettings)) {
1538 return toolsettings;
1539 }
1540
1541 Scene *scene = CTX_data_scene(C);
1542 if (scene) {
1543 return scene->toolsettings;
1544 }
1545
1546 return nullptr;
1547}
1548
1550{
1551 return ctx_data_collection_get(C, "selected_ids", list);
1552}
1553
1555{
1556 return ctx_data_collection_get(C, "selected_nodes", list);
1557}
1558
1560{
1561 return ctx_data_collection_get(C, "selected_editable_objects", list);
1562}
1563
1565{
1566 return ctx_data_base_collection_get(C, "selected_editable_objects", list);
1567}
1568
1570{
1571 return ctx_data_collection_get(C, "editable_objects", list);
1572}
1573
1575{
1576 return ctx_data_base_collection_get(C, "editable_objects", list);
1577}
1578
1580{
1581 return ctx_data_collection_get(C, "selected_objects", list);
1582}
1583
1585{
1586 return ctx_data_base_collection_get(C, "selected_objects", list);
1587}
1588
1590{
1591 return ctx_data_collection_get(C, "visible_objects", list);
1592}
1593
1595{
1596 return ctx_data_base_collection_get(C, "visible_objects", list);
1597}
1598
1600{
1601 return ctx_data_collection_get(C, "selectable_objects", list);
1602}
1603
1605{
1606 return ctx_data_base_collection_get(C, "selectable_objects", list);
1607}
1608
1610{
1611 return static_cast<Object *>(ctx_data_pointer_get(C, "active_object"));
1612}
1613
1615{
1617
1618 if (ob == nullptr) {
1619 return nullptr;
1620 }
1621 const Scene *scene = CTX_data_scene(C);
1622 ViewLayer *view_layer = CTX_data_view_layer(C);
1623 BKE_view_layer_synced_ensure(scene, view_layer);
1624 return BKE_view_layer_base_find(view_layer, ob);
1625}
1626
1628{
1629 return static_cast<Object *>(ctx_data_pointer_get(C, "edit_object"));
1630}
1631
1633{
1634 return static_cast<Image *>(ctx_data_pointer_get(C, "edit_image"));
1635}
1636
1638{
1639 return static_cast<Text *>(ctx_data_pointer_get(C, "edit_text"));
1640}
1641
1643{
1644 return static_cast<MovieClip *>(ctx_data_pointer_get(C, "edit_movieclip"));
1645}
1646
1648{
1649 return static_cast<Mask *>(ctx_data_pointer_get(C, "edit_mask"));
1650}
1651
1653{
1654 return static_cast<EditBone *>(ctx_data_pointer_get(C, "active_bone"));
1655}
1656
1658{
1659 return static_cast<CacheFile *>(ctx_data_pointer_get(C, "edit_cachefile"));
1660}
1661
1663{
1664 return ctx_data_collection_get(C, "selected_bones", list);
1665}
1666
1668{
1669 return ctx_data_collection_get(C, "selected_editable_bones", list);
1670}
1671
1673{
1674 return ctx_data_collection_get(C, "visible_bones", list);
1675}
1676
1678{
1679 return ctx_data_collection_get(C, "editable_bones", list);
1680}
1681
1683{
1684 return static_cast<bPoseChannel *>(ctx_data_pointer_get(C, "active_pose_bone"));
1685}
1686
1688{
1689 return ctx_data_collection_get(C, "selected_pose_bones", list);
1690}
1691
1694{
1695 return ctx_data_collection_get(C, "selected_pose_bones_from_active_object", list);
1696}
1697
1699{
1700 return ctx_data_collection_get(C, "visible_pose_bones", list);
1701}
1702
1704{
1705 return static_cast<AssetLibraryReference *>(ctx_data_pointer_get(C, "asset_library_reference"));
1706}
1707
1713
1715{
1716 Main *bmain = CTX_data_main(C);
1717 Scene *scene = CTX_data_scene(C);
1718 ViewLayer *view_layer = CTX_data_view_layer(C);
1719 Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
1720 /* Dependency graph might have been just allocated, and hence it will not be marked.
1721 * This confuses redo system due to the lack of flushing changes back to the original data.
1722 * In the future we would need to check whether the CTX_wm_window(C) is in editing mode (as an
1723 * opposite of playback-preview-only) and set active flag based on that. */
1725 return depsgraph;
1726}
1727
1729{
1731 /* TODO(sergey): Assert that the dependency graph is fully evaluated.
1732 * Note that first the depsgraph and scene post-evaluation hooks needs to run extra round of
1733 * updates first to make check here really reliable. */
1734 return depsgraph;
1735}
1736
1738{
1740 Main *bmain = CTX_data_main(C);
1742 return depsgraph;
1743}
1744
1746{
1747 Scene *scene = CTX_data_scene(C);
1748 ViewLayer *view_layer = CTX_data_view_layer(C);
1749 return BKE_scene_get_depsgraph(scene, view_layer);
1750}
1751
1753{
1754 C->data.log_access = enable;
1755}
1756
1758{
1759 return C->data.log_access;
1760}
const char * CTX_data_mode_string(const bContext *C)
eContextObjectMode
@ CTX_MODE_PAINT_GREASE_PENCIL
@ 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_POINTCLOUD
@ 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
eContextResult
@ CTX_RESULT_MEMBER_NOT_FOUND
@ CTX_RESULT_OK
@ CTX_RESULT_NO_DATA
int(*)(const bContext *C, const char *member, bContextDataResult *result) bContextDataCallback
ContextDataType
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:2626
Depsgraph * BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer)
Definition scene.cc:3416
Depsgraph * BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer)
Definition scene.cc:3403
void BKE_sound_refresh_callback_bmain(struct Main *bmain)
bScreen * BKE_workspace_active_screen_get(const WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:614
WorkSpace * BKE_workspace_active_get(WorkSpaceInstanceHook *hook) GETTER_ATTRS
Definition workspace.cc:563
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:83
#define BLI_assert(a)
Definition BLI_assert.h:46
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
int BLI_thread_is_main(void)
Definition threads.cc:179
#define ARRAY_SIZE(arr)
#define UNUSED_VARS(...)
#define UNLIKELY(x)
#define ELEM(...)
#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)
std::optional< std::string > BPY_python_current_file_and_line(void)
bool BPY_context_member_get(bContext *C, const char *member, bContextDataResult *result)
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:189
#define CLOG_AT_LEVEL_NOCHECK(clg_ref, verbose_level,...)
Definition CLG_log.h:159
#define CLOG_CHECK(clg_ref, verbose_level,...)
Definition CLG_log.h:147
@ CLG_LEVEL_TRACE
Definition CLG_log.h:64
#define CLG_LOGREF_DECLARE_GLOBAL(var, id)
Definition CLG_log.h:139
#define CLOG_TRACE(clg_ref,...)
Definition CLG_log.h:192
void DEG_make_active(Depsgraph *depsgraph)
Definition depsgraph.cc:336
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_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)
#define C
Definition RandGen.cpp:29
bContextStore * CTX_store_add_all(Vector< std::unique_ptr< bContextStore > > &contexts, const bContextStore *context)
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)
void CTX_member_logging_set(bContext *C, bool enable)
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)
static void ctx_member_log_access(const bContext *C, const char *member, const bContextDataResult &result)
WorkSpace * CTX_wm_workspace(const bContext *C)
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)
void CTX_data_prop_set(bContextDataResult *result, PropertyRNA *prop, int index)
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)
std::optional< int64_t > CTX_store_int_lookup(const bContextStore *store, const blender::StringRef name)
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_data_type_set(bContextDataResult *result, ContextDataType type)
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)
std::optional< int64_t > CTX_data_int_get(const bContext *C, const char *member)
bool CTX_py_init_get(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)
const PointerRNA * CTX_store_ptr_lookup(const bContextStore *store, const blender::StringRef name, const StructRNA *type)
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)
const T * ctx_store_lookup_impl(const bContextStore *store, const blender::StringRef name)
ContextDataType CTX_data_type_get(bContextDataResult *result)
void CTX_data_collection_remap_property(blender::MutableSpan< PointerRNA > collection_pointers, const char *propname)
void CTX_wm_area_set(bContext *C, ScrArea *area)
static std::string ctx_result_brief_repr(const bContextDataResult &result)
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)
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, std::optional< int64_t > *r_int_value, ContextDataType *r_type)
void CTX_wm_region_set(bContext *C, ARegion *region)
RegionView3D * CTX_wm_region_view3d(const bContext *C)
bool CTX_member_logging_get(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)
Scene * CTX_data_sequencer_scene(const bContext *C)
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)
std::optional< blender::StringRefNull > CTX_store_string_lookup(const bContextStore *store, const blender::StringRef name)
bContextStore * CTX_store_add(Vector< std::unique_ptr< bContextStore > > &contexts, const blender::StringRef name, const PointerRNA *ptr)
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)
BMesh const char void * data
BPy_StructRNA * depsgraph
CLG_LogRef * BKE_LOG_CONTEXT
long long int int64_t
std::reverse_iterator< T * > rbegin()
void append(const T &value)
std::reverse_iterator< T * > rend()
int64_t size() const
bool is_empty() const
#define offsetof(t, d)
#define str(s)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
RenderEngineType * RE_engines_find(const char *idname)
format
#define LOG(level)
Definition log.h:97
static char ** members
Definition makesdna.cc:69
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define T
const char * name
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 PointerRNA PointerRNA_NULL
char * RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop, char *fixedbuf, int fixedlen, int *r_len)
const char * RNA_struct_identifier(const StructRNA *type)
PropertyRNA * RNA_struct_name_property(const StructRNA *type)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
PropertyRNA * RNA_struct_iterator_property(StructRNA *type)
const char * RNA_property_identifier(const PropertyRNA *prop)
PointerRNA RNA_id_pointer_create(ID *id)
void * regiondata
ARegionRuntimeHandle * runtime
Definition DNA_ID.h:414
struct Collection * collection
void * data
void * first
StructRNA * type
Definition RNA_types.hh:52
void * data
Definition RNA_types.hh:53
char engine[32]
struct Collection * master_collection
struct ToolSettings * toolsettings
struct RenderData r
ListBase spacedata
struct SpaceType * type
bContextDataCallback context
struct Scene * sequencer_scene
std::optional< int64_t > int_value
blender::StringRefNull str
blender::Vector< bContextStoreEntry > entries
const char * operator_poll_msg
bContextPollMsgDyn_Params operator_poll_msg_dyn_params
const bContextStore * store
wmGizmoGroup * gizmo_group
wmWindowManager * manager
struct bContext::@342215117220227010050134206372242253175123130242 wm
struct Scene * scene
struct WorkSpaceInstanceHook * workspace_hook
PointerRNA * ptr
Definition wm_files.cc:4238