Blender V5.0
creator_args.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#ifndef WITH_PYTHON_MODULE
10
11# include <cerrno>
12# include <cstdlib>
13# include <cstring>
14
15# include "MEM_guardedalloc.h"
16
17# include "CLG_log.h"
18
19# ifdef WIN32
20# include "BLI_winstuff.h"
21# endif
22
23# include "BLI_args.h"
24# include "BLI_dynstr.h"
25# include "BLI_fileops.h"
26# include "BLI_listbase.h"
27# include "BLI_path_utils.hh"
28# include "BLI_string.h"
29# include "BLI_string_utf8.h"
30# include "BLI_system.h"
31# include "BLI_threads.h"
32# include "BLI_utildefines.h"
33# ifndef NDEBUG
34# include "BLI_mempool.h"
35# endif
36
37# include "BKE_appdir.hh"
38# include "BKE_blender.hh"
40# include "BKE_blender_version.h"
41# include "BKE_blendfile.hh"
42# include "BKE_context.hh"
43
44# include "BKE_global.hh"
45# include "BKE_image_format.hh"
46# include "BKE_lib_id.hh"
47# include "BKE_main.hh"
48# include "BKE_report.hh"
49# include "BKE_scene.hh"
50# include "BKE_sound.h"
51
52# include "GPU_context.hh"
53# ifdef WITH_OPENGL_BACKEND
54# include "GPU_capabilities.hh"
56# endif
57
58# ifdef WITH_PYTHON
59# include "BPY_extern_python.hh"
60# include "BPY_extern_run.hh"
61# endif
62
63# include "RE_engine.h"
64# include "RE_pipeline.h"
65
66# include "WM_api.hh"
67
68# ifdef WITH_LIBMV
69# include "libmv-capi.h"
70# endif
71
72# include "DEG_depsgraph.hh"
73
74# include "WM_types.hh"
75
76# include "creator_intern.h" /* Own include. */
77
78/* -------------------------------------------------------------------- */
81
104
105static void build_defs_init(BuildDefs *build_defs, bool force_all)
106{
107 if (force_all) {
108 bool *var_end = (bool *)(build_defs + 1);
109 for (bool *var = (bool *)build_defs; var < var_end; var++) {
110 *var = true;
111 }
112 return;
113 }
114
115 memset(build_defs, 0x0, sizeof(*build_defs));
116
117# ifdef WIN32
118 build_defs->win32 = true;
119# endif
120# ifdef WITH_CYCLES
121 build_defs->with_cycles = true;
122# endif
123# ifdef WITH_FFMPEG
124 build_defs->with_ffmpeg = true;
125# endif
126# ifdef WITH_FREESTYLE
127 build_defs->with_freestyle = true;
128# endif
129# ifdef WITH_LIBMV
130 build_defs->with_libmv = true;
131# endif
132# ifdef WITH_OPENGL_BACKEND
133 build_defs->with_opengl_backend = true;
134# endif
135# ifdef WITH_OPENCOLORIO
136 build_defs->with_opencolorio = true;
137# endif
138# ifdef WITH_RENDERDOC
139 build_defs->with_renderdoc = true;
140# endif
141# ifdef WITH_VULKAN_BACKEND
142 build_defs->with_vulkan_backend = true;
143# endif
144# ifdef WITH_XR_OPENXR
145 build_defs->with_xr_openxr = true;
146# endif
147}
148
150
151/* -------------------------------------------------------------------- */
154
155static bool parse_int_relative(const char *str,
156 const char *str_end_test,
157 int pos,
158 int neg,
159 int *r_value,
160 const char **r_err_msg)
161{
162 char *str_end = nullptr;
163 long value;
164
165 errno = 0;
166
167 switch (*str) {
168 case '+':
169 value = pos + strtol(str + 1, &str_end, 10);
170 break;
171 case '-':
172 value = (neg - strtol(str + 1, &str_end, 10)) + 1;
173 break;
174 default:
175 value = strtol(str, &str_end, 10);
176 break;
177 }
178
179 if (*str_end != '\0' && (str_end != str_end_test)) {
180 static const char *msg = "not a number";
181 *r_err_msg = msg;
182 return false;
183 }
184 if ((errno == ERANGE) || ((value < INT_MIN) || (value > INT_MAX))) {
185 static const char *msg = "exceeds range";
186 *r_err_msg = msg;
187 return false;
188 }
189 *r_value = int(value);
190 return true;
191}
192
193static const char *parse_int_range_sep_search(const char *str, const char *str_end_test)
194{
195 const char *str_end_range = nullptr;
196 if (str_end_test) {
197 str_end_range = static_cast<const char *>(memchr(str, '.', (str_end_test - str) - 1));
198 if (str_end_range && (str_end_range[1] != '.')) {
199 str_end_range = nullptr;
200 }
201 }
202 else {
203 str_end_range = strstr(str, "..");
204 if (str_end_range && (str_end_range[2] == '\0')) {
205 str_end_range = nullptr;
206 }
207 }
208 return str_end_range;
209}
210
216static bool parse_int_range_relative(const char *str,
217 const char *str_end_range,
218 const char *str_end_test,
219 int pos,
220 int neg,
221 int r_value_range[2],
222 const char **r_err_msg)
223{
224 if (parse_int_relative(str, str_end_range, pos, neg, &r_value_range[0], r_err_msg) &&
225 parse_int_relative(str_end_range + 2, str_end_test, pos, neg, &r_value_range[1], r_err_msg))
226 {
227 return true;
228 }
229 return false;
230}
231
232static bool parse_int_relative_clamp(const char *str,
233 const char *str_end_test,
234 int pos,
235 int neg,
236 int min,
237 int max,
238 int *r_value,
239 const char **r_err_msg)
240{
241 if (parse_int_relative(str, str_end_test, pos, neg, r_value, r_err_msg)) {
242 CLAMP(*r_value, min, max);
243 return true;
244 }
245 return false;
246}
247
248static bool parse_int_range_relative_clamp(const char *str,
249 const char *str_end_range,
250 const char *str_end_test,
251 int pos,
252 int neg,
253 int min,
254 int max,
255 int r_value_range[2],
256 const char **r_err_msg)
257{
259 str, str_end_range, str_end_test, pos, neg, r_value_range, r_err_msg))
260 {
261 CLAMP(r_value_range[0], min, max);
262 CLAMP(r_value_range[1], min, max);
263 return true;
264 }
265 return false;
266}
267
271static bool parse_int_strict_range(const char *str,
272 const char *str_end_test,
273 const int min,
274 const int max,
275 int *r_value,
276 const char **r_err_msg)
277{
278 char *str_end = nullptr;
279 long value;
280
281 errno = 0;
282 value = strtol(str, &str_end, 10);
283
284 if (*str_end != '\0' && (str_end != str_end_test)) {
285 static const char *msg = "not a number";
286 *r_err_msg = msg;
287 return false;
288 }
289 if ((errno == ERANGE) || ((value < min) || (value > max))) {
290 static const char *msg = "exceeds range";
291 *r_err_msg = msg;
292 return false;
293 }
294 *r_value = int(value);
295 return true;
296}
297
298static bool parse_int(const char *str,
299 const char *str_end_test,
300 int *r_value,
301 const char **r_err_msg)
302{
303 return parse_int_strict_range(str, str_end_test, INT_MIN, INT_MAX, r_value, r_err_msg);
304}
305
306static bool parse_int_clamp(const char *str,
307 const char *str_end_test,
308 int min,
309 int max,
310 int *r_value,
311 const char **r_err_msg)
312{
313 if (parse_int(str, str_end_test, r_value, r_err_msg)) {
314 CLAMP(*r_value, min, max);
315 return true;
316 }
317 return false;
318}
319
320# if 0
325static int *parse_int_relative_clamp_n(
326 const char *str, int pos, int neg, int min, int max, int *r_value_len, const char **r_err_msg)
327{
328 const char sep = ',';
329 int len = 1;
330 for (int i = 0; str[i]; i++) {
331 if (str[i] == sep) {
332 len++;
333 }
334 }
335
336 int *values = MEM_malloc_arrayN<int>(size_t(len), __func__);
337 int i = 0;
338 while (true) {
339 const char *str_end = strchr(str, sep);
340 if (ELEM(*str, sep, '\0')) {
341 static const char *msg = "incorrect comma use";
342 *r_err_msg = msg;
343 goto fail;
344 }
345 else if (parse_int_relative_clamp(str, str_end, pos, neg, min, max, &values[i], r_err_msg)) {
346 i++;
347 }
348 else {
349 goto fail; /* Error message already set. */
350 }
351
352 if (str_end) { /* Next. */
353 str = str_end + 1;
354 }
355 else { /* Finished. */
356 break;
357 }
358 }
359
360 *r_value_len = i;
361 return values;
362
363fail:
364 MEM_freeN(values);
365 return nullptr;
366}
367
368# endif
369
376static int (*parse_int_range_relative_clamp_n(const char *str,
377 int pos,
378 int neg,
379 int min,
380 int max,
381 int *r_value_len,
382 const char **r_err_msg))[2]
383{
384 const char sep = ',';
385 int len = 1;
386 for (int i = 0; str[i]; i++) {
387 if (str[i] == sep) {
388 len++;
389 }
390 }
391
392 int (*values)[2] = MEM_malloc_arrayN<int[2]>(size_t(len), __func__);
393 int i = 0;
394 while (true) {
395 const char *str_end_range;
396 const char *str_end = strchr(str, sep);
397 if (ELEM(*str, sep, '\0')) {
398 static const char *msg = "incorrect comma use";
399 *r_err_msg = msg;
400 goto fail;
401 }
402 else if ((str_end_range = parse_int_range_sep_search(str, str_end)) ?
404 str, str_end_range, str_end, pos, neg, min, max, values[i], r_err_msg) :
406 str, str_end, pos, neg, min, max, &values[i][0], r_err_msg))
407 {
408 if (str_end_range == nullptr) {
409 values[i][1] = values[i][0];
410 }
411 i++;
412 }
413 else {
414 goto fail; /* Error message already set. */
415 }
416
417 if (str_end) { /* Next. */
418 str = str_end + 1;
419 }
420 else { /* Finished. */
421 break;
422 }
423 }
424
425 *r_value_len = i;
426 return values;
427
428fail:
429 MEM_freeN(values);
430 return nullptr;
431}
432
434
435/* -------------------------------------------------------------------- */
442
443/* When the deferred argument is handled on Windows the `argv` will have been freed,
444 * see `USE_WIN32_UNICODE_ARGS` in `creator.cc`. */
445
446# ifdef WIN32
447static char **argv_duplicate(const char **argv, int argc)
448{
449 char **argv_copy = MEM_malloc_arrayN<char *>(size_t(argc), __func__);
450 for (int i = 0; i < argc; i++) {
451 argv_copy[i] = BLI_strdup(argv[i]);
452 }
453 return argv_copy;
454}
455
456static void argv_free(char **argv, int argc)
457{
458 for (int i = 0; i < argc; i++) {
459 MEM_freeN(argv[i]);
460 }
461 MEM_freeN(argv);
462}
463# endif /* !WIN32 */
464
473
475{
476 return app_state.main_arg_deferred != nullptr;
477}
478
479static void main_arg_deferred_setup(BA_ArgCallback func, int argc, const char **argv, void *data)
480{
481 BLI_assert(app_state.main_arg_deferred == nullptr);
483 d->func = func;
484 d->argc = argc;
485 d->argv = argv;
486 d->data = data;
487 d->exit_code = 0;
488# ifdef WIN32
489 d->argv = const_cast<const char **>(argv_duplicate(d->argv, d->argc));
490# endif
491 app_state.main_arg_deferred = d;
492}
493
495{
496 BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
497 app_state.main_arg_deferred = nullptr;
498# ifdef WIN32
499 argv_free(const_cast<char **>(d->argv), d->argc);
500# endif
501 MEM_freeN(d);
502}
503
504static void main_arg_deferred_exit_code_set(int exit_code)
505{
506 BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
507 BLI_assert(d != nullptr);
508 d->exit_code = exit_code;
509}
510
512{
513 BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
514 d->func(d->argc, d->argv, d->data);
515 return d->exit_code;
516}
517
519
520/* -------------------------------------------------------------------- */
523
524# ifdef WITH_PYTHON
525
526struct BlendePyContextStore {
527 wmWindowManager *wm;
528 Scene *scene;
529 wmWindow *win;
530 bool has_win;
531};
532
533static void arg_py_context_backup(bContext *C, BlendePyContextStore *c_py)
534{
535 c_py->wm = CTX_wm_manager(C);
536 c_py->scene = CTX_data_scene(C);
537 c_py->has_win = c_py->wm && !BLI_listbase_is_empty(&c_py->wm->windows);
538 if (c_py->has_win) {
539 c_py->win = CTX_wm_window(C);
540 CTX_wm_window_set(C, static_cast<wmWindow *>(c_py->wm->windows.first));
541 }
542 else {
543 /* NOTE: this should never happen, although it may be possible when loading
544 * `.blend` files without windowing data. Whatever the case, it shouldn't crash,
545 * although typical scripts that accesses the context is not expected to work usefully. */
546 c_py->win = nullptr;
547 fprintf(stderr, "Python script running with missing context data.\n");
548 }
549}
550
551static void arg_py_context_restore(bContext *C, BlendePyContextStore *c_py)
552{
553 /* Script may load a file, check old data is valid before using. */
554 if (c_py->has_win) {
555 if ((c_py->win == nullptr) || ((BLI_findindex(&G_MAIN->wm, c_py->wm) != -1) &&
556 (BLI_findindex(&c_py->wm->windows, c_py->win) != -1)))
557 {
558 CTX_wm_window_set(C, c_py->win);
559 }
560 }
561
562 if ((c_py->scene == nullptr) || BLI_findindex(&G_MAIN->scenes, c_py->scene) != -1) {
563 CTX_data_scene_set(C, c_py->scene);
564 }
565}
566
567/* Macro for context setup/reset. */
568# define BPY_CTX_SETUP(_cmd) \
569 { \
570 BlendePyContextStore py_c; \
571 arg_py_context_backup(C, &py_c); \
572 { \
573 _cmd; \
574 } \
575 arg_py_context_restore(C, &py_c); \
576 } \
577 ((void)0)
578
579# endif /* WITH_PYTHON */
580
582
583/* -------------------------------------------------------------------- */
596
598{
599 printf("Blender %s\n", BKE_blender_version_string());
600# ifdef BUILD_DATE
601 printf("\tbuild date: %s\n", build_date);
602 printf("\tbuild time: %s\n", build_time);
603 printf("\tbuild commit date: %s\n", build_commit_date);
604 printf("\tbuild commit time: %s\n", build_commit_time);
605 printf("\tbuild hash: %s\n", build_hash);
606 printf("\tbuild branch: %s\n", build_branch);
607 printf("\tbuild platform: %s\n", build_platform);
608 printf("\tbuild type: %s\n", build_type);
609 printf("\tbuild c flags: %s\n", build_cflags);
610 printf("\tbuild c++ flags: %s\n", build_cxxflags);
611 printf("\tbuild link flags: %s\n", build_linkflags);
612 printf("\tbuild system: %s\n", build_system);
613# endif
614}
615
617{
618# ifdef BUILD_DATE
619 /* NOTE: We include built time since sometimes we need to tell broken from
620 * working built of the same hash. */
621 printf("Blender %s (hash %s built %s %s)\n",
625 build_time);
626# else
627 printf("Blender %s\n", BKE_blender_version_string());
628# endif
629}
630
631static const char arg_handle_print_version_doc[] =
632 "\n\t"
633 "Print Blender version and exit.";
634static int arg_handle_print_version(int /*argc*/, const char ** /*argv*/, void * /*data*/)
635{
637
638 /* Handles cleanup before exit. */
640
641 exit(EXIT_SUCCESS);
643 return 0;
644}
645
646static void print_help(bArgs *ba, bool all)
647{
648 BuildDefs defs;
649 build_defs_init(&defs, all);
650
651/* All printing must go via `PRINT` macro. */
652# define printf __ERROR__
653
654# define PRINT(...) BLI_args_printf(ba, __VA_ARGS__)
655
656 PRINT("Blender %s\n", BKE_blender_version_string());
657 PRINT("Usage: blender [args ...] [file] [args ...]\n");
658 PRINT("\n");
659
660 PRINT("Render Options:\n");
661 BLI_args_print_arg_doc(ba, "--background");
662 BLI_args_print_arg_doc(ba, "--render-anim");
663 BLI_args_print_arg_doc(ba, "--scene");
664 BLI_args_print_arg_doc(ba, "--render-frame");
665 BLI_args_print_arg_doc(ba, "--frame-start");
666 BLI_args_print_arg_doc(ba, "--frame-end");
667 BLI_args_print_arg_doc(ba, "--frame-jump");
668 BLI_args_print_arg_doc(ba, "--render-output");
669 BLI_args_print_arg_doc(ba, "--engine");
670 BLI_args_print_arg_doc(ba, "--threads");
671
672 if (defs.with_cycles) {
673 PRINT("Cycles Render Options:\n");
674 PRINT("\tCycles add-on options must be specified following a double dash.\n");
675 PRINT("\n");
676 PRINT("--cycles-device <device>\n");
677 PRINT("\tSet the device used for rendering.\n");
678 PRINT("\tValid options are: 'CPU' 'CUDA' 'OPTIX' 'HIP' 'ONEAPI' 'METAL'.\n");
679 PRINT("\n");
680 PRINT("\tAppend +CPU to a GPU device to render on both CPU and GPU.\n");
681 PRINT("\n");
682 PRINT("\tExample:\n");
683 PRINT("\t# blender -b file.blend -f 20 -- --cycles-device OPTIX\n");
684 PRINT("--cycles-print-stats\n");
685 PRINT("\tLog statistics about render memory and time usage.\n");
686 }
687
688 PRINT("\n");
689 PRINT("Format Options:\n");
690 BLI_args_print_arg_doc(ba, "--render-format");
691 BLI_args_print_arg_doc(ba, "--use-extension");
692
693 PRINT("\n");
694 PRINT("Animation Playback Options:\n");
695 BLI_args_print_arg_doc(ba, "-a");
696
697 PRINT("\n");
698 PRINT("Window Options:\n");
699 BLI_args_print_arg_doc(ba, "--window-border");
700 BLI_args_print_arg_doc(ba, "--window-maximized");
701 BLI_args_print_arg_doc(ba, "--window-fullscreen");
702 BLI_args_print_arg_doc(ba, "--window-geometry");
703 BLI_args_print_arg_doc(ba, "--start-console");
704 BLI_args_print_arg_doc(ba, "--no-native-pixels");
705 BLI_args_print_arg_doc(ba, "--no-window-frame");
706 BLI_args_print_arg_doc(ba, "--no-window-focus");
707
708 PRINT("\n");
709 PRINT("Python Options:\n");
710 BLI_args_print_arg_doc(ba, "--enable-autoexec");
711 BLI_args_print_arg_doc(ba, "--disable-autoexec");
712
713 PRINT("\n");
714
715 BLI_args_print_arg_doc(ba, "--python");
716 BLI_args_print_arg_doc(ba, "--python-text");
717 BLI_args_print_arg_doc(ba, "--python-expr");
718 BLI_args_print_arg_doc(ba, "--python-console");
719 BLI_args_print_arg_doc(ba, "--python-exit-code");
720 BLI_args_print_arg_doc(ba, "--python-use-system-env");
721 BLI_args_print_arg_doc(ba, "--addons");
722
723 PRINT("\n");
724 PRINT("Network Options:\n");
725 BLI_args_print_arg_doc(ba, "--online-mode");
726 BLI_args_print_arg_doc(ba, "--offline-mode");
727
728 PRINT("\n");
729 PRINT("Logging Options:\n");
730 BLI_args_print_arg_doc(ba, "--log");
731 BLI_args_print_arg_doc(ba, "--log-level");
732 BLI_args_print_arg_doc(ba, "--log-show-memory");
733 BLI_args_print_arg_doc(ba, "--log-show-source");
734 BLI_args_print_arg_doc(ba, "--log-show-backtrace");
735 BLI_args_print_arg_doc(ba, "--log-file");
736 BLI_args_print_arg_doc(ba, "--log-list-categories");
737
738 PRINT("\n");
739 PRINT("Debug Options:\n");
740 BLI_args_print_arg_doc(ba, "--debug");
741 BLI_args_print_arg_doc(ba, "--debug-value");
742
743 PRINT("\n");
744 BLI_args_print_arg_doc(ba, "--debug-events");
745 BLI_args_print_arg_doc(ba, "--debug-handlers");
746 if (defs.with_libmv) {
747 BLI_args_print_arg_doc(ba, "--debug-libmv");
748 }
749 BLI_args_print_arg_doc(ba, "--debug-memory");
750 BLI_args_print_arg_doc(ba, "--debug-jobs");
751 BLI_args_print_arg_doc(ba, "--debug-python");
752 BLI_args_print_arg_doc(ba, "--debug-depsgraph");
753 BLI_args_print_arg_doc(ba, "--debug-depsgraph-eval");
754 BLI_args_print_arg_doc(ba, "--debug-depsgraph-build");
755 BLI_args_print_arg_doc(ba, "--debug-depsgraph-tag");
756 BLI_args_print_arg_doc(ba, "--debug-depsgraph-no-threads");
757 BLI_args_print_arg_doc(ba, "--debug-depsgraph-time");
758 BLI_args_print_arg_doc(ba, "--debug-depsgraph-pretty");
759 BLI_args_print_arg_doc(ba, "--debug-depsgraph-uid");
760 BLI_args_print_arg_doc(ba, "--debug-ghost");
761 BLI_args_print_arg_doc(ba, "--debug-wintab");
762 BLI_args_print_arg_doc(ba, "--debug-gpu");
763 BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds");
764 BLI_args_print_arg_doc(ba, "--debug-gpu-compile-shaders");
765 BLI_args_print_arg_doc(ba, "--debug-gpu-shader-debug-info");
766 if (defs.with_renderdoc) {
767 BLI_args_print_arg_doc(ba, "--debug-gpu-scope-capture");
768 BLI_args_print_arg_doc(ba, "--debug-gpu-renderdoc");
769 }
770 if (defs.with_vulkan_backend) {
771 BLI_args_print_arg_doc(ba, "--debug-gpu-vulkan-local-read");
772 }
773 BLI_args_print_arg_doc(ba, "--debug-wm");
774 if (defs.with_xr_openxr) {
775 BLI_args_print_arg_doc(ba, "--debug-xr");
776 BLI_args_print_arg_doc(ba, "--debug-xr-time");
777 }
778 BLI_args_print_arg_doc(ba, "--debug-all");
779 BLI_args_print_arg_doc(ba, "--debug-io");
780
781 PRINT("\n");
782 BLI_args_print_arg_doc(ba, "--debug-fpe");
783 BLI_args_print_arg_doc(ba, "--debug-exit-on-error");
784 if (defs.with_freestyle) {
785 BLI_args_print_arg_doc(ba, "--debug-freestyle");
786 }
787 BLI_args_print_arg_doc(ba, "--disable-crash-handler");
788 BLI_args_print_arg_doc(ba, "--disable-abort-handler");
789
790 BLI_args_print_arg_doc(ba, "--verbose");
791 BLI_args_print_arg_doc(ba, "--quiet");
792
793 PRINT("\n");
794 PRINT("GPU Options:\n");
795 BLI_args_print_arg_doc(ba, "--gpu-backend");
796 BLI_args_print_arg_doc(ba, "--gpu-vsync");
797 if (defs.with_opengl_backend) {
798 BLI_args_print_arg_doc(ba, "--gpu-compilation-subprocesses");
799 }
800 BLI_args_print_arg_doc(ba, "--profile-gpu");
801
802 PRINT("\n");
803 PRINT("Misc Options:\n");
804 BLI_args_print_arg_doc(ba, "--open-last");
805 BLI_args_print_arg_doc(ba, "--app-template");
806 BLI_args_print_arg_doc(ba, "--factory-startup");
807 BLI_args_print_arg_doc(ba, "--enable-event-simulate");
808 PRINT("\n");
809 BLI_args_print_arg_doc(ba, "--env-system-datafiles");
810 BLI_args_print_arg_doc(ba, "--env-system-scripts");
811 BLI_args_print_arg_doc(ba, "--env-system-extensions");
812 BLI_args_print_arg_doc(ba, "--env-system-python");
813 PRINT("\n");
814 BLI_args_print_arg_doc(ba, "-noaudio");
815 BLI_args_print_arg_doc(ba, "-setaudio");
816 PRINT("\n");
817 BLI_args_print_arg_doc(ba, "--command");
818
819 PRINT("\n");
820
821 BLI_args_print_arg_doc(ba, "--help");
822 BLI_args_print_arg_doc(ba, "/?");
823
824 /* File type registration (Windows & Linux only). */
825 BLI_args_print_arg_doc(ba, "--register");
826 BLI_args_print_arg_doc(ba, "--register-allusers");
827 BLI_args_print_arg_doc(ba, "--unregister");
828 BLI_args_print_arg_doc(ba, "--unregister-allusers");
829 /* Windows only. */
830 BLI_args_print_arg_doc(ba, "--qos");
831
832 BLI_args_print_arg_doc(ba, "--version");
833
834 BLI_args_print_arg_doc(ba, "--");
835
836 // PRINT("\n");
837 // PRINT("Experimental Features:\n");
838
839 /* Other options _must_ be last (anything not handled will show here).
840 *
841 * Note that it's good practice for this to remain empty,
842 * nevertheless print if any exist. */
843 if (BLI_args_has_other_doc(ba)) {
844 PRINT("\n");
845 PRINT("Other Options:\n");
847 }
848
849 PRINT("\n");
850 PRINT("Argument Parsing:\n");
851 PRINT("\tArguments must be separated by white space, eg:\n");
852 PRINT("\t# blender -ba test.blend\n");
853 PRINT("\t...will exit since '-ba' is an unknown argument.\n");
854 PRINT("\n");
855
856 PRINT("Argument Order:\n");
857 PRINT("\tArguments are executed in the order they are given. eg:\n");
858 PRINT("\t# blender --background test.blend --render-frame 1 --render-output \"/tmp\"\n");
859 PRINT(
860 "\t...will not render to '/tmp' because '--render-frame 1' renders before the output path "
861 "is set.\n");
862 PRINT("\t# blender --background --render-output /tmp test.blend --render-frame 1\n");
863 PRINT(
864 "\t...will not render to '/tmp' because loading the blend-file overwrites the render output "
865 "that was set.\n");
866 PRINT("\t# blender --background test.blend --render-output /tmp --render-frame 1\n");
867 PRINT("\t...works as expected.\n");
868 PRINT("\n");
869
870 PRINT("Environment Variables:\n");
871 PRINT(" $BLENDER_USER_RESOURCES Replace default directory of all user files.\n");
872 PRINT(" Other 'BLENDER_USER_*' variables override when set.\n");
873 PRINT(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
874 PRINT(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
875 PRINT(" $BLENDER_USER_EXTENSIONS Directory for user extensions.\n");
876 PRINT(" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
877 PRINT("\n");
878 PRINT(" $BLENDER_SYSTEM_RESOURCES Replace default directory of all bundled resource files.\n");
879 PRINT(" $BLENDER_SYSTEM_SCRIPTS Directories to add extra scripts.\n");
880 PRINT(" $BLENDER_SYSTEM_EXTENSIONS Directory for system extensions repository.\n");
881 PRINT(" $BLENDER_SYSTEM_DATAFILES Directory to replace bundled datafiles.\n");
882 PRINT(" $BLENDER_SYSTEM_PYTHON Directory to replace bundled Python libraries.\n");
883 PRINT(" $BLENDER_CUSTOM_SPLASH Full path to an image that replaces the splash screen.\n");
884 PRINT(
885 " $BLENDER_CUSTOM_SPLASH_BANNER Full path to an image to overlay on the splash screen.\n");
886
887 if (defs.with_opencolorio) {
888 PRINT(
889 " $BLENDER_OCIO Path to override the OpenColorIO configuration file.\n"
890 " If not set, the 'OCIO' environment variable is used.\n");
891 }
892 if (defs.win32 || all) {
893 PRINT(" $TEMP Store temporary files here (MS-Windows).\n");
894 }
895 if (!defs.win32 || all) {
896 PRINT(" $TMPDIR Store temporary files here (UNIX Systems).\n");
897 }
898 PRINT(
899 " The path must reference an existing directory "
900 "or it will be ignored.\n");
901
902# undef printf
903# undef PRINT
904}
905
907static void help_print_ds_fn(void *ds_v, const char *format, va_list args)
908{
909 DynStr *ds = static_cast<DynStr *>(ds_v);
910 BLI_dynstr_vappendf(ds, format, args);
911}
912
914{
915 DynStr *ds = BLI_dynstr_new();
916 {
917 bArgs *ba = BLI_args_create(0, nullptr);
918 main_args_setup(nullptr, ba, all);
920 print_help(ba, all);
922 }
923 char *buf = BLI_dynstr_get_cstring(ds);
924 BLI_dynstr_free(ds);
925 return buf;
926}
927
928static const char arg_handle_print_help_doc[] =
929 "\n\t"
930 "Print this help text and exit.";
932 "\n\t"
933 "Print this help text and exit (Windows only).";
934static int arg_handle_print_help(int /*argc*/, const char ** /*argv*/, void *data)
935{
936 bArgs *ba = (bArgs *)data;
937
938 print_help(ba, false);
939
940 /* Handles cleanup before exit. */
942
943 exit(EXIT_SUCCESS);
945
946 return 0;
947}
948
949static const char arg_handle_arguments_end_doc[] =
950 "\n\t"
951 "End option processing, following arguments passed unchanged. Access via Python's "
952 "'sys.argv'.";
953static int arg_handle_arguments_end(int /*argc*/, const char ** /*argv*/, void * /*data*/)
954{
955 return -1;
956}
957
958/* Only to give help message. */
959# ifdef WITH_PYTHON_SECURITY /* Default. */
960# define PY_ENABLE_AUTO ""
961# define PY_DISABLE_AUTO ", (default)"
962# else
963# define PY_ENABLE_AUTO ", (default, non-standard compilation option)"
964# define PY_DISABLE_AUTO ""
965# endif
966
968 "\n\t"
969 "Enable automatic Python script execution" PY_ENABLE_AUTO ".";
971 "\n\t"
972 "Disable automatic Python script execution "
973 "(Python-drivers & startup scripts)" PY_DISABLE_AUTO ".";
974# undef PY_ENABLE_AUTO
975# undef PY_DISABLE_AUTO
976
977static int arg_handle_python_set(int /*argc*/, const char ** /*argv*/, void *data)
978{
979 if (bool(data)) {
981 }
982 else {
984 }
986 return 0;
987}
988
990 "\n\t"
991 "Allow internet access, overriding the preference.";
993 "\n\t"
994 "Disallow internet access, overriding the preference.";
995
996static int arg_handle_internet_allow_set(int /*argc*/, const char ** /*argv*/, void *data)
997{
999 if (bool(data)) {
1002 }
1003 else {
1006 }
1007 return 0;
1008}
1009
1011 "\n\t"
1012 "Disable the crash handler.";
1013static int arg_handle_crash_handler_disable(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1014{
1015 app_state.signal.use_crash_handler = false;
1016 return 0;
1017}
1018
1020 "\n\t"
1021 "Disable the abort handler.";
1022static int arg_handle_abort_handler_disable(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1023{
1024 app_state.signal.use_abort_handler = false;
1025 return 0;
1026}
1027
1028static void clog_abort_on_error_callback(void *fp)
1029{
1030 BLI_system_backtrace(static_cast<FILE *>(fp));
1031 fflush(static_cast<FILE *>(fp));
1032 abort();
1033}
1034
1036 "\n\t"
1037 "Immediately exit when internal errors are detected.";
1038static int arg_handle_debug_exit_on_error(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1039{
1042 return 0;
1043}
1044
1045static const char arg_handle_quiet_set_doc[] =
1046 "\n\t"
1047 "Suppress status printing (warnings & errors are still printed).";
1048static int arg_handle_quiet_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1049{
1050 CLG_quiet_set(true);
1051 return 0;
1052}
1053
1056{
1057 G.background = true;
1058
1059 /* Background Mode Defaults:
1060 *
1061 * In general background mode should strive to match the behavior of running
1062 * Blender inside a graphical session, any exception to this should have a well
1063 * justified reason and be noted in the doc-string. */
1064
1065 /* NOTE(@ideasman42): While there is no requirement for sound to be disabled in background-mode,
1066 * the use case for playing audio in background mode is enough of a special-case
1067 * that users who wish to do this can explicitly enable audio in background mode.
1068 * While the down sides for connecting to an audio device aren't terrible they include:
1069 * - Listing Blender as an active application which may output audio.
1070 * - Unnecessary overhead running an operation in background mode or ...
1071 * - Having to remember to include `-noaudio` with batch operations.
1072 * - A quiet but audible click when Blender starts & configures its audio device.
1073 */
1074 BKE_sound_force_device("None");
1075}
1076
1078 "\n"
1079 "\tRun in background (often used for UI-less rendering).\n"
1080 "\n"
1081 "\tThe audio device is disabled in background-mode by default\n"
1082 "\tand can be re-enabled by passing in '-setaudio Default' afterwards.";
1083static int arg_handle_background_mode_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1084{
1085 if (!CLG_quiet_get()) {
1087 }
1089 return 0;
1090}
1091
1092static const char arg_handle_command_set_doc[] =
1093 "<command>\n"
1094 "\tRun a command which consumes all remaining arguments.\n"
1095 "\tUse '-c help' to list all other commands.\n"
1096 "\tPass '--help' after the command to see its help text.\n"
1097 "\n"
1098 "\tThis implies '--background' mode.";
1099static int arg_handle_command_set(int argc, const char **argv, void *data)
1100{
1101 if (!main_arg_deferred_is_set()) {
1102 if (argc < 2) {
1103 fprintf(stderr, "%s requires at least one argument\n", argv[0]);
1104 exit(EXIT_FAILURE);
1106 }
1107 /* Application "info" messages get in the way of command line output, suppress them. */
1108 CLG_quiet_set(true);
1109
1111
1113 }
1114 else {
1115 bContext *C = static_cast<bContext *>(data);
1116 const char *id = argv[1];
1117 int exit_code;
1118 if (STREQ(id, "help")) {
1120 exit_code = EXIT_SUCCESS;
1121 }
1122 else {
1123 exit_code = BKE_blender_cli_command_exec(C, id, argc - 2, argv + 2);
1124 }
1126 }
1127
1128 /* Consume remaining arguments. */
1129 return argc - 1;
1130}
1131
1133 "\n"
1134 "\tBackground mode: Do not systematically build and evaluate ViewLayers' dependency graphs\n"
1135 "\twhen loading a blend-file in background mode ('-b' or '-c' options).\n"
1136 "\n"
1137 "\tScripts requiring evaluated data then need to explicitly ensure that\n"
1138 "\tan evaluated depsgraph is available\n"
1139 "\t(e.g. by calling 'depsgraph = context.evaluated_depsgraph_get()').\n"
1140 "\n"
1141 "\tNOTE: this is a temporary option, in the future depsgraph will never be\n"
1142 "\tautomatically generated on file load in background mode.";
1144 const char ** /*argv*/,
1145 void * /*data*/)
1146{
1147 G.fileflags |= G_BACKGROUND_NO_DEPSGRAPH;
1148 return 0;
1149}
1150
1152 "\n"
1153 "\tDo not perform library override automatic resync when loading a new blend-file.\n"
1154 "\n"
1155 "\tNOTE: this is an alternative way to get the same effect as when setting the\n"
1156 "\t'No Override Auto Resync' User Preferences Debug option.";
1158 const char ** /*argv*/,
1159 void * /*data*/)
1160{
1161 G.fileflags |= G_LIBOVERRIDE_NO_AUTO_RESYNC;
1162 return 0;
1163}
1164
1165static const char arg_handle_log_level_set_doc[] =
1166 "<level>\n"
1167 "\tSet the logging verbosity level.\n"
1168 "\n"
1169 "\tfatal: Fatal errors only\n"
1170 "\terror: Errors only\n"
1171 "\twarning: Warnings\n"
1172 "\tinfo: Information about devices, files, configuration, operations\n"
1173 "\tdebug: Verbose messages for developers\n"
1174 "\ttrace: Very verbose code execution tracing";
1175static int arg_handle_log_level_set(int argc, const char **argv, void * /*data*/)
1176{
1177 const char *arg_id = "--log-level";
1178 if (argc > 1) {
1179 const char *err_msg = nullptr;
1180
1181 if (STRCASEEQ(argv[1], "fatal")) {
1182 G.log.level = CLG_LEVEL_FATAL;
1183 }
1184 else if (STRCASEEQ(argv[1], "error")) {
1185 G.log.level = CLG_LEVEL_ERROR;
1186 }
1187 else if (STRCASEEQ(argv[1], "warning")) {
1188 G.log.level = CLG_LEVEL_WARN;
1189 }
1190 else if (STRCASEEQ(argv[1], "info")) {
1191 G.log.level = CLG_LEVEL_INFO;
1192 }
1193 else if (STRCASEEQ(argv[1], "debug")) {
1194 G.log.level = CLG_LEVEL_DEBUG;
1195 }
1196 else if (STRCASEEQ(argv[1], "trace")) {
1197 G.log.level = CLG_LEVEL_TRACE;
1198 }
1199 else if (parse_int_clamp(argv[1], nullptr, -1, INT_MAX, &G.log.level, &err_msg)) {
1200 /* Numeric level for backwards compatibility. */
1201 if (G.log.level < 0) {
1202 G.log.level = CLG_LEVEL_LEN - 1;
1203 }
1204 else {
1205 G.log.level = std::min(CLG_LEVEL_INFO + G.log.level, CLG_LEVEL_LEN - 1);
1206 }
1207 }
1208 else {
1209 fprintf(stderr, "\nError: Invalid log level '%s %s'.\n", arg_id, argv[1]);
1210 return 1;
1211 }
1212
1213 CLG_level_set(CLG_Level(G.log.level));
1214 return 1;
1215 }
1216 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
1217 return 0;
1218}
1219
1221 "\n\t"
1222 "Show source file and function name in output.";
1223static int arg_handle_log_show_source_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1224{
1226 return 0;
1227}
1228
1230 "\n\t"
1231 "Show a back trace for each log message (debug builds only).";
1232static int arg_handle_log_show_backtrace_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1233{
1234 /* Ensure types don't become incompatible. */
1235 void (*fn)(FILE *fp) = BLI_system_backtrace;
1236 CLG_backtrace_fn_set((void (*)(void *))fn);
1237 return 0;
1238}
1239
1241 "\n\t"
1242 "Show memory usage for each log message.";
1243static int arg_handle_log_show_memory_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1244{
1246 return 0;
1247}
1248
1249static const char arg_handle_log_file_set_doc[] =
1250 "<filepath>\n"
1251 "\tSet a file to output the log to.";
1252static int arg_handle_log_file_set(int argc, const char **argv, void * /*data*/)
1253{
1254 const char *arg_id = "--log-file";
1255 if (argc > 1) {
1256 errno = 0;
1257 FILE *fp = BLI_fopen(argv[1], "w");
1258 if (fp == nullptr) {
1259 const char *err_msg = errno ? strerror(errno) : "unknown";
1260 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1261 }
1262 else {
1263 if (UNLIKELY(G.log.file != nullptr)) {
1264 fclose(static_cast<FILE *>(G.log.file));
1265 }
1266 G.log.file = fp;
1267 CLG_output_set(G.log.file);
1268 }
1269 return 1;
1270 }
1271 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
1272 return 0;
1273}
1274
1275static const char arg_handle_log_set_doc[] =
1276 "<match>\n"
1277 "\tEnable logging categories, taking a single comma separated argument.\n"
1278 "\n"
1279 "\t--log \"*\": log everything\n"
1280 "\t--log \"event\": logs every category starting with 'event'.\n"
1281 "\t--log \"render,cycles\": log both render and cycles messages.\n"
1282 "\t--log \"*mesh*\": log every category containing 'mesh' sub-string.\n"
1283 "\t--log \"*,^operator\": log everything except operators, with '^prefix' to exclude.";
1284static int arg_handle_log_set(int argc, const char **argv, void * /*data*/)
1285{
1286 const char *arg_id = "--log";
1287 if (argc > 1) {
1288 const char *str_step = argv[1];
1289 while (*str_step) {
1290 const char *str_step_end = strchr(str_step, ',');
1291 int str_step_len = str_step_end ? (str_step_end - str_step) : strlen(str_step);
1292
1293 if (str_step[0] == '^') {
1294 CLG_type_filter_exclude(str_step + 1, str_step_len - 1);
1295 }
1296 else {
1297 CLG_type_filter_include(str_step, str_step_len);
1298 }
1299
1300 if (str_step_end) {
1301 /* Typically only be one, but don't fail on multiple. */
1302 while (*str_step_end == ',') {
1303 str_step_end++;
1304 }
1305 str_step = str_step_end;
1306 }
1307 else {
1308 break;
1309 }
1310 }
1311 return 1;
1312 }
1313 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
1314 return 0;
1315}
1316
1318 "\n"
1319 "\tList all available logging categories for '--log', and exit.\n";
1320
1321static int arg_handle_list_clog_cats(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1322{
1323 auto print_identifier = [](const char *identifier, void *) { printf("%s\n", identifier); };
1324 CLG_logref_list_all(print_identifier, nullptr);
1326 exit(EXIT_SUCCESS);
1327 return 0;
1328}
1329
1331 "\n"
1332 "\tTurn debugging on.\n"
1333 "\n"
1334 "\t* Enables memory error detection\n"
1335 "\t* Disables mouse grab (to interact with a debugger in some cases)\n"
1336 "\t* Keeps Python's 'sys.stdin' rather than setting it to None";
1337static int arg_handle_debug_mode_set(int /*argc*/, const char ** /*argv*/, void *data)
1338{
1339 G.debug |= G_DEBUG;
1340 printf("Blender %s\n", BKE_blender_version_string());
1342# ifndef NDEBUG
1344# endif
1345
1346# ifdef WITH_BUILDINFO
1347 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
1348# endif
1349
1350 BLI_args_print(static_cast<bArgs *>(data));
1351 return 0;
1352}
1353
1355 "\n\t"
1356 "Enable debug messages for Freestyle.";
1358 "\n\t"
1359 "Enable debug messages for Python.";
1361 "\n\t"
1362 "Enable debug messages for the event system.";
1364 "\n\t"
1365 "Enable debug messages for event handling.";
1367 "\n\t"
1368 "Enable debug messages for the window manager, shows all operators in search, shows "
1369 "keymap errors.";
1371 "\n\t"
1372 "Enable debug messages for Ghost (Linux only).";
1374 "\n\t"
1375 "Enable debug messages for Wintab.";
1377 "\n\t"
1378 "Enable debug messages for virtual reality contexts.\n"
1379 "\tEnables the OpenXR API validation layer, (OpenXR) debug messages and general information "
1380 "prints.";
1382 "\n\t"
1383 "Enable debug messages for virtual reality frame rendering times.";
1385 "\n\t"
1386 "Enable time profiling for background jobs.";
1388 "\n\t"
1389 "Enable all debug messages from dependency graph.";
1391 "\n\t"
1392 "Enable debug messages from dependency graph related on graph construction.";
1394 "\n\t"
1395 "Enable debug messages from dependency graph related on tagging.";
1397 "\n\t"
1398 "Enable debug messages from dependency graph related on timing.";
1400 "\n\t"
1401 "Enable debug messages from dependency graph related on evaluation.";
1403 "\n\t"
1404 "Switch dependency graph to a single threaded evaluation.";
1406 "\n\t"
1407 "Enable colors for dependency graph debug messages.";
1409 "\n\t"
1410 "Verify validness of session-wide identifiers assigned to ID data-blocks.";
1412 "\n\t"
1413 "Enable workarounds for typical GPU issues and disable all GPU extensions.";
1415 "\n\t"
1416 "Force Vulkan dynamic rendering local read when supported by device.";
1417
1418static int arg_handle_debug_mode_generic_set(int /*argc*/, const char ** /*argv*/, void *data)
1419{
1420 G.debug |= POINTER_AS_INT(data);
1421 return 0;
1422}
1423
1424static const char arg_handle_debug_mode_io_doc[] =
1425 "\n\t"
1426 "Enable debug messages for I/O.";
1427static int arg_handle_debug_mode_io(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1428{
1429 G.debug |= G_DEBUG_IO;
1430 return 0;
1431}
1432
1434 "\n\t"
1435 "Enable all debug messages.";
1436static int arg_handle_debug_mode_all(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1437{
1438 G.debug |= G_DEBUG_ALL;
1439# ifdef WITH_LIBMV
1441# endif
1442 return 0;
1443}
1444
1446 "\n\t"
1447 "Enable debug messages from libmv library.";
1448static int arg_handle_debug_mode_libmv(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1449{
1450# ifdef WITH_LIBMV
1452# endif
1453 return 0;
1454}
1455
1457 "\n\t"
1458 "Enable debug messages from Cycles.";
1459static int arg_handle_debug_mode_cycles(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1460{
1461 const char *cycles_filter = "cycles.*";
1462 CLG_type_filter_include(cycles_filter, strlen(cycles_filter));
1463 return 0;
1464}
1465
1467 "\n\t"
1468 "Enable debug messages from FFmpeg video input and output.";
1469static int arg_handle_debug_mode_ffmpeg(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1470{
1471 const char *video_filter = "video.*";
1472 CLG_type_filter_include(video_filter, strlen(video_filter));
1473 return 0;
1474}
1475
1477 "\n\t"
1478 "Enable fully guarded memory allocation and debugging.";
1479static int arg_handle_debug_mode_memory_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1480{
1482 return 0;
1483}
1484
1486 "<value>\n"
1487 "\tSet debug value of <value> on startup.";
1488static int arg_handle_debug_value_set(int argc, const char **argv, void * /*data*/)
1489{
1490 const char *arg_id = "--debug-value";
1491 if (argc > 1) {
1492 const char *err_msg = nullptr;
1493 int value;
1494 if (!parse_int(argv[1], nullptr, &value, &err_msg)) {
1495 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1496 return 1;
1497 }
1498
1499 G.debug_value = value;
1500
1501 return 1;
1502 }
1503 fprintf(stderr, "\nError: you must specify debug value to set.\n");
1504 return 0;
1505}
1506
1507static const char arg_handle_debug_gpu_set_doc[] =
1508 "\n"
1509 "\tEnable GPU debug context and information for OpenGL 4.3+.";
1510static int arg_handle_debug_gpu_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1511{
1512 /* Also enable logging because that how gl errors are reported. */
1513 const char *gpu_filter = "gpu.*";
1514 CLG_type_filter_include(gpu_filter, strlen(gpu_filter));
1515 G.debug |= G_DEBUG_GPU;
1516 return 0;
1517}
1518
1520 "\n"
1521 "\tCompile all statically defined shaders to test platform compatibility.";
1523 const char ** /*argv*/,
1524 void * /*data*/)
1525{
1527 return 0;
1528}
1529
1531 "\n"
1532 "\tCapture the GPU commands issued inside the give scope name.";
1533static int arg_handle_debug_gpu_scope_capture_set(int argc, const char **argv, void * /*data*/)
1534{
1535 if (argc > 1) {
1536# ifdef WITH_RENDERDOC
1537 STRNCPY(G.gpu_debug_scope_name, argv[1]);
1538# else
1539 UNUSED_VARS(argc, argv);
1541# endif
1542 return 1;
1543 }
1544 fprintf(stderr, "\nError: you must specify a scope name to capture.\n");
1545 return 0;
1546}
1547
1549 "\n"
1550 "\tEnable RenderDoc integration for GPU frame grabbing and debugging.";
1552 const char ** /*argv*/,
1553 void * /*data*/)
1554{
1555# ifdef WITH_RENDERDOC
1557# else
1559# endif
1560 return 0;
1561}
1562
1564 "\n"
1565 "\tEnable shader debug info generation (Vulkan only).";
1567 const char ** /*argv*/,
1568 void * /*data*/)
1569{
1571 return 0;
1572}
1573
1575 "\n"
1576 "\tForce to use a specific GPU backend. Valid options: "
1577 "'vulkan', "
1578 "'metal', "
1579 "'opengl'.";
1581 "\n"
1582 "\tForce to use a specific GPU backend. Valid options: "
1583# ifdef WITH_OPENGL_BACKEND
1584 "'opengl'"
1585# endif
1586# ifdef WITH_METAL_BACKEND
1587 "'metal'"
1588# endif
1589# ifdef WITH_VULKAN_BACKEND
1590# if defined(WITH_OPENGL_BACKEND) || defined(WITH_METAL_BACKEND)
1591 " or "
1592# endif
1593 "'vulkan'"
1594# endif
1595 ".";
1596static int arg_handle_gpu_backend_set(int argc, const char **argv, void * /*data*/)
1597{
1598 if (argc < 2) {
1599 fprintf(stderr, "\nError: GPU backend must follow '--gpu-backend'.\n");
1600 return 0;
1601 }
1602 const char *backends_supported[3] = {nullptr};
1603 int backends_supported_num = 0;
1604
1605 GPUBackendType gpu_backend = GPU_BACKEND_NONE;
1606
1607 /* NOLINTBEGIN: bugprone-assignment-in-if-condition */
1608 if (false) {
1609 /* Use a dummy block to make the following `ifdef` blocks work. */
1610 }
1611# ifdef WITH_OPENGL_BACKEND
1612 else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "opengl"))) {
1613 gpu_backend = GPU_BACKEND_OPENGL;
1614 }
1615# endif
1616# ifdef WITH_VULKAN_BACKEND
1617 else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "vulkan"))) {
1618 gpu_backend = GPU_BACKEND_VULKAN;
1619 }
1620# endif
1621# ifdef WITH_METAL_BACKEND
1622 else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "metal"))) {
1623 gpu_backend = GPU_BACKEND_METAL;
1624 }
1625# endif
1626 else {
1627 fprintf(stderr, "\nError: Unrecognized GPU backend for '--gpu-backend', expected one of [");
1628 for (int i = 0; i < backends_supported_num; i++) {
1629 fprintf(stderr, (i + 1 != backends_supported_num) ? "%s, " : "%s", backends_supported[i]);
1630 }
1631 fprintf(stderr, "].\n");
1632 return 1;
1633 }
1634 /* NOLINTEND: bugprone-assignment-in-if-condition */
1635
1637
1638 return 1;
1639}
1640
1641static const char arg_handle_gpu_vsync_set_doc[] =
1642 "\n"
1643 "\tSet the VSync.\n"
1644 "\tValid options are: 'on', 'off' & 'auto' for adaptive sync.\n"
1645 "\n"
1646 "\t* The default settings depend on the GPU driver.\n"
1647 "\t* Disabling VSync can be useful for testing performance.\n"
1648 "\t* 'auto' is only supported by the OpenGL backend.";
1649static int arg_handle_gpu_vsync_set(int argc, const char **argv, void * /*data*/)
1650{
1651 const char *arg_id = "--gpu-vsync";
1652
1653 if (argc < 2) {
1654 fprintf(stderr, "\nError: VSync value must follow '%s'.\n", arg_id);
1655 return 0;
1656 }
1657
1658 /* Must be compatible with #GHOST_TVSyncModes. */
1659 int vsync;
1660 if (STREQ(argv[1], "on")) {
1661 vsync = 1;
1662 }
1663 else if (STREQ(argv[1], "off")) {
1664 vsync = 0;
1665 }
1666 else if (STREQ(argv[1], "auto")) {
1667 vsync = -1;
1668 }
1669 else {
1670 fprintf(stderr, "\nError: expected a value in [on, off, auto] '%s %s'.\n", arg_id, argv[1]);
1671 return 1;
1672 }
1673
1675
1676 return 1;
1677}
1678
1680 "\n"
1681 "\tOverride the Max Compilation Subprocesses setting (OpenGL only).";
1683 const char **argv,
1684 void * /*data*/)
1685{
1686 const char *arg_id = "--gpu-compilation-subprocesses";
1687 const int min = 0, max = BLI_system_thread_count();
1688 if (argc > 1) {
1689 const char *err_msg = nullptr;
1690 int subprocesses;
1691 if (!parse_int_strict_range(argv[1], nullptr, min, max, &subprocesses, &err_msg)) {
1692 fprintf(stderr,
1693 "\nError: %s '%s %s', expected number in [%d..%d].\n",
1694 err_msg,
1695 arg_id,
1696 argv[1],
1697 min,
1698 max);
1699 return 1;
1700 }
1701
1702# ifdef WITH_OPENGL_BACKEND
1704# else
1705 UNUSED_VARS(subprocesses);
1707# endif
1708 return 1;
1709 }
1710 fprintf(stderr,
1711 "\nError: you must specify a number of subprocesses in [%d..%d] '%s'.\n",
1712 min,
1713 max,
1714 arg_id);
1715 return 0;
1716}
1717
1718static const char arg_handle_debug_fpe_set_doc[] =
1719 "\n\t"
1720 "Enable floating-point exceptions.";
1721static int arg_handle_debug_fpe_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1722{
1724 return 0;
1725}
1726
1727static const char arg_handle_app_template_doc[] =
1728 "<template>\n"
1729 "\tSet the application template (matching the directory name), use 'default' for none.";
1730static int arg_handle_app_template(int argc, const char **argv, void * /*data*/)
1731{
1732 if (argc > 1) {
1733 const char *app_template = STREQ(argv[1], "default") ? "" : argv[1];
1735 return 1;
1736 }
1737 fprintf(stderr, "\nError: App template must follow '--app-template'.\n");
1738 return 0;
1739}
1740
1742 "\n\t"
1743 "Skip reading the '" BLENDER_STARTUP_FILE "' in the users home directory.";
1744static int arg_handle_factory_startup_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1745{
1746 G.factory_startup = true;
1748 return 0;
1749}
1750
1752 "\n\t"
1753 "Enable event simulation testing feature 'bpy.types.Window.event_simulate'.";
1754static int arg_handle_enable_event_simulate(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1755{
1757 return 0;
1758}
1759
1761 "\n\t"
1762 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES) " environment variable.";
1764 "\n\t"
1765 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS) " environment variable.";
1767 "\n\t"
1768 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON) " environment variable.";
1770 "\n\t"
1771 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_EXTENSIONS) " environment variable.";
1772
1773static int arg_handle_env_system_set(int argc, const char **argv, void * /*data*/)
1774{
1775 /* `--env-system-scripts` -> `BLENDER_SYSTEM_SCRIPTS` */
1776
1777 char env[64] = "BLENDER";
1778 char *ch_dst = env + 7; /* Skip `BLENDER`. */
1779 const char *ch_src = argv[0] + 5; /* Skip `--env`. */
1780
1781 if (argc < 2) {
1782 fprintf(stderr, "%s requires one argument\n", argv[0]);
1783 exit(EXIT_FAILURE);
1785 }
1786
1787 for (; *ch_src; ch_src++, ch_dst++) {
1788 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* Inline #toupper(). */
1789 }
1790
1791 *ch_dst = '\0';
1792 BLI_setenv(env, argv[1]);
1793 return 1;
1794}
1795
1796static const char arg_handle_playback_mode_doc[] =
1797 "<options> <file(s)>\n"
1798 "\tInstead of showing Blender's user interface, this runs Blender as an animation player,\n"
1799 "\tto view movies and image sequences rendered in Blender (ignored if '-b' is set).\n"
1800 "\n"
1801 "\tPlayback Arguments:\n"
1802 "\n"
1803 "\t-p <sx> <sy>\n"
1804 "\t\tOpen with lower left corner at <sx>, <sy>.\n"
1805 "\t-m\n"
1806 "\t\tRead from disk (Do not buffer).\n"
1807 "\t-f <fps> <fps_base>\n"
1808 "\t\tSpecify FPS to start with.\n"
1809 "\t-j <frame>\n"
1810 "\t\tSet frame step to <frame>.\n"
1811 "\t-s <frame>\n"
1812 "\t\tPlay from <frame>.\n"
1813 "\t-e <frame>\n"
1814 "\t\tPlay until <frame>.\n"
1815 "\t-c <cache_memory>\n"
1816 "\t\tAmount of memory in megabytes to allow for caching images during playback.\n"
1817 "\t\tZero disables (clamping to a fixed number of frames instead).";
1818static int arg_handle_playback_mode(int argc, const char **argv, void * /*data*/)
1819{
1820 /* Ignore the animation player if `-b` was given first. */
1821 if (G.background == 0) {
1822 /* Skip this argument (`-a`). */
1823 const int exit_code = WM_main_playanim(argc - 1, argv + 1);
1824
1825 exit(exit_code);
1826 }
1827
1828 return -2;
1829}
1830
1832 "<sx> <sy> <w> <h>\n"
1833 "\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>.";
1834static int arg_handle_window_geometry(int argc, const char **argv, void * /*data*/)
1835{
1836 const char *arg_id = "-p / --window-geometry";
1837 int params[4], i;
1838
1839 if (argc < 5) {
1840 fprintf(stderr, "Error: requires four arguments '%s'\n", arg_id);
1841 exit(1);
1842 }
1843
1844 for (i = 0; i < 4; i++) {
1845 const char *err_msg = nullptr;
1846 if (!parse_int(argv[i + 1], nullptr, &params[i], &err_msg)) {
1847 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1848 exit(1);
1849 }
1850 }
1851
1853
1854 return 4;
1855}
1856
1858 "\n\t"
1859 "Do not use native pixel size, for high resolution displays (MacBook 'Retina').";
1860static int arg_handle_native_pixels_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1861{
1862 WM_init_native_pixels(false);
1863 return 0;
1864}
1865
1866static const char arg_handle_window_border_doc[] =
1867 "\n\t"
1868 "Force opening with borders, in a normal (non maximized) state.";
1869static int arg_handle_window_border(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1870{
1872 return 0;
1873}
1874
1876 "\n\t"
1877 "Force opening full-screen.";
1878static int arg_handle_window_fullscreen(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1879{
1881 return 0;
1882}
1883
1885 "\n\t"
1886 "Force opening maximized.";
1887static int arg_handle_window_maximized(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1888{
1890 return 0;
1891}
1892
1894 "\n\t"
1895 "Disable all window decorations (Linux only).";
1896static int arg_handle_no_window_frame(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1897{
1899 return 0;
1900}
1901
1903 "\n\t"
1904 "Open behind other windows and without taking focus.";
1905static int arg_handle_no_window_focus(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1906{
1908 return 0;
1909}
1910
1912 "\n\t"
1913 "Start with the console window open (ignored if '-b' is set), (Windows only).";
1914static int arg_handle_start_with_console(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1915{
1917 return 0;
1918}
1919
1920static bool arg_handle_extension_registration(const bool do_register, const bool all_users)
1921{
1922 /* Logic runs in #main_args_handle_registration. */
1923# ifdef WIN32
1924 /* This process has been launched with the permissions needed
1925 * to register or unregister, so just do it now and then exit. */
1926 if (do_register) {
1928 }
1929 else {
1931 }
1932 TerminateProcess(GetCurrentProcess(), 0);
1933 return true;
1934# else
1935 char *error_msg = nullptr;
1936 bool result = WM_platform_associate_set(do_register, all_users, &error_msg);
1937 if (error_msg) {
1938 fprintf(stderr, "Error: %s\n", error_msg);
1939 MEM_freeN(error_msg);
1940 }
1941 return result;
1942# endif
1943}
1944
1946 "\n\t"
1947 "Register blend-file extension for current user, then exit (Windows & Linux only).";
1948static int arg_handle_register_extension(int argc, const char **argv, void *data)
1949{
1950 CLG_quiet_set(true);
1952
1953# if !(defined(WIN32) || defined(__APPLE__))
1954 if (!main_arg_deferred_is_set()) {
1956 return argc - 1;
1957 }
1958# else
1959 UNUSED_VARS(argv, data);
1960# endif
1962 return argc - 1;
1963}
1964
1966 "\n\t"
1967 "Register blend-file extension for all users, then exit (Windows & Linux only).";
1968static int arg_handle_register_extension_all(int argc, const char **argv, void *data)
1969{
1970 CLG_quiet_set(true);
1972
1973# if !(defined(WIN32) || defined(__APPLE__))
1974 if (!main_arg_deferred_is_set()) {
1976 return argc - 1;
1977 }
1978# else
1979 UNUSED_VARS(argv, data);
1980# endif
1982 return argc - 1;
1983}
1984
1986 "\n\t"
1987 "Unregister blend-file extension for current user, then exit (Windows & Linux only).";
1988static int arg_handle_unregister_extension(int argc, const char **argv, void *data)
1989{
1990 CLG_quiet_set(true);
1992
1993# if !(defined(WIN32) || defined(__APPLE__))
1994 if (!main_arg_deferred_is_set()) {
1996 return argc - 1;
1997 }
1998# else
1999 UNUSED_VARS(argc, argv, data);
2000# endif
2002 return 0;
2003}
2004
2006 "\n\t"
2007 "Unregister blend-file extension for all users, then exit (Windows & Linux only).";
2008static int arg_handle_unregister_extension_all(int argc, const char **argv, void *data)
2009{
2010 CLG_quiet_set(true);
2012
2013# if !(defined(WIN32) || defined(__APPLE__))
2014 if (!main_arg_deferred_is_set()) {
2016 return argc - 1;
2017 }
2018# else
2019 UNUSED_VARS(argc, argv, data);
2020# endif
2022 return 0;
2023}
2024
2025static const char arg_handle_qos_set_doc[] =
2026 "<level>\n"
2027 "\tSet the Quality of Service (QoS) mode for hybrid CPU architectures (Windows only).\n"
2028 "\n"
2029 "\tdefault: Uses the default behavior of the OS.\n"
2030 "\thigh: Always makes use of performance cores.\n"
2031 "\teco: Schedules Blender threads exclusively to efficiency cores.";
2032static int arg_handle_qos_set(int argc, const char **argv, void * /*data*/)
2033{
2034 const char *arg_id = "--qos";
2035 if (argc > 1) {
2036# ifdef _WIN32
2037 QoSMode qos_mode;
2038 if (STRCASEEQ(argv[1], "default")) {
2039 qos_mode = QoSMode::DEFAULT;
2040 }
2041 else if (STRCASEEQ(argv[1], "high")) {
2042 qos_mode = QoSMode::HIGH;
2043 }
2044 else if (STRCASEEQ(argv[1], "eco")) {
2045 qos_mode = QoSMode::ECO;
2046 }
2047 else {
2048 fprintf(stderr, "\nError: Invalid QoS level '%s %s'.\n", arg_id, argv[1]);
2049 return 1;
2050 }
2052# else
2053 UNUSED_VARS(argv);
2054 fprintf(stderr, "\nError: '%s' is Windows only.\n", arg_id);
2055# endif
2056 return 1;
2057 }
2058 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
2059 return 0;
2060}
2061
2062static const char arg_handle_audio_disable_doc[] =
2063 "\n\t"
2064 "Force sound system to None.";
2065static int arg_handle_audio_disable(int /*argc*/, const char ** /*argv*/, void * /*data*/)
2066{
2067 BKE_sound_force_device("None");
2068 return 0;
2069}
2070
2071static const char arg_handle_audio_set_doc[] =
2072 "\n\t"
2073 "Force sound system to a specific device.\n"
2074 "\t'None' 'Default' 'SDL' 'OpenAL' 'CoreAudio' 'JACK' 'PulseAudio' 'WASAPI'.";
2075static int arg_handle_audio_set(int argc, const char **argv, void * /*data*/)
2076{
2077 if (argc < 1) {
2078 fprintf(stderr, "-setaudio requires one argument\n");
2079 exit(1);
2080 }
2081
2082 const char *device = argv[1];
2083 if (STREQ(device, "Default")) {
2084 /* Unset any forced device. */
2085 device = nullptr;
2086 }
2087
2088 BKE_sound_force_device(device);
2089 return 1;
2090}
2091
2092static const char arg_handle_output_set_doc[] =
2093 "<path>\n"
2094 "\tSet the render path and file name.\n"
2095 "\tUse '//' at the start of the path to render relative to the blend-file.\n"
2096 "\n"
2097 "\tYou can use path templating features such as '{blend_name}' in the path.\n"
2098 "\tSee Blender's documentation on path templates for more details.\n"
2099 "\n"
2100 "\tThe '#' characters are replaced by the frame number, and used to define zero padding.\n"
2101 "\n"
2102 "\t* 'animation_##_test.png' becomes 'animation_01_test.png'\n"
2103 "\t* 'test-######.png' becomes 'test-000001.png'\n"
2104 "\n"
2105 "\tWhen the filename does not contain '#', the suffix '####' is added to the filename.\n"
2106 "\n"
2107 "\tThe frame number will be added at the end of the filename, eg:\n"
2108 "\t# blender -b animation.blend -o //render_ -F PNG -x 1 -a\n"
2109 "\t'//render_' becomes '//render_####', writing frames as '//render_0001.png'";
2110static int arg_handle_output_set(int argc, const char **argv, void *data)
2111{
2112 bContext *C = static_cast<bContext *>(data);
2113 if (argc > 1) {
2114 Scene *scene = CTX_data_scene(C);
2115 if (scene) {
2116 STRNCPY(scene->r.pic, argv[1]);
2118 }
2119 else {
2120 fprintf(stderr, "\nError: no blend loaded. cannot use '-o / --render-output'.\n");
2121 }
2122 return 1;
2123 }
2124 fprintf(stderr, "\nError: you must specify a path after '-o / --render-output'.\n");
2125 return 0;
2126}
2127
2128static const char arg_handle_engine_set_doc[] =
2129 "<engine>\n"
2130 "\tSpecify the render engine.\n"
2131 "\tUse '-E help' to list available engines.";
2132static int arg_handle_engine_set(int argc, const char **argv, void *data)
2133{
2134 bContext *C = static_cast<bContext *>(data);
2135 if (argc >= 2) {
2136 const char *engine_name = argv[1];
2137
2138 if (STREQ(engine_name, "help")) {
2139 printf("Blender Engine Listing:\n");
2141 printf("\t%s\n", type->idname);
2142 }
2143 WM_exit_ex(C, false, false);
2144 exit(0);
2145 }
2146 else {
2147 Scene *scene = CTX_data_scene(C);
2148 if (scene) {
2149 /* Backwards compatibility. */
2150 if (STREQ(engine_name, "BLENDER_EEVEE_NEXT")) {
2151 engine_name = "BLENDER_EEVEE";
2152 }
2153
2154 if (BLI_findstring(&R_engines, engine_name, offsetof(RenderEngineType, idname))) {
2155 STRNCPY_UTF8(scene->r.engine, engine_name);
2157 }
2158 else {
2159 fprintf(stderr, "\nError: engine not found '%s'\n", engine_name);
2160 WM_exit_ex(C, false, false);
2161 exit(1);
2162 }
2163 }
2164 else {
2165 fprintf(stderr,
2166 "\nError: no blend loaded. "
2167 "order the arguments so '-E / --engine' is after a blend is loaded.\n");
2168 }
2169 }
2170
2171 return 1;
2172 }
2173 fprintf(stderr, "\nEngine not specified, give 'help' for a list of available engines.\n");
2174 return 0;
2175}
2176
2178 "<format>\n"
2179 "\tSet the render format.\n"
2180 "\tValid options are:\n"
2181 "\t'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'PNG' 'BMP' 'HDR' 'TIFF'.\n"
2182 "\n"
2183 "\tFormats that can be compiled into Blender, not available on all systems:\n"
2184 "\t'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'FFMPEG' 'CINEON' 'DPX' 'JP2' 'WEBP'.";
2185static int arg_handle_image_type_set(int argc, const char **argv, void *data)
2186{
2187 bContext *C = static_cast<bContext *>(data);
2188 if (argc > 1) {
2189 const char *imtype = argv[1];
2190 Scene *scene = CTX_data_scene(C);
2191 if (scene) {
2192 const char imtype_new = BKE_imtype_from_arg(imtype);
2193
2194 if (imtype_new == R_IMF_IMTYPE_INVALID) {
2195 fprintf(stderr,
2196 "\nError: Format from '-F / --render-format' not known or not compiled in this "
2197 "release.\n");
2198 }
2199 else {
2200 BKE_image_format_set(&scene->r.im_format, &scene->id, imtype_new);
2202 }
2203 }
2204 else {
2205 fprintf(stderr,
2206 "\nError: no blend loaded. "
2207 "order the arguments so '-F / --render-format' is after the blend is loaded.\n");
2208 }
2209 return 1;
2210 }
2211 fprintf(stderr, "\nError: you must specify a format after '-F / --render-format'.\n");
2212 return 0;
2213}
2214
2215static const char arg_handle_threads_set_doc[] =
2216 "<threads>\n"
2217 "\tUse amount of <threads> for rendering and other operations\n"
2218 "\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 to use the systems processor count.";
2219static int arg_handle_threads_set(int argc, const char **argv, void * /*data*/)
2220{
2221 const char *arg_id = "-t / --threads";
2222 const int min = 0, max = BLENDER_MAX_THREADS;
2223 if (argc > 1) {
2224 const char *err_msg = nullptr;
2225 int threads;
2226 if (!parse_int_strict_range(argv[1], nullptr, min, max, &threads, &err_msg)) {
2227 fprintf(stderr,
2228 "\nError: %s '%s %s', expected number in [%d..%d].\n",
2229 err_msg,
2230 arg_id,
2231 argv[1],
2232 min,
2233 max);
2234 return 1;
2235 }
2236
2238 return 1;
2239 }
2240 fprintf(stderr,
2241 "\nError: you must specify a number of threads in [%d..%d] '%s'.\n",
2242 min,
2243 max,
2244 arg_id);
2245 return 0;
2246}
2247
2248static const char arg_handle_verbosity_set_doc[] =
2249 "<verbose>\n"
2250 "\tSet the logging verbosity level for debug messages that support it.";
2251static int arg_handle_verbosity_set(int argc, const char **argv, void * /*data*/)
2252{
2253 const char *arg_id = "--verbose";
2254 if (argc > 1) {
2255 const char *err_msg = nullptr;
2256 int level;
2257 if (!parse_int(argv[1], nullptr, &level, &err_msg)) {
2258 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2259 }
2260
2261# ifdef WITH_LIBMV
2263# endif
2264
2265 return 1;
2266 }
2267 fprintf(stderr, "\nError: you must specify a verbosity level.\n");
2268 return 0;
2269}
2270
2271static const char arg_handle_extension_set_doc[] =
2272 "<bool>\n"
2273 "\tSet option to add the file extension to the end of the file.";
2274static int arg_handle_extension_set(int argc, const char **argv, void *data)
2275{
2276 bContext *C = static_cast<bContext *>(data);
2277 if (argc > 1) {
2278 Scene *scene = CTX_data_scene(C);
2279 if (scene) {
2280 if (argv[1][0] == '0') {
2281 scene->r.scemode &= ~R_EXTENSION;
2283 }
2284 else if (argv[1][0] == '1') {
2285 scene->r.scemode |= R_EXTENSION;
2287 }
2288 else {
2289 fprintf(stderr,
2290 "\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
2291 }
2292 }
2293 else {
2294 fprintf(stderr,
2295 "\nError: no blend loaded. "
2296 "order the arguments so '-o ' is after '-x '.\n");
2297 }
2298 return 1;
2299 }
2300 fprintf(stderr, "\nError: you must specify a path after '- '.\n");
2301 return 0;
2302}
2303
2305{
2306 const char *render_filter = "render.*";
2307 CLG_type_filter_include(render_filter, strlen(render_filter));
2308}
2309
2310static const char arg_handle_render_frame_doc[] =
2311 "<frame>\n"
2312 "\tRender frame <frame> and save it.\n"
2313 "\n"
2314 "\t* +<frame> start frame relative, -<frame> end frame relative.\n"
2315 "\t* A comma separated list of frames can also be used (no spaces).\n"
2316 "\t* A range of frames can be expressed using '..' separator between the first and last "
2317 "frames (inclusive).\n";
2318static int arg_handle_render_frame(int argc, const char **argv, void *data)
2319{
2320 const char *arg_id = "-f / --render-frame";
2321 bContext *C = static_cast<bContext *>(data);
2322 Scene *scene = CTX_data_scene(C);
2323 if (scene) {
2325
2326 Main *bmain = CTX_data_main(C);
2327
2328 if (argc > 1) {
2329 const char *err_msg = nullptr;
2330 Render *re;
2331 ReportList reports;
2332
2333 int (*frame_range_arr)[2], frames_range_len;
2334 if ((frame_range_arr = parse_int_range_relative_clamp_n(argv[1],
2335 scene->r.sfra,
2336 scene->r.efra,
2337 MINAFRAME,
2338 MAXFRAME,
2339 &frames_range_len,
2340 &err_msg)) == nullptr)
2341 {
2342 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2343 return 1;
2344 }
2345
2346 re = RE_NewSceneRender(scene);
2347 BKE_reports_init(&reports, RPT_STORE);
2348 RE_SetReports(re, &reports);
2349 for (int i = 0; i < frames_range_len; i++) {
2350 /* We could pass in frame ranges,
2351 * but prefer having exact behavior as passing in multiple frames. */
2352 if ((frame_range_arr[i][0] <= frame_range_arr[i][1]) == 0) {
2353 fprintf(stderr, "\nWarning: negative range ignored '%s %s'.\n", arg_id, argv[1]);
2354 }
2355
2356 for (int frame = frame_range_arr[i][0]; frame <= frame_range_arr[i][1]; frame++) {
2357 RE_RenderAnim(re, bmain, scene, nullptr, nullptr, frame, frame, scene->r.frame_step);
2358 }
2359 }
2360 RE_SetReports(re, nullptr);
2361 BKE_reports_free(&reports);
2362 MEM_freeN(frame_range_arr);
2363 return 1;
2364 }
2365 fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id);
2366 return 0;
2367 }
2368 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2369 return 0;
2370}
2371
2373 "\n\t"
2374 "Render frames from start to end (inclusive).";
2375static int arg_handle_render_animation(int /*argc*/, const char ** /*argv*/, void *data)
2376{
2377 bContext *C = static_cast<bContext *>(data);
2378 Scene *scene = CTX_data_scene(C);
2379 if (scene) {
2381
2382 Main *bmain = CTX_data_main(C);
2383 Render *re = RE_NewSceneRender(scene);
2384 ReportList reports;
2385 BKE_reports_init(&reports, RPT_STORE);
2386 RE_SetReports(re, &reports);
2388 re, bmain, scene, nullptr, nullptr, scene->r.sfra, scene->r.efra, scene->r.frame_step);
2389 RE_SetReports(re, nullptr);
2390 BKE_reports_free(&reports);
2391 }
2392 else {
2393 fprintf(stderr, "\nError: no blend loaded. cannot use '-a'.\n");
2394 }
2395 return 0;
2396}
2397
2398static const char arg_handle_scene_set_doc[] =
2399 "<name>\n"
2400 "\tSet the active scene <name> for rendering.";
2401static int arg_handle_scene_set(int argc, const char **argv, void *data)
2402{
2403 if (argc > 1) {
2404 bContext *C = static_cast<bContext *>(data);
2405 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
2406 if (scene) {
2407 CTX_data_scene_set(C, scene);
2408
2409 /* Set the scene of the first window, see: #55991,
2410 * otherwise scripts that run later won't get this scene back from the context. */
2411 wmWindow *win = CTX_wm_window(C);
2412 if (win == nullptr) {
2413 win = static_cast<wmWindow *>(CTX_wm_manager(C)->windows.first);
2414 }
2415 if (win != nullptr) {
2417 }
2418 }
2419 return 1;
2420 }
2421 fprintf(stderr, "\nError: Scene name must follow '-S / --scene'.\n");
2422 return 0;
2423}
2424
2426 "<frame>\n"
2427 "\tSet start to frame <frame>, supports +/- for relative frames too.";
2428static int arg_handle_frame_start_set(int argc, const char **argv, void *data)
2429{
2430 const char *arg_id = "-s / --frame-start";
2431 bContext *C = static_cast<bContext *>(data);
2432 Scene *scene = CTX_data_scene(C);
2433 if (scene) {
2434 if (argc > 1) {
2435 const char *err_msg = nullptr;
2436 if (!parse_int_relative_clamp(argv[1],
2437 nullptr,
2438 scene->r.sfra,
2439 scene->r.sfra - 1,
2440 MINAFRAME,
2441 MAXFRAME,
2442 &scene->r.sfra,
2443 &err_msg))
2444 {
2445 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2446 }
2447 else {
2449 }
2450 return 1;
2451 }
2452 fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id);
2453 return 0;
2454 }
2455 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2456 return 0;
2457}
2458
2459static const char arg_handle_frame_end_set_doc[] =
2460 "<frame>\n"
2461 "\tSet end to frame <frame>, supports +/- for relative frames too.";
2462static int arg_handle_frame_end_set(int argc, const char **argv, void *data)
2463{
2464 const char *arg_id = "-e / --frame-end";
2465 bContext *C = static_cast<bContext *>(data);
2466 Scene *scene = CTX_data_scene(C);
2467 if (scene) {
2468 if (argc > 1) {
2469 const char *err_msg = nullptr;
2470 if (!parse_int_relative_clamp(argv[1],
2471 nullptr,
2472 scene->r.efra,
2473 scene->r.efra - 1,
2474 MINAFRAME,
2475 MAXFRAME,
2476 &scene->r.efra,
2477 &err_msg))
2478 {
2479 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2480 }
2481 else {
2483 }
2484 return 1;
2485 }
2486 fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id);
2487 return 0;
2488 }
2489 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2490 return 0;
2491}
2492
2494 "<frames>\n"
2495 "\tSet number of frames to step forward after each rendered frame.";
2496static int arg_handle_frame_skip_set(int argc, const char **argv, void *data)
2497{
2498 const char *arg_id = "-j / --frame-jump";
2499 bContext *C = static_cast<bContext *>(data);
2500 Scene *scene = CTX_data_scene(C);
2501 if (scene) {
2502 if (argc > 1) {
2503 const char *err_msg = nullptr;
2504 if (!parse_int_clamp(argv[1], nullptr, 1, MAXFRAME, &scene->r.frame_step, &err_msg)) {
2505 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2506 }
2507 else {
2509 }
2510 return 1;
2511 }
2512 fprintf(stderr, "\nError: number of frames to step must follow '%s'.\n", arg_id);
2513 return 0;
2514 }
2515 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2516 return 0;
2517}
2518
2520 "<filepath>\n"
2521 "\tRun the given Python script file.";
2522static int arg_handle_python_file_run(int argc, const char **argv, void *data)
2523{
2524 bContext *C = static_cast<bContext *>(data);
2525
2526 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2527 if (argc > 1) {
2528# ifdef WITH_PYTHON
2529 /* Make the path absolute because its needed for relative linked blends to be found. */
2530 char filepath[FILE_MAX];
2531 STRNCPY(filepath, argv[1]);
2532 BLI_path_canonicalize_native(filepath, sizeof(filepath));
2533
2534 bool ok;
2535 BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, nullptr));
2536 if (!ok && app_state.exit_code_on_error.python) {
2537 fprintf(stderr, "\nError: script failed, file: '%s', exiting.\n", argv[1]);
2538 WM_exit(C, app_state.exit_code_on_error.python);
2539 }
2540# else
2541 UNUSED_VARS(C);
2542 fprintf(stderr, "This Blender was built without Python support\n");
2543# endif /* WITH_PYTHON */
2544
2545 return 1;
2546 }
2547 fprintf(stderr, "\nError: you must specify a filepath after '%s'.\n", argv[0]);
2548 return 0;
2549}
2550
2552 "<name>\n"
2553 "\tRun the given Python script text block.";
2554static int arg_handle_python_text_run(int argc, const char **argv, void *data)
2555{
2556 bContext *C = static_cast<bContext *>(data);
2557
2558 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2559 if (argc > 1) {
2560# ifdef WITH_PYTHON
2561 Main *bmain = CTX_data_main(C);
2562 /* Make the path absolute because its needed for relative linked blends to be found. */
2563 Text *text = (Text *)BKE_libblock_find_name(bmain, ID_TXT, argv[1]);
2564 bool ok;
2565
2566 if (text) {
2567 BPY_CTX_SETUP(ok = BPY_run_text(C, text, nullptr, false));
2568 }
2569 else {
2570 fprintf(stderr, "\nError: text block not found %s.\n", argv[1]);
2571 ok = false;
2572 }
2573
2574 if (!ok && app_state.exit_code_on_error.python) {
2575 fprintf(stderr, "\nError: script failed, text: '%s', exiting.\n", argv[1]);
2576 WM_exit(C, app_state.exit_code_on_error.python);
2577 }
2578# else
2579 UNUSED_VARS(C);
2580 fprintf(stderr, "This Blender was built without Python support\n");
2581# endif /* WITH_PYTHON */
2582
2583 return 1;
2584 }
2585
2586 fprintf(stderr, "\nError: you must specify a text block after '%s'.\n", argv[0]);
2587 return 0;
2588}
2589
2591 "<expression>\n"
2592 "\tRun the given expression as a Python script.";
2593static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
2594{
2595 bContext *C = static_cast<bContext *>(data);
2596
2597 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2598 if (argc > 1) {
2599# ifdef WITH_PYTHON
2600 bool ok;
2601 BPY_CTX_SETUP(ok = BPY_run_string_exec(C, nullptr, argv[1]));
2602 if (!ok && app_state.exit_code_on_error.python) {
2603 fprintf(stderr, "\nError: script failed, expr: '%s', exiting.\n", argv[1]);
2604 WM_exit(C, app_state.exit_code_on_error.python);
2605 }
2606# else
2607 UNUSED_VARS(C);
2608 fprintf(stderr, "This Blender was built without Python support\n");
2609# endif /* WITH_PYTHON */
2610
2611 return 1;
2612 }
2613 fprintf(stderr, "\nError: you must specify a Python expression after '%s'.\n", argv[0]);
2614 return 0;
2615}
2616
2618 "\n\t"
2619 "Run Blender with an interactive console.";
2620static int arg_handle_python_console_run(int /*argc*/, const char ** /*argv*/, void *data)
2621{
2622 bContext *C = static_cast<bContext *>(data);
2623# ifdef WITH_PYTHON
2624 const char *imports[] = {"code", nullptr};
2625 BPY_CTX_SETUP(BPY_run_string_eval(C, imports, "code.interact()"));
2626# else
2627 UNUSED_VARS(C);
2628 fprintf(stderr, "This Blender was built without python support\n");
2629# endif /* WITH_PYTHON */
2630
2631 return 0;
2632}
2633
2635 "<code>\n"
2636 "\tSet the exit-code in [0..255] to exit if a Python exception is raised\n"
2637 "\t(only for scripts executed from the command line), zero disables.";
2638static int arg_handle_python_exit_code_set(int argc, const char **argv, void * /*data*/)
2639{
2640 const char *arg_id = "--python-exit-code";
2641 if (argc > 1) {
2642 const char *err_msg = nullptr;
2643 const int min = 0, max = 255;
2644 int exit_code;
2645 if (!parse_int_strict_range(argv[1], nullptr, min, max, &exit_code, &err_msg)) {
2646 fprintf(stderr,
2647 "\nError: %s '%s %s', expected number in [%d..%d].\n",
2648 err_msg,
2649 arg_id,
2650 argv[1],
2651 min,
2652 max);
2653 return 1;
2654 }
2655
2656 app_state.exit_code_on_error.python = uchar(exit_code);
2657 return 1;
2658 }
2659 fprintf(stderr, "\nError: you must specify an exit code number '%s'.\n", arg_id);
2660 return 0;
2661}
2662
2664 "\n\t"
2665 "Allow Python to use system environment variables such as 'PYTHONPATH' and the user "
2666 "site-packages directory.";
2668 const char ** /*argv*/,
2669 void * /*data*/)
2670{
2671# ifdef WITH_PYTHON
2673# endif
2674 return 0;
2675}
2676
2677static const char arg_handle_addons_set_doc[] =
2678 "<addon(s)>\n"
2679 "\tComma separated list (no spaces) of add-ons to enable in addition to any default add-ons.";
2680static int arg_handle_addons_set(int argc, const char **argv, void *data)
2681{
2682 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2683 if (argc > 1) {
2684# ifdef WITH_PYTHON
2685 const char script_str[] =
2686 "from _bpy_internal.addons.cli import set_from_cli\n"
2687 "set_from_cli('%s')";
2688 const int slen = strlen(argv[1]) + (sizeof(script_str) - 2);
2689 char *str = static_cast<char *>(malloc(slen));
2690 bContext *C = static_cast<bContext *>(data);
2691 BLI_snprintf(str, slen, script_str, argv[1]);
2692
2693 BLI_assert(strlen(str) + 1 == slen);
2694 BPY_CTX_SETUP(BPY_run_string_exec(C, nullptr, str));
2695 free(str);
2696# else
2697 UNUSED_VARS(argv, data);
2698# endif /* WITH_PYTHON */
2699 return 1;
2700 }
2701 fprintf(stderr, "\nError: you must specify a comma separated list after '--addons'.\n");
2702 return 0;
2703}
2704
2706 "\n"
2707 "\tEnable CPU & GPU performance profiling for GPU debug groups\n"
2708 "\t(Outputs a profile.json file in the Trace Event Format to the current directory)";
2709static int arg_handle_profile_gpu_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
2710{
2711 G.profile_gpu = true;
2712 return 0;
2713}
2714
2719static bool handle_load_file(bContext *C, const char *filepath_arg, const bool load_empty_file)
2720{
2721 /* Make the path absolute because its needed for relative linked blends to be found. */
2722 char filepath[FILE_MAX];
2723 STRNCPY(filepath, filepath_arg);
2724 BLI_path_canonicalize_native(filepath, sizeof(filepath));
2725
2726 /* Load the file. */
2727 ReportList reports;
2730 /* When activating from the command line there isn't an exact equivalent to operator properties.
2731 * Instead, enabling auto-execution via `--enable-autoexec` causes the auto-execution
2732 * check to be skipped (if it's set), so it's fine to always enable the check here. */
2733 const bool use_scripts_autoexec_check = true;
2734 const bool success = WM_file_read(C, filepath, use_scripts_autoexec_check, &reports);
2735
2737 WM_reports_from_reports_move(wm, &reports);
2738 BKE_reports_free(&reports);
2739
2740 if (success) {
2741 if (G.background) {
2742 /* Ensure we use 'C->data.scene' for background render. */
2743 CTX_wm_window_set(C, nullptr);
2744 }
2745 }
2746 else {
2747 /* Failed to load file, stop processing arguments if running in background mode. */
2748 if (G.background) {
2749 /* Set `is_break` if running in the background mode so
2750 * blender will return non-zero exit code which then
2751 * could be used in automated script to control how
2752 * good or bad things are. */
2753 G.is_break = true;
2754 return false;
2755 }
2756
2757 const char *error_msg_generic = "file could not be loaded";
2758 const char *error_msg = nullptr;
2759
2760 if (load_empty_file == false) {
2761 error_msg = error_msg_generic;
2762 }
2763 else if (!BKE_blendfile_extension_check(filepath)) {
2764 /* Non-blend. Continue loading and give warning. */
2765 G_MAIN->is_read_invalid = true;
2766 return true;
2767 }
2768 else if (BLI_exists(filepath)) {
2769 /* When a file is found but can't be loaded, handling it as a new file
2770 * could cause it to be unintentionally overwritten (data loss).
2771 * Further this is almost certainly not that a user would expect or want.
2772 * If they do, they can delete the file beforehand. */
2773 error_msg = error_msg_generic;
2774 }
2775
2776 if (error_msg) {
2777 fprintf(stderr, "Error: %s, exiting! %s\n", error_msg, filepath);
2778 WM_exit(C, EXIT_FAILURE);
2779 /* Unreachable, return for clarity. */
2780 return false;
2781 }
2782
2783 /* Behave as if a file was loaded, calling "Save" will write to the `filepath` from the CLI.
2784 *
2785 * WARNING: The path referenced may be incorrect, no attempt is made to validate the path
2786 * here or check that writing to it will work. If the users enters the path of a directory
2787 * that doesn't exist (for example) saving will fail.
2788 * Attempting to create the file at this point is possible but likely to cause more
2789 * trouble than it's worth (what with network drives), removable devices ... etc. */
2790
2791 STRNCPY(G_MAIN->filepath, filepath);
2792 printf("... opened default scene instead; saving will write to: %s\n", filepath);
2793 }
2794
2795 return true;
2796}
2797
2798int main_args_handle_load_file(int /*argc*/, const char **argv, void *data)
2799{
2800 bContext *C = static_cast<bContext *>(data);
2801 const char *filepath = argv[0];
2802
2803 /* NOTE: we could skip these, but so far we always tried to load these files. */
2804 if (argv[0][0] == '-') {
2805 fprintf(stderr, "unknown argument, loading as file: %s\n", filepath);
2806 }
2807
2808 if (!handle_load_file(C, filepath, true)) {
2809 return -1;
2810 }
2811 return 0;
2812}
2813
2815 "\n\t"
2816 "Open the most recently opened blend file, instead of the default startup file.";
2817static int arg_handle_load_last_file(int /*argc*/, const char ** /*argv*/, void *data)
2818{
2819 if (BLI_listbase_is_empty(&G.recent_files)) {
2820 fprintf(stderr, "Warning: no recent files known, opening default startup file instead.\n");
2821 return -1;
2822 }
2823
2824 bContext *C = static_cast<bContext *>(data);
2825 const RecentFile *recent_file = static_cast<const RecentFile *>(G.recent_files.first);
2826 if (!handle_load_file(C, recent_file->filepath, false)) {
2827 return -1;
2828 }
2829 return 0;
2830}
2831
2833{
2835# define CB(a) a##_doc, a
2837# define CB_EX(a, b) a##_doc_##b, a
2839# define CB_ALL(a) (all ? a##_doc_all : a##_doc), a
2840
2841 BuildDefs defs;
2842 build_defs_init(&defs, all);
2843
2844 /* end argument processing after -- */
2845 BLI_args_pass_set(ba, -1);
2846 BLI_args_add(ba, "--", nullptr, CB(arg_handle_arguments_end), nullptr);
2847
2848 /* Pass: Environment Setup
2849 *
2850 * It's important these run before any initialization is done, since they set up
2851 * the environment used to access data-files, which are be used when initializing
2852 * sub-systems such as color management. */
2855 ba, nullptr, "--python-use-system-env", CB(arg_handle_python_use_system_env_set), nullptr);
2856
2857 /* Note that we could add used environment variables too. */
2859 ba, nullptr, "--env-system-datafiles", CB_EX(arg_handle_env_system_set, datafiles), nullptr);
2861 ba, nullptr, "--env-system-scripts", CB_EX(arg_handle_env_system_set, scripts), nullptr);
2863 ba, nullptr, "--env-system-python", CB_EX(arg_handle_env_system_set, python), nullptr);
2864 BLI_args_add(ba,
2865 nullptr,
2866 "--env-system-extensions",
2867 CB_EX(arg_handle_env_system_set, extensions),
2868 nullptr);
2869
2870 BLI_args_add(ba, "-t", "--threads", CB(arg_handle_threads_set), nullptr);
2871
2872 /* Include in the environment pass so it's possible display errors initializing subsystems,
2873 * especially `bpy.appdir` since it's useful to show errors finding paths on startup. */
2874 BLI_args_add(ba, nullptr, "--log", CB(arg_handle_log_set), ba);
2875 BLI_args_add(ba, nullptr, "--log-level", CB(arg_handle_log_level_set), ba);
2876 BLI_args_add(ba, nullptr, "--log-show-source", CB(arg_handle_log_show_source_set), ba);
2877 BLI_args_add(ba, nullptr, "--log-show-backtrace", CB(arg_handle_log_show_backtrace_set), ba);
2878 BLI_args_add(ba, nullptr, "--log-show-memory", CB(arg_handle_log_show_memory_set), ba);
2879 BLI_args_add(ba, nullptr, "--log-file", CB(arg_handle_log_file_set), ba);
2880
2881 /* GPU backend selection should be part of #ARG_PASS_ENVIRONMENT for correct GPU context
2882 * selection for animation player. */
2883 BLI_args_add(ba, nullptr, "--gpu-backend", CB_ALL(arg_handle_gpu_backend_set), nullptr);
2884 BLI_args_add(ba, nullptr, "--gpu-vsync", CB(arg_handle_gpu_vsync_set), nullptr);
2885 if (defs.with_opengl_backend) {
2886 BLI_args_add(ba,
2887 nullptr,
2888 "--gpu-compilation-subprocesses",
2890 nullptr);
2891 }
2892 BLI_args_add(ba, nullptr, "--profile-gpu", CB(arg_handle_profile_gpu_set), nullptr);
2893
2894 /* Pass: Background Mode & Settings
2895 *
2896 * Also and commands that exit after usage. */
2898 BLI_args_add(ba, "-h", "--help", CB(arg_handle_print_help), ba);
2899
2900 /* MS-Windows only. */
2901 BLI_args_add(ba, "/?", nullptr, CB_EX(arg_handle_print_help, win32), ba);
2902
2903 BLI_args_add(ba, "-v", "--version", CB(arg_handle_print_version), nullptr);
2904 BLI_args_add(ba, nullptr, "--log-list-categories", CB(arg_handle_list_clog_cats), nullptr);
2905
2906 BLI_args_add(ba, "-y", "--enable-autoexec", CB_EX(arg_handle_python_set, enable), (void *)true);
2908 ba, "-Y", "--disable-autoexec", CB_EX(arg_handle_python_set, disable), (void *)false);
2909
2911 ba, nullptr, "--offline-mode", CB_EX(arg_handle_internet_allow_set, offline), (void *)false);
2913 ba, nullptr, "--online-mode", CB_EX(arg_handle_internet_allow_set, online), (void *)true);
2914
2916 ba, nullptr, "--disable-crash-handler", CB(arg_handle_crash_handler_disable), nullptr);
2918 ba, nullptr, "--disable-abort-handler", CB(arg_handle_abort_handler_disable), nullptr);
2919
2920 BLI_args_add(ba, "-q", "--quiet", CB(arg_handle_quiet_set), nullptr);
2921 BLI_args_add(ba, "-b", "--background", CB(arg_handle_background_mode_set), nullptr);
2922 /* Command implies background mode (defers execution). */
2923 BLI_args_add(ba, "-c", "--command", CB(arg_handle_command_set), C);
2924
2925 BLI_args_add(ba, nullptr, "--qos", CB(arg_handle_qos_set), nullptr);
2926
2927 BLI_args_add(ba,
2928 nullptr,
2929 "--disable-depsgraph-on-file-load",
2931 nullptr);
2932
2933 BLI_args_add(ba,
2934 nullptr,
2935 "--disable-liboverride-auto-resync",
2937 nullptr);
2938
2939 BLI_args_add(ba, "-a", nullptr, CB(arg_handle_playback_mode), nullptr);
2940
2941 BLI_args_add(ba, "-d", "--debug", CB(arg_handle_debug_mode_set), ba);
2942
2943 if (defs.with_ffmpeg) {
2944 BLI_args_add(ba, nullptr, "--debug-ffmpeg", CB(arg_handle_debug_mode_ffmpeg), nullptr);
2945 }
2946
2947 if (defs.with_freestyle) {
2948 BLI_args_add(ba,
2949 nullptr,
2950 "--debug-freestyle",
2952 (void *)G_DEBUG_FREESTYLE);
2953 }
2954 BLI_args_add(ba,
2955 nullptr,
2956 "--debug-python",
2958 (void *)G_DEBUG_PYTHON);
2959 BLI_args_add(ba,
2960 nullptr,
2961 "--debug-events",
2963 (void *)G_DEBUG_EVENTS);
2964 BLI_args_add(ba,
2965 nullptr,
2966 "--debug-handlers",
2968 (void *)G_DEBUG_HANDLERS);
2970 ba, nullptr, "--debug-wm", CB_EX(arg_handle_debug_mode_generic_set, wm), (void *)G_DEBUG_WM);
2971 if (defs.with_xr_openxr) {
2972 BLI_args_add(ba,
2973 nullptr,
2974 "--debug-xr",
2976 (void *)G_DEBUG_XR);
2977 BLI_args_add(ba,
2978 nullptr,
2979 "--debug-xr-time",
2981 (void *)G_DEBUG_XR_TIME);
2982 }
2983 BLI_args_add(ba,
2984 nullptr,
2985 "--debug-ghost",
2987 (void *)G_DEBUG_GHOST);
2988 BLI_args_add(ba,
2989 nullptr,
2990 "--debug-wintab",
2992 (void *)G_DEBUG_WINTAB);
2993 BLI_args_add(ba, nullptr, "--debug-all", CB(arg_handle_debug_mode_all), nullptr);
2994
2995 BLI_args_add(ba, nullptr, "--debug-io", CB(arg_handle_debug_mode_io), nullptr);
2996
2997 BLI_args_add(ba, nullptr, "--debug-fpe", CB(arg_handle_debug_fpe_set), nullptr);
2998
2999 if (defs.with_libmv) {
3000 BLI_args_add(ba, nullptr, "--debug-libmv", CB(arg_handle_debug_mode_libmv), nullptr);
3001 }
3002 if (defs.with_cycles) {
3003 BLI_args_add(ba, nullptr, "--debug-cycles", CB(arg_handle_debug_mode_cycles), nullptr);
3004 }
3005 BLI_args_add(ba, nullptr, "--debug-memory", CB(arg_handle_debug_mode_memory_set), nullptr);
3006
3007 BLI_args_add(ba, nullptr, "--debug-value", CB(arg_handle_debug_value_set), nullptr);
3008 BLI_args_add(ba,
3009 nullptr,
3010 "--debug-jobs",
3012 (void *)G_DEBUG_JOBS);
3013 BLI_args_add(ba, nullptr, "--debug-gpu", CB(arg_handle_debug_gpu_set), nullptr);
3014 BLI_args_add(ba,
3015 nullptr,
3016 "--debug-gpu-compile-shaders",
3018 nullptr);
3019 if (defs.with_renderdoc) {
3020 BLI_args_add(ba,
3021 nullptr,
3022 "--debug-gpu-scope-capture",
3024 nullptr);
3026 ba, nullptr, "--debug-gpu-renderdoc", CB(arg_handle_debug_gpu_renderdoc_set), nullptr);
3027 }
3028 BLI_args_add(ba,
3029 nullptr,
3030 "--debug-gpu-shader-debug-info",
3032 nullptr);
3033
3034 BLI_args_add(ba,
3035 nullptr,
3036 "--debug-depsgraph",
3038 (void *)G_DEBUG_DEPSGRAPH);
3039 BLI_args_add(ba,
3040 nullptr,
3041 "--debug-depsgraph-build",
3042 CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build),
3043 (void *)G_DEBUG_DEPSGRAPH_BUILD);
3044 BLI_args_add(ba,
3045 nullptr,
3046 "--debug-depsgraph-eval",
3048 (void *)G_DEBUG_DEPSGRAPH_EVAL);
3049 BLI_args_add(ba,
3050 nullptr,
3051 "--debug-depsgraph-tag",
3053 (void *)G_DEBUG_DEPSGRAPH_TAG);
3054 BLI_args_add(ba,
3055 nullptr,
3056 "--debug-depsgraph-time",
3058 (void *)G_DEBUG_DEPSGRAPH_TIME);
3059 BLI_args_add(ba,
3060
3061 nullptr,
3062 "--debug-depsgraph-no-threads",
3063 CB_EX(arg_handle_debug_mode_generic_set, depsgraph_no_threads),
3065 BLI_args_add(ba,
3066 nullptr,
3067 "--debug-depsgraph-pretty",
3068 CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty),
3069 (void *)G_DEBUG_DEPSGRAPH_PRETTY);
3070 BLI_args_add(ba,
3071 nullptr,
3072 "--debug-depsgraph-uid",
3074 (void *)G_DEBUG_DEPSGRAPH_UID);
3075 BLI_args_add(ba,
3076 nullptr,
3077 "--debug-gpu-force-workarounds",
3078 CB_EX(arg_handle_debug_mode_generic_set, gpu_force_workarounds),
3080 if (defs.with_vulkan_backend) {
3081 BLI_args_add(ba,
3082 nullptr,
3083 "--debug-gpu-vulkan-local-read",
3084 CB_EX(arg_handle_debug_mode_generic_set, gpu_force_vulkan_local_read),
3086 }
3087 BLI_args_add(ba, nullptr, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), nullptr);
3088
3089 BLI_args_add(ba, nullptr, "--verbose", CB(arg_handle_verbosity_set), nullptr);
3090
3091 BLI_args_add(ba, nullptr, "--app-template", CB(arg_handle_app_template), nullptr);
3092 BLI_args_add(ba, nullptr, "--factory-startup", CB(arg_handle_factory_startup_set), nullptr);
3094 ba, nullptr, "--enable-event-simulate", CB(arg_handle_enable_event_simulate), nullptr);
3095
3096 /* Pass: Custom Window Stuff. */
3098 BLI_args_add(ba, "-p", "--window-geometry", CB(arg_handle_window_geometry), nullptr);
3099 BLI_args_add(ba, "-w", "--window-border", CB(arg_handle_window_border), nullptr);
3100 BLI_args_add(ba, "-W", "--window-fullscreen", CB(arg_handle_window_fullscreen), nullptr);
3101 BLI_args_add(ba, "-M", "--window-maximized", CB(arg_handle_window_maximized), nullptr);
3102 BLI_args_add(ba, nullptr, "--no-window-frame", CB(arg_handle_no_window_frame), nullptr);
3103 BLI_args_add(ba, nullptr, "--no-window-focus", CB(arg_handle_no_window_focus), nullptr);
3104 BLI_args_add(ba, "-con", "--start-console", CB(arg_handle_start_with_console), nullptr);
3105 BLI_args_add(ba, "-r", "--register", CB(arg_handle_register_extension), nullptr);
3106 BLI_args_add(ba, nullptr, "--register-allusers", CB(arg_handle_register_extension_all), nullptr);
3107 BLI_args_add(ba, nullptr, "--unregister", CB(arg_handle_unregister_extension), nullptr);
3109 ba, nullptr, "--unregister-allusers", CB(arg_handle_unregister_extension_all), nullptr);
3110 BLI_args_add(ba, nullptr, "--no-native-pixels", CB(arg_handle_native_pixels_set), ba);
3111
3112 /* Pass: Disabling Things & Forcing Settings. */
3114 BLI_args_add_case(ba, "-noaudio", 1, nullptr, 0, CB(arg_handle_audio_disable), nullptr);
3115 BLI_args_add_case(ba, "-setaudio", 1, nullptr, 0, CB(arg_handle_audio_set), nullptr);
3116
3117 /* Pass: Processing Arguments. */
3118 /* NOTE: Use #WM_exit for these callbacks, not `exit()`
3119 * so temporary files are properly cleaned up. */
3121 BLI_args_add(ba, "-f", "--render-frame", CB(arg_handle_render_frame), C);
3122 BLI_args_add(ba, "-a", "--render-anim", CB(arg_handle_render_animation), C);
3123 BLI_args_add(ba, "-S", "--scene", CB(arg_handle_scene_set), C);
3124 BLI_args_add(ba, "-s", "--frame-start", CB(arg_handle_frame_start_set), C);
3125 BLI_args_add(ba, "-e", "--frame-end", CB(arg_handle_frame_end_set), C);
3126 BLI_args_add(ba, "-j", "--frame-jump", CB(arg_handle_frame_skip_set), C);
3127 BLI_args_add(ba, "-P", "--python", CB(arg_handle_python_file_run), C);
3128 BLI_args_add(ba, nullptr, "--python-text", CB(arg_handle_python_text_run), C);
3129 BLI_args_add(ba, nullptr, "--python-expr", CB(arg_handle_python_expr_run), C);
3130 BLI_args_add(ba, nullptr, "--python-console", CB(arg_handle_python_console_run), C);
3131 BLI_args_add(ba, nullptr, "--python-exit-code", CB(arg_handle_python_exit_code_set), nullptr);
3132 BLI_args_add(ba, nullptr, "--addons", CB(arg_handle_addons_set), C);
3133
3134 BLI_args_add(ba, "-o", "--render-output", CB(arg_handle_output_set), C);
3135 BLI_args_add(ba, "-E", "--engine", CB(arg_handle_engine_set), C);
3136
3137 BLI_args_add(ba, "-F", "--render-format", CB(arg_handle_image_type_set), C);
3138 BLI_args_add(ba, "-x", "--use-extension", CB(arg_handle_extension_set), C);
3139
3140 BLI_args_add(ba, nullptr, "--open-last", CB(arg_handle_load_last_file), C);
3141
3142# undef CB
3143# undef CB_EX
3144# undef CB_ALL
3145
3146# ifdef WITH_PYTHON
3147 /* Use for Python to extract help text (Python can't call directly - bad-level call). */
3149# else
3150 /* Quiet unused function warning. */
3152# endif
3153}
3154
3156
3157#endif /* !WITH_PYTHON_MODULE */
#define BLENDER_STARTUP_FILE
@ BLENDER_SYSTEM_DATAFILES
@ BLENDER_SYSTEM_EXTENSIONS
@ BLENDER_SYSTEM_PYTHON
@ BLENDER_SYSTEM_SCRIPTS
Blender util stuff.
void BKE_blender_atexit()
Definition blender.cc:515
Blender CLI Generic --command Support.
int BKE_blender_cli_command_exec(struct bContext *C, const char *id, const int argc, const char **argv)
void BKE_blender_cli_command_print_help()
const char * BKE_blender_version_string(void)
Definition blender.cc:146
bool BKE_blendfile_extension_check(const char *str)
Definition blendfile.cc:86
wmWindow * CTX_wm_window(const bContext *C)
void CTX_data_scene_set(bContext *C, Scene *scene)
Scene * CTX_data_scene(const bContext *C)
void CTX_wm_window_set(bContext *C, wmWindow *win)
Main * CTX_data_main(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
@ G_FLAG_INTERNET_OVERRIDE_PREF_ONLINE
@ G_FLAG_SCRIPT_OVERRIDE_PREF
@ G_FLAG_EVENT_SIMULATE
@ G_FLAG_INTERNET_OVERRIDE_PREF_OFFLINE
@ G_FLAG_USERPREF_NO_SAVE_ON_EXIT
@ G_FLAG_SCRIPT_AUTOEXEC
@ G_FLAG_INTERNET_ALLOW
@ G_DEBUG_DEPSGRAPH_UID
@ G_DEBUG
@ G_DEBUG_GPU
@ G_DEBUG_GHOST
@ G_DEBUG_XR
@ G_DEBUG_HANDLERS
@ G_DEBUG_FREESTYLE
@ G_DEBUG_IO
@ G_DEBUG_JOBS
@ G_DEBUG_GPU_FORCE_WORKAROUNDS
@ G_DEBUG_GPU_SHADER_DEBUG_INFO
@ G_DEBUG_DEPSGRAPH_PRETTY
@ G_DEBUG_XR_TIME
@ G_DEBUG_WINTAB
@ G_DEBUG_DEPSGRAPH_TIME
@ G_DEBUG_DEPSGRAPH
@ G_DEBUG_DEPSGRAPH_EVAL
@ G_DEBUG_GPU_FORCE_VULKAN_LOCAL_READ
@ G_DEBUG_GPU_RENDERDOC
@ G_DEBUG_DEPSGRAPH_NO_THREADS
@ G_DEBUG_GPU_COMPILE_SHADERS
@ G_DEBUG_DEPSGRAPH_TAG
@ G_DEBUG_WM
@ G_DEBUG_EVENTS
@ G_DEBUG_PYTHON
@ G_DEBUG_DEPSGRAPH_BUILD
#define G_MAIN
#define G_FLAG_INTERNET_OVERRIDE_PREF_ANY
#define G_DEBUG_ALL
@ G_BACKGROUND_NO_DEPSGRAPH
@ G_LIBOVERRIDE_NO_AUTO_RESYNC
char BKE_imtype_from_arg(const char *imtype_arg)
void BKE_image_format_set(ImageFormatData *imf, ID *owner_id, const char imtype)
ID * BKE_libblock_find_name(Main *bmain, short type, const char *name, const std::optional< Library * > lib=std::nullopt) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition lib_id.cc:1710
@ RPT_PRINT
Definition BKE_report.hh:55
@ RPT_STORE
Definition BKE_report.hh:56
@ RPT_WARNING
Definition BKE_report.hh:38
void BKE_reports_free(ReportList *reports)
Definition report.cc:97
void BKE_report_print_level_set(ReportList *reports, eReportType level)
Definition report.cc:265
void BKE_reports_init(ReportList *reports, int flag)
Definition report.cc:82
Scene * BKE_scene_set_name(Main *bmain, const char *name)
Definition scene.cc:2056
void BKE_sound_force_device(const char *device)
A general argument parsing module.
void BLI_args_destroy(struct bArgs *ba)
Definition BLI_args.cc:144
void BLI_args_print_other_doc(struct bArgs *ba)
Definition BLI_args.cc:317
void BLI_args_print_arg_doc(struct bArgs *ba, const char *arg)
Definition BLI_args.cc:287
void BLI_args_add_case(struct bArgs *ba, const char *short_arg, int short_case, const char *long_arg, int long_case, const char *doc, BA_ArgCallback cb, void *data)
Definition BLI_args.cc:242
void BLI_args_pass_set(struct bArgs *ba, int current_pass)
Definition BLI_args.cc:166
void BLI_args_add(struct bArgs *ba, const char *short_arg, const char *long_arg, const char *doc, BA_ArgCallback cb, void *data)
Definition BLI_args.cc:262
int(*)(int argc, const char **argv, void *data) BA_ArgCallback
Definition BLI_args.h:24
void BLI_args_print_fn_set(struct bArgs *ba, ATTR_PRINTF_FORMAT(2, 0) bArgPrintFn print_fn, void *user_data)
bool BLI_args_has_other_doc(const struct bArgs *ba)
struct bArgs * BLI_args_create(int argc, const char **argv)
Definition BLI_args.cc:124
void BLI_args_print(const struct bArgs *ba)
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define ATTR_PRINTF_FORMAT(format_param, dots_param)
A dynamically sized string ADT.
char * BLI_dynstr_get_cstring(const DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition BLI_dynstr.cc:37
void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args) ATTR_PRINTF_FORMAT(2
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:360
FILE * BLI_fopen(const char *filepath, const char *mode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_kdtree_nd_ free(KDTree *tree)
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:586
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void void void BLI_mempool_set_memory_debug()
#define FILE_MAX
void BLI_setenv(const char *env, const char *val) ATTR_NONNULL(1)
int BLI_path_canonicalize_native(char *path, int path_maxncpy)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:693
size_t BLI_snprintf(char *__restrict dst, size_t dst_maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
#define STRNCPY_UTF8(dst, src)
unsigned char uchar
void BLI_system_backtrace(FILE *fp)
Definition system.cc:103
void BLI_system_num_threads_override_set(int num)
Definition threads.cc:289
int BLI_system_thread_count(void)
Definition threads.cc:253
#define BLENDER_MAX_THREADS
Definition BLI_threads.h:16
#define CLAMP(a, b, c)
#define UNPACK4(a)
#define UNUSED_VARS(...)
#define STRINGIFY(x)
#define STRINGIFY_ARG(x)
#define POINTER_AS_INT(i)
#define UNLIKELY(x)
#define ELEM(...)
#define STRCASEEQ(a, b)
#define STREQ(a, b)
Compatibility-like things for windows.
bool BLI_windows_unregister_blend_extension(bool all_users)
QoSMode
void BLI_windows_process_set_qos(QoSMode qos_mode, QoSPrecedence qos_precedence)
bool BLI_windows_register_blend_extension(bool all_users)
void BPY_python_use_system_env()
char *(* BPY_python_app_help_text_fn)(bool all)
Definition bpy_app.cc:712
bool bool BPY_run_text(bContext *C, Text *text, ReportList *reports, bool do_jump) ATTR_NONNULL(1
bool BPY_run_filepath(bContext *C, const char *filepath, ReportList *reports) ATTR_NONNULL(1
bool BPY_run_string_eval(bContext *C, const char *imports[], const char *expr)
bool BPY_run_string_exec(bContext *C, const char *imports[], const char *expr)
void CLG_type_filter_exclude(const char *type_match, int type_match_len)
Definition clog.cc:925
bool CLG_quiet_get()
Definition clog.cc:945
void CLG_output_set(void *file_handle)
Definition clog.cc:885
void CLG_output_use_memory_set(int value)
Definition clog.cc:905
void CLG_error_fn_set(void(*error_fn)(void *file_handle))
Definition clog.cc:910
void CLG_level_set(CLG_Level level)
Definition clog.cc:935
void CLG_output_use_source_set(int value)
Definition clog.cc:890
void CLG_backtrace_fn_set(void(*fatal_fn)(void *file_handle))
Definition clog.cc:920
void CLG_logref_list_all(void(*callback)(const char *identifier, void *user_data), void *user_data)
Definition clog.cc:969
void CLG_type_filter_include(const char *type_match, int type_match_len)
Definition clog.cc:930
#define CLG_LEVEL_LEN
Definition CLG_log.h:66
CLG_Level
Definition CLG_log.h:52
@ CLG_LEVEL_ERROR
Definition CLG_log.h:56
@ CLG_LEVEL_DEBUG
Definition CLG_log.h:62
@ CLG_LEVEL_INFO
Definition CLG_log.h:60
@ CLG_LEVEL_FATAL
Definition CLG_log.h:54
@ CLG_LEVEL_WARN
Definition CLG_log.h:58
@ CLG_LEVEL_TRACE
Definition CLG_log.h:64
void CLG_quiet_set(bool quiet)
Definition clog.cc:940
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1118
@ ID_TXT
#define MINAFRAME
struct Scene Scene
@ R_IMF_IMTYPE_INVALID
@ R_EXTENSION
#define MAXFRAME
struct wmWindowManager wmWindowManager
struct wmWindow wmWindow
void GPU_compilation_subprocess_override_set(int count)
void GPU_backend_vsync_set_override(int vsync)
void GPU_backend_type_selection_set_override(GPUBackendType backend_type)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
BMesh const char void * data
char build_type[]
Definition bpy_app.cc:73
char build_cflags[]
Definition bpy_app.cc:74
char build_hash[]
Definition bpy_app.cc:70
char build_commit_date[]
Definition bpy_app.cc:68
char build_commit_time[]
Definition bpy_app.cc:69
char build_linkflags[]
Definition bpy_app.cc:76
char build_system[]
Definition bpy_app.cc:77
char build_branch[]
Definition bpy_app.cc:71
char build_date[]
Definition bpy_app.cc:65
char build_cxxflags[]
Definition bpy_app.cc:75
char build_time[]
Definition bpy_app.cc:66
char build_platform[]
Definition bpy_app.cc:72
BPy_StructRNA * depsgraph
ApplicationState app_state
Definition creator.cc:126
static int arg_handle_python_exit_code_set(int argc, const char **argv, void *)
static int arg_handle_command_set(int argc, const char **argv, void *data)
static int arg_handle_debug_gpu_renderdoc_set(int, const char **, void *)
static const char arg_handle_engine_set_doc[]
static const char arg_handle_debug_mode_io_doc[]
static const char arg_handle_debug_mode_generic_set_doc_xr[]
static const char arg_handle_factory_startup_set_doc[]
static int arg_handle_unregister_extension(int argc, const char **argv, void *data)
static int arg_handle_debug_gpu_set(int, const char **, void *)
static int arg_handle_log_set(int argc, const char **argv, void *)
static void add_log_render_filter()
static int arg_handle_render_frame(int argc, const char **argv, void *data)
static int arg_handle_python_use_system_env_set(int, const char **, void *)
static int arg_handle_window_border(int, const char **, void *)
static int arg_handle_audio_set(int argc, const char **argv, void *)
static const char * parse_int_range_sep_search(const char *str, const char *str_end_test)
static const char arg_handle_scene_set_doc[]
static const char arg_handle_debug_mode_generic_set_doc_jobs[]
static const char arg_handle_frame_start_set_doc[]
static int arg_handle_log_file_set(int argc, const char **argv, void *)
static bool arg_handle_extension_registration(const bool do_register, const bool all_users)
static bool parse_int_relative(const char *str, const char *str_end_test, int pos, int neg, int *r_value, const char **r_err_msg)
static int arg_handle_debug_gpu_compile_shaders_set(int, const char **, void *)
static const char arg_handle_output_set_doc[]
static int arg_handle_python_set(int, const char **, void *data)
static int arg_handle_playback_mode(int argc, const char **argv, void *)
static const char arg_handle_render_animation_doc[]
#define PRINT(...)
static int arg_handle_python_console_run(int, const char **, void *data)
static const char arg_handle_debug_mode_generic_set_doc_wm[]
static const char arg_handle_env_system_set_doc_datafiles[]
static const char arg_handle_verbosity_set_doc[]
static const char arg_handle_env_system_set_doc_python[]
static void print_version_short()
static const char arg_handle_print_version_doc[]
static int arg_handle_print_help(int, const char **, void *data)
static const char arg_handle_debug_value_set_doc[]
static const char arg_handle_debug_mode_generic_set_doc_ghost[]
static int arg_handle_python_text_run(int argc, const char **argv, void *data)
static int arg_handle_output_set(int argc, const char **argv, void *data)
static const char arg_handle_internet_allow_set_doc_offline[]
static int(* parse_int_range_relative_clamp_n(const char *str, int pos, int neg, int min, int max, int *r_value_len, const char **r_err_msg))[2]
static bool main_arg_deferred_is_set()
static int arg_handle_debug_mode_all(int, const char **, void *)
#define CB_EX(a, b)
static int arg_handle_unregister_extension_all(int argc, const char **argv, void *data)
static bool parse_int_range_relative_clamp(const char *str, const char *str_end_range, const char *str_end_test, int pos, int neg, int min, int max, int r_value_range[2], const char **r_err_msg)
static int arg_handle_debug_mode_memory_set(int, const char **, void *)
static const char arg_handle_log_set_doc[]
static int arg_handle_env_system_set(int argc, const char **argv, void *)
static bool parse_int_range_relative(const char *str, const char *str_end_range, const char *str_end_test, int pos, int neg, int r_value_range[2], const char **r_err_msg)
static const char arg_handle_native_pixels_set_doc[]
static const char arg_handle_debug_gpu_set_doc[]
static int arg_handle_enable_event_simulate(int, const char **, void *)
static const char arg_handle_debug_mode_generic_set_doc_handlers[]
static int arg_handle_verbosity_set(int argc, const char **argv, void *)
static const char arg_handle_no_window_frame_doc[]
static const char arg_handle_log_level_set_doc[]
#define printf
static const char arg_handle_python_console_run_doc[]
static const char arg_handle_window_fullscreen_doc[]
static const char arg_handle_debug_mode_set_doc[]
static bool parse_int_clamp(const char *str, const char *str_end_test, int min, int max, int *r_value, const char **r_err_msg)
void main_arg_deferred_free()
static const char arg_handle_frame_end_set_doc[]
static const char arg_handle_register_extension_doc[]
static int arg_handle_gpu_compilation_subprocesses_set(int argc, const char **argv, void *)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_no_threads[]
static int arg_handle_extension_set(int argc, const char **argv, void *data)
static const char arg_handle_debug_mode_generic_set_doc_gpu_force_vulkan_local_read[]
static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
static const char arg_handle_debug_mode_generic_set_doc_python[]
static int arg_handle_profile_gpu_set(int, const char **, void *)
static int arg_handle_register_extension_all(int argc, const char **argv, void *data)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_time[]
static int arg_handle_quiet_set(int, const char **, void *)
static const char arg_handle_python_exit_code_set_doc[]
static int arg_handle_window_fullscreen(int, const char **, void *)
#define CB_ALL(a)
static int arg_handle_debug_gpu_scope_capture_set(int argc, const char **argv, void *)
static const char arg_handle_python_expr_run_doc[]
static const char arg_handle_frame_skip_set_doc[]
static const char arg_handle_debug_gpu_shader_debug_info_set_doc[]
static const char arg_handle_python_set_doc_disable[]
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_eval[]
#define PY_ENABLE_AUTO
#define CB(a)
static void main_arg_deferred_setup(BA_ArgCallback func, int argc, const char **argv, void *data)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_build[]
static const char arg_handle_env_system_set_doc_scripts[]
static const char arg_handle_window_maximized_doc[]
static int arg_handle_render_animation(int, const char **, void *data)
static const char arg_handle_window_border_doc[]
static int arg_handle_native_pixels_set(int, const char **, void *)
static const char arg_handle_python_text_run_doc[]
static int arg_handle_debug_mode_cycles(int, const char **, void *)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_uid[]
static int arg_handle_scene_set(int argc, const char **argv, void *data)
static const char arg_handle_image_type_set_doc[]
static void clog_abort_on_error_callback(void *fp)
static const char arg_handle_render_frame_doc[]
static const char arg_handle_print_help_doc_win32[]
static const char arg_handle_debug_mode_libmv_doc[]
static const char arg_handle_audio_disable_doc[]
static const char arg_handle_gpu_backend_set_doc_all[]
static const char arg_handle_env_system_set_doc_extensions[]
static void print_version_full()
static bool parse_int(const char *str, const char *str_end_test, int *r_value, const char **r_err_msg)
static const char arg_handle_start_with_console_doc[]
static int arg_handle_debug_mode_libmv(int, const char **, void *)
static int arg_handle_debug_exit_on_error(int, const char **, void *)
static const char arg_handle_gpu_backend_set_doc[]
static int arg_handle_window_maximized(int, const char **, void *)
static void build_defs_init(BuildDefs *build_defs, bool force_all)
static int arg_handle_threads_set(int argc, const char **argv, void *)
static const char arg_handle_addons_set_doc[]
static int arg_handle_addons_set(int argc, const char **argv, void *data)
static int arg_handle_log_show_memory_set(int, const char **, void *)
static int arg_handle_gpu_vsync_set(int argc, const char **argv, void *)
static int arg_handle_debug_mode_ffmpeg(int, const char **, void *)
static int arg_handle_crash_handler_disable(int, const char **, void *)
static const char arg_handle_debug_gpu_renderdoc_set_doc[]
static int arg_handle_log_show_source_set(int, const char **, void *)
static int arg_handle_image_type_set(int argc, const char **argv, void *data)
static bool handle_load_file(bContext *C, const char *filepath_arg, const bool load_empty_file)
static const char arg_handle_print_help_doc[]
static int arg_handle_debug_mode_io(int, const char **, void *)
static const char arg_handle_debug_mode_generic_set_doc_xr_time[]
static int arg_handle_list_clog_cats(int, const char **, void *)
static const char arg_handle_list_clog_cats_doc[]
static void main_arg_deferred_exit_code_set(int exit_code)
static int arg_handle_arguments_end(int, const char **, void *)
static int arg_handle_log_show_backtrace_set(int, const char **, void *)
static int arg_handle_app_template(int argc, const char **argv, void *)
static const char arg_handle_quiet_set_doc[]
static const char arg_handle_extension_set_doc[]
static const char arg_handle_disable_liboverride_auto_resync_doc[]
static bool parse_int_relative_clamp(const char *str, const char *str_end_test, int pos, int neg, int min, int max, int *r_value, const char **r_err_msg)
static const char arg_handle_debug_mode_memory_set_doc[]
static const char arg_handle_background_mode_set_doc[]
static int arg_handle_window_geometry(int argc, const char **argv, void *)
static int arg_handle_log_level_set(int argc, const char **argv, void *)
static const char arg_handle_qos_set_doc[]
static char * main_args_help_as_string(bool all)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_tag[]
static void print_help(bArgs *ba, bool all)
static const char arg_handle_register_extension_all_doc[]
static int arg_handle_audio_disable(int, const char **, void *)
static const char arg_handle_log_show_backtrace_set_doc[]
static void background_mode_set()
static const char arg_handle_enable_event_simulate_doc[]
static bool parse_int_strict_range(const char *str, const char *str_end_test, const int min, const int max, int *r_value, const char **r_err_msg)
static int arg_handle_gpu_backend_set(int argc, const char **argv, void *)
static int arg_handle_abort_handler_disable(int, const char **, void *)
static int arg_handle_factory_startup_set(int, const char **, void *)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph[]
static int arg_handle_register_extension(int argc, const char **argv, void *data)
static int arg_handle_disable_depsgraph_on_file_load(int, const char **, void *)
static int arg_handle_debug_gpu_shader_debug_info_set(int, const char **, void *)
static const char arg_handle_unregister_extension_doc[]
static const char arg_handle_debug_gpu_scope_capture_set_doc[]
static const char arg_handle_gpu_vsync_set_doc[]
static const char arg_handle_debug_fpe_set_doc[]
static int arg_handle_load_last_file(int, const char **, void *data)
static int arg_handle_python_file_run(int argc, const char **argv, void *data)
static const char arg_handle_debug_mode_generic_set_doc_depsgraph_pretty[]
static const char arg_handle_gpu_compilation_subprocesses_set_doc[]
static int arg_handle_frame_end_set(int argc, const char **argv, void *data)
static const char arg_handle_debug_gpu_compile_shaders_set_doc[]
static void help_print_ds_fn(void *ds_v, const char *format, va_list args)
static int arg_handle_no_window_frame(int, const char **, void *)
int main_args_handle_load_file(int, const char **argv, void *data)
static const char arg_handle_log_file_set_doc[]
static const char arg_handle_window_geometry_doc[]
static const char arg_handle_python_file_run_doc[]
static const char arg_handle_python_set_doc_enable[]
#define PY_DISABLE_AUTO
static const char arg_handle_arguments_end_doc[]
static const char arg_handle_load_last_file_doc[]
static const char arg_handle_debug_mode_generic_set_doc_freestyle[]
static int arg_handle_debug_mode_generic_set(int, const char **, void *data)
static const char arg_handle_crash_handler_disable_doc[]
static const char arg_handle_app_template_doc[]
static const char arg_handle_threads_set_doc[]
static const char arg_handle_python_use_system_env_set_doc[]
static int arg_handle_disable_liboverride_auto_resync(int, const char **, void *)
static const char arg_handle_debug_mode_ffmpeg_doc[]
static int arg_handle_print_version(int, const char **, void *)
static int arg_handle_qos_set(int argc, const char **argv, void *)
static int arg_handle_debug_value_set(int argc, const char **argv, void *)
static int arg_handle_background_mode_set(int, const char **, void *)
static const char arg_handle_abort_handler_disable_doc[]
static const char arg_handle_debug_exit_on_error_doc[]
static const char arg_handle_unregister_extension_all_doc[]
static const char arg_handle_playback_mode_doc[]
static const char arg_handle_debug_mode_generic_set_doc_events[]
static const char arg_handle_internet_allow_set_doc_online[]
static const char arg_handle_command_set_doc[]
static const char arg_handle_log_show_memory_set_doc[]
static const char arg_handle_profile_gpu_set_doc[]
static const char arg_handle_debug_mode_generic_set_doc_wintab[]
static const char arg_handle_debug_mode_generic_set_doc_gpu_force_workarounds[]
int main_arg_deferred_handle()
void main_args_setup(bContext *C, bArgs *ba, bool all)
static int arg_handle_frame_skip_set(int argc, const char **argv, void *data)
static const char arg_handle_disable_depsgraph_on_file_load_doc[]
static int arg_handle_start_with_console(int, const char **, void *)
static int arg_handle_frame_start_set(int argc, const char **argv, void *data)
static int arg_handle_debug_mode_set(int, const char **, void *data)
static int arg_handle_internet_allow_set(int, const char **, void *data)
static const char arg_handle_log_show_source_set_doc[]
static const char arg_handle_no_window_focus_doc[]
static const char arg_handle_debug_mode_cycles_doc[]
static int arg_handle_debug_fpe_set(int, const char **, void *)
static int arg_handle_engine_set(int argc, const char **argv, void *data)
static const char arg_handle_debug_mode_all_doc[]
static int arg_handle_no_window_focus(int, const char **, void *)
static const char arg_handle_audio_set_doc[]
@ ARG_PASS_ENVIRONMENT
@ ARG_PASS_SETTINGS_FORCE
@ ARG_PASS_SETTINGS_GUI
@ ARG_PASS_FINAL
@ ARG_PASS_SETTINGS
void main_signal_setup_fpe(void)
#define offsetof(t, d)
#define str(s)
uint pos
bool all(VecOp< bool, D >) RET
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
ListBase R_engines
void MEM_enable_fail_on_memleak()
format
void libmv_setLoggingVerbosity(int verbosity)
Definition logging.cc:42
void libmv_startDebugLogging(void)
Definition logging.cc:32
void(* MEM_set_memory_debug)(void)
Definition mallocn.cc:69
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define G(x, y, z)
#define min(a, b)
Definition sort.cc:36
Render * RE_NewSceneRender(const Scene *scene)
void RE_RenderAnim(Render *re, Main *bmain, Scene *scene, ViewLayer *single_layer, Object *camera_override, int sfra, int efra, int tfra)
void RE_SetReports(Render *re, ReportList *reports)
bool with_opencolorio
bool with_vulkan_backend
bool with_opengl_backend
bool with_libmv
bool with_renderdoc
bool with_ffmpeg
bool with_cycles
bool with_xr_openxr
bool with_freestyle
void * first
char * filepath
Definition WM_types.hh:1451
char engine[32]
struct ImageFormatData im_format
char pic[1024]
struct RenderData r
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251
uint len
void WM_reports_from_reports_move(wmWindowManager *wm, ReportList *reports)
bool WM_file_read(bContext *C, const char *filepath, const bool use_scripts_autoexec_check, ReportList *reports)
Definition wm_files.cc:1054
void WM_init_state_app_template_set(const char *app_template)
Definition wm_files.cc:1195
char app_template[64]
Definition wm_files.cc:1191
void WM_exit(bContext *C, const int exit_code)
void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_actions)
void WM_init_state_start_with_console_set(bool value)
bool WM_platform_associate_set(bool do_register, bool all_users, char **r_error_msg)
int WM_main_playanim(int argc, const char **argv)
void WM_window_set_active_scene(Main *bmain, bContext *C, wmWindow *win, Scene *scene)
void WM_init_state_maximized_set()
void WM_init_native_pixels(bool do_it)
void WM_init_state_size_set(int stax, int stay, int sizx, int sizy)
void WM_init_window_frame_set(bool do_it)
void WM_init_state_fullscreen_set()
void WM_init_state_normal_set()
void WM_init_window_focus_set(bool do_it)