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"
60 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
61 #include "BLI_utildefines.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"
71 #include "BKE_depsgraph.h" // for DAG_on_load_update
73 #include "BKE_global.h"
75 #include "BKE_material.h"
76 #include "BKE_packedFile.h"
77 #include "BKE_scene.h"
79 #include "BKE_report.h"
80 #include "BKE_sound.h"
82 #include "IMB_imbuf.h" // for IMB_init
85 #include "BPY_extern.h"
88 #include "RE_pipeline.h"
90 //XXX #include "playanim_ext.h"
91 #include "ED_datafiles.h"
95 #include "RNA_define.h"
98 #include "GPU_extensions.h"
100 /* for passing information between creator and gameengine */
101 #ifdef WITH_GAMEENGINE
102 #include "GEN_messaging.h"
103 #include "SYS_System.h"
105 #define SYS_SystemHandle int
111 # include <sys/types.h>
112 # include <floatingpoint.h>
113 # include <sys/rtprio.h>
117 #include "binreloc.h"
122 extern char build_date[];
123 extern char build_time[];
124 extern char build_rev[];
125 extern char build_platform[];
126 extern char build_type[];
127 extern char build_cflags[];
128 extern char build_cxxflags[];
129 extern char build_linkflags[];
130 extern char build_system[];
133 /* Local Function prototypes */
134 static int print_help(int argc, char **argv, void *data);
135 static int print_version(int argc, char **argv, void *data);
137 /* for the callbacks: */
139 extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */
141 char bprogname[FILE_MAXDIR+FILE_MAXFILE]; /* from blenpluginapi:pluginapi.c */
142 char btempdir[FILE_MAXDIR+FILE_MAXFILE];
144 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d) Build\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
146 /* Initialise callbacks for the modules that need them */
147 static void setCallbacks(void);
149 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
150 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
151 static void fpe_handler(int UNUSED(sig))
153 // printf("SIGFPE trapped\n");
157 /* handling ctrl-c event in console */
158 static void blender_esc(int sig)
160 static int count = 0;
162 G.afbreek = 1; /* forces render loop to read queue, not sure if its needed */
166 printf("\nBlender killed\n");
169 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
174 /* buildinfo can have quotes */
176 static void strip_quotes(char *str)
179 int len= strlen(str) - 1;
180 memmove(str, str+1, len);
181 if(str[len-1] == '"') {
188 static int print_version(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
190 printf (BLEND_VERSION_STRING_FMT);
192 printf ("\tbuild date: %s\n", build_date);
193 printf ("\tbuild time: %s\n", build_time);
194 printf ("\tbuild revision: %s\n", build_rev);
195 printf ("\tbuild platform: %s\n", build_platform);
196 printf ("\tbuild type: %s\n", build_type);
197 printf ("\tbuild c flags: %s\n", build_cflags);
198 printf ("\tbuild c++ flags: %s\n", build_cxxflags);
199 printf ("\tbuild link flags: %s\n", build_linkflags);
200 printf ("\tbuild system: %s\n", build_system);
207 static int print_help(int UNUSED(argc), char **UNUSED(argv), void *data)
209 bArgs *ba = (bArgs*)data;
211 printf (BLEND_VERSION_STRING_FMT);
212 printf ("Usage: blender [args ...] [file] [args ...]\n\n");
214 printf ("Render Options:\n");
215 BLI_argsPrintArgDoc(ba, "--background");
216 BLI_argsPrintArgDoc(ba, "--render-anim");
217 BLI_argsPrintArgDoc(ba, "--scene");
218 BLI_argsPrintArgDoc(ba, "--render-frame");
219 BLI_argsPrintArgDoc(ba, "--frame-start");
220 BLI_argsPrintArgDoc(ba, "--frame-end");
221 BLI_argsPrintArgDoc(ba, "--frame-jump");
222 BLI_argsPrintArgDoc(ba, "--render-output");
223 BLI_argsPrintArgDoc(ba, "--engine");
226 printf ("Format Options:\n");
227 BLI_argsPrintArgDoc(ba, "--render-format");
228 BLI_argsPrintArgDoc(ba, "--use-extension");
229 BLI_argsPrintArgDoc(ba, "--threads");
232 printf ("Animation Playback Options:\n");
233 BLI_argsPrintArgDoc(ba, "-a");
236 printf ("Window Options:\n");
237 BLI_argsPrintArgDoc(ba, "--window-border");
238 BLI_argsPrintArgDoc(ba, "--window-borderless");
239 BLI_argsPrintArgDoc(ba, "--window-geometry");
242 printf ("Game Engine Specific Options:\n");
243 BLI_argsPrintArgDoc(ba, "-g");
246 printf ("Misc Options:\n");
247 BLI_argsPrintArgDoc(ba, "--debug");
248 BLI_argsPrintArgDoc(ba, "--debug-fpe");
250 BLI_argsPrintArgDoc(ba, "--factory-startup");
252 BLI_argsPrintArgDoc(ba, "--env-system-config");
253 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
254 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
255 BLI_argsPrintArgDoc(ba, "--env-system-plugins");
256 BLI_argsPrintArgDoc(ba, "--env-system-python");
258 BLI_argsPrintArgDoc(ba, "-nojoystick");
259 BLI_argsPrintArgDoc(ba, "-noglsl");
260 BLI_argsPrintArgDoc(ba, "-noaudio");
261 BLI_argsPrintArgDoc(ba, "-setaudio");
265 BLI_argsPrintArgDoc(ba, "--help");
269 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
270 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
274 BLI_argsPrintArgDoc(ba, "--python");
275 BLI_argsPrintArgDoc(ba, "--python-console");
276 BLI_argsPrintArgDoc(ba, "--addons");
279 BLI_argsPrintArgDoc(ba, "-R");
281 BLI_argsPrintArgDoc(ba, "--version");
283 BLI_argsPrintArgDoc(ba, "--");
285 printf ("Other Options:\n");
286 BLI_argsPrintOtherDoc(ba);
288 printf ("Argument Parsing:\n");
289 printf ("\targuments must be separated by white space. eg\n");
290 printf ("\t\t\"blender -ba test.blend\"\n");
291 printf ("\t...will ignore the 'a'\n");
292 printf ("\t\t\"blender -b test.blend -f8\"\n");
293 printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
295 printf ("Argument Order:\n");
296 printf ("Arguments are executed in the order they are given. eg\n");
297 printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
298 printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
299 printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
300 printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
301 printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
303 printf ("\nEnvironment Variables:\n");
304 printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
305 printf (" $BLENDER_SYSTEM_CONFIG Directory for system wide configuration files.\n");
306 printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
307 printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
308 printf (" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
309 printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
310 printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
312 printf (" $TEMP Store temporary files here.\n");
314 printf (" $TMP or $TMPDIR Store temporary files here.\n");
317 printf (" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
319 printf (" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
327 double PIL_check_seconds_timer(void);
329 /* XXX This was here to fix a crash when running python scripts
330 * with -P that used the screen.
332 * static void main_init_screen( void )
334 setscreen(G.curscreen);
336 if(G.main->scene.first==0) {
337 set_scene( add_scene("1") );
341 static int end_arguments(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
346 static int enable_python(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
348 G.f |= G_SCRIPT_AUTOEXEC;
352 static int disable_python(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
354 G.f &= ~G_SCRIPT_AUTOEXEC;
358 static int background_mode(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
364 static int debug_mode(int UNUSED(argc), char **UNUSED(argv), void *data)
366 G.f |= G_DEBUG; /* std output printf's */
367 printf(BLEND_VERSION_STRING_FMT);
368 MEM_set_memory_debug();
371 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
372 #endif // NAN_BUILDINFO
378 static int set_fpe(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
380 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || OSX_SSE_FPE
381 /* zealous but makes float issues a heck of a lot easier to find!
382 * set breakpoints on fpe_handler */
383 signal(SIGFPE, fpe_handler);
385 # if defined(__linux__) && defined(__GNUC__)
386 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
387 # endif /* defined(__linux__) && defined(__GNUC__) */
389 /* OSX uses SSE for floating point by default, so here
390 * use SSE instructions to throw floating point exceptions */
391 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
392 (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
393 # endif /* OSX_SSE_FPE */
394 # if defined(_WIN32) && defined(_MSC_VER)
395 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
396 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
397 # endif /* _WIN32 && _MSC_VER */
403 static int set_factory_startup(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
405 G.factory_startup= 1;
409 static int set_env(int argc, char **argv, void *UNUSED(data))
411 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
413 char env[64]= "BLENDER";
414 char *ch_dst= env + 7; /* skip BLENDER */
415 char *ch_src= argv[0] + 5; /* skip --env */
418 printf("%s requires one argument\n", argv[0]);
422 for(; *ch_src; ch_src++, ch_dst++) {
423 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
427 BLI_setenv(env, argv[1]);
431 static int playback_mode(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
433 /* not if -b was given first */
434 if (G.background == 0) {
436 // XXX playanim(argc, argv); /* not the same argc and argv as before */
443 static int prefsize(int argc, char **argv, void *UNUSED(data))
445 int stax, stay, sizx, sizy;
448 printf ("-p requires four arguments\n");
457 WM_setprefsize(stax, stay, sizx, sizy);
462 static int with_borders(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
464 WM_setinitialstate_normal();
468 static int without_borders(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
470 WM_setinitialstate_fullscreen();
474 static int register_extension(int UNUSED(argc), char **UNUSED(argv), void *data)
477 char *path = BLI_argsArgv(data)[0];
478 RegisterBlendExtension(path);
480 (void)data; /* unused */
486 static int no_joystick(int UNUSED(argc), char **UNUSED(argv), void *data)
488 #ifndef WITH_GAMEENGINE
491 SYS_SystemHandle *syshandle = data;
494 don't initialize joysticks if user doesn't want to use joysticks
495 failed joystick initialization delays over 5 seconds, before game engine start
497 SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
498 if (G.f & G_DEBUG) printf("disabling nojoystick\n");
504 static int no_glsl(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
506 GPU_extensions_disable();
510 static int no_audio(int UNUSED(argc), char **UNUSED(argv), void *UNUSED(data))
512 sound_force_device(0);
516 static int set_audio(int argc, char **argv, void *UNUSED(data))
519 printf("-setaudio require one argument\n");
523 sound_force_device(sound_define_from_str(argv[1]));
527 static int set_output(int argc, char **argv, void *data)
531 if (CTX_data_scene(C)) {
532 Scene *scene= CTX_data_scene(C);
533 BLI_strncpy(scene->r.pic, argv[1], FILE_MAXDIR);
535 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
539 printf("\nError: you must specify a path after '-o / --render-output'.\n");
544 static int set_engine(int argc, char **argv, void *data)
549 if (!strcmp(argv[1],"help"))
551 RenderEngineType *type = NULL;
553 for( type = R_engines.first; type; type = type->next )
555 printf("\t%s\n", type->idname);
561 if (CTX_data_scene(C)==NULL)
563 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
567 Scene *scene= CTX_data_scene(C);
568 RenderData *rd = &scene->r;
569 RenderEngineType *type = NULL;
571 for( type = R_engines.first; type; type = type->next )
573 if (!strcmp(argv[1],type->idname))
575 BLI_strncpy(rd->engine, type->idname, sizeof(rd->engine));
585 printf("\nEngine not specified.\n");
590 static int set_image_type(int argc, char **argv, void *data)
594 char *imtype = argv[1];
595 if (CTX_data_scene(C)==NULL) {
596 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
598 Scene *scene= CTX_data_scene(C);
599 if (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
600 else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
602 else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
604 else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
605 else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
606 else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
607 else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
608 else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
609 else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
610 else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
611 else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
612 else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
614 else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
617 else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
620 else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
621 else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
623 else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
624 else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
626 else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
627 else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
630 else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
632 else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
636 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
641 static int set_threads(int argc, char **argv, void *UNUSED(data))
645 RE_set_max_threads(atoi(argv[1]));
647 printf("Warning: threads can only be set in background mode\n");
651 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
656 static int set_extension(int argc, char **argv, void *data)
660 if (CTX_data_scene(C)) {
661 Scene *scene= CTX_data_scene(C);
662 if (argv[1][0] == '0') {
663 scene->r.scemode &= ~R_EXTENSION;
664 } else if (argv[1][0] == '1') {
665 scene->r.scemode |= R_EXTENSION;
667 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
670 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
674 printf("\nError: you must specify a path after '- '.\n");
679 static int set_ge_parameters(int argc, char **argv, void *data)
682 #ifdef WITH_GAMEENGINE
683 SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
689 gameengine parameters are automaticly put into system
690 -g [paramname = value]
694 -g maxvertexarraysize = 512
699 char* paramname = argv[a];
700 /* check for single value versus assignment */
701 if (a+1 < argc && (*(argv[a+1]) == '='))
708 #ifdef WITH_GAMEENGINE
709 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
713 printf("error: argument assignment (%s) without value.\n",paramname);
719 #ifdef WITH_GAMEENGINE
720 SYS_WriteCommandLineInt(syshandle,argv[a],1);
723 if (!strcmp(argv[a],"nomipmap"))
725 GPU_set_mipmap(0); //doMipMap = 0;
728 if (!strcmp(argv[a],"linearmipmap"))
730 GPU_set_linear_mipmap(1); //linearMipMap = 1;
734 } /* if (*(argv[a+1]) == '=') */
740 static int render_frame(int argc, char **argv, void *data)
743 if (CTX_data_scene(C)) {
744 Main *bmain= CTX_data_main(C);
745 Scene *scene= CTX_data_scene(C);
748 Render *re = RE_NewRender(scene->id.name);
754 frame= scene->r.sfra + atoi(argv[1]+1);
757 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
760 frame= atoi(argv[1]);
764 BKE_reports_init(&reports, RPT_PRINT);
766 frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
768 RE_BlenderAnim(re, bmain, scene, scene->lay, frame, frame, scene->r.frame_step, &reports);
771 printf("\nError: frame number must follow '-f / --render-frame'.\n");
775 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
780 static int render_animation(int UNUSED(argc), char **UNUSED(argv), void *data)
783 if (CTX_data_scene(C)) {
784 Main *bmain= CTX_data_main(C);
785 Scene *scene= CTX_data_scene(C);
786 Render *re= RE_NewRender(scene->id.name);
788 BKE_reports_init(&reports, RPT_PRINT);
789 RE_BlenderAnim(re, bmain, scene, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
791 printf("\nError: no blend loaded. cannot use '-a'.\n");
796 static int set_scene(int argc, char **argv, void *data)
800 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
802 CTX_data_scene_set(C, sce);
806 printf("\nError: Scene name must follow '-S / --scene'.\n");
811 static int set_start_frame(int argc, char **argv, void *data)
814 if (CTX_data_scene(C)) {
815 Scene *scene= CTX_data_scene(C);
817 int frame = atoi(argv[1]);
818 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
821 printf("\nError: frame number must follow '-s / --frame-start'.\n");
825 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
830 static int set_end_frame(int argc, char **argv, void *data)
833 if (CTX_data_scene(C)) {
834 Scene *scene= CTX_data_scene(C);
836 int frame = atoi(argv[1]);
837 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
840 printf("\nError: frame number must follow '-e / --frame-end'.\n");
844 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
849 static int set_skip_frame(int argc, char **argv, void *data)
852 if (CTX_data_scene(C)) {
853 Scene *scene= CTX_data_scene(C);
855 int frame = atoi(argv[1]);
856 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
859 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
863 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
868 /* macro for ugly context setup/reset */
870 #define BPY_CTX_SETUP(_cmd) \
872 wmWindowManager *wm= CTX_wm_manager(C); \
873 wmWindow *prevwin= CTX_wm_window(C); \
874 Scene *prevscene= CTX_data_scene(C); \
875 if(wm->windows.first) { \
876 CTX_wm_window_set(C, wm->windows.first); \
878 CTX_wm_window_set(C, prevwin); \
881 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
884 CTX_data_scene_set(C, prevscene); \
887 #endif /* WITH_PYTHON */
889 static int run_python(int argc, char **argv, void *data)
894 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
896 /* Make the path absolute because its needed for relative linked blends to be found */
897 char filename[FILE_MAXDIR + FILE_MAXFILE];
898 BLI_strncpy(filename, argv[1], sizeof(filename));
899 BLI_path_cwd(filename);
901 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
905 printf("\nError: you must specify a Python script after '-P / --python'.\n");
909 (void)argc; (void)argv; (void)data; /* unused */
910 printf("This blender was built without python support\n");
912 #endif /* WITH_PYTHON */
915 static int run_python_console(int UNUSED(argc), char **argv, void *data)
920 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
924 (void)argv; (void)data; /* unused */
925 printf("This blender was built without python support\n");
927 #endif /* WITH_PYTHON */
930 static int set_addons(int argc, char **argv, void *data)
932 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
935 char *str= malloc(strlen(argv[1]) + 100);
937 sprintf(str, "[__import__('bpy').utils.addon_enable(i) for i in '%s'.split(',')]", argv[1]);
938 BPY_CTX_SETUP(BPY_string_exec(C, str));
941 (void)argv; (void)data; /* unused */
942 #endif /* WITH_PYTHON */
946 printf("\nError: you must specify a comma separated list after '--addons'.\n");
952 static int load_file(int UNUSED(argc), char **argv, void *data)
956 /* Make the path absolute because its needed for relative linked blends to be found */
957 char filename[FILE_MAXDIR + FILE_MAXFILE];
958 BLI_strncpy(filename, argv[0], sizeof(filename));
959 BLI_path_cwd(filename);
962 int retval = BKE_read_file(C, filename, NULL);
964 /*we successfully loaded a blend file, get sure that
966 if (retval != BKE_READ_FILE_FAIL) {
967 wmWindowManager *wm= CTX_wm_manager(C);
969 /* special case, 2.4x files */
970 if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
971 extern void wm_add_default(bContext *C);
973 /* wm_add_default() needs the screen to be set. */
974 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
978 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
981 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
983 DAG_on_load_update(CTX_data_main(C), TRUE);
986 /* WM_read_file() runs normally but since we're in background mode do here */
988 /* run any texts that were loaded in and flagged as modules */
990 BPY_modules_load_user(C);
993 /* happens for the UI on file reading too (huh? (ton))*/
994 // XXX BKE_reset_undo();
995 // BKE_write_undo("original"); /* save current state */
997 /* we are not running in background mode here, but start blender in UI mode with
998 a file - this should do everything a 'load file' does */
1000 BKE_reports_init(&reports, RPT_PRINT);
1001 WM_read_file(C, filename, &reports);
1002 BKE_reports_clear(&reports);
1010 void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1012 static char output_doc[] = "<path>"
1013 "\n\tSet the render path and file name."
1014 "\n\tUse // at the start of the path to"
1015 "\n\t\trender relative to the blend file."
1016 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1017 "\n\t\tani_##_test.png becomes ani_01_test.png"
1018 "\n\t\ttest-######.png becomes test-000001.png"
1019 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1020 "\n\tThe frame number will be added at the end of the filename."
1021 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1022 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1024 static char format_doc[] = "<format>"
1025 "\n\tSet the render format, Valid options are..."
1026 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1027 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1028 "\n\t(formats that can be compiled into blender, not available on all systems)"
1029 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1031 static char playback_doc[] = "<options> <file(s)>"
1032 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1033 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1034 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1035 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1036 "\n\t\t-j <frame>\tSet frame step to <frame>";
1038 static char game_doc[] = "Game Engine specific options"
1039 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1040 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1041 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1042 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1044 static char debug_doc[] = "\n\tTurn debugging on\n"
1045 "\n\t* Prints every operator call and their arguments"
1046 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1047 "\n\t* Keeps python sys.stdin rather then setting it to None";
1049 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1051 /* end argument processing after -- */
1052 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1054 /* first pass: background mode, disable python and commands that exit after usage */
1055 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1057 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1059 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1061 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution (default)", enable_python, NULL);
1062 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)", disable_python, NULL);
1064 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1066 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1068 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1069 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1071 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1073 /* TODO, add user env vars? */
1074 BLI_argsAdd(ba, 1, NULL, "--env-system-config", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_CONFIG)" environment variable", set_env, NULL);
1075 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1076 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1077 BLI_argsAdd(ba, 1, NULL, "--env-system-plugins", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1078 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1080 /* second pass: custom window stuff */
1081 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);
1082 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1083 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1084 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension (windows only)", register_extension, ba);
1086 /* third pass: disabling things and forcing settings */
1087 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1088 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1089 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1090 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1092 /* fourth pass: processing arguments */
1093 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1094 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);
1095 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1096 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1097 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1098 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1099 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1100 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1101 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1102 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1104 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1105 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1107 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1108 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);
1109 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);
1113 int main(int argc, char **argv)
1115 SYS_SystemHandle syshandle;
1116 bContext *C= CTX_create();
1119 #ifdef WITH_BINRELOC
1125 /* patch to ignore argument finder gives us (pid?) */
1126 if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1127 extern int GHOST_HACK_getFirstFile(char buf[]);
1128 static char firstfilebuf[512];
1132 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1134 argv[1]= firstfilebuf;
1144 // copy path to executable in bprogname. playanim and creting runtimes
1147 BLI_where_am_i(bprogname, argv[0]);
1150 strip_quotes(build_date);
1151 strip_quotes(build_time);
1152 strip_quotes(build_rev);
1153 strip_quotes(build_platform);
1154 strip_quotes(build_type);
1155 strip_quotes(build_cflags);
1156 strip_quotes(build_cxxflags);
1157 strip_quotes(build_linkflags);
1158 strip_quotes(build_system);
1161 BLI_threadapi_init();
1166 /* Hack - force inclusion of the plugin api functions,
1167 * see blenpluginapi:pluginapi.c
1169 pluginapi_force_ref();
1173 initglobals(); /* blender.c */
1177 #ifdef WITH_GAMEENGINE
1178 syshandle = SYS_GetSystem();
1179 GEN_init_messaging_system();
1184 /* first test for background */
1185 ba = BLI_argsInit(argc, argv); /* skip binary path */
1186 setupArguments(C, ba, &syshandle);
1188 BLI_argsParse(ba, 1, NULL, NULL);
1191 setuid(getuid()); /* end superuser */
1195 /* for all platforms, even windos has it! */
1196 if(G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1198 /* background render uses this font too */
1199 BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1201 /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1202 rendered via ffmpeg */
1205 init_def_material();
1207 if(G.background==0) {
1208 BLI_argsParse(ba, 2, NULL, NULL);
1209 BLI_argsParse(ba, 3, NULL, NULL);
1211 WM_init(C, argc, argv);
1213 /* this is properly initialized with user defs, but this is default */
1214 BLI_where_is_temp( btempdir, 1 ); /* call after loading the startup.blend so we can read U.tempdir */
1217 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1221 BLI_argsParse(ba, 3, NULL, NULL);
1223 WM_init(C, argc, argv);
1225 BLI_where_is_temp( btempdir, 0 ); /* call after loading the startup.blend so we can read U.tempdir */
1229 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1230 * so we provide the BPY_ function below to append the user defined
1231 * pythondir to Python's sys.path at this point. Simply putting
1232 * WM_init() before BPY_python_start() crashes Blender at startup.
1233 * Update: now this function also inits the bpymenus, which also depend
1237 // TODO - U.pythondir
1239 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1242 CTX_py_init_set(C, 1);
1245 /* OK we are ready for it */
1246 BLI_argsParse(ba, 4, load_file, C);
1251 /* actually incorrect, but works for now (ton) */
1256 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1261 else if(!G.file_loaded)
1268 /*XXX if (scr_init==0) {
1272 screenmain();*/ /* main display loop */
1275 } /* end of int main(argc,argv) */
1277 static void error_cb(char *err)
1280 printf("%s\n", err); /* XXX do this in WM too */
1283 static void mem_error_cb(const char *errorStr)
1285 fputs(errorStr, stderr);
1289 static void setCallbacks(void)
1291 /* Error output from the alloc routines: */
1292 MEM_set_error_callback(mem_error_cb);
1297 BLI_setErrorCallBack(error_cb); /* */
1298 // XXX BLI_setInterruptCallBack(blender_test_break);