ListBase API: add utility api funcs for clearing and checking empty
[blender-staging.git] / source / creator / creator.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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file creator/creator.c
29  *  \ingroup creator
30  */
31
32
33 #if defined(__linux__) && defined(__GNUC__)
34 #  define _GNU_SOURCE
35 #  include <fenv.h>
36 #endif
37
38 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
39 #  define OSX_SSE_FPE
40 #  include <xmmintrin.h>
41 #endif
42
43 /* crash handler */
44 #ifdef WIN32
45 #  include <process.h> /* getpid */
46 #else
47 #  include <unistd.h> /* getpid */
48 #endif
49
50 #ifdef WIN32
51 #  include <windows.h>
52 #  include "utfconv.h"
53 #endif
54
55 /* for backtrace */
56 #if defined(__linux__) || defined(__APPLE__)
57 #  include <execinfo.h>
58 #elif defined(_MSV_VER)
59 #  include <DbgHelp.h>
60 #endif
61
62 #include <stdlib.h>
63 #include <stddef.h>
64 #include <string.h>
65 #include <errno.h>
66 #include <time.h>
67
68 /* This little block needed for linking to Blender... */
69
70 #include "MEM_guardedalloc.h"
71
72 #ifdef WIN32
73 #  include "BLI_winstuff.h"
74 #endif
75
76 #include "BLI_args.h"
77 #include "BLI_threads.h"
78 #include "BLI_utildefines.h"
79 #include "BLI_callbacks.h"
80 #include "BLI_blenlib.h"
81 #include "BLI_mempool.h"
82
83 #include "DNA_ID.h"
84 #include "DNA_scene_types.h"
85 #include "DNA_userdef_types.h"
86
87 #include "BKE_blender.h"
88 #include "BKE_brush.h"
89 #include "BKE_context.h"
90 #include "BKE_depsgraph.h" /* for DAG_on_visible_update */
91 #include "BKE_font.h"
92 #include "BKE_global.h"
93 #include "BKE_library.h"
94 #include "BKE_main.h"
95 #include "BKE_material.h"
96 #include "BKE_modifier.h"
97 #include "BKE_packedFile.h"
98 #include "BKE_scene.h"
99 #include "BKE_node.h"
100 #include "BKE_report.h"
101 #include "BKE_sound.h"
102 #include "BKE_image.h"
103
104 #include "IMB_imbuf.h"  /* for IMB_init */
105
106 #ifdef WITH_PYTHON
107 #include "BPY_extern.h"
108 #endif
109
110 #include "RE_engine.h"
111 #include "RE_pipeline.h"
112
113 #include "ED_datafiles.h"
114
115 #include "WM_api.h"
116
117 #include "RNA_define.h"
118
119 #include "GPU_draw.h"
120 #include "GPU_extensions.h"
121
122 #ifdef WITH_FREESTYLE
123 #  include "FRS_freestyle.h"
124 #endif
125
126 #ifdef WITH_BUILDINFO_HEADER
127 #  define BUILD_DATE
128 #endif
129
130 /* for passing information between creator and gameengine */
131 #ifdef WITH_GAMEENGINE
132 #  include "BL_System.h"
133 #else /* dummy */
134 #  define SYS_SystemHandle int
135 #endif
136
137 #include <signal.h>
138
139 #ifdef __FreeBSD__
140 #  include <sys/types.h>
141 #  include <floatingpoint.h>
142 #  include <sys/rtprio.h>
143 #endif
144
145 #ifdef WITH_BINRELOC
146 #  include "binreloc.h"
147 #endif
148
149 #ifdef WITH_LIBMV
150 #  include "libmv-capi.h"
151 #endif
152
153 /* from buildinfo.c */
154 #ifdef BUILD_DATE
155 extern char build_date[];
156 extern char build_time[];
157 extern char build_hash[];
158 extern unsigned long build_commit_timestamp;
159
160 /* TODO(sergey): ideally size need to be in sync with buildinfo.c */
161 extern char build_commit_date[16];
162 extern char build_commit_time[16];
163
164 extern char build_branch[];
165 extern char build_platform[];
166 extern char build_type[];
167 extern char build_cflags[];
168 extern char build_cxxflags[];
169 extern char build_linkflags[];
170 extern char build_system[];
171 #endif
172
173 /*      Local Function prototypes */
174 #ifdef WITH_PYTHON_MODULE
175 int  main_python_enter(int argc, const char **argv);
176 void main_python_exit(void);
177 #else
178 static int print_help(int argc, const char **argv, void *data);
179 static int print_version(int argc, const char **argv, void *data);
180 #endif
181
182 /* for the callbacks: */
183 #ifndef WITH_PYTHON_MODULE
184 #define BLEND_VERSION_FMT         "Blender %d.%02d (sub %d)"
185 #define BLEND_VERSION_ARG         BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION
186 /* pass directly to printf */
187 #define BLEND_VERSION_STRING_FMT  BLEND_VERSION_FMT "\n", BLEND_VERSION_ARG
188 #endif
189
190 /* Initialize callbacks for the modules that need them */
191 static void setCallbacks(void); 
192
193 #ifndef WITH_PYTHON_MODULE
194
195 static bool use_crash_handler = true;
196
197 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
198 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
199 static void fpe_handler(int UNUSED(sig))
200 {
201         // printf("SIGFPE trapped\n");
202 }
203 #endif
204
205 /* handling ctrl-c event in console */
206 #if !(defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS))
207 static void blender_esc(int sig)
208 {
209         static int count = 0;
210         
211         G.is_break = TRUE;  /* forces render loop to read queue, not sure if its needed */
212         
213         if (sig == 2) {
214                 if (count) {
215                         printf("\nBlender killed\n");
216                         exit(2);
217                 }
218                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
219                 count++;
220         }
221 }
222 #endif
223
224 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
225 {
226         printf(BLEND_VERSION_STRING_FMT);
227 #ifdef BUILD_DATE
228         printf("\tbuild date: %s\n", build_date);
229         printf("\tbuild time: %s\n", build_time);
230         printf("\tbuild commit date: %s\n", build_commit_date);
231         printf("\tbuild commit time: %s\n", build_commit_time);
232         printf("\tbuild hash: %s\n", build_hash);
233         printf("\tbuild platform: %s\n", build_platform);
234         printf("\tbuild type: %s\n", build_type);
235         printf("\tbuild c flags: %s\n", build_cflags);
236         printf("\tbuild c++ flags: %s\n", build_cxxflags);
237         printf("\tbuild link flags: %s\n", build_linkflags);
238         printf("\tbuild system: %s\n", build_system);
239 #endif
240         exit(0);
241
242         return 0;
243 }
244
245 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
246 {
247         bArgs *ba = (bArgs *)data;
248
249         printf(BLEND_VERSION_STRING_FMT);
250         printf("Usage: blender [args ...] [file] [args ...]\n\n");
251
252         printf("Render Options:\n");
253         BLI_argsPrintArgDoc(ba, "--background");
254         BLI_argsPrintArgDoc(ba, "--render-anim");
255         BLI_argsPrintArgDoc(ba, "--scene");
256         BLI_argsPrintArgDoc(ba, "--render-frame");
257         BLI_argsPrintArgDoc(ba, "--frame-start");
258         BLI_argsPrintArgDoc(ba, "--frame-end");
259         BLI_argsPrintArgDoc(ba, "--frame-jump");
260         BLI_argsPrintArgDoc(ba, "--render-output");
261         BLI_argsPrintArgDoc(ba, "--engine");
262         BLI_argsPrintArgDoc(ba, "--threads");
263         
264         printf("\n");
265         printf("Format Options:\n");
266         BLI_argsPrintArgDoc(ba, "--render-format");
267         BLI_argsPrintArgDoc(ba, "--use-extension");
268
269         printf("\n");
270         printf("Animation Playback Options:\n");
271         BLI_argsPrintArgDoc(ba, "-a");
272                                 
273         printf("\n");
274         printf("Window Options:\n");
275         BLI_argsPrintArgDoc(ba, "--window-border");
276         BLI_argsPrintArgDoc(ba, "--window-borderless");
277         BLI_argsPrintArgDoc(ba, "--window-geometry");
278         BLI_argsPrintArgDoc(ba, "--start-console");
279         BLI_argsPrintArgDoc(ba, "--no-native-pixels");
280
281
282         printf("\n");
283         printf("Game Engine Specific Options:\n");
284         BLI_argsPrintArgDoc(ba, "-g");
285
286         printf("\n");
287         printf("Python Options:\n");
288         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
289         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
290
291         printf("\n");
292
293         BLI_argsPrintArgDoc(ba, "--python");
294         BLI_argsPrintArgDoc(ba, "--python-text");
295         BLI_argsPrintArgDoc(ba, "--python-console");
296         BLI_argsPrintArgDoc(ba, "--addons");
297
298
299         printf("\n");
300         printf("Debug Options:\n");
301         BLI_argsPrintArgDoc(ba, "--debug");
302         BLI_argsPrintArgDoc(ba, "--debug-value");
303
304         printf("\n");
305         BLI_argsPrintArgDoc(ba, "--debug-events");
306 #ifdef WITH_FFMPEG
307         BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
308 #endif
309         BLI_argsPrintArgDoc(ba, "--debug-handlers");
310 #ifdef WITH_LIBMV
311         BLI_argsPrintArgDoc(ba, "--debug-libmv");
312 #endif
313         BLI_argsPrintArgDoc(ba, "--debug-memory");
314         BLI_argsPrintArgDoc(ba, "--debug-jobs");
315         BLI_argsPrintArgDoc(ba, "--debug-python");
316         BLI_argsPrintArgDoc(ba, "--debug-depsgraph");
317
318         BLI_argsPrintArgDoc(ba, "--debug-wm");
319         BLI_argsPrintArgDoc(ba, "--debug-all");
320
321         printf("\n");
322         BLI_argsPrintArgDoc(ba, "--debug-fpe");
323         BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
324
325         printf("\n");
326         printf("Misc Options:\n");
327         BLI_argsPrintArgDoc(ba, "--factory-startup");
328         printf("\n");
329         BLI_argsPrintArgDoc(ba, "--env-system-config");
330         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
331         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
332         BLI_argsPrintArgDoc(ba, "--env-system-python");
333         printf("\n");
334         BLI_argsPrintArgDoc(ba, "-nojoystick");
335         BLI_argsPrintArgDoc(ba, "-noglsl");
336         BLI_argsPrintArgDoc(ba, "-noaudio");
337         BLI_argsPrintArgDoc(ba, "-setaudio");
338
339         printf("\n");
340
341         BLI_argsPrintArgDoc(ba, "--help");
342
343 #ifdef WIN32
344         BLI_argsPrintArgDoc(ba, "-R");
345         BLI_argsPrintArgDoc(ba, "-r");
346 #endif
347         BLI_argsPrintArgDoc(ba, "--version");
348
349         BLI_argsPrintArgDoc(ba, "--");
350
351         printf("Other Options:\n");
352         BLI_argsPrintOtherDoc(ba);
353
354         printf("Argument Parsing:\n");
355         printf("\targuments must be separated by white space. eg\n");
356         printf("\t\t\"blender -ba test.blend\"\n");
357         printf("\t...will ignore the 'a'\n");
358         printf("\t\t\"blender -b test.blend -f8\"\n");
359         printf("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
360
361         printf("Argument Order:\n");
362         printf("\targuments are executed in the order they are given. eg\n");
363         printf("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
364         printf("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
365         printf("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
366         printf("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
367         printf("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
368
369         printf("\nEnvironment Variables:\n");
370         printf("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
371         printf("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
372         printf("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
373         printf("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
374         printf("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
375         printf("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
376 #ifdef WIN32
377         printf("  $TEMP                     Store temporary files here.\n");
378 #else
379         printf("  $TMP or $TMPDIR           Store temporary files here.\n");
380 #endif
381 #ifdef WITH_SDL
382         printf("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
383 #endif
384         printf("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
385
386         exit(0);
387
388         return 0;
389 }
390
391 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
392 {
393         return -1;
394 }
395
396 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
397 {
398         G.f |= G_SCRIPT_AUTOEXEC;
399         G.f |= G_SCRIPT_OVERRIDE_PREF;
400         return 0;
401 }
402
403 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
404 {
405         G.f &= ~G_SCRIPT_AUTOEXEC;
406         G.f |= G_SCRIPT_OVERRIDE_PREF;
407         return 0;
408 }
409
410 static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
411 {
412         use_crash_handler = false;
413         return 0;
414 }
415
416 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
417 {
418         G.background = 1;
419         return 0;
420 }
421
422 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
423 {
424         G.debug |= G_DEBUG;  /* std output printf's */
425         printf(BLEND_VERSION_STRING_FMT);
426         MEM_set_memory_debug();
427 #ifdef DEBUG
428         BLI_mempool_set_memory_debug();
429 #endif
430
431 #ifdef WITH_BUILDINFO
432         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
433 #endif
434
435         BLI_argsPrint(data);
436         return 0;
437 }
438
439 static int debug_mode_generic(int UNUSED(argc), const char **UNUSED(argv), void *data)
440 {
441         G.debug |= GET_INT_FROM_POINTER(data);
442         return 0;
443 }
444
445 #ifdef WITH_LIBMV
446 static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
447 {
448         libmv_startDebugLogging();
449
450         return 0;
451 }
452 #endif
453
454 static int debug_mode_memory(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
455 {
456         MEM_set_memory_debug();
457         return 0;
458 }
459
460 static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
461 {
462         if (argc > 1) {
463                 G.debug_value = atoi(argv[1]);
464
465                 return 1;
466         }
467         else {
468                 printf("\nError: you must specify debug value to set.\n");
469                 return 0;
470         }
471 }
472
473 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
474 {
475 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
476         /* zealous but makes float issues a heck of a lot easier to find!
477          * set breakpoints on fpe_handler */
478         signal(SIGFPE, fpe_handler);
479
480 # if defined(__linux__) && defined(__GNUC__)
481         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
482 # endif /* defined(__linux__) && defined(__GNUC__) */
483 # if defined(OSX_SSE_FPE)
484         /* OSX uses SSE for floating point by default, so here 
485          * use SSE instructions to throw floating point exceptions */
486         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK & ~
487                                (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO));
488 # endif /* OSX_SSE_FPE */
489 # if defined(_WIN32) && defined(_MSC_VER)
490         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
491         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
492 # endif /* _WIN32 && _MSC_VER */
493 #endif
494
495         return 0;
496 }
497
498 #if defined(__linux__) || defined(__APPLE__)
499
500 /* Unix */
501 static void blender_crash_handler_backtrace(FILE *fp)
502 {
503 #define SIZE 100
504         void *buffer[SIZE];
505         int nptrs;
506         char **strings;
507         int i;
508
509         fputs("\n# backtrace\n", fp);
510
511         /* include a backtrace for good measure */
512         nptrs = backtrace(buffer, SIZE);
513         strings = backtrace_symbols(buffer, nptrs);
514         for (i = 0; i < nptrs; i++) {
515                 fputs(strings[i], fp);
516                 fputc('\n', fp);
517         }
518
519         free(strings);
520 #undef SIZE
521 }
522
523 #elif defined(_MSC_VER)
524
525 static void blender_crash_handler_backtrace(FILE *fp)
526 {
527         (void)fp;
528
529 #if 0
530 #define MAXSYMBOL 256
531         unsigned short  i;
532         void *stack[SIZE];
533         unsigned short nframes;
534         SYMBOL_INFO     *symbolinfo;
535         HANDLE process;
536
537         process = GetCurrentProcess();
538
539         SymInitialize(process, NULL, TRUE);
540
541         nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
542         symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof( char ), "crash Symbol table");
543         symbolinfo->MaxNameLen = MAXSYMBOL - 1;
544         symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
545
546         for (i = 0; i < nframes; i++) {
547                 SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo);
548
549                 fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address);
550         }
551
552         MEM_freeN(symbolinfo);
553 #endif
554 }
555
556 #else  /* non msvc/osx/linux */
557
558 static void blender_crash_handler_backtrace(FILE *fp)
559 {
560         (void)fp;
561 }
562
563 #endif
564
565 static void blender_crash_handler(int signum)
566 {
567
568 #if 0
569         {
570                 char fname[FILE_MAX];
571
572                 if (!G.main->name[0]) {
573                         BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
574                 }
575                 else {
576                         BLI_strncpy(fname, G.main->name, sizeof(fname));
577                         BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
578                 }
579
580                 printf("Writing: %s\n", fname);
581                 fflush(stdout);
582
583                 BKE_undo_save_file(fname);
584         }
585 #endif
586
587         FILE *fp;
588         char header[512];
589         wmWindowManager *wm = G.main->wm.first;
590
591         char fname[FILE_MAX];
592
593         if (!G.main->name[0]) {
594                 BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), "blender.crash.txt");
595         }
596         else {
597                 BLI_join_dirfile(fname, sizeof(fname), BLI_temporary_dir(), BLI_path_basename(G.main->name));
598                 BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
599         }
600
601         printf("Writing: %s\n", fname);
602         fflush(stdout);
603
604 #ifndef BUILD_DATE
605         BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Unknown revision\n", BLEND_VERSION_ARG);
606 #else
607         BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Commit date: %s %s, Hash %s\n",
608                      BLEND_VERSION_ARG, build_commit_date, build_commit_time, build_hash);
609 #endif
610
611         /* open the crash log */
612         errno = 0;
613         fp = BLI_fopen(fname, "wb");
614         if (fp == NULL) {
615                 fprintf(stderr, "Unable to save '%s': %s\n",
616                         fname, errno ? strerror(errno) : "Unknown error opening file");
617         }
618         else {
619                 if (wm) {
620                         BKE_report_write_file_fp(fp, &wm->reports, header);
621                 }
622
623                 blender_crash_handler_backtrace(fp);
624
625                 fclose(fp);
626         }
627
628
629         /* really crash */
630         signal(signum, SIG_DFL);
631 #ifndef WIN32
632         kill(getpid(), signum);
633 #else
634         TerminateProcess(GetCurrentProcess(), signum);
635 #endif
636 }
637
638
639 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
640 {
641         G.factory_startup = 1;
642         return 0;
643 }
644
645 static int set_env(int argc, const char **argv, void *UNUSED(data))
646 {
647         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
648
649         char env[64] = "BLENDER";
650         char *ch_dst = env + 7; /* skip BLENDER */
651         const char *ch_src = argv[0] + 5; /* skip --env */
652
653         if (argc < 2) {
654                 printf("%s requires one argument\n", argv[0]);
655                 exit(1);
656         }
657
658         for (; *ch_src; ch_src++, ch_dst++) {
659                 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
660         }
661
662         *ch_dst = '\0';
663         BLI_setenv(env, argv[1]);
664         return 1;
665 }
666
667 static int playback_mode(int argc, const char **argv, void *UNUSED(data))
668 {
669         /* not if -b was given first */
670         if (G.background == 0) {
671 #ifdef WITH_FFMPEG
672                 /* Setup FFmpeg with current debug flags. */
673                 IMB_ffmpeg_init();
674 #endif
675
676                 WM_main_playanim(argc, argv); /* not the same argc and argv as before */
677                 exit(0); /* 2.4x didn't do this */
678         }
679
680         return -2;
681 }
682
683 static int prefsize(int argc, const char **argv, void *UNUSED(data))
684 {
685         int stax, stay, sizx, sizy;
686
687         if (argc < 5) {
688                 fprintf(stderr, "-p requires four arguments\n");
689                 exit(1);
690         }
691
692         stax = atoi(argv[1]);
693         stay = atoi(argv[2]);
694         sizx = atoi(argv[3]);
695         sizy = atoi(argv[4]);
696
697         WM_init_state_size_set(stax, stay, sizx, sizy);
698
699         return 4;
700 }
701
702 static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
703 {
704         WM_init_native_pixels(false);
705         return 0;
706 }
707
708 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
709 {
710         WM_init_state_normal_set();
711         return 0;
712 }
713
714 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
715 {
716         WM_init_state_fullscreen_set();
717         return 0;
718 }
719
720 extern bool wm_start_with_console; /* wm_init_exit.c */
721 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
722 {
723         wm_start_with_console = true;
724         return 0;
725 }
726
727 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
728 {
729 #ifdef WIN32
730         if (data)
731                 G.background = 1;
732         RegisterBlendExtension();
733 #else
734         (void)data; /* unused */
735 #endif
736         return 0;
737 }
738
739 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
740 {
741 #ifndef WITH_GAMEENGINE
742         (void)data;
743 #else
744         SYS_SystemHandle *syshandle = data;
745
746         /**
747          * don't initialize joysticks if user doesn't want to use joysticks
748          * failed joystick initialization delays over 5 seconds, before game engine start
749          */
750         SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
751         if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
752 #endif
753
754         return 0;
755 }
756
757 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
758 {
759         GPU_extensions_disable();
760         return 0;
761 }
762
763 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
764 {
765         sound_force_device(0);
766         return 0;
767 }
768
769 static int set_audio(int argc, const char **argv, void *UNUSED(data))
770 {
771         if (argc < 1) {
772                 fprintf(stderr, "-setaudio require one argument\n");
773                 exit(1);
774         }
775
776         sound_force_device(sound_define_from_str(argv[1]));
777         return 1;
778 }
779
780 static int set_output(int argc, const char **argv, void *data)
781 {
782         bContext *C = data;
783         if (argc > 1) {
784                 Scene *scene = CTX_data_scene(C);
785                 if (scene) {
786                         BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
787                 }
788                 else {
789                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
790                 }
791                 return 1;
792         }
793         else {
794                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
795                 return 0;
796         }
797 }
798
799 static int set_engine(int argc, const char **argv, void *data)
800 {
801         bContext *C = data;
802         if (argc >= 2) {
803                 if (!strcmp(argv[1], "help")) {
804                         RenderEngineType *type = NULL;
805                         printf("Blender Engine Listing:\n");
806                         for (type = R_engines.first; type; type = type->next) {
807                                 printf("\t%s\n", type->idname);
808                         }
809                         exit(0);
810                 }
811                 else {
812                         Scene *scene = CTX_data_scene(C);
813                         if (scene) {
814                                 RenderData *rd = &scene->r;
815
816                                 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
817                                         BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
818                                 }
819                         }
820                         else {
821                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
822                         }
823                 }
824
825                 return 1;
826         }
827         else {
828                 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
829                 return 0;
830         }
831 }
832
833 static int set_image_type(int argc, const char **argv, void *data)
834 {
835         bContext *C = data;
836         if (argc > 1) {
837                 const char *imtype = argv[1];
838                 Scene *scene = CTX_data_scene(C);
839                 if (scene) {
840                         const char imtype_new = BKE_imtype_from_arg(imtype);
841
842                         if (imtype_new == R_IMF_IMTYPE_INVALID) {
843                                 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
844                         }
845                         else {
846                                 scene->r.im_format.imtype = imtype_new;
847                         }
848                 }
849                 else {
850                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
851                 }
852                 return 1;
853         }
854         else {
855                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
856                 return 0;
857         }
858 }
859
860 static int set_threads(int argc, const char **argv, void *UNUSED(data))
861 {
862         if (argc > 1) {
863                 int threads = atoi(argv[1]);
864
865                 if (threads >= 0 && threads <= BLENDER_MAX_THREADS) {
866                         BLI_system_num_threads_override_set(threads);
867                 }
868                 else {
869                         printf("Error, threads has to be in range 0-%d\n", BLENDER_MAX_THREADS);
870                 }
871                 return 1;
872         }
873         else {
874                 printf("\nError: you must specify a number of threads between 0 and %d '-t / --threads'.\n", BLENDER_MAX_THREADS);
875                 return 0;
876         }
877 }
878
879 static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
880 {
881         if (argc > 1) {
882                 int level = atoi(argv[1]);
883
884 #ifdef WITH_LIBMV
885                 libmv_setLoggingVerbosity(level);
886 #else
887                 (void)level;
888 #endif
889
890                 return 1;
891         }
892         else {
893                 printf("\nError: you must specify a verbosity level.\n");
894                 return 0;
895         }
896 }
897
898 static int set_extension(int argc, const char **argv, void *data)
899 {
900         bContext *C = data;
901         if (argc > 1) {
902                 Scene *scene = CTX_data_scene(C);
903                 if (scene) {
904                         if (argv[1][0] == '0') {
905                                 scene->r.scemode &= ~R_EXTENSION;
906                         }
907                         else if (argv[1][0] == '1') {
908                                 scene->r.scemode |= R_EXTENSION;
909                         }
910                         else {
911                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
912                         }
913                 }
914                 else {
915                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
916                 }
917                 return 1;
918         }
919         else {
920                 printf("\nError: you must specify a path after '- '.\n");
921                 return 0;
922         }
923 }
924
925 static int set_ge_parameters(int argc, const char **argv, void *data)
926 {
927         int a = 0;
928 #ifdef WITH_GAMEENGINE
929         SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
930 #else
931         (void)data;
932 #endif
933
934         /**
935          * gameengine parameters are automatically put into system
936          * -g [paramname = value]
937          * -g [boolparamname]
938          * example:
939          * -g novertexarrays
940          * -g maxvertexarraysize = 512
941          */
942
943         if (argc >= 1) {
944                 const char *paramname = argv[a];
945                 /* check for single value versus assignment */
946                 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
947                         a++;
948                         if (a + 1 < argc) {
949                                 a++;
950                                 /* assignment */
951 #ifdef WITH_GAMEENGINE
952                                 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
953 #endif
954                         }
955                         else {
956                                 printf("error: argument assignment (%s) without value.\n", paramname);
957                                 return 0;
958                         }
959                         /* name arg eaten */
960
961                 }
962                 else {
963 #ifdef WITH_GAMEENGINE
964                         SYS_WriteCommandLineInt(syshandle, argv[a], 1);
965 #endif
966                         /* doMipMap */
967                         if (!strcmp(argv[a], "nomipmap")) {
968                                 GPU_set_mipmap(0); //doMipMap = 0;
969                         }
970                         /* linearMipMap */
971                         if (!strcmp(argv[a], "linearmipmap")) {
972                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
973                         }
974
975
976                 } /* if (*(argv[a + 1]) == '=') */
977         }
978
979         return a;
980 }
981
982 static int render_frame(int argc, const char **argv, void *data)
983 {
984         bContext *C = data;
985         Scene *scene = CTX_data_scene(C);
986         if (scene) {
987                 Main *bmain = CTX_data_main(C);
988
989                 if (argc > 1) {
990                         Render *re = RE_NewRender(scene->id.name);
991                         int frame;
992                         ReportList reports;
993
994                         switch (*argv[1]) {
995                                 case '+':
996                                         frame = scene->r.sfra + atoi(argv[1] + 1);
997                                         break;
998                                 case '-':
999                                         frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
1000                                         break;
1001                                 default:
1002                                         frame = atoi(argv[1]);
1003                                         break;
1004                         }
1005
1006                         BKE_reports_init(&reports, RPT_PRINT);
1007
1008                         frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
1009
1010                         RE_SetReports(re, &reports);
1011                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
1012                         RE_SetReports(re, NULL);
1013                         return 1;
1014                 }
1015                 else {
1016                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
1017                         return 0;
1018                 }
1019         }
1020         else {
1021                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
1022                 return 0;
1023         }
1024 }
1025
1026 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
1027 {
1028         bContext *C = data;
1029         Scene *scene = CTX_data_scene(C);
1030         if (scene) {
1031                 Main *bmain = CTX_data_main(C);
1032                 Render *re = RE_NewRender(scene->id.name);
1033                 ReportList reports;
1034                 BKE_reports_init(&reports, RPT_PRINT);
1035                 RE_SetReports(re, &reports);
1036                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
1037                 RE_SetReports(re, NULL);
1038         }
1039         else {
1040                 printf("\nError: no blend loaded. cannot use '-a'.\n");
1041         }
1042         return 0;
1043 }
1044
1045 static int set_scene(int argc, const char **argv, void *data)
1046 {
1047         if (argc > 1) {
1048                 bContext *C = data;
1049                 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
1050                 if (scene) {
1051                         CTX_data_scene_set(C, scene);
1052                 }
1053                 return 1;
1054         }
1055         else {
1056                 printf("\nError: Scene name must follow '-S / --scene'.\n");
1057                 return 0;
1058         }
1059 }
1060
1061 static int set_start_frame(int argc, const char **argv, void *data)
1062 {
1063         bContext *C = data;
1064         Scene *scene = CTX_data_scene(C);
1065         if (scene) {
1066                 if (argc > 1) {
1067                         int frame = atoi(argv[1]);
1068                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
1069                         return 1;
1070                 }
1071                 else {
1072                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
1073                         return 0;
1074                 }
1075         }
1076         else {
1077                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
1078                 return 0;
1079         }
1080 }
1081
1082 static int set_end_frame(int argc, const char **argv, void *data)
1083 {
1084         bContext *C = data;
1085         Scene *scene = CTX_data_scene(C);
1086         if (scene) {
1087                 if (argc > 1) {
1088                         int frame = atoi(argv[1]);
1089                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
1090                         return 1;
1091                 }
1092                 else {
1093                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
1094                         return 0;
1095                 }
1096         }
1097         else {
1098                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
1099                 return 0;
1100         }
1101 }
1102
1103 static int set_skip_frame(int argc, const char **argv, void *data)
1104 {
1105         bContext *C = data;
1106         Scene *scene = CTX_data_scene(C);
1107         if (scene) {
1108                 if (argc > 1) {
1109                         int frame = atoi(argv[1]);
1110                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
1111                         return 1;
1112                 }
1113                 else {
1114                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
1115                         return 0;
1116                 }
1117         }
1118         else {
1119                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
1120                 return 0;
1121         }
1122 }
1123
1124 /* macro for ugly context setup/reset */
1125 #ifdef WITH_PYTHON
1126 #define BPY_CTX_SETUP(_cmd)                                                   \
1127         {                                                                         \
1128                 wmWindowManager *wm = CTX_wm_manager(C);                              \
1129                 wmWindow *prevwin = CTX_wm_window(C);                                 \
1130                 Scene *prevscene = CTX_data_scene(C);                                 \
1131                 if (wm->windows.first) {                                              \
1132                         CTX_wm_window_set(C, wm->windows.first);                          \
1133                         _cmd;                                                             \
1134                         CTX_wm_window_set(C, prevwin);                                    \
1135                 }                                                                     \
1136                 else {                                                                \
1137                         fprintf(stderr, "Python script \"%s\" "                           \
1138                                 "running with missing context data.\n", argv[1]);         \
1139                         _cmd;                                                             \
1140                 }                                                                     \
1141                 CTX_data_scene_set(C, prevscene);                                     \
1142         } (void)0                                                                 \
1143
1144 #endif /* WITH_PYTHON */
1145
1146 static int run_python_file(int argc, const char **argv, void *data)
1147 {
1148 #ifdef WITH_PYTHON
1149         bContext *C = data;
1150
1151         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1152         if (argc > 1) {
1153                 /* Make the path absolute because its needed for relative linked blends to be found */
1154                 char filename[FILE_MAX];
1155                 BLI_strncpy(filename, argv[1], sizeof(filename));
1156                 BLI_path_cwd(filename);
1157
1158                 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL));
1159
1160                 return 1;
1161         }
1162         else {
1163                 printf("\nError: you must specify a filepath after '%s'.\n", argv[0]);
1164                 return 0;
1165         }
1166 #else
1167         (void)argc; (void)argv; (void)data; /* unused */
1168         printf("This blender was built without python support\n");
1169         return 0;
1170 #endif /* WITH_PYTHON */
1171 }
1172
1173 static int run_python_text(int argc, const char **argv, void *data)
1174 {
1175 #ifdef WITH_PYTHON
1176         bContext *C = data;
1177
1178         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1179         if (argc > 1) {
1180                 /* Make the path absolute because its needed for relative linked blends to be found */
1181                 struct Text *text = (struct Text *)BKE_libblock_find_name(ID_TXT, argv[1]);
1182
1183                 if (text) {
1184                         BPY_CTX_SETUP(BPY_text_exec(C, text, NULL, false));
1185                         return 1;
1186                 }
1187                 else {
1188                         printf("\nError: text block not found %s.\n", argv[1]);
1189                         return 1;
1190                 }
1191         }
1192         else {
1193                 printf("\nError: you must specify a text block after '%s'.\n", argv[0]);
1194                 return 0;
1195         }
1196 #else
1197         (void)argc; (void)argv; (void)data; /* unused */
1198         printf("This blender was built without python support\n");
1199         return 0;
1200 #endif /* WITH_PYTHON */
1201 }
1202
1203 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
1204 {
1205 #ifdef WITH_PYTHON
1206         bContext *C = data;
1207
1208         BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"));
1209
1210         return 0;
1211 #else
1212         (void)argv; (void)data; /* unused */
1213         printf("This blender was built without python support\n");
1214         return 0;
1215 #endif /* WITH_PYTHON */
1216 }
1217
1218 static int set_addons(int argc, const char **argv, void *data)
1219 {
1220         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1221         if (argc > 1) {
1222 #ifdef WITH_PYTHON
1223                 const int slen = strlen(argv[1]) + 128;
1224                 char *str = malloc(slen);
1225                 bContext *C = data;
1226                 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
1227                 BPY_CTX_SETUP(BPY_string_exec(C, str));
1228                 free(str);
1229 #else
1230                 (void)argv; (void)data; /* unused */
1231 #endif /* WITH_PYTHON */
1232                 return 1;
1233         }
1234         else {
1235                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
1236                 return 0;
1237         }
1238 }
1239
1240 static int load_file(int UNUSED(argc), const char **argv, void *data)
1241 {
1242         bContext *C = data;
1243
1244         /* Make the path absolute because its needed for relative linked blends to be found */
1245         char filename[FILE_MAX];
1246
1247         /* note, we could skip these, but so far we always tried to load these files */
1248         if (argv[0][0] == '-') {
1249                 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1250         }
1251
1252         BLI_strncpy(filename, argv[0], sizeof(filename));
1253         BLI_path_cwd(filename);
1254
1255         if (G.background) {
1256                 int retval = BKE_read_file(C, filename, NULL);
1257
1258                 /* we successfully loaded a blend file, get sure that
1259                  * pointcache works */
1260                 if (retval != BKE_READ_FILE_FAIL) {
1261                         wmWindowManager *wm = CTX_wm_manager(C);
1262                         Main *bmain = CTX_data_main(C);
1263
1264                         /* special case, 2.4x files */
1265                         if (wm == NULL && BLI_listbase_is_empty(&bmain->wm)) {
1266                                 extern void wm_add_default(bContext *C);
1267
1268                                 /* wm_add_default() needs the screen to be set. */
1269                                 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
1270                                 wm_add_default(C);
1271                         }
1272
1273                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1274                         WM_check(C);
1275                         G.relbase_valid = 1;
1276                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm);  /* reset wm */
1277
1278                         DAG_on_visible_update(bmain, TRUE);
1279                         BKE_scene_update_tagged(bmain->eval_ctx, bmain, CTX_data_scene(C));
1280                 }
1281                 else {
1282                         /* failed to load file, stop processing arguments */
1283                         return -1;
1284                 }
1285
1286                 /* WM_file_read() runs normally but since we're in background mode do here */
1287 #ifdef WITH_PYTHON
1288                 /* run any texts that were loaded in and flagged as modules */
1289                 BPY_python_reset(C);
1290 #endif
1291
1292                 /* happens for the UI on file reading too (huh? (ton))*/
1293                 // XXX          BKE_reset_undo();
1294                 //                      BKE_write_undo("original");     /* save current state */
1295         }
1296         else {
1297                 /* we are not running in background mode here, but start blender in UI mode with
1298                  * a file - this should do everything a 'load file' does */
1299                 ReportList reports;
1300                 BKE_reports_init(&reports, RPT_PRINT);
1301                 WM_file_autoexec_init(filename);
1302                 WM_file_read(C, filename, &reports);
1303                 BKE_reports_clear(&reports);
1304         }
1305
1306         G.file_loaded = 1;
1307
1308         return 0;
1309 }
1310
1311 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1312 {
1313         static char output_doc[] = "<path>"
1314                 "\n\tSet the render path and file name."
1315                 "\n\tUse // at the start of the path to"
1316                 "\n\t\trender relative to the blend file."
1317                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1318                 "\n\t\tani_##_test.png becomes ani_01_test.png"
1319                 "\n\t\ttest-######.png becomes test-000001.png"
1320                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1321                 "\n\tThe frame number will be added at the end of the filename."
1322                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1323                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1324
1325         static char format_doc[] = "<format>"
1326                 "\n\tSet the render format, Valid options are..."
1327                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1328                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1329                 "\n\t(formats that can be compiled into blender, not available on all systems)"
1330                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1331
1332         static char playback_doc[] = "<options> <file(s)>"
1333                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1334                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1335                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1336                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1337                 "\n\t\t-j <frame>\tSet frame step to <frame>"
1338                 "\n\t\t-s <frame>\tPlay from <frame>"
1339                 "\n\t\t-e <frame>\tPlay until <frame>";
1340
1341         static char game_doc[] = "Game Engine specific options"
1342                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1343                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1344                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1345                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1346
1347         static char debug_doc[] = "\n\tTurn debugging on\n"
1348                 "\n\t* Prints every operator call and their arguments"
1349                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1350                 "\n\t* Keeps python sys.stdin rather than setting it to None";
1351
1352         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1353
1354         /* end argument processing after -- */
1355         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1356
1357         /* first pass: background mode, disable python and commands that exit after usage */
1358         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1359         /* Windows only */
1360         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1361
1362         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1363         
1364         /* only to give help message */
1365 #ifndef WITH_PYTHON_SECURITY /* default */
1366 #  define   PY_ENABLE_AUTO ", (default)"
1367 #  define   PY_DISABLE_AUTO ""
1368 #else
1369 #  define   PY_ENABLE_AUTO ""
1370 #  define   PY_DISABLE_AUTO ", (compiled as non-standard default)"
1371 #endif
1372
1373         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1374         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1375
1376         BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
1377
1378 #undef PY_ENABLE_AUTO
1379 #undef PY_DISABLE_AUTO
1380         
1381         BLI_argsAdd(ba, 1, "-b", "--background", "\n\tRun in background (often used for UI-less rendering)", background_mode, NULL);
1382
1383         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1384
1385         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1386
1387 #ifdef WITH_FFMPEG
1388         BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1389 #endif
1390
1391 #ifdef WITH_FREESTYLE
1392         BLI_argsAdd(ba, 1, NULL, "--debug-freestyle", "\n\tEnable debug/profiling messages from Freestyle rendering", debug_mode_generic, (void *)G_DEBUG_FREESTYLE);
1393 #endif
1394
1395         BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1396         BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1397         BLI_argsAdd(ba, 1, NULL, "--debug-handlers", "\n\tEnable debug messages for event handling", debug_mode_generic, (void *)G_DEBUG_HANDLERS);
1398         BLI_argsAdd(ba, 1, NULL, "--debug-wm",     "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1399         BLI_argsAdd(ba, 1, NULL, "--debug-all",    "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1400
1401         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1402
1403 #ifdef WITH_LIBMV
1404         BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1405 #endif
1406         BLI_argsAdd(ba, 1, NULL, "--debug-memory", "\n\tEnable fully guarded memory allocation and debugging", debug_mode_memory, NULL);
1407
1408         BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1409         BLI_argsAdd(ba, 1, NULL, "--debug-jobs",  "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1410         BLI_argsAdd(ba, 1, NULL, "--debug-depsgraph", "\n\tEnable debug messages from dependency graph", debug_mode_generic, (void *)G_DEBUG_DEPSGRAPH);
1411
1412         BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1413
1414         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1415
1416         /* TODO, add user env vars? */
1417         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles",  "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1418         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts",    "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1419         BLI_argsAdd(ba, 1, NULL, "--env-system-python",     "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1420
1421         /* second pass: custom window stuff */
1422         BLI_argsAdd(ba, 2, "-p", "--window-geometry", "<sx> <sy> <w> <h>\n\tOpen with lower left corner at <sx>, <sy> and width and height as <w>, <h>", prefsize, NULL);
1423         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1424         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1425         BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set), (Windows only)", start_with_console, NULL);
1426         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1427         BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1428         BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba);
1429
1430         /* third pass: disabling things and forcing settings */
1431         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1432         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1433         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1434         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1435
1436         /* fourth pass: processing arguments */
1437         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1438         BLI_argsAdd(ba, 4, "-f", "--render-frame", "<frame>\n\tRender frame <frame> and save it.\n\t+<frame> start frame relative, -<frame> end frame relative.", render_frame, C);
1439         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1440         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1441         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1442         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1443         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1444         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script file", run_python_file, C);
1445         BLI_argsAdd(ba, 4, NULL, "--python-text", "<name>\n\tRun the given Python script text block", run_python_text, C);
1446         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1447         BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1448
1449         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1450         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1451
1452         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1453         BLI_argsAdd(ba, 4, "-t", "--threads", "<threads>\n\tUse amount of <threads> for rendering and other operations\n\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems processor count.", set_threads, NULL);
1454         BLI_argsAdd(ba, 4, "-x", "--use-extension", "<bool>\n\tSet option to add the file extension to the end of the file", set_extension, C);
1455
1456 }
1457 #endif /* WITH_PYTHON_MODULE */
1458
1459 #ifdef WITH_PYTHON_MODULE
1460 /* allow python module to call main */
1461 #  define main main_python_enter
1462 static void *evil_C = NULL;
1463
1464 #  ifdef __APPLE__
1465      /* environ is not available in mac shared libraries */
1466 #    include <crt_externs.h>
1467 char **environ = NULL;
1468 #  endif
1469 #endif
1470
1471
1472 #ifdef WIN32
1473 int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
1474 #else
1475 int main(int argc, const char **argv)
1476 #endif
1477 {
1478         bContext *C;
1479         SYS_SystemHandle syshandle;
1480
1481 #ifndef WITH_PYTHON_MODULE
1482         bArgs *ba;
1483 #endif
1484
1485 #ifdef WIN32 /* Win32 Unicode Args */
1486         /* NOTE: cannot use guardedalloc malloc here, as it's not yet initialized
1487          *       (it depends on the args passed in, which is what we're getting here!)
1488          */
1489         wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1490         char **argv = malloc(argc * sizeof(char *));
1491         int argci = 0;
1492         
1493         for (argci = 0; argci < argc; argci++) {
1494                 argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
1495         }
1496         
1497         LocalFree(argv_16);
1498 #endif
1499
1500         /* NOTE: Special exception for guarded allocator type switch:
1501          *       we need to perform switch from lock-free to fully
1502          *       guarded allocator before any allocation happened.
1503          */
1504         {
1505                 int i;
1506                 for (i = 0; i < argc; i++) {
1507                         if (STREQ(argv[i], "--debug") || STREQ(argv[i], "-d") ||
1508                             STREQ(argv[i], "--debug-memory"))
1509                         {
1510                                 printf("Switching to fully guarded memory allocator.\n");
1511                                 MEM_use_guarded_allocator();
1512                                 break;
1513                         }
1514                         else if (STREQ(argv[i], "--")) {
1515                                 break;
1516                         }
1517                 }
1518         }
1519
1520 #ifdef BUILD_DATE
1521         {
1522                 time_t temp_time = build_commit_timestamp;
1523                 struct tm *tm = gmtime(&temp_time);
1524                 if (LIKELY(tm)) {
1525                         strftime(build_commit_date, sizeof(build_commit_date), "%Y-%m-%d", tm);
1526                         strftime(build_commit_time, sizeof(build_commit_time), "%H:%M", tm);
1527                 }
1528                 else {
1529                         const char *unknown = "date-unknown";
1530                         BLI_strncpy(build_commit_date, unknown, sizeof(build_commit_date));
1531                         BLI_strncpy(build_commit_time, unknown, sizeof(build_commit_time));
1532                 }
1533         }
1534 #endif
1535
1536         C = CTX_create();
1537
1538 #ifdef WITH_PYTHON_MODULE
1539 #ifdef __APPLE__
1540         environ = *_NSGetEnviron();
1541 #endif
1542
1543 #undef main
1544         evil_C = C;
1545 #endif
1546
1547
1548
1549 #ifdef WITH_BINRELOC
1550         br_init(NULL);
1551 #endif
1552
1553 #ifdef WITH_LIBMV
1554         libmv_initLogging(argv[0]);
1555 #endif
1556
1557         setCallbacks();
1558 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1559         /* patch to ignore argument finder gives us (pid?) */
1560         if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
1561                 extern int GHOST_HACK_getFirstFile(char buf[]);
1562                 static char firstfilebuf[512];
1563
1564                 argc = 1;
1565
1566                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1567                         argc = 2;
1568                         argv[1] = firstfilebuf;
1569                 }
1570         }
1571
1572 #endif
1573
1574 #ifdef __FreeBSD__
1575         fpsetmask(0);
1576 #endif
1577
1578         /* initialize path to executable */
1579         BLI_init_program_path(argv[0]);
1580
1581         BLI_threadapi_init();
1582
1583         initglobals();  /* blender.c */
1584
1585         IMB_init();
1586         BKE_images_init();
1587         BKE_modifier_init();
1588         DAG_init();
1589
1590         BKE_brush_system_init();
1591
1592         BLI_callback_global_init();
1593
1594 #ifdef WITH_GAMEENGINE
1595         syshandle = SYS_GetSystem();
1596 #else
1597         syshandle = 0;
1598 #endif
1599
1600         /* first test for background */
1601 #ifndef WITH_PYTHON_MODULE
1602         ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1603         setupArguments(C, ba, &syshandle);
1604
1605         BLI_argsParse(ba, 1, NULL, NULL);
1606
1607         if (use_crash_handler) {
1608                 /* after parsing args */
1609                 signal(SIGSEGV, blender_crash_handler);
1610         }
1611 #else
1612         G.factory_startup = true;  /* using preferences or user startup makes no sense for py-as-module */
1613         (void)syshandle;
1614 #endif
1615
1616 #ifdef WITH_FFMPEG
1617         IMB_ffmpeg_init();
1618 #endif
1619
1620         /* after level 1 args, this is so playanim skips RNA init */
1621         RNA_init();
1622
1623         RE_engines_init();
1624         init_nodesystem();
1625         /* end second init */
1626
1627
1628 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1629         G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
1630 #else
1631         /* for all platforms, even windos has it! */
1632         if (G.background) {
1633                 signal(SIGINT, blender_esc);  /* ctrl c out bg render */
1634         }
1635 #endif
1636
1637         /* background render uses this font too */
1638         BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
1639
1640         /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1641          * rendered via ffmpeg */
1642         sound_init_once();
1643         
1644         init_def_material();
1645
1646         if (G.background == 0) {
1647 #ifndef WITH_PYTHON_MODULE
1648                 BLI_argsParse(ba, 2, NULL, NULL);
1649                 BLI_argsParse(ba, 3, NULL, NULL);
1650 #endif
1651                 WM_init(C, argc, (const char **)argv);
1652
1653                 /* this is properly initialized with user defs, but this is default */
1654                 /* call after loading the startup.blend so we can read U.tempdir */
1655                 BLI_init_temporary_dir(U.tempdir);
1656         }
1657         else {
1658 #ifndef WITH_PYTHON_MODULE
1659                 BLI_argsParse(ba, 3, NULL, NULL);
1660 #endif
1661
1662                 WM_init(C, argc, (const char **)argv);
1663
1664                 /* don't use user preferences temp dir */
1665                 BLI_init_temporary_dir(NULL);
1666         }
1667 #ifdef WITH_PYTHON
1668         /**
1669          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1670          * so we provide the BPY_ function below to append the user defined
1671          * python-dir to Python's sys.path at this point.  Simply putting
1672          * WM_init() before #BPY_python_start() crashes Blender at startup.
1673          */
1674
1675         /* TODO - U.pythondir */
1676 #else
1677         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1678 #endif
1679         
1680         CTX_py_init_set(C, 1);
1681         WM_keymap_init(C);
1682
1683 #ifdef WITH_FREESTYLE
1684         /* initialize Freestyle */
1685         FRS_initialize();
1686         FRS_set_context(C);
1687 #endif
1688
1689         /* OK we are ready for it */
1690 #ifndef WITH_PYTHON_MODULE
1691         BLI_argsParse(ba, 4, load_file, C);
1692         
1693         if (G.background == 0) {
1694                 if (!G.file_loaded)
1695                         if (U.uiflag2 & USER_KEEP_SESSION)
1696                                 WM_recover_last_session(C, NULL);
1697         }
1698
1699 #endif
1700
1701 #ifndef WITH_PYTHON_MODULE
1702         BLI_argsFree(ba);
1703 #endif
1704
1705 #ifdef WIN32
1706         while (argci) {
1707                 free(argv[--argci]);
1708         }
1709         free(argv);
1710         argv = NULL;
1711 #endif
1712
1713 #ifdef WITH_PYTHON_MODULE
1714         return 0; /* keep blender in background mode running */
1715 #endif
1716
1717         if (G.background) {
1718                 /* actually incorrect, but works for now (ton) */
1719                 WM_exit(C);
1720         }
1721         else {
1722                 if (G.fileflags & G_FILE_AUTOPLAY) {
1723                         if (G.f & G_SCRIPT_AUTOEXEC) {
1724                                 if (WM_init_game(C)) {
1725                                         return 0;
1726                                 }
1727                         }
1728                         else {
1729                                 if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
1730                                         G.f |= G_SCRIPT_AUTOEXEC_FAIL;
1731                                         BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Game AutoStart");
1732                                 }
1733                         }
1734                 }
1735
1736                 if (!G.file_loaded) {
1737                         WM_init_splash(C);
1738                 }
1739         }
1740
1741         WM_main(C);
1742
1743         return 0;
1744 } /* end of int main(argc, argv)        */
1745
1746 #ifdef WITH_PYTHON_MODULE
1747 void main_python_exit(void)
1748 {
1749         WM_exit((bContext *)evil_C);
1750         evil_C = NULL;
1751 }
1752 #endif
1753
1754 static void mem_error_cb(const char *errorStr)
1755 {
1756         fputs(errorStr, stderr);
1757         fflush(stderr);
1758 }
1759
1760 static void setCallbacks(void)
1761 {
1762         /* Error output from the alloc routines: */
1763         MEM_set_error_callback(mem_error_cb);
1764 }