Blender  V3.3
blender.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "MEM_guardedalloc.h"
15 
16 #include "BLI_listbase.h"
17 #include "BLI_string.h"
18 #include "BLI_utildefines.h"
19 
20 #include "IMB_imbuf.h"
21 #include "IMB_moviecache.h"
22 
23 #include "BKE_addon.h"
24 #include "BKE_blender.h" /* own include */
25 #include "BKE_blender_user_menu.h"
26 #include "BKE_blender_version.h" /* own include */
27 #include "BKE_blendfile.h"
28 #include "BKE_brush.h"
29 #include "BKE_cachefile.h"
30 #include "BKE_callbacks.h"
31 #include "BKE_global.h"
32 #include "BKE_idprop.h"
33 #include "BKE_image.h"
34 #include "BKE_layer.h"
35 #include "BKE_main.h"
36 #include "BKE_node.h"
37 #include "BKE_report.h"
38 #include "BKE_scene.h"
39 #include "BKE_screen.h"
40 #include "BKE_studiolight.h"
41 
42 #include "DEG_depsgraph.h"
43 
44 #include "RE_pipeline.h"
45 #include "RE_texture.h"
46 
47 #include "SEQ_sequencer.h"
48 
49 #include "BLF_api.h"
50 
53 
54 /* -------------------------------------------------------------------- */
58 void BKE_blender_free(void)
59 {
60  /* samples are in a global list..., also sets G_MAIN->sound->sample NULL */
61 
62  /* Needs to run before main free as wm is still referenced for icons preview jobs. */
64 
66  G_MAIN = NULL;
67 
68  if (G.log.file != NULL) {
69  fclose(G.log.file);
70  }
71 
72  BKE_spacetypes_free(); /* after free main, it uses space callbacks */
73 
74  IMB_exit();
77 
80 
82 
84 
86 }
87 
90 /* -------------------------------------------------------------------- */
94 static char blender_version_string[48] = "";
95 
96 static void blender_version_init(void)
97 {
98  const char *version_cycle = "";
99  if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha")) {
100  version_cycle = " Alpha";
101  }
102  else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "beta")) {
103  version_cycle = " Beta";
104  }
105  else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "rc")) {
106  version_cycle = " Release Candidate";
107  }
108  else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
109  version_cycle = "";
110  }
111  else {
112  BLI_assert_msg(0, "Invalid Blender version cycle");
113  }
114 
117  "%d.%01d.%d%s",
118  BLENDER_VERSION / 100,
119  BLENDER_VERSION % 100,
121  version_cycle);
122 }
123 
124 const char *BKE_blender_version_string(void)
125 {
126  return blender_version_string;
127 }
128 
130  const size_t str_buff_len,
131  const short file_version,
132  const short file_subversion)
133 {
134  const short file_version_major = file_version / 100;
135  const short file_version_minor = file_version % 100;
136  if (file_subversion >= 0) {
137  BLI_snprintf(str_buff,
138  str_buff_len,
139  "%d.%d (sub %d)",
140  file_version_major,
141  file_version_minor,
142  file_subversion);
143  }
144  else {
145  BLI_snprintf(str_buff, str_buff_len, "%d.%d", file_version_major, file_version_minor);
146  }
147 }
148 
150 {
151  bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha");
152  return is_alpha;
153 }
154 
157 /* -------------------------------------------------------------------- */
162 {
164 
165  memset(&G, 0, sizeof(Global));
166 
167  U.savetime = 1;
168 
169  G_MAIN = BKE_main_new();
170 
171  strcpy(G.ima, "//");
172 
173 #ifndef WITH_PYTHON_SECURITY /* default */
175 #else
177 #endif
178 
179  G.log.level = 1;
180 }
181 
183 {
184  BKE_main_free(G_MAIN); /* free all lib data */
185 
186  G_MAIN = NULL;
187 }
188 
191 /* -------------------------------------------------------------------- */
196 {
197  if (kmi->properties) {
199  }
200  if (kmi->ptr) {
201  MEM_freeN(kmi->ptr);
202  }
203 }
204 
205 void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
206 {
207  SWAP(UserDef, *userdef_a, *userdef_b);
208 }
209 
211 {
212  BKE_blender_userdef_data_swap(&U, userdef);
213  BKE_blender_userdef_data_free(userdef, true);
214 }
215 
217 {
219  MEM_freeN(userdef);
220 }
221 
222 static void userdef_free_keymaps(UserDef *userdef)
223 {
224  for (wmKeyMap *km = userdef->user_keymaps.first, *km_next; km; km = km_next) {
225  km_next = km->next;
226  LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
227  if (kmdi->add_item) {
228  keymap_item_free(kmdi->add_item);
229  MEM_freeN(kmdi->add_item);
230  }
231  if (kmdi->remove_item) {
232  keymap_item_free(kmdi->remove_item);
233  MEM_freeN(kmdi->remove_item);
234  }
235  }
236 
237  LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
238  keymap_item_free(kmi);
239  }
240 
241  BLI_freelistN(&km->diff_items);
242  BLI_freelistN(&km->items);
243 
244  MEM_freeN(km);
245  }
246  BLI_listbase_clear(&userdef->user_keymaps);
247 }
248 
250 {
251  for (wmKeyConfigPref *kpt = userdef->user_keyconfig_prefs.first, *kpt_next; kpt;
252  kpt = kpt_next) {
253  kpt_next = kpt->next;
254  IDP_FreeProperty(kpt->prop);
255  MEM_freeN(kpt);
256  }
258 }
259 
260 static void userdef_free_user_menus(UserDef *userdef)
261 {
262  for (bUserMenu *um = userdef->user_menus.first, *um_next; um; um = um_next) {
263  um_next = um->next;
265  MEM_freeN(um);
266  }
267 }
268 
269 static void userdef_free_addons(UserDef *userdef)
270 {
271  for (bAddon *addon = userdef->addons.first, *addon_next; addon; addon = addon_next) {
272  addon_next = addon->next;
273  BKE_addon_free(addon);
274  }
275  BLI_listbase_clear(&userdef->addons);
276 }
277 
278 void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
279 {
280 #define U BLI_STATIC_ASSERT(false, "Global 'U' not allowed, only use arguments passed in!")
281 #ifdef U /* quiet warning */
282 #endif
283 
284  userdef_free_keymaps(userdef);
286  userdef_free_user_menus(userdef);
287  userdef_free_addons(userdef);
288 
289  if (clear_fonts) {
290  LISTBASE_FOREACH (uiFont *, font, &userdef->uifonts) {
291  BLF_unload_id(font->blf_id);
292  }
293  BLF_default_set(-1);
294  }
295 
296  BLI_freelistN(&userdef->autoexec_paths);
297  BLI_freelistN(&userdef->asset_libraries);
298 
299  BLI_freelistN(&userdef->uistyles);
300  BLI_freelistN(&userdef->uifonts);
301  BLI_freelistN(&userdef->themes);
302 
303 #undef U
304 }
305 
308 /* -------------------------------------------------------------------- */
313 {
314  /* TODO:
315  * - various minor settings (add as needed).
316  */
317 
318 #define DATA_SWAP(id) \
319  { \
320  UserDef userdef_tmp; \
321  memcpy(&(userdef_tmp.id), &(userdef_a->id), sizeof(userdef_tmp.id)); \
322  memcpy(&(userdef_a->id), &(userdef_b->id), sizeof(userdef_tmp.id)); \
323  memcpy(&(userdef_b->id), &(userdef_tmp.id), sizeof(userdef_tmp.id)); \
324  } \
325  ((void)0)
326 
327 #define LIST_SWAP(id) \
328  { \
329  SWAP(ListBase, userdef_a->id, userdef_b->id); \
330  } \
331  ((void)0)
332 
333 #define FLAG_SWAP(id, ty, flags) \
334  { \
335  CHECK_TYPE(&(userdef_a->id), ty *); \
336  const ty f = flags; \
337  const ty a = userdef_a->id; \
338  const ty b = userdef_b->id; \
339  userdef_a->id = (userdef_a->id & ~f) | (b & f); \
340  userdef_b->id = (userdef_b->id & ~f) | (a & f); \
341  } \
342  ((void)0)
343 
344  LIST_SWAP(uistyles);
345  LIST_SWAP(uifonts);
346  LIST_SWAP(themes);
347  LIST_SWAP(addons);
348  LIST_SWAP(user_keymaps);
349  LIST_SWAP(user_keyconfig_prefs);
350 
351  DATA_SWAP(font_path_ui);
352  DATA_SWAP(font_path_ui_mono);
353  DATA_SWAP(keyconfigstr);
354 
355  DATA_SWAP(gizmo_flag);
356  DATA_SWAP(app_flag);
357 
358  /* We could add others. */
360 
361  DATA_SWAP(ui_scale);
362 
363 #undef SWAP_TYPELESS
364 #undef DATA_SWAP
365 #undef LIST_SWAP
366 #undef FLAG_SWAP
367 }
368 
370 {
372  BKE_blender_userdef_data_free(userdef, true);
373 }
374 
376 {
378  MEM_freeN(userdef);
379 }
380 
383 /* -------------------------------------------------------------------- */
389 static struct AtExitData {
390  struct AtExitData *next;
391 
392  void (*func)(void *user_data);
393  void *user_data;
395 
397 {
398  struct AtExitData *ae = malloc(sizeof(*ae));
399  ae->next = g_atexit;
400  ae->func = func;
401  ae->user_data = user_data;
402  g_atexit = ae;
403 }
404 
405 void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *user_data)
406 {
407  struct AtExitData *ae = g_atexit;
408  struct AtExitData **ae_p = &g_atexit;
409 
410  while (ae) {
411  if ((ae->func == func) && (ae->user_data == user_data)) {
412  *ae_p = ae->next;
413  free(ae);
414  return;
415  }
416  ae_p = &ae->next;
417  ae = ae->next;
418  }
419 }
420 
422 {
423  struct AtExitData *ae = g_atexit, *ae_next;
424  while (ae) {
425  ae_next = ae->next;
426 
427  ae->func(ae->user_data);
428 
429  free(ae);
430  ae = ae_next;
431  }
432  g_atexit = NULL;
433 }
434 
void BKE_addon_free(struct bAddon *addon)
Definition: addon.c:66
Blender util stuff.
void BKE_blender_user_menu_item_free_list(struct ListBase *lb)
#define BLENDER_VERSION_PATCH
#define BLENDER_VERSION_CYCLE
#define BLENDER_VERSION
void BKE_brush_system_exit(void)
Definition: brush.cc:433
void BKE_cachefiles_exit(void)
Definition: cachefile.c:169
void BKE_callback_global_finalize(void)
Definition: callbacks.c:105
#define G_MAIN
Definition: BKE_global.h:267
@ G_FLAG_SCRIPT_AUTOEXEC
Definition: BKE_global.h:154
void IDP_FreeProperty(struct IDProperty *prop)
Definition: idprop.c:1093
struct Main * BKE_main_new(void)
Definition: main.c:32
void BKE_main_free(struct Main *mainvar)
Definition: main.c:40
void BKE_node_system_exit(void)
Definition: node.cc:4957
void BKE_spacetypes_free(void)
Definition: screen.c:344
void BKE_studiolight_free(void)
Definition: studiolight.c:1429
void BLF_default_set(int fontid)
Definition: blf_default.c:37
void BLF_unload_id(int fontid)
Definition: blf.c:242
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
void BLI_kdtree_nd_() free(KDTree *tree)
Definition: kdtree_impl.h:102
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define ARRAY_SIZE(arr)
#define SWAP(type, a, b)
#define STRINGIFY(x)
#define STREQ(a, b)
void DEG_free_node_types(void)
@ USER_SPLASH_DISABLE
@ USER_SHOW_GIZMO_NAVIGATE
@ USER_SAVE_PROMPT
void IMB_exit(void)
Definition: module.c:25
void IMB_moviecache_destruct(void)
Definition: moviecache.cc:257
Read Guarded memory(de)allocation.
static struct AtExitData * g_atexit
void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
Definition: blender.c:205
static char blender_version_string[48]
Definition: blender.c:94
bool BKE_blender_version_is_alpha(void)
Definition: blender.c:149
static void userdef_free_keymaps(UserDef *userdef)
Definition: blender.c:222
void BKE_blender_version_blendfile_string_from_values(char *str_buff, const size_t str_buff_len, const short file_version, const short file_subversion)
Definition: blender.c:129
void BKE_blender_userdef_data_set(UserDef *userdef)
Definition: blender.c:210
static void userdef_free_addons(UserDef *userdef)
Definition: blender.c:269
void BKE_blender_globals_clear(void)
Definition: blender.c:182
static void userdef_free_user_menus(UserDef *userdef)
Definition: blender.c:260
void BKE_blender_userdef_app_template_data_set_and_free(UserDef *userdef)
Definition: blender.c:375
void BKE_blender_atexit_register(void(*func)(void *user_data), void *user_data)
Definition: blender.c:396
#define DATA_SWAP(id)
void BKE_blender_atexit_unregister(void(*func)(void *user_data), const void *user_data)
Definition: blender.c:405
void BKE_blender_userdef_data_set_and_free(UserDef *userdef)
Definition: blender.c:216
#define LIST_SWAP(id)
void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
Definition: blender.c:369
#define FLAG_SWAP(id, ty, flags)
void BKE_blender_atexit(void)
Definition: blender.c:421
void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *userdef_b)
Definition: blender.c:312
void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
Definition: blender.c:278
Global G
Definition: blender.c:51
void BKE_blender_globals_init(void)
Definition: blender.c:161
static void keymap_item_free(wmKeyMapItem *kmi)
Definition: blender.c:195
void BKE_blender_free(void)
Definition: blender.c:58
const char * BKE_blender_version_string(void)
Definition: blender.c:124
static void blender_version_init(void)
Definition: blender.c:96
static void userdef_free_keyconfig_prefs(UserDef *userdef)
Definition: blender.c:249
#define U
unsigned int U
Definition: btGjkEpa3.h:78
void * user_data
SyclQueue void void size_t num_bytes void
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
struct AtExitData * next
Definition: blender.c:390
void * user_data
Definition: blender.c:393
void(* func)(void *user_data)
Definition: blender.c:392
int f
Definition: BKE_global.h:103
struct Global::@24 log
void * file
Definition: BKE_global.h:115
int level
Definition: BKE_global.h:110
char ima[1024]
Definition: BKE_global.h:33
void * first
Definition: DNA_listBase.h:31
struct ListBase addons
struct ListBase uistyles
struct ListBase user_keymaps
struct ListBase themes
struct ListBase autoexec_paths
struct ListBase uifonts
struct ListBase user_keyconfig_prefs
struct ListBase user_menus
struct ListBase asset_libraries
struct PointerRNA * ptr
void RE_texture_rng_exit(void)