Blender  V2.59
creator.c
Go to the documentation of this file.
00001 /*
00002  * $Id: creator.c 38804 2011-07-29 01:24:03Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * The Original Code is: all of this file.
00024  *
00025  * Contributor(s): none yet.
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  */
00029 
00035 #if defined(__linux__) && defined(__GNUC__)
00036 #define _GNU_SOURCE
00037 #include <fenv.h>
00038 #endif
00039 
00040 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
00041 #define OSX_SSE_FPE
00042 #include <xmmintrin.h>
00043 #endif
00044 
00045 #include <stdlib.h>
00046 #include <stddef.h>
00047 #include <string.h>
00048 
00049 /* for setuid / getuid */
00050 #ifdef __sgi
00051 #include <sys/types.h>
00052 #include <unistd.h>
00053 #endif
00054 
00055 /* This little block needed for linking to Blender... */
00056 
00057 #include "MEM_guardedalloc.h"
00058 
00059 #ifdef WIN32
00060 #include "BLI_winstuff.h"
00061 #endif
00062 
00063 #include "BLI_args.h"
00064 #include "BLI_threads.h"
00065 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
00066 #include "BLI_utildefines.h"
00067 #include "BLI_callbacks.h"
00068 
00069 #include "DNA_ID.h"
00070 #include "DNA_scene_types.h"
00071 
00072 #include "BLI_blenlib.h"
00073 
00074 #include "BKE_utildefines.h"
00075 #include "BKE_blender.h"
00076 #include "BKE_context.h"
00077 #include "BKE_depsgraph.h" // for DAG_on_visible_update
00078 #include "BKE_font.h"
00079 #include "BKE_global.h"
00080 #include "BKE_main.h"
00081 #include "BKE_material.h"
00082 #include "BKE_packedFile.h"
00083 #include "BKE_scene.h"
00084 #include "BKE_node.h"
00085 #include "BKE_report.h"
00086 #include "BKE_sound.h"
00087 
00088 #include "IMB_imbuf.h"  // for IMB_init
00089 
00090 #ifdef WITH_PYTHON
00091 #include "BPY_extern.h"
00092 #endif
00093 
00094 #include "RE_pipeline.h"
00095 
00096 //XXX #include "playanim_ext.h"
00097 #include "ED_datafiles.h"
00098 
00099 #include "WM_api.h"
00100 
00101 #include "RNA_define.h"
00102 
00103 #include "GPU_draw.h"
00104 #include "GPU_extensions.h"
00105 
00106 #ifdef WITH_BUILDINFO_HEADER
00107 #define BUILD_DATE
00108 #endif
00109 
00110 /* for passing information between creator and gameengine */
00111 #ifdef WITH_GAMEENGINE
00112 #include "BL_System.h"
00113 #else /* dummy */
00114 #define SYS_SystemHandle int
00115 #endif
00116 
00117 #include <signal.h>
00118 
00119 #ifdef __FreeBSD__
00120 # include <sys/types.h>
00121 # include <floatingpoint.h>
00122 # include <sys/rtprio.h>
00123 #endif
00124 
00125 #ifdef WITH_BINRELOC
00126 #include "binreloc.h"
00127 #endif
00128 
00129 // from buildinfo.c
00130 #ifdef BUILD_DATE
00131 extern char build_date[];
00132 extern char build_time[];
00133 extern char build_rev[];
00134 extern char build_platform[];
00135 extern char build_type[];
00136 extern char build_cflags[];
00137 extern char build_cxxflags[];
00138 extern char build_linkflags[];
00139 extern char build_system[];
00140 #endif
00141 
00142 /*      Local Function prototypes */
00143 static int print_help(int argc, const char **argv, void *data);
00144 static int print_version(int argc, const char **argv, void *data);
00145 
00146 /* for the callbacks: */
00147 
00148 extern int pluginapi_force_ref(void);  /* from blenpluginapi:pluginapi.c */
00149 
00150 char bprogname[FILE_MAX]; /* from blenpluginapi:pluginapi.c */
00151 char btempdir[FILE_MAX];
00152 
00153 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
00154 
00155 /* Initialize callbacks for the modules that need them */
00156 static void setCallbacks(void); 
00157 
00158 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
00159 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
00160 static void fpe_handler(int UNUSED(sig))
00161 {
00162         // printf("SIGFPE trapped\n");
00163 }
00164 #endif
00165 
00166 #ifndef WITH_PYTHON_MODULE
00167 /* handling ctrl-c event in console */
00168 static void blender_esc(int sig)
00169 {
00170         static int count = 0;
00171         
00172         G.afbreek = 1;  /* forces render loop to read queue, not sure if its needed */
00173         
00174         if (sig == 2) {
00175                 if (count) {
00176                         printf("\nBlender killed\n");
00177                         exit(2);
00178                 }
00179                 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
00180                 count++;
00181         }
00182 }
00183 #endif
00184 
00185 /* buildinfo can have quotes */
00186 #ifdef BUILD_DATE
00187 static void strip_quotes(char *str)
00188 {
00189         if(str[0] == '"') {
00190                 int len= strlen(str) - 1;
00191                 memmove(str, str+1, len);
00192                 if(str[len-1] == '"') {
00193                         str[len-1]= '\0';
00194                 }
00195         }
00196 }
00197 #endif
00198 
00199 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00200 {
00201         printf (BLEND_VERSION_STRING_FMT);
00202 #ifdef BUILD_DATE
00203         printf ("\tbuild date: %s\n", build_date);
00204         printf ("\tbuild time: %s\n", build_time);
00205         printf ("\tbuild revision: %s\n", build_rev);
00206         printf ("\tbuild platform: %s\n", build_platform);
00207         printf ("\tbuild type: %s\n", build_type);
00208         printf ("\tbuild c flags: %s\n", build_cflags);
00209         printf ("\tbuild c++ flags: %s\n", build_cxxflags);
00210         printf ("\tbuild link flags: %s\n", build_linkflags);
00211         printf ("\tbuild system: %s\n", build_system);
00212 #endif
00213         exit(0);
00214 
00215         return 0;
00216 }
00217 
00218 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
00219 {
00220         bArgs *ba = (bArgs*)data;
00221 
00222         printf (BLEND_VERSION_STRING_FMT);
00223         printf ("Usage: blender [args ...] [file] [args ...]\n\n");
00224 
00225         printf ("Render Options:\n");
00226         BLI_argsPrintArgDoc(ba, "--background");
00227         BLI_argsPrintArgDoc(ba, "--render-anim");
00228         BLI_argsPrintArgDoc(ba, "--scene");
00229         BLI_argsPrintArgDoc(ba, "--render-frame");
00230         BLI_argsPrintArgDoc(ba, "--frame-start");
00231         BLI_argsPrintArgDoc(ba, "--frame-end");
00232         BLI_argsPrintArgDoc(ba, "--frame-jump");
00233         BLI_argsPrintArgDoc(ba, "--render-output");
00234         BLI_argsPrintArgDoc(ba, "--engine");
00235         
00236         printf("\n");
00237         printf ("Format Options:\n");
00238         BLI_argsPrintArgDoc(ba, "--render-format");
00239         BLI_argsPrintArgDoc(ba, "--use-extension");
00240         BLI_argsPrintArgDoc(ba, "--threads");
00241 
00242         printf("\n");
00243         printf ("Animation Playback Options:\n");
00244         BLI_argsPrintArgDoc(ba, "-a");
00245                                 
00246         printf("\n");
00247         printf ("Window Options:\n");
00248         BLI_argsPrintArgDoc(ba, "--window-border");
00249         BLI_argsPrintArgDoc(ba, "--window-borderless");
00250         BLI_argsPrintArgDoc(ba, "--window-geometry");
00251         BLI_argsPrintArgDoc(ba, "--start-console");
00252 
00253         printf("\n");
00254         printf ("Game Engine Specific Options:\n");
00255         BLI_argsPrintArgDoc(ba, "-g");
00256 
00257         printf("\n");
00258         printf ("Misc Options:\n");
00259         BLI_argsPrintArgDoc(ba, "--debug");
00260         BLI_argsPrintArgDoc(ba, "--debug-fpe");
00261         printf("\n");
00262         BLI_argsPrintArgDoc(ba, "--factory-startup");
00263         printf("\n");
00264         BLI_argsPrintArgDoc(ba, "--env-system-config");
00265         BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
00266         BLI_argsPrintArgDoc(ba, "--env-system-scripts");
00267         BLI_argsPrintArgDoc(ba, "--env-system-plugins");
00268         BLI_argsPrintArgDoc(ba, "--env-system-python");
00269         printf("\n");
00270         BLI_argsPrintArgDoc(ba, "-nojoystick");
00271         BLI_argsPrintArgDoc(ba, "-noglsl");
00272         BLI_argsPrintArgDoc(ba, "-noaudio");
00273         BLI_argsPrintArgDoc(ba, "-setaudio");
00274 
00275         printf("\n");
00276 
00277         BLI_argsPrintArgDoc(ba, "--help");
00278 
00279         printf("\n");
00280 
00281         BLI_argsPrintArgDoc(ba, "--enable-autoexec");
00282         BLI_argsPrintArgDoc(ba, "--disable-autoexec");
00283 
00284         printf("\n");
00285 
00286         BLI_argsPrintArgDoc(ba, "--python");
00287         BLI_argsPrintArgDoc(ba, "--python-console");
00288         BLI_argsPrintArgDoc(ba, "--addons");
00289 
00290 #ifdef WIN32
00291         BLI_argsPrintArgDoc(ba, "-R");
00292         BLI_argsPrintArgDoc(ba, "-r");
00293 #endif
00294         BLI_argsPrintArgDoc(ba, "--version");
00295 
00296         BLI_argsPrintArgDoc(ba, "--");
00297 
00298         printf ("Other Options:\n");
00299         BLI_argsPrintOtherDoc(ba);
00300 
00301         printf ("Argument Parsing:\n");
00302         printf ("\targuments must be separated by white space. eg\n");
00303         printf ("\t\t\"blender -ba test.blend\"\n");
00304         printf ("\t...will ignore the 'a'\n");
00305         printf ("\t\t\"blender -b test.blend -f8\"\n");
00306         printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
00307 
00308         printf ("Argument Order:\n");
00309         printf ("Arguments are executed in the order they are given. eg\n");
00310         printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
00311         printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
00312         printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
00313         printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
00314         printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
00315 
00316         printf ("\nEnvironment Variables:\n");
00317         printf ("  $BLENDER_USER_CONFIG      Directory for user configuration files.\n");
00318         printf ("  $BLENDER_USER_SCRIPTS     Directory for user scripts.\n");
00319         printf ("  $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.\n");
00320         printf ("  $BLENDER_USER_DATAFILES   Directory for user data files (icons, translations, ..).\n");
00321         printf ("  $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
00322         printf ("  $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.\n");
00323 #ifdef WIN32
00324         printf ("  $TEMP                     Store temporary files here.\n");
00325 #else
00326         printf ("  $TMP or $TMPDIR           Store temporary files here.\n");
00327 #endif
00328 #ifndef DISABLE_SDL
00329         printf ("  $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.\n");
00330 #endif
00331         printf ("  $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.\n\n");
00332 
00333         exit(0);
00334 
00335         return 0;
00336 }
00337 
00338 
00339 double PIL_check_seconds_timer(void);
00340 
00341 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00342 {
00343         return -1;
00344 }
00345 
00346 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00347 {
00348         G.f |= G_SCRIPT_AUTOEXEC;
00349         G.f |= G_SCRIPT_OVERRIDE_PREF;
00350         return 0;
00351 }
00352 
00353 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00354 {
00355         G.f &= ~G_SCRIPT_AUTOEXEC;
00356         G.f |= G_SCRIPT_OVERRIDE_PREF;
00357         return 0;
00358 }
00359 
00360 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00361 {
00362         G.background = 1;
00363         return 0;
00364 }
00365 
00366 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
00367 {
00368         G.f |= G_DEBUG;         /* std output printf's */
00369         printf(BLEND_VERSION_STRING_FMT);
00370         MEM_set_memory_debug();
00371 
00372 #ifdef NAN_BUILDINFO
00373         printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
00374 #endif // NAN_BUILDINFO
00375 
00376         BLI_argsPrint(data);
00377         return 0;
00378 }
00379 
00380 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00381 {
00382 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
00383         /* zealous but makes float issues a heck of a lot easier to find!
00384          * set breakpoints on fpe_handler */
00385         signal(SIGFPE, fpe_handler);
00386 
00387 # if defined(__linux__) && defined(__GNUC__)
00388         feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
00389 # endif /* defined(__linux__) && defined(__GNUC__) */
00390 # if defined(OSX_SSE_FPE)
00391         /* OSX uses SSE for floating point by default, so here 
00392          * use SSE instructions to throw floating point exceptions */
00393         _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
00394                         (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
00395 # endif /* OSX_SSE_FPE */
00396 # if defined(_WIN32) && defined(_MSC_VER)
00397         _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
00398         _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
00399 # endif /* _WIN32 && _MSC_VER */
00400 #endif
00401 
00402         return 0;
00403 }
00404 
00405 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00406 {
00407         G.factory_startup= 1;
00408         return 0;
00409 }
00410 
00411 static int set_env(int argc, const char **argv, void *UNUSED(data))
00412 {
00413         /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
00414 
00415         char env[64]= "BLENDER";
00416         char *ch_dst= env + 7; /* skip BLENDER */
00417         const char *ch_src= argv[0] + 5; /* skip --env */
00418 
00419         if (argc < 2) {
00420                 printf("%s requires one argument\n", argv[0]);
00421                 exit(1);
00422         }
00423 
00424         for(; *ch_src; ch_src++, ch_dst++) {
00425                 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
00426         }
00427 
00428         *ch_dst= '\0';
00429         BLI_setenv(env, argv[1]);
00430         return 1;
00431 }
00432 
00433 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00434 {
00435         /* not if -b was given first */
00436         if (G.background == 0) {
00437 #if 0   /* TODO, bring player back? */
00438                 playanim(argc, argv); /* not the same argc and argv as before */
00439 #else
00440                 fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
00441                 exit(0);
00442 #endif
00443         }
00444 
00445         return -2;
00446 }
00447 
00448 static int prefsize(int argc, const char **argv, void *UNUSED(data))
00449 {
00450         int stax, stay, sizx, sizy;
00451 
00452         if (argc < 5) {
00453                 printf ("-p requires four arguments\n");
00454                 exit(1);
00455         }
00456 
00457         stax= atoi(argv[1]);
00458         stay= atoi(argv[2]);
00459         sizx= atoi(argv[3]);
00460         sizy= atoi(argv[4]);
00461 
00462         WM_setprefsize(stax, stay, sizx, sizy);
00463 
00464         return 4;
00465 }
00466 
00467 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00468 {
00469         WM_setinitialstate_normal();
00470         return 0;
00471 }
00472 
00473 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00474 {
00475         WM_setinitialstate_fullscreen();
00476         return 0;
00477 }
00478 
00479 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
00480 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00481 {
00482         wm_start_with_console = 1;
00483         return 0;
00484 }
00485 
00486 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
00487 {
00488 #ifdef WIN32
00489         if (data)
00490                 G.background = 1;
00491         RegisterBlendExtension();
00492 #else
00493         (void)data; /* unused */
00494 #endif
00495         return 0;
00496 }
00497 
00498 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
00499 {
00500 #ifndef WITH_GAMEENGINE
00501         (void)data;
00502 #else
00503         SYS_SystemHandle *syshandle = data;
00504 
00509         SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
00510         if (G.f & G_DEBUG) printf("disabling nojoystick\n");
00511 #endif
00512 
00513         return 0;
00514 }
00515 
00516 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00517 {
00518         GPU_extensions_disable();
00519         return 0;
00520 }
00521 
00522 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
00523 {
00524         sound_force_device(0);
00525         return 0;
00526 }
00527 
00528 static int set_audio(int argc, const char **argv, void *UNUSED(data))
00529 {
00530         if (argc < 1) {
00531                 printf("-setaudio require one argument\n");
00532                 exit(1);
00533         }
00534 
00535         sound_force_device(sound_define_from_str(argv[1]));
00536         return 1;
00537 }
00538 
00539 static int set_output(int argc, const char **argv, void *data)
00540 {
00541         bContext *C = data;
00542         if (argc >= 1){
00543                 if (CTX_data_scene(C)) {
00544                         Scene *scene= CTX_data_scene(C);
00545                         BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
00546                 } else {
00547                         printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
00548                 }
00549                 return 1;
00550         } else {
00551                 printf("\nError: you must specify a path after '-o  / --render-output'.\n");
00552                 return 0;
00553         }
00554 }
00555 
00556 static int set_engine(int argc, const char **argv, void *data)
00557 {
00558         bContext *C = data;
00559         if (argc >= 1)
00560         {
00561                 if (!strcmp(argv[1],"help"))
00562                 {
00563                         RenderEngineType *type = NULL;
00564 
00565                         for( type = R_engines.first; type; type = type->next )
00566                         {
00567                                 printf("\t%s\n", type->idname);
00568                         }
00569                         exit(0);
00570                 }
00571                 else
00572                 {
00573                         if (CTX_data_scene(C)==NULL)
00574                         {
00575                                 printf("\nError: no blend loaded. order the arguments so '-E  / --engine ' is after a blend is loaded.\n");
00576                         }
00577                         else {
00578                                 Scene *scene= CTX_data_scene(C);
00579                                 RenderData *rd = &scene->r;
00580 
00581                                 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
00582                                         BLI_strncpy(rd->engine, argv[1], sizeof(rd->engine));
00583                                 }
00584                         }
00585                 }
00586 
00587                 return 1;
00588         }
00589         else
00590         {
00591                 printf("\nEngine not specified.\n");
00592                 return 0;
00593         }
00594 }
00595 
00596 static int set_image_type(int argc, const char **argv, void *data)
00597 {
00598         bContext *C = data;
00599         if (argc >= 1){
00600                 const char *imtype = argv[1];
00601                 if (CTX_data_scene(C)==NULL) {
00602                         printf("\nError: no blend loaded. order the arguments so '-F  / --render-format' is after the blend is loaded.\n");
00603                 } else {
00604                         Scene *scene= CTX_data_scene(C);
00605                         if      (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
00606                         else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
00607 #ifdef WITH_DDS
00608                         else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
00609 #endif
00610                         else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
00611                         else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
00612                         else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
00613                         else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
00614                         else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
00615                         else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
00616                         else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
00617                         else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
00618                         else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
00619 #ifdef WITH_HDR
00620                         else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
00621 #endif
00622 #ifdef WITH_TIFF
00623                         else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
00624 #endif
00625 #ifdef WITH_OPENEXR
00626                         else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
00627                         else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
00628 #endif
00629                         else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
00630                         else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
00631 #ifdef WITH_CINEON
00632                         else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
00633                         else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
00634 #endif
00635 #ifdef WITH_OPENJPEG
00636                         else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
00637 #endif
00638                         else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
00639                 }
00640                 return 1;
00641         } else {
00642                 printf("\nError: you must specify a format after '-F  / --render-foramt'.\n");
00643                 return 0;
00644         }
00645 }
00646 
00647 static int set_threads(int argc, const char **argv, void *UNUSED(data))
00648 {
00649         if (argc >= 1) {
00650                 if(G.background) {
00651                         RE_set_max_threads(atoi(argv[1]));
00652                 } else {
00653                         printf("Warning: threads can only be set in background mode\n");
00654                 }
00655                 return 1;
00656         } else {
00657                 printf("\nError: you must specify a number of threads between 0 and 8 '-t  / --threads'.\n");
00658                 return 0;
00659         }
00660 }
00661 
00662 static int set_extension(int argc, const char **argv, void *data)
00663 {
00664         bContext *C = data;
00665         if (argc >= 1) {
00666                 if (CTX_data_scene(C)) {
00667                         Scene *scene= CTX_data_scene(C);
00668                         if (argv[1][0] == '0') {
00669                                 scene->r.scemode &= ~R_EXTENSION;
00670                         } else if (argv[1][0] == '1') {
00671                                 scene->r.scemode |= R_EXTENSION;
00672                         } else {
00673                                 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
00674                         }
00675                 } else {
00676                         printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
00677                 }
00678                 return 1;
00679         } else {
00680                 printf("\nError: you must specify a path after '- '.\n");
00681                 return 0;
00682         }
00683 }
00684 
00685 static int set_ge_parameters(int argc, const char **argv, void *data)
00686 {
00687         int a = 0;
00688 #ifdef WITH_GAMEENGINE
00689         SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
00690 #else
00691         (void)data;
00692 #endif
00693 
00703         if(argc >= 1)
00704         {
00705                 const char *paramname = argv[a];
00706                 /* check for single value versus assignment */
00707                 if (a+1 < argc && (*(argv[a+1]) == '='))
00708                 {
00709                         a++;
00710                         if (a+1 < argc)
00711                         {
00712                                 a++;
00713                                 /* assignment */
00714 #ifdef WITH_GAMEENGINE
00715                                 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
00716 #endif
00717                         }  else
00718                         {
00719                                 printf("error: argument assignment (%s) without value.\n",paramname);
00720                                 return 0;
00721                         }
00722                         /* name arg eaten */
00723 
00724                 } else {
00725 #ifdef WITH_GAMEENGINE
00726                         SYS_WriteCommandLineInt(syshandle,argv[a],1);
00727 #endif
00728                         /* doMipMap */
00729                         if (!strcmp(argv[a],"nomipmap"))
00730                         {
00731                                 GPU_set_mipmap(0); //doMipMap = 0;
00732                         }
00733                         /* linearMipMap */
00734                         if (!strcmp(argv[a],"linearmipmap"))
00735                         {
00736                                 GPU_set_linear_mipmap(1); //linearMipMap = 1;
00737                         }
00738 
00739 
00740                 } /* if (*(argv[a+1]) == '=') */
00741         }
00742 
00743         return a;
00744 }
00745 
00746 static int render_frame(int argc, const char **argv, void *data)
00747 {
00748         bContext *C = data;
00749         if (CTX_data_scene(C)) {
00750                 Main *bmain= CTX_data_main(C);
00751                 Scene *scene= CTX_data_scene(C);
00752 
00753                 if (argc > 1) {
00754                         Render *re = RE_NewRender(scene->id.name);
00755                         int frame;
00756                         ReportList reports;
00757 
00758                         switch(*argv[1]) {
00759                         case '+':
00760                                 frame= scene->r.sfra + atoi(argv[1]+1);
00761                                 break;
00762                         case '-':
00763                                 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
00764                                 break;
00765                         default:
00766                                 frame= atoi(argv[1]);
00767                                 break;
00768                         }
00769 
00770                         BKE_reports_init(&reports, RPT_PRINT);
00771 
00772                         frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
00773 
00774                         RE_SetReports(re, &reports);
00775                         RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
00776                         RE_SetReports(re, NULL);
00777                         return 1;
00778                 } else {
00779                         printf("\nError: frame number must follow '-f / --render-frame'.\n");
00780                         return 0;
00781                 }
00782         } else {
00783                 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
00784                 return 0;
00785         }
00786 }
00787 
00788 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
00789 {
00790         bContext *C = data;
00791         if (CTX_data_scene(C)) {
00792                 Main *bmain= CTX_data_main(C);
00793                 Scene *scene= CTX_data_scene(C);
00794                 Render *re= RE_NewRender(scene->id.name);
00795                 ReportList reports;
00796                 BKE_reports_init(&reports, RPT_PRINT);
00797                 RE_SetReports(re, &reports);
00798                 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
00799                 RE_SetReports(re, NULL);
00800         } else {
00801                 printf("\nError: no blend loaded. cannot use '-a'.\n");
00802         }
00803         return 0;
00804 }
00805 
00806 static int set_scene(int argc, const char **argv, void *data)
00807 {
00808         if(argc > 1) {
00809                 bContext *C= data;
00810                 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
00811                 if(sce) {
00812                         CTX_data_scene_set(C, sce);
00813                 }
00814                 return 1;
00815         } else {
00816                 printf("\nError: Scene name must follow '-S / --scene'.\n");
00817                 return 0;
00818         }
00819 }
00820 
00821 static int set_start_frame(int argc, const char **argv, void *data)
00822 {
00823         bContext *C = data;
00824         if (CTX_data_scene(C)) {
00825                 Scene *scene= CTX_data_scene(C);
00826                 if (argc > 1) {
00827                         int frame = atoi(argv[1]);
00828                         (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
00829                         return 1;
00830                 } else {
00831                         printf("\nError: frame number must follow '-s / --frame-start'.\n");
00832                         return 0;
00833                 }
00834         } else {
00835                 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
00836                 return 0;
00837         }
00838 }
00839 
00840 static int set_end_frame(int argc, const char **argv, void *data)
00841 {
00842         bContext *C = data;
00843         if (CTX_data_scene(C)) {
00844                 Scene *scene= CTX_data_scene(C);
00845                 if (argc > 1) {
00846                         int frame = atoi(argv[1]);
00847                         (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
00848                         return 1;
00849                 } else {
00850                         printf("\nError: frame number must follow '-e / --frame-end'.\n");
00851                         return 0;
00852                 }
00853         } else {
00854                 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
00855                 return 0;
00856         }
00857 }
00858 
00859 static int set_skip_frame(int argc, const char **argv, void *data)
00860 {
00861         bContext *C = data;
00862         if (CTX_data_scene(C)) {
00863                 Scene *scene= CTX_data_scene(C);
00864                 if (argc > 1) {
00865                         int frame = atoi(argv[1]);
00866                         (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
00867                         return 1;
00868                 } else {
00869                         printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
00870                         return 0;
00871                 }
00872         } else {
00873                 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
00874                 return 0;
00875         }
00876 }
00877 
00878 /* macro for ugly context setup/reset */
00879 #ifdef WITH_PYTHON
00880 #define BPY_CTX_SETUP(_cmd) \
00881 { \
00882         wmWindowManager *wm= CTX_wm_manager(C); \
00883         wmWindow *prevwin= CTX_wm_window(C); \
00884         Scene *prevscene= CTX_data_scene(C); \
00885         if(wm->windows.first) { \
00886                 CTX_wm_window_set(C, wm->windows.first); \
00887                 _cmd; \
00888                 CTX_wm_window_set(C, prevwin); \
00889         } \
00890         else { \
00891                 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
00892                 _cmd; \
00893         } \
00894         CTX_data_scene_set(C, prevscene); \
00895 } \
00896 
00897 #endif /* WITH_PYTHON */
00898 
00899 static int run_python(int argc, const char **argv, void *data)
00900 {
00901 #ifdef WITH_PYTHON
00902         bContext *C = data;
00903 
00904         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
00905         if (argc > 1) {
00906                 /* Make the path absolute because its needed for relative linked blends to be found */
00907                 char filename[FILE_MAXDIR + FILE_MAXFILE];
00908                 BLI_strncpy(filename, argv[1], sizeof(filename));
00909                 BLI_path_cwd(filename);
00910 
00911                 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
00912 
00913                 return 1;
00914         } else {
00915                 printf("\nError: you must specify a Python script after '-P / --python'.\n");
00916                 return 0;
00917         }
00918 #else
00919         (void)argc; (void)argv; (void)data; /* unused */
00920         printf("This blender was built without python support\n");
00921         return 0;
00922 #endif /* WITH_PYTHON */
00923 }
00924 
00925 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
00926 {
00927 #ifdef WITH_PYTHON
00928         bContext *C = data;
00929 
00930         BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
00931 
00932         return 0;
00933 #else
00934         (void)argv; (void)data; /* unused */
00935         printf("This blender was built without python support\n");
00936         return 0;
00937 #endif /* WITH_PYTHON */
00938 }
00939 
00940 static int set_addons(int argc, const char **argv, void *data)
00941 {
00942         /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
00943         if (argc > 1) {
00944 #ifdef WITH_PYTHON
00945                 const int slen= strlen(argv[1]) + 128;
00946                 char *str= malloc(slen);
00947                 bContext *C= data;
00948                 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
00949                 BPY_CTX_SETUP(BPY_string_exec(C, str));
00950                 free(str);
00951 #else
00952                 (void)argv; (void)data; /* unused */
00953 #endif /* WITH_PYTHON */
00954                 return 1;
00955         }
00956         else {
00957                 printf("\nError: you must specify a comma separated list after '--addons'.\n");
00958                 return 0;
00959         }
00960 }
00961 
00962 
00963 static int load_file(int UNUSED(argc), const char **argv, void *data)
00964 {
00965         bContext *C = data;
00966 
00967         /* Make the path absolute because its needed for relative linked blends to be found */
00968         char filename[FILE_MAXDIR + FILE_MAXFILE];
00969         BLI_strncpy(filename, argv[0], sizeof(filename));
00970         BLI_path_cwd(filename);
00971 
00972         if (G.background) {
00973                 int retval = BKE_read_file(C, filename, NULL);
00974 
00975                 /*we successfully loaded a blend file, get sure that
00976                 pointcache works */
00977                 if (retval != BKE_READ_FILE_FAIL) {
00978                         wmWindowManager *wm= CTX_wm_manager(C);
00979 
00980                         /* special case, 2.4x files */
00981                         if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
00982                                 extern void wm_add_default(bContext *C);
00983 
00984                                 /* wm_add_default() needs the screen to be set. */
00985                                 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
00986                                 wm_add_default(C);
00987                         }
00988 
00989                         CTX_wm_manager_set(C, NULL); /* remove wm to force check */
00990                         WM_check(C);
00991                         G.relbase_valid = 1;
00992                         if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
00993 
00994                         DAG_on_visible_update(CTX_data_main(C), TRUE);
00995                 }
00996 
00997                 /* WM_read_file() runs normally but since we're in background mode do here */
00998 #ifdef WITH_PYTHON
00999                 /* run any texts that were loaded in and flagged as modules */
01000                 BPY_driver_reset();
01001                 BPY_app_handlers_reset();
01002                 BPY_modules_load_user(C);
01003 #endif
01004 
01005                 /* happens for the UI on file reading too (huh? (ton))*/
01006         // XXX                  BKE_reset_undo();
01007         //                              BKE_write_undo("original");     /* save current state */
01008         } else {
01009                 /* we are not running in background mode here, but start blender in UI mode with
01010                    a file - this should do everything a 'load file' does */
01011                 ReportList reports;
01012                 BKE_reports_init(&reports, RPT_PRINT);
01013                 WM_read_file(C, filename, &reports);
01014                 BKE_reports_clear(&reports);
01015         }
01016 
01017         G.file_loaded = 1;
01018 
01019         return 0;
01020 }
01021 
01022 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
01023 {
01024         static char output_doc[] = "<path>"
01025                 "\n\tSet the render path and file name."
01026                 "\n\tUse // at the start of the path to"
01027                 "\n\t\trender relative to the blend file."
01028                 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
01029                 "\n\t\tani_##_test.png becomes ani_01_test.png"
01030                 "\n\t\ttest-######.png becomes test-000001.png"
01031                 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
01032                 "\n\tThe frame number will be added at the end of the filename."
01033                 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
01034                 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
01035 
01036         static char format_doc[] = "<format>"
01037                 "\n\tSet the render format, Valid options are..."
01038                 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
01039                 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
01040                 "\n\t(formats that can be compiled into blender, not available on all systems)"
01041                 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
01042 
01043         static char playback_doc[] = "<options> <file(s)>"
01044                 "\n\tPlayback <file(s)>, only operates this way when not running in background."
01045                 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
01046                 "\n\t\t-m\t\tRead from disk (Don't buffer)"
01047                 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
01048                 "\n\t\t-j <frame>\tSet frame step to <frame>";
01049 
01050         static char game_doc[] = "Game Engine specific options"
01051                 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
01052                 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
01053                 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
01054                 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
01055 
01056         static char debug_doc[] = "\n\tTurn debugging on\n"
01057                 "\n\t* Prints every operator call and their arguments"
01058                 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
01059                 "\n\t* Keeps python sys.stdin rather than setting it to None";
01060 
01061         //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
01062 
01063         /* end argument processing after -- */
01064         BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
01065 
01066         /* first pass: background mode, disable python and commands that exit after usage */
01067         BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
01068         /* Windows only */
01069         BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
01070 
01071         BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
01072         
01073         /* only to give help message */
01074 #ifndef WITH_PYTHON_SECURITY /* default */
01075 #  define       PY_ENABLE_AUTO ", (default)"
01076 #  define       PY_DISABLE_AUTO ""
01077 #else
01078 #  define       PY_ENABLE_AUTO ""
01079 #  define       PY_DISABLE_AUTO ", (compiled as non-standard default)"
01080 #endif
01081 
01082         BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
01083         BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
01084 
01085 #undef PY_ENABLE_AUTO
01086 #undef PY_DISABLE_AUTO
01087         
01088         BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
01089 
01090         BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
01091 
01092         BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
01093         BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
01094 
01095         BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
01096 
01097         /* TODO, add user env vars? */
01098         BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles",      "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
01099         BLI_argsAdd(ba, 1, NULL, "--env-system-scripts",        "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
01100         BLI_argsAdd(ba, 1, NULL, "--env-system-plugins",        "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
01101         BLI_argsAdd(ba, 1, NULL, "--env-system-python",         "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
01102 
01103         /* second pass: custom window stuff */
01104         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);
01105         BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
01106         BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
01107         BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
01108         BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
01109         BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
01110 
01111         /* third pass: disabling things and forcing settings */
01112         BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
01113         BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
01114         BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
01115         BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
01116 
01117         /* fourth pass: processing arguments */
01118         BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
01119         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);
01120         BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
01121         BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
01122         BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
01123         BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
01124         BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
01125         BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
01126         BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
01127         BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
01128 
01129         BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
01130         BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
01131 
01132         BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
01133         BLI_argsAdd(ba, 4, "-t", "--threads", "<threads>\n\tUse amount of <threads> for rendering in background\n\t[1-" STRINGIFY(BLENDER_MAX_THREADS) "], 0 for systems processor count.", set_threads, NULL);
01134         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);
01135 
01136 }
01137 
01138 #ifdef WITH_PYTHON_MODULE
01139 /* allow python module to call main */
01140 #define main main_python_enter
01141 static void *evil_C= NULL;
01142 #endif
01143 
01144 int main(int argc, const char **argv)
01145 {
01146         SYS_SystemHandle syshandle;
01147         bContext *C= CTX_create();
01148         bArgs *ba;
01149 
01150 #ifdef WITH_PYTHON_MODULE
01151 #undef main
01152         evil_C= C;
01153 #endif
01154 
01155 #ifdef WITH_BINRELOC
01156         br_init( NULL );
01157 #endif
01158 
01159         setCallbacks();
01160 #ifdef __APPLE__
01161                 /* patch to ignore argument finder gives us (pid?) */
01162         if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
01163                 extern int GHOST_HACK_getFirstFile(char buf[]);
01164                 static char firstfilebuf[512];
01165 
01166                 argc= 1;
01167 
01168                 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
01169                         argc= 2;
01170                         argv[1]= firstfilebuf;
01171                 }
01172         }
01173 
01174 #endif
01175 
01176 #ifdef __FreeBSD__
01177         fpsetmask(0);
01178 #endif
01179 
01180         // copy path to executable in bprogname. playanim and creting runtimes
01181         // need this.
01182 
01183         BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
01184         
01185 #ifdef BUILD_DATE       
01186         strip_quotes(build_date);
01187         strip_quotes(build_time);
01188         strip_quotes(build_rev);
01189         strip_quotes(build_platform);
01190         strip_quotes(build_type);
01191         strip_quotes(build_cflags);
01192         strip_quotes(build_cxxflags);
01193         strip_quotes(build_linkflags);
01194         strip_quotes(build_system);
01195 #endif
01196 
01197         BLI_threadapi_init();
01198 
01199         RNA_init();
01200         RE_engines_init();
01201 
01202                 /* Hack - force inclusion of the plugin api functions,
01203                  * see blenpluginapi:pluginapi.c
01204                  */
01205         pluginapi_force_ref();
01206 
01207         init_nodesystem();
01208         
01209         initglobals();  /* blender.c */
01210 
01211         IMB_init();
01212 
01213         BLI_cb_init();
01214 
01215 #ifdef WITH_GAMEENGINE
01216         syshandle = SYS_GetSystem();
01217 #else
01218         syshandle= 0;
01219 #endif
01220 
01221         /* first test for background */
01222         ba = BLI_argsInit(argc, argv); /* skip binary path */
01223         setupArguments(C, ba, &syshandle);
01224 
01225         BLI_argsParse(ba, 1, NULL, NULL);
01226 
01227 #ifdef __sgi
01228         setuid(getuid()); /* end superuser */
01229 #endif
01230 
01231 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
01232         G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
01233 #else
01234         /* for all platforms, even windos has it! */
01235         if(G.background) signal(SIGINT, blender_esc);   /* ctrl c out bg render */
01236 #endif
01237 
01238         /* background render uses this font too */
01239         BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
01240 
01241         /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
01242            rendered via ffmpeg */
01243         sound_init_once();
01244         
01245         init_def_material();
01246 
01247         if(G.background==0) {
01248                 BLI_argsParse(ba, 2, NULL, NULL);
01249                 BLI_argsParse(ba, 3, NULL, NULL);
01250 
01251                 WM_init(C, argc, argv);
01252 
01253                 /* this is properly initialized with user defs, but this is default */
01254                 BLI_where_is_temp(btempdir, FILE_MAX, 1); /* call after loading the startup.blend so we can read U.tempdir */
01255 
01256 #ifndef DISABLE_SDL
01257         BLI_setenv("SDL_VIDEODRIVER", "dummy");
01258 #endif
01259         }
01260         else {
01261                 BLI_argsParse(ba, 3, NULL, NULL);
01262 
01263                 WM_init(C, argc, argv);
01264 
01265                 BLI_where_is_temp(btempdir, FILE_MAX, 0); /* call after loading the startup.blend so we can read U.tempdir */
01266         }
01267 #ifdef WITH_PYTHON
01268 
01277         // TODO - U.pythondir
01278 #else
01279         printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
01280 #endif
01281         
01282         CTX_py_init_set(C, 1);
01283         WM_keymap_init(C);
01284 
01285         /* OK we are ready for it */
01286         BLI_argsParse(ba, 4, load_file, C);
01287 
01288         BLI_argsFree(ba);
01289 
01290 #ifdef WITH_PYTHON_MODULE
01291         return 0; /* keep blender in background mode running */
01292 #endif
01293 
01294         if(G.background) {
01295                 /* actually incorrect, but works for now (ton) */
01296                 WM_exit(C);
01297         }
01298 
01299         else {
01300                 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
01301                 {
01302                         if(WM_init_game(C))
01303                                 return 0;
01304                 }
01305                 else if(!G.file_loaded)
01306                         WM_init_splash(C);
01307         }
01308 
01309         WM_main(C);
01310 
01311 
01312         /*XXX if (scr_init==0) {
01313                 main_init_screen();
01314         }
01315         
01316         screenmain();*/ /* main display loop */
01317 
01318         return 0;
01319 } /* end of int main(argc,argv) */
01320 
01321 #ifdef WITH_PYTHON_MODULE
01322 void main_python_exit(void)
01323 {
01324         WM_exit((bContext *)evil_C);
01325         evil_C= NULL;
01326 }
01327 #endif
01328 
01329 static void error_cb(const char *err)
01330 {
01331         
01332         printf("%s\n", err);    /* XXX do this in WM too */
01333 }
01334 
01335 static void mem_error_cb(const char *errorStr)
01336 {
01337         fputs(errorStr, stderr);
01338         fflush(stderr);
01339 }
01340 
01341 static void setCallbacks(void)
01342 {
01343         /* Error output from the alloc routines: */
01344         MEM_set_error_callback(mem_error_cb);
01345 
01346 
01347         /* BLI_blenlib: */
01348 
01349         BLI_setErrorCallBack(error_cb); /* */
01350 // XXX  BLI_setInterruptCallBack(blender_test_break);
01351 
01352 }