4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 #if defined(__linux__) && defined(__GNUC__)
35 #define OSX_SSE_FPE (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
38 #include <xmmintrin.h>
44 /* for setuid / getuid */
46 #include <sys/types.h>
50 /* This little block needed for linking to Blender... */
52 #include "MEM_guardedalloc.h"
55 #include "BLI_winstuff.h"
59 #include "BLI_threads.h"
61 #include "GEN_messaging.h"
64 #include "DNA_scene_types.h"
66 #include "BLI_blenlib.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_blender.h"
70 #include "BKE_context.h"
72 #include "BKE_global.h"
74 #include "BKE_material.h"
75 #include "BKE_packedFile.h"
76 #include "BKE_scene.h"
78 #include "BKE_report.h"
79 #include "BKE_sound.h"
81 #include "IMB_imbuf.h" // for IMB_init
83 #ifndef DISABLE_PYTHON
84 #include "BPY_extern.h"
87 #include "RE_pipeline.h"
89 //XXX #include "playanim_ext.h"
90 #include "ED_datafiles.h"
94 #include "RNA_define.h"
97 #include "GPU_extensions.h"
99 /* for passing information between creator and gameengine */
100 #include "SYS_System.h"
105 # include <sys/types.h>
106 # include <floatingpoint.h>
107 # include <sys/rtprio.h>
111 #include "binreloc.h"
116 extern char build_date[];
117 extern char build_time[];
118 extern char build_rev[];
119 extern char build_platform[];
120 extern char build_type[];
121 extern char build_cflags[];
122 extern char build_cxxflags[];
123 extern char build_linkflags[];
124 extern char build_system[];
127 /* Local Function prototypes */
128 static int print_help(int argc, char **argv, void *data);
129 static int print_version(int argc, char **argv, void *data);
131 /* for the callbacks: */
133 extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */
135 char bprogname[FILE_MAXDIR+FILE_MAXFILE]; /* from blenpluginapi:pluginapi.c */
136 char btempdir[FILE_MAXDIR+FILE_MAXFILE];
138 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
140 /* Initialise callbacks for the modules that need them */
141 static void setCallbacks(void);
143 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
144 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
145 static void fpe_handler(int UNUSED(sig))
147 // printf("SIGFPE trapped\n");
151 /* handling ctrl-c event in console */
152 static void blender_esc(int sig)
154 static int count = 0;
156 G.afbreek = 1; /* forces render loop to read queue, not sure if its needed */
160 printf("\nBlender killed\n");
163 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
168 /* buildinfo can have quotes */
170 static void strip_quotes(char *str)
173 int len= strlen(str) - 1;
174 memmove(str, str+1, len);
175 if(str[len-1] == '"') {
182 static int print_version(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
184 printf (BLEND_VERSION_STRING_FMT);
186 printf ("\tbuild date: %s\n", build_date);
187 printf ("\tbuild time: %s\n", build_time);
188 printf ("\tbuild revision: %s\n", build_rev);
189 printf ("\tbuild platform: %s\n", build_platform);
190 printf ("\tbuild type: %s\n", build_type);
191 printf ("\tbuild c flags: %s\n", build_cflags);
192 printf ("\tbuild c++ flags: %s\n", build_cxxflags);
193 printf ("\tbuild link flags: %s\n", build_linkflags);
194 printf ("\tbuild system: %s\n", build_system);
201 static int print_help(int UNUSED(argc), char **UNUSED(argv), void *data)
203 bArgs *ba = (bArgs*)data;
205 printf (BLEND_VERSION_STRING_FMT);
206 printf ("Usage: blender [args ...] [file] [args ...]\n\n");
208 printf ("Render Options:\n");
209 BLI_argsPrintArgDoc(ba, "--background");
210 BLI_argsPrintArgDoc(ba, "--render-anim");
211 BLI_argsPrintArgDoc(ba, "--scene");
212 BLI_argsPrintArgDoc(ba, "--render-frame");
213 BLI_argsPrintArgDoc(ba, "--frame-start");
214 BLI_argsPrintArgDoc(ba, "--frame-end");
215 BLI_argsPrintArgDoc(ba, "--frame-jump");
216 BLI_argsPrintArgDoc(ba, "--render-output");
217 BLI_argsPrintArgDoc(ba, "--engine");
220 printf ("Format Options:\n");
221 BLI_argsPrintArgDoc(ba, "--render-format");
222 BLI_argsPrintArgDoc(ba, "--use-extension");
223 BLI_argsPrintArgDoc(ba, "--threads");
226 printf ("Animation Playback Options:\n");
227 BLI_argsPrintArgDoc(ba, "-a");
230 printf ("Window Options:\n");
231 BLI_argsPrintArgDoc(ba, "--window-border");
232 BLI_argsPrintArgDoc(ba, "--window-borderless");
233 BLI_argsPrintArgDoc(ba, "--window-geometry");
236 printf ("Game Engine Specific Options:\n");
237 BLI_argsPrintArgDoc(ba, "-g");
240 printf ("Misc Options:\n");
241 BLI_argsPrintArgDoc(ba, "--debug");
242 BLI_argsPrintArgDoc(ba, "--debug-fpe");
246 BLI_argsPrintArgDoc(ba, "-nojoystick");
247 BLI_argsPrintArgDoc(ba, "-noglsl");
248 BLI_argsPrintArgDoc(ba, "-noaudio");
249 BLI_argsPrintArgDoc(ba, "-setaudio");
253 BLI_argsPrintArgDoc(ba, "--help");
257 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
258 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
262 BLI_argsPrintArgDoc(ba, "--python");
263 BLI_argsPrintArgDoc(ba, "--python-console");
266 BLI_argsPrintArgDoc(ba, "-R");
268 BLI_argsPrintArgDoc(ba, "--version");
270 BLI_argsPrintArgDoc(ba, "--");
272 printf ("Other Options:\n");
273 BLI_argsPrintOtherDoc(ba);
275 printf ("Argument Parsing:\n");
276 printf ("\targuments must be separated by white space. eg\n");
277 printf ("\t\t\"blender -ba test.blend\"\n");
278 printf ("\t...will ignore the 'a'\n");
279 printf ("\t\t\"blender -b test.blend -f8\"\n");
280 printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
282 printf ("Argument Order:\n");
283 printf ("Arguments are executed in the order they are given. eg\n");
284 printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
285 printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
286 printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
287 printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
288 printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
290 printf ("\nEnvironment Variables:\n");
291 printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
292 printf (" $BLENDER_SYSTEM_CONFIG Directory for system wide configuration files.\n");
293 printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
294 printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
295 printf (" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
296 printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
297 printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
299 printf (" $TEMP Store temporary files here.\n");
301 printf (" $TMP or $TMPDIR Store temporary files here.\n");
304 printf (" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
306 printf (" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
314 double PIL_check_seconds_timer(void);
316 /* XXX This was here to fix a crash when running python scripts
317 * with -P that used the screen.
319 * static void main_init_screen( void )
321 setscreen(G.curscreen);
323 if(G.main->scene.first==0) {
324 set_scene( add_scene("1") );
328 static int end_arguments(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
333 static int enable_python(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
335 G.f |= G_SCRIPT_AUTOEXEC;
339 static int disable_python(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
341 G.f &= ~G_SCRIPT_AUTOEXEC;
345 static int background_mode(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
351 static int debug_mode(int UNUSED(argc), char **UNUSED(argv), void *data)
353 G.f |= G_DEBUG; /* std output printf's */
354 printf(BLEND_VERSION_STRING_FMT);
355 MEM_set_memory_debug();
358 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
359 #endif // NAN_BUILDINFO
365 static int set_fpe(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
367 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
368 /* zealous but makes float issues a heck of a lot easier to find!
369 * set breakpoints on fpe_handler */
370 signal(SIGFPE, fpe_handler);
372 # if defined(__linux__) && defined(__GNUC__)
373 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
374 # endif /* defined(__linux__) && defined(__GNUC__) */
376 /* OSX uses SSE for floating point by default, so here
377 * use SSE instructions to throw floating point exceptions */
378 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
379 (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
380 # endif /* OSX_SSE_FPE */
381 # if defined(_WIN32) && defined(_MSC_VER)
382 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
383 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
384 # endif /* _WIN32 && _MSC_VER */
390 static int playback_mode(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
392 /* not if -b was given first */
393 if (G.background == 0) {
395 // XXX playanim(argc, argv); /* not the same argc and argv as before */
402 static int prefsize(int argc, char **argv, void *UNUSED(data))
404 int stax, stay, sizx, sizy;
407 printf ("-p requires four arguments\n");
416 WM_setprefsize(stax, stay, sizx, sizy);
421 static int with_borders(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
423 WM_setinitialstate_normal();
427 static int without_borders(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
429 WM_setinitialstate_fullscreen();
433 static int register_extension(int UNUSED(argc), char **UNUSED(argv), void *data)
436 char *path = BLI_argsArgv(data)[0];
437 RegisterBlendExtension(path);
439 (void)data; /* unused */
445 static int no_joystick(int UNUSED(argc), char **UNUSED(argv), void *data)
447 SYS_SystemHandle *syshandle = data;
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
453 SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
454 if (G.f & G_DEBUG) printf("disabling nojoystick\n");
459 static int no_glsl(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
461 GPU_extensions_disable();
465 static int no_audio(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
467 sound_force_device(0);
471 static int set_audio(int argc, char **argv, void *UNUSED(data))
474 printf("-setaudio require one argument\n");
478 sound_force_device(sound_define_from_str(argv[1]));
482 static int set_output(int argc, char **argv, void *data)
486 if (CTX_data_scene(C)) {
487 Scene *scene= CTX_data_scene(C);
488 BLI_strncpy(scene->r.pic, argv[1], FILE_MAXDIR);
490 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
494 printf("\nError: you must specify a path after '-o / --render-output'.\n");
499 static int set_engine(int argc, char **argv, void *data)
504 if (!strcmp(argv[1],"help"))
506 RenderEngineType *type = NULL;
508 for( type = R_engines.first; type; type = type->next )
510 printf("\t%s\n", type->idname);
516 if (CTX_data_scene(C)==NULL)
518 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
522 Scene *scene= CTX_data_scene(C);
523 RenderData *rd = &scene->r;
524 RenderEngineType *type = NULL;
526 for( type = R_engines.first; type; type = type->next )
528 if (!strcmp(argv[1],type->idname))
530 BLI_strncpy(rd->engine, type->idname, sizeof(rd->engine));
540 printf("\nEngine not specified.\n");
545 static int set_image_type(int argc, char **argv, void *data)
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");
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;
557 else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
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;
569 else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
572 else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
575 else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
576 else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
578 else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
579 else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
581 else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
582 else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
585 else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
587 else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
591 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
596 static int set_threads(int argc, char **argv, void *UNUSED(data))
600 RE_set_max_threads(atoi(argv[1]));
602 printf("Warning: threads can only be set in background mode\n");
606 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
611 static int set_extension(int argc, char **argv, void *data)
615 if (CTX_data_scene(C)) {
616 Scene *scene= CTX_data_scene(C);
617 if (argv[1][0] == '0') {
618 scene->r.scemode &= ~R_EXTENSION;
619 } else if (argv[1][0] == '1') {
620 scene->r.scemode |= R_EXTENSION;
622 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
625 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
629 printf("\nError: you must specify a path after '- '.\n");
634 static int set_ge_parameters(int argc, char **argv, void *data)
636 SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
639 gameengine parameters are automaticly put into system
640 -g [paramname = value]
644 -g maxvertexarraysize = 512
649 char* paramname = argv[a];
650 /* check for single value versus assignment */
651 if (a+1 < argc && (*(argv[a+1]) == '='))
658 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
661 printf("error: argument assignment (%s) without value.\n",paramname);
667 SYS_WriteCommandLineInt(syshandle,argv[a],1);
670 if (!strcmp(argv[a],"nomipmap"))
672 GPU_set_mipmap(0); //doMipMap = 0;
675 if (!strcmp(argv[a],"linearmipmap"))
677 GPU_set_linear_mipmap(1); //linearMipMap = 1;
681 } /* if (*(argv[a+1]) == '=') */
687 static int render_frame(int argc, char **argv, void *data)
690 if (CTX_data_scene(C)) {
691 Main *bmain= CTX_data_main(C);
692 Scene *scene= CTX_data_scene(C);
695 Render *re = RE_NewRender(scene->id.name);
701 frame= scene->r.sfra + atoi(argv[1]+1);
704 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
707 frame= atoi(argv[1]);
711 BKE_reports_init(&reports, RPT_PRINT);
713 frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
715 RE_BlenderAnim(re, bmain, scene, scene->lay, frame, frame, scene->r.frame_step, &reports);
718 printf("\nError: frame number must follow '-f / --render-frame'.\n");
722 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
727 static int render_animation(int UNUSED(argc), char **UNUSED(argv), void *data)
730 if (CTX_data_scene(C)) {
731 Main *bmain= CTX_data_main(C);
732 Scene *scene= CTX_data_scene(C);
733 Render *re= RE_NewRender(scene->id.name);
735 BKE_reports_init(&reports, RPT_PRINT);
736 RE_BlenderAnim(re, bmain, scene, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
738 printf("\nError: no blend loaded. cannot use '-a'.\n");
743 static int set_scene(int argc, char **argv, void *data)
747 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
749 CTX_data_scene_set(C, sce);
753 printf("\nError: Scene name must follow '-S / --scene'.\n");
758 static int set_start_frame(int argc, char **argv, void *data)
761 if (CTX_data_scene(C)) {
762 Scene *scene= CTX_data_scene(C);
764 int frame = atoi(argv[1]);
765 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
768 printf("\nError: frame number must follow '-s / --frame-start'.\n");
772 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
777 static int set_end_frame(int argc, char **argv, void *data)
780 if (CTX_data_scene(C)) {
781 Scene *scene= CTX_data_scene(C);
783 int frame = atoi(argv[1]);
784 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
787 printf("\nError: frame number must follow '-e / --frame-end'.\n");
791 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
796 static int set_skip_frame(int argc, char **argv, void *data)
799 if (CTX_data_scene(C)) {
800 Scene *scene= CTX_data_scene(C);
802 int frame = atoi(argv[1]);
803 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
806 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
810 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
815 /* macro for ugly context setup/reset */
816 #ifndef DISABLE_PYTHON
817 #define BPY_CTX_SETUP(_cmd) \
819 wmWindowManager *wm= CTX_wm_manager(C); \
820 wmWindow *prevwin= CTX_wm_window(C); \
821 Scene *prevscene= CTX_data_scene(C); \
822 if(wm->windows.first) { \
823 CTX_wm_window_set(C, wm->windows.first); \
825 CTX_wm_window_set(C, prevwin); \
828 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
831 CTX_data_scene_set(C, prevscene); \
834 #endif /* DISABLE_PYTHON */
836 static int run_python(int argc, char **argv, void *data)
838 #ifndef DISABLE_PYTHON
841 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
843 /* Make the path absolute because its needed for relative linked blends to be found */
844 char filename[FILE_MAXDIR + FILE_MAXFILE];
845 BLI_strncpy(filename, argv[1], sizeof(filename));
846 BLI_path_cwd(filename);
848 BPY_CTX_SETUP( BPY_run_python_script(C, filename, NULL, NULL) )
852 printf("\nError: you must specify a Python script after '-P / --python'.\n");
856 (void)argc; (void)argv; (void)data; /* unused */
857 printf("This blender was built without python support\n");
859 #endif /* DISABLE_PYTHON */
862 static int run_python_console(int UNUSED(argc), char **argv, void *data)
864 #ifndef DISABLE_PYTHON
866 const char *expr= "__import__('code').interact()";
868 BPY_CTX_SETUP( BPY_eval_string(C, expr) )
872 (void)argv; (void)data; /* unused */
873 printf("This blender was built without python support\n");
875 #endif /* DISABLE_PYTHON */
878 static int load_file(int UNUSED(argc), char **argv, void *data)
882 /* Make the path absolute because its needed for relative linked blends to be found */
883 char filename[FILE_MAXDIR + FILE_MAXFILE];
884 BLI_strncpy(filename, argv[0], sizeof(filename));
885 BLI_path_cwd(filename);
888 int retval = BKE_read_file(C, filename, NULL);
890 /*we successfully loaded a blend file, get sure that
893 wmWindowManager *wm= CTX_wm_manager(C);
894 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
897 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
900 /* WM_read_file() runs normally but since we're in background mode do here */
901 #ifndef DISABLE_PYTHON
902 /* run any texts that were loaded in and flagged as modules */
903 BPY_load_user_modules(C);
906 /* happens for the UI on file reading too (huh? (ton))*/
907 // XXX BKE_reset_undo();
908 // BKE_write_undo("original"); /* save current state */
910 /* we are not running in background mode here, but start blender in UI mode with
911 a file - this should do everything a 'load file' does */
913 BKE_reports_init(&reports, RPT_PRINT);
914 WM_read_file(C, filename, &reports);
915 BKE_reports_clear(&reports);
923 void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
925 static char output_doc[] = "<path>"
926 "\n\tSet the render path and file name."
927 "\n\tUse // at the start of the path to"
928 "\n\t\trender relative to the blend file."
929 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
930 "\n\t\tani_##_test.png becomes ani_01_test.png"
931 "\n\t\ttest-######.png becomes test-000001.png"
932 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
933 "\n\tThe frame number will be added at the end of the filename."
934 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
935 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
937 static char format_doc[] = "<format>"
938 "\n\tSet the render format, Valid options are..."
939 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
940 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
941 "\n\t(formats that can be compiled into blender, not available on all systems)"
942 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
944 static char playback_doc[] = "<options> <file(s)>"
945 "\n\tPlayback <file(s)>, only operates this way when not running in background."
946 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
947 "\n\t\t-m\t\tRead from disk (Don't buffer)"
948 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
949 "\n\t\t-j <frame>\tSet frame step to <frame>";
951 static char game_doc[] = "Game Engine specific options"
952 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
953 "\n\t-g vertexarrays\tUse Vertex Arrays for rendering (usually faster)"
954 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
955 "\n\t-g linearmipmap\tLinear Texture Mipmapping instead of Nearest (default)";
957 static char debug_doc[] = "\n\tTurn debugging on\n"
958 "\n\t* Prints every operator call and their arguments"
959 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
960 "\n\t* Keeps python sys.stdin rather then setting it to None";
962 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
964 /* end argument processing after -- */
965 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
967 /* first pass: background mode, disable python and commands that exit after usage */
968 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
970 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
972 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
974 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution (default)", enable_python, NULL);
975 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)", disable_python, NULL);
977 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
979 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
981 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
982 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
984 /* second pass: custom window stuff */
985 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);
986 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
987 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening with without borders", without_borders, NULL);
988 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension (windows only)", register_extension, ba);
990 /* third pass: disabling things and forcing settings */
991 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
992 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
993 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
994 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
996 /* fourth pass: processing arguments */
997 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
998 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);
999 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1000 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1001 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1002 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1003 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1004 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1005 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1007 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1008 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1010 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1011 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);
1012 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);
1016 int main(int argc, char **argv)
1018 SYS_SystemHandle syshandle;
1019 bContext *C= CTX_create();
1022 #ifdef WITH_BINRELOC
1028 /* patch to ignore argument finder gives us (pid?) */
1029 if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1030 extern int GHOST_HACK_getFirstFile(char buf[]);
1031 static char firstfilebuf[512];
1035 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1037 argv[1]= firstfilebuf;
1047 // copy path to executable in bprogname. playanim and creting runtimes
1050 BLI_where_am_i(bprogname, argv[0]);
1053 strip_quotes(build_date);
1054 strip_quotes(build_time);
1055 strip_quotes(build_rev);
1056 strip_quotes(build_platform);
1057 strip_quotes(build_type);
1058 strip_quotes(build_cflags);
1059 strip_quotes(build_cxxflags);
1060 strip_quotes(build_linkflags);
1061 strip_quotes(build_system);
1064 BLI_threadapi_init();
1069 /* Hack - force inclusion of the plugin api functions,
1070 * see blenpluginapi:pluginapi.c
1072 pluginapi_force_ref();
1076 initglobals(); /* blender.c */
1080 syshandle = SYS_GetSystem();
1081 GEN_init_messaging_system();
1083 /* first test for background */
1084 ba = BLI_argsInit(argc, argv); /* skip binary path */
1085 setupArguments(C, ba, &syshandle);
1087 BLI_argsParse(ba, 1, NULL, NULL);
1090 setuid(getuid()); /* end superuser */
1094 /* for all platforms, even windos has it! */
1095 if(G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1097 /* background render uses this font too */
1098 BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1100 /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1101 rendered via ffmpeg */
1104 init_def_material();
1106 if(G.background==0) {
1107 BLI_argsParse(ba, 2, NULL, NULL);
1108 BLI_argsParse(ba, 3, NULL, NULL);
1110 WM_init(C, argc, argv);
1112 /* this is properly initialized with user defs, but this is default */
1113 BLI_where_is_temp( btempdir, 1 ); /* call after loading the startup.blend so we can read U.tempdir */
1116 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1117 /* I think this is not necessary anymore (04-24-2010 neXyon)
1119 // On linux the default SDL driver dma often would not play
1120 // use alsa if none is set
1121 setenv("SDL_AUDIODRIVER", "alsa", 0);
1127 BLI_argsParse(ba, 3, NULL, NULL);
1129 WM_init(C, argc, argv);
1131 BLI_where_is_temp( btempdir, 0 ); /* call after loading the startup.blend so we can read U.tempdir */
1133 #ifndef DISABLE_PYTHON
1135 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1136 * so we provide the BPY_ function below to append the user defined
1137 * pythondir to Python's sys.path at this point. Simply putting
1138 * WM_init() before BPY_start_python() crashes Blender at startup.
1139 * Update: now this function also inits the bpymenus, which also depend
1143 // TODO - U.pythondir
1147 CTX_py_init_set(C, 1);
1150 /* OK we are ready for it */
1151 BLI_argsParse(ba, 4, load_file, C);
1156 /* actually incorrect, but works for now (ton) */
1161 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1166 else if(!G.file_loaded)
1173 /*XXX if (scr_init==0) {
1177 screenmain();*/ /* main display loop */
1180 } /* end of int main(argc,argv) */
1182 static void error_cb(char *err)
1185 printf("%s\n", err); /* XXX do this in WM too */
1188 static void mem_error_cb(const char *errorStr)
1190 fputs(errorStr, stderr);
1194 static void setCallbacks(void)
1196 /* Error output from the alloc routines: */
1197 MEM_set_error_callback(mem_error_cb);
1202 BLI_setErrorCallBack(error_cb); /* */
1203 // XXX BLI_setInterruptCallBack(blender_test_break);