Blender V4.5
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"
39# include "BKE_blender_version.h"
40# include "BKE_blendfile.hh"
41# include "BKE_context.hh"
42
43# include "BKE_global.hh"
44# include "BKE_image_format.hh"
45# include "BKE_lib_id.hh"
46# include "BKE_main.hh"
47# include "BKE_report.hh"
48# include "BKE_scene.hh"
49# include "BKE_sound.h"
50
51# include "GPU_context.hh"
52# ifdef WITH_OPENGL_BACKEND
53# include "GPU_capabilities.hh"
55# endif
56
57# ifdef WITH_PYTHON
58# include "BPY_extern_python.hh"
59# include "BPY_extern_run.hh"
60# endif
61
62# include "RE_engine.h"
63# include "RE_pipeline.h"
64
65# include "WM_api.hh"
66
67# ifdef WITH_LIBMV
68# include "libmv-capi.h"
69# endif
70
71# ifdef WITH_CYCLES_LOGGING
72# include "CCL_api.h"
73# endif
74
75# include "DEG_depsgraph.hh"
76
77# include "WM_types.hh"
78
79# include "creator_intern.h" /* Own include. */
80
81/* -------------------------------------------------------------------- */
84
100
101static void build_defs_init(BuildDefs *build_defs, bool force_all)
102{
103 if (force_all) {
104 bool *var_end = (bool *)(build_defs + 1);
105 for (bool *var = (bool *)build_defs; var < var_end; var++) {
106 *var = true;
107 }
108 return;
109 }
110
111 memset(build_defs, 0x0, sizeof(*build_defs));
112
113# ifdef WIN32
114 build_defs->win32 = true;
115# endif
116# ifdef WITH_CYCLES
117 build_defs->with_cycles = true;
118# endif
119# ifdef WITH_CYCLES_LOGGING
120 build_defs->with_cycles_logging = true;
121# endif
122# ifdef WITH_FFMPEG
123 build_defs->with_ffmpeg = true;
124# endif
125# ifdef WITH_FREESTYLE
126 build_defs->with_freestyle = true;
127# endif
128# ifdef WITH_LIBMV
129 build_defs->with_libmv = true;
130# endif
131# ifdef WITH_OPENCOLORIO
132 build_defs->with_opencolorio = true;
133# endif
134# ifdef WITH_RENDERDOC
135 build_defs->with_renderdoc = true;
136# endif
137# ifdef WITH_XR_OPENXR
138 build_defs->with_xr_openxr = true;
139# endif
140}
141
143
144/* -------------------------------------------------------------------- */
147
148static bool parse_int_relative(const char *str,
149 const char *str_end_test,
150 int pos,
151 int neg,
152 int *r_value,
153 const char **r_err_msg)
154{
155 char *str_end = nullptr;
156 long value;
157
158 errno = 0;
159
160 switch (*str) {
161 case '+':
162 value = pos + strtol(str + 1, &str_end, 10);
163 break;
164 case '-':
165 value = (neg - strtol(str + 1, &str_end, 10)) + 1;
166 break;
167 default:
168 value = strtol(str, &str_end, 10);
169 break;
170 }
171
172 if (*str_end != '\0' && (str_end != str_end_test)) {
173 static const char *msg = "not a number";
174 *r_err_msg = msg;
175 return false;
176 }
177 if ((errno == ERANGE) || ((value < INT_MIN) || (value > INT_MAX))) {
178 static const char *msg = "exceeds range";
179 *r_err_msg = msg;
180 return false;
181 }
182 *r_value = int(value);
183 return true;
184}
185
186static const char *parse_int_range_sep_search(const char *str, const char *str_end_test)
187{
188 const char *str_end_range = nullptr;
189 if (str_end_test) {
190 str_end_range = static_cast<const char *>(memchr(str, '.', (str_end_test - str) - 1));
191 if (str_end_range && (str_end_range[1] != '.')) {
192 str_end_range = nullptr;
193 }
194 }
195 else {
196 str_end_range = strstr(str, "..");
197 if (str_end_range && (str_end_range[2] == '\0')) {
198 str_end_range = nullptr;
199 }
200 }
201 return str_end_range;
202}
203
209static bool parse_int_range_relative(const char *str,
210 const char *str_end_range,
211 const char *str_end_test,
212 int pos,
213 int neg,
214 int r_value_range[2],
215 const char **r_err_msg)
216{
217 if (parse_int_relative(str, str_end_range, pos, neg, &r_value_range[0], r_err_msg) &&
218 parse_int_relative(str_end_range + 2, str_end_test, pos, neg, &r_value_range[1], r_err_msg))
219 {
220 return true;
221 }
222 return false;
223}
224
225static bool parse_int_relative_clamp(const char *str,
226 const char *str_end_test,
227 int pos,
228 int neg,
229 int min,
230 int max,
231 int *r_value,
232 const char **r_err_msg)
233{
234 if (parse_int_relative(str, str_end_test, pos, neg, r_value, r_err_msg)) {
235 CLAMP(*r_value, min, max);
236 return true;
237 }
238 return false;
239}
240
241static bool parse_int_range_relative_clamp(const char *str,
242 const char *str_end_range,
243 const char *str_end_test,
244 int pos,
245 int neg,
246 int min,
247 int max,
248 int r_value_range[2],
249 const char **r_err_msg)
250{
252 str, str_end_range, str_end_test, pos, neg, r_value_range, r_err_msg))
253 {
254 CLAMP(r_value_range[0], min, max);
255 CLAMP(r_value_range[1], min, max);
256 return true;
257 }
258 return false;
259}
260
264static bool parse_int_strict_range(const char *str,
265 const char *str_end_test,
266 const int min,
267 const int max,
268 int *r_value,
269 const char **r_err_msg)
270{
271 char *str_end = nullptr;
272 long value;
273
274 errno = 0;
275 value = strtol(str, &str_end, 10);
276
277 if (*str_end != '\0' && (str_end != str_end_test)) {
278 static const char *msg = "not a number";
279 *r_err_msg = msg;
280 return false;
281 }
282 if ((errno == ERANGE) || ((value < min) || (value > max))) {
283 static const char *msg = "exceeds range";
284 *r_err_msg = msg;
285 return false;
286 }
287 *r_value = int(value);
288 return true;
289}
290
291static bool parse_int(const char *str,
292 const char *str_end_test,
293 int *r_value,
294 const char **r_err_msg)
295{
296 return parse_int_strict_range(str, str_end_test, INT_MIN, INT_MAX, r_value, r_err_msg);
297}
298
299static bool parse_int_clamp(const char *str,
300 const char *str_end_test,
301 int min,
302 int max,
303 int *r_value,
304 const char **r_err_msg)
305{
306 if (parse_int(str, str_end_test, r_value, r_err_msg)) {
307 CLAMP(*r_value, min, max);
308 return true;
309 }
310 return false;
311}
312
313# if 0
318static int *parse_int_relative_clamp_n(
319 const char *str, int pos, int neg, int min, int max, int *r_value_len, const char **r_err_msg)
320{
321 const char sep = ',';
322 int len = 1;
323 for (int i = 0; str[i]; i++) {
324 if (str[i] == sep) {
325 len++;
326 }
327 }
328
329 int *values = MEM_malloc_arrayN<int>(size_t(len), __func__);
330 int i = 0;
331 while (true) {
332 const char *str_end = strchr(str, sep);
333 if (ELEM(*str, sep, '\0')) {
334 static const char *msg = "incorrect comma use";
335 *r_err_msg = msg;
336 goto fail;
337 }
338 else if (parse_int_relative_clamp(str, str_end, pos, neg, min, max, &values[i], r_err_msg)) {
339 i++;
340 }
341 else {
342 goto fail; /* Error message already set. */
343 }
344
345 if (str_end) { /* Next. */
346 str = str_end + 1;
347 }
348 else { /* Finished. */
349 break;
350 }
351 }
352
353 *r_value_len = i;
354 return values;
355
356fail:
357 MEM_freeN(values);
358 return nullptr;
359}
360
361# endif
362
369static int (*parse_int_range_relative_clamp_n(const char *str,
370 int pos,
371 int neg,
372 int min,
373 int max,
374 int *r_value_len,
375 const char **r_err_msg))[2]
376{
377 const char sep = ',';
378 int len = 1;
379 for (int i = 0; str[i]; i++) {
380 if (str[i] == sep) {
381 len++;
382 }
383 }
384
385 int(*values)[2] = MEM_malloc_arrayN<int[2]>(size_t(len), __func__);
386 int i = 0;
387 while (true) {
388 const char *str_end_range;
389 const char *str_end = strchr(str, sep);
390 if (ELEM(*str, sep, '\0')) {
391 static const char *msg = "incorrect comma use";
392 *r_err_msg = msg;
393 goto fail;
394 }
395 else if ((str_end_range = parse_int_range_sep_search(str, str_end)) ?
397 str, str_end_range, str_end, pos, neg, min, max, values[i], r_err_msg) :
399 str, str_end, pos, neg, min, max, &values[i][0], r_err_msg))
400 {
401 if (str_end_range == nullptr) {
402 values[i][1] = values[i][0];
403 }
404 i++;
405 }
406 else {
407 goto fail; /* Error message already set. */
408 }
409
410 if (str_end) { /* Next. */
411 str = str_end + 1;
412 }
413 else { /* Finished. */
414 break;
415 }
416 }
417
418 *r_value_len = i;
419 return values;
420
421fail:
422 MEM_freeN(values);
423 return nullptr;
424}
425
427
428/* -------------------------------------------------------------------- */
435
436/* When the deferred argument is handled on Windows the `argv` will have been freed,
437 * see `USE_WIN32_UNICODE_ARGS` in `creator.cc`. */
438
439# ifdef WIN32
440static char **argv_duplicate(const char **argv, int argc)
441{
442 char **argv_copy = MEM_malloc_arrayN<char *>(size_t(argc), __func__);
443 for (int i = 0; i < argc; i++) {
444 argv_copy[i] = BLI_strdup(argv[i]);
445 }
446 return argv_copy;
447}
448
449static void argv_free(char **argv, int argc)
450{
451 for (int i = 0; i < argc; i++) {
452 MEM_freeN(argv[i]);
453 }
454 MEM_freeN(argv);
455}
456# endif /* !WIN32 */
457
466
468{
469 return app_state.main_arg_deferred != nullptr;
470}
471
472static void main_arg_deferred_setup(BA_ArgCallback func, int argc, const char **argv, void *data)
473{
474 BLI_assert(app_state.main_arg_deferred == nullptr);
476 d->func = func;
477 d->argc = argc;
478 d->argv = argv;
479 d->data = data;
480 d->exit_code = 0;
481# ifdef WIN32
482 d->argv = const_cast<const char **>(argv_duplicate(d->argv, d->argc));
483# endif
484 app_state.main_arg_deferred = d;
485}
486
488{
489 BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
490 app_state.main_arg_deferred = nullptr;
491# ifdef WIN32
492 argv_free(const_cast<char **>(d->argv), d->argc);
493# endif
494 MEM_freeN(d);
495}
496
497static void main_arg_deferred_exit_code_set(int exit_code)
498{
499 BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
500 BLI_assert(d != nullptr);
501 d->exit_code = exit_code;
502}
503
505{
506 BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
507 d->func(d->argc, d->argv, d->data);
508 return d->exit_code;
509}
510
512
513/* -------------------------------------------------------------------- */
516
517# ifdef WITH_PYTHON
518
519struct BlendePyContextStore {
520 wmWindowManager *wm;
521 Scene *scene;
522 wmWindow *win;
523 bool has_win;
524};
525
526static void arg_py_context_backup(bContext *C, BlendePyContextStore *c_py)
527{
528 c_py->wm = CTX_wm_manager(C);
529 c_py->scene = CTX_data_scene(C);
530 c_py->has_win = c_py->wm && !BLI_listbase_is_empty(&c_py->wm->windows);
531 if (c_py->has_win) {
532 c_py->win = CTX_wm_window(C);
533 CTX_wm_window_set(C, static_cast<wmWindow *>(c_py->wm->windows.first));
534 }
535 else {
536 /* NOTE: this should never happen, although it may be possible when loading
537 * `.blend` files without windowing data. Whatever the case, it shouldn't crash,
538 * although typical scripts that accesses the context is not expected to work usefully. */
539 c_py->win = nullptr;
540 fprintf(stderr, "Python script running with missing context data.\n");
541 }
542}
543
544static void arg_py_context_restore(bContext *C, BlendePyContextStore *c_py)
545{
546 /* Script may load a file, check old data is valid before using. */
547 if (c_py->has_win) {
548 if ((c_py->win == nullptr) || ((BLI_findindex(&G_MAIN->wm, c_py->wm) != -1) &&
549 (BLI_findindex(&c_py->wm->windows, c_py->win) != -1)))
550 {
551 CTX_wm_window_set(C, c_py->win);
552 }
553 }
554
555 if ((c_py->scene == nullptr) || BLI_findindex(&G_MAIN->scenes, c_py->scene) != -1) {
556 CTX_data_scene_set(C, c_py->scene);
557 }
558}
559
560/* Macro for context setup/reset. */
561# define BPY_CTX_SETUP(_cmd) \
562 { \
563 BlendePyContextStore py_c; \
564 arg_py_context_backup(C, &py_c); \
565 { \
566 _cmd; \
567 } \
568 arg_py_context_restore(C, &py_c); \
569 } \
570 ((void)0)
571
572# endif /* WITH_PYTHON */
573
575
576/* -------------------------------------------------------------------- */
589
591{
592 printf("Blender %s\n", BKE_blender_version_string());
593# ifdef BUILD_DATE
594 printf("\tbuild date: %s\n", build_date);
595 printf("\tbuild time: %s\n", build_time);
596 printf("\tbuild commit date: %s\n", build_commit_date);
597 printf("\tbuild commit time: %s\n", build_commit_time);
598 printf("\tbuild hash: %s\n", build_hash);
599 printf("\tbuild branch: %s\n", build_branch);
600 printf("\tbuild platform: %s\n", build_platform);
601 printf("\tbuild type: %s\n", build_type);
602 printf("\tbuild c flags: %s\n", build_cflags);
603 printf("\tbuild c++ flags: %s\n", build_cxxflags);
604 printf("\tbuild link flags: %s\n", build_linkflags);
605 printf("\tbuild system: %s\n", build_system);
606# endif
607}
608
610{
611# ifdef BUILD_DATE
612 /* NOTE: We include built time since sometimes we need to tell broken from
613 * working built of the same hash. */
614 printf("Blender %s (hash %s built %s %s)\n",
618 build_time);
619# else
620 printf("Blender %s\n", BKE_blender_version_string());
621# endif
622}
623
624static const char arg_handle_print_version_doc[] =
625 "\n\t"
626 "Print Blender version and exit.";
627static int arg_handle_print_version(int /*argc*/, const char ** /*argv*/, void * /*data*/)
628{
630 exit(EXIT_SUCCESS);
632 return 0;
633}
634
635static void print_help(bArgs *ba, bool all)
636{
637 BuildDefs defs;
638 build_defs_init(&defs, all);
639
640/* All printing must go via `PRINT` macro. */
641# define printf __ERROR__
642
643# define PRINT(...) BLI_args_printf(ba, __VA_ARGS__)
644
645 PRINT("Blender %s\n", BKE_blender_version_string());
646 PRINT("Usage: blender [args ...] [file] [args ...]\n");
647 PRINT("\n");
648
649 PRINT("Render Options:\n");
650 BLI_args_print_arg_doc(ba, "--background");
651 BLI_args_print_arg_doc(ba, "--render-anim");
652 BLI_args_print_arg_doc(ba, "--scene");
653 BLI_args_print_arg_doc(ba, "--render-frame");
654 BLI_args_print_arg_doc(ba, "--frame-start");
655 BLI_args_print_arg_doc(ba, "--frame-end");
656 BLI_args_print_arg_doc(ba, "--frame-jump");
657 BLI_args_print_arg_doc(ba, "--render-output");
658 BLI_args_print_arg_doc(ba, "--engine");
659 BLI_args_print_arg_doc(ba, "--threads");
660
661 if (defs.with_cycles) {
662 PRINT("Cycles Render Options:\n");
663 PRINT("\tCycles add-on options must be specified following a double dash.\n");
664 PRINT("\n");
665 PRINT("--cycles-device <device>\n");
666 PRINT("\tSet the device used for rendering.\n");
667 PRINT("\tValid options are: 'CPU' 'CUDA' 'OPTIX' 'HIP' 'ONEAPI' 'METAL'.\n");
668 PRINT("\n");
669 PRINT("\tAppend +CPU to a GPU device to render on both CPU and GPU.\n");
670 PRINT("\n");
671 PRINT("\tExample:\n");
672 PRINT("\t# blender -b file.blend -f 20 -- --cycles-device OPTIX\n");
673 PRINT("--cycles-print-stats\n");
674 PRINT("\tLog statistics about render memory and time usage.\n");
675 }
676
677 PRINT("\n");
678 PRINT("Format Options:\n");
679 BLI_args_print_arg_doc(ba, "--render-format");
680 BLI_args_print_arg_doc(ba, "--use-extension");
681
682 PRINT("\n");
683 PRINT("Animation Playback Options:\n");
684 BLI_args_print_arg_doc(ba, "-a");
685
686 PRINT("\n");
687 PRINT("Window Options:\n");
688 BLI_args_print_arg_doc(ba, "--window-border");
689 BLI_args_print_arg_doc(ba, "--window-fullscreen");
690 BLI_args_print_arg_doc(ba, "--window-geometry");
691 BLI_args_print_arg_doc(ba, "--window-maximized");
692 BLI_args_print_arg_doc(ba, "--start-console");
693 BLI_args_print_arg_doc(ba, "--no-native-pixels");
694 BLI_args_print_arg_doc(ba, "--no-window-focus");
695
696 PRINT("\n");
697 PRINT("Python Options:\n");
698 BLI_args_print_arg_doc(ba, "--enable-autoexec");
699 BLI_args_print_arg_doc(ba, "--disable-autoexec");
700
701 PRINT("\n");
702
703 BLI_args_print_arg_doc(ba, "--python");
704 BLI_args_print_arg_doc(ba, "--python-text");
705 BLI_args_print_arg_doc(ba, "--python-expr");
706 BLI_args_print_arg_doc(ba, "--python-console");
707 BLI_args_print_arg_doc(ba, "--python-exit-code");
708 BLI_args_print_arg_doc(ba, "--python-use-system-env");
709 BLI_args_print_arg_doc(ba, "--addons");
710
711 PRINT("\n");
712 PRINT("Network Options:\n");
713 BLI_args_print_arg_doc(ba, "--online-mode");
714 BLI_args_print_arg_doc(ba, "--offline-mode");
715
716 PRINT("\n");
717 PRINT("Logging Options:\n");
718 BLI_args_print_arg_doc(ba, "--log");
719 BLI_args_print_arg_doc(ba, "--log-level");
720 BLI_args_print_arg_doc(ba, "--log-show-basename");
721 BLI_args_print_arg_doc(ba, "--log-show-backtrace");
722 BLI_args_print_arg_doc(ba, "--log-show-timestamp");
723 BLI_args_print_arg_doc(ba, "--log-file");
724
725 PRINT("\n");
726 PRINT("Debug Options:\n");
727 BLI_args_print_arg_doc(ba, "--debug");
728 BLI_args_print_arg_doc(ba, "--debug-value");
729
730 PRINT("\n");
731 BLI_args_print_arg_doc(ba, "--debug-events");
732 if (defs.with_ffmpeg) {
733 BLI_args_print_arg_doc(ba, "--debug-ffmpeg");
734 }
735 BLI_args_print_arg_doc(ba, "--debug-handlers");
736 if (defs.with_libmv) {
737 BLI_args_print_arg_doc(ba, "--debug-libmv");
738 }
739 if (defs.with_cycles_logging) {
740 BLI_args_print_arg_doc(ba, "--debug-cycles");
741 }
742 BLI_args_print_arg_doc(ba, "--debug-memory");
743 BLI_args_print_arg_doc(ba, "--debug-jobs");
744 BLI_args_print_arg_doc(ba, "--debug-python");
745 BLI_args_print_arg_doc(ba, "--debug-depsgraph");
746 BLI_args_print_arg_doc(ba, "--debug-depsgraph-eval");
747 BLI_args_print_arg_doc(ba, "--debug-depsgraph-build");
748 BLI_args_print_arg_doc(ba, "--debug-depsgraph-tag");
749 BLI_args_print_arg_doc(ba, "--debug-depsgraph-no-threads");
750 BLI_args_print_arg_doc(ba, "--debug-depsgraph-time");
751 BLI_args_print_arg_doc(ba, "--debug-depsgraph-pretty");
752 BLI_args_print_arg_doc(ba, "--debug-depsgraph-uid");
753 BLI_args_print_arg_doc(ba, "--debug-ghost");
754 BLI_args_print_arg_doc(ba, "--debug-wintab");
755 BLI_args_print_arg_doc(ba, "--debug-gpu");
756 BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds");
757 BLI_args_print_arg_doc(ba, "--debug-gpu-compile-shaders");
758 if (defs.with_renderdoc) {
759 BLI_args_print_arg_doc(ba, "--debug-gpu-scope-capture");
760 BLI_args_print_arg_doc(ba, "--debug-gpu-renderdoc");
761 }
762# ifdef WITH_VULKAN_BACKEND
763 BLI_args_print_arg_doc(ba, "--debug-gpu-vulkan-local-read");
764# endif
765 BLI_args_print_arg_doc(ba, "--debug-wm");
766 if (defs.with_xr_openxr) {
767 BLI_args_print_arg_doc(ba, "--debug-xr");
768 BLI_args_print_arg_doc(ba, "--debug-xr-time");
769 }
770 BLI_args_print_arg_doc(ba, "--debug-all");
771 BLI_args_print_arg_doc(ba, "--debug-io");
772
773 PRINT("\n");
774 BLI_args_print_arg_doc(ba, "--debug-fpe");
775 BLI_args_print_arg_doc(ba, "--debug-exit-on-error");
776 if (defs.with_freestyle) {
777 BLI_args_print_arg_doc(ba, "--debug-freestyle");
778 }
779 BLI_args_print_arg_doc(ba, "--disable-crash-handler");
780 BLI_args_print_arg_doc(ba, "--disable-abort-handler");
781
782 BLI_args_print_arg_doc(ba, "--verbose");
783 BLI_args_print_arg_doc(ba, "--quiet");
784
785 PRINT("\n");
786 PRINT("GPU Options:\n");
787 BLI_args_print_arg_doc(ba, "--gpu-backend");
788# ifdef WITH_OPENGL_BACKEND
789 BLI_args_print_arg_doc(ba, "--gpu-compilation-subprocesses");
790# endif
791 BLI_args_print_arg_doc(ba, "--profile-gpu");
792
793 PRINT("\n");
794 PRINT("Misc Options:\n");
795 BLI_args_print_arg_doc(ba, "--open-last");
796 BLI_args_print_arg_doc(ba, "--app-template");
797 BLI_args_print_arg_doc(ba, "--factory-startup");
798 BLI_args_print_arg_doc(ba, "--enable-event-simulate");
799 PRINT("\n");
800 BLI_args_print_arg_doc(ba, "--env-system-datafiles");
801 BLI_args_print_arg_doc(ba, "--env-system-scripts");
802 BLI_args_print_arg_doc(ba, "--env-system-extensions");
803 BLI_args_print_arg_doc(ba, "--env-system-python");
804 PRINT("\n");
805 BLI_args_print_arg_doc(ba, "-noaudio");
806 BLI_args_print_arg_doc(ba, "-setaudio");
807 PRINT("\n");
808 BLI_args_print_arg_doc(ba, "--command");
809
810 PRINT("\n");
811
812 BLI_args_print_arg_doc(ba, "--help");
813 BLI_args_print_arg_doc(ba, "/?");
814
815 /* WIN32 only (ignored for non-WIN32). */
816 BLI_args_print_arg_doc(ba, "--register");
817 BLI_args_print_arg_doc(ba, "--register-allusers");
818 BLI_args_print_arg_doc(ba, "--unregister");
819 BLI_args_print_arg_doc(ba, "--unregister-allusers");
820
821 BLI_args_print_arg_doc(ba, "--version");
822
823 BLI_args_print_arg_doc(ba, "--");
824
825 // PRINT("\n");
826 // PRINT("Experimental Features:\n");
827
828 /* Other options _must_ be last (anything not handled will show here).
829 *
830 * Note that it's good practice for this to remain empty,
831 * nevertheless print if any exist. */
832 if (BLI_args_has_other_doc(ba)) {
833 PRINT("\n");
834 PRINT("Other Options:\n");
836 }
837
838 PRINT("\n");
839 PRINT("Argument Parsing:\n");
840 PRINT("\tArguments must be separated by white space, eg:\n");
841 PRINT("\t# blender -ba test.blend\n");
842 PRINT("\t...will exit since '-ba' is an unknown argument.\n");
843 PRINT("\n");
844
845 PRINT("Argument Order:\n");
846 PRINT("\tArguments are executed in the order they are given. eg:\n");
847 PRINT("\t# blender --background test.blend --render-frame 1 --render-output \"/tmp\"\n");
848 PRINT(
849 "\t...will not render to '/tmp' because '--render-frame 1' renders before the output path "
850 "is set.\n");
851 PRINT("\t# blender --background --render-output /tmp test.blend --render-frame 1\n");
852 PRINT(
853 "\t...will not render to '/tmp' because loading the blend-file overwrites the render output "
854 "that was set.\n");
855 PRINT("\t# blender --background test.blend --render-output /tmp --render-frame 1\n");
856 PRINT("\t...works as expected.\n");
857 PRINT("\n");
858
859 PRINT("Environment Variables:\n");
860 PRINT(" $BLENDER_USER_RESOURCES Replace default directory of all user files.\n");
861 PRINT(" Other 'BLENDER_USER_*' variables override when set.\n");
862 PRINT(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
863 PRINT(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
864 PRINT(" $BLENDER_USER_EXTENSIONS Directory for user extensions.\n");
865 PRINT(" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
866 PRINT("\n");
867 PRINT(" $BLENDER_SYSTEM_RESOURCES Replace default directory of all bundled resource files.\n");
868 PRINT(" $BLENDER_SYSTEM_SCRIPTS Directories to add extra scripts.\n");
869 PRINT(" $BLENDER_SYSTEM_EXTENSIONS Directory for system extensions repository.\n");
870 PRINT(" $BLENDER_SYSTEM_DATAFILES Directory to replace bundled datafiles.\n");
871 PRINT(" $BLENDER_SYSTEM_PYTHON Directory to replace bundled Python libraries.\n");
872 PRINT(" $BLENDER_CUSTOM_SPLASH Full path to an image that replaces the splash screen.\n");
873 PRINT(
874 " $BLENDER_CUSTOM_SPLASH_BANNER Full path to an image to overlay on the splash screen.\n");
875
876 if (defs.with_opencolorio) {
877 PRINT(" $OCIO Path to override the OpenColorIO configuration file.\n");
878 }
879 if (defs.win32 || all) {
880 PRINT(" $TEMP Store temporary files here (MS-Windows).\n");
881 }
882 if (!defs.win32 || all) {
883 /* NOTE: while `TMP` checked, don't include here as it's non-standard & may be removed. */
884 PRINT(" $TMPDIR Store temporary files here (UNIX Systems).\n");
885 }
886 PRINT(
887 " The path must reference an existing directory "
888 "or it will be ignored.\n");
889
890# undef printf
891# undef PRINT
892}
893
895static void help_print_ds_fn(void *ds_v, const char *format, va_list args)
896{
897 DynStr *ds = static_cast<DynStr *>(ds_v);
898 BLI_dynstr_vappendf(ds, format, args);
899}
900
902{
903 DynStr *ds = BLI_dynstr_new();
904 {
905 bArgs *ba = BLI_args_create(0, nullptr);
906 main_args_setup(nullptr, ba, all);
908 print_help(ba, all);
910 }
911 char *buf = BLI_dynstr_get_cstring(ds);
912 BLI_dynstr_free(ds);
913 return buf;
914}
915
916static const char arg_handle_print_help_doc[] =
917 "\n\t"
918 "Print this help text and exit.";
920 "\n\t"
921 "Print this help text and exit (Windows only).";
922static int arg_handle_print_help(int /*argc*/, const char ** /*argv*/, void *data)
923{
924 bArgs *ba = (bArgs *)data;
925
926 print_help(ba, false);
927
928 exit(EXIT_SUCCESS);
930
931 return 0;
932}
933
934static const char arg_handle_arguments_end_doc[] =
935 "\n\t"
936 "End option processing, following arguments passed unchanged. Access via Python's "
937 "'sys.argv'.";
938static int arg_handle_arguments_end(int /*argc*/, const char ** /*argv*/, void * /*data*/)
939{
940 return -1;
941}
942
943/* Only to give help message. */
944# ifdef WITH_PYTHON_SECURITY /* Default. */
945# define PY_ENABLE_AUTO ""
946# define PY_DISABLE_AUTO ", (default)"
947# else
948# define PY_ENABLE_AUTO ", (default, non-standard compilation option)"
949# define PY_DISABLE_AUTO ""
950# endif
951
953 "\n\t"
954 "Enable automatic Python script execution" PY_ENABLE_AUTO ".";
956 "\n\t"
957 "Disable automatic Python script execution "
958 "(Python-drivers & startup scripts)" PY_DISABLE_AUTO ".";
959# undef PY_ENABLE_AUTO
960# undef PY_DISABLE_AUTO
961
962static int arg_handle_python_set(int /*argc*/, const char ** /*argv*/, void *data)
963{
964 if (bool(data)) {
966 }
967 else {
969 }
971 return 0;
972}
973
975 "\n\t"
976 "Allow internet access, overriding the preference.";
978 "\n\t"
979 "Disallow internet access, overriding the preference.";
980
981static int arg_handle_internet_allow_set(int /*argc*/, const char ** /*argv*/, void *data)
982{
984 if (bool(data)) {
987 }
988 else {
991 }
992 return 0;
993}
994
996 "\n\t"
997 "Disable the crash handler.";
998static int arg_handle_crash_handler_disable(int /*argc*/, const char ** /*argv*/, void * /*data*/)
999{
1000 app_state.signal.use_crash_handler = false;
1001 return 0;
1002}
1003
1005 "\n\t"
1006 "Disable the abort handler.";
1007static int arg_handle_abort_handler_disable(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1008{
1009 app_state.signal.use_abort_handler = false;
1010 return 0;
1011}
1012
1013static void clog_abort_on_error_callback(void *fp)
1014{
1015 BLI_system_backtrace(static_cast<FILE *>(fp));
1016 fflush(static_cast<FILE *>(fp));
1017 abort();
1018}
1019
1021 "\n\t"
1022 "Immediately exit when internal errors are detected.";
1023static int arg_handle_debug_exit_on_error(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1024{
1027 return 0;
1028}
1029
1030static const char arg_handle_quiet_set_doc[] =
1031 "\n\t"
1032 "Suppress status printing (warnings & errors are still printed).";
1033static int arg_handle_quiet_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1034{
1035 G.quiet = true;
1036 return 0;
1037}
1038
1041{
1042 G.background = true;
1043
1044 /* Background Mode Defaults:
1045 *
1046 * In general background mode should strive to match the behavior of running
1047 * Blender inside a graphical session, any exception to this should have a well
1048 * justified reason and be noted in the doc-string. */
1049
1050 /* NOTE(@ideasman42): While there is no requirement for sound to be disabled in background-mode,
1051 * the use case for playing audio in background mode is enough of a special-case
1052 * that users who wish to do this can explicitly enable audio in background mode.
1053 * While the down sides for connecting to an audio device aren't terrible they include:
1054 * - Listing Blender as an active application which may output audio.
1055 * - Unnecessary overhead running an operation in background mode or ...
1056 * - Having to remember to include `-noaudio` with batch operations.
1057 * - A quiet but audible click when Blender starts & configures its audio device.
1058 */
1059 BKE_sound_force_device("None");
1060}
1061
1063 "\n"
1064 "\tRun in background (often used for UI-less rendering).\n"
1065 "\n"
1066 "\tThe audio device is disabled in background-mode by default\n"
1067 "\tand can be re-enabled by passing in '-setaudio Default' afterwards.";
1068static int arg_handle_background_mode_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1069{
1070 if (!G.quiet) {
1072 }
1074 return 0;
1075}
1076
1077static const char arg_handle_command_set_doc[] =
1078 "<command>\n"
1079 "\tRun a command which consumes all remaining arguments.\n"
1080 "\tUse '-c help' to list all other commands.\n"
1081 "\tPass '--help' after the command to see its help text.\n"
1082 "\n"
1083 "\tThis implies '--background' mode.";
1084static int arg_handle_command_set(int argc, const char **argv, void *data)
1085{
1086 if (!main_arg_deferred_is_set()) {
1087 if (argc < 2) {
1088 fprintf(stderr, "%s requires at least one argument\n", argv[0]);
1089 exit(EXIT_FAILURE);
1091 }
1092 /* Application "info" messages get in the way of command line output, suppress them. */
1093 G.quiet = true;
1094
1096
1098 }
1099 else {
1100 bContext *C = static_cast<bContext *>(data);
1101 const char *id = argv[1];
1102 int exit_code;
1103 if (STREQ(id, "help")) {
1105 exit_code = EXIT_SUCCESS;
1106 }
1107 else {
1108 exit_code = BKE_blender_cli_command_exec(C, id, argc - 2, argv + 2);
1109 }
1111 }
1112
1113 /* Consume remaining arguments. */
1114 return argc - 1;
1115}
1116
1118 "\n"
1119 "\tBackground mode: Do not systematically build and evaluate ViewLayers' dependency graphs\n"
1120 "\twhen loading a blend-file in background mode ('-b' or '-c' options).\n"
1121 "\n"
1122 "\tScripts requiring evaluated data then need to explicitly ensure that\n"
1123 "\tan evaluated depsgraph is available\n"
1124 "\t(e.g. by calling 'depsgraph = context.evaluated_depsgraph_get()').\n"
1125 "\n"
1126 "\tNOTE: this is a temporary option, in the future depsgraph will never be\n"
1127 "\tautomatically generated on file load in background mode.";
1129 const char ** /*argv*/,
1130 void * /*data*/)
1131{
1132 G.fileflags |= G_BACKGROUND_NO_DEPSGRAPH;
1133 return 0;
1134}
1135
1137 "\n"
1138 "\tDo not perform library override automatic resync when loading a new blend-file.\n"
1139 "\n"
1140 "\tNOTE: this is an alternative way to get the same effect as when setting the\n"
1141 "\t'No Override Auto Resync' User Preferences Debug option.";
1143 const char ** /*argv*/,
1144 void * /*data*/)
1145{
1146 G.fileflags |= G_LIBOVERRIDE_NO_AUTO_RESYNC;
1147 return 0;
1148}
1149
1150static const char arg_handle_log_level_set_doc[] =
1151 "<level>\n"
1152 "\tSet the logging verbosity level (higher for more details) defaults to 1,\n"
1153 "\tuse -1 to log all levels.";
1154static int arg_handle_log_level_set(int argc, const char **argv, void * /*data*/)
1155{
1156 const char *arg_id = "--log-level";
1157 if (argc > 1) {
1158 const char *err_msg = nullptr;
1159 if (!parse_int_clamp(argv[1], nullptr, -1, INT_MAX, &G.log.level, &err_msg)) {
1160 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1161 }
1162 else {
1163 if (G.log.level == -1) {
1164 G.log.level = INT_MAX;
1165 }
1166 CLG_level_set(G.log.level);
1167 }
1168 return 1;
1169 }
1170 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
1171 return 0;
1172}
1173
1175 "\n\t"
1176 "Only show file name in output (not the leading path).";
1177static int arg_handle_log_show_basename_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1178{
1180 return 0;
1181}
1182
1184 "\n\t"
1185 "Show a back trace for each log message (debug builds only).";
1186static int arg_handle_log_show_backtrace_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1187{
1188 /* Ensure types don't become incompatible. */
1189 void (*fn)(FILE *fp) = BLI_system_backtrace;
1190 CLG_backtrace_fn_set((void (*)(void *))fn);
1191 return 0;
1192}
1193
1195 "\n\t"
1196 "Show a timestamp for each log message in seconds since start.";
1197static int arg_handle_log_show_timestamp_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1198{
1200 return 0;
1201}
1202
1203static const char arg_handle_log_file_set_doc[] =
1204 "<filepath>\n"
1205 "\tSet a file to output the log to.";
1206static int arg_handle_log_file_set(int argc, const char **argv, void * /*data*/)
1207{
1208 const char *arg_id = "--log-file";
1209 if (argc > 1) {
1210 errno = 0;
1211 FILE *fp = BLI_fopen(argv[1], "w");
1212 if (fp == nullptr) {
1213 const char *err_msg = errno ? strerror(errno) : "unknown";
1214 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1215 }
1216 else {
1217 if (UNLIKELY(G.log.file != nullptr)) {
1218 fclose(static_cast<FILE *>(G.log.file));
1219 }
1220 G.log.file = fp;
1221 CLG_output_set(G.log.file);
1222 }
1223 return 1;
1224 }
1225 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
1226 return 0;
1227}
1228
1229static const char arg_handle_log_set_doc[] =
1230 "<match>\n"
1231 "\tEnable logging categories, taking a single comma separated argument.\n"
1232 "\tMultiple categories can be matched using a '.*' suffix,\n"
1233 "\tso '--log \"wm.*\"' logs every kind of window-manager message.\n"
1234 "\tSub-string can be matched using a '*' prefix and suffix,\n"
1235 "\tso '--log \"*undo*\"' logs every kind of undo-related message.\n"
1236 "\tUse \"^\" prefix to ignore, so '--log \"*,^wm.operator.*\"' logs all except for "
1237 "'wm.operators.*'\n"
1238 "\tUse \"*\" to log everything.";
1239static int arg_handle_log_set(int argc, const char **argv, void * /*data*/)
1240{
1241 const char *arg_id = "--log";
1242 if (argc > 1) {
1243 const char *str_step = argv[1];
1244 while (*str_step) {
1245 const char *str_step_end = strchr(str_step, ',');
1246 int str_step_len = str_step_end ? (str_step_end - str_step) : strlen(str_step);
1247
1248 if (str_step[0] == '^') {
1249 CLG_type_filter_exclude(str_step + 1, str_step_len - 1);
1250 }
1251 else {
1252 CLG_type_filter_include(str_step, str_step_len);
1253 }
1254
1255 if (str_step_end) {
1256 /* Typically only be one, but don't fail on multiple. */
1257 while (*str_step_end == ',') {
1258 str_step_end++;
1259 }
1260 str_step = str_step_end;
1261 }
1262 else {
1263 break;
1264 }
1265 }
1266 return 1;
1267 }
1268 fprintf(stderr, "\nError: '%s' no args given.\n", arg_id);
1269 return 0;
1270}
1271
1273 "\n"
1274 "\tTurn debugging on.\n"
1275 "\n"
1276 "\t* Enables memory error detection\n"
1277 "\t* Disables mouse grab (to interact with a debugger in some cases)\n"
1278 "\t* Keeps Python's 'sys.stdin' rather than setting it to None";
1279static int arg_handle_debug_mode_set(int /*argc*/, const char ** /*argv*/, void *data)
1280{
1281 G.debug |= G_DEBUG;
1282 printf("Blender %s\n", BKE_blender_version_string());
1284# ifndef NDEBUG
1286# endif
1287
1288# ifdef WITH_BUILDINFO
1289 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
1290# endif
1291
1292 BLI_args_print(static_cast<bArgs *>(data));
1293 return 0;
1294}
1295
1297 "\n\t"
1298 "Enable debug messages from FFmpeg library.";
1300 "\n\t"
1301 "Enable debug messages for Freestyle.";
1303 "\n\t"
1304 "Enable debug messages for Python.";
1306 "\n\t"
1307 "Enable debug messages for the event system.";
1309 "\n\t"
1310 "Enable debug messages for event handling.";
1312 "\n\t"
1313 "Enable debug messages for the window manager, shows all operators in search, shows "
1314 "keymap errors.";
1316 "\n\t"
1317 "Enable debug messages for Ghost (Linux only).";
1319 "\n\t"
1320 "Enable debug messages for Wintab.";
1322 "\n\t"
1323 "Enable debug messages for virtual reality contexts.\n"
1324 "\tEnables the OpenXR API validation layer, (OpenXR) debug messages and general information "
1325 "prints.";
1327 "\n\t"
1328 "Enable debug messages for virtual reality frame rendering times.";
1330 "\n\t"
1331 "Enable time profiling for background jobs.";
1333 "\n\t"
1334 "Enable all debug messages from dependency graph.";
1336 "\n\t"
1337 "Enable debug messages from dependency graph related on graph construction.";
1339 "\n\t"
1340 "Enable debug messages from dependency graph related on tagging.";
1342 "\n\t"
1343 "Enable debug messages from dependency graph related on timing.";
1345 "\n\t"
1346 "Enable debug messages from dependency graph related on evaluation.";
1348 "\n\t"
1349 "Switch dependency graph to a single threaded evaluation.";
1351 "\n\t"
1352 "Enable colors for dependency graph debug messages.";
1354 "\n\t"
1355 "Verify validness of session-wide identifiers assigned to ID data-blocks.";
1357 "\n\t"
1358 "Enable workarounds for typical GPU issues and disable all GPU extensions.";
1359# ifdef WITH_VULKAN_BACKEND
1360static const char arg_handle_debug_mode_generic_set_doc_gpu_force_vulkan_local_read[] =
1361 "\n\t"
1362 "Force Vulkan dynamic rendering local read when supported by device.";
1363# endif
1364
1365static int arg_handle_debug_mode_generic_set(int /*argc*/, const char ** /*argv*/, void *data)
1366{
1367 G.debug |= POINTER_AS_INT(data);
1368 return 0;
1369}
1370
1371static const char arg_handle_debug_mode_io_doc[] =
1372 "\n\t"
1373 "Enable debug messages for I/O (Collada, ...).";
1374static int arg_handle_debug_mode_io(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1375{
1376 G.debug |= G_DEBUG_IO;
1377 return 0;
1378}
1379
1381 "\n\t"
1382 "Enable all debug messages.";
1383static int arg_handle_debug_mode_all(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1384{
1385 G.debug |= G_DEBUG_ALL;
1386# ifdef WITH_LIBMV
1388# endif
1389# ifdef WITH_CYCLES_LOGGING
1391# endif
1392 return 0;
1393}
1394
1396 "\n\t"
1397 "Enable debug messages from libmv library.";
1398static int arg_handle_debug_mode_libmv(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1399{
1400# ifdef WITH_LIBMV
1402# endif
1403 return 0;
1404}
1405
1407 "\n\t"
1408 "Enable debug messages from Cycles.";
1409static int arg_handle_debug_mode_cycles(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1410{
1411# ifdef WITH_CYCLES_LOGGING
1413# endif
1414 return 0;
1415}
1416
1418 "\n\t"
1419 "Enable fully guarded memory allocation and debugging.";
1420static int arg_handle_debug_mode_memory_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1421{
1423 return 0;
1424}
1425
1427 "<value>\n"
1428 "\tSet debug value of <value> on startup.";
1429static int arg_handle_debug_value_set(int argc, const char **argv, void * /*data*/)
1430{
1431 const char *arg_id = "--debug-value";
1432 if (argc > 1) {
1433 const char *err_msg = nullptr;
1434 int value;
1435 if (!parse_int(argv[1], nullptr, &value, &err_msg)) {
1436 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1437 return 1;
1438 }
1439
1440 G.debug_value = value;
1441
1442 return 1;
1443 }
1444 fprintf(stderr, "\nError: you must specify debug value to set.\n");
1445 return 0;
1446}
1447
1448static const char arg_handle_debug_gpu_set_doc[] =
1449 "\n"
1450 "\tEnable GPU debug context and information for OpenGL 4.3+.";
1451static int arg_handle_debug_gpu_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1452{
1453 /* Also enable logging because that how gl errors are reported. */
1454 const char *gpu_filter = "gpu.*";
1455 CLG_type_filter_include(gpu_filter, strlen(gpu_filter));
1456 G.debug |= G_DEBUG_GPU;
1457 return 0;
1458}
1459
1461 "\n"
1462 "\tCompile all statically defined shaders to test platform compatibility.";
1464 const char ** /*argv*/,
1465 void * /*data*/)
1466{
1468 return 0;
1469}
1470
1472 "\n"
1473 "\tCapture the GPU commands issued inside the give scope name.";
1474static int arg_handle_debug_gpu_scope_capture_set(int argc, const char **argv, void * /*data*/)
1475{
1476 if (argc > 1) {
1477 STRNCPY(G.gpu_debug_scope_name, argv[1]);
1478 return 1;
1479 }
1480 fprintf(stderr, "\nError: you must specify a scope name to capture.\n");
1481 return 0;
1482}
1483
1485 "\n"
1486 "\tEnable RenderDoc integration for GPU frame grabbing and debugging.";
1488 const char ** /*argv*/,
1489 void * /*data*/)
1490{
1491# ifdef WITH_RENDERDOC
1493# endif
1494 return 0;
1495}
1496
1498 "\n"
1499 "\tForce to use a specific GPU backend. Valid options: "
1500 "'vulkan', "
1501 "'metal', "
1502 "'opengl'.";
1504 "\n"
1505 "\tForce to use a specific GPU backend. Valid options: "
1506# ifdef WITH_OPENGL_BACKEND
1507 "'opengl'"
1508# endif
1509# ifdef WITH_METAL_BACKEND
1510 "'metal'"
1511# endif
1512# ifdef WITH_VULKAN_BACKEND
1513# if defined(WITH_OPENGL_BACKEND) || defined(WITH_METAL_BACKEND)
1514 " or "
1515# endif
1516 "'vulkan'"
1517# endif
1518 ".";
1519static int arg_handle_gpu_backend_set(int argc, const char **argv, void * /*data*/)
1520{
1521 if (argc < 2) {
1522 fprintf(stderr, "\nError: GPU backend must follow '--gpu-backend'.\n");
1523 return 0;
1524 }
1525 const char *backends_supported[3] = {nullptr};
1526 int backends_supported_num = 0;
1527
1528 eGPUBackendType gpu_backend = GPU_BACKEND_NONE;
1529
1530 /* NOLINTBEGIN: bugprone-assignment-in-if-condition */
1531 if (false) {
1532 /* Just a dummy if to make the following ifdef blocks work. */
1533 }
1534# ifdef WITH_OPENGL_BACKEND
1535 else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "opengl"))) {
1536 gpu_backend = GPU_BACKEND_OPENGL;
1537 }
1538# endif
1539# ifdef WITH_VULKAN_BACKEND
1540 else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "vulkan"))) {
1541 gpu_backend = GPU_BACKEND_VULKAN;
1542 }
1543# endif
1544# ifdef WITH_METAL_BACKEND
1545 else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "metal"))) {
1546 gpu_backend = GPU_BACKEND_METAL;
1547 }
1548# endif
1549 else {
1550 fprintf(stderr, "\nError: Unrecognized GPU backend for '--gpu-backend', expected one of [");
1551 for (int i = 0; i < backends_supported_num; i++) {
1552 fprintf(stderr, (i + 1 != backends_supported_num) ? "%s, " : "%s", backends_supported[i]);
1553 }
1554 fprintf(stderr, "].\n");
1555 return 1;
1556 }
1557 /* NOLINTEND: bugprone-assignment-in-if-condition */
1558
1560
1561 return 1;
1562}
1563
1564# ifdef WITH_OPENGL_BACKEND
1565static const char arg_handle_gpu_compilation_subprocesses_set_doc[] =
1566 "\n"
1567 "\tOverride the Max Compilation Subprocesses setting (OpenGL only).";
1568static int arg_handle_gpu_compilation_subprocesses_set(int argc,
1569 const char **argv,
1570 void * /*data*/)
1571{
1572 const char *arg_id = "--gpu-compilation-subprocesses";
1573 const int min = 0, max = BLI_system_thread_count();
1574 if (argc > 1) {
1575 const char *err_msg = nullptr;
1576 int subprocesses;
1577 if (!parse_int_strict_range(argv[1], nullptr, min, max, &subprocesses, &err_msg)) {
1578 fprintf(stderr,
1579 "\nError: %s '%s %s', expected number in [%d..%d].\n",
1580 err_msg,
1581 arg_id,
1582 argv[1],
1583 min,
1584 max);
1585 return 0;
1586 }
1587
1589 return 1;
1590 }
1591 fprintf(stderr,
1592 "\nError: you must specify a number of subprocesses in [%d..%d] '%s'.\n",
1593 min,
1594 max,
1595 arg_id);
1596 return 0;
1597}
1598# endif
1599
1600static const char arg_handle_debug_fpe_set_doc[] =
1601 "\n\t"
1602 "Enable floating-point exceptions.";
1603static int arg_handle_debug_fpe_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1604{
1606 return 0;
1607}
1608
1609static const char arg_handle_app_template_doc[] =
1610 "<template>\n"
1611 "\tSet the application template (matching the directory name), use 'default' for none.";
1612static int arg_handle_app_template(int argc, const char **argv, void * /*data*/)
1613{
1614 if (argc > 1) {
1615 const char *app_template = STREQ(argv[1], "default") ? "" : argv[1];
1617 return 1;
1618 }
1619 fprintf(stderr, "\nError: App template must follow '--app-template'.\n");
1620 return 0;
1621}
1622
1624 "\n\t"
1625 "Skip reading the '" BLENDER_STARTUP_FILE "' in the users home directory.";
1626static int arg_handle_factory_startup_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1627{
1628 G.factory_startup = true;
1630 return 0;
1631}
1632
1634 "\n\t"
1635 "Enable event simulation testing feature 'bpy.types.Window.event_simulate'.";
1636static int arg_handle_enable_event_simulate(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1637{
1639 return 0;
1640}
1641
1643 "\n\t"
1644 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES) " environment variable.";
1646 "\n\t"
1647 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS) " environment variable.";
1649 "\n\t"
1650 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON) " environment variable.";
1652 "\n\t"
1653 "Set the " STRINGIFY_ARG(BLENDER_SYSTEM_EXTENSIONS) " environment variable.";
1654
1655static int arg_handle_env_system_set(int argc, const char **argv, void * /*data*/)
1656{
1657 /* `--env-system-scripts` -> `BLENDER_SYSTEM_SCRIPTS` */
1658
1659 char env[64] = "BLENDER";
1660 char *ch_dst = env + 7; /* Skip `BLENDER`. */
1661 const char *ch_src = argv[0] + 5; /* Skip `--env`. */
1662
1663 if (argc < 2) {
1664 fprintf(stderr, "%s requires one argument\n", argv[0]);
1665 exit(EXIT_FAILURE);
1667 }
1668
1669 for (; *ch_src; ch_src++, ch_dst++) {
1670 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* Inline #toupper(). */
1671 }
1672
1673 *ch_dst = '\0';
1674 BLI_setenv(env, argv[1]);
1675 return 1;
1676}
1677
1678static const char arg_handle_playback_mode_doc[] =
1679 "<options> <file(s)>\n"
1680 "\tInstead of showing Blender's user interface, this runs Blender as an animation player,\n"
1681 "\tto view movies and image sequences rendered in Blender (ignored if '-b' is set).\n"
1682 "\n"
1683 "\tPlayback Arguments:\n"
1684 "\n"
1685 "\t-p <sx> <sy>\n"
1686 "\t\tOpen with lower left corner at <sx>, <sy>.\n"
1687 "\t-m\n"
1688 "\t\tRead from disk (Do not buffer).\n"
1689 "\t-f <fps> <fps_base>\n"
1690 "\t\tSpecify FPS to start with.\n"
1691 "\t-j <frame>\n"
1692 "\t\tSet frame step to <frame>.\n"
1693 "\t-s <frame>\n"
1694 "\t\tPlay from <frame>.\n"
1695 "\t-e <frame>\n"
1696 "\t\tPlay until <frame>.\n"
1697 "\t-c <cache_memory>\n"
1698 "\t\tAmount of memory in megabytes to allow for caching images during playback.\n"
1699 "\t\tZero disables (clamping to a fixed number of frames instead).";
1700static int arg_handle_playback_mode(int argc, const char **argv, void * /*data*/)
1701{
1702 /* Ignore the animation player if `-b` was given first. */
1703 if (G.background == 0) {
1704 /* Skip this argument (`-a`). */
1705 WM_main_playanim(argc - 1, argv + 1);
1706
1707 exit(EXIT_SUCCESS);
1708 }
1709
1710 return -2;
1711}
1712
1714 "<sx> <sy> <w> <h>\n"
1715 "\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>.";
1716static int arg_handle_window_geometry(int argc, const char **argv, void * /*data*/)
1717{
1718 const char *arg_id = "-p / --window-geometry";
1719 int params[4], i;
1720
1721 if (argc < 5) {
1722 fprintf(stderr, "Error: requires four arguments '%s'\n", arg_id);
1723 exit(1);
1724 }
1725
1726 for (i = 0; i < 4; i++) {
1727 const char *err_msg = nullptr;
1728 if (!parse_int(argv[i + 1], nullptr, &params[i], &err_msg)) {
1729 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1730 exit(1);
1731 }
1732 }
1733
1735
1736 return 4;
1737}
1738
1740 "\n\t"
1741 "Do not use native pixel size, for high resolution displays (MacBook 'Retina').";
1742static int arg_handle_native_pixels_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1743{
1744 WM_init_native_pixels(false);
1745 return 0;
1746}
1747
1748static const char arg_handle_with_borders_doc[] =
1749 "\n\t"
1750 "Force opening with borders.";
1751static int arg_handle_with_borders(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1752{
1754 return 0;
1755}
1756
1758 "\n\t"
1759 "Force opening in full-screen mode.";
1760static int arg_handle_without_borders(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1761{
1763 return 0;
1764}
1765
1767 "\n\t"
1768 "Force opening maximized.";
1769static int arg_handle_window_maximized(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1770{
1772 return 0;
1773}
1774
1776 "\n\t"
1777 "Open behind other windows and without taking focus.";
1778static int arg_handle_no_window_focus(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1779{
1781 return 0;
1782}
1783
1785 "\n\t"
1786 "Start with the console window open (ignored if '-b' is set), (Windows only).";
1787static int arg_handle_start_with_console(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1788{
1790 return 0;
1791}
1792
1793static bool arg_handle_extension_registration(const bool do_register, const bool all_users)
1794{
1795 /* Logic runs in #main_args_handle_registration. */
1796# ifdef WIN32
1797 /* This process has been launched with the permissions needed
1798 * to register or unregister, so just do it now and then exit. */
1799 if (do_register) {
1801 }
1802 else {
1804 }
1805 TerminateProcess(GetCurrentProcess(), 0);
1806 return true;
1807# else
1808 char *error_msg = nullptr;
1809 bool result = WM_platform_associate_set(do_register, all_users, &error_msg);
1810 if (error_msg) {
1811 fprintf(stderr, "Error: %s\n", error_msg);
1812 MEM_freeN(error_msg);
1813 }
1814 return result;
1815# endif
1816}
1817
1819 "\n\t"
1820 "Register blend-file extension for current user, then exit (Windows & Linux only).";
1821static int arg_handle_register_extension(int argc, const char **argv, void *data)
1822{
1823 G.quiet = true;
1825
1826# if !(defined(WIN32) && defined(__APPLE__))
1827 if (!main_arg_deferred_is_set()) {
1829 return argc - 1;
1830 }
1831# endif
1833 return argc - 1;
1834}
1835
1837 "\n\t"
1838 "Register blend-file extension for all users, then exit (Windows & Linux only).";
1839static int arg_handle_register_extension_all(int argc, const char **argv, void *data)
1840{
1841 G.quiet = true;
1843
1844# if !(defined(WIN32) && defined(__APPLE__))
1845 if (!main_arg_deferred_is_set()) {
1847 return argc - 1;
1848 }
1849# endif
1851 return argc - 1;
1852}
1853
1855 "\n\t"
1856 "Unregister blend-file extension for current user, then exit (Windows & Linux only).";
1857static int arg_handle_unregister_extension(int argc, const char **argv, void *data)
1858{
1859 G.quiet = true;
1861
1862# if !(defined(WIN32) && defined(__APPLE__))
1863 if (!main_arg_deferred_is_set()) {
1865 return argc - 1;
1866 }
1867# endif
1869 return 0;
1870}
1871
1873 "\n\t"
1874 "Unregister blend-file extension for all users, then exit (Windows & Linux only).";
1875static int arg_handle_unregister_extension_all(int argc, const char **argv, void *data)
1876{
1877 G.quiet = true;
1879
1880# if !(defined(WIN32) && defined(__APPLE__))
1881 if (!main_arg_deferred_is_set()) {
1883 return argc - 1;
1884 }
1885# endif
1887 return 0;
1888}
1889
1890static const char arg_handle_audio_disable_doc[] =
1891 "\n\t"
1892 "Force sound system to None.";
1893static int arg_handle_audio_disable(int /*argc*/, const char ** /*argv*/, void * /*data*/)
1894{
1895 BKE_sound_force_device("None");
1896 return 0;
1897}
1898
1899static const char arg_handle_audio_set_doc[] =
1900 "\n\t"
1901 "Force sound system to a specific device.\n"
1902 "\t'None' 'Default' 'SDL' 'OpenAL' 'CoreAudio' 'JACK' 'PulseAudio' 'WASAPI'.";
1903static int arg_handle_audio_set(int argc, const char **argv, void * /*data*/)
1904{
1905 if (argc < 1) {
1906 fprintf(stderr, "-setaudio requires one argument\n");
1907 exit(1);
1908 }
1909
1910 const char *device = argv[1];
1911 if (STREQ(device, "Default")) {
1912 /* Unset any forced device. */
1913 device = nullptr;
1914 }
1915
1916 BKE_sound_force_device(device);
1917 return 1;
1918}
1919
1920static const char arg_handle_output_set_doc[] =
1921 "<path>\n"
1922 "\tSet the render path and file name.\n"
1923 "\tUse '//' at the start of the path to render relative to the blend-file.\n"
1924 "\n"
1925 "\tYou can use path templating features such as '{blend_name}' in the path.\n"
1926 "\tSee Blender's documentation on path templates for more details.\n"
1927 "\n"
1928 "\tThe '#' characters are replaced by the frame number, and used to define zero padding.\n"
1929 "\n"
1930 "\t* 'animation_##_test.png' becomes 'animation_01_test.png'\n"
1931 "\t* 'test-######.png' becomes 'test-000001.png'\n"
1932 "\n"
1933 "\tWhen the filename does not contain '#', the suffix '####' is added to the filename.\n"
1934 "\n"
1935 "\tThe frame number will be added at the end of the filename, eg:\n"
1936 "\t# blender -b animation.blend -o //render_ -F PNG -x 1 -a\n"
1937 "\t'//render_' becomes '//render_####', writing frames as '//render_0001.png'";
1938static int arg_handle_output_set(int argc, const char **argv, void *data)
1939{
1940 bContext *C = static_cast<bContext *>(data);
1941 if (argc > 1) {
1942 Scene *scene = CTX_data_scene(C);
1943 if (scene) {
1944 STRNCPY(scene->r.pic, argv[1]);
1946 }
1947 else {
1948 fprintf(stderr, "\nError: no blend loaded. cannot use '-o / --render-output'.\n");
1949 }
1950 return 1;
1951 }
1952 fprintf(stderr, "\nError: you must specify a path after '-o / --render-output'.\n");
1953 return 0;
1954}
1955
1956static const char arg_handle_engine_set_doc[] =
1957 "<engine>\n"
1958 "\tSpecify the render engine.\n"
1959 "\tUse '-E help' to list available engines.";
1960static int arg_handle_engine_set(int argc, const char **argv, void *data)
1961{
1962 bContext *C = static_cast<bContext *>(data);
1963 if (argc >= 2) {
1964 if (STREQ(argv[1], "help")) {
1965 printf("Blender Engine Listing:\n");
1967 printf("\t%s\n", type->idname);
1968 }
1969 exit(0);
1970 }
1971 else {
1972 Scene *scene = CTX_data_scene(C);
1973 if (scene) {
1974 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
1975 STRNCPY_UTF8(scene->r.engine, argv[1]);
1977 }
1978 else {
1979 fprintf(stderr, "\nError: engine not found '%s'\n", argv[1]);
1980 exit(1);
1981 }
1982 }
1983 else {
1984 fprintf(stderr,
1985 "\nError: no blend loaded. "
1986 "order the arguments so '-E / --engine' is after a blend is loaded.\n");
1987 }
1988 }
1989
1990 return 1;
1991 }
1992 fprintf(stderr, "\nEngine not specified, give 'help' for a list of available engines.\n");
1993 return 0;
1994}
1995
1997 "<format>\n"
1998 "\tSet the render format.\n"
1999 "\tValid options are:\n"
2000 "\t'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP' 'HDR' 'TIFF'.\n"
2001 "\n"
2002 "\tFormats that can be compiled into Blender, not available on all systems:\n"
2003 "\t'OPEN_EXR' 'OPEN_EXR_MULTILAYER' 'FFMPEG' 'CINEON' 'DPX' 'JP2' 'WEBP'.";
2004static int arg_handle_image_type_set(int argc, const char **argv, void *data)
2005{
2006 bContext *C = static_cast<bContext *>(data);
2007 if (argc > 1) {
2008 const char *imtype = argv[1];
2009 Scene *scene = CTX_data_scene(C);
2010 if (scene) {
2011 const char imtype_new = BKE_imtype_from_arg(imtype);
2012
2013 if (imtype_new == R_IMF_IMTYPE_INVALID) {
2014 fprintf(stderr,
2015 "\nError: Format from '-F / --render-format' not known or not compiled in this "
2016 "release.\n");
2017 }
2018 else {
2019 BKE_image_format_set(&scene->r.im_format, &scene->id, imtype_new);
2021 }
2022 }
2023 else {
2024 fprintf(stderr,
2025 "\nError: no blend loaded. "
2026 "order the arguments so '-F / --render-format' is after the blend is loaded.\n");
2027 }
2028 return 1;
2029 }
2030 fprintf(stderr, "\nError: you must specify a format after '-F / --render-format'.\n");
2031 return 0;
2032}
2033
2034static const char arg_handle_threads_set_doc[] =
2035 "<threads>\n"
2036 "\tUse amount of <threads> for rendering and other operations\n"
2037 "\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 to use the systems processor count.";
2038static int arg_handle_threads_set(int argc, const char **argv, void * /*data*/)
2039{
2040 const char *arg_id = "-t / --threads";
2041 const int min = 0, max = BLENDER_MAX_THREADS;
2042 if (argc > 1) {
2043 const char *err_msg = nullptr;
2044 int threads;
2045 if (!parse_int_strict_range(argv[1], nullptr, min, max, &threads, &err_msg)) {
2046 fprintf(stderr,
2047 "\nError: %s '%s %s', expected number in [%d..%d].\n",
2048 err_msg,
2049 arg_id,
2050 argv[1],
2051 min,
2052 max);
2053 return 1;
2054 }
2055
2057 return 1;
2058 }
2059 fprintf(stderr,
2060 "\nError: you must specify a number of threads in [%d..%d] '%s'.\n",
2061 min,
2062 max,
2063 arg_id);
2064 return 0;
2065}
2066
2067static const char arg_handle_verbosity_set_doc[] =
2068 "<verbose>\n"
2069 "\tSet the logging verbosity level for debug messages that support it.";
2070static int arg_handle_verbosity_set(int argc, const char **argv, void * /*data*/)
2071{
2072 const char *arg_id = "--verbose";
2073 if (argc > 1) {
2074 const char *err_msg = nullptr;
2075 int level;
2076 if (!parse_int(argv[1], nullptr, &level, &err_msg)) {
2077 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2078 }
2079
2080# ifdef WITH_LIBMV
2082# elif defined(WITH_CYCLES_LOGGING)
2084# else
2085 (void)level;
2086# endif
2087
2088 return 1;
2089 }
2090 fprintf(stderr, "\nError: you must specify a verbosity level.\n");
2091 return 0;
2092}
2093
2094static const char arg_handle_extension_set_doc[] =
2095 "<bool>\n"
2096 "\tSet option to add the file extension to the end of the file.";
2097static int arg_handle_extension_set(int argc, const char **argv, void *data)
2098{
2099 bContext *C = static_cast<bContext *>(data);
2100 if (argc > 1) {
2101 Scene *scene = CTX_data_scene(C);
2102 if (scene) {
2103 if (argv[1][0] == '0') {
2104 scene->r.scemode &= ~R_EXTENSION;
2106 }
2107 else if (argv[1][0] == '1') {
2108 scene->r.scemode |= R_EXTENSION;
2110 }
2111 else {
2112 fprintf(stderr,
2113 "\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
2114 }
2115 }
2116 else {
2117 fprintf(stderr,
2118 "\nError: no blend loaded. "
2119 "order the arguments so '-o ' is after '-x '.\n");
2120 }
2121 return 1;
2122 }
2123 fprintf(stderr, "\nError: you must specify a path after '- '.\n");
2124 return 0;
2125}
2126
2127static const char arg_handle_render_frame_doc[] =
2128 "<frame>\n"
2129 "\tRender frame <frame> and save it.\n"
2130 "\n"
2131 "\t* +<frame> start frame relative, -<frame> end frame relative.\n"
2132 "\t* A comma separated list of frames can also be used (no spaces).\n"
2133 "\t* A range of frames can be expressed using '..' separator between the first and last "
2134 "frames (inclusive).\n";
2135static int arg_handle_render_frame(int argc, const char **argv, void *data)
2136{
2137 const char *arg_id = "-f / --render-frame";
2138 bContext *C = static_cast<bContext *>(data);
2139 Scene *scene = CTX_data_scene(C);
2140 if (scene) {
2141 Main *bmain = CTX_data_main(C);
2142
2143 if (argc > 1) {
2144 const char *err_msg = nullptr;
2145 Render *re;
2147
2148 int(*frame_range_arr)[2], frames_range_len;
2149 if ((frame_range_arr = parse_int_range_relative_clamp_n(argv[1],
2150 scene->r.sfra,
2151 scene->r.efra,
2152 MINAFRAME,
2153 MAXFRAME,
2154 &frames_range_len,
2155 &err_msg)) == nullptr)
2156 {
2157 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2158 return 1;
2159 }
2160
2161 re = RE_NewSceneRender(scene);
2163 RE_SetReports(re, &reports);
2164 for (int i = 0; i < frames_range_len; i++) {
2165 /* We could pass in frame ranges,
2166 * but prefer having exact behavior as passing in multiple frames. */
2167 if ((frame_range_arr[i][0] <= frame_range_arr[i][1]) == 0) {
2168 fprintf(stderr, "\nWarning: negative range ignored '%s %s'.\n", arg_id, argv[1]);
2169 }
2170
2171 for (int frame = frame_range_arr[i][0]; frame <= frame_range_arr[i][1]; frame++) {
2172 RE_RenderAnim(re, bmain, scene, nullptr, nullptr, frame, frame, scene->r.frame_step);
2173 }
2174 }
2175 RE_SetReports(re, nullptr);
2177 MEM_freeN(frame_range_arr);
2178 return 1;
2179 }
2180 fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id);
2181 return 0;
2182 }
2183 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2184 return 0;
2185}
2186
2188 "\n\t"
2189 "Render frames from start to end (inclusive).";
2190static int arg_handle_render_animation(int /*argc*/, const char ** /*argv*/, void *data)
2191{
2192 bContext *C = static_cast<bContext *>(data);
2193 Scene *scene = CTX_data_scene(C);
2194 if (scene) {
2195 Main *bmain = CTX_data_main(C);
2196 Render *re = RE_NewSceneRender(scene);
2199 RE_SetReports(re, &reports);
2201 re, bmain, scene, nullptr, nullptr, scene->r.sfra, scene->r.efra, scene->r.frame_step);
2202 RE_SetReports(re, nullptr);
2204 }
2205 else {
2206 fprintf(stderr, "\nError: no blend loaded. cannot use '-a'.\n");
2207 }
2208 return 0;
2209}
2210
2211static const char arg_handle_scene_set_doc[] =
2212 "<name>\n"
2213 "\tSet the active scene <name> for rendering.";
2214static int arg_handle_scene_set(int argc, const char **argv, void *data)
2215{
2216 if (argc > 1) {
2217 bContext *C = static_cast<bContext *>(data);
2218 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
2219 if (scene) {
2220 CTX_data_scene_set(C, scene);
2221
2222 /* Set the scene of the first window, see: #55991,
2223 * otherwise scripts that run later won't get this scene back from the context. */
2224 wmWindow *win = CTX_wm_window(C);
2225 if (win == nullptr) {
2226 win = static_cast<wmWindow *>(CTX_wm_manager(C)->windows.first);
2227 }
2228 if (win != nullptr) {
2230 }
2231 }
2232 return 1;
2233 }
2234 fprintf(stderr, "\nError: Scene name must follow '-S / --scene'.\n");
2235 return 0;
2236}
2237
2239 "<frame>\n"
2240 "\tSet start to frame <frame>, supports +/- for relative frames too.";
2241static int arg_handle_frame_start_set(int argc, const char **argv, void *data)
2242{
2243 const char *arg_id = "-s / --frame-start";
2244 bContext *C = static_cast<bContext *>(data);
2245 Scene *scene = CTX_data_scene(C);
2246 if (scene) {
2247 if (argc > 1) {
2248 const char *err_msg = nullptr;
2249 if (!parse_int_relative_clamp(argv[1],
2250 nullptr,
2251 scene->r.sfra,
2252 scene->r.sfra - 1,
2253 MINAFRAME,
2254 MAXFRAME,
2255 &scene->r.sfra,
2256 &err_msg))
2257 {
2258 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2259 }
2260 else {
2262 }
2263 return 1;
2264 }
2265 fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id);
2266 return 0;
2267 }
2268 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2269 return 0;
2270}
2271
2272static const char arg_handle_frame_end_set_doc[] =
2273 "<frame>\n"
2274 "\tSet end to frame <frame>, supports +/- for relative frames too.";
2275static int arg_handle_frame_end_set(int argc, const char **argv, void *data)
2276{
2277 const char *arg_id = "-e / --frame-end";
2278 bContext *C = static_cast<bContext *>(data);
2279 Scene *scene = CTX_data_scene(C);
2280 if (scene) {
2281 if (argc > 1) {
2282 const char *err_msg = nullptr;
2283 if (!parse_int_relative_clamp(argv[1],
2284 nullptr,
2285 scene->r.efra,
2286 scene->r.efra - 1,
2287 MINAFRAME,
2288 MAXFRAME,
2289 &scene->r.efra,
2290 &err_msg))
2291 {
2292 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2293 }
2294 else {
2296 }
2297 return 1;
2298 }
2299 fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id);
2300 return 0;
2301 }
2302 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2303 return 0;
2304}
2305
2307 "<frames>\n"
2308 "\tSet number of frames to step forward after each rendered frame.";
2309static int arg_handle_frame_skip_set(int argc, const char **argv, void *data)
2310{
2311 const char *arg_id = "-j / --frame-jump";
2312 bContext *C = static_cast<bContext *>(data);
2313 Scene *scene = CTX_data_scene(C);
2314 if (scene) {
2315 if (argc > 1) {
2316 const char *err_msg = nullptr;
2317 if (!parse_int_clamp(argv[1], nullptr, 1, MAXFRAME, &scene->r.frame_step, &err_msg)) {
2318 fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
2319 }
2320 else {
2322 }
2323 return 1;
2324 }
2325 fprintf(stderr, "\nError: number of frames to step must follow '%s'.\n", arg_id);
2326 return 0;
2327 }
2328 fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id);
2329 return 0;
2330}
2331
2333 "<filepath>\n"
2334 "\tRun the given Python script file.";
2335static int arg_handle_python_file_run(int argc, const char **argv, void *data)
2336{
2337 bContext *C = static_cast<bContext *>(data);
2338
2339 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2340 if (argc > 1) {
2341# ifdef WITH_PYTHON
2342 /* Make the path absolute because its needed for relative linked blends to be found. */
2343 char filepath[FILE_MAX];
2344 STRNCPY(filepath, argv[1]);
2345 BLI_path_canonicalize_native(filepath, sizeof(filepath));
2346
2347 bool ok;
2348 BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, nullptr));
2349 if (!ok && app_state.exit_code_on_error.python) {
2350 fprintf(stderr, "\nError: script failed, file: '%s', exiting.\n", argv[1]);
2351 WM_exit(C, app_state.exit_code_on_error.python);
2352 }
2353# else
2354 UNUSED_VARS(C);
2355 fprintf(stderr, "This Blender was built without Python support\n");
2356# endif /* WITH_PYTHON */
2357
2358 return 1;
2359 }
2360 fprintf(stderr, "\nError: you must specify a filepath after '%s'.\n", argv[0]);
2361 return 0;
2362}
2363
2365 "<name>\n"
2366 "\tRun the given Python script text block.";
2367static int arg_handle_python_text_run(int argc, const char **argv, void *data)
2368{
2369 bContext *C = static_cast<bContext *>(data);
2370
2371 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2372 if (argc > 1) {
2373# ifdef WITH_PYTHON
2374 Main *bmain = CTX_data_main(C);
2375 /* Make the path absolute because its needed for relative linked blends to be found. */
2376 Text *text = (Text *)BKE_libblock_find_name(bmain, ID_TXT, argv[1]);
2377 bool ok;
2378
2379 if (text) {
2380 BPY_CTX_SETUP(ok = BPY_run_text(C, text, nullptr, false));
2381 }
2382 else {
2383 fprintf(stderr, "\nError: text block not found %s.\n", argv[1]);
2384 ok = false;
2385 }
2386
2387 if (!ok && app_state.exit_code_on_error.python) {
2388 fprintf(stderr, "\nError: script failed, text: '%s', exiting.\n", argv[1]);
2389 WM_exit(C, app_state.exit_code_on_error.python);
2390 }
2391# else
2392 UNUSED_VARS(C);
2393 fprintf(stderr, "This Blender was built without Python support\n");
2394# endif /* WITH_PYTHON */
2395
2396 return 1;
2397 }
2398
2399 fprintf(stderr, "\nError: you must specify a text block after '%s'.\n", argv[0]);
2400 return 0;
2401}
2402
2404 "<expression>\n"
2405 "\tRun the given expression as a Python script.";
2406static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
2407{
2408 bContext *C = static_cast<bContext *>(data);
2409
2410 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2411 if (argc > 1) {
2412# ifdef WITH_PYTHON
2413 bool ok;
2414 BPY_CTX_SETUP(ok = BPY_run_string_exec(C, nullptr, argv[1]));
2415 if (!ok && app_state.exit_code_on_error.python) {
2416 fprintf(stderr, "\nError: script failed, expr: '%s', exiting.\n", argv[1]);
2417 WM_exit(C, app_state.exit_code_on_error.python);
2418 }
2419# else
2420 UNUSED_VARS(C);
2421 fprintf(stderr, "This Blender was built without Python support\n");
2422# endif /* WITH_PYTHON */
2423
2424 return 1;
2425 }
2426 fprintf(stderr, "\nError: you must specify a Python expression after '%s'.\n", argv[0]);
2427 return 0;
2428}
2429
2431 "\n\t"
2432 "Run Blender with an interactive console.";
2433static int arg_handle_python_console_run(int /*argc*/, const char ** /*argv*/, void *data)
2434{
2435 bContext *C = static_cast<bContext *>(data);
2436# ifdef WITH_PYTHON
2437 const char *imports[] = {"code", nullptr};
2438 BPY_CTX_SETUP(BPY_run_string_eval(C, imports, "code.interact()"));
2439# else
2440 UNUSED_VARS(C);
2441 fprintf(stderr, "This Blender was built without python support\n");
2442# endif /* WITH_PYTHON */
2443
2444 return 0;
2445}
2446
2448 "<code>\n"
2449 "\tSet the exit-code in [0..255] to exit if a Python exception is raised\n"
2450 "\t(only for scripts executed from the command line), zero disables.";
2451static int arg_handle_python_exit_code_set(int argc, const char **argv, void * /*data*/)
2452{
2453 const char *arg_id = "--python-exit-code";
2454 if (argc > 1) {
2455 const char *err_msg = nullptr;
2456 const int min = 0, max = 255;
2457 int exit_code;
2458 if (!parse_int_strict_range(argv[1], nullptr, min, max, &exit_code, &err_msg)) {
2459 fprintf(stderr,
2460 "\nError: %s '%s %s', expected number in [%d..%d].\n",
2461 err_msg,
2462 arg_id,
2463 argv[1],
2464 min,
2465 max);
2466 return 1;
2467 }
2468
2469 app_state.exit_code_on_error.python = uchar(exit_code);
2470 return 1;
2471 }
2472 fprintf(stderr, "\nError: you must specify an exit code number '%s'.\n", arg_id);
2473 return 0;
2474}
2475
2477 "\n\t"
2478 "Allow Python to use system environment variables such as 'PYTHONPATH' and the user "
2479 "site-packages directory.";
2481 const char ** /*argv*/,
2482 void * /*data*/)
2483{
2484# ifdef WITH_PYTHON
2486# endif
2487 return 0;
2488}
2489
2490static const char arg_handle_addons_set_doc[] =
2491 "<addon(s)>\n"
2492 "\tComma separated list (no spaces) of add-ons to enable in addition to any default add-ons.";
2493static int arg_handle_addons_set(int argc, const char **argv, void *data)
2494{
2495 /* Workaround for scripts not getting a `bpy.context.scene`, causes internal errors elsewhere. */
2496 if (argc > 1) {
2497# ifdef WITH_PYTHON
2498 const char script_str[] =
2499 "from _bpy_internal.addons.cli import set_from_cli\n"
2500 "set_from_cli('%s')";
2501 const int slen = strlen(argv[1]) + (sizeof(script_str) - 2);
2502 char *str = static_cast<char *>(malloc(slen));
2503 bContext *C = static_cast<bContext *>(data);
2504 BLI_snprintf(str, slen, script_str, argv[1]);
2505
2506 BLI_assert(strlen(str) + 1 == slen);
2507 BPY_CTX_SETUP(BPY_run_string_exec(C, nullptr, str));
2508 free(str);
2509# else
2510 UNUSED_VARS(argv, data);
2511# endif /* WITH_PYTHON */
2512 return 1;
2513 }
2514 fprintf(stderr, "\nError: you must specify a comma separated list after '--addons'.\n");
2515 return 0;
2516}
2517
2519 "\n"
2520 "\tEnable CPU & GPU performance profiling for GPU debug groups\n"
2521 "\t(Outputs a profile.json file in the Trace Event Format to the current directory)";
2522static int arg_handle_profile_gpu_set(int /*argc*/, const char ** /*argv*/, void * /*data*/)
2523{
2524 G.profile_gpu = true;
2525 return 0;
2526}
2527
2532static bool handle_load_file(bContext *C, const char *filepath_arg, const bool load_empty_file)
2533{
2534 /* Make the path absolute because its needed for relative linked blends to be found. */
2535 char filepath[FILE_MAX];
2536 STRNCPY(filepath, filepath_arg);
2537 BLI_path_canonicalize_native(filepath, sizeof(filepath));
2538
2539 /* Load the file. */
2542 /* When activating from the command line there isn't an exact equivalent to operator properties.
2543 * Instead, enabling auto-execution via `--enable-autoexec` causes the auto-execution
2544 * check to be skipped (if it's set), so it's fine to always enable the check here. */
2545 const bool use_scripts_autoexec_check = true;
2546 const bool success = WM_file_read(C, filepath, use_scripts_autoexec_check, &reports);
2548
2549 if (success) {
2550 if (G.background) {
2551 /* Ensure we use 'C->data.scene' for background render. */
2552 CTX_wm_window_set(C, nullptr);
2553 }
2554 }
2555 else {
2556 /* Failed to load file, stop processing arguments if running in background mode. */
2557 if (G.background) {
2558 /* Set `is_break` if running in the background mode so
2559 * blender will return non-zero exit code which then
2560 * could be used in automated script to control how
2561 * good or bad things are. */
2562 G.is_break = true;
2563 return false;
2564 }
2565
2566 const char *error_msg_generic = "file could not be loaded";
2567 const char *error_msg = nullptr;
2568
2569 if (load_empty_file == false) {
2570 error_msg = error_msg_generic;
2571 }
2572 else if (BLI_exists(filepath)) {
2573 /* When a file is found but can't be loaded, handling it as a new file
2574 * could cause it to be unintentionally overwritten (data loss).
2575 * Further this is almost certainly not that a user would expect or want.
2576 * If they do, they can delete the file beforehand. */
2577 error_msg = error_msg_generic;
2578 }
2579 else if (!BKE_blendfile_extension_check(filepath)) {
2580 /* Unrelated arguments should not be treated as new blend files. */
2581 error_msg = "argument has no '.blend' file extension, not using as new file";
2582 }
2583
2584 if (error_msg) {
2585 fprintf(stderr, "Error: %s, exiting! %s\n", error_msg, filepath);
2586 WM_exit(C, EXIT_FAILURE);
2587 /* Unreachable, return for clarity. */
2588 return false;
2589 }
2590
2591 /* Behave as if a file was loaded, calling "Save" will write to the `filepath` from the CLI.
2592 *
2593 * WARNING: The path referenced may be incorrect, no attempt is made to validate the path
2594 * here or check that writing to it will work. If the users enters the path of a directory
2595 * that doesn't exist (for example) saving will fail.
2596 * Attempting to create the file at this point is possible but likely to cause more
2597 * trouble than it's worth (what with network drives), removable devices ... etc. */
2598
2599 STRNCPY(G_MAIN->filepath, filepath);
2600 printf("... opened default scene instead; saving will write to: %s\n", filepath);
2601 }
2602
2603 return true;
2604}
2605
2606int main_args_handle_load_file(int /*argc*/, const char **argv, void *data)
2607{
2608 bContext *C = static_cast<bContext *>(data);
2609 const char *filepath = argv[0];
2610
2611 /* NOTE: we could skip these, but so far we always tried to load these files. */
2612 if (argv[0][0] == '-') {
2613 fprintf(stderr, "unknown argument, loading as file: %s\n", filepath);
2614 }
2615
2616 if (!handle_load_file(C, filepath, true)) {
2617 return -1;
2618 }
2619 return 0;
2620}
2621
2623 "\n\t"
2624 "Open the most recently opened blend file, instead of the default startup file.";
2625static int arg_handle_load_last_file(int /*argc*/, const char ** /*argv*/, void *data)
2626{
2627 if (BLI_listbase_is_empty(&G.recent_files)) {
2628 fprintf(stderr, "Warning: no recent files known, opening default startup file instead.\n");
2629 return -1;
2630 }
2631
2632 bContext *C = static_cast<bContext *>(data);
2633 const RecentFile *recent_file = static_cast<const RecentFile *>(G.recent_files.first);
2634 if (!handle_load_file(C, recent_file->filepath, false)) {
2635 return -1;
2636 }
2637 return 0;
2638}
2639
2641{
2643# define CB(a) a##_doc, a
2645# define CB_EX(a, b) a##_doc_##b, a
2647# define CB_ALL(a) (all ? a##_doc_all : a##_doc), a
2648
2649 BuildDefs defs;
2650 build_defs_init(&defs, all);
2651
2652 /* end argument processing after -- */
2653 BLI_args_pass_set(ba, -1);
2654 BLI_args_add(ba, "--", nullptr, CB(arg_handle_arguments_end), nullptr);
2655
2656 /* Pass: Environment Setup
2657 *
2658 * It's important these run before any initialization is done, since they set up
2659 * the environment used to access data-files, which are be used when initializing
2660 * sub-systems such as color management. */
2663 ba, nullptr, "--python-use-system-env", CB(arg_handle_python_use_system_env_set), nullptr);
2664
2665 /* Note that we could add used environment variables too. */
2667 ba, nullptr, "--env-system-datafiles", CB_EX(arg_handle_env_system_set, datafiles), nullptr);
2669 ba, nullptr, "--env-system-scripts", CB_EX(arg_handle_env_system_set, scripts), nullptr);
2671 ba, nullptr, "--env-system-python", CB_EX(arg_handle_env_system_set, python), nullptr);
2672 BLI_args_add(ba,
2673 nullptr,
2674 "--env-system-extensions",
2675 CB_EX(arg_handle_env_system_set, extensions),
2676 nullptr);
2677
2678 BLI_args_add(ba, "-t", "--threads", CB(arg_handle_threads_set), nullptr);
2679
2680 /* Include in the environment pass so it's possible display errors initializing subsystems,
2681 * especially `bpy.appdir` since it's useful to show errors finding paths on startup. */
2682 BLI_args_add(ba, nullptr, "--log", CB(arg_handle_log_set), ba);
2683 BLI_args_add(ba, nullptr, "--log-level", CB(arg_handle_log_level_set), ba);
2684 BLI_args_add(ba, nullptr, "--log-show-basename", CB(arg_handle_log_show_basename_set), ba);
2685 BLI_args_add(ba, nullptr, "--log-show-backtrace", CB(arg_handle_log_show_backtrace_set), ba);
2686 BLI_args_add(ba, nullptr, "--log-show-timestamp", CB(arg_handle_log_show_timestamp_set), ba);
2687 BLI_args_add(ba, nullptr, "--log-file", CB(arg_handle_log_file_set), ba);
2688
2689 /* GPU backend selection should be part of #ARG_PASS_ENVIRONMENT for correct GPU context
2690 * selection for animation player. */
2691 BLI_args_add(ba, nullptr, "--gpu-backend", CB_ALL(arg_handle_gpu_backend_set), nullptr);
2692# ifdef WITH_OPENGL_BACKEND
2693 BLI_args_add(ba,
2694 nullptr,
2695 "--gpu-compilation-subprocesses",
2696 CB(arg_handle_gpu_compilation_subprocesses_set),
2697 nullptr);
2698# endif
2699 BLI_args_add(ba, nullptr, "--profile-gpu", CB(arg_handle_profile_gpu_set), nullptr);
2700
2701 /* Pass: Background Mode & Settings
2702 *
2703 * Also and commands that exit after usage. */
2705 BLI_args_add(ba, "-h", "--help", CB(arg_handle_print_help), ba);
2706 /* MS-Windows only. */
2707 BLI_args_add(ba, "/?", nullptr, CB_EX(arg_handle_print_help, win32), ba);
2708
2709 BLI_args_add(ba, "-v", "--version", CB(arg_handle_print_version), nullptr);
2710
2711 BLI_args_add(ba, "-y", "--enable-autoexec", CB_EX(arg_handle_python_set, enable), (void *)true);
2713 ba, "-Y", "--disable-autoexec", CB_EX(arg_handle_python_set, disable), (void *)false);
2714
2716 ba, nullptr, "--offline-mode", CB_EX(arg_handle_internet_allow_set, offline), (void *)false);
2718 ba, nullptr, "--online-mode", CB_EX(arg_handle_internet_allow_set, online), (void *)true);
2719
2721 ba, nullptr, "--disable-crash-handler", CB(arg_handle_crash_handler_disable), nullptr);
2723 ba, nullptr, "--disable-abort-handler", CB(arg_handle_abort_handler_disable), nullptr);
2724
2725 BLI_args_add(ba, "-q", "--quiet", CB(arg_handle_quiet_set), nullptr);
2726 BLI_args_add(ba, "-b", "--background", CB(arg_handle_background_mode_set), nullptr);
2727 /* Command implies background mode (defers execution). */
2728 BLI_args_add(ba, "-c", "--command", CB(arg_handle_command_set), C);
2729
2730 BLI_args_add(ba,
2731 nullptr,
2732 "--disable-depsgraph-on-file-load",
2734 nullptr);
2735
2736 BLI_args_add(ba,
2737 nullptr,
2738 "--disable-liboverride-auto-resync",
2740 nullptr);
2741
2742 BLI_args_add(ba, "-a", nullptr, CB(arg_handle_playback_mode), nullptr);
2743
2744 BLI_args_add(ba, "-d", "--debug", CB(arg_handle_debug_mode_set), ba);
2745
2746 if (defs.with_ffmpeg) {
2747 BLI_args_add(ba,
2748 nullptr,
2749 "--debug-ffmpeg",
2751 (void *)G_DEBUG_FFMPEG);
2752 }
2753
2754 if (defs.with_freestyle) {
2755 BLI_args_add(ba,
2756 nullptr,
2757 "--debug-freestyle",
2759 (void *)G_DEBUG_FREESTYLE);
2760 }
2761 BLI_args_add(ba,
2762 nullptr,
2763 "--debug-python",
2765 (void *)G_DEBUG_PYTHON);
2766 BLI_args_add(ba,
2767 nullptr,
2768 "--debug-events",
2770 (void *)G_DEBUG_EVENTS);
2771 BLI_args_add(ba,
2772 nullptr,
2773 "--debug-handlers",
2775 (void *)G_DEBUG_HANDLERS);
2777 ba, nullptr, "--debug-wm", CB_EX(arg_handle_debug_mode_generic_set, wm), (void *)G_DEBUG_WM);
2778 if (defs.with_xr_openxr) {
2779 BLI_args_add(ba,
2780 nullptr,
2781 "--debug-xr",
2783 (void *)G_DEBUG_XR);
2784 BLI_args_add(ba,
2785 nullptr,
2786 "--debug-xr-time",
2788 (void *)G_DEBUG_XR_TIME);
2789 }
2790 BLI_args_add(ba,
2791 nullptr,
2792 "--debug-ghost",
2794 (void *)G_DEBUG_GHOST);
2795 BLI_args_add(ba,
2796 nullptr,
2797 "--debug-wintab",
2799 (void *)G_DEBUG_WINTAB);
2800 BLI_args_add(ba, nullptr, "--debug-all", CB(arg_handle_debug_mode_all), nullptr);
2801
2802 BLI_args_add(ba, nullptr, "--debug-io", CB(arg_handle_debug_mode_io), nullptr);
2803
2804 BLI_args_add(ba, nullptr, "--debug-fpe", CB(arg_handle_debug_fpe_set), nullptr);
2805
2806 if (defs.with_libmv) {
2807 BLI_args_add(ba, nullptr, "--debug-libmv", CB(arg_handle_debug_mode_libmv), nullptr);
2808 }
2809 if (defs.with_cycles_logging) {
2810 BLI_args_add(ba, nullptr, "--debug-cycles", CB(arg_handle_debug_mode_cycles), nullptr);
2811 }
2812 BLI_args_add(ba, nullptr, "--debug-memory", CB(arg_handle_debug_mode_memory_set), nullptr);
2813
2814 BLI_args_add(ba, nullptr, "--debug-value", CB(arg_handle_debug_value_set), nullptr);
2815 BLI_args_add(ba,
2816 nullptr,
2817 "--debug-jobs",
2819 (void *)G_DEBUG_JOBS);
2820 BLI_args_add(ba, nullptr, "--debug-gpu", CB(arg_handle_debug_gpu_set), nullptr);
2821 BLI_args_add(ba,
2822 nullptr,
2823 "--debug-gpu-compile-shaders",
2825 nullptr);
2826 if (defs.with_renderdoc) {
2827 BLI_args_add(ba,
2828 nullptr,
2829 "--debug-gpu-scope-capture",
2831 nullptr);
2833 ba, nullptr, "--debug-gpu-renderdoc", CB(arg_handle_debug_gpu_renderdoc_set), nullptr);
2834 }
2835
2836 BLI_args_add(ba,
2837 nullptr,
2838 "--debug-depsgraph",
2840 (void *)G_DEBUG_DEPSGRAPH);
2841 BLI_args_add(ba,
2842 nullptr,
2843 "--debug-depsgraph-build",
2844 CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build),
2845 (void *)G_DEBUG_DEPSGRAPH_BUILD);
2846 BLI_args_add(ba,
2847 nullptr,
2848 "--debug-depsgraph-eval",
2850 (void *)G_DEBUG_DEPSGRAPH_EVAL);
2851 BLI_args_add(ba,
2852 nullptr,
2853 "--debug-depsgraph-tag",
2855 (void *)G_DEBUG_DEPSGRAPH_TAG);
2856 BLI_args_add(ba,
2857 nullptr,
2858 "--debug-depsgraph-time",
2860 (void *)G_DEBUG_DEPSGRAPH_TIME);
2861 BLI_args_add(ba,
2862
2863 nullptr,
2864 "--debug-depsgraph-no-threads",
2865 CB_EX(arg_handle_debug_mode_generic_set, depsgraph_no_threads),
2867 BLI_args_add(ba,
2868 nullptr,
2869 "--debug-depsgraph-pretty",
2870 CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty),
2871 (void *)G_DEBUG_DEPSGRAPH_PRETTY);
2872 BLI_args_add(ba,
2873 nullptr,
2874 "--debug-depsgraph-uid",
2876 (void *)G_DEBUG_DEPSGRAPH_UID);
2877 BLI_args_add(ba,
2878 nullptr,
2879 "--debug-gpu-force-workarounds",
2880 CB_EX(arg_handle_debug_mode_generic_set, gpu_force_workarounds),
2882# ifdef WITH_VULKAN_BACKEND
2883 BLI_args_add(ba,
2884 nullptr,
2885 "--debug-gpu-vulkan-local-read",
2886 CB_EX(arg_handle_debug_mode_generic_set, gpu_force_vulkan_local_read),
2888# endif
2889 BLI_args_add(ba, nullptr, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), nullptr);
2890
2891 BLI_args_add(ba, nullptr, "--verbose", CB(arg_handle_verbosity_set), nullptr);
2892
2893 BLI_args_add(ba, nullptr, "--app-template", CB(arg_handle_app_template), nullptr);
2894 BLI_args_add(ba, nullptr, "--factory-startup", CB(arg_handle_factory_startup_set), nullptr);
2896 ba, nullptr, "--enable-event-simulate", CB(arg_handle_enable_event_simulate), nullptr);
2897
2898 /* Pass: Custom Window Stuff. */
2900 BLI_args_add(ba, "-p", "--window-geometry", CB(arg_handle_window_geometry), nullptr);
2901 BLI_args_add(ba, "-w", "--window-border", CB(arg_handle_with_borders), nullptr);
2902 BLI_args_add(ba, "-W", "--window-fullscreen", CB(arg_handle_without_borders), nullptr);
2903 BLI_args_add(ba, "-M", "--window-maximized", CB(arg_handle_window_maximized), nullptr);
2904 BLI_args_add(ba, nullptr, "--no-window-focus", CB(arg_handle_no_window_focus), nullptr);
2905 BLI_args_add(ba, "-con", "--start-console", CB(arg_handle_start_with_console), nullptr);
2906 BLI_args_add(ba, "-r", "--register", CB(arg_handle_register_extension), nullptr);
2907 BLI_args_add(ba, nullptr, "--register-allusers", CB(arg_handle_register_extension_all), nullptr);
2908 BLI_args_add(ba, nullptr, "--unregister", CB(arg_handle_unregister_extension), nullptr);
2910 ba, nullptr, "--unregister-allusers", CB(arg_handle_unregister_extension_all), nullptr);
2911 BLI_args_add(ba, nullptr, "--no-native-pixels", CB(arg_handle_native_pixels_set), ba);
2912
2913 /* Pass: Disabling Things & Forcing Settings. */
2915 BLI_args_add_case(ba, "-noaudio", 1, nullptr, 0, CB(arg_handle_audio_disable), nullptr);
2916 BLI_args_add_case(ba, "-setaudio", 1, nullptr, 0, CB(arg_handle_audio_set), nullptr);
2917
2918 /* Pass: Processing Arguments. */
2919 /* NOTE: Use #WM_exit for these callbacks, not `exit()`
2920 * so temporary files are properly cleaned up. */
2922 BLI_args_add(ba, "-f", "--render-frame", CB(arg_handle_render_frame), C);
2923 BLI_args_add(ba, "-a", "--render-anim", CB(arg_handle_render_animation), C);
2924 BLI_args_add(ba, "-S", "--scene", CB(arg_handle_scene_set), C);
2925 BLI_args_add(ba, "-s", "--frame-start", CB(arg_handle_frame_start_set), C);
2926 BLI_args_add(ba, "-e", "--frame-end", CB(arg_handle_frame_end_set), C);
2927 BLI_args_add(ba, "-j", "--frame-jump", CB(arg_handle_frame_skip_set), C);
2928 BLI_args_add(ba, "-P", "--python", CB(arg_handle_python_file_run), C);
2929 BLI_args_add(ba, nullptr, "--python-text", CB(arg_handle_python_text_run), C);
2930 BLI_args_add(ba, nullptr, "--python-expr", CB(arg_handle_python_expr_run), C);
2931 BLI_args_add(ba, nullptr, "--python-console", CB(arg_handle_python_console_run), C);
2932 BLI_args_add(ba, nullptr, "--python-exit-code", CB(arg_handle_python_exit_code_set), nullptr);
2933 BLI_args_add(ba, nullptr, "--addons", CB(arg_handle_addons_set), C);
2934
2935 BLI_args_add(ba, "-o", "--render-output", CB(arg_handle_output_set), C);
2936 BLI_args_add(ba, "-E", "--engine", CB(arg_handle_engine_set), C);
2937
2938 BLI_args_add(ba, "-F", "--render-format", CB(arg_handle_image_type_set), C);
2939 BLI_args_add(ba, "-x", "--use-extension", CB(arg_handle_extension_set), C);
2940
2941 BLI_args_add(ba, nullptr, "--open-last", CB(arg_handle_load_last_file), C);
2942
2943# undef CB
2944# undef CB_EX
2945# undef CB_ALL
2946
2947# ifdef WITH_PYTHON
2948 /* Use for Python to extract help text (Python can't call directly - bad-level call). */
2950# else
2951 /* Quiet unused function warning. */
2953# endif
2954}
2955
2957
2958#endif /* !WITH_PYTHON_MODULE */
@ BLENDER_SYSTEM_DATAFILES
@ BLENDER_SYSTEM_EXTENSIONS
@ BLENDER_SYSTEM_PYTHON
@ BLENDER_SYSTEM_SCRIPTS
#define BLENDER_STARTUP_FILE
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:143
bool BKE_blendfile_extension_check(const char *str)
Definition blendfile.cc:84
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_BACKGROUND_NO_DEPSGRAPH
@ G_LIBOVERRIDE_NO_AUTO_RESYNC
@ 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_FFMPEG
@ 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
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:1679
void BKE_reports_free(ReportList *reports)
Definition report.cc:70
void BKE_reports_init(ReportList *reports, int flag)
Definition report.cc:55
Scene * BKE_scene_set_name(Main *bmain, const char *name)
Definition scene.cc:2065
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:36
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:373
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:688
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:102
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 STREQ(a, b)
Compatibility-like things for windows.
bool BLI_windows_unregister_blend_extension(bool all_users)
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:608
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 CCL_start_debug_logging(void)
Definition logging.cpp:13
void CCL_logging_verbosity_set(const int verbosity)
Definition logging.cpp:18
void CLG_type_filter_exclude(const char *type_match, int type_match_len)
Definition clog.c:739
void CLG_output_set(void *file_handle)
Definition clog.c:709
void CLG_output_use_basename_set(int value)
Definition clog.c:714
void CLG_error_fn_set(void(*error_fn)(void *file_handle))
Definition clog.c:724
void CLG_backtrace_fn_set(void(*fatal_fn)(void *file_handle))
Definition clog.c:734
void CLG_type_filter_include(const char *type_match, int type_match_len)
Definition clog.c:744
void CLG_level_set(int level)
Definition clog.c:749
void CLG_output_use_timestamp_set(int value)
Definition clog.c:719
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_SYNC_TO_EVAL
Definition DNA_ID.h:1026
@ ID_TXT
#define MINAFRAME
@ R_IMF_IMTYPE_INVALID
struct Scene Scene
@ R_EXTENSION
#define MAXFRAME
struct wmWindowManager wmWindowManager
struct wmWindow wmWindow
void GPU_compilation_subprocess_override_set(int count)
void GPU_backend_type_selection_set_override(eGPUBackendType backend_type)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
ReportList * reports
Definition WM_types.hh:1025
BMesh const char void * data
char build_type[]
Definition bpy_app.cc:70
char build_cflags[]
Definition bpy_app.cc:71
char build_hash[]
Definition bpy_app.cc:67
char build_commit_date[]
Definition bpy_app.cc:65
char build_commit_time[]
Definition bpy_app.cc:66
char build_linkflags[]
Definition bpy_app.cc:73
char build_system[]
Definition bpy_app.cc:74
char build_branch[]
Definition bpy_app.cc:68
char build_date[]
Definition bpy_app.cc:62
char build_cxxflags[]
Definition bpy_app.cc:72
char build_time[]
Definition bpy_app.cc:63
char build_platform[]
Definition bpy_app.cc:69
BPy_StructRNA * depsgraph
ApplicationState app_state
Definition creator.cc:118
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 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_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 int arg_handle_without_borders(int, const char **, void *)
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_with_borders_doc[]
static const char arg_handle_debug_mode_generic_set_doc_ghost[]
static int arg_handle_with_borders(int, const char **, void *)
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 int arg_handle_log_show_basename_set(int, const char **, 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_log_level_set_doc[]
#define printf
static const char arg_handle_python_console_run_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 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 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[]
#define CB_ALL(a)
static const char arg_handle_without_borders_doc[]
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_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 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_crash_handler_disable(int, const char **, void *)
static const char arg_handle_debug_gpu_renderdoc_set_doc[]
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 int arg_handle_log_show_timestamp_set(int, const char **, void *)
static const char arg_handle_debug_mode_generic_set_doc_xr_time[]
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_log_show_basename_set_doc[]
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 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 const char arg_handle_unregister_extension_doc[]
static const char arg_handle_debug_gpu_scope_capture_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 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)
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 int arg_handle_print_version(int, const char **, void *)
static const char arg_handle_log_show_timestamp_set_doc[]
static const char arg_handle_debug_mode_generic_set_doc_ffmpeg[]
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_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_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_libmv
bool with_renderdoc
bool with_ffmpeg
bool with_cycles
bool with_xr_openxr
bool with_cycles_logging
bool with_freestyle
void * first
char * filepath
Definition WM_types.hh:1446
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
bool WM_file_read(bContext *C, const char *filepath, const bool use_scripts_autoexec_check, ReportList *reports)
Definition wm_files.cc:1046
void WM_init_state_app_template_set(const char *app_template)
Definition wm_files.cc:1187
char app_template[64]
Definition wm_files.cc:1183
void WM_exit(bContext *C, const int exit_code)
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)
void 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_state_fullscreen_set()
void WM_init_state_normal_set()
void WM_init_window_focus_set(bool do_it)