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