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