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 /** \file creator/creator.c
35 #if defined(__linux__) && defined(__GNUC__)
40 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
42 #include <xmmintrin.h>
49 /* This little block needed for linking to Blender... */
51 #include "MEM_guardedalloc.h"
54 #include "BLI_winstuff.h"
58 #include "BLI_threads.h"
59 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
60 #include "BLI_utildefines.h"
61 #include "BLI_callbacks.h"
64 #include "DNA_scene_types.h"
65 #include "DNA_userdef_types.h"
67 #include "BLI_blenlib.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_blender.h"
71 #include "BKE_context.h"
72 #include "BKE_depsgraph.h" // for DAG_on_visible_update
74 #include "BKE_global.h"
76 #include "BKE_material.h"
77 #include "BKE_packedFile.h"
78 #include "BKE_scene.h"
80 #include "BKE_report.h"
81 #include "BKE_sound.h"
83 #include "IMB_imbuf.h" // for IMB_init
86 #include "BPY_extern.h"
89 #include "RE_engine.h"
90 #include "RE_pipeline.h"
92 //XXX #include "playanim_ext.h"
93 #include "ED_datafiles.h"
97 #include "RNA_define.h"
100 #include "GPU_extensions.h"
102 #ifdef WITH_BUILDINFO_HEADER
106 /* for passing information between creator and gameengine */
107 #ifdef WITH_GAMEENGINE
108 #include "BL_System.h"
110 #define SYS_SystemHandle int
116 # include <sys/types.h>
117 # include <floatingpoint.h>
118 # include <sys/rtprio.h>
122 #include "binreloc.h"
127 extern char build_date[];
128 extern char build_time[];
129 extern char build_rev[];
130 extern char build_platform[];
131 extern char build_type[];
132 extern char build_cflags[];
133 extern char build_cxxflags[];
134 extern char build_linkflags[];
135 extern char build_system[];
138 /* Local Function prototypes */
139 static int print_help(int argc, const char **argv, void *data);
140 static int print_version(int argc, const char **argv, void *data);
142 /* for the callbacks: */
144 extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */
146 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
148 /* Initialize callbacks for the modules that need them */
149 static void setCallbacks(void);
151 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
152 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
153 static void fpe_handler(int UNUSED(sig))
155 // printf("SIGFPE trapped\n");
159 #ifndef WITH_PYTHON_MODULE
160 /* handling ctrl-c event in console */
161 static void blender_esc(int sig)
163 static int count = 0;
165 G.afbreek = 1; /* forces render loop to read queue, not sure if its needed */
169 printf("\nBlender killed\n");
172 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
178 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
180 printf (BLEND_VERSION_STRING_FMT);
182 printf ("\tbuild date: %s\n", build_date);
183 printf ("\tbuild time: %s\n", build_time);
184 printf ("\tbuild revision: %s\n", build_rev);
185 printf ("\tbuild platform: %s\n", build_platform);
186 printf ("\tbuild type: %s\n", build_type);
187 printf ("\tbuild c flags: %s\n", build_cflags);
188 printf ("\tbuild c++ flags: %s\n", build_cxxflags);
189 printf ("\tbuild link flags: %s\n", build_linkflags);
190 printf ("\tbuild system: %s\n", build_system);
197 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
199 bArgs *ba = (bArgs*)data;
201 printf (BLEND_VERSION_STRING_FMT);
202 printf ("Usage: blender [args ...] [file] [args ...]\n\n");
204 printf ("Render Options:\n");
205 BLI_argsPrintArgDoc(ba, "--background");
206 BLI_argsPrintArgDoc(ba, "--render-anim");
207 BLI_argsPrintArgDoc(ba, "--scene");
208 BLI_argsPrintArgDoc(ba, "--render-frame");
209 BLI_argsPrintArgDoc(ba, "--frame-start");
210 BLI_argsPrintArgDoc(ba, "--frame-end");
211 BLI_argsPrintArgDoc(ba, "--frame-jump");
212 BLI_argsPrintArgDoc(ba, "--render-output");
213 BLI_argsPrintArgDoc(ba, "--engine");
216 printf ("Format Options:\n");
217 BLI_argsPrintArgDoc(ba, "--render-format");
218 BLI_argsPrintArgDoc(ba, "--use-extension");
219 BLI_argsPrintArgDoc(ba, "--threads");
222 printf ("Animation Playback Options:\n");
223 BLI_argsPrintArgDoc(ba, "-a");
226 printf ("Window Options:\n");
227 BLI_argsPrintArgDoc(ba, "--window-border");
228 BLI_argsPrintArgDoc(ba, "--window-borderless");
229 BLI_argsPrintArgDoc(ba, "--window-geometry");
230 BLI_argsPrintArgDoc(ba, "--start-console");
233 printf ("Game Engine Specific Options:\n");
234 BLI_argsPrintArgDoc(ba, "-g");
237 printf ("Misc Options:\n");
238 BLI_argsPrintArgDoc(ba, "--debug");
239 BLI_argsPrintArgDoc(ba, "--debug-fpe");
241 BLI_argsPrintArgDoc(ba, "--factory-startup");
243 BLI_argsPrintArgDoc(ba, "--env-system-config");
244 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
245 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
246 BLI_argsPrintArgDoc(ba, "--env-system-plugins");
247 BLI_argsPrintArgDoc(ba, "--env-system-python");
249 BLI_argsPrintArgDoc(ba, "-nojoystick");
250 BLI_argsPrintArgDoc(ba, "-noglsl");
251 BLI_argsPrintArgDoc(ba, "-noaudio");
252 BLI_argsPrintArgDoc(ba, "-setaudio");
256 BLI_argsPrintArgDoc(ba, "--help");
260 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
261 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
265 BLI_argsPrintArgDoc(ba, "--python");
266 BLI_argsPrintArgDoc(ba, "--python-console");
267 BLI_argsPrintArgDoc(ba, "--addons");
270 BLI_argsPrintArgDoc(ba, "-R");
271 BLI_argsPrintArgDoc(ba, "-r");
273 BLI_argsPrintArgDoc(ba, "--version");
275 BLI_argsPrintArgDoc(ba, "--");
277 printf ("Other Options:\n");
278 BLI_argsPrintOtherDoc(ba);
280 printf ("Argument Parsing:\n");
281 printf ("\targuments must be separated by white space. eg\n");
282 printf ("\t\t\"blender -ba test.blend\"\n");
283 printf ("\t...will ignore the 'a'\n");
284 printf ("\t\t\"blender -b test.blend -f8\"\n");
285 printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
287 printf ("Argument Order:\n");
288 printf ("Arguments are executed in the order they are given. eg\n");
289 printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
290 printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
291 printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
292 printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
293 printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
295 printf ("\nEnvironment Variables:\n");
296 printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
297 printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
298 printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
299 printf (" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
300 printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
301 printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
303 printf (" $TEMP Store temporary files here.\n");
305 printf (" $TMP or $TMPDIR Store temporary files here.\n");
308 printf (" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
310 printf (" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
318 double PIL_check_seconds_timer(void);
320 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
325 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
327 G.f |= G_SCRIPT_AUTOEXEC;
328 G.f |= G_SCRIPT_OVERRIDE_PREF;
332 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
334 G.f &= ~G_SCRIPT_AUTOEXEC;
335 G.f |= G_SCRIPT_OVERRIDE_PREF;
339 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
345 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
347 G.f |= G_DEBUG; /* std output printf's */
348 printf(BLEND_VERSION_STRING_FMT);
349 MEM_set_memory_debug();
351 #ifdef WITH_BUILDINFO
352 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
353 #endif // WITH_BUILDINFO
359 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
361 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
362 /* zealous but makes float issues a heck of a lot easier to find!
363 * set breakpoints on fpe_handler */
364 signal(SIGFPE, fpe_handler);
366 # if defined(__linux__) && defined(__GNUC__)
367 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
368 # endif /* defined(__linux__) && defined(__GNUC__) */
369 # if defined(OSX_SSE_FPE)
370 /* OSX uses SSE for floating point by default, so here
371 * use SSE instructions to throw floating point exceptions */
372 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
373 (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
374 # endif /* OSX_SSE_FPE */
375 # if defined(_WIN32) && defined(_MSC_VER)
376 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
377 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
378 # endif /* _WIN32 && _MSC_VER */
384 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
386 G.factory_startup= 1;
390 static int set_env(int argc, const char **argv, void *UNUSED(data))
392 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
394 char env[64]= "BLENDER";
395 char *ch_dst= env + 7; /* skip BLENDER */
396 const char *ch_src= argv[0] + 5; /* skip --env */
399 printf("%s requires one argument\n", argv[0]);
403 for(; *ch_src; ch_src++, ch_dst++) {
404 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
408 BLI_setenv(env, argv[1]);
412 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
414 /* not if -b was given first */
415 if (G.background == 0) {
416 #if 0 /* TODO, bring player back? */
417 playanim(argc, argv); /* not the same argc and argv as before */
419 fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
427 static int prefsize(int argc, const char **argv, void *UNUSED(data))
429 int stax, stay, sizx, sizy;
432 printf ("-p requires four arguments\n");
441 WM_setprefsize(stax, stay, sizx, sizy);
446 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
448 WM_setinitialstate_normal();
452 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
454 WM_setinitialstate_fullscreen();
458 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
459 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
461 wm_start_with_console = 1;
465 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
470 RegisterBlendExtension();
472 (void)data; /* unused */
477 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
479 #ifndef WITH_GAMEENGINE
482 SYS_SystemHandle *syshandle = data;
485 don't initialize joysticks if user doesn't want to use joysticks
486 failed joystick initialization delays over 5 seconds, before game engine start
488 SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
489 if (G.f & G_DEBUG) printf("disabling nojoystick\n");
495 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
497 GPU_extensions_disable();
501 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
503 sound_force_device(0);
507 static int set_audio(int argc, const char **argv, void *UNUSED(data))
510 printf("-setaudio require one argument\n");
514 sound_force_device(sound_define_from_str(argv[1]));
518 static int set_output(int argc, const char **argv, void *data)
522 Scene *scene= CTX_data_scene(C);
524 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
526 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
530 printf("\nError: you must specify a path after '-o / --render-output'.\n");
535 static int set_engine(int argc, const char **argv, void *data)
539 if (!strcmp(argv[1], "help")) {
540 RenderEngineType *type = NULL;
541 printf("Blender Engine Listing:\n");
542 for( type = R_engines.first; type; type = type->next ) {
543 printf("\t%s\n", type->idname);
548 Scene *scene= CTX_data_scene(C);
550 RenderData *rd = &scene->r;
552 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
553 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
557 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
565 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
570 static int set_image_type(int argc, const char **argv, void *data)
574 const char *imtype = argv[1];
575 Scene *scene= CTX_data_scene(C);
577 if (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
578 else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
580 else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
582 else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
583 else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
584 else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
585 else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
586 else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
587 else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
588 else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
589 else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
590 else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
592 else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
595 else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
598 else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
599 else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
601 else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
602 else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
604 else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
605 else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
608 else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
610 else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
613 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
617 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
622 static int set_threads(int argc, const char **argv, void *UNUSED(data))
626 RE_set_max_threads(atoi(argv[1]));
628 printf("Warning: threads can only be set in background mode\n");
632 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
637 static int set_extension(int argc, const char **argv, void *data)
641 Scene *scene= CTX_data_scene(C);
643 if (argv[1][0] == '0') {
644 scene->r.scemode &= ~R_EXTENSION;
645 } else if (argv[1][0] == '1') {
646 scene->r.scemode |= R_EXTENSION;
648 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
651 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
655 printf("\nError: you must specify a path after '- '.\n");
660 static int set_ge_parameters(int argc, const char **argv, void *data)
663 #ifdef WITH_GAMEENGINE
664 SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
670 gameengine parameters are automaticly put into system
671 -g [paramname = value]
675 -g maxvertexarraysize = 512
680 const char *paramname = argv[a];
681 /* check for single value versus assignment */
682 if (a+1 < argc && (*(argv[a+1]) == '='))
689 #ifdef WITH_GAMEENGINE
690 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
694 printf("error: argument assignment (%s) without value.\n",paramname);
700 #ifdef WITH_GAMEENGINE
701 SYS_WriteCommandLineInt(syshandle,argv[a],1);
704 if (!strcmp(argv[a],"nomipmap"))
706 GPU_set_mipmap(0); //doMipMap = 0;
709 if (!strcmp(argv[a],"linearmipmap"))
711 GPU_set_linear_mipmap(1); //linearMipMap = 1;
715 } /* if (*(argv[a+1]) == '=') */
721 static int render_frame(int argc, const char **argv, void *data)
724 Scene *scene= CTX_data_scene(C);
726 Main *bmain= CTX_data_main(C);
729 Render *re = RE_NewRender(scene->id.name);
735 frame= scene->r.sfra + atoi(argv[1]+1);
738 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
741 frame= atoi(argv[1]);
745 BKE_reports_init(&reports, RPT_PRINT);
747 frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
749 RE_SetReports(re, &reports);
750 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
751 RE_SetReports(re, NULL);
754 printf("\nError: frame number must follow '-f / --render-frame'.\n");
758 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
763 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
766 Scene *scene= CTX_data_scene(C);
768 Main *bmain= CTX_data_main(C);
769 Render *re= RE_NewRender(scene->id.name);
771 BKE_reports_init(&reports, RPT_PRINT);
772 RE_SetReports(re, &reports);
773 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
774 RE_SetReports(re, NULL);
776 printf("\nError: no blend loaded. cannot use '-a'.\n");
781 static int set_scene(int argc, const char **argv, void *data)
785 Scene *scene= set_scene_name(CTX_data_main(C), argv[1]);
787 CTX_data_scene_set(C, scene);
791 printf("\nError: Scene name must follow '-S / --scene'.\n");
796 static int set_start_frame(int argc, const char **argv, void *data)
799 Scene *scene= CTX_data_scene(C);
802 int frame = atoi(argv[1]);
803 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
806 printf("\nError: frame number must follow '-s / --frame-start'.\n");
810 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
815 static int set_end_frame(int argc, const char **argv, void *data)
818 Scene *scene= CTX_data_scene(C);
821 int frame = atoi(argv[1]);
822 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
825 printf("\nError: frame number must follow '-e / --frame-end'.\n");
829 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
834 static int set_skip_frame(int argc, const char **argv, void *data)
837 Scene *scene= CTX_data_scene(C);
840 int frame = atoi(argv[1]);
841 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
844 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
848 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
853 /* macro for ugly context setup/reset */
855 #define BPY_CTX_SETUP(_cmd) \
857 wmWindowManager *wm= CTX_wm_manager(C); \
858 wmWindow *prevwin= CTX_wm_window(C); \
859 Scene *prevscene= CTX_data_scene(C); \
860 if(wm->windows.first) { \
861 CTX_wm_window_set(C, wm->windows.first); \
863 CTX_wm_window_set(C, prevwin); \
866 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
869 CTX_data_scene_set(C, prevscene); \
872 #endif /* WITH_PYTHON */
874 static int run_python(int argc, const char **argv, void *data)
879 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
881 /* Make the path absolute because its needed for relative linked blends to be found */
882 char filename[FILE_MAXDIR + FILE_MAXFILE];
883 BLI_strncpy(filename, argv[1], sizeof(filename));
884 BLI_path_cwd(filename);
886 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
890 printf("\nError: you must specify a Python script after '-P / --python'.\n");
894 (void)argc; (void)argv; (void)data; /* unused */
895 printf("This blender was built without python support\n");
897 #endif /* WITH_PYTHON */
900 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
905 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
909 (void)argv; (void)data; /* unused */
910 printf("This blender was built without python support\n");
912 #endif /* WITH_PYTHON */
915 static int set_addons(int argc, const char **argv, void *data)
917 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
920 const int slen= strlen(argv[1]) + 128;
921 char *str= malloc(slen);
923 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
924 BPY_CTX_SETUP(BPY_string_exec(C, str));
927 (void)argv; (void)data; /* unused */
928 #endif /* WITH_PYTHON */
932 printf("\nError: you must specify a comma separated list after '--addons'.\n");
938 static int load_file(int UNUSED(argc), const char **argv, void *data)
942 /* Make the path absolute because its needed for relative linked blends to be found */
943 char filename[FILE_MAXDIR + FILE_MAXFILE];
944 BLI_strncpy(filename, argv[0], sizeof(filename));
945 BLI_path_cwd(filename);
948 int retval = BKE_read_file(C, filename, NULL);
950 /*we successfully loaded a blend file, get sure that
952 if (retval != BKE_READ_FILE_FAIL) {
953 wmWindowManager *wm= CTX_wm_manager(C);
955 /* special case, 2.4x files */
956 if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
957 extern void wm_add_default(bContext *C);
959 /* wm_add_default() needs the screen to be set. */
960 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
964 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
967 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
969 DAG_on_visible_update(CTX_data_main(C), TRUE);
972 /* WM_read_file() runs normally but since we're in background mode do here */
974 /* run any texts that were loaded in and flagged as modules */
976 BPY_app_handlers_reset();
977 BPY_modules_load_user(C);
980 /* happens for the UI on file reading too (huh? (ton))*/
981 // XXX BKE_reset_undo();
982 // BKE_write_undo("original"); /* save current state */
984 /* we are not running in background mode here, but start blender in UI mode with
985 a file - this should do everything a 'load file' does */
987 BKE_reports_init(&reports, RPT_PRINT);
988 WM_read_file(C, filename, &reports);
989 BKE_reports_clear(&reports);
997 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
999 static char output_doc[] = "<path>"
1000 "\n\tSet the render path and file name."
1001 "\n\tUse // at the start of the path to"
1002 "\n\t\trender relative to the blend file."
1003 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1004 "\n\t\tani_##_test.png becomes ani_01_test.png"
1005 "\n\t\ttest-######.png becomes test-000001.png"
1006 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1007 "\n\tThe frame number will be added at the end of the filename."
1008 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1009 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1011 static char format_doc[] = "<format>"
1012 "\n\tSet the render format, Valid options are..."
1013 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1014 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1015 "\n\t(formats that can be compiled into blender, not available on all systems)"
1016 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1018 static char playback_doc[] = "<options> <file(s)>"
1019 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1020 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1021 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1022 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1023 "\n\t\t-j <frame>\tSet frame step to <frame>";
1025 static char game_doc[] = "Game Engine specific options"
1026 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1027 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1028 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1029 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1031 static char debug_doc[] = "\n\tTurn debugging on\n"
1032 "\n\t* Prints every operator call and their arguments"
1033 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1034 "\n\t* Keeps python sys.stdin rather than setting it to None";
1036 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1038 /* end argument processing after -- */
1039 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1041 /* first pass: background mode, disable python and commands that exit after usage */
1042 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1044 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1046 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1048 /* only to give help message */
1049 #ifndef WITH_PYTHON_SECURITY /* default */
1050 # define PY_ENABLE_AUTO ", (default)"
1051 # define PY_DISABLE_AUTO ""
1053 # define PY_ENABLE_AUTO ""
1054 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1057 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1058 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1060 #undef PY_ENABLE_AUTO
1061 #undef PY_DISABLE_AUTO
1063 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1065 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1067 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1068 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1070 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1072 /* TODO, add user env vars? */
1073 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1074 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1075 BLI_argsAdd(ba, 1, NULL, "--env-system-plugins", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1076 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1078 /* second pass: custom window stuff */
1079 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);
1080 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1081 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1082 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1083 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1084 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (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 #ifdef WITH_PYTHON_MODULE
1114 /* allow python module to call main */
1115 #define main main_python_enter
1116 static void *evil_C= NULL;
1119 int main(int argc, const char **argv)
1121 SYS_SystemHandle syshandle;
1122 bContext *C= CTX_create();
1125 #ifdef WITH_PYTHON_MODULE
1130 #ifdef WITH_BINRELOC
1136 /* patch to ignore argument finder gives us (pid?) */
1137 if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1138 extern int GHOST_HACK_getFirstFile(char buf[]);
1139 static char firstfilebuf[512];
1143 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1145 argv[1]= firstfilebuf;
1155 // initialize path to executable
1156 BLI_init_program_path(argv[0]);
1158 BLI_threadapi_init();
1163 /* Hack - force inclusion of the plugin api functions,
1164 * see blenpluginapi:pluginapi.c
1166 pluginapi_force_ref();
1170 initglobals(); /* blender.c */
1176 #ifdef WITH_GAMEENGINE
1177 syshandle = SYS_GetSystem();
1182 /* first test for background */
1183 ba = BLI_argsInit(argc, argv); /* skip binary path */
1184 setupArguments(C, ba, &syshandle);
1186 BLI_argsParse(ba, 1, NULL, NULL);
1188 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1189 G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1191 /* for all platforms, even windos has it! */
1192 if(G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1195 /* background render uses this font too */
1196 BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1198 /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1199 rendered via ffmpeg */
1202 init_def_material();
1204 if(G.background==0) {
1205 BLI_argsParse(ba, 2, NULL, NULL);
1206 BLI_argsParse(ba, 3, NULL, NULL);
1208 WM_init(C, argc, argv);
1210 /* this is properly initialized with user defs, but this is default */
1211 /* call after loading the startup.blend so we can read U.tempdir */
1212 BLI_init_temporary_dir(U.tempdir);
1215 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1219 BLI_argsParse(ba, 3, NULL, NULL);
1221 WM_init(C, argc, argv);
1223 /* don't use user preferences temp dir */
1224 BLI_init_temporary_dir(NULL);
1228 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1229 * so we provide the BPY_ function below to append the user defined
1230 * pythondir to Python's sys.path at this point. Simply putting
1231 * WM_init() before BPY_python_start() crashes Blender at startup.
1232 * Update: now this function also inits the bpymenus, which also depend
1236 // TODO - U.pythondir
1238 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1241 CTX_py_init_set(C, 1);
1244 /* OK we are ready for it */
1245 BLI_argsParse(ba, 4, load_file, C);
1249 #ifdef WITH_PYTHON_MODULE
1250 return 0; /* keep blender in background mode running */
1254 /* actually incorrect, but works for now (ton) */
1259 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1264 else if(!G.file_loaded)
1271 /*XXX if (scr_init==0) {
1275 screenmain();*/ /* main display loop */
1278 } /* end of int main(argc,argv) */
1280 #ifdef WITH_PYTHON_MODULE
1281 void main_python_exit(void)
1283 WM_exit((bContext *)evil_C);
1288 static void error_cb(const char *err)
1291 printf("%s\n", err); /* XXX do this in WM too */
1294 static void mem_error_cb(const char *errorStr)
1296 fputs(errorStr, stderr);
1300 static void setCallbacks(void)
1302 /* Error output from the alloc routines: */
1303 MEM_set_error_callback(mem_error_cb);
1308 BLI_setErrorCallBack(error_cb); /* */
1309 // XXX BLI_setInterruptCallBack(blender_test_break);