Blender V4.3
blender.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include <cstdio>
12#include <cstdlib>
13#include <cstring>
14
15#include "MEM_guardedalloc.h"
16
17#include "BLI_listbase.h"
18#include "BLI_string.h"
19#include "BLI_utildefines.h"
20
21#include "IMB_imbuf.hh"
22#include "IMB_moviecache.hh"
23
24#include "BKE_addon.h"
25#include "BKE_asset.hh"
26#include "BKE_blender.hh" /* own include */
27#include "BKE_blender_user_menu.hh" /* own include */
28#include "BKE_blender_version.h" /* own include */
29#include "BKE_brush.hh"
30#include "BKE_cachefile.hh"
31#include "BKE_callbacks.hh"
32#include "BKE_global.hh"
33#include "BKE_idprop.hh"
34#include "BKE_main.hh"
35#include "BKE_node.hh"
36#include "BKE_report.hh"
37#include "BKE_screen.hh"
38#include "BKE_studiolight.h"
39#include "BKE_writeffmpeg.hh"
40
41#include "DEG_depsgraph.hh"
42
43#include "RE_texture.h"
44
45#include "BLF_api.hh"
46
49
50/* -------------------------------------------------------------------- */
55{
56 /* samples are in a global list..., also sets G_MAIN->sound->sample nullptr */
57
58 /* Needs to run before main free as window-manager is still referenced for icons preview jobs. */
60
62
63 if (G.log.file != nullptr) {
64 fclose(static_cast<FILE *>(G.log.file));
65 }
66
67 BKE_spacetypes_free(); /* after free main, it uses space callbacks */
68
69 IMB_exit();
72
75
77
79#ifdef WITH_FFMPEG
80 BKE_ffmpeg_exit();
81#endif
82
84}
85
88/* -------------------------------------------------------------------- */
92static char blender_version_string[48] = "";
93
94/* Only includes patch if non-zero. */
95static char blender_version_string_compact[48] = "";
96
98{
99 const char *version_cycle = "";
100 const char *version_cycle_compact = "";
101 if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha")) {
102 version_cycle = " Alpha";
103 version_cycle_compact = " a";
104 }
105 else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "beta")) {
106 version_cycle = " Beta";
107 version_cycle_compact = " b";
108 }
109 else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "rc")) {
110 version_cycle = " Release Candidate";
111 version_cycle_compact = " RC";
112 }
113 else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
114 version_cycle = "";
115 version_cycle_compact = "";
116 }
117 else {
118 BLI_assert_msg(0, "Invalid Blender version cycle");
119 }
120
121 const char *version_suffix = BKE_blender_version_is_lts() ? " LTS" : "";
122
124 "%d.%01d.%d%s%s",
125 BLENDER_VERSION / 100,
126 BLENDER_VERSION % 100,
128 version_suffix,
129 version_cycle);
130
132 "%d.%01d.%d%s",
133 BLENDER_VERSION / 100,
134 BLENDER_VERSION % 100,
136 version_cycle_compact);
137}
138
140{
142}
143
148
150 const size_t str_buff_maxncpy,
151 const short file_version,
152 const short file_subversion)
153{
154 const short file_version_major = file_version / 100;
155 const short file_version_minor = file_version % 100;
156 if (file_subversion >= 0) {
157 BLI_snprintf(str_buff,
158 str_buff_maxncpy,
159 "%d.%d (sub %d)",
160 file_version_major,
161 file_version_minor,
162 file_subversion);
163 }
164 else {
165 BLI_snprintf(str_buff, str_buff_maxncpy, "%d.%d", file_version_major, file_version_minor);
166 }
167}
168
170{
171 bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha");
172 return is_alpha;
173}
174
179
182/* -------------------------------------------------------------------- */
187{
189
190 memset(&G, 0, sizeof(Global));
191
192 U.savetime = 1;
193
195
197
198#ifndef WITH_PYTHON_SECURITY /* default */
200#else
201 G.f &= ~G_FLAG_SCRIPT_AUTOEXEC;
202#endif
203
204 G.log.level = 1;
205}
206
208{
209 if (G_MAIN == nullptr) {
210 return;
211 }
212 BLI_assert(G_MAIN->is_global_main);
213 BKE_main_free(G_MAIN); /* free all lib data */
214
215 G_MAIN = nullptr;
216}
217
219{
220 BLI_assert(!bmain->is_global_main);
222 bmain->is_global_main = true;
223 G_MAIN = bmain;
224}
225
227{
228 Main *old_gmain = G_MAIN;
229 BLI_assert(old_gmain->is_global_main);
230 BLI_assert(!new_gmain->is_global_main);
231 new_gmain->is_global_main = true;
232 G_MAIN = new_gmain;
233 old_gmain->is_global_main = false;
234 return old_gmain;
235}
236
239/* -------------------------------------------------------------------- */
244{
245 if (kmi->properties) {
247 }
248 if (kmi->ptr) {
249 MEM_delete(kmi->ptr);
250 }
251}
252
254{
255 blender::dna::shallow_swap(*userdef_a, *userdef_b);
256}
257
259{
261 BKE_blender_userdef_data_free(userdef, true);
262}
263
265{
267 MEM_freeN(userdef);
268}
269
270static void userdef_free_keymaps(UserDef *userdef)
271{
272 for (wmKeyMap *km = static_cast<wmKeyMap *>(userdef->user_keymaps.first), *km_next; km;
273 km = km_next)
274 {
275 km_next = km->next;
276 LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
277 if (kmdi->add_item) {
278 keymap_item_free(kmdi->add_item);
279 MEM_freeN(kmdi->add_item);
280 }
281 if (kmdi->remove_item) {
282 keymap_item_free(kmdi->remove_item);
283 MEM_freeN(kmdi->remove_item);
284 }
285 }
286
287 LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
288 keymap_item_free(kmi);
289 }
290
291 BLI_freelistN(&km->diff_items);
292 BLI_freelistN(&km->items);
293
294 MEM_freeN(km);
295 }
297}
298
300{
301 for (wmKeyConfigPref *kpt = static_cast<wmKeyConfigPref *>(userdef->user_keyconfig_prefs.first),
302 *kpt_next;
303 kpt;
304 kpt = kpt_next)
305 {
306 kpt_next = kpt->next;
307 IDP_FreeProperty(kpt->prop);
308 MEM_freeN(kpt);
309 }
311}
312
313static void userdef_free_user_menus(UserDef *userdef)
314{
315 for (bUserMenu *um = static_cast<bUserMenu *>(userdef->user_menus.first), *um_next; um;
316 um = um_next)
317 {
318 um_next = um->next;
320 MEM_freeN(um);
321 }
322}
323
324static void userdef_free_addons(UserDef *userdef)
325{
326 for (bAddon *addon = static_cast<bAddon *>(userdef->addons.first), *addon_next; addon;
327 addon = addon_next)
328 {
329 addon_next = addon->next;
330 BKE_addon_free(addon);
331 }
332 BLI_listbase_clear(&userdef->addons);
333}
334
335void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
336{
337#define U BLI_STATIC_ASSERT(false, "Global 'U' not allowed, only use arguments passed in!")
338#ifdef U
339 /* Quiet warning. */
340#endif
341
342 userdef_free_keymaps(userdef);
345 userdef_free_addons(userdef);
346
347 if (clear_fonts) {
348 LISTBASE_FOREACH (uiFont *, font, &userdef->uifonts) {
349 BLF_unload_id(font->blf_id);
350 }
351 BLF_default_set(-1);
352 }
353
354 BLI_freelistN(&userdef->autoexec_paths);
357
359 MEM_SAFE_FREE(repo_ref->access_token);
360 MEM_freeN(repo_ref);
361 }
363
365 {
366 BKE_asset_catalog_path_list_free(settings->enabled_catalog_paths);
367 MEM_freeN(settings);
368 }
370
371 BLI_freelistN(&userdef->uistyles);
372 BLI_freelistN(&userdef->uifonts);
373 BLI_freelistN(&userdef->themes);
374
375#undef U
376}
377
380/* -------------------------------------------------------------------- */
385{
386 /* TODO:
387 * - various minor settings (add as needed).
388 */
389
390#define VALUE_SWAP(id) \
391 { \
392 std::swap(userdef_a->id, userdef_b->id); \
393 }
394
395#define DATA_SWAP(id) \
396 { \
397 UserDef userdef_tmp; \
398 memcpy(&(userdef_tmp.id), &(userdef_a->id), sizeof(userdef_tmp.id)); \
399 memcpy(&(userdef_a->id), &(userdef_b->id), sizeof(userdef_tmp.id)); \
400 memcpy(&(userdef_b->id), &(userdef_tmp.id), sizeof(userdef_tmp.id)); \
401 } \
402 ((void)0)
403
404#define FLAG_SWAP(id, ty, flags) \
405 { \
406 CHECK_TYPE(&(userdef_a->id), ty *); \
407 const ty f = flags; \
408 const ty a = userdef_a->id; \
409 const ty b = userdef_b->id; \
410 userdef_a->id = (userdef_a->id & ~f) | (b & f); \
411 userdef_b->id = (userdef_b->id & ~f) | (a & f); \
412 } \
413 ((void)0)
414
415 VALUE_SWAP(uistyles);
416 VALUE_SWAP(uifonts);
417 VALUE_SWAP(themes);
418 VALUE_SWAP(addons);
419 VALUE_SWAP(user_keymaps);
420 VALUE_SWAP(user_keyconfig_prefs);
421
422 DATA_SWAP(font_path_ui);
423 DATA_SWAP(font_path_ui_mono);
424 DATA_SWAP(keyconfigstr);
425
426 DATA_SWAP(gizmo_flag);
427 DATA_SWAP(app_flag);
428
429 /* We could add others. */
431
432 DATA_SWAP(ui_scale);
433
434#undef VALUE_SWAP
435#undef DATA_SWAP
436#undef FLAG_SWAP
437}
438
444
450
453/* -------------------------------------------------------------------- */
459static struct AtExitData {
461
462 void (*func)(void *user_data);
464} *g_atexit = nullptr;
465
466void BKE_blender_atexit_register(void (*func)(void *user_data), void *user_data)
467{
468 AtExitData *ae = static_cast<AtExitData *>(malloc(sizeof(*ae)));
469 ae->next = g_atexit;
470 ae->func = func;
471 ae->user_data = user_data;
472 g_atexit = ae;
473}
474
475void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *user_data)
476{
477 AtExitData *ae = g_atexit;
478 AtExitData **ae_p = &g_atexit;
479
480 while (ae) {
481 if ((ae->func == func) && (ae->user_data == user_data)) {
482 *ae_p = ae->next;
483 free(ae);
484 return;
485 }
486 ae_p = &ae->next;
487 ae = ae->next;
488 }
489}
490
492{
493 AtExitData *ae = g_atexit, *ae_next;
494 while (ae) {
495 ae_next = ae->next;
496
497 ae->func(ae->user_data);
498
499 free(ae);
500 ae = ae_next;
501 }
502 g_atexit = nullptr;
503}
504
void BKE_addon_free(struct bAddon *addon)
Definition addon.cc:69
void BKE_asset_catalog_path_list_free(ListBase &catalog_path_list)
Blender util stuff.
void BKE_blender_user_menu_item_free_list(ListBase *lb)
#define BLENDER_VERSION_PATCH
#define BLENDER_VERSION_CYCLE
#define BLENDER_VERSION
#define BLENDER_VERSION_SUFFIX
void BKE_brush_system_exit()
Definition brush.cc:476
void BKE_cachefiles_exit()
Definition cachefile.cc:161
void BKE_callback_global_finalize()
Definition callbacks.cc:108
@ G_FLAG_SCRIPT_AUTOEXEC
#define G_MAIN
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1227
Main * BKE_main_new(void)
Definition main.cc:45
void BKE_main_free(Main *bmain)
Definition main.cc:175
void BKE_spacetypes_free()
Definition screen.cc:238
void BKE_studiolight_free(void)
void BLF_default_set(int fontid)
void BLF_unload_id(int fontid)
Definition blf.cc:284
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
void BLI_kdtree_nd_ free(KDTree *tree)
#define LISTBASE_FOREACH(type, var, list)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
#define STRNCPY(dst, src)
Definition BLI_string.h:593
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:597
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STRINGIFY(x)
#define STREQ(a, b)
void DEG_free_node_types()
@ USER_SPLASH_DISABLE
@ USER_SHOW_GIZMO_NAVIGATE
@ USER_SAVE_PROMPT
void IMB_exit()
Definition module.cc:26
void IMB_moviecache_destruct()
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static struct AtExitData * g_atexit
void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
Definition blender.cc:253
#define VALUE_SWAP(id)
static char blender_version_string[48]
Definition blender.cc:92
static void blender_version_init()
Definition blender.cc:97
static void userdef_free_keymaps(UserDef *userdef)
Definition blender.cc:270
const char * BKE_blender_version_string_compact()
Definition blender.cc:144
bool BKE_blender_version_is_alpha()
Definition blender.cc:169
Main * BKE_blender_globals_main_swap(Main *new_gmain)
Definition blender.cc:226
void BKE_blender_userdef_data_set(UserDef *userdef)
Definition blender.cc:258
const char * BKE_blender_version_string()
Definition blender.cc:139
static void userdef_free_addons(UserDef *userdef)
Definition blender.cc:324
void BKE_blender_globals_main_replace(Main *bmain)
Definition blender.cc:218
static void userdef_free_user_menus(UserDef *userdef)
Definition blender.cc:313
void BKE_blender_userdef_app_template_data_set_and_free(UserDef *userdef)
Definition blender.cc:445
void BKE_blender_atexit_register(void(*func)(void *user_data), void *user_data)
Definition blender.cc:466
#define DATA_SWAP(id)
void BKE_blender_atexit()
Definition blender.cc:491
void BKE_blender_atexit_unregister(void(*func)(void *user_data), const void *user_data)
Definition blender.cc:475
void BKE_blender_globals_init()
Definition blender.cc:186
void BKE_blender_version_blendfile_string_from_values(char *str_buff, const size_t str_buff_maxncpy, const short file_version, const short file_subversion)
Definition blender.cc:149
void BKE_blender_userdef_data_set_and_free(UserDef *userdef)
Definition blender.cc:264
void BKE_blender_globals_clear()
Definition blender.cc:207
void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
Definition blender.cc:439
#define FLAG_SWAP(id, ty, flags)
void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *userdef_b)
Definition blender.cc:384
void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
Definition blender.cc:335
Global G
Definition blender.cc:47
static void keymap_item_free(wmKeyMapItem *kmi)
Definition blender.cc:243
void BKE_blender_free()
Definition blender.cc:54
static char blender_version_string_compact[48]
Definition blender.cc:95
static void userdef_free_keyconfig_prefs(UserDef *userdef)
Definition blender.cc:299
bool BKE_blender_version_is_lts()
Definition blender.cc:175
#define U
unsigned int U
Definition btGjkEpa3.h:78
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
void node_system_exit()
Definition node.cc:4659
void * user_data
Definition blender.cc:463
void(* func)(void *user_data)
Definition blender.cc:462
AtExitData * next
Definition blender.cc:460
struct Global::@26 log
void * file
char filepath_last_image[1024]
Definition BKE_global.hh:43
int level
void * first
bool is_global_main
Definition BKE_main.hh:191
struct ListBase addons
ListBase script_directories
struct ListBase uistyles
struct ListBase asset_shelves_settings
struct ListBase user_keymaps
struct ListBase themes
struct ListBase autoexec_paths
struct ListBase uifonts
struct ListBase user_keyconfig_prefs
struct ListBase extension_repos
struct ListBase user_menus
struct ListBase asset_libraries
struct PointerRNA * ptr
void RE_texture_rng_exit()