Fix blenderplayer build after OpenMP changes.
[blender.git] / source / creator / creator_args.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file creator/creator_args.c
22  *  \ingroup creator
23  */
24
25 #ifndef WITH_PYTHON_MODULE
26
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "CLG_log.h"
34
35 #ifdef WIN32
36 #  include "BLI_winstuff.h"
37 #endif
38
39 #include "BLI_args.h"
40 #include "BLI_threads.h"
41 #include "BLI_utildefines.h"
42 #include "BLI_listbase.h"
43 #include "BLI_string.h"
44 #include "BLI_string_utf8.h"
45 #include "BLI_path_util.h"
46 #include "BLI_fileops.h"
47 #include "BLI_mempool.h"
48 #include "BLI_system.h"
49
50 #include "BLO_readfile.h"  /* only for BLO_has_bfile_extension */
51
52 #include "BKE_blender_version.h"
53 #include "BKE_context.h"
54
55 #include "BKE_global.h"
56 #include "BKE_library.h"
57 #include "BKE_main.h"
58 #include "BKE_scene.h"
59 #include "BKE_report.h"
60 #include "BKE_sound.h"
61 #include "BKE_image.h"
62
63 #include "DNA_screen_types.h"
64
65 #include "DEG_depsgraph.h"
66
67 #ifdef WITH_FFMPEG
68 #include "IMB_imbuf.h"
69 #endif
70
71 #ifdef WITH_PYTHON
72 #include "BPY_extern.h"
73 #endif
74
75 #include "RE_engine.h"
76 #include "RE_pipeline.h"
77
78 #include "ED_datafiles.h"
79
80 #include "WM_api.h"
81
82 #include "GPU_basic_shader.h"
83 #include "GPU_draw.h"
84 #include "GPU_extensions.h"
85
86 /* for passing information between creator and gameengine */
87 #ifdef WITH_GAMEENGINE
88 #  include "BL_System.h"
89 #else /* dummy */
90 #  define SYS_SystemHandle int
91 #endif
92
93 #ifdef WITH_LIBMV
94 #  include "libmv-capi.h"
95 #endif
96
97 #ifdef WITH_CYCLES_LOGGING
98 #  include "CCL_api.h"
99 #endif
100
101 #include "creator_intern.h"  /* own include */
102
103
104 /* -------------------------------------------------------------------- */
105
106 /** \name Utility String Parsing
107  * \{ */
108
109 static bool parse_int_relative(
110         const char *str, const char *str_end_test, int pos, int neg,
111         int *r_value, const char **r_err_msg)
112 {
113         char *str_end = NULL;
114         long value;
115
116         errno = 0;
117
118         switch (*str) {
119                 case '+':
120                         value = pos + strtol(str + 1, &str_end, 10);
121                         break;
122                 case '-':
123                         value = (neg - strtol(str + 1, &str_end, 10)) + 1;
124                         break;
125                 default:
126                         value = strtol(str, &str_end, 10);
127                         break;
128         }
129
130
131         if (*str_end != '\0' && (str_end != str_end_test)) {
132                 static const char *msg = "not a number";
133                 *r_err_msg = msg;
134                 return false;
135         }
136         else if ((errno == ERANGE) || ((value < INT_MIN || value > INT_MAX))) {
137                 static const char *msg = "exceeds range";
138                 *r_err_msg = msg;
139                 return false;
140         }
141         else {
142                 *r_value = (int)value;
143                 return true;
144         }
145 }
146
147 static const char *parse_int_range_sep_search(const char *str, const char *str_end_test)
148 {
149         const char *str_end_range = NULL;
150         if (str_end_test) {
151                 str_end_range = memchr(str, '.', (str_end_test - str) - 1);
152                 if (str_end_range && (str_end_range[1] != '.')) {
153                         str_end_range = NULL;
154                 }
155         }
156         else {
157                 str_end_range = strstr(str, "..");
158                 if (str_end_range && (str_end_range[2] == '\0')) {
159                         str_end_range = NULL;
160                 }
161         }
162         return str_end_range;
163 }
164
165 /**
166  * Parse a number as a range, eg: `1..4`.
167  *
168  * The \a str_end_range argument is a result of #parse_int_range_sep_search.
169  */
170 static bool parse_int_range_relative(
171         const char *str, const char *str_end_range, const char *str_end_test, int pos, int neg,
172         int r_value_range[2], const char **r_err_msg)
173 {
174         if (parse_int_relative(str,               str_end_range, pos, neg, &r_value_range[0], r_err_msg) &&
175             parse_int_relative(str_end_range + 2, str_end_test,  pos, neg, &r_value_range[1], r_err_msg))
176         {
177                 return true;
178         }
179         else {
180                 return false;
181         }
182 }
183
184 static bool parse_int_relative_clamp(
185         const char *str, const char *str_end_test, int pos, int neg, int min, int max,
186         int *r_value, const char **r_err_msg)
187 {
188         if (parse_int_relative(str, str_end_test, pos, neg, r_value, r_err_msg)) {
189                 CLAMP(*r_value, min, max);
190                 return true;
191         }
192         else {
193                 return false;
194         }
195 }
196
197 static bool parse_int_range_relative_clamp(
198         const char *str, const char *str_end_range, const char *str_end_test, int pos, int neg, int min, int max,
199         int r_value_range[2], const char **r_err_msg)
200 {
201         if (parse_int_range_relative(str, str_end_range, str_end_test, pos, neg, r_value_range, r_err_msg)) {
202                 CLAMP(r_value_range[0], min, max);
203                 CLAMP(r_value_range[1], min, max);
204                 return true;
205         }
206         else {
207                 return false;
208         }
209 }
210
211 /**
212  * No clamping, fails with any number outside the range.
213  */
214 static bool parse_int_strict_range(
215         const char *str, const char *str_end_test, const int min, const int max,
216         int *r_value, const char **r_err_msg)
217 {
218         char *str_end = NULL;
219         long value;
220
221         errno = 0;
222         value = strtol(str, &str_end, 10);
223
224         if (*str_end != '\0' && (str_end != str_end_test)) {
225                 static const char *msg = "not a number";
226                 *r_err_msg = msg;
227                 return false;
228         }
229         else if ((errno == ERANGE) || ((value < min || value > max))) {
230                 static const char *msg = "exceeds range";
231                 *r_err_msg = msg;
232                 return false;
233         }
234         else {
235                 *r_value = (int)value;
236                 return true;
237         }
238 }
239
240 static bool parse_int(
241         const char *str, const char *str_end_test,
242         int *r_value, const char **r_err_msg)
243 {
244         return parse_int_strict_range(str, str_end_test, INT_MIN, INT_MAX, r_value, r_err_msg);
245 }
246
247 static bool parse_int_clamp(
248         const char *str, const char *str_end_test, int min, int max,
249         int *r_value, const char **r_err_msg)
250 {
251         if (parse_int(str, str_end_test, r_value, r_err_msg)) {
252                 CLAMP(*r_value, min, max);
253                 return true;
254         }
255         else {
256                 return false;
257         }
258 }
259
260 #if 0
261 /**
262  * Version of #parse_int_relative_clamp
263  * that parses a comma separated list of numbers.
264  */
265 static int *parse_int_relative_clamp_n(
266         const char *str, int pos, int neg, int min, int max,
267         int *r_value_len, const char **r_err_msg)
268 {
269         const char sep = ',';
270         int len = 1;
271         for (int i = 0; str[i]; i++) {
272                 if (str[i] == sep) {
273                         len++;
274                 }
275         }
276
277         int *values = MEM_mallocN(sizeof(*values) * len, __func__);
278         int i = 0;
279         while (true) {
280                 const char *str_end = strchr(str, sep);
281                 if ((*str == sep) || (*str == '\0')) {
282                         static const char *msg = "incorrect comma use";
283                         *r_err_msg = msg;
284                         goto fail;
285
286                 }
287                 else if (parse_int_relative_clamp(str, str_end, pos, neg, min, max, &values[i], r_err_msg)) {
288                         i++;
289                 }
290                 else {
291                         goto fail;  /* error message already set */
292                 }
293
294                 if (str_end) {  /* next */
295                         str = str_end + 1;
296                 }
297                 else {  /* finished */
298                         break;
299                 }
300         }
301
302         *r_value_len = i;
303         return values;
304
305 fail:
306         MEM_freeN(values);
307         return NULL;
308 }
309
310 #endif
311
312 /**
313  * Version of #parse_int_relative_clamp & #parse_int_range_relative_clamp
314  * that parses a comma separated list of numbers.
315  *
316  * \note single values are evaluated as a range with matching start/end.
317  */
318 static int (*parse_int_range_relative_clamp_n(
319         const char *str, int pos, int neg, int min, int max,
320         int *r_value_len, const char **r_err_msg))[2]
321 {
322         const char sep = ',';
323         int len = 1;
324         for (int i = 0; str[i]; i++) {
325                 if (str[i] == sep) {
326                         len++;
327                 }
328         }
329
330         int (*values)[2] = MEM_mallocN(sizeof(*values) * len, __func__);
331         int i = 0;
332         while (true) {
333                 const char *str_end_range;
334                 const char *str_end = strchr(str, sep);
335                 if ((*str == sep) || (*str == '\0')) {
336                         static const char *msg = "incorrect comma use";
337                         *r_err_msg = msg;
338                         goto fail;
339                 }
340                 else if ((str_end_range = parse_int_range_sep_search(str, str_end)) ?
341                          parse_int_range_relative_clamp(str, str_end_range, str_end, pos, neg, min, max, values[i], r_err_msg) :
342                          parse_int_relative_clamp(str, str_end, pos, neg, min, max, &values[i][0], r_err_msg))
343                 {
344                         if (str_end_range == NULL) {
345                                 values[i][1] = values[i][0];
346                         }
347                         i++;
348                 }
349                 else {
350                         goto fail;  /* error message already set */
351                 }
352
353                 if (str_end) {  /* next */
354                         str = str_end + 1;
355                 }
356                 else {  /* finished */
357                         break;
358                 }
359         }
360
361         *r_value_len = i;
362         return values;
363
364 fail:
365         MEM_freeN(values);
366         return NULL;
367 }
368
369 /** \} */
370
371
372 /* -------------------------------------------------------------------- */
373
374 #ifdef WITH_PYTHON
375
376 /** \name Utilities Python Context Macro (#BPY_CTX_SETUP)
377  * \{ */
378 struct BlendePyContextStore {
379         wmWindowManager *wm;
380         Scene *scene;
381         wmWindow *win;
382         bool has_win;
383 };
384
385 static void arg_py_context_backup(
386         bContext *C, struct BlendePyContextStore *c_py,
387         const char *script_id)
388 {
389         c_py->wm = CTX_wm_manager(C);
390         c_py->scene = CTX_data_scene(C);
391         c_py->has_win = !BLI_listbase_is_empty(&c_py->wm->windows);
392         if (c_py->has_win) {
393                 c_py->win = CTX_wm_window(C);
394                 CTX_wm_window_set(C, c_py->wm->windows.first);
395         }
396         else {
397                 c_py->win = NULL;
398                 fprintf(stderr, "Python script \"%s\" "
399                         "running with missing context data.\n", script_id);
400         }
401 }
402
403 static void arg_py_context_restore(
404         bContext *C, struct BlendePyContextStore *c_py)
405 {
406         /* script may load a file, check old data is valid before using */
407         if (c_py->has_win) {
408                 if ((c_py->win == NULL) ||
409                     ((BLI_findindex(&G_MAIN->wm, c_py->wm) != -1) &&
410                      (BLI_findindex(&c_py->wm->windows, c_py->win) != -1)))
411                 {
412                         CTX_wm_window_set(C, c_py->win);
413                 }
414         }
415
416         if ((c_py->scene == NULL) ||
417             BLI_findindex(&G_MAIN->scene, c_py->scene) != -1)
418         {
419                 CTX_data_scene_set(C, c_py->scene);
420         }
421 }
422
423 /* macro for context setup/reset */
424 #define BPY_CTX_SETUP(_cmd) \
425         { \
426                 struct BlendePyContextStore py_c; \
427                 arg_py_context_backup(C, &py_c, argv[1]); \
428                 { _cmd; } \
429                 arg_py_context_restore(C, &py_c); \
430         } ((void)0)
431
432 #endif /* WITH_PYTHON */
433
434 /** \} */
435
436
437 /* -------------------------------------------------------------------- */
438
439 /** \name Handle Argument Callbacks
440  *
441  * \note Doc strings here are used in differently:
442  *
443  * - The `--help` message.
444  * - The man page (for Unix systems),
445  *   see: `doc/manpage/blender.1.py`
446  * - Parsed and extracted for the manual,
447  *   which converts our ad-hoc formatting to reStructuredText.
448  *   see: https://docs.blender.org/manual/en/dev/advanced/command_line.html
449  *
450  * \{ */
451
452 static const char arg_handle_print_version_doc[] =
453 "\n\tPrint Blender version and exit."
454 ;
455 static int arg_handle_print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
456 {
457         printf(BLEND_VERSION_STRING_FMT);
458 #ifdef BUILD_DATE
459         printf("\tbuild date: %s\n", build_date);
460         printf("\tbuild time: %s\n", build_time);
461         printf("\tbuild commit date: %s\n", build_commit_date);
462         printf("\tbuild commit time: %s\n", build_commit_time);
463         printf("\tbuild hash: %s\n", build_hash);
464         printf("\tbuild platform: %s\n", build_platform);
465         printf("\tbuild type: %s\n", build_type);
466         printf("\tbuild c flags: %s\n", build_cflags);
467         printf("\tbuild c++ flags: %s\n", build_cxxflags);
468         printf("\tbuild link flags: %s\n", build_linkflags);
469         printf("\tbuild system: %s\n", build_system);
470 #endif
471         exit(0);
472
473         return 0;
474 }
475
476 static const char arg_handle_print_help_doc[] =
477 "\n\tPrint this help text and exit."
478 ;
479 static const char arg_handle_print_help_doc_win32[] =
480 "\n\tPrint this help text and exit (windows only)."
481 ;
482 static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
483 {
484         bArgs *ba = (bArgs *)data;
485
486         printf(BLEND_VERSION_STRING_FMT);
487         printf("Usage: blender [args ...] [file] [args ...]\n\n");
488
489         printf("Render Options:\n");
490         BLI_argsPrintArgDoc(ba, "--background");
491         BLI_argsPrintArgDoc(ba, "--render-anim");
492         BLI_argsPrintArgDoc(ba, "--scene");
493         BLI_argsPrintArgDoc(ba, "--render-frame");
494         BLI_argsPrintArgDoc(ba, "--frame-start");
495         BLI_argsPrintArgDoc(ba, "--frame-end");
496         BLI_argsPrintArgDoc(ba, "--frame-jump");
497         BLI_argsPrintArgDoc(ba, "--render-output");
498         BLI_argsPrintArgDoc(ba, "--engine");
499         BLI_argsPrintArgDoc(ba, "--threads");
500
501         printf("\n");
502         printf("Format Options:\n");
503         BLI_argsPrintArgDoc(ba, "--render-format");
504         BLI_argsPrintArgDoc(ba, "--use-extension");
505
506         printf("\n");
507         printf("Animation Playback Options:\n");
508         BLI_argsPrintArgDoc(ba, "-a");
509
510         printf("\n");
511         printf("Window Options:\n");
512         BLI_argsPrintArgDoc(ba, "--window-border");
513         BLI_argsPrintArgDoc(ba, "--window-fullscreen");
514         BLI_argsPrintArgDoc(ba, "--window-geometry");
515         BLI_argsPrintArgDoc(ba, "--start-console");
516         BLI_argsPrintArgDoc(ba, "--no-native-pixels");
517         BLI_argsPrintArgDoc(ba, "--no-window-focus");
518
519
520         printf("\n");
521         printf("Game Engine Specific Options:\n");
522         BLI_argsPrintArgDoc(ba, "-g");
523
524         printf("\n");
525         printf("Python Options:\n");
526         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
527         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
528
529         printf("\n");
530
531         BLI_argsPrintArgDoc(ba, "--python");
532         BLI_argsPrintArgDoc(ba, "--python-text");
533         BLI_argsPrintArgDoc(ba, "--python-expr");
534         BLI_argsPrintArgDoc(ba, "--python-console");
535         BLI_argsPrintArgDoc(ba, "--python-exit-code");
536         BLI_argsPrintArgDoc(ba, "--addons");
537
538         printf("\n");
539         printf("Logging Options:\n");
540         BLI_argsPrintArgDoc(ba, "--log");
541         BLI_argsPrintArgDoc(ba, "--log-level");
542         BLI_argsPrintArgDoc(ba, "--log-show-basename");
543         BLI_argsPrintArgDoc(ba, "--log-show-backtrace");
544         BLI_argsPrintArgDoc(ba, "--log-file");
545
546         printf("\n");
547         printf("Debug Options:\n");
548         BLI_argsPrintArgDoc(ba, "--debug");
549         BLI_argsPrintArgDoc(ba, "--debug-value");
550
551         printf("\n");
552         BLI_argsPrintArgDoc(ba, "--debug-events");
553 #ifdef WITH_FFMPEG
554         BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
555 #endif
556         BLI_argsPrintArgDoc(ba, "--debug-handlers");
557 #ifdef WITH_LIBMV
558         BLI_argsPrintArgDoc(ba, "--debug-libmv");
559 #endif
560 #ifdef WITH_CYCLES_LOGGING
561         BLI_argsPrintArgDoc(ba, "--debug-cycles");
562 #endif
563         BLI_argsPrintArgDoc(ba, "--debug-memory");
564         BLI_argsPrintArgDoc(ba, "--debug-jobs");
565         BLI_argsPrintArgDoc(ba, "--debug-python");
566         BLI_argsPrintArgDoc(ba, "--debug-depsgraph");
567         BLI_argsPrintArgDoc(ba, "--debug-depsgraph-eval");
568         BLI_argsPrintArgDoc(ba, "--debug-depsgraph-build");
569         BLI_argsPrintArgDoc(ba, "--debug-depsgraph-tag");
570         BLI_argsPrintArgDoc(ba, "--debug-depsgraph-no-threads");
571
572         BLI_argsPrintArgDoc(ba, "--debug-gpumem");
573         BLI_argsPrintArgDoc(ba, "--debug-gpu-shaders");
574         BLI_argsPrintArgDoc(ba, "--debug-wm");
575         BLI_argsPrintArgDoc(ba, "--debug-all");
576         BLI_argsPrintArgDoc(ba, "--debug-io");
577
578         printf("\n");
579         BLI_argsPrintArgDoc(ba, "--debug-fpe");
580         BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
581
582         printf("\n");
583         printf("Misc Options:\n");
584         BLI_argsPrintArgDoc(ba, "--app-template");
585         BLI_argsPrintArgDoc(ba, "--factory-startup");
586         printf("\n");
587         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
588         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
589         BLI_argsPrintArgDoc(ba, "--env-system-python");
590         printf("\n");
591         BLI_argsPrintArgDoc(ba, "-nojoystick");
592         BLI_argsPrintArgDoc(ba, "-noglsl");
593         BLI_argsPrintArgDoc(ba, "-noaudio");
594         BLI_argsPrintArgDoc(ba, "-setaudio");
595
596         printf("\n");
597
598         BLI_argsPrintArgDoc(ba, "--help");
599
600 #ifdef WIN32
601         BLI_argsPrintArgDoc(ba, "-R");
602         BLI_argsPrintArgDoc(ba, "-r");
603 #endif
604         BLI_argsPrintArgDoc(ba, "--version");
605
606         BLI_argsPrintArgDoc(ba, "--");
607
608         printf("\n");
609         printf("Experimental Features:\n");
610         BLI_argsPrintArgDoc(ba, "--enable-new-depsgraph");
611         BLI_argsPrintArgDoc(ba, "--enable-new-basic-shader-glsl");
612
613         /* Other options _must_ be last (anything not handled will show here) */
614         printf("\n");
615         printf("Other Options:\n");
616         BLI_argsPrintOtherDoc(ba);
617
618         printf("\n");
619         printf("Argument Parsing:\n");
620         printf("\tArguments must be separated by white space, eg:\n");
621         printf("\t# blender -ba test.blend\n");
622         printf("\t...will ignore the 'a'.\n");
623         printf("\t# blender -b test.blend -f8\n");
624         printf("\t...will ignore '8' because there is no space between the '-f' and the frame value.\n\n");
625
626         printf("Argument Order:\n");
627         printf("\tArguments are executed in the order they are given. eg:\n");
628         printf("\t# blender --background test.blend --render-frame 1 --render-output '/tmp'\n");
629         printf("\t...will not render to '/tmp' because '--render-frame 1' renders before the output path is set.\n");
630         printf("\t# blender --background --render-output /tmp test.blend --render-frame 1\n");
631         printf("\t...will not render to '/tmp' because loading the blend-file overwrites the render output that was set.\n");
632         printf("\t# blender --background test.blend --render-output /tmp --render-frame 1\n");
633         printf("\t...works as expected.\n\n");
634
635         printf("Environment Variables:\n");
636         printf("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
637         printf("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
638         printf("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
639         printf("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
640         printf("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
641         printf("  $BLENDER_SYSTEM_PYTHON    Directory for system Python libraries.\n");
642 #ifdef WIN32
643         printf("  $TEMP                     Store temporary files here.\n");
644 #else
645         printf("  $TMP or $TMPDIR           Store temporary files here.\n");
646 #endif
647 #ifdef WITH_SDL
648         printf("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
649 #endif
650         printf("  $PYTHONHOME               Path to the Python directory, eg. /usr/lib/python.\n\n");
651
652         exit(0);
653
654         return 0;
655 }
656
657 static const char arg_handle_arguments_end_doc[] =
658 "\n\tEnd option processing, following arguments passed unchanged. Access via Python's 'sys.argv'."
659 ;
660 static int arg_handle_arguments_end(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
661 {
662         return -1;
663 }
664
665 /* only to give help message */
666 #ifndef WITH_PYTHON_SECURITY /* default */
667 #  define   PY_ENABLE_AUTO ", (default)"
668 #  define   PY_DISABLE_AUTO ""
669 #else
670 #  define   PY_ENABLE_AUTO ""
671 #  define   PY_DISABLE_AUTO ", (compiled as non-standard default)"
672 #endif
673
674 static const char arg_handle_python_set_doc_enable[] =
675 "\n\tEnable automatic Python script execution" PY_ENABLE_AUTO "."
676 ;
677 static const char arg_handle_python_set_doc_disable[] =
678 "\n\tDisable automatic Python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO "."
679 ;
680 #undef PY_ENABLE_AUTO
681 #undef PY_DISABLE_AUTO
682
683 static int arg_handle_python_set(int UNUSED(argc), const char **UNUSED(argv), void *data)
684 {
685         if ((bool)data) {
686                 G.f |= G_SCRIPT_AUTOEXEC;
687         }
688         else {
689                 G.f &= ~G_SCRIPT_AUTOEXEC;
690         }
691         G.f |= G_SCRIPT_OVERRIDE_PREF;
692         return 0;
693 }
694
695 static const char arg_handle_crash_handler_disable_doc[] =
696 "\n\tDisable the crash handler."
697 ;
698 static int arg_handle_crash_handler_disable(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
699 {
700         app_state.signal.use_crash_handler = false;
701         return 0;
702 }
703
704 static const char arg_handle_abort_handler_disable_doc[] =
705 "\n\tDisable the abort handler."
706 ;
707 static int arg_handle_abort_handler_disable(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
708 {
709         app_state.signal.use_abort_handler = false;
710         return 0;
711 }
712
713 static const char arg_handle_background_mode_set_doc[] =
714 "\n\tRun in background (often used for UI-less rendering)."
715 ;
716 static int arg_handle_background_mode_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
717 {
718         G.background = 1;
719         return 0;
720 }
721
722 static const char arg_handle_log_level_set_doc[] =
723 "<level>\n"
724 "\n"
725 "\tSet the logging verbosity level (higher for more details) defaults to 1, use -1 to log all levels."
726 ;
727 static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(data))
728 {
729         const char *arg_id = "--log-level";
730         if (argc > 1) {
731                 const char *err_msg = NULL;
732                 if (!parse_int_clamp(argv[1], NULL, -1, INT_MAX, &G.log.level, &err_msg)) {
733                         printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
734                 }
735                 else {
736                         if (G.log.level == -1) {
737                                 G.log.level = INT_MAX;
738                         }
739                         CLG_level_set(G.log.level);
740                 }
741                 return 1;
742         }
743         else {
744                 printf("\nError: '%s' no args given.\n", arg_id);
745                 return 0;
746         }
747 }
748
749 static const char arg_handle_log_show_basename_set_doc[] =
750 "\n\tOnly show file name in output (not the leading path)."
751 ;
752 static int arg_handle_log_show_basename_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
753 {
754         CLG_output_use_basename_set(true);
755         return 0;
756 }
757
758 static const char arg_handle_log_show_backtrace_set_doc[] =
759 "\n\tShow a back trace for each log message (debug builds only)."
760 ;
761 static int arg_handle_log_show_backtrace_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
762 {
763         /* Ensure types don't become incompatible. */
764         void (*fn)(FILE *fp) = BLI_system_backtrace;
765         CLG_backtrace_fn_set((void (*)(void *))fn);
766         return 0;
767 }
768
769 static const char arg_handle_log_file_set_doc[] =
770 "<filename>\n"
771 "\n"
772 "\tSet a file to output the log to."
773 ;
774 static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(data))
775 {
776         const char *arg_id = "--log-file";
777         if (argc > 1) {
778                 errno = 0;
779                 FILE *fp = BLI_fopen(argv[1], "w");
780                 if (fp == NULL) {
781                         const char *err_msg = errno ? strerror(errno) : "unknown";
782                         printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
783                 }
784                 else {
785                         if (UNLIKELY(G.log.file != NULL)) {
786                                 fclose(G.log.file);
787                         }
788                         G.log.file = fp;
789                         CLG_output_set(G.log.file);
790                 }
791                 return 1;
792         }
793         else {
794                 printf("\nError: '%s' no args given.\n", arg_id);
795                 return 0;
796         }
797 }
798
799 static const char arg_handle_log_set_doc[] =
800 "<match>\n"
801 "\tEnable logging categories, taking a single comma separated argument.\n"
802 "\tMultiple categories can be matched using a '.*' suffix,\n"
803 "\tso '--log \"wm.*\"' logs every kind of window-manager message.\n"
804 "\tUse \"^\" prefix to ignore, so '--log \"*,^wm.operator.*\"' logs all except for 'wm.operators.*'\n"
805 "\tUse \"*\" to log everything."
806 ;
807 static int arg_handle_log_set(int argc, const char **argv, void *UNUSED(data))
808 {
809         const char *arg_id = "--log";
810         if (argc > 1) {
811                 const char *str_step = argv[1];
812                 while (*str_step) {
813                         const char *str_step_end = strchr(str_step, ',');
814                         int str_step_len = str_step_end ? (str_step_end - str_step) : strlen(str_step);
815
816                         if (str_step[0] == '^') {
817                                 CLG_type_filter_exclude(str_step + 1, str_step_len - 1);
818                         }
819                         else {
820                                 CLG_type_filter_include(str_step, str_step_len);
821                         }
822
823                         if (str_step_end) {
824                                 /* typically only be one, but don't fail on multiple.*/
825                                 while (*str_step_end == ',') {
826                                         str_step_end++;
827                                 }
828                                 str_step = str_step_end;
829                         }
830                         else {
831                                 break;
832                         }
833                 }
834                 return 1;
835         }
836         else {
837                 printf("\nError: '%s' no args given.\n", arg_id);
838                 return 0;
839         }
840 }
841
842 static const char arg_handle_debug_mode_set_doc[] =
843 "\n"
844 "\tTurn debugging on.\n"
845 "\n"
846 "\t* Enables memory error detection\n"
847 "\t* Disables mouse grab (to interact with a debugger in some cases)\n"
848 "\t* Keeps Python's 'sys.stdin' rather than setting it to None"
849 ;
850 static int arg_handle_debug_mode_set(int UNUSED(argc), const char **UNUSED(argv), void *data)
851 {
852         G.debug |= G_DEBUG;  /* std output printf's */
853         printf(BLEND_VERSION_STRING_FMT);
854         MEM_set_memory_debug();
855 #ifndef NDEBUG
856         BLI_mempool_set_memory_debug();
857 #endif
858
859 #ifdef WITH_BUILDINFO
860         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
861 #endif
862
863         BLI_argsPrint(data);
864         return 0;
865 }
866
867 #ifdef WITH_FFMPEG
868 static const char arg_handle_debug_mode_generic_set_doc_ffmpeg[] =
869 "\n\tEnable debug messages from FFmpeg library.";
870 #endif
871 #ifdef WITH_FREESTYLE
872 static const char arg_handle_debug_mode_generic_set_doc_freestyle[] =
873 "\n\tEnable debug messages for FreeStyle.";
874 #endif
875 static const char arg_handle_debug_mode_generic_set_doc_python[] =
876 "\n\tEnable debug messages for Python.";
877 static const char arg_handle_debug_mode_generic_set_doc_events[] =
878 "\n\tEnable debug messages for the event system.";
879 static const char arg_handle_debug_mode_generic_set_doc_handlers[] =
880 "\n\tEnable debug messages for event handling.";
881 static const char arg_handle_debug_mode_generic_set_doc_wm[] =
882 "\n\tEnable debug messages for the window manager, also prints every operator call.";
883 static const char arg_handle_debug_mode_generic_set_doc_jobs[] =
884 "\n\tEnable time profiling for background jobs.";
885 static const char arg_handle_debug_mode_generic_set_doc_gpu[] =
886 "\n\tEnable gpu debug context and information for OpenGL 4.3+.";
887 static const char arg_handle_debug_mode_generic_set_doc_depsgraph[] =
888 "\n\tEnable all debug messages from dependency graph.";
889 static const char arg_handle_debug_mode_generic_set_doc_depsgraph_build[] =
890 "\n\tEnable debug messages from dependency graph related on graph construction.";
891 static const char arg_handle_debug_mode_generic_set_doc_depsgraph_tag[] =
892 "\n\tEnable debug messages from dependency graph related on tagging.";
893 static const char arg_handle_debug_mode_generic_set_doc_depsgraph_time[] =
894 "\n\tEnable debug messages from dependency graph related on timing.";
895 static const char arg_handle_debug_mode_generic_set_doc_depsgraph_eval[] =
896 "\n\tEnable debug messages from dependency graph related on evaluation.";
897 static const char arg_handle_debug_mode_generic_set_doc_depsgraph_no_threads[] =
898 "\n\tSwitch dependency graph to a single threaded evaluation.";
899 static const char arg_handle_debug_mode_generic_set_doc_depsgraph_pretty[] =
900 "\n\tEnable colors for dependency graph debug messages.";
901 static const char arg_handle_debug_mode_generic_set_doc_gpumem[] =
902 "\n\tEnable GPU memory stats in status bar.";
903
904 static int arg_handle_debug_mode_generic_set(int UNUSED(argc), const char **UNUSED(argv), void *data)
905 {
906         G.debug |= POINTER_AS_INT(data);
907         return 0;
908 }
909
910 static const char arg_handle_debug_mode_io_doc[] =
911 "\n\tEnable debug messages for I/O (collada, ...).";
912 static int arg_handle_debug_mode_io(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
913 {
914         G.debug |= G_DEBUG_IO;
915         return 0;
916 }
917
918 static const char arg_handle_debug_mode_all_doc[] =
919 "\n\tEnable all debug messages.";
920 static int arg_handle_debug_mode_all(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
921 {
922         G.debug |= G_DEBUG_ALL;
923 #ifdef WITH_LIBMV
924         libmv_startDebugLogging();
925 #endif
926 #ifdef WITH_CYCLES_LOGGING
927         CCL_start_debug_logging();
928 #endif
929         return 0;
930 }
931
932 #ifdef WITH_LIBMV
933 static const char arg_handle_debug_mode_libmv_doc[] =
934 "\n\tEnable debug messages from libmv library."
935 ;
936 static int arg_handle_debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
937 {
938         libmv_startDebugLogging();
939
940         return 0;
941 }
942 #endif
943
944 #ifdef WITH_CYCLES_LOGGING
945 static const char arg_handle_debug_mode_cycles_doc[] =
946 "\n\tEnable debug messages from Cycles."
947 ;
948 static int arg_handle_debug_mode_cycles(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
949 {
950         CCL_start_debug_logging();
951         return 0;
952 }
953 #endif
954
955 static const char arg_handle_debug_mode_memory_set_doc[] =
956 "\n\tEnable fully guarded memory allocation and debugging."
957 ;
958 static int arg_handle_debug_mode_memory_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
959 {
960         MEM_set_memory_debug();
961         return 0;
962 }
963
964 static const char arg_handle_debug_value_set_doc[] =
965 "<value>\n"
966 "\tSet debug value of <value> on startup."
967 ;
968 static int arg_handle_debug_value_set(int argc, const char **argv, void *UNUSED(data))
969 {
970         const char *arg_id = "--debug-value";
971         if (argc > 1) {
972                 const char *err_msg = NULL;
973                 int value;
974                 if (!parse_int(argv[1], NULL, &value, &err_msg)) {
975                         printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
976                         return 1;
977                 }
978
979                 G.debug_value = value;
980
981                 return 1;
982         }
983         else {
984                 printf("\nError: you must specify debug value to set.\n");
985                 return 0;
986         }
987 }
988
989 static const char arg_handle_debug_fpe_set_doc[] =
990 "\n\tEnable floating point exceptions."
991 ;
992 static int arg_handle_debug_fpe_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
993 {
994         main_signal_setup_fpe();
995         return 0;
996 }
997
998 static const char arg_handle_app_template_doc[] =
999 "\n\tSet the application template, use 'default' for none."
1000 ;
1001 static int arg_handle_app_template(int argc, const char **argv, void *UNUSED(data))
1002 {
1003         if (argc > 1) {
1004                 const char *app_template = STREQ(argv[1], "default") ? "" : argv[1];
1005                 WM_init_state_app_template_set(app_template);
1006                 return 1;
1007         }
1008         else {
1009                 printf("\nError: App template must follow '--app-template'.\n");
1010                 return 0;
1011         }
1012 }
1013
1014 static const char arg_handle_factory_startup_set_doc[] =
1015 "\n\tSkip reading the " STRINGIFY(BLENDER_STARTUP_FILE) " in the users home directory."
1016 ;
1017 static int arg_handle_factory_startup_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1018 {
1019         G.factory_startup = 1;
1020         return 0;
1021 }
1022
1023 static const char arg_handle_env_system_set_doc_datafiles[] =
1024 "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable.";
1025 static const char arg_handle_env_system_set_doc_scripts[] =
1026 "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable.";
1027 static const char arg_handle_env_system_set_doc_python[] =
1028 "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable.";
1029
1030 static int arg_handle_env_system_set(int argc, const char **argv, void *UNUSED(data))
1031 {
1032         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
1033
1034         char env[64] = "BLENDER";
1035         char *ch_dst = env + 7; /* skip BLENDER */
1036         const char *ch_src = argv[0] + 5; /* skip --env */
1037
1038         if (argc < 2) {
1039                 printf("%s requires one argument\n", argv[0]);
1040                 exit(1);
1041         }
1042
1043         for (; *ch_src; ch_src++, ch_dst++) {
1044                 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
1045         }
1046
1047         *ch_dst = '\0';
1048         BLI_setenv(env, argv[1]);
1049         return 1;
1050 }
1051
1052 static const char arg_handle_playback_mode_doc[] =
1053 "<options> <file(s)>\n"
1054 "\tPlayback <file(s)>, only operates this way when not running in background.\n\n"
1055 "\t-p <sx> <sy>\n"
1056 "\t\tOpen with lower left corner at <sx>, <sy>.\n"
1057 "\t-m\n"
1058 "\t\tRead from disk (Do not buffer).\n"
1059 "\t-f <fps> <fps-base>\n"
1060 "\t\tSpecify FPS to start with.\n"
1061 "\t-j <frame>\n"
1062 "\t\tSet frame step to <frame>.\n"
1063 "\t-s <frame>\n"
1064 "\t\tPlay from <frame>.\n"
1065 "\t-e <frame>\n"
1066 "\t\tPlay until <frame>."
1067 ;
1068 static int arg_handle_playback_mode(int argc, const char **argv, void *UNUSED(data))
1069 {
1070         /* not if -b was given first */
1071         if (G.background == 0) {
1072 #ifdef WITH_FFMPEG
1073                 /* Setup FFmpeg with current debug flags. */
1074                 IMB_ffmpeg_init();
1075 #endif
1076
1077                 WM_main_playanim(argc, argv); /* not the same argc and argv as before */
1078                 exit(0); /* 2.4x didn't do this */
1079         }
1080
1081         return -2;
1082 }
1083
1084 static const char arg_handle_window_geometry_doc[] =
1085 "<sx> <sy> <w> <h>\n"
1086 "\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>."
1087 ;
1088 static int arg_handle_window_geometry(int argc, const char **argv, void *UNUSED(data))
1089 {
1090         const char *arg_id = "-p / --window-geometry";
1091         int params[4], i;
1092
1093         if (argc < 5) {
1094                 fprintf(stderr, "Error: requires four arguments '%s'\n", arg_id);
1095                 exit(1);
1096         }
1097
1098         for (i = 0; i < 4; i++) {
1099                 const char *err_msg = NULL;
1100                 if (!parse_int(argv[i + 1], NULL, &params[i], &err_msg)) {
1101                         printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1102                         exit(1);
1103                 }
1104         }
1105
1106         WM_init_state_size_set(UNPACK4(params));
1107
1108         return 4;
1109 }
1110
1111 static const char arg_handle_native_pixels_set_doc[] =
1112 "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')."
1113 ;
1114 static int arg_handle_native_pixels_set(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1115 {
1116         WM_init_native_pixels(false);
1117         return 0;
1118 }
1119
1120 static const char arg_handle_with_borders_doc[] =
1121 "\n\tForce opening with borders."
1122 ;
1123 static int arg_handle_with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1124 {
1125         WM_init_state_normal_set();
1126         return 0;
1127 }
1128
1129 static const char arg_handle_without_borders_doc[] =
1130 "\n\tForce opening in fullscreen mode."
1131 ;
1132 static int arg_handle_without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1133 {
1134         WM_init_state_fullscreen_set();
1135         return 0;
1136 }
1137
1138 static const char arg_handle_no_window_focus_doc[] =
1139 "\n\tOpen behind other windows and without taking focus."
1140 ;
1141 static int arg_handle_no_window_focus(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1142 {
1143         WM_init_window_focus_set(false);
1144         return 0;
1145 }
1146
1147 extern bool wm_start_with_console; /* wm_init_exit.c */
1148
1149 static const char arg_handle_start_with_console_doc[] =
1150 "\n\tStart with the console window open (ignored if -b is set), (Windows only)."
1151 ;
1152 static int arg_handle_start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1153 {
1154         wm_start_with_console = true;
1155         return 0;
1156 }
1157
1158 static const char arg_handle_register_extension_doc[] =
1159 "\n\tRegister blend-file extension, then exit (Windows only)."
1160 ;
1161 static const char arg_handle_register_extension_doc_silent[] =
1162 "\n\tSilently register blend-file extension, then exit (Windows only)."
1163 ;
1164 static int arg_handle_register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
1165 {
1166 #ifdef WIN32
1167         if (data)
1168                 G.background = 1;
1169         RegisterBlendExtension();
1170 #else
1171         (void)data; /* unused */
1172 #endif
1173         return 0;
1174 }
1175
1176 static const char arg_handle_joystick_disable_doc[] =
1177 "\n\tDisable joystick support."
1178 ;
1179 static int arg_handle_joystick_disable(int UNUSED(argc), const char **UNUSED(argv), void *data)
1180 {
1181 #ifndef WITH_GAMEENGINE
1182         (void)data;
1183 #else
1184         SYS_SystemHandle *syshandle = data;
1185
1186         /**
1187          * don't initialize joysticks if user doesn't want to use joysticks
1188          * failed joystick initialization delays over 5 seconds, before game engine start
1189          */
1190         SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
1191         if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
1192 #endif
1193
1194         return 0;
1195 }
1196
1197 static const char arg_handle_glsl_disable_doc[] =
1198 "\n\tDisable GLSL shading."
1199 ;
1200 static int arg_handle_glsl_disable(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1201 {
1202         GPU_extensions_disable();
1203         return 0;
1204 }
1205
1206 static const char arg_handle_audio_disable_doc[] =
1207 "\n\tForce sound system to None."
1208 ;
1209 static int arg_handle_audio_disable(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1210 {
1211         BKE_sound_force_device("Null");
1212         return 0;
1213 }
1214
1215 static const char arg_handle_audio_set_doc[] =
1216 "\n\tForce sound system to a specific device.\n\t'NULL' 'SDL' 'OPENAL' 'JACK'."
1217 ;
1218 static int arg_handle_audio_set(int argc, const char **argv, void *UNUSED(data))
1219 {
1220         if (argc < 1) {
1221                 fprintf(stderr, "-setaudio require one argument\n");
1222                 exit(1);
1223         }
1224
1225         BKE_sound_force_device(argv[1]);
1226         return 1;
1227 }
1228
1229 static const char arg_handle_output_set_doc[] =
1230 "<path>\n"
1231 "\tSet the render path and file name.\n"
1232 "\tUse '//' at the start of the path to render relative to the blend-file.\n"
1233 "\n"
1234 "\tThe '#' characters are replaced by the frame number, and used to define zero padding.\n"
1235 "\n"
1236 "\t* 'ani_##_test.png' becomes 'ani_01_test.png'\n"
1237 "\t* 'test-######.png' becomes 'test-000001.png'\n"
1238 "\n"
1239 "\tWhen the filename does not contain '#', The suffix '####' is added to the filename.\n"
1240 "\n"
1241 "\tThe frame number will be added at the end of the filename, eg:\n"
1242 "\t# blender -b foobar.blend -o //render_ -F PNG -x 1 -a\n"
1243 "\t'//render_' becomes '//render_####', writing frames as '//render_0001.png'"
1244 ;
1245 static int arg_handle_output_set(int argc, const char **argv, void *data)
1246 {
1247         bContext *C = data;
1248         if (argc > 1) {
1249                 Scene *scene = CTX_data_scene(C);
1250                 if (scene) {
1251                         BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
1252                 }
1253                 else {
1254                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
1255                 }
1256                 return 1;
1257         }
1258         else {
1259                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
1260                 return 0;
1261         }
1262 }
1263
1264 static const char arg_handle_engine_set_doc[] =
1265 "<engine>\n"
1266 "\tSpecify the render engine.\n\tUse -E help to list available engines."
1267 ;
1268 static int arg_handle_engine_set(int argc, const char **argv, void *data)
1269 {
1270         bContext *C = data;
1271         if (argc >= 2) {
1272                 if (STREQ(argv[1], "help")) {
1273                         RenderEngineType *type = NULL;
1274                         printf("Blender Engine Listing:\n");
1275                         for (type = R_engines.first; type; type = type->next) {
1276                                 printf("\t%s\n", type->idname);
1277                         }
1278                         exit(0);
1279                 }
1280                 else {
1281                         Scene *scene = CTX_data_scene(C);
1282                         if (scene) {
1283                                 RenderData *rd = &scene->r;
1284
1285                                 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
1286                                         BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
1287                                 }
1288                                 else {
1289                                         printf("\nError: engine not found '%s'\n", argv[1]);
1290                                         exit(1);
1291                                 }
1292                         }
1293                         else {
1294                                 printf("\nError: no blend loaded. "
1295                                        "order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
1296                         }
1297                 }
1298
1299                 return 1;
1300         }
1301         else {
1302                 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
1303                 return 0;
1304         }
1305 }
1306
1307 static const char arg_handle_image_type_set_doc[] =
1308 "<format>\n"
1309 "\tSet the render format.\n"
1310 "\tValid options are 'TGA' 'RAWTGA' 'JPEG' 'IRIS' 'IRIZ' 'AVIRAW' 'AVIJPEG' 'PNG' 'BMP'\n"
1311 "\n"
1312 "\tFormats that can be compiled into Blender, not available on all systems: 'HDR' 'TIFF' 'EXR' 'MULTILAYER'\n"
1313 "\t'MPEG' 'FRAMESERVER' 'CINEON' 'DPX' 'DDS' 'JP2'"
1314 ;
1315 static int arg_handle_image_type_set(int argc, const char **argv, void *data)
1316 {
1317         bContext *C = data;
1318         if (argc > 1) {
1319                 const char *imtype = argv[1];
1320                 Scene *scene = CTX_data_scene(C);
1321                 if (scene) {
1322                         const char imtype_new = BKE_imtype_from_arg(imtype);
1323
1324                         if (imtype_new == R_IMF_IMTYPE_INVALID) {
1325                                 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
1326                         }
1327                         else {
1328                                 scene->r.im_format.imtype = imtype_new;
1329                         }
1330                 }
1331                 else {
1332                         printf("\nError: no blend loaded. "
1333                                "order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
1334                 }
1335                 return 1;
1336         }
1337         else {
1338                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
1339                 return 0;
1340         }
1341 }
1342
1343 static const char arg_handle_threads_set_doc[] =
1344 "<threads>\n"
1345 "\tUse amount of <threads> for rendering and other operations\n"
1346 "\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems processor count."
1347 ;
1348 static int arg_handle_threads_set(int argc, const char **argv, void *UNUSED(data))
1349 {
1350         const char *arg_id = "-t / --threads";
1351         const int min = 0, max = BLENDER_MAX_THREADS;
1352         if (argc > 1) {
1353                 const char *err_msg = NULL;
1354                 int threads;
1355                 if (!parse_int_strict_range(argv[1], NULL, min, max, &threads, &err_msg)) {
1356                         printf("\nError: %s '%s %s', expected number in [%d..%d].\n", err_msg, arg_id, argv[1], min, max);
1357                         return 1;
1358                 }
1359
1360                 BLI_system_num_threads_override_set(threads);
1361                 return 1;
1362         }
1363         else {
1364                 printf("\nError: you must specify a number of threads in [%d..%d] '%s'.\n", min, max, arg_id);
1365                 return 0;
1366         }
1367 }
1368
1369 static const char arg_handle_depsgraph_use_new_doc[] =
1370 "\n\tUse new dependency graph."
1371 ;
1372 static int arg_handle_depsgraph_use_new(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1373 {
1374         printf("Using new dependency graph.\n");
1375         DEG_depsgraph_switch_to_new();
1376         return 0;
1377 }
1378
1379 static const char arg_handle_basic_shader_glsl_use_new_doc[] =
1380 "\n\tUse new GLSL basic shader."
1381 ;
1382 static int arg_handle_basic_shader_glsl_use_new(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
1383 {
1384         printf("Using new GLSL basic shader.\n");
1385         GPU_basic_shader_use_glsl_set(true);
1386         return 0;
1387 }
1388
1389 static const char arg_handle_verbosity_set_doc[] =
1390 "<verbose>\n"
1391 "\tSet logging verbosity level."
1392 ;
1393 static int arg_handle_verbosity_set(int argc, const char **argv, void *UNUSED(data))
1394 {
1395         const char *arg_id = "--verbose";
1396         if (argc > 1) {
1397                 const char *err_msg = NULL;
1398                 int level;
1399                 if (!parse_int(argv[1], NULL, &level, &err_msg)) {
1400                         printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1401                 }
1402
1403 #ifdef WITH_LIBMV
1404                 libmv_setLoggingVerbosity(level);
1405 #elif defined(WITH_CYCLES_LOGGING)
1406                 CCL_logging_verbosity_set(level);
1407 #else
1408                 (void)level;
1409 #endif
1410
1411                 return 1;
1412         }
1413         else {
1414                 printf("\nError: you must specify a verbosity level.\n");
1415                 return 0;
1416         }
1417 }
1418
1419 static const char arg_handle_extension_set_doc[] =
1420 "<bool>\n"
1421 "\tSet option to add the file extension to the end of the file."
1422 ;
1423 static int arg_handle_extension_set(int argc, const char **argv, void *data)
1424 {
1425         bContext *C = data;
1426         if (argc > 1) {
1427                 Scene *scene = CTX_data_scene(C);
1428                 if (scene) {
1429                         if (argv[1][0] == '0') {
1430                                 scene->r.scemode &= ~R_EXTENSION;
1431                         }
1432                         else if (argv[1][0] == '1') {
1433                                 scene->r.scemode |= R_EXTENSION;
1434                         }
1435                         else {
1436                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
1437                         }
1438                 }
1439                 else {
1440                         printf("\nError: no blend loaded. "
1441                                "order the arguments so '-o ' is after '-x '.\n");
1442                 }
1443                 return 1;
1444         }
1445         else {
1446                 printf("\nError: you must specify a path after '- '.\n");
1447                 return 0;
1448         }
1449 }
1450
1451 static const char arg_handle_ge_parameters_set_doc[] =
1452 "Game Engine specific options\n"
1453 "\n"
1454 "\t'fixedtime'\n"
1455 "\t\tRun on 50 hertz without dropping frames.\n"
1456 "\t'vertexarrays'\n"
1457 "\t\tUse Vertex Arrays for rendering (usually faster).\n"
1458 "\t'nomipmap'\n"
1459 "\t\tNo Texture Mipmapping.\n"
1460 "\t'linearmipmap'\n"
1461 "\t\tLinear Texture Mipmapping instead of Nearest (default)."
1462 ;
1463 static int arg_handle_ge_parameters_set(int argc, const char **argv, void *data)
1464 {
1465         int a = 0;
1466 #ifdef WITH_GAMEENGINE
1467         SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
1468 #else
1469         (void)data;
1470 #endif
1471
1472         /**
1473          * gameengine parameters are automatically put into system
1474          * -g [paramname = value]
1475          * -g [boolparamname]
1476          * example:
1477          * -g novertexarrays
1478          * -g maxvertexarraysize = 512
1479          */
1480
1481         if (argc >= 1) {
1482                 const char *paramname = argv[a];
1483                 /* check for single value versus assignment */
1484                 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
1485                         a++;
1486                         if (a + 1 < argc) {
1487                                 a++;
1488                                 /* assignment */
1489 #ifdef WITH_GAMEENGINE
1490                                 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
1491 #endif
1492                         }
1493                         else {
1494                                 printf("Error: argument assignment (%s) without value.\n", paramname);
1495                                 return 0;
1496                         }
1497                         /* name arg eaten */
1498
1499                 }
1500                 else {
1501 #ifdef WITH_GAMEENGINE
1502                         SYS_WriteCommandLineInt(syshandle, argv[a], 1);
1503 #endif
1504                         /* doMipMap */
1505                         if (STREQ(argv[a], "nomipmap")) {
1506                                 GPU_set_mipmap(G_MAIN, 0); //doMipMap = 0;
1507                         }
1508                         /* linearMipMap */
1509                         if (STREQ(argv[a], "linearmipmap")) {
1510                                 GPU_set_mipmap(G_MAIN, 1);
1511                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
1512                         }
1513
1514
1515                 } /* if (*(argv[a + 1]) == '=') */
1516         }
1517
1518         return a;
1519 }
1520
1521 static const char arg_handle_render_frame_doc[] =
1522 "<frame>\n"
1523 "\tRender frame <frame> and save it.\n"
1524 "\n"
1525 "\t* +<frame> start frame relative, -<frame> end frame relative.\n"
1526 "\t* A comma separated list of frames can also be used (no spaces).\n"
1527 "\t* A range of frames can be expressed using '..' separator between the first and last frames (inclusive).\n"
1528 ;
1529 static int arg_handle_render_frame(int argc, const char **argv, void *data)
1530 {
1531         const char *arg_id = "-f / --render-frame";
1532         bContext *C = data;
1533         Scene *scene = CTX_data_scene(C);
1534         if (scene) {
1535                 Main *bmain = CTX_data_main(C);
1536
1537                 if (argc > 1) {
1538                         const char *err_msg = NULL;
1539                         Render *re;
1540                         ReportList reports;
1541
1542                         int (*frame_range_arr)[2], frames_range_len;
1543                         if ((frame_range_arr = parse_int_range_relative_clamp_n(
1544                                  argv[1], scene->r.sfra, scene->r.efra, MINAFRAME, MAXFRAME,
1545                                  &frames_range_len, &err_msg)) == NULL)
1546                         {
1547                                 printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1548                                 return 1;
1549                         }
1550
1551                         re = RE_NewSceneRender(scene);
1552                         BLI_threaded_malloc_begin();
1553                         BKE_reports_init(&reports, RPT_STORE);
1554
1555                         RE_SetReports(re, &reports);
1556                         for (int i = 0; i < frames_range_len; i++) {
1557                                 /* We could pass in frame ranges,
1558                                  * but prefer having exact behavior as passing in multiple frames */
1559                                 if ((frame_range_arr[i][0] <= frame_range_arr[i][1]) == 0) {
1560                                         printf("\nWarning: negative range ignored '%s %s'.\n", arg_id, argv[1]);
1561                                 }
1562
1563                                 for (int frame = frame_range_arr[i][0]; frame <= frame_range_arr[i][1]; frame++) {
1564                                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
1565                                 }
1566                         }
1567                         RE_SetReports(re, NULL);
1568                         BKE_reports_clear(&reports);
1569                         BLI_threaded_malloc_end();
1570                         MEM_freeN(frame_range_arr);
1571                         return 1;
1572                 }
1573                 else {
1574                         printf("\nError: frame number must follow '%s'.\n", arg_id);
1575                         return 0;
1576                 }
1577         }
1578         else {
1579                 printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id);
1580                 return 0;
1581         }
1582 }
1583
1584 static const char arg_handle_render_animation_doc[] =
1585 "\n\tRender frames from start to end (inclusive)."
1586 ;
1587 static int arg_handle_render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
1588 {
1589         bContext *C = data;
1590         Scene *scene = CTX_data_scene(C);
1591         if (scene) {
1592                 Main *bmain = CTX_data_main(C);
1593                 Render *re = RE_NewSceneRender(scene);
1594                 ReportList reports;
1595                 BLI_threaded_malloc_begin();
1596                 BKE_reports_init(&reports, RPT_STORE);
1597                 RE_SetReports(re, &reports);
1598                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
1599                 RE_SetReports(re, NULL);
1600                 BKE_reports_clear(&reports);
1601                 BLI_threaded_malloc_end();
1602         }
1603         else {
1604                 printf("\nError: no blend loaded. cannot use '-a'.\n");
1605         }
1606         return 0;
1607 }
1608
1609 static const char arg_handle_scene_set_doc[] =
1610 "<name>\n"
1611 "\tSet the active scene <name> for rendering."
1612 ;
1613 static int arg_handle_scene_set(int argc, const char **argv, void *data)
1614 {
1615         if (argc > 1) {
1616                 bContext *C = data;
1617                 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
1618                 if (scene) {
1619                         CTX_data_scene_set(C, scene);
1620
1621                         /* Set the scene of the first window, see: T55991,
1622                          * otherwise scrips that run later won't get this scene back from the context. */
1623                         wmWindow *win = CTX_wm_window(C);
1624                         if (win == NULL) {
1625                                 win = CTX_wm_manager(C)->windows.first;
1626                         }
1627                         if (win != NULL) {
1628                                 win->screen->scene = scene;
1629                         }
1630                 }
1631                 return 1;
1632         }
1633         else {
1634                 printf("\nError: Scene name must follow '-S / --scene'.\n");
1635                 return 0;
1636         }
1637 }
1638
1639 static const char arg_handle_frame_start_set_doc[] =
1640 "<frame>\n"
1641 "\tSet start to frame <frame>, supports +/- for relative frames too."
1642 ;
1643 static int arg_handle_frame_start_set(int argc, const char **argv, void *data)
1644 {
1645         const char *arg_id = "-s / --frame-start";
1646         bContext *C = data;
1647         Scene *scene = CTX_data_scene(C);
1648         if (scene) {
1649                 if (argc > 1) {
1650                         const char *err_msg = NULL;
1651                         if (!parse_int_relative_clamp(
1652                                 argv[1], NULL, scene->r.sfra, scene->r.sfra - 1, MINAFRAME, MAXFRAME,
1653                                 &scene->r.sfra, &err_msg))
1654                         {
1655                                 printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1656                         }
1657                         return 1;
1658                 }
1659                 else {
1660                         printf("\nError: frame number must follow '%s'.\n", arg_id);
1661                         return 0;
1662                 }
1663         }
1664         else {
1665                 printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id);
1666                 return 0;
1667         }
1668 }
1669
1670 static const char arg_handle_frame_end_set_doc[] =
1671 "<frame>\n"
1672 "\tSet end to frame <frame>, supports +/- for relative frames too."
1673 ;
1674 static int arg_handle_frame_end_set(int argc, const char **argv, void *data)
1675 {
1676         const char *arg_id = "-e / --frame-end";
1677         bContext *C = data;
1678         Scene *scene = CTX_data_scene(C);
1679         if (scene) {
1680                 if (argc > 1) {
1681                         const char *err_msg = NULL;
1682                         if (!parse_int_relative_clamp(
1683                                 argv[1], NULL, scene->r.efra, scene->r.efra - 1, MINAFRAME, MAXFRAME,
1684                                 &scene->r.efra, &err_msg))
1685                         {
1686                                 printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1687                         }
1688                         return 1;
1689                 }
1690                 else {
1691                         printf("\nError: frame number must follow '%s'.\n", arg_id);
1692                         return 0;
1693                 }
1694         }
1695         else {
1696                 printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id);
1697                 return 0;
1698         }
1699 }
1700
1701 static const char arg_handle_frame_skip_set_doc[] =
1702 "<frames>\n"
1703 "\tSet number of frames to step forward after each rendered frame."
1704 ;
1705 static int arg_handle_frame_skip_set(int argc, const char **argv, void *data)
1706 {
1707         const char *arg_id = "-j / --frame-jump";
1708         bContext *C = data;
1709         Scene *scene = CTX_data_scene(C);
1710         if (scene) {
1711                 if (argc > 1) {
1712                         const char *err_msg = NULL;
1713                         if (!parse_int_clamp(argv[1], NULL, 1, MAXFRAME, &scene->r.frame_step, &err_msg)) {
1714                                 printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]);
1715                         }
1716                         return 1;
1717                 }
1718                 else {
1719                         printf("\nError: number of frames to step must follow '%s'.\n", arg_id);
1720                         return 0;
1721                 }
1722         }
1723         else {
1724                 printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id);
1725                 return 0;
1726         }
1727 }
1728
1729 static const char arg_handle_python_file_run_doc[] =
1730 "<filename>\n"
1731 "\tRun the given Python script file."
1732 ;
1733 static int arg_handle_python_file_run(int argc, const char **argv, void *data)
1734 {
1735 #ifdef WITH_PYTHON
1736         bContext *C = data;
1737
1738         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1739         if (argc > 1) {
1740                 /* Make the path absolute because its needed for relative linked blends to be found */
1741                 char filename[FILE_MAX];
1742                 BLI_strncpy(filename, argv[1], sizeof(filename));
1743                 BLI_path_cwd(filename, sizeof(filename));
1744
1745                 bool ok;
1746                 BPY_CTX_SETUP(ok = BPY_execute_filepath(C, filename, NULL));
1747                 if (!ok && app_state.exit_code_on_error.python) {
1748                         printf("\nError: script failed, file: '%s', exiting.\n", argv[1]);
1749                         exit(app_state.exit_code_on_error.python);
1750                 }
1751                 return 1;
1752         }
1753         else {
1754                 printf("\nError: you must specify a filepath after '%s'.\n", argv[0]);
1755                 return 0;
1756         }
1757 #else
1758         UNUSED_VARS(argc, argv, data);
1759         printf("This Blender was built without Python support\n");
1760         return 0;
1761 #endif /* WITH_PYTHON */
1762 }
1763
1764 static const char arg_handle_python_text_run_doc[] =
1765 "<name>\n"
1766 "\tRun the given Python script text block."
1767 ;
1768 static int arg_handle_python_text_run(int argc, const char **argv, void *data)
1769 {
1770 #ifdef WITH_PYTHON
1771         bContext *C = data;
1772
1773         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1774         if (argc > 1) {
1775                 Main *bmain = CTX_data_main(C);
1776                 /* Make the path absolute because its needed for relative linked blends to be found */
1777                 struct Text *text = (struct Text *)BKE_libblock_find_name(bmain, ID_TXT, argv[1]);
1778                 bool ok;
1779
1780                 if (text) {
1781                         BPY_CTX_SETUP(ok = BPY_execute_text(C, text, NULL, false));
1782                 }
1783                 else {
1784                         printf("\nError: text block not found %s.\n", argv[1]);
1785                         ok = false;
1786                 }
1787
1788                 if (!ok && app_state.exit_code_on_error.python) {
1789                         printf("\nError: script failed, text: '%s', exiting.\n", argv[1]);
1790                         exit(app_state.exit_code_on_error.python);
1791                 }
1792
1793                 return 1;
1794         }
1795         else {
1796                 printf("\nError: you must specify a text block after '%s'.\n", argv[0]);
1797                 return 0;
1798         }
1799 #else
1800         UNUSED_VARS(argc, argv, data);
1801         printf("This Blender was built without Python support\n");
1802         return 0;
1803 #endif /* WITH_PYTHON */
1804 }
1805
1806 static const char arg_handle_python_expr_run_doc[] =
1807 "<expression>\n"
1808 "\tRun the given expression as a Python script."
1809 ;
1810 static int arg_handle_python_expr_run(int argc, const char **argv, void *data)
1811 {
1812 #ifdef WITH_PYTHON
1813         bContext *C = data;
1814
1815         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1816         if (argc > 1) {
1817                 bool ok;
1818                 BPY_CTX_SETUP(ok = BPY_execute_string_ex(C, NULL, argv[1], false));
1819                 if (!ok && app_state.exit_code_on_error.python) {
1820                         printf("\nError: script failed, expr: '%s', exiting.\n", argv[1]);
1821                         exit(app_state.exit_code_on_error.python);
1822                 }
1823                 return 1;
1824         }
1825         else {
1826                 printf("\nError: you must specify a Python expression after '%s'.\n", argv[0]);
1827                 return 0;
1828         }
1829 #else
1830         UNUSED_VARS(argc, argv, data);
1831         printf("This Blender was built without Python support\n");
1832         return 0;
1833 #endif /* WITH_PYTHON */
1834 }
1835
1836 static const char arg_handle_python_console_run_doc[] =
1837 "\n\tRun Blender with an interactive console."
1838 ;
1839 static int arg_handle_python_console_run(int UNUSED(argc), const char **argv, void *data)
1840 {
1841 #ifdef WITH_PYTHON
1842         bContext *C = data;
1843
1844         BPY_CTX_SETUP(BPY_execute_string(C, (const char *[]){"code", NULL}, "code.interact()"));
1845
1846         return 0;
1847 #else
1848         UNUSED_VARS(argv, data);
1849         printf("This Blender was built without python support\n");
1850         return 0;
1851 #endif /* WITH_PYTHON */
1852 }
1853
1854 static const char arg_handle_python_exit_code_set_doc[] =
1855 "<code>\n"
1856 "\tSet the exit-code in [0..255] to exit if a Python exception is raised\n"
1857 "\t(only for scripts executed from the command line), zero disables."
1858 ;
1859 static int arg_handle_python_exit_code_set(int argc, const char **argv, void *UNUSED(data))
1860 {
1861         const char *arg_id = "--python-exit-code";
1862         if (argc > 1) {
1863                 const char *err_msg = NULL;
1864                 const int min = 0, max = 255;
1865                 int exit_code;
1866                 if (!parse_int_strict_range(argv[1], NULL, min, max, &exit_code, &err_msg)) {
1867                         printf("\nError: %s '%s %s', expected number in [%d..%d].\n", err_msg, arg_id, argv[1], min, max);
1868                         return 1;
1869                 }
1870
1871                 app_state.exit_code_on_error.python = (unsigned char)exit_code;
1872                 return 1;
1873         }
1874         else {
1875                 printf("\nError: you must specify an exit code number '%s'.\n", arg_id);
1876                 return 0;
1877         }
1878 }
1879
1880 static const char arg_handle_addons_set_doc[] =
1881 "<addon(s)>\n"
1882 "\tComma separated list of add-ons (no spaces)."
1883 ;
1884 static int arg_handle_addons_set(int argc, const char **argv, void *data)
1885 {
1886         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1887         if (argc > 1) {
1888 #ifdef WITH_PYTHON
1889                 const char script_str[] =
1890                         "from addon_utils import check, enable\n"
1891                         "for m in '%s'.split(','):\n"
1892                         "    if check(m)[1] is False:\n"
1893                         "        enable(m, persistent=True)";
1894                 const int slen = strlen(argv[1]) + (sizeof(script_str) - 2);
1895                 char *str = malloc(slen);
1896                 bContext *C = data;
1897                 BLI_snprintf(str, slen, script_str, argv[1]);
1898
1899                 BLI_assert(strlen(str) + 1 == slen);
1900                 BPY_CTX_SETUP(BPY_execute_string_ex(C, NULL, str, false));
1901                 free(str);
1902 #else
1903                 UNUSED_VARS(argv, data);
1904 #endif /* WITH_PYTHON */
1905                 return 1;
1906         }
1907         else {
1908                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
1909                 return 0;
1910         }
1911 }
1912
1913 static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data)
1914 {
1915         bContext *C = data;
1916         ReportList reports;
1917         bool success;
1918
1919         /* Make the path absolute because its needed for relative linked blends to be found */
1920         char filename[FILE_MAX];
1921
1922         /* note, we could skip these, but so far we always tried to load these files */
1923         if (argv[0][0] == '-') {
1924                 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1925         }
1926
1927         BLI_strncpy(filename, argv[0], sizeof(filename));
1928         BLI_path_cwd(filename, sizeof(filename));
1929
1930         /* load the file */
1931         BKE_reports_init(&reports, RPT_PRINT);
1932         WM_file_autoexec_init(filename);
1933         success = WM_file_read(C, filename, &reports);
1934         BKE_reports_clear(&reports);
1935
1936         if (success) {
1937                 if (G.background) {
1938                         /* ensuer we use 'C->data.scene' for background render */
1939                         CTX_wm_window_set(C, NULL);
1940                 }
1941         }
1942         else {
1943                 /* failed to load file, stop processing arguments if running in background mode */
1944                 if (G.background) {
1945                         /* Set is_break if running in the background mode so
1946                          * blender will return non-zero exit code which then
1947                          * could be used in automated script to control how
1948                          * good or bad things are.
1949                          */
1950                         G.is_break = true;
1951                         return -1;
1952                 }
1953
1954                 if (BLO_has_bfile_extension(filename)) {
1955                         /* Just pretend a file was loaded, so the user can press Save and it'll
1956                          * save at the filename from the CLI. */
1957                         BLI_strncpy(G_MAIN->name, filename, FILE_MAX);
1958                         G.relbase_valid = true;
1959                         G.save_over = true;
1960                         printf("... opened default scene instead; saving will write to: %s\n", filename);
1961                 }
1962                 else {
1963                         printf("Error: argument has no '.blend' file extension, not using as new file, exiting! %s\n", filename);
1964                         G.is_break = true;
1965                         WM_exit(C);
1966                 }
1967         }
1968
1969         G.file_loaded = 1;
1970
1971         return 0;
1972 }
1973
1974
1975 void main_args_setup(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1976 {
1977
1978 #define CB(a) a##_doc, a
1979 #define CB_EX(a, b) a##_doc_##b, a
1980
1981         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1982
1983         /* end argument processing after -- */
1984         BLI_argsAdd(ba, -1, "--", NULL, CB(arg_handle_arguments_end), NULL);
1985
1986         /* first pass: background mode, disable python and commands that exit after usage */
1987         BLI_argsAdd(ba, 1, "-h", "--help", CB(arg_handle_print_help), ba);
1988         /* Windows only */
1989         BLI_argsAdd(ba, 1, "/?", NULL, CB_EX(arg_handle_print_help, win32), ba);
1990
1991         BLI_argsAdd(ba, 1, "-v", "--version", CB(arg_handle_print_version), NULL);
1992
1993         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", CB_EX(arg_handle_python_set, enable), (void *)true);
1994         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", CB_EX(arg_handle_python_set, disable), (void *)false);
1995
1996         BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", CB(arg_handle_crash_handler_disable), NULL);
1997         BLI_argsAdd(ba, 1, NULL, "--disable-abort-handler", CB(arg_handle_abort_handler_disable), NULL);
1998
1999         BLI_argsAdd(ba, 1, "-b", "--background", CB(arg_handle_background_mode_set), NULL);
2000
2001         BLI_argsAdd(ba, 1, "-a", NULL, CB(arg_handle_playback_mode), NULL);
2002
2003         BLI_argsAdd(ba, 1, NULL, "--log", CB(arg_handle_log_set), ba);
2004         BLI_argsAdd(ba, 1, NULL, "--log-level", CB(arg_handle_log_level_set), ba);
2005         BLI_argsAdd(ba, 1, NULL, "--log-show-basename", CB(arg_handle_log_show_basename_set), ba);
2006         BLI_argsAdd(ba, 1, NULL, "--log-show-backtrace", CB(arg_handle_log_show_backtrace_set), ba);
2007         BLI_argsAdd(ba, 1, NULL, "--log-file", CB(arg_handle_log_file_set), ba);
2008
2009         BLI_argsAdd(ba, 1, "-d", "--debug", CB(arg_handle_debug_mode_set), ba);
2010
2011 #ifdef WITH_FFMPEG
2012         BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg",
2013                     CB_EX(arg_handle_debug_mode_generic_set, ffmpeg), (void *)G_DEBUG_FFMPEG);
2014 #endif
2015
2016 #ifdef WITH_FREESTYLE
2017         BLI_argsAdd(ba, 1, NULL, "--debug-freestyle",
2018                     CB_EX(arg_handle_debug_mode_generic_set, freestyle), (void *)G_DEBUG_FREESTYLE);
2019 #endif
2020
2021         BLI_argsAdd(ba, 1, NULL, "--debug-python",
2022                     CB_EX(arg_handle_debug_mode_generic_set, python), (void *)G_DEBUG_PYTHON);
2023         BLI_argsAdd(ba, 1, NULL, "--debug-events",
2024                     CB_EX(arg_handle_debug_mode_generic_set, events), (void *)G_DEBUG_EVENTS);
2025         BLI_argsAdd(ba, 1, NULL, "--debug-handlers",
2026                     CB_EX(arg_handle_debug_mode_generic_set, handlers), (void *)G_DEBUG_HANDLERS);
2027         BLI_argsAdd(ba, 1, NULL, "--debug-wm",
2028                     CB_EX(arg_handle_debug_mode_generic_set, wm), (void *)G_DEBUG_WM);
2029         BLI_argsAdd(ba, 1, NULL, "--debug-all", CB(arg_handle_debug_mode_all), NULL);
2030
2031         BLI_argsAdd(ba, 1, NULL, "--debug-io", CB(arg_handle_debug_mode_io), NULL);
2032
2033         BLI_argsAdd(ba, 1, NULL, "--debug-fpe",
2034                     CB(arg_handle_debug_fpe_set), NULL);
2035
2036 #ifdef WITH_LIBMV
2037         BLI_argsAdd(ba, 1, NULL, "--debug-libmv", CB(arg_handle_debug_mode_libmv), NULL);
2038 #endif
2039 #ifdef WITH_CYCLES_LOGGING
2040         BLI_argsAdd(ba, 1, NULL, "--debug-cycles", CB(arg_handle_debug_mode_cycles), NULL);
2041 #endif
2042         BLI_argsAdd(ba, 1, NULL, "--debug-memory", CB(arg_handle_debug_mode_memory_set), NULL);
2043
2044         BLI_argsAdd(ba, 1, NULL, "--debug-value",
2045                     CB(arg_handle_debug_value_set), NULL);
2046         BLI_argsAdd(ba, 1, NULL, "--debug-jobs",
2047                     CB_EX(arg_handle_debug_mode_generic_set, jobs), (void *)G_DEBUG_JOBS);
2048         BLI_argsAdd(ba, 1, NULL, "--debug-gpu",
2049                     CB_EX(arg_handle_debug_mode_generic_set, gpu), (void *)G_DEBUG_GPU);
2050         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph",
2051                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph), (void *)G_DEBUG_DEPSGRAPH);
2052         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph-build",
2053                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build), (void *)G_DEBUG_DEPSGRAPH_BUILD);
2054         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph-eval",
2055                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph_eval), (void *)G_DEBUG_DEPSGRAPH_EVAL);
2056         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph-tag",
2057                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph_tag), (void *)G_DEBUG_DEPSGRAPH_TAG);
2058         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph-time",
2059                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph_time), (void *)G_DEBUG_DEPSGRAPH_TIME);
2060         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph-no-threads",
2061                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph_no_threads), (void *)G_DEBUG_DEPSGRAPH_NO_THREADS);
2062         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph-pretty",
2063                     CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty), (void *)G_DEBUG_DEPSGRAPH_PRETTY);
2064         BLI_argsAdd(ba, 1, NULL, "--debug-gpumem",
2065                     CB_EX(arg_handle_debug_mode_generic_set, gpumem), (void *)G_DEBUG_GPU_MEM);
2066         BLI_argsAdd(ba, 1, NULL, "--debug-gpu-shaders",
2067                     CB_EX(arg_handle_debug_mode_generic_set, gpumem), (void *)G_DEBUG_GPU_SHADERS);
2068
2069         BLI_argsAdd(ba, 1, NULL, "--enable-new-depsgraph", CB(arg_handle_depsgraph_use_new), NULL);
2070         BLI_argsAdd(ba, 1, NULL, "--enable-new-basic-shader-glsl", CB(arg_handle_basic_shader_glsl_use_new), NULL);
2071
2072         BLI_argsAdd(ba, 1, NULL, "--verbose", CB(arg_handle_verbosity_set), NULL);
2073
2074         BLI_argsAdd(ba, 1, NULL, "--app-template", CB(arg_handle_app_template), NULL);
2075         BLI_argsAdd(ba, 1, NULL, "--factory-startup", CB(arg_handle_factory_startup_set), NULL);
2076
2077         /* TODO, add user env vars? */
2078         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", CB_EX(arg_handle_env_system_set, datafiles), NULL);
2079         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", CB_EX(arg_handle_env_system_set, scripts), NULL);
2080         BLI_argsAdd(ba, 1, NULL, "--env-system-python", CB_EX(arg_handle_env_system_set, python), NULL);
2081
2082         /* second pass: custom window stuff */
2083         BLI_argsAdd(ba, 2, "-p", "--window-geometry", CB(arg_handle_window_geometry), NULL);
2084         BLI_argsAdd(ba, 2, "-w", "--window-border", CB(arg_handle_with_borders), NULL);
2085         BLI_argsAdd(ba, 2, "-W", "--window-fullscreen", CB(arg_handle_without_borders), NULL);
2086         BLI_argsAdd(ba, 2, NULL, "--no-window-focus", CB(arg_handle_no_window_focus), NULL);
2087         BLI_argsAdd(ba, 2, "-con", "--start-console", CB(arg_handle_start_with_console), NULL);
2088         BLI_argsAdd(ba, 2, "-R", NULL, CB(arg_handle_register_extension), NULL);
2089         BLI_argsAdd(ba, 2, "-r", NULL, CB_EX(arg_handle_register_extension, silent), ba);
2090         BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", CB(arg_handle_native_pixels_set), ba);
2091
2092         /* third pass: disabling things and forcing settings */
2093         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, CB(arg_handle_joystick_disable), syshandle);
2094         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, CB(arg_handle_glsl_disable), NULL);
2095         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, CB(arg_handle_audio_disable), NULL);
2096         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, CB(arg_handle_audio_set), NULL);
2097
2098         /* fourth pass: processing arguments */
2099         BLI_argsAdd(ba, 4, "-g", NULL, CB(arg_handle_ge_parameters_set), syshandle);
2100         BLI_argsAdd(ba, 4, "-f", "--render-frame", CB(arg_handle_render_frame), C);
2101         BLI_argsAdd(ba, 4, "-a", "--render-anim", CB(arg_handle_render_animation), C);
2102         BLI_argsAdd(ba, 4, "-S", "--scene", CB(arg_handle_scene_set), C);
2103         BLI_argsAdd(ba, 4, "-s", "--frame-start", CB(arg_handle_frame_start_set), C);
2104         BLI_argsAdd(ba, 4, "-e", "--frame-end", CB(arg_handle_frame_end_set), C);
2105         BLI_argsAdd(ba, 4, "-j", "--frame-jump", CB(arg_handle_frame_skip_set), C);
2106         BLI_argsAdd(ba, 4, "-P", "--python", CB(arg_handle_python_file_run), C);
2107         BLI_argsAdd(ba, 4, NULL, "--python-text", CB(arg_handle_python_text_run), C);
2108         BLI_argsAdd(ba, 4, NULL, "--python-expr", CB(arg_handle_python_expr_run), C);
2109         BLI_argsAdd(ba, 4, NULL, "--python-console", CB(arg_handle_python_console_run), C);
2110         BLI_argsAdd(ba, 4, NULL, "--python-exit-code", CB(arg_handle_python_exit_code_set), NULL);
2111         BLI_argsAdd(ba, 4, NULL, "--addons", CB(arg_handle_addons_set), C);
2112
2113         BLI_argsAdd(ba, 4, "-o", "--render-output", CB(arg_handle_output_set), C);
2114         BLI_argsAdd(ba, 4, "-E", "--engine", CB(arg_handle_engine_set), C);
2115
2116         BLI_argsAdd(ba, 4, "-F", "--render-format", CB(arg_handle_image_type_set), C);
2117         BLI_argsAdd(ba, 1, "-t", "--threads", CB(arg_handle_threads_set), NULL);
2118         BLI_argsAdd(ba, 4, "-x", "--use-extension", CB(arg_handle_extension_set), C);
2119
2120 #undef CB
2121 #undef CB_EX
2122
2123 }
2124
2125 /**
2126  * Needs to be added separately.
2127  */
2128 void main_args_setup_post(bContext *C, bArgs *ba)
2129 {
2130         BLI_argsParse(ba, 4, arg_handle_load_file, C);
2131 }
2132
2133 /** \} */
2134
2135 #endif /* WITH_PYTHON_MODULE */