Merged changes in the trunk up to revision 29409.
[blender.git] / source / creator / creator.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #if defined(__linux__) && defined(__GNUC__)
31 #define _GNU_SOURCE
32 #include <fenv.h>
33 #endif
34
35 #define OSX_SSE_FPE (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
36
37 #if OSX_SSE_FPE
38 #include <xmmintrin.h>
39 #endif
40
41 #include <stdlib.h>
42 #include <string.h>
43
44 /* for setuid / getuid */
45 #ifdef __sgi
46 #include <sys/types.h>
47 #include <unistd.h>
48 #endif
49
50 /* This little block needed for linking to Blender... */
51
52 #include "MEM_guardedalloc.h"
53
54 #ifdef WIN32
55 #include "BLI_winstuff.h"
56 #endif
57
58 #include "BLI_args.h"
59 #include "BLI_threads.h"
60
61 #include "GEN_messaging.h"
62
63 #include "DNA_ID.h"
64 #include "DNA_scene_types.h"
65
66 #include "BLI_blenlib.h"
67
68 #include "BKE_utildefines.h"
69 #include "BKE_blender.h"
70 #include "BKE_context.h"
71 #include "BKE_font.h"
72 #include "BKE_global.h"
73 #include "BKE_main.h"
74 #include "BKE_material.h"
75 #include "BKE_packedFile.h"
76 #include "BKE_scene.h"
77 #include "BKE_node.h"
78 #include "BKE_report.h"
79 #include "BKE_sound.h"
80
81 #include "IMB_imbuf.h"  // for IMB_init
82
83 #ifndef DISABLE_PYTHON
84 #include "BPY_extern.h"
85 #endif
86
87 #include "RE_pipeline.h"
88
89 //XXX #include "playanim_ext.h"
90 #include "ED_datafiles.h"
91
92 #include "WM_api.h"
93
94 #include "RNA_define.h"
95
96 #include "GPU_draw.h"
97 #include "GPU_extensions.h"
98
99 #include "FRS_freestyle.h"
100
101 /* for passing information between creator and gameengine */
102 #include "SYS_System.h"
103
104 #include <signal.h>
105
106 #ifdef __FreeBSD__
107 # include <sys/types.h>
108 # include <floatingpoint.h>
109 # include <sys/rtprio.h>
110 #endif
111
112 #ifdef WITH_BINRELOC
113 #include "binreloc.h"
114 #endif
115
116 // from buildinfo.c
117 #ifdef BUILD_DATE
118 extern char build_date[];
119 extern char build_time[];
120 extern char build_rev[];
121 extern char build_platform[];
122 extern char build_type[];
123 #endif
124
125 /*      Local Function prototypes */
126 static int print_help(int argc, char **argv, void *data);
127 static int print_version(int argc, char **argv, void *data);
128
129 /* for the callbacks: */
130
131 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
132
133 char bprogname[FILE_MAXDIR+FILE_MAXFILE]; /* from blenpluginapi:pluginapi.c */
134 char btempdir[FILE_MAXDIR+FILE_MAXFILE];
135
136 /* unix path support.
137  * defined by the compiler. eg "/usr/share/blender/2.5" "/opt/blender/2.5" */
138 #ifndef BLENDERPATH
139 #define BLENDERPATH ""
140 #endif
141  
142 char blender_path[FILE_MAXDIR+FILE_MAXFILE] = BLENDERPATH;
143
144 /* Initialise callbacks for the modules that need them */
145 static void setCallbacks(void); 
146
147 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
148 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
149 static void fpe_handler(int sig)
150 {
151         // printf("SIGFPE trapped\n");
152 }
153 #endif
154
155 /* handling ctrl-c event in console */
156 static void blender_esc(int sig)
157 {
158         static int count = 0;
159         
160         G.afbreek = 1;  /* forces render loop to read queue, not sure if its needed */
161         
162         if (sig == 2) {
163                 if (count) {
164                         printf("\nBlender killed\n");
165                         exit(2);
166                 }
167                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
168                 count++;
169         }
170 }
171
172 /* buildinfo can have quotes */
173 #ifdef BUILD_DATE
174 static void strip_quotes(char *str)
175 {
176     if(str[0] == '"') {
177         int len= strlen(str) - 1;
178         memmove(str, str+1, len);
179         if(str[len-1] == '"') {
180             str[len-1]= '\0';
181         }
182     }
183 }
184 #endif
185
186 static int print_version(int argc, char **argv, void *data)
187 {
188 #ifdef BUILD_DATE
189         printf ("Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
190         printf ("\tbuild date: %s\n", build_date);
191         printf ("\tbuild time: %s\n", build_time);
192         printf ("\tbuild revision: %s\n", build_rev);
193         printf ("\tbuild platform: %s\n", build_platform);
194         printf ("\tbuild type: %s\n", build_type);
195 #else
196         printf ("Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
197 #endif
198
199         exit(0);
200
201         return 0;
202 }
203
204 static int print_help(int argc, char **argv, void *data)
205 {
206         bArgs *ba = (bArgs*)data;
207
208         printf ("Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
209         printf ("Usage: blender [args ...] [file] [args ...]\n\n");
210
211         printf ("Render Options:\n");
212         BLI_argsPrintArgDoc(ba, "--background");
213         BLI_argsPrintArgDoc(ba, "--render-anim");
214         BLI_argsPrintArgDoc(ba, "--scene");
215         BLI_argsPrintArgDoc(ba, "--render-frame");
216         BLI_argsPrintArgDoc(ba, "--frame-start");
217         BLI_argsPrintArgDoc(ba, "--frame-end");
218         BLI_argsPrintArgDoc(ba, "--frame-jump");
219         BLI_argsPrintArgDoc(ba, "--render-output");
220         BLI_argsPrintArgDoc(ba, "--engine");
221         
222         printf("\n");
223         printf ("Format Options:\n");
224         BLI_argsPrintArgDoc(ba, "--render-format");
225         BLI_argsPrintArgDoc(ba, "--use-extension");
226         BLI_argsPrintArgDoc(ba, "--threads");
227
228         printf("\n");
229         printf ("Animation Playback Options:\n");
230         BLI_argsPrintArgDoc(ba, "-a");
231                                 
232         printf("\n");
233         printf ("Window Options:\n");
234         BLI_argsPrintArgDoc(ba, "--window-border");
235         BLI_argsPrintArgDoc(ba, "--window-borderless");
236         BLI_argsPrintArgDoc(ba, "--window-geometry");
237
238         printf("\n");
239         printf ("Game Engine specific options:\n");
240         BLI_argsPrintArgDoc(ba, "-g");
241
242         printf("\n");
243         printf ("Misc options:\n");
244         BLI_argsPrintArgDoc(ba, "--debug");
245         BLI_argsPrintArgDoc(ba, "--debug-fpe");
246
247         printf("\n");
248
249         BLI_argsPrintArgDoc(ba, "-nojoystick");
250         BLI_argsPrintArgDoc(ba, "-noglsl");
251         BLI_argsPrintArgDoc(ba, "-noaudio");
252         BLI_argsPrintArgDoc(ba, "-setaudio");
253
254         printf("\n");
255
256         BLI_argsPrintArgDoc(ba, "--help");
257
258         printf("\n");
259
260         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
261         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
262
263         printf("\n");
264
265         BLI_argsPrintArgDoc(ba, "--python");
266         BLI_argsPrintArgDoc(ba, "--python-console");
267
268 #ifdef WIN32
269         BLI_argsPrintArgDoc(ba, "-R");
270 #endif
271         BLI_argsPrintArgDoc(ba, "--version");
272
273         BLI_argsPrintArgDoc(ba, "--");
274
275         printf ("Other Options:\n");
276         BLI_argsPrintOtherDoc(ba);
277
278         printf ("\nEnvironment Variables:\n");
279         printf ("  $HOME\t\t\tStore files such as .blender/ .B.blend .Bfs .Blog here.\n");
280         printf ("  $BLENDERPATH  System directory to use for data files and scripts.\n");
281         printf ("                For this build of blender the default BLENDERPATH is...\n");
282         printf ("                \"%s\"\n", blender_path);
283         printf ("                setting the $BLENDERPATH will override this\n");
284 #ifdef WIN32
285         printf ("  $TEMP         Store temporary files here.\n");
286 #else
287         printf ("  $TMP or $TMPDIR  Store temporary files here.\n");
288 #endif
289 #ifndef DISABLE_SDL
290         printf ("  $SDL_AUDIODRIVER  LibSDL audio driver - alsa, esd, alsa, dma.\n");
291 #endif
292         printf ("  $PYTHONHOME   Path to the python directory, eg. /usr/lib/python.\n\n");
293
294         printf ("Note: Arguments must be separated by white space. eg:\n");
295         printf ("    \"blender -ba test.blend\"\n");
296         printf ("  ...will ignore the 'a'\n");
297         printf ("    \"blender -b test.blend -f8\"\n");
298         printf ("  ...will ignore 8 because there is no space between the -f and the frame value\n\n");
299
300         printf ("Note: Arguments are executed in the order they are given. eg:\n");
301         printf ("    \"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
302         printf ("  ...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
303         printf ("    \"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
304         printf ("  ...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
305         printf ("    \"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
306
307         exit(0);
308
309         return 0;
310 }
311
312
313 double PIL_check_seconds_timer(void);
314
315 /* XXX This was here to fix a crash when running python scripts
316  * with -P that used the screen.
317  *
318  * static void main_init_screen( void )
319 {
320         setscreen(G.curscreen);
321         
322         if(G.main->scene.first==0) {
323                 set_scene( add_scene("1") );
324         }
325 }*/
326
327 static int end_arguments(int argc, char **argv, void *data)
328 {
329         return -1;
330 }
331
332 static int enable_python(int argc, char **argv, void *data)
333 {
334         G.f |= G_SCRIPT_AUTOEXEC;
335         return 0;
336 }
337
338 static int disable_python(int argc, char **argv, void *data)
339 {
340         G.f &= ~G_SCRIPT_AUTOEXEC;
341         return 0;
342 }
343
344 static int background_mode(int argc, char **argv, void *data)
345 {
346         G.background = 1;
347         return 0;
348 }
349
350 static int debug_mode(int argc, char **argv, void *data)
351 {
352         G.f |= G_DEBUG;         /* std output printf's */
353         printf ("Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION);
354         MEM_set_memory_debug();
355
356 #ifdef NAN_BUILDINFO
357         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
358 #endif // NAN_BUILDINFO
359
360         BLI_argsPrint(data);
361         return 0;
362 }
363
364 static int set_fpe(int argc, char **argv, void *data)
365 {
366 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
367         /* zealous but makes float issues a heck of a lot easier to find!
368          * set breakpoints on fpe_handler */
369         signal(SIGFPE, fpe_handler);
370
371 # if defined(__linux__) && defined(__GNUC__)
372         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
373 # endif /* defined(__linux__) && defined(__GNUC__) */
374 # if OSX_SSE_FPE
375         /* OSX uses SSE for floating point by default, so here 
376          * use SSE instructions to throw floating point exceptions */
377         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
378                                                    (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
379 # endif /* OSX_SSE_FPE */
380 # if defined(_WIN32) && defined(_MSC_VER)
381         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
382         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
383 # endif /* _WIN32 && _MSC_VER */
384 #endif
385
386         return 0;
387 }
388
389 static int playback_mode(int argc, char **argv, void *data)
390 {
391         /* not if -b was given first */
392         if (G.background == 0) {
393
394 // XXX                          playanim(argc, argv); /* not the same argc and argv as before */
395                 exit(0);
396         }
397
398         return -2;
399 }
400
401 static int prefsize(int argc, char **argv, void *data)
402 {
403         int stax, stay, sizx, sizy;
404
405         if (argc < 5) {
406                 printf ("-p requires four arguments\n");
407                 exit(1);
408         }
409
410         stax= atoi(argv[1]);
411         stay= atoi(argv[2]);
412         sizx= atoi(argv[3]);
413         sizy= atoi(argv[4]);
414
415         WM_setprefsize(stax, stay, sizx, sizy);
416
417         return 4;
418 }
419
420 static int with_borders(int argc, char **argv, void *data)
421 {
422         /* with borders XXX OLD CRUFT!*/
423
424         return 0;
425 }
426
427 static int without_borders(int argc, char **argv, void *data)
428 {
429         /* borderless, win + linux XXX OLD CRUFT */
430         /* XXX, fixme mein, borderless on OSX */
431
432         return 0;
433 }
434
435 static int register_extension(int argc, char **argv, void *data)
436 {
437 #ifdef WIN32
438         char *path = BLI_argsArgv(data)[0];
439         RegisterBlendExtension(path);
440 #endif
441
442         return 0;
443 }
444
445 static int no_joystick(int argc, char **argv, void *data)
446 {
447         SYS_SystemHandle *syshandle = data;
448
449         /**
450                 don't initialize joysticks if user doesn't want to use joysticks
451                 failed joystick initialization delays over 5 seconds, before game engine start
452         */
453         SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
454         if (G.f & G_DEBUG) printf("disabling nojoystick\n");
455
456         return 0;
457 }
458
459 static int no_glsl(int argc, char **argv, void *data)
460 {
461         GPU_extensions_disable();
462         return 0;
463 }
464
465 static int no_audio(int argc, char **argv, void *data)
466 {
467         sound_force_device(0);
468         return 0;
469 }
470
471 static int set_audio(int argc, char **argv, void *data)
472 {
473         if (argc < 1) {
474                 printf("-setaudio require one argument\n");
475                 exit(1);
476         }
477
478         sound_force_device(sound_define_from_str(argv[1]));
479         return 1;
480 }
481
482 static int set_output(int argc, char **argv, void *data)
483 {
484         bContext *C = data;
485         if (argc >= 1){
486                 if (CTX_data_scene(C)) {
487                         Scene *scene= CTX_data_scene(C);
488                         BLI_strncpy(scene->r.pic, argv[1], FILE_MAXDIR);
489                 } else {
490                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
491                 }
492                 return 1;
493         } else {
494                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
495                 return 0;
496         }
497 }
498
499 static int set_engine(int argc, char **argv, void *data)
500 {
501         bContext *C = data;
502         if (argc >= 1)
503         {
504                 if (!strcmp(argv[1],"help"))
505                 {
506                         RenderEngineType *type = NULL;
507
508                         for( type = R_engines.first; type; type = type->next )
509                         {
510                                 printf("\t%s\n", type->idname);
511                         }
512                         exit(0);
513                 }
514                 else
515                 {
516                         if (CTX_data_scene(C)==NULL)
517                         {
518                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
519                         }
520                         else
521                         {
522                                 Scene *scene= CTX_data_scene(C);
523                                 RenderData *rd = &scene->r;
524                                 RenderEngineType *type = NULL;
525
526                                 for( type = R_engines.first; type; type = type->next )
527                                 {
528                                         if (!strcmp(argv[1],type->idname))
529                                         {
530                                                 BLI_strncpy(rd->engine, type->idname, sizeof(rd->engine));
531                                         }
532                                 }
533                         }
534                 }
535
536                 return 1;
537         }
538         else
539         {
540                 printf("\nEngine not specified.\n");
541                 return 0;
542         }
543 }
544
545 static int set_image_type(int argc, char **argv, void *data)
546 {
547         bContext *C = data;
548         if (argc >= 1){
549                 char *imtype = argv[1];
550                 if (CTX_data_scene(C)==NULL) {
551                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
552                 } else {
553                         Scene *scene= CTX_data_scene(C);
554                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
555                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
556 #ifdef WITH_DDS
557                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
558 #endif
559                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
560                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
561                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
562                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
563                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
564                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
565                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
566                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
567                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
568                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
569 #ifdef WITH_TIFF
570                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
571 #endif
572 #ifdef WITH_OPENEXR
573                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
574                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
575 #endif
576                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
577                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
578                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
579                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
580 #if WITH_OPENJPEG
581                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
582 #endif
583                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
584                 }
585                 return 1;
586         } else {
587                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
588                 return 0;
589         }
590 }
591
592 static int set_threads(int argc, char **argv, void *data)
593 {
594         if (argc >= 1) {
595                 if(G.background) {
596                         RE_set_max_threads(atoi(argv[1]));
597                 } else {
598                         printf("Warning: threads can only be set in background mode\n");
599                 }
600                 return 1;
601         } else {
602                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
603                 return 0;
604         }
605 }
606
607 static int set_extension(int argc, char **argv, void *data)
608 {
609         bContext *C = data;
610         if (argc >= 1) {
611                 if (CTX_data_scene(C)) {
612                         Scene *scene= CTX_data_scene(C);
613                         if (argv[1][0] == '0') {
614                                 scene->r.scemode &= ~R_EXTENSION;
615                         } else if (argv[1][0] == '1') {
616                                 scene->r.scemode |= R_EXTENSION;
617                         } else {
618                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
619                         }
620                 } else {
621                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
622                 }
623                 return 1;
624         } else {
625                 printf("\nError: you must specify a path after '- '.\n");
626                 return 0;
627         }
628 }
629
630 static int set_ge_parameters(int argc, char **argv, void *data)
631 {
632         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
633         int a = 0;
634 /**
635 gameengine parameters are automaticly put into system
636 -g [paramname = value]
637 -g [boolparamname]
638 example:
639 -g novertexarrays
640 -g maxvertexarraysize = 512
641 */
642
643         if(argc >= 1)
644         {
645                 char* paramname = argv[a];
646                 /* check for single value versus assignment */
647                 if (a+1 < argc && (*(argv[a+1]) == '='))
648                 {
649                         a++;
650                         if (a+1 < argc)
651                         {
652                                 a++;
653                                 /* assignment */
654                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
655                         }  else
656                         {
657                                 printf("error: argument assignment (%s) without value.\n",paramname);
658                                 return 0;
659                         }
660                         /* name arg eaten */
661
662                 } else {
663                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
664
665                         /* doMipMap */
666                         if (!strcmp(argv[a],"nomipmap"))
667                         {
668                                 GPU_set_mipmap(0); //doMipMap = 0;
669                         }
670                         /* linearMipMap */
671                         if (!strcmp(argv[a],"linearmipmap"))
672                         {
673                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
674                         }
675
676
677                 } /* if (*(argv[a+1]) == '=') */
678         }
679
680         return a;
681 }
682
683 static int render_frame(int argc, char **argv, void *data)
684 {
685         bContext *C = data;
686         if (CTX_data_scene(C)) {
687                 Scene *scene= CTX_data_scene(C);
688
689                 if (argc > 1) {
690                         int frame = atoi(argv[1]);
691                         Render *re = RE_NewRender(scene->id.name);
692                         ReportList reports;
693
694                         BKE_reports_init(&reports, RPT_PRINT);
695
696                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
697
698                         RE_BlenderAnim(re, scene, scene->lay, frame, frame, scene->r.frame_step, &reports);
699                         return 1;
700                 } else {
701                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
702                         return 0;
703                 }
704         } else {
705                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
706                 return 0;
707         }
708 }
709
710 static int render_animation(int argc, char **argv, void *data)
711 {
712         bContext *C = data;
713         if (CTX_data_scene(C)) {
714                 Scene *scene= CTX_data_scene(C);
715                 Render *re= RE_NewRender(scene->id.name);
716                 ReportList reports;
717                 BKE_reports_init(&reports, RPT_PRINT);
718                 RE_BlenderAnim(re, scene, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
719         } else {
720                 printf("\nError: no blend loaded. cannot use '-a'.\n");
721         }
722         return 0;
723 }
724
725 static int set_scene(int argc, char **argv, void *data)
726 {
727         if(argc > 1) {
728                 set_scene_name(argv[1]);
729                 return 1;
730         } else {
731                 printf("\nError: Scene name must follow '-S / --scene'.\n");
732                 return 0;
733         }
734 }
735
736 static int set_start_frame(int argc, char **argv, void *data)
737 {
738         bContext *C = data;
739         if (CTX_data_scene(C)) {
740                 Scene *scene= CTX_data_scene(C);
741                 if (argc > 1) {
742                         int frame = atoi(argv[1]);
743                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
744                         return 1;
745                 } else {
746                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
747                         return 0;
748                 }
749         } else {
750                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
751                 return 0;
752         }
753 }
754
755 static int set_end_frame(int argc, char **argv, void *data)
756 {
757         bContext *C = data;
758         if (CTX_data_scene(C)) {
759                 Scene *scene= CTX_data_scene(C);
760                 if (argc > 1) {
761                         int frame = atoi(argv[1]);
762                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
763                         return 1;
764                 } else {
765                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
766                         return 0;
767                 }
768         } else {
769                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
770                 return 0;
771         }
772 }
773
774 static int set_skip_frame(int argc, char **argv, void *data)
775 {
776         bContext *C = data;
777         if (CTX_data_scene(C)) {
778                 Scene *scene= CTX_data_scene(C);
779                 if (argc > 1) {
780                         int frame = atoi(argv[1]);
781                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
782                         return 1;
783                 } else {
784                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
785                         return 0;
786                 }
787         } else {
788                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
789                 return 0;
790         }
791 }
792
793 /* macro for ugly context setup/reset */
794 #ifndef DISABLE_PYTHON
795 #define BPY_CTX_SETUP(_cmd) \
796 { \
797         wmWindowManager *wm= CTX_wm_manager(C); \
798         wmWindow *prevwin= CTX_wm_window(C); \
799         Scene *prevscene= CTX_data_scene(C); \
800         if(wm->windows.first) { \
801                 CTX_wm_window_set(C, wm->windows.first); \
802                 _cmd; \
803                 CTX_wm_window_set(C, prevwin); \
804         } \
805         else { \
806                 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
807                 _cmd; \
808         } \
809         CTX_data_scene_set(C, prevscene); \
810 } \
811
812 #endif /* DISABLE_PYTHON */
813
814 static int run_python(int argc, char **argv, void *data)
815 {
816 #ifndef DISABLE_PYTHON
817         bContext *C = data;
818
819         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
820         if (argc > 1) {
821                 /* Make the path absolute because its needed for relative linked blends to be found */
822                 char filename[FILE_MAXDIR + FILE_MAXFILE];
823                 BLI_strncpy(filename, argv[1], sizeof(filename));
824                 BLI_path_cwd(filename);
825
826                 BPY_CTX_SETUP( BPY_run_python_script(C, filename, NULL, NULL) )
827
828                 return 1;
829         } else {
830                 printf("\nError: you must specify a Python script after '-P / --python'.\n");
831                 return 0;
832         }
833 #else
834         printf("This blender was built without python support\n");
835         return 0;
836 #endif /* DISABLE_PYTHON */
837 }
838
839 static int run_python_console(int argc, char **argv, void *data)
840 {
841 #ifndef DISABLE_PYTHON
842         bContext *C = data;     
843         const char *expr= "__import__('code').interact()";
844
845         BPY_CTX_SETUP( BPY_eval_string(C, expr) )
846
847         return 0;
848 #else
849         printf("This blender was built without python support\n");
850         return 0;
851 #endif /* DISABLE_PYTHON */
852 }
853
854 static int load_file(int argc, char **argv, void *data)
855 {
856         bContext *C = data;
857
858         /* Make the path absolute because its needed for relative linked blends to be found */
859         char filename[FILE_MAXDIR + FILE_MAXFILE];
860         BLI_strncpy(filename, argv[0], sizeof(filename));
861         BLI_path_cwd(filename);
862
863         if (G.background) {
864                 int retval = BKE_read_file(C, filename, NULL, NULL);
865
866                 /*we successfully loaded a blend file, get sure that
867                 pointcache works */
868                 if (retval!=0) {
869                         wmWindowManager *wm= CTX_wm_manager(C);
870                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
871                         WM_check(C);
872                         G.relbase_valid = 1;
873                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
874                 }
875
876                 /* WM_read_file() runs normally but since we're in background mode do here */
877 #ifndef DISABLE_PYTHON
878                 /* run any texts that were loaded in and flagged as modules */
879                 BPY_load_user_modules(C);
880 #endif
881
882                 /* happens for the UI on file reading too (huh? (ton))*/
883         // XXX                  BKE_reset_undo();
884         //                              BKE_write_undo("original");     /* save current state */
885         } else {
886                 /* we are not running in background mode here, but start blender in UI mode with
887                    a file - this should do everything a 'load file' does */
888                 WM_read_file(C, filename, NULL);
889         }
890
891         G.file_loaded = 1;
892
893         return 0;
894 }
895
896 void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
897 {
898         static char output_doc[] = "<path>"
899                 "\n\tSet the render path and file name."
900                 "\n\tUse // at the start of the path to"
901                 "\n\t\trender relative to the blend file."
902                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
903                 "\n\t\tani_##_test.png becomes ani_01_test.png"
904                 "\n\t\ttest-######.png becomes test-000001.png"
905                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
906                 "\n\tThe frame number will be added at the end of the filename."
907                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
908                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
909
910         static char format_doc[] = "<format>"
911                 "\n\tSet the render format, Valid options are..."
912                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
913                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
914                 "\n\t(formats that can be compiled into blender, not available on all systems)"
915                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
916
917         static char playback_doc[] = "<options> <file(s)>"
918                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
919                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
920                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
921                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
922                 "\n\t\t-j <frame>\tSet frame step to <frame>";
923
924         static char game_doc[] = "Game Engine specific options"
925                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
926                 "\n\t-g vertexarrays\tUse Vertex Arrays for rendering (usually faster)"
927                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
928                 "\n\t-g linearmipmap\tLinear Texture Mipmapping instead of Nearest (default)";
929
930         static char debug_doc[] = "\n\tTurn debugging on\n"
931                 "\n\t* Prints every operator call and their arguments"
932                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
933                 "\n\t* Keeps python sys.stdin rather then setting it to None";
934
935         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
936
937         /* end argument processing after -- */
938         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
939
940         /* first pass: background mode, disable python and commands that exit after usage */
941         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
942         /* Windows only */
943         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
944
945         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
946
947         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution (default)", enable_python, NULL);
948         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)", disable_python, NULL);
949
950         BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
951
952         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
953
954         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
955     BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
956
957         /* second pass: custom window stuff */
958         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);
959         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
960         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening with without borders", without_borders, NULL);
961         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension (windows only)", register_extension, ba);
962
963         /* third pass: disabling things and forcing settings */
964         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
965         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
966         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
967         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
968
969         /* fourth pass: processing arguments */
970         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
971         BLI_argsAdd(ba, 4, "-f", "--render-frame", "<frame>\n\tRender frame <frame> and save it", render_frame, C);
972         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
973         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, NULL);
974         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
975         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
976         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
977         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
978         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
979
980         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
981         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
982
983         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
984         BLI_argsAdd(ba, 4, "-t", "--threads", "<threads>\n\tUse amount of <threads> for rendering in background\n\t[1-" QUOTE(BLENDER_MAX_THREADS) "], 0 for systems processor count.", set_threads, NULL);
985         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);
986
987 }
988
989 int main(int argc, char **argv)
990 {
991         SYS_SystemHandle syshandle;
992         bContext *C= CTX_create();
993         bArgs *ba;
994
995 #ifdef WITH_BINRELOC
996         br_init( NULL );
997 #endif
998
999         setCallbacks();
1000 #ifdef __APPLE__
1001                 /* patch to ignore argument finder gives us (pid?) */
1002         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1003                 extern int GHOST_HACK_getFirstFile(char buf[]);
1004                 static char firstfilebuf[512];
1005
1006                 argc= 1;
1007
1008                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1009                         argc= 2;
1010                         argv[1]= firstfilebuf;
1011                 }
1012         }
1013
1014 #endif
1015
1016 #ifdef __FreeBSD__
1017         fpsetmask(0);
1018 #endif
1019
1020         // copy path to executable in bprogname. playanim and creting runtimes
1021         // need this.
1022
1023         BLI_where_am_i(bprogname, argv[0]);
1024         
1025         {       /* override the hard coded blender path */
1026                 char *blender_path_env = getenv("BLENDERPATH");
1027                 if(blender_path_env)
1028                         BLI_strncpy(blender_path, blender_path_env, sizeof(blender_path));
1029         }
1030
1031 #ifdef BUILD_DATE       
1032     strip_quotes(build_date);
1033     strip_quotes(build_time);
1034     strip_quotes(build_rev);
1035     strip_quotes(build_platform);
1036     strip_quotes(build_type);
1037 #endif
1038
1039         BLI_threadapi_init();
1040
1041         RNA_init();
1042         RE_engines_init();
1043
1044                 /* Hack - force inclusion of the plugin api functions,
1045                  * see blenpluginapi:pluginapi.c
1046                  */
1047         pluginapi_force_ref();
1048
1049         init_nodesystem();
1050         
1051         initglobals();  /* blender.c */
1052
1053         IMB_init();
1054
1055         syshandle = SYS_GetSystem();
1056         GEN_init_messaging_system();
1057
1058         /* first test for background */
1059         ba = BLI_argsInit(argc, argv); /* skip binary path */
1060         setupArguments(C, ba, &syshandle);
1061
1062         BLI_argsParse(ba, 1, NULL, NULL);
1063
1064 #ifdef __sgi
1065         setuid(getuid()); /* end superuser */
1066 #endif
1067
1068
1069         /* for all platforms, even windos has it! */
1070         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
1071         
1072         /* background render uses this font too */
1073         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1074
1075         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1076            rendered via ffmpeg */
1077         sound_init_once();
1078         
1079         init_def_material();
1080
1081         if(G.background==0) {
1082                 BLI_argsParse(ba, 2, NULL, NULL);
1083                 BLI_argsParse(ba, 3, NULL, NULL);
1084
1085                 WM_init(C, argc, argv);
1086                 
1087                 /* this is properly initialized with user defs, but this is default */
1088                 BLI_where_is_temp( btempdir, 1 ); /* call after loading the .B.blend so we can read U.tempdir */
1089
1090 #ifndef DISABLE_SDL
1091         BLI_setenv("SDL_VIDEODRIVER", "dummy");
1092 /* I think this is not necessary anymore (04-24-2010 neXyon)
1093 #ifdef __linux__
1094         // On linux the default SDL driver dma often would not play
1095         // use alsa if none is set
1096         setenv("SDL_AUDIODRIVER", "alsa", 0);
1097 #endif
1098 */
1099 #endif
1100         }
1101         else {
1102                 BLI_argsParse(ba, 3, NULL, NULL);
1103
1104                 WM_init(C, argc, argv);
1105
1106                 BLI_where_is_temp( btempdir, 0 ); /* call after loading the .B.blend so we can read U.tempdir */
1107         }
1108 #ifndef DISABLE_PYTHON
1109         /**
1110          * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1111          * so we provide the BPY_ function below to append the user defined
1112          * pythondir to Python's sys.path at this point.  Simply putting
1113          * WM_init() before BPY_start_python() crashes Blender at startup.
1114          * Update: now this function also inits the bpymenus, which also depend
1115          * on U.pythondir.
1116          */
1117
1118         // TODO - U.pythondir
1119
1120 #endif
1121         
1122         CTX_py_init_set(C, 1);
1123         WM_keymap_init(C);
1124
1125         /* initialize Freestyle */
1126         FRS_initialize();
1127         FRS_set_context(C);
1128
1129         /* OK we are ready for it */
1130         BLI_argsParse(ba, 4, load_file, C);
1131
1132         BLI_argsFree(ba);
1133
1134         if(G.background) {
1135                 /* actually incorrect, but works for now (ton) */
1136                 WM_exit(C);
1137         }
1138
1139         else {
1140                 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1141                         WM_init_game(C);
1142
1143                 else if(!G.file_loaded)
1144                         WM_init_splash(C);
1145         }
1146
1147         WM_main(C);
1148
1149
1150         /*XXX if (scr_init==0) {
1151                 main_init_screen();
1152         }
1153         
1154         screenmain();*/ /* main display loop */
1155
1156         return 0;
1157 } /* end of int main(argc,argv) */
1158
1159 static void error_cb(char *err)
1160 {
1161         
1162         printf("%s\n", err);    /* XXX do this in WM too */
1163 }
1164
1165 static void mem_error_cb(const char *errorStr)
1166 {
1167         fputs(errorStr, stderr);
1168         fflush(stderr);
1169 }
1170
1171 static void setCallbacks(void)
1172 {
1173         /* Error output from the alloc routines: */
1174         MEM_set_error_callback(mem_error_cb);
1175
1176
1177         /* BLI_blenlib: */
1178
1179         BLI_setErrorCallBack(error_cb); /* */
1180 // XXX  BLI_setInterruptCallBack(blender_test_break);
1181
1182 }