1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 /** \file
18  * \ingroup bke
19  */
20 
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "MEM_guardedalloc.h"
26 
27 #include "DNA_collection_types.h"
28 #include "DNA_gpencil_types.h"
29 #include "DNA_linestyle_types.h"
30 #include "DNA_object_types.h"
31 #include "DNA_scene_types.h"
32 #include "DNA_screen_types.h"
33 #include "DNA_space_types.h"
34 #include "DNA_view3d_types.h"
35 #include "DNA_windowmanager_types.h"
36 #include "DNA_workspace_types.h"
37 
38 #include "DEG_depsgraph.h"
39 
40 #include "BLI_listbase.h"
41 #include "BLI_string.h"
42 #include "BLI_threads.h"
43 #include "BLI_utildefines.h"
44 
45 #include "BLT_translation.h"
46 
47 #include "BKE_context.h"
48 #include "BKE_layer.h"
49 #include "BKE_main.h"
50 #include "BKE_scene.h"
51 #include "BKE_screen.h"
52 #include "BKE_sound.h"
53 #include "BKE_workspace.h"
54 
55 #include "RE_engine.h"
56 
57 #include "RNA_access.h"
58 
59 #include "CLG_log.h"
60 
61 #ifdef WITH_PYTHON
62 #  include "BPY_extern.h"
63 #endif
64 
65 static CLG_LogRef LOG = {"bke.context"};
66 
67 /* struct */
68 
69 struct bContext {
70   int thread;
71 
72   /* windowmanager context */
73   struct {
74     struct wmWindowManager *manager;
75     struct wmWindow *window;
76     struct WorkSpace *workspace;
77     struct bScreen *screen;
78     struct ScrArea *area;
79     struct ARegion *region;
80     struct ARegion *menu;
81     struct wmGizmoGroup *gizmo_group;
82     struct bContextStore *store;
83     const char *operator_poll_msg; /* reason for poll failing */
84   } wm;
85 
86   /* data context */
87   struct {
88     struct Main *main;
89     struct Scene *scene;
90 
91     int recursion;
92     /** True if python is initialized. */
93     bool py_init;
94     void *py_context;
95     /**
96      * If we need to remove members, do so in a copy
97      * (keep this to check if the copy needs freeing).
98      */
99     void *py_context_orig;
100   } data;
101 };
102 
103 /* context */
104 
CTX_create(void)105 bContext *CTX_create(void)
106 {
107   bContext *C = MEM_callocN(sizeof(bContext), "bContext");
108 
109   return C;
110 }
111 
CTX_copy(const bContext * C)112 bContext *CTX_copy(const bContext *C)
113 {
114   bContext *newC = MEM_dupallocN((void *)C);
115 
116   return newC;
117 }
118 
CTX_free(bContext * C)119 void CTX_free(bContext *C)
120 {
121   MEM_freeN(C);
122 }
123 
124 /* store */
125 
CTX_store_add(ListBase * contexts,const char * name,PointerRNA * ptr)126 bContextStore *CTX_store_add(ListBase *contexts, const char *name, PointerRNA *ptr)
127 {
128   /* ensure we have a context to put the entry in, if it was already used
129    * we have to copy the context to ensure */
130   bContextStore *ctx = contexts->last;
131 
132   if (!ctx || ctx->used) {
133     if (ctx) {
134       bContextStore *lastctx = ctx;
135       ctx = MEM_dupallocN(lastctx);
136       BLI_duplicatelist(&ctx->entries, &lastctx->entries);
137     }
138     else {
139       ctx = MEM_callocN(sizeof(bContextStore), "bContextStore");
140     }
141 
142     BLI_addtail(contexts, ctx);
143   }
144 
145   bContextStoreEntry *entry = MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry");
146   BLI_strncpy(entry->name, name, sizeof(entry->name));
147   entry->ptr = *ptr;
148 
149   BLI_addtail(&ctx->entries, entry);
150 
151   return ctx;
152 }
153 
CTX_store_add_all(ListBase * contexts,bContextStore * context)154 bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context)
155 {
156   /* ensure we have a context to put the entries in, if it was already used
157    * we have to copy the context to ensure */
158   bContextStore *ctx = contexts->last;
159 
160   if (!ctx || ctx->used) {
161     if (ctx) {
162       bContextStore *lastctx = ctx;
163       ctx = MEM_dupallocN(lastctx);
164       BLI_duplicatelist(&ctx->entries, &lastctx->entries);
165     }
166     else {
167       ctx = MEM_callocN(sizeof(bContextStore), "bContextStore");
168     }
169 
170     BLI_addtail(contexts, ctx);
171   }
172 
173   LISTBASE_FOREACH (bContextStoreEntry *, tentry, &context->entries) {
174     bContextStoreEntry *entry = MEM_dupallocN(tentry);
175     BLI_addtail(&ctx->entries, entry);
176   }
177 
178   return ctx;
179 }
180 
CTX_store_set(bContext * C,bContextStore * store)181 void CTX_store_set(bContext *C, bContextStore *store)
182 {
183   C->wm.store = store;
184 }
185 
CTX_store_copy(bContextStore * store)186 bContextStore *CTX_store_copy(bContextStore *store)
187 {
188   bContextStore *ctx = MEM_dupallocN(store);
189   BLI_duplicatelist(&ctx->entries, &store->entries);
190 
191   return ctx;
192 }
193 
CTX_store_free(bContextStore * store)194 void CTX_store_free(bContextStore *store)
195 {
196   BLI_freelistN(&store->entries);
197   MEM_freeN(store);
198 }
199 
CTX_store_free_list(ListBase * contexts)200 void CTX_store_free_list(ListBase *contexts)
201 {
202   bContextStore *ctx;
203   while ((ctx = BLI_pophead(contexts))) {
204     CTX_store_free(ctx);
205   }
206 }
207 
208 /* is python initialized? */
209 
CTX_py_init_get(bContext * C)210 bool CTX_py_init_get(bContext *C)
211 {
212   return C->data.py_init;
213 }
CTX_py_init_set(bContext * C,bool value)214 void CTX_py_init_set(bContext *C, bool value)
215 {
216   C->data.py_init = value;
217 }
218 
CTX_py_dict_get(const bContext * C)219 void *CTX_py_dict_get(const bContext *C)
220 {
221   return C->data.py_context;
222 }
CTX_py_dict_get_orig(const bContext * C)223 void *CTX_py_dict_get_orig(const bContext *C)
224 {
225   return C->data.py_context_orig;
226 }
227 
CTX_py_state_push(bContext * C,struct bContext_PyState * pystate,void * value)228 void CTX_py_state_push(bContext *C, struct bContext_PyState *pystate, void *value)
229 {
230   pystate->py_context = C->data.py_context;
231   pystate->py_context_orig = C->data.py_context_orig;
232 
233   C->data.py_context = value;
234   C->data.py_context_orig = value;
235 }
CTX_py_state_pop(bContext * C,struct bContext_PyState * pystate)236 void CTX_py_state_pop(bContext *C, struct bContext_PyState *pystate)
237 {
238   C->data.py_context = pystate->py_context;
239   C->data.py_context_orig = pystate->py_context_orig;
240 }
241 
242 /* data context utility functions */
243 
244 struct bContextDataResult {
245   PointerRNA ptr;
246   ListBase list;
247   const char **dir;
248   short type; /* 0: normal, 1: seq */
249 };
250 
ctx_wm_python_context_get(const bContext * C,const char * member,const StructRNA * member_type,void * fall_through)251 static void *ctx_wm_python_context_get(const bContext *C,
252                                        const char *member,
253                                        const StructRNA *member_type,
254                                        void *fall_through)
255 {
256 #ifdef WITH_PYTHON
257   if (UNLIKELY(C && CTX_py_dict_get(C))) {
258     bContextDataResult result;
259     memset(&result, 0, sizeof(bContextDataResult));
260     BPY_context_member_get((bContext *)C, member, &result);
261 
262     if (result.ptr.data) {
263       if (RNA_struct_is_a(result.ptr.type, member_type)) {
264         return result.ptr.data;
265       }
266 
267       CLOG_WARN(&LOG,
268                 "PyContext '%s' is a '%s', expected a '%s'",
269                 member,
270                 RNA_struct_identifier(result.ptr.type),
271                 RNA_struct_identifier(member_type));
272     }
273   }
274 #else
275   UNUSED_VARS(C, member, member_type);
276 #endif
277 
278   /* don't allow UI context access from non-main threads */
279   if (!BLI_thread_is_main()) {
280     return NULL;
281   }
282 
283   return fall_through;
284 }
285 
ctx_data_get(bContext * C,const char * member,bContextDataResult * result)286 static eContextResult ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
287 {
288   bScreen *screen;
289   ScrArea *area;
290   ARegion *region;
291   int done = 0, recursion = C->data.recursion;
292   int ret = 0;
293 
294   memset(result, 0, sizeof(bContextDataResult));
295 #ifdef WITH_PYTHON
296   if (CTX_py_dict_get(C)) {
297     if (BPY_context_member_get(C, member, result)) {
298       return 1;
299     }
300   }
301 #endif
302 
303   /* don't allow UI context access from non-main threads */
304   if (!BLI_thread_is_main()) {
305     return done;
306   }
307 
308   /* we check recursion to ensure that we do not get infinite
309    * loops requesting data from ourselves in a context callback */
310 
311   /* Ok, this looks evil...
312    * if (ret) done = -(-ret | -done);
313    *
314    * Values in order of importance
315    * (0, -1, 1) - Where 1 is highest priority
316    * */
317   if (done != 1 && recursion < 1 && C->wm.store) {
318     C->data.recursion = 1;
319 
320     bContextStoreEntry *entry = BLI_rfindstring(
321         &C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
322 
323     if (entry) {
324       result->ptr = entry->ptr;
325       done = 1;
326     }
327   }
328   if (done != 1 && recursion < 2 && (region = CTX_wm_region(C))) {
329     C->data.recursion = 2;
330     if (region->type && region->type->context) {
331       ret = region->type->context(C, member, result);
332       if (ret) {
333         done = -(-ret | -done);
334       }
335     }
336   }
337   if (done != 1 && recursion < 3 && (area = CTX_wm_area(C))) {
338     C->data.recursion = 3;
339     if (area->type && area->type->context) {
340       ret = area->type->context(C, member, result);
341       if (ret) {
342         done = -(-ret | -done);
343       }
344     }
345   }
346 
347   if (done != 1 && recursion < 4 && (screen = CTX_wm_screen(C))) {
348     bContextDataCallback cb = screen->context;
349     C->data.recursion = 4;
350     if (cb) {
351       ret = cb(C, member, result);
352       if (ret) {
353         done = -(-ret | -done);
354       }
355     }
356   }
357 
358   C->data.recursion = recursion;
359 
360   return done;
361 }
362 
ctx_data_pointer_get(const bContext * C,const char * member)363 static void *ctx_data_pointer_get(const bContext *C, const char *member)
364 {
365   bContextDataResult result;
366   if (C && ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
367     BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
368     return result.ptr.data;
369   }
370 
371   return NULL;
372 }
373 
ctx_data_pointer_verify(const bContext * C,const char * member,void ** pointer)374 static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
375 {
376   /* if context is NULL, pointer must be NULL too and that is a valid return */
377   if (C == NULL) {
378     *pointer = NULL;
379     return 1;
380   }
381 
382   bContextDataResult result;
383   if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
384     BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
385     *pointer = result.ptr.data;
386     return 1;
387   }
388 
389   *pointer = NULL;
390   return 0;
391 }
392 
ctx_data_collection_get(const bContext * C,const char * member,ListBase * list)393 static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
394 {
395   bContextDataResult result;
396   if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
397     BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
398     *list = result.list;
399     return 1;
400   }
401 
402   BLI_listbase_clear(list);
403 
404   return 0;
405 }
406 
ctx_data_base_collection_get(const bContext * C,const char * member,ListBase * list)407 static int ctx_data_base_collection_get(const bContext *C, const char *member, ListBase *list)
408 {
409   ListBase ctx_object_list;
410   if ((ctx_data_collection_get(C, member, &ctx_object_list) == false) ||
411       BLI_listbase_is_empty(&ctx_object_list)) {
412     BLI_listbase_clear(list);
413     return 0;
414   }
415 
416   bContextDataResult result;
417   memset(&result, 0, sizeof(bContextDataResult));
418 
419   Scene *scene = CTX_data_scene(C);
420   ViewLayer *view_layer = CTX_data_view_layer(C);
421 
422   bool ok = false;
423 
424   CollectionPointerLink *ctx_object;
425   for (ctx_object = ctx_object_list.first; ctx_object; ctx_object = ctx_object->next) {
426     Object *ob = ctx_object->ptr.data;
427     Base *base = BKE_view_layer_base_find(view_layer, ob);
428     if (base != NULL) {
429       CTX_data_list_add(&result, &scene->id, &RNA_ObjectBase, base);
430       ok = true;
431     }
432   }
433   CTX_data_type_set(&result, CTX_DATA_TYPE_COLLECTION);
434   BLI_freelistN(&ctx_object_list);
435 
436   *list = result.list;
437   return ok;
438 }
439 
CTX_data_pointer_get(const bContext * C,const char * member)440 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
441 {
442   bContextDataResult result;
443   if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
444     BLI_assert(result.type == CTX_DATA_TYPE_POINTER);
445     return result.ptr;
446   }
447 
448   return PointerRNA_NULL;
449 }
450 
CTX_data_pointer_get_type(const bContext * C,const char * member,StructRNA * type)451 PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
452 {
453   PointerRNA ptr = CTX_data_pointer_get(C, member);
454 
455   if (ptr.data) {
456     if (RNA_struct_is_a(ptr.type, type)) {
457       return ptr;
458     }
459 
460     CLOG_WARN(&LOG,
461               "member '%s' is '%s', not '%s'",
462               member,
463               RNA_struct_identifier(ptr.type),
464               RNA_struct_identifier(type));
465   }
466 
467   return PointerRNA_NULL;
468 }
469 
CTX_data_pointer_get_type_silent(const bContext * C,const char * member,StructRNA * type)470 PointerRNA CTX_data_pointer_get_type_silent(const bContext *C, const char *member, StructRNA *type)
471 {
472   PointerRNA ptr = CTX_data_pointer_get(C, member);
473 
474   if (ptr.data && RNA_struct_is_a(ptr.type, type)) {
475     return ptr;
476   }
477 
478   return PointerRNA_NULL;
479 }
480 
CTX_data_collection_get(const bContext * C,const char * member)481 ListBase CTX_data_collection_get(const bContext *C, const char *member)
482 {
483   bContextDataResult result;
484   if (ctx_data_get((bContext *)C, member, &result) == CTX_RESULT_OK) {
485     BLI_assert(result.type == CTX_DATA_TYPE_COLLECTION);
486     return result.list;
487   }
488 
489   ListBase list = {NULL, NULL};
490   return list;
491 }
492 
CTX_data_get(const bContext * C,const char * member,PointerRNA * r_ptr,ListBase * r_lb,short * r_type)493 int /*eContextResult*/ CTX_data_get(
494     const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb, short *r_type)
495 {
496   bContextDataResult result;
497   eContextResult ret = ctx_data_get((bContext *)C, member, &result);
498 
499   if (ret == CTX_RESULT_OK) {
500     *r_ptr = result.ptr;
501     *r_lb = result.list;
502     *r_type = result.type;
503   }
504   else {
505     memset(r_ptr, 0, sizeof(*r_ptr));
506     memset(r_lb, 0, sizeof(*r_lb));
507     *r_type = 0;
508   }
509 
510   return ret;
511 }
512 
data_dir_add(ListBase * lb,const char * member,const bool use_all)513 static void data_dir_add(ListBase *lb, const char *member, const bool use_all)
514 {
515   LinkData *link;
516 
517   if ((use_all == false) && STREQ(member, "scene")) { /* exception */
518     return;
519   }
520 
521   if (BLI_findstring(lb, member, offsetof(LinkData, data))) {
522     return;
523   }
524 
525   link = MEM_callocN(sizeof(LinkData), "LinkData");
526   link->data = (void *)member;
527   BLI_addtail(lb, link);
528 }
529 
530 /**
531  * \param C: Context
532  * \param use_store: Use 'C->wm.store'
533  * \param use_rna: Use Include the properties from 'RNA_Context'
534  * \param use_all: Don't skip values (currently only "scene")
535  */
CTX_data_dir_get_ex(const bContext * C,const bool use_store,const bool use_rna,const bool use_all)536 ListBase CTX_data_dir_get_ex(const bContext *C,
537                              const bool use_store,
538                              const bool use_rna,
539                              const bool use_all)
540 {
541   bContextDataResult result;
542   ListBase lb;
543   bScreen *screen;
544   ScrArea *area;
545   ARegion *region;
546   int a;
547 
548   memset(&lb, 0, sizeof(lb));
549 
550   if (use_rna) {
551     char name[256], *nameptr;
552     int namelen;
553 
554     PropertyRNA *iterprop;
555     PointerRNA ctx_ptr;
556     RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr);
557 
558     iterprop = RNA_struct_iterator_property(ctx_ptr.type);
559 
560     RNA_PROP_BEGIN (&ctx_ptr, itemptr, iterprop) {
561       nameptr = RNA_struct_name_get_alloc(&itemptr, name, sizeof(name), &namelen);
562       data_dir_add(&lb, name, use_all);
563       if (nameptr) {
564         if (name != nameptr) {
565           MEM_freeN(nameptr);
566         }
567       }
568     }
569     RNA_PROP_END;
570   }
571   if (use_store && C->wm.store) {
572     bContextStoreEntry *entry;
573 
574     for (entry = C->wm.store->entries.first; entry; entry = entry->next) {
575       data_dir_add(&lb, entry->name, use_all);
576     }
577   }
578   if ((region = CTX_wm_region(C)) && region->type && region->type->context) {
579     memset(&result, 0, sizeof(result));
580     region->type->context(C, "", &result);
581 
582     if (result.dir) {
583       for (a = 0; result.dir[a]; a++) {
584         data_dir_add(&lb, result.dir[a], use_all);
585       }
586     }
587   }
588   if ((area = CTX_wm_area(C)) && area->type && area->type->context) {
589     memset(&result, 0, sizeof(result));
590     area->type->context(C, "", &result);
591 
592     if (result.dir) {
593       for (a = 0; result.dir[a]; a++) {
594         data_dir_add(&lb, result.dir[a], use_all);
595       }
596     }
597   }
598   if ((screen = CTX_wm_screen(C)) && screen->context) {
599     bContextDataCallback cb = screen->context;
600     memset(&result, 0, sizeof(result));
601     cb(C, "", &result);
602 
603     if (result.dir) {
604       for (a = 0; result.dir[a]; a++) {
605         data_dir_add(&lb, result.dir[a], use_all);
606       }
607     }
608   }
609 
610   return lb;
611 }
612 
CTX_data_dir_get(const bContext * C)613 ListBase CTX_data_dir_get(const bContext *C)
614 {
615   return CTX_data_dir_get_ex(C, true, false, false);
616 }
617 
CTX_data_equals(const char * member,const char * str)618 bool CTX_data_equals(const char *member, const char *str)
619 {
620   return (STREQ(member, str));
621 }
622 
CTX_data_dir(const char * member)623 bool CTX_data_dir(const char *member)
624 {
625   return member[0] == '\0';
626 }
627 
CTX_data_id_pointer_set(bContextDataResult * result,ID * id)628 void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
629 {
630   RNA_id_pointer_create(id, &result->ptr);
631 }
632 
CTX_data_pointer_set(bContextDataResult * result,ID * id,StructRNA * type,void * data)633 void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
634 {
635   RNA_pointer_create(id, type, data, &result->ptr);
636 }
637 
CTX_data_id_list_add(bContextDataResult * result,ID * id)638 void CTX_data_id_list_add(bContextDataResult *result, ID *id)
639 {
640   CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
641   RNA_id_pointer_create(id, &link->ptr);
642 
643   BLI_addtail(&result->list, link);
644 }
645 
CTX_data_list_add(bContextDataResult * result,ID * id,StructRNA * type,void * data)646 void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
647 {
648   CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
649   RNA_pointer_create(id, type, data, &link->ptr);
650 
651   BLI_addtail(&result->list, link);
652 }
653 
ctx_data_list_count(const bContext * C,int (* func)(const bContext *,ListBase *))654 int ctx_data_list_count(const bContext *C, int (*func)(const bContext *, ListBase *))
655 {
656   ListBase list;
657 
658   if (func(C, &list)) {
659     int tot = BLI_listbase_count(&list);
660     BLI_freelistN(&list);
661     return tot;
662   }
663 
664   return 0;
665 }
666 
CTX_data_dir_set(bContextDataResult * result,const char ** dir)667 void CTX_data_dir_set(bContextDataResult *result, const char **dir)
668 {
669   result->dir = dir;
670 }
671 
CTX_data_type_set(bContextDataResult * result,short type)672 void CTX_data_type_set(bContextDataResult *result, short type)
673 {
674   result->type = type;
675 }
676 
CTX_data_type_get(bContextDataResult * result)677 short CTX_data_type_get(bContextDataResult *result)
678 {
679   return result->type;
680 }
681 
682 /* window manager context */
683 
CTX_wm_manager(const bContext * C)684 wmWindowManager *CTX_wm_manager(const bContext *C)
685 {
686   return C->wm.manager;
687 }
688 
CTX_wm_interface_locked(const bContext * C)689 bool CTX_wm_interface_locked(const bContext *C)
690 {
691   return (bool)C->wm.manager->is_interface_locked;
692 }
693 
CTX_wm_window(const bContext * C)694 wmWindow *CTX_wm_window(const bContext *C)
695 {
696   return ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window);
697 }
698 
CTX_wm_workspace(const bContext * C)699 WorkSpace *CTX_wm_workspace(const bContext *C)
700 {
701   return ctx_wm_python_context_get(C, "workspace", &RNA_WorkSpace, C->wm.workspace);
702 }
703 
CTX_wm_screen(const bContext * C)704 bScreen *CTX_wm_screen(const bContext *C)
705 {
706   return ctx_wm_python_context_get(C, "screen", &RNA_Screen, C->wm.screen);
707 }
708 
CTX_wm_area(const bContext * C)709 ScrArea *CTX_wm_area(const bContext *C)
710 {
711   return ctx_wm_python_context_get(C, "area", &RNA_Area, C->wm.area);
712 }
713 
CTX_wm_space_data(const bContext * C)714 SpaceLink *CTX_wm_space_data(const bContext *C)
715 {
716   ScrArea *area = CTX_wm_area(C);
717   return (area) ? area->spacedata.first : NULL;
718 }
719 
CTX_wm_region(const bContext * C)720 ARegion *CTX_wm_region(const bContext *C)
721 {
722   return ctx_wm_python_context_get(C, "region", &RNA_Region, C->wm.region);
723 }
724 
CTX_wm_region_data(const bContext * C)725 void *CTX_wm_region_data(const bContext *C)
726 {
727   ARegion *region = CTX_wm_region(C);
728   return (region) ? region->regiondata : NULL;
729 }
730 
CTX_wm_menu(const bContext * C)731 struct ARegion *CTX_wm_menu(const bContext *C)
732 {
733   return C->wm.menu;
734 }
735 
CTX_wm_gizmo_group(const bContext * C)736 struct wmGizmoGroup *CTX_wm_gizmo_group(const bContext *C)
737 {
738   return C->wm.gizmo_group;
739 }
740 
CTX_wm_message_bus(const bContext * C)741 struct wmMsgBus *CTX_wm_message_bus(const bContext *C)
742 {
743   return C->wm.manager ? C->wm.manager->message_bus : NULL;
744 }
745 
CTX_wm_reports(const bContext * C)746 struct ReportList *CTX_wm_reports(const bContext *C)
747 {
748   if (C->wm.manager) {
749     return &(C->wm.manager->reports);
750   }
751 
752   return NULL;
753 }
754 
CTX_wm_view3d(const bContext * C)755 View3D *CTX_wm_view3d(const bContext *C)
756 {
757   ScrArea *area = CTX_wm_area(C);
758   if (area && area->spacetype == SPACE_VIEW3D) {
759     return area->spacedata.first;
760   }
761   return NULL;
762 }
763 
CTX_wm_region_view3d(const bContext * C)764 RegionView3D *CTX_wm_region_view3d(const bContext *C)
765 {
766   ScrArea *area = CTX_wm_area(C);
767   ARegion *region = CTX_wm_region(C);
768 
769   if (area && area->spacetype == SPACE_VIEW3D) {
770     if (region && region->regiontype == RGN_TYPE_WINDOW) {
771       return region->regiondata;
772     }
773   }
774   return NULL;
775 }
776 
CTX_wm_space_text(const bContext * C)777 struct SpaceText *CTX_wm_space_text(const bContext *C)
778 {
779   ScrArea *area = CTX_wm_area(C);
780   if (area && area->spacetype == SPACE_TEXT) {
781     return area->spacedata.first;
782   }
783   return NULL;
784 }
785 
CTX_wm_space_console(const bContext * C)786 struct SpaceConsole *CTX_wm_space_console(const bContext *C)
787 {
788   ScrArea *area = CTX_wm_area(C);
789   if (area && area->spacetype == SPACE_CONSOLE) {
790     return area->spacedata.first;
791   }
792   return NULL;
793 }
794 
CTX_wm_space_image(const bContext * C)795 struct SpaceImage *CTX_wm_space_image(const bContext *C)
796 {
797   ScrArea *area = CTX_wm_area(C);
798   if (area && area->spacetype == SPACE_IMAGE) {
799     return area->spacedata.first;
800   }
801   return NULL;
802 }
803 
CTX_wm_space_properties(const bContext * C)804 struct SpaceProperties *CTX_wm_space_properties(const bContext *C)
805 {
806   ScrArea *area = CTX_wm_area(C);
807   if (area && area->spacetype == SPACE_PROPERTIES) {
808     return area->spacedata.first;
809   }
810   return NULL;
811 }
812 
CTX_wm_space_file(const bContext * C)813 struct SpaceFile *CTX_wm_space_file(const bContext *C)
814 {
815   ScrArea *area = CTX_wm_area(C);
816   if (area && area->spacetype == SPACE_FILE) {
817     return area->spacedata.first;
818   }
819   return NULL;
820 }
821 
CTX_wm_space_seq(const bContext * C)822 struct SpaceSeq *CTX_wm_space_seq(const bContext *C)
823 {
824   ScrArea *area = CTX_wm_area(C);
825   if (area && area->spacetype == SPACE_SEQ) {
826     return area->spacedata.first;
827   }
828   return NULL;
829 }
830 
CTX_wm_space_outliner(const bContext * C)831 struct SpaceOutliner *CTX_wm_space_outliner(const bContext *C)
832 {
833   ScrArea *area = CTX_wm_area(C);
834   if (area && area->spacetype == SPACE_OUTLINER) {
835     return area->spacedata.first;
836   }
837   return NULL;
838 }
839 
CTX_wm_space_nla(const bContext * C)840 struct SpaceNla *CTX_wm_space_nla(const bContext *C)
841 {
842   ScrArea *area = CTX_wm_area(C);
843   if (area && area->spacetype == SPACE_NLA) {
844     return area->spacedata.first;
845   }
846   return NULL;
847 }
848 
CTX_wm_space_node(const bContext * C)849 struct SpaceNode *CTX_wm_space_node(const bContext *C)
850 {
851   ScrArea *area = CTX_wm_area(C);
852   if (area && area->spacetype == SPACE_NODE) {
853     return area->spacedata.first;
854   }
855   return NULL;
856 }
857 
CTX_wm_space_graph(const bContext * C)858 struct SpaceGraph *CTX_wm_space_graph(const bContext *C)
859 {
860   ScrArea *area = CTX_wm_area(C);
861   if (area && area->spacetype == SPACE_GRAPH) {
862     return area->spacedata.first;
863   }
864   return NULL;
865 }
866 
CTX_wm_space_action(const bContext * C)867 struct SpaceAction *CTX_wm_space_action(const bContext *C)
868 {
869   ScrArea *area = CTX_wm_area(C);
870   if (area && area->spacetype == SPACE_ACTION) {
871     return area->spacedata.first;
872   }
873   return NULL;
874 }
875 
CTX_wm_space_info(const bContext * C)876 struct SpaceInfo *CTX_wm_space_info(const bContext *C)
877 {
878   ScrArea *area = CTX_wm_area(C);
879   if (area && area->spacetype == SPACE_INFO) {
880     return area->spacedata.first;
881   }
882   return NULL;
883 }
884 
CTX_wm_space_userpref(const bContext * C)885 struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C)
886 {
887   ScrArea *area = CTX_wm_area(C);
888   if (area && area->spacetype == SPACE_USERPREF) {
889     return area->spacedata.first;
890   }
891   return NULL;
892 }
893 
CTX_wm_space_clip(const bContext * C)894 struct SpaceClip *CTX_wm_space_clip(const bContext *C)
895 {
896   ScrArea *area = CTX_wm_area(C);
897   if (area && area->spacetype == SPACE_CLIP) {
898     return area->spacedata.first;
899   }
900   return NULL;
901 }
902 
CTX_wm_space_topbar(const bContext * C)903 struct SpaceTopBar *CTX_wm_space_topbar(const bContext *C)
904 {
905   ScrArea *area = CTX_wm_area(C);
906   if (area && area->spacetype == SPACE_TOPBAR) {
907     return area->spacedata.first;
908   }
909   return NULL;
910 }
911 
CTX_wm_manager_set(bContext * C,wmWindowManager * wm)912 void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
913 {
914   C->wm.manager = wm;
915   C->wm.window = NULL;
916   C->wm.screen = NULL;
917   C->wm.area = NULL;
918   C->wm.region = NULL;
919 }
920 
921 #ifdef WITH_PYTHON
922 #  define PYCTX_REGION_MEMBERS "region", "region_data"
923 #  define PYCTX_AREA_MEMBERS "area", "space_data", PYCTX_REGION_MEMBERS
924 #  define PYCTX_SCREEN_MEMBERS "screen", PYCTX_AREA_MEMBERS
925 #  define PYCTX_WINDOW_MEMBERS "window", "scene", "workspace", PYCTX_SCREEN_MEMBERS
926 #endif
927 
CTX_wm_window_set(bContext * C,wmWindow * win)928 void CTX_wm_window_set(bContext *C, wmWindow *win)
929 {
930   C->wm.window = win;
931   if (win) {
932     C->data.scene = win->scene;
933   }
934   C->wm.workspace = (win) ? BKE_workspace_active_get(win->workspace_hook) : NULL;
935   C->wm.screen = (win) ? BKE_workspace_active_screen_get(win->workspace_hook) : NULL;
936   C->wm.area = NULL;
937   C->wm.region = NULL;
938 
939 #ifdef WITH_PYTHON
940   if (C->data.py_context != NULL) {
941     BPY_context_dict_clear_members(C, PYCTX_WINDOW_MEMBERS);
942   }
943 #endif
944 }
945 
CTX_wm_screen_set(bContext * C,bScreen * screen)946 void CTX_wm_screen_set(bContext *C, bScreen *screen)
947 {
948   C->wm.screen = screen;
949   C->wm.area = NULL;
950   C->wm.region = NULL;
951 
952 #ifdef WITH_PYTHON
953   if (C->data.py_context != NULL) {
954     BPY_context_dict_clear_members(C, PYCTX_SCREEN_MEMBERS);
955   }
956 #endif
957 }
958 
CTX_wm_area_set(bContext * C,ScrArea * area)959 void CTX_wm_area_set(bContext *C, ScrArea *area)
960 {
961   C->wm.area = area;
962   C->wm.region = NULL;
963 
964 #ifdef WITH_PYTHON
965   if (C->data.py_context != NULL) {
966     BPY_context_dict_clear_members(C, PYCTX_AREA_MEMBERS);
967   }
968 #endif
969 }
970 
CTX_wm_region_set(bContext * C,ARegion * region)971 void CTX_wm_region_set(bContext *C, ARegion *region)
972 {
973   C->wm.region = region;
974 
975 #ifdef WITH_PYTHON
976   if (C->data.py_context != NULL) {
977     BPY_context_dict_clear_members(C, PYCTX_REGION_MEMBERS);
978   }
979 #endif
980 }
981 
CTX_wm_menu_set(bContext * C,ARegion * menu)982 void CTX_wm_menu_set(bContext *C, ARegion *menu)
983 {
984   C->wm.menu = menu;
985 }
986 
CTX_wm_gizmo_group_set(bContext * C,struct wmGizmoGroup * gzgroup)987 void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *gzgroup)
988 {
989   C->wm.gizmo_group = gzgroup;
990 }
991 
CTX_wm_operator_poll_msg_set(bContext * C,const char * msg)992 void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
993 {
994   C->wm.operator_poll_msg = msg;
995 }
996 
CTX_wm_operator_poll_msg_get(bContext * C)997 const char *CTX_wm_operator_poll_msg_get(bContext *C)
998 {
999   return IFACE_(C->wm.operator_poll_msg);
1000 }
1001 
1002 /* data context */
1003 
CTX_data_main(const bContext * C)1004 Main *CTX_data_main(const bContext *C)
1005 {
1006   Main *bmain;
1007   if (ctx_data_pointer_verify(C, "blend_data", (void *)&bmain)) {
1008     return bmain;
1009   }
1010 
1011   return C->data.main;
1012 }
1013 
CTX_data_main_set(bContext * C,Main * bmain)1014 void CTX_data_main_set(bContext *C, Main *bmain)
1015 {
1016   C->data.main = bmain;
1017   BKE_sound_init_main(bmain);
1018 }
1019 
CTX_data_scene(const bContext * C)1020 Scene *CTX_data_scene(const bContext *C)
1021 {
1022   Scene *scene;
1023   if (ctx_data_pointer_verify(C, "scene", (void *)&scene)) {
1024     return scene;
1025   }
1026 
1027   return C->data.scene;
1028 }
1029 
CTX_data_view_layer(const bContext * C)1030 ViewLayer *CTX_data_view_layer(const bContext *C)
1031 {
1032   ViewLayer *view_layer;
1033 
1034   if (ctx_data_pointer_verify(C, "view_layer", (void *)&view_layer)) {
1035     return view_layer;
1036   }
1037 
1038   wmWindow *win = CTX_wm_window(C);
1039   Scene *scene = CTX_data_scene(C);
1040   if (win) {
1041     view_layer = BKE_view_layer_find(scene, win->view_layer_name);
1042     if (view_layer) {
1043       return view_layer;
1044     }
1045   }
1046 
1047   return BKE_view_layer_default_view(scene);
1048 }
1049 
CTX_data_engine_type(const bContext * C)1050 RenderEngineType *CTX_data_engine_type(const bContext *C)
1051 {
1052   Scene *scene = CTX_data_scene(C);
1053   return RE_engines_find(scene->r.engine);
1054 }
1055 
1056 /**
1057  * This is tricky. Sometimes the user overrides the render_layer
1058  * but not the scene_collection. In this case what to do?
1059  *
1060  * If the scene_collection is linked to the ViewLayer we use it.
1061  * Otherwise we fallback to the active one of the ViewLayer.
1062  */
CTX_data_layer_collection(const bContext * C)1063 LayerCollection *CTX_data_layer_collection(const bContext *C)
1064 {
1065   ViewLayer *view_layer = CTX_data_view_layer(C);
1066   LayerCollection *layer_collection;
1067 
1068   if (ctx_data_pointer_verify(C, "layer_collection", (void *)&layer_collection)) {
1069     if (BKE_view_layer_has_collection(view_layer, layer_collection->collection)) {
1070       return layer_collection;
1071     }
1072   }
1073 
1074   /* fallback */
1075   return BKE_layer_collection_get_active(view_layer);
1076 }
1077 
CTX_data_collection(const bContext * C)1078 Collection *CTX_data_collection(const bContext *C)
1079 {
1080   Collection *collection;
1081   if (ctx_data_pointer_verify(C, "collection", (void *)&collection)) {
1082     return collection;
1083   }
1084 
1085   LayerCollection *layer_collection = CTX_data_layer_collection(C);
1086   if (layer_collection) {
1087     return layer_collection->collection;
1088   }
1089 
1090   /* fallback */
1091   Scene *scene = CTX_data_scene(C);
1092   return scene->master_collection;
1093 }
1094 
CTX_data_mode_enum_ex(const Object * obedit,const Object * ob,const eObjectMode object_mode)1095 enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit,
1096                                               const Object *ob,
1097                                               const eObjectMode object_mode)
1098 {
1099   // Object *obedit = CTX_data_edit_object(C);
1100   if (obedit) {
1101     switch (obedit->type) {
1102       case OB_MESH:
1103         return CTX_MODE_EDIT_MESH;
1104       case OB_CURVE:
1105         return CTX_MODE_EDIT_CURVE;
1106       case OB_SURF:
1107         return CTX_MODE_EDIT_SURFACE;
1108       case OB_FONT:
1109         return CTX_MODE_EDIT_TEXT;
1110       case OB_ARMATURE:
1111         return CTX_MODE_EDIT_ARMATURE;
1112       case OB_MBALL:
1113         return CTX_MODE_EDIT_METABALL;
1114       case OB_LATTICE:
1115         return CTX_MODE_EDIT_LATTICE;
1116     }
1117   }
1118   else {
1119     // Object *ob = CTX_data_active_object(C);
1120     if (ob) {
1121       if (object_mode & OB_MODE_POSE) {
1122         return CTX_MODE_POSE;
1123       }
1124       if (object_mode & OB_MODE_SCULPT) {
1125         return CTX_MODE_SCULPT;
1126       }
1127       if (object_mode & OB_MODE_WEIGHT_PAINT) {
1128         return CTX_MODE_PAINT_WEIGHT;
1129       }
1130       if (object_mode & OB_MODE_VERTEX_PAINT) {
1131         return CTX_MODE_PAINT_VERTEX;
1132       }
1133       if (object_mode & OB_MODE_TEXTURE_PAINT) {
1134         return CTX_MODE_PAINT_TEXTURE;
1135       }
1136       if (object_mode & OB_MODE_PARTICLE_EDIT) {
1137         return CTX_MODE_PARTICLE;
1138       }
1139       if (object_mode & OB_MODE_PAINT_GPENCIL) {
1140         return CTX_MODE_PAINT_GPENCIL;
1141       }
1142       if (object_mode & OB_MODE_EDIT_GPENCIL) {
1143         return CTX_MODE_EDIT_GPENCIL;
1144       }
1145       if (object_mode & OB_MODE_SCULPT_GPENCIL) {
1146         return CTX_MODE_SCULPT_GPENCIL;
1147       }
1148       if (object_mode & OB_MODE_WEIGHT_GPENCIL) {
1149         return CTX_MODE_WEIGHT_GPENCIL;
1150       }
1151       if (object_mode & OB_MODE_VERTEX_GPENCIL) {
1152         return CTX_MODE_VERTEX_GPENCIL;
1153       }
1154     }
1155   }
1156 
1157   return CTX_MODE_OBJECT;
1158 }
1159 
CTX_data_mode_enum(const bContext * C)1160 enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
1161 {
1162   Object *obedit = CTX_data_edit_object(C);
1163   Object *obact = obedit ? NULL : CTX_data_active_object(C);
1164   return CTX_data_mode_enum_ex(obedit, obact, obact ? obact->mode : OB_MODE_OBJECT);
1165 }
1166 
1167 /* would prefer if we can use the enum version below over this one - Campbell */
1168 /* must be aligned with above enum  */
1169 static const char *data_mode_strings[] = {
1170     "mesh_edit",           "curve_edit",          "surface_edit",        "text_edit",
1171     "armature_edit",       "mball_edit",          "lattice_edit",        "posemode",
1172     "sculpt_mode",         "weightpaint",         "vertexpaint",         "imagepaint",
1173     "particlemode",        "objectmode",          "greasepencil_paint",  "greasepencil_edit",
1174     "greasepencil_sculpt", "greasepencil_weight", "greasepencil_vertex", NULL,
1175 };
ARRAY_SIZE(data_mode_strings)1176 BLI_STATIC_ASSERT(ARRAY_SIZE(data_mode_strings) == CTX_MODE_NUM + 1,
1177                   "Must have a string for each context mode")
1178 const char *CTX_data_mode_string(const bContext *C)
1179 {
1180   return data_mode_strings[CTX_data_mode_enum(C)];
1181 }
1182 
CTX_data_scene_set(bContext * C,Scene * scene)1183 void CTX_data_scene_set(bContext *C, Scene *scene)
1184 {
1185   C->data.scene = scene;
1186 
1187 #ifdef WITH_PYTHON
1188   if (C->data.py_context != NULL) {
1189     BPY_context_dict_clear_members(C, "scene");
1190   }
1191 #endif
1192 }
1193 
CTX_data_tool_settings(const bContext * C)1194 ToolSettings *CTX_data_tool_settings(const bContext *C)
1195 {
1196   Scene *scene = CTX_data_scene(C);
1197 
1198   if (scene) {
1199     return scene->toolsettings;
1200   }
1201 
1202   return NULL;
1203 }
1204 
CTX_data_selected_nodes(const bContext * C,ListBase * list)1205 int CTX_data_selected_nodes(const bContext *C, ListBase *list)
1206 {
1207   return ctx_data_collection_get(C, "selected_nodes", list);
1208 }
1209 
CTX_data_selected_editable_objects(const bContext * C,ListBase * list)1210 int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
1211 {
1212   return ctx_data_collection_get(C, "selected_editable_objects", list);
1213 }
1214 
CTX_data_selected_editable_bases(const bContext * C,ListBase * list)1215 int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
1216 {
1217   return ctx_data_base_collection_get(C, "selected_editable_objects", list);
1218 }
1219 
CTX_data_editable_objects(const bContext * C,ListBase * list)1220 int CTX_data_editable_objects(const bContext *C, ListBase *list)
1221 {
1222   return ctx_data_collection_get(C, "editable_objects", list);
1223 }
1224 
CTX_data_editable_bases(const bContext * C,ListBase * list)1225 int CTX_data_editable_bases(const bContext *C, ListBase *list)
1226 {
1227   return ctx_data_base_collection_get(C, "editable_objects", list);
1228 }
1229 
CTX_data_selected_objects(const bContext * C,ListBase * list)1230 int CTX_data_selected_objects(const bContext *C, ListBase *list)
1231 {
1232   return ctx_data_collection_get(C, "selected_objects", list);
1233 }
1234 
CTX_data_selected_bases(const bContext * C,ListBase * list)1235 int CTX_data_selected_bases(const bContext *C, ListBase *list)
1236 {
1237   return ctx_data_base_collection_get(C, "selected_objects", list);
1238 }
1239 
CTX_data_visible_objects(const bContext * C,ListBase * list)1240 int CTX_data_visible_objects(const bContext *C, ListBase *list)
1241 {
1242   return ctx_data_collection_get(C, "visible_objects", list);
1243 }
1244 
CTX_data_visible_bases(const bContext * C,ListBase * list)1245 int CTX_data_visible_bases(const bContext *C, ListBase *list)
1246 {
1247   return ctx_data_base_collection_get(C, "visible_objects", list);
1248 }
1249 
CTX_data_selectable_objects(const bContext * C,ListBase * list)1250 int CTX_data_selectable_objects(const bContext *C, ListBase *list)
1251 {
1252   return ctx_data_collection_get(C, "selectable_objects", list);
1253 }
1254 
CTX_data_selectable_bases(const bContext * C,ListBase * list)1255 int CTX_data_selectable_bases(const bContext *C, ListBase *list)
1256 {
1257   return ctx_data_base_collection_get(C, "selectable_objects", list);
1258 }
1259 
CTX_data_active_object(const bContext * C)1260 struct Object *CTX_data_active_object(const bContext *C)
1261 {
1262   return ctx_data_pointer_get(C, "active_object");
1263 }
1264 
CTX_data_active_base(const bContext * C)1265 struct Base *CTX_data_active_base(const bContext *C)
1266 {
1267   Object *ob = ctx_data_pointer_get(C, "active_object");
1268 
1269   if (ob == NULL) {
1270     return NULL;
1271   }
1272 
1273   ViewLayer *view_layer = CTX_data_view_layer(C);
1274   return BKE_view_layer_base_find(view_layer, ob);
1275 }
1276 
CTX_data_edit_object(const bContext * C)1277 struct Object *CTX_data_edit_object(const bContext *C)
1278 {
1279   return ctx_data_pointer_get(C, "edit_object");
1280 }
1281 
CTX_data_edit_image(const bContext * C)1282 struct Image *CTX_data_edit_image(const bContext *C)
1283 {
1284   return ctx_data_pointer_get(C, "edit_image");
1285 }
1286 
CTX_data_edit_text(const bContext * C)1287 struct Text *CTX_data_edit_text(const bContext *C)
1288 {
1289   return ctx_data_pointer_get(C, "edit_text");
1290 }
1291 
CTX_data_edit_movieclip(const bContext * C)1292 struct MovieClip *CTX_data_edit_movieclip(const bContext *C)
1293 {
1294   return ctx_data_pointer_get(C, "edit_movieclip");
1295 }
1296 
CTX_data_edit_mask(const bContext * C)1297 struct Mask *CTX_data_edit_mask(const bContext *C)
1298 {
1299   return ctx_data_pointer_get(C, "edit_mask");
1300 }
1301 
CTX_data_active_bone(const bContext * C)1302 struct EditBone *CTX_data_active_bone(const bContext *C)
1303 {
1304   return ctx_data_pointer_get(C, "active_bone");
1305 }
1306 
CTX_data_edit_cachefile(const bContext * C)1307 struct CacheFile *CTX_data_edit_cachefile(const bContext *C)
1308 {
1309   return ctx_data_pointer_get(C, "edit_cachefile");
1310 }
1311 
CTX_data_selected_bones(const bContext * C,ListBase * list)1312 int CTX_data_selected_bones(const bContext *C, ListBase *list)
1313 {
1314   return ctx_data_collection_get(C, "selected_bones", list);
1315 }
1316 
CTX_data_selected_editable_bones(const bContext * C,ListBase * list)1317 int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
1318 {
1319   return ctx_data_collection_get(C, "selected_editable_bones", list);
1320 }
1321 
CTX_data_visible_bones(const bContext * C,ListBase * list)1322 int CTX_data_visible_bones(const bContext *C, ListBase *list)
1323 {
1324   return ctx_data_collection_get(C, "visible_bones", list);
1325 }
1326 
CTX_data_editable_bones(const bContext * C,ListBase * list)1327 int CTX_data_editable_bones(const bContext *C, ListBase *list)
1328 {
1329   return ctx_data_collection_get(C, "editable_bones", list);
1330 }
1331 
CTX_data_active_pose_bone(const bContext * C)1332 struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C)
1333 {
1334   return ctx_data_pointer_get(C, "active_pose_bone");
1335 }
1336 
CTX_data_selected_pose_bones(const bContext * C,ListBase * list)1337 int CTX_data_selected_pose_bones(const bContext *C, ListBase *list)
1338 {
1339   return ctx_data_collection_get(C, "selected_pose_bones", list);
1340 }
1341 
CTX_data_selected_pose_bones_from_active_object(const bContext * C,ListBase * list)1342 int CTX_data_selected_pose_bones_from_active_object(const bContext *C, ListBase *list)
1343 {
1344   return ctx_data_collection_get(C, "selected_pose_bones_from_active_object", list);
1345 }
1346 
CTX_data_visible_pose_bones(const bContext * C,ListBase * list)1347 int CTX_data_visible_pose_bones(const bContext *C, ListBase *list)
1348 {
1349   return ctx_data_collection_get(C, "visible_pose_bones", list);
1350 }
1351 
CTX_data_gpencil_data(const bContext * C)1352 bGPdata *CTX_data_gpencil_data(const bContext *C)
1353 {
1354   return ctx_data_pointer_get(C, "gpencil_data");
1355 }
1356 
CTX_data_active_gpencil_layer(const bContext * C)1357 bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C)
1358 {
1359   return ctx_data_pointer_get(C, "active_gpencil_layer");
1360 }
1361 
CTX_data_active_gpencil_frame(const bContext * C)1362 bGPDframe *CTX_data_active_gpencil_frame(const bContext *C)
1363 {
1364   return ctx_data_pointer_get(C, "active_gpencil_frame");
1365 }
1366 
CTX_data_visible_gpencil_layers(const bContext * C,ListBase * list)1367 int CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list)
1368 {
1369   return ctx_data_collection_get(C, "visible_gpencil_layers", list);
1370 }
1371 
CTX_data_editable_gpencil_layers(const bContext * C,ListBase * list)1372 int CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list)
1373 {
1374   return ctx_data_collection_get(C, "editable_gpencil_layers", list);
1375 }
1376 
CTX_data_editable_gpencil_strokes(const bContext * C,ListBase * list)1377 int CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
1378 {
1379   return ctx_data_collection_get(C, "editable_gpencil_strokes", list);
1380 }
1381 
CTX_data_depsgraph_pointer(const bContext * C)1382 Depsgraph *CTX_data_depsgraph_pointer(const bContext *C)
1383 {
1384   Main *bmain = CTX_data_main(C);
1385   Scene *scene = CTX_data_scene(C);
1386   ViewLayer *view_layer = CTX_data_view_layer(C);
1387   Depsgraph *depsgraph = BKE_scene_ensure_depsgraph(bmain, scene, view_layer);
1388   /* Dependency graph might have been just allocated, and hence it will not be marked.
1389    * This confuses redo system due to the lack of flushing changes back to the original data.
1390    * In the future we would need to check whether the CTX_wm_window(C)  is in editing mode (as an
1391    * opposite of playback-preview-only) and set active flag based on that. */
1392   DEG_make_active(depsgraph);
1393   return depsgraph;
1394 }
1395 
CTX_data_expect_evaluated_depsgraph(const bContext * C)1396 Depsgraph *CTX_data_expect_evaluated_depsgraph(const bContext *C)
1397 {
1398   Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1399   /* TODO(sergey): Assert that the dependency graph is fully evaluated.
1400    * Note that first the depsgraph and scene post-eval hooks needs to run extra round of updates
1401    * first to make check here really reliable. */
1402   return depsgraph;
1403 }
1404 
CTX_data_ensure_evaluated_depsgraph(const bContext * C)1405 Depsgraph *CTX_data_ensure_evaluated_depsgraph(const bContext *C)
1406 {
1407   Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
1408   Main *bmain = CTX_data_main(C);
1409   BKE_scene_graph_evaluated_ensure(depsgraph, bmain);
1410   return depsgraph;
1411 }
1412 
CTX_data_depsgraph_on_load(const bContext * C)1413 Depsgraph *CTX_data_depsgraph_on_load(const bContext *C)
1414 {
1415   Scene *scene = CTX_data_scene(C);
1416   ViewLayer *view_layer = CTX_data_view_layer(C);
1417   return BKE_scene_get_depsgraph(scene, view_layer);
1418 }
1419