Blender V4.5
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
10
11#include <cstdio>
12#include <cstdlib>
13#include <cstring>
14
16
17#include "MEM_guardedalloc.h"
18
20
21#include "BLI_listbase.h"
22#include "BLI_string.h"
23#include "BLI_utildefines.h"
24
25#include "IMB_imbuf.hh"
26#include "IMB_moviecache.hh"
27
28#include "MOV_util.hh"
29
30#include "BKE_addon.h"
31#include "BKE_appdir.hh"
32#include "BKE_asset.hh"
33#include "BKE_blender.hh" /* own include */
34#include "BKE_blender_user_menu.hh" /* own include */
35#include "BKE_blender_version.h" /* own include */
36#include "BKE_brush.hh"
37#include "BKE_callbacks.hh"
38#include "BKE_global.hh"
39#include "BKE_idprop.hh"
40#include "BKE_main.hh"
41#include "BKE_node.hh"
42#include "BKE_screen.hh"
43#include "BKE_studiolight.h"
44
45#include "DEG_depsgraph.hh"
46
47#include "RE_texture.h"
48
49#include "BLF_api.hh"
50
51#include "SEQ_utils.hh"
52
55
56/* -------------------------------------------------------------------- */
59
61{
62 /* samples are in a global list..., also sets G_MAIN->sound->sample nullptr */
63
64 /* Needs to run before main free as window-manager is still referenced for icons preview jobs. */
66
68
69 if (G.log.file != nullptr) {
70 fclose(static_cast<FILE *>(G.log.file));
71 }
72
73 BKE_spacetypes_free(); /* after free main, it uses space callbacks */
74
75 IMB_exit();
77
80
82
85 MOV_exit();
86
88}
89
91
92/* -------------------------------------------------------------------- */
95
96static char blender_version_string[48] = "";
97
98/* Only includes patch if non-zero. */
99static char blender_version_string_compact[48] = "";
100
102{
103 const char *version_cycle = "";
104 const char *version_cycle_compact = "";
105 if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha")) {
106 version_cycle = " Alpha";
107 version_cycle_compact = " a";
108 }
109 else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "beta")) {
110 version_cycle = " Beta";
111 version_cycle_compact = " b";
112 }
113 else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "rc")) {
114 version_cycle = " Release Candidate";
115 version_cycle_compact = " RC";
116 }
117 else if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
118 version_cycle = "";
119 version_cycle_compact = "";
120 }
121 else {
122 BLI_assert_msg(0, "Invalid Blender version cycle");
123 }
124
125 const char *version_suffix = BKE_blender_version_is_lts() ? " LTS" : "";
126
128 "%d.%01d.%d%s%s",
129 BLENDER_VERSION / 100,
130 BLENDER_VERSION % 100,
132 version_suffix,
133 version_cycle);
134
136 "%d.%01d.%d%s",
137 BLENDER_VERSION / 100,
138 BLENDER_VERSION % 100,
140 version_cycle_compact);
141}
142
144{
146}
147
152
154 const size_t str_buff_maxncpy,
155 const short file_version,
156 const short file_subversion)
157{
158 const short file_version_major = file_version / 100;
159 const short file_version_minor = file_version % 100;
160 if (file_subversion >= 0) {
161 BLI_snprintf(str_buff,
162 str_buff_maxncpy,
163 "%d.%d (sub %d)",
164 file_version_major,
165 file_version_minor,
166 file_subversion);
167 }
168 else {
169 BLI_snprintf(str_buff, str_buff_maxncpy, "%d.%d", file_version_major, file_version_minor);
170 }
171}
172
174{
175 bool is_alpha = STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "alpha");
176 return is_alpha;
177}
178
183
185
186/* -------------------------------------------------------------------- */
189
191{
193
194 memset(&G, 0, sizeof(Global));
195
196 U.savetime = 1;
197
199
200 STRNCPY(G.filepath_last_image, "//");
201 G.filepath_last_blend[0] = '\0';
202
203#ifndef WITH_PYTHON_SECURITY /* default */
205#else
207#endif
208
209 G.log.level = 1;
210
211 G.profile_gpu = false;
212}
213
215{
216 if (G_MAIN == nullptr) {
217 return;
218 }
219 BLI_assert(G_MAIN->is_global_main);
220 BKE_main_free(G_MAIN); /* free all lib data */
221
222 G_MAIN = nullptr;
223}
224
226{
227 BLI_assert(!bmain->is_global_main);
229 bmain->is_global_main = true;
230 G_MAIN = bmain;
231}
232
234{
235 Main *old_gmain = G_MAIN;
236 BLI_assert(old_gmain->is_global_main);
237 BLI_assert(!new_gmain->is_global_main);
238 new_gmain->is_global_main = true;
239 G_MAIN = new_gmain;
240 old_gmain->is_global_main = false;
241 return old_gmain;
242}
243
245{
246 /* Might be called after WM/Main exit, so needs to be careful about nullptr-checking before
247 * de-referencing. */
248
249 if (!(G_MAIN && G_MAIN->filepath[0])) {
250 BLI_path_join(filepath, FILE_MAX, BKE_tempdir_base(), "blender.crash.txt");
251 }
252 else {
254 BLI_path_extension_replace(filepath, FILE_MAX, ".crash.txt");
255 }
256}
257
259
260/* -------------------------------------------------------------------- */
263
265{
266 if (kmi->properties) {
268 }
269 if (kmi->ptr) {
270 MEM_delete(kmi->ptr);
271 }
272}
273
275{
276 blender::dna::shallow_swap(*userdef_a, *userdef_b);
277}
278
280{
282 BKE_blender_userdef_data_free(userdef, true);
283}
284
286{
288 MEM_freeN(userdef);
289}
290
291static void userdef_free_keymaps(UserDef *userdef)
292{
293 for (wmKeyMap *km = static_cast<wmKeyMap *>(userdef->user_keymaps.first), *km_next; km;
294 km = km_next)
295 {
296 km_next = km->next;
297 LISTBASE_FOREACH (wmKeyMapDiffItem *, kmdi, &km->diff_items) {
298 if (kmdi->add_item) {
299 keymap_item_free(kmdi->add_item);
300 MEM_freeN(kmdi->add_item);
301 }
302 if (kmdi->remove_item) {
303 keymap_item_free(kmdi->remove_item);
304 MEM_freeN(kmdi->remove_item);
305 }
306 }
307
308 LISTBASE_FOREACH (wmKeyMapItem *, kmi, &km->items) {
309 keymap_item_free(kmi);
310 }
311
312 BLI_freelistN(&km->diff_items);
313 BLI_freelistN(&km->items);
314
315 MEM_freeN(km);
316 }
318}
319
321{
322 for (wmKeyConfigPref *kpt = static_cast<wmKeyConfigPref *>(userdef->user_keyconfig_prefs.first),
323 *kpt_next;
324 kpt;
325 kpt = kpt_next)
326 {
327 kpt_next = kpt->next;
328 IDP_FreeProperty(kpt->prop);
329 MEM_freeN(kpt);
330 }
332}
333
334static void userdef_free_user_menus(UserDef *userdef)
335{
336 for (bUserMenu *um = static_cast<bUserMenu *>(userdef->user_menus.first), *um_next; um;
337 um = um_next)
338 {
339 um_next = um->next;
341 MEM_freeN(um);
342 }
343}
344
345static void userdef_free_addons(UserDef *userdef)
346{
347 for (bAddon *addon = static_cast<bAddon *>(userdef->addons.first), *addon_next; addon;
348 addon = addon_next)
349 {
350 addon_next = addon->next;
351 BKE_addon_free(addon);
352 }
353 BLI_listbase_clear(&userdef->addons);
354}
355
356void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
357{
358#define U BLI_STATIC_ASSERT(false, "Global 'U' not allowed, only use arguments passed in!")
359#ifdef U
360 /* Quiet warning. */
361#endif
362
363 userdef_free_keymaps(userdef);
366 userdef_free_addons(userdef);
367
368 if (clear_fonts) {
369 LISTBASE_FOREACH (uiFont *, font, &userdef->uifonts) {
370 BLF_unload_id(font->blf_id);
371 }
372 BLF_default_set(-1);
373 }
374
375 BLI_freelistN(&userdef->autoexec_paths);
378
380 MEM_SAFE_FREE(repo_ref->access_token);
381 MEM_freeN(repo_ref);
382 }
384
386 {
387 BKE_asset_catalog_path_list_free(settings->enabled_catalog_paths);
388 MEM_freeN(settings);
389 }
391
392 BLI_freelistN(&userdef->uistyles);
393 BLI_freelistN(&userdef->uifonts);
394 BLI_freelistN(&userdef->themes);
395
396#undef U
397}
398
400
401/* -------------------------------------------------------------------- */
404
406{
407 /* TODO:
408 * - various minor settings (add as needed).
409 */
410
411#define VALUE_SWAP(id) \
412 { \
413 std::swap(userdef_a->id, userdef_b->id); \
414 }
415
416#define DATA_SWAP(id) \
417 { \
418 UserDef userdef_tmp; \
419 memcpy(&(userdef_tmp.id), &(userdef_a->id), sizeof(userdef_tmp.id)); \
420 memcpy(&(userdef_a->id), &(userdef_b->id), sizeof(userdef_tmp.id)); \
421 memcpy(&(userdef_b->id), &(userdef_tmp.id), sizeof(userdef_tmp.id)); \
422 } \
423 ((void)0)
424
425#define FLAG_SWAP(id, ty, flags) \
426 { \
427 CHECK_TYPE(&(userdef_a->id), ty *); \
428 const ty f = flags; \
429 const ty a = userdef_a->id; \
430 const ty b = userdef_b->id; \
431 userdef_a->id = (userdef_a->id & ~f) | (b & f); \
432 userdef_b->id = (userdef_b->id & ~f) | (a & f); \
433 } \
434 ((void)0)
435
436 VALUE_SWAP(uistyles);
437 VALUE_SWAP(uifonts);
438 VALUE_SWAP(themes);
439 VALUE_SWAP(addons);
440 VALUE_SWAP(user_keymaps);
441 VALUE_SWAP(user_keyconfig_prefs);
442
443 DATA_SWAP(font_path_ui);
444 DATA_SWAP(font_path_ui_mono);
445 DATA_SWAP(keyconfigstr);
446
447 DATA_SWAP(gizmo_flag);
448 DATA_SWAP(app_flag);
449
450 /* We could add others. */
452
453 DATA_SWAP(ui_scale);
454
455#undef VALUE_SWAP
456#undef DATA_SWAP
457#undef FLAG_SWAP
458}
459
465
471
473
474/* -------------------------------------------------------------------- */
479
480static struct AtExitData {
482
483 void (*func)(void *user_data);
485} *g_atexit = nullptr;
486
487void BKE_blender_atexit_register(void (*func)(void *user_data), void *user_data)
488{
489 AtExitData *ae = static_cast<AtExitData *>(malloc(sizeof(*ae)));
490 ae->next = g_atexit;
491 ae->func = func;
492 ae->user_data = user_data;
493 g_atexit = ae;
494}
495
496void BKE_blender_atexit_unregister(void (*func)(void *user_data), const void *user_data)
497{
498 AtExitData *ae = g_atexit;
499 AtExitData **ae_p = &g_atexit;
500
501 while (ae) {
502 if ((ae->func == func) && (ae->user_data == user_data)) {
503 *ae_p = ae->next;
504 free(ae);
505 return;
506 }
507 ae_p = &ae->next;
508 ae = ae->next;
509 }
510}
511
513{
514 AtExitData *ae = g_atexit, *ae_next;
515 while (ae) {
516 ae_next = ae->next;
517
518 ae->func(ae->user_data);
519
520 free(ae);
521 ae = ae_next;
522 }
523 g_atexit = nullptr;
524}
525
void BKE_addon_free(struct bAddon *addon)
Definition addon.cc:68
const char * BKE_tempdir_base() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition appdir.cc:1249
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:518
void BKE_callback_global_finalize()
Definition callbacks.cc:107
@ G_FLAG_SCRIPT_AUTOEXEC
#define G_MAIN
void IDP_FreeProperty(IDProperty *prop)
Definition idprop.cc:1243
Main * BKE_main_new()
Definition main.cc:48
void BKE_main_free(Main *bmain)
Definition main.cc:175
void BKE_spacetypes_free()
Definition screen.cc:246
void BKE_studiolight_free(void)
void BLF_default_set(int fontid)
bool BLF_unload_id(int fontid)
Definition blf.cc:280
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
void BLI_kdtree_nd_ free(KDTree *tree)
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE void BLI_listbase_clear(ListBase *lb)
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void void void const char * BLI_path_basename(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define FILE_MAX
bool BLI_path_extension_replace(char *path, size_t path_maxncpy, const char *ext) ATTR_NONNULL(1
#define BLI_path_join(...)
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
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:23
void IMB_moviecache_destruct()
Read Guarded memory(de)allocation.
static struct AtExitData * g_atexit
void BKE_blender_userdef_data_swap(UserDef *userdef_a, UserDef *userdef_b)
Definition blender.cc:274
#define VALUE_SWAP(id)
static char blender_version_string[48]
Definition blender.cc:96
static void blender_version_init()
Definition blender.cc:101
static void userdef_free_keymaps(UserDef *userdef)
Definition blender.cc:291
const char * BKE_blender_version_string_compact()
Definition blender.cc:148
bool BKE_blender_version_is_alpha()
Definition blender.cc:173
Main * BKE_blender_globals_main_swap(Main *new_gmain)
Definition blender.cc:233
void BKE_blender_userdef_data_set(UserDef *userdef)
Definition blender.cc:279
const char * BKE_blender_version_string()
Definition blender.cc:143
static void userdef_free_addons(UserDef *userdef)
Definition blender.cc:345
void BKE_blender_globals_main_replace(Main *bmain)
Definition blender.cc:225
static void userdef_free_user_menus(UserDef *userdef)
Definition blender.cc:334
void BKE_blender_userdef_app_template_data_set_and_free(UserDef *userdef)
Definition blender.cc:466
void BKE_blender_atexit_register(void(*func)(void *user_data), void *user_data)
Definition blender.cc:487
void BKE_blender_globals_crash_path_get(char filepath[FILE_MAX])
Definition blender.cc:244
#define DATA_SWAP(id)
void BKE_blender_atexit()
Definition blender.cc:512
void BKE_blender_atexit_unregister(void(*func)(void *user_data), const void *user_data)
Definition blender.cc:496
void BKE_blender_globals_init()
Definition blender.cc:190
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:153
void BKE_blender_userdef_data_set_and_free(UserDef *userdef)
Definition blender.cc:285
void BKE_blender_globals_clear()
Definition blender.cc:214
void BKE_blender_userdef_app_template_data_set(UserDef *userdef)
Definition blender.cc:460
#define FLAG_SWAP(id, ty, flags)
void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *userdef_b)
Definition blender.cc:405
void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
Definition blender.cc:356
static void keymap_item_free(wmKeyMapItem *kmi)
Definition blender.cc:264
void BKE_blender_free()
Definition blender.cc:60
static char blender_version_string_compact[48]
Definition blender.cc:99
static void userdef_free_keyconfig_prefs(UserDef *userdef)
Definition blender.cc:320
bool BKE_blender_version_is_lts()
Definition blender.cc:179
#define U
#define MEM_SAFE_FREE(v)
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
void MOV_exit()
void node_system_exit()
Definition node.cc:5620
void * user_data
Definition blender.cc:484
void(* func)(void *user_data)
Definition blender.cc:483
AtExitData * next
Definition blender.cc:481
void * first
bool is_global_main
Definition BKE_main.hh:211
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()