2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file creator/creator.c
33 #if defined(__linux__) && defined(__GNUC__)
38 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
40 # include <xmmintrin.h>
52 /* This little block needed for linking to Blender... */
54 #include "MEM_guardedalloc.h"
57 # include "BLI_winstuff.h"
61 #include "BLI_threads.h"
62 #include "BLI_utildefines.h"
63 #include "BLI_callbacks.h"
66 #include "DNA_scene_types.h"
67 #include "DNA_userdef_types.h"
69 #include "BLI_blenlib.h"
71 #include "BKE_utildefines.h"
72 #include "BKE_blender.h"
73 #include "BKE_context.h"
74 #include "BKE_depsgraph.h" /* for DAG_on_visible_update */
76 #include "BKE_global.h"
78 #include "BKE_material.h"
79 #include "BKE_packedFile.h"
80 #include "BKE_scene.h"
82 #include "BKE_report.h"
83 #include "BKE_sound.h"
84 #include "BKE_image.h"
86 #include "IMB_imbuf.h" /* for IMB_init */
89 #include "BPY_extern.h"
92 #include "RE_engine.h"
93 #include "RE_pipeline.h"
95 //XXX #include "playanim_ext.h"
96 #include "ED_datafiles.h"
100 #include "RNA_define.h"
102 #include "GPU_draw.h"
103 #include "GPU_extensions.h"
105 #include "BLI_scanfill.h" /* for BLI_setErrorCallBack, TODO, move elsewhere */
107 #ifdef WITH_BUILDINFO_HEADER
111 /* for passing information between creator and gameengine */
112 #ifdef WITH_GAMEENGINE
113 # include "BL_System.h"
115 # define SYS_SystemHandle int
121 # include <sys/types.h>
122 # include <floatingpoint.h>
123 # include <sys/rtprio.h>
127 # include "binreloc.h"
131 # include "libmv-capi.h"
134 /* from buildinfo.c */
136 extern char build_date[];
137 extern char build_time[];
138 extern char build_rev[];
139 extern char build_platform[];
140 extern char build_type[];
141 extern char build_cflags[];
142 extern char build_cxxflags[];
143 extern char build_linkflags[];
144 extern char build_system[];
147 /* Local Function prototypes */
148 #ifndef WITH_PYTHON_MODULE
149 static int print_help(int argc, const char **argv, void *data);
150 static int print_version(int argc, const char **argv, void *data);
153 /* for the callbacks: */
155 #define BLEND_VERSION_STRING_FMT \
156 "Blender %d.%02d (sub %d)\n", \
157 BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION \
159 /* Initialize callbacks for the modules that need them */
160 static void setCallbacks(void);
162 #ifndef WITH_PYTHON_MODULE
164 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
165 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
166 static void fpe_handler(int UNUSED(sig))
168 // printf("SIGFPE trapped\n");
172 /* handling ctrl-c event in console */
173 static void blender_esc(int sig)
175 static int count = 0;
177 G.afbreek = 1; /* forces render loop to read queue, not sure if its needed */
181 printf("\nBlender killed\n");
184 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
189 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
191 printf(BLEND_VERSION_STRING_FMT);
193 printf("\tbuild date: %s\n", build_date);
194 printf("\tbuild time: %s\n", build_time);
195 printf("\tbuild revision: %s\n", build_rev);
196 printf("\tbuild platform: %s\n", build_platform);
197 printf("\tbuild type: %s\n", build_type);
198 printf("\tbuild c flags: %s\n", build_cflags);
199 printf("\tbuild c++ flags: %s\n", build_cxxflags);
200 printf("\tbuild link flags: %s\n", build_linkflags);
201 printf("\tbuild system: %s\n", build_system);
208 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
210 bArgs *ba = (bArgs *)data;
212 printf(BLEND_VERSION_STRING_FMT);
213 printf("Usage: blender [args ...] [file] [args ...]\n\n");
215 printf("Render Options:\n");
216 BLI_argsPrintArgDoc(ba, "--background");
217 BLI_argsPrintArgDoc(ba, "--render-anim");
218 BLI_argsPrintArgDoc(ba, "--scene");
219 BLI_argsPrintArgDoc(ba, "--render-frame");
220 BLI_argsPrintArgDoc(ba, "--frame-start");
221 BLI_argsPrintArgDoc(ba, "--frame-end");
222 BLI_argsPrintArgDoc(ba, "--frame-jump");
223 BLI_argsPrintArgDoc(ba, "--render-output");
224 BLI_argsPrintArgDoc(ba, "--engine");
227 printf("Format Options:\n");
228 BLI_argsPrintArgDoc(ba, "--render-format");
229 BLI_argsPrintArgDoc(ba, "--use-extension");
230 BLI_argsPrintArgDoc(ba, "--threads");
233 printf("Animation Playback Options:\n");
234 BLI_argsPrintArgDoc(ba, "-a");
237 printf("Window Options:\n");
238 BLI_argsPrintArgDoc(ba, "--window-border");
239 BLI_argsPrintArgDoc(ba, "--window-borderless");
240 BLI_argsPrintArgDoc(ba, "--window-geometry");
241 BLI_argsPrintArgDoc(ba, "--start-console");
244 printf("Game Engine Specific Options:\n");
245 BLI_argsPrintArgDoc(ba, "-g");
248 printf("Misc Options:\n");
249 BLI_argsPrintArgDoc(ba, "--debug");
250 BLI_argsPrintArgDoc(ba, "--debug-fpe");
253 BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
257 BLI_argsPrintArgDoc(ba, "--debug-libmv");
261 BLI_argsPrintArgDoc(ba, "--factory-startup");
263 BLI_argsPrintArgDoc(ba, "--env-system-config");
264 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
265 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
266 BLI_argsPrintArgDoc(ba, "--env-system-python");
268 BLI_argsPrintArgDoc(ba, "-nojoystick");
269 BLI_argsPrintArgDoc(ba, "-noglsl");
270 BLI_argsPrintArgDoc(ba, "-noaudio");
271 BLI_argsPrintArgDoc(ba, "-setaudio");
275 BLI_argsPrintArgDoc(ba, "--help");
279 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
280 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
284 BLI_argsPrintArgDoc(ba, "--python");
285 BLI_argsPrintArgDoc(ba, "--python-console");
286 BLI_argsPrintArgDoc(ba, "--addons");
289 BLI_argsPrintArgDoc(ba, "-R");
290 BLI_argsPrintArgDoc(ba, "-r");
292 BLI_argsPrintArgDoc(ba, "--version");
294 BLI_argsPrintArgDoc(ba, "--");
296 printf("Other Options:\n");
297 BLI_argsPrintOtherDoc(ba);
299 printf("Argument Parsing:\n");
300 printf("\targuments must be separated by white space. eg\n");
301 printf("\t\t\"blender -ba test.blend\"\n");
302 printf("\t...will ignore the 'a'\n");
303 printf("\t\t\"blender -b test.blend -f8\"\n");
304 printf("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
306 printf("Argument Order:\n");
307 printf("Arguments are executed in the order they are given. eg\n");
308 printf("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
309 printf("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
310 printf("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
311 printf("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
312 printf("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
314 printf("\nEnvironment Variables:\n");
315 printf(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
316 printf(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
317 printf(" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
318 printf(" $Directory for user data files (icons, translations, ..).\n");
319 printf(" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
320 printf(" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
322 printf(" $TEMP Store temporary files here.\n");
324 printf(" $TMP or $TMPDIR Store temporary files here.\n");
327 printf(" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
329 printf(" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
336 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
341 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
343 G.f |= G_SCRIPT_AUTOEXEC;
344 G.f |= G_SCRIPT_OVERRIDE_PREF;
348 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
350 G.f &= ~G_SCRIPT_AUTOEXEC;
351 G.f |= G_SCRIPT_OVERRIDE_PREF;
355 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
361 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
363 G.debug |= G_DEBUG; /* std output printf's */
364 printf(BLEND_VERSION_STRING_FMT);
365 MEM_set_memory_debug();
367 #ifdef WITH_BUILDINFO
368 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
369 #endif // WITH_BUILDINFO
375 static int debug_mode_generic(int UNUSED(argc), const char **UNUSED(argv), void *data)
377 G.debug |= GET_INT_FROM_POINTER(data);
382 static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
384 libmv_startDebugLogging();
390 static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
393 G.rt = atoi(argv[1]);
398 printf("\nError: you must specify debug value to set.\n");
403 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
405 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
406 /* zealous but makes float issues a heck of a lot easier to find!
407 * set breakpoints on fpe_handler */
408 signal(SIGFPE, fpe_handler);
410 # if defined(__linux__) && defined(__GNUC__)
411 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
412 # endif /* defined(__linux__) && defined(__GNUC__) */
413 # if defined(OSX_SSE_FPE)
414 /* OSX uses SSE for floating point by default, so here
415 * use SSE instructions to throw floating point exceptions */
416 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK & ~
417 (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO));
418 # endif /* OSX_SSE_FPE */
419 # if defined(_WIN32) && defined(_MSC_VER)
420 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
421 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
422 # endif /* _WIN32 && _MSC_VER */
428 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
430 G.factory_startup = 1;
434 static int set_env(int argc, const char **argv, void *UNUSED(data))
436 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
438 char env[64] = "BLENDER";
439 char *ch_dst = env + 7; /* skip BLENDER */
440 const char *ch_src = argv[0] + 5; /* skip --env */
443 printf("%s requires one argument\n", argv[0]);
447 for (; *ch_src; ch_src++, ch_dst++) {
448 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
452 BLI_setenv(env, argv[1]);
456 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
458 /* not if -b was given first */
459 if (G.background == 0) {
460 #if 0 /* TODO, bring player back? */
461 playanim(argc, argv); /* not the same argc and argv as before */
463 fprintf(stderr, "Playback mode not supported in blender 2.6x\n");
471 static int prefsize(int argc, const char **argv, void *UNUSED(data))
473 int stax, stay, sizx, sizy;
476 fprintf(stderr, "-p requires four arguments\n");
480 stax = atoi(argv[1]);
481 stay = atoi(argv[2]);
482 sizx = atoi(argv[3]);
483 sizy = atoi(argv[4]);
485 WM_setprefsize(stax, stay, sizx, sizy);
490 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
492 WM_setinitialstate_normal();
496 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
498 WM_setinitialstate_fullscreen();
502 extern int wm_start_with_console; /* wm_init_exit.c */
503 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
505 wm_start_with_console = 1;
509 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
514 RegisterBlendExtension();
516 (void)data; /* unused */
521 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
523 #ifndef WITH_GAMEENGINE
526 SYS_SystemHandle *syshandle = data;
529 * don't initialize joysticks if user doesn't want to use joysticks
530 * failed joystick initialization delays over 5 seconds, before game engine start
532 SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
533 if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
539 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
541 GPU_extensions_disable();
545 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
547 sound_force_device(0);
551 static int set_audio(int argc, const char **argv, void *UNUSED(data))
554 fprintf(stderr, "-setaudio require one argument\n");
558 sound_force_device(sound_define_from_str(argv[1]));
562 static int set_output(int argc, const char **argv, void *data)
566 Scene *scene = CTX_data_scene(C);
568 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
571 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
576 printf("\nError: you must specify a path after '-o / --render-output'.\n");
581 static int set_engine(int argc, const char **argv, void *data)
585 if (!strcmp(argv[1], "help")) {
586 RenderEngineType *type = NULL;
587 printf("Blender Engine Listing:\n");
588 for (type = R_engines.first; type; type = type->next) {
589 printf("\t%s\n", type->idname);
594 Scene *scene = CTX_data_scene(C);
596 RenderData *rd = &scene->r;
598 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
599 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
603 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
610 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
615 static int set_image_type(int argc, const char **argv, void *data)
619 const char *imtype = argv[1];
620 Scene *scene = CTX_data_scene(C);
622 const char imtype_new = BKE_imtype_from_arg(imtype);
624 if (imtype_new == R_IMF_IMTYPE_INVALID) {
625 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
628 scene->r.im_format.imtype = imtype_new;
632 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
637 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
642 static int set_threads(int argc, const char **argv, void *UNUSED(data))
646 RE_set_max_threads(atoi(argv[1]));
649 printf("Warning: threads can only be set in background mode\n");
654 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
659 static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
662 int level = atoi(argv[1]);
665 libmv_setLoggingVerbosity(level);
673 printf("\nError: you must specify a verbosity level.\n");
678 static int set_extension(int argc, const char **argv, void *data)
682 Scene *scene = CTX_data_scene(C);
684 if (argv[1][0] == '0') {
685 scene->r.scemode &= ~R_EXTENSION;
687 else if (argv[1][0] == '1') {
688 scene->r.scemode |= R_EXTENSION;
691 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
695 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
700 printf("\nError: you must specify a path after '- '.\n");
705 static int set_ge_parameters(int argc, const char **argv, void *data)
708 #ifdef WITH_GAMEENGINE
709 SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
715 * gameengine parameters are automatically put into system
716 * -g [paramname = value]
720 * -g maxvertexarraysize = 512
724 const char *paramname = argv[a];
725 /* check for single value versus assignment */
726 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
731 #ifdef WITH_GAMEENGINE
732 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
736 printf("error: argument assignment (%s) without value.\n", paramname);
743 #ifdef WITH_GAMEENGINE
744 SYS_WriteCommandLineInt(syshandle, argv[a], 1);
747 if (!strcmp(argv[a], "nomipmap")) {
748 GPU_set_mipmap(0); //doMipMap = 0;
751 if (!strcmp(argv[a], "linearmipmap")) {
752 GPU_set_linear_mipmap(1); //linearMipMap = 1;
756 } /* if (*(argv[a+1]) == '=') */
762 static int render_frame(int argc, const char **argv, void *data)
765 Scene *scene = CTX_data_scene(C);
767 Main *bmain = CTX_data_main(C);
770 Render *re = RE_NewRender(scene->id.name);
776 frame = scene->r.sfra + atoi(argv[1] + 1);
779 frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
782 frame = atoi(argv[1]);
786 BKE_reports_init(&reports, RPT_PRINT);
788 frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
790 RE_SetReports(re, &reports);
791 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
792 RE_SetReports(re, NULL);
796 printf("\nError: frame number must follow '-f / --render-frame'.\n");
801 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
806 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
809 Scene *scene = CTX_data_scene(C);
811 Main *bmain = CTX_data_main(C);
812 Render *re = RE_NewRender(scene->id.name);
814 BKE_reports_init(&reports, RPT_PRINT);
815 RE_SetReports(re, &reports);
816 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
817 RE_SetReports(re, NULL);
820 printf("\nError: no blend loaded. cannot use '-a'.\n");
825 static int set_scene(int argc, const char **argv, void *data)
829 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
831 CTX_data_scene_set(C, scene);
836 printf("\nError: Scene name must follow '-S / --scene'.\n");
841 static int set_start_frame(int argc, const char **argv, void *data)
844 Scene *scene = CTX_data_scene(C);
847 int frame = atoi(argv[1]);
848 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
852 printf("\nError: frame number must follow '-s / --frame-start'.\n");
857 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
862 static int set_end_frame(int argc, const char **argv, void *data)
865 Scene *scene = CTX_data_scene(C);
868 int frame = atoi(argv[1]);
869 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
873 printf("\nError: frame number must follow '-e / --frame-end'.\n");
878 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
883 static int set_skip_frame(int argc, const char **argv, void *data)
886 Scene *scene = CTX_data_scene(C);
889 int frame = atoi(argv[1]);
890 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
894 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
899 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
904 /* macro for ugly context setup/reset */
906 #define BPY_CTX_SETUP(_cmd) \
908 wmWindowManager *wm = CTX_wm_manager(C); \
909 wmWindow *prevwin = CTX_wm_window(C); \
910 Scene *prevscene = CTX_data_scene(C); \
911 if (wm->windows.first) { \
912 CTX_wm_window_set(C, wm->windows.first); \
914 CTX_wm_window_set(C, prevwin); \
917 fprintf(stderr, "Python script \"%s\" " \
918 "running with missing context data.\n", argv[1]); \
921 CTX_data_scene_set(C, prevscene); \
924 #endif /* WITH_PYTHON */
926 static int run_python(int argc, const char **argv, void *data)
931 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
933 /* Make the path absolute because its needed for relative linked blends to be found */
934 char filename[FILE_MAX];
935 BLI_strncpy(filename, argv[1], sizeof(filename));
936 BLI_path_cwd(filename);
938 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
943 printf("\nError: you must specify a Python script after '-P / --python'.\n");
947 (void)argc; (void)argv; (void)data; /* unused */
948 printf("This blender was built without python support\n");
950 #endif /* WITH_PYTHON */
953 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
958 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
962 (void)argv; (void)data; /* unused */
963 printf("This blender was built without python support\n");
965 #endif /* WITH_PYTHON */
968 static int set_addons(int argc, const char **argv, void *data)
970 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
973 const int slen = strlen(argv[1]) + 128;
974 char *str = malloc(slen);
976 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
977 BPY_CTX_SETUP(BPY_string_exec(C, str));
980 (void)argv; (void)data; /* unused */
981 #endif /* WITH_PYTHON */
985 printf("\nError: you must specify a comma separated list after '--addons'.\n");
990 static int load_file(int UNUSED(argc), const char **argv, void *data)
994 /* Make the path absolute because its needed for relative linked blends to be found */
995 char filename[FILE_MAX];
997 /* note, we could skip these, but so far we always tried to load these files */
998 if (argv[0][0] == '-') {
999 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1002 BLI_strncpy(filename, argv[0], sizeof(filename));
1003 BLI_path_cwd(filename);
1006 int retval = BKE_read_file(C, filename, NULL);
1008 /* we successfully loaded a blend file, get sure that
1009 * pointcache works */
1010 if (retval != BKE_READ_FILE_FAIL) {
1011 wmWindowManager *wm = CTX_wm_manager(C);
1013 /* special case, 2.4x files */
1014 if (wm == NULL && CTX_data_main(C)->wm.first == NULL) {
1015 extern void wm_add_default(bContext *C);
1017 /* wm_add_default() needs the screen to be set. */
1018 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
1022 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1024 G.relbase_valid = 1;
1025 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
1027 DAG_on_visible_update(CTX_data_main(C), TRUE);
1030 /* failed to load file, stop processing arguments */
1034 /* WM_read_file() runs normally but since we're in background mode do here */
1036 /* run any texts that were loaded in and flagged as modules */
1038 BPY_app_handlers_reset(FALSE);
1039 BPY_modules_load_user(C);
1042 /* happens for the UI on file reading too (huh? (ton))*/
1043 // XXX BKE_reset_undo();
1044 // BKE_write_undo("original"); /* save current state */
1047 /* we are not running in background mode here, but start blender in UI mode with
1048 * a file - this should do everything a 'load file' does */
1050 BKE_reports_init(&reports, RPT_PRINT);
1051 WM_read_file(C, filename, &reports);
1052 BKE_reports_clear(&reports);
1060 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1062 static char output_doc[] = "<path>"
1063 "\n\tSet the render path and file name."
1064 "\n\tUse // at the start of the path to"
1065 "\n\t\trender relative to the blend file."
1066 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1067 "\n\t\tani_##_test.png becomes ani_01_test.png"
1068 "\n\t\ttest-######.png becomes test-000001.png"
1069 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1070 "\n\tThe frame number will be added at the end of the filename."
1071 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1072 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1074 static char format_doc[] = "<format>"
1075 "\n\tSet the render format, Valid options are..."
1076 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1077 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1078 "\n\t(formats that can be compiled into blender, not available on all systems)"
1079 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1081 static char playback_doc[] = "<options> <file(s)>"
1082 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1083 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1084 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1085 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1086 "\n\t\t-j <frame>\tSet frame step to <frame>";
1088 static char game_doc[] = "Game Engine specific options"
1089 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1090 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1091 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1092 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1094 static char debug_doc[] = "\n\tTurn debugging on\n"
1095 "\n\t* Prints every operator call and their arguments"
1096 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1097 "\n\t* Keeps python sys.stdin rather than setting it to None";
1099 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1101 /* end argument processing after -- */
1102 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1104 /* first pass: background mode, disable python and commands that exit after usage */
1105 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1107 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1109 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1111 /* only to give help message */
1112 #ifndef WITH_PYTHON_SECURITY /* default */
1113 # define PY_ENABLE_AUTO ", (default)"
1114 # define PY_DISABLE_AUTO ""
1116 # define PY_ENABLE_AUTO ""
1117 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1120 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1121 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1123 #undef PY_ENABLE_AUTO
1124 #undef PY_DISABLE_AUTO
1126 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1128 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1130 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1133 BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1135 BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1136 BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1137 BLI_argsAdd(ba, 1, NULL, "--debug-wm", "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1138 BLI_argsAdd(ba, 1, NULL, "--debug-all", "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1140 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1143 BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1146 BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1147 BLI_argsAdd(ba, 1, NULL, "--debug-jobs", "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1149 BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1151 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1153 /* TODO, add user env vars? */
1154 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1155 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1156 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1158 /* second pass: custom window stuff */
1159 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);
1160 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1161 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1162 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1163 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1164 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1166 /* third pass: disabling things and forcing settings */
1167 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1168 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1169 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1170 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1172 /* fourth pass: processing arguments */
1173 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1174 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);
1175 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1176 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1177 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1178 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1179 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1180 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1181 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1182 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1184 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1185 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1187 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1188 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);
1189 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);
1192 #endif /* WITH_PYTHON_MODULE */
1194 #ifdef WITH_PYTHON_MODULE
1195 /* allow python module to call main */
1196 # define main main_python_enter
1197 static void *evil_C = NULL;
1200 /* environ is not available in mac shared libraries */
1201 # include <crt_externs.h>
1202 char **environ = NULL;
1208 int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
1210 int main(int argc, const char **argv)
1213 bContext *C = CTX_create();
1214 SYS_SystemHandle syshandle;
1216 #ifndef WITH_PYTHON_MODULE
1221 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1223 char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
1224 for (argci = 0; argci < argc; argci++) {
1225 argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
1230 #ifdef WITH_PYTHON_MODULE
1232 environ = *_NSGetEnviron();
1241 #ifdef WITH_BINRELOC
1246 libmv_initLogging(argv[0]);
1250 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1251 /* patch to ignore argument finder gives us (pid?) */
1252 if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
1253 extern int GHOST_HACK_getFirstFile(char buf[]);
1254 static char firstfilebuf[512];
1258 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1260 argv[1] = firstfilebuf;
1270 /* initialize path to executable */
1271 BLI_init_program_path(argv[0]);
1273 BLI_threadapi_init();
1280 initglobals(); /* blender.c */
1284 BLI_callback_global_init();
1286 #ifdef WITH_GAMEENGINE
1287 syshandle = SYS_GetSystem();
1292 /* first test for background */
1293 #ifndef WITH_PYTHON_MODULE
1294 ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1295 setupArguments(C, ba, &syshandle);
1297 BLI_argsParse(ba, 1, NULL, NULL);
1300 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1301 G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */
1303 /* for all platforms, even windos has it! */
1304 if (G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1307 /* background render uses this font too */
1308 BKE_vfont_builtin_register(datatoc_Bfont, datatoc_Bfont_size);
1310 /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1311 * rendered via ffmpeg */
1314 init_def_material();
1316 if (G.background == 0) {
1317 #ifndef WITH_PYTHON_MODULE
1318 BLI_argsParse(ba, 2, NULL, NULL);
1319 BLI_argsParse(ba, 3, NULL, NULL);
1321 WM_init(C, argc, (const char **)argv);
1323 /* this is properly initialized with user defs, but this is default */
1324 /* call after loading the startup.blend so we can read U.tempdir */
1325 BLI_init_temporary_dir(U.tempdir);
1328 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1332 #ifndef WITH_PYTHON_MODULE
1333 BLI_argsParse(ba, 3, NULL, NULL);
1336 WM_init(C, argc, (const char **)argv);
1338 /* don't use user preferences temp dir */
1339 BLI_init_temporary_dir(NULL);
1343 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1344 * so we provide the BPY_ function below to append the user defined
1345 * python-dir to Python's sys.path at this point. Simply putting
1346 * WM_init() before #BPY_python_start() crashes Blender at startup.
1349 /* TODO - U.pythondir */
1351 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1354 CTX_py_init_set(C, 1);
1357 /* OK we are ready for it */
1358 #ifndef WITH_PYTHON_MODULE
1359 BLI_argsParse(ba, 4, load_file, C);
1362 #ifndef WITH_PYTHON_MODULE
1368 free(argv[--argci]);
1374 #ifdef WITH_PYTHON_MODULE
1375 return 0; /* keep blender in background mode running */
1379 /* actually incorrect, but works for now (ton) */
1383 if ((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC)) {
1384 if (WM_init_game(C))
1387 else if (!G.file_loaded) {
1395 } /* end of int main(argc,argv) */
1397 #ifdef WITH_PYTHON_MODULE
1398 void main_python_exit(void)
1400 WM_exit((bContext *)evil_C);
1405 static void error_cb(const char *err)
1408 printf("%s\n", err); /* XXX do this in WM too */
1411 static void mem_error_cb(const char *errorStr)
1413 fputs(errorStr, stderr);
1417 static void setCallbacks(void)
1419 /* Error output from the alloc routines: */
1420 MEM_set_error_callback(mem_error_cb);
1425 BLI_setErrorCallBack(error_cb); /* */
1426 // XXX BLI_setInterruptCallBack(blender_test_break);