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