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_blender.h"
72 #include "BKE_context.h"
73 #include "BKE_depsgraph.h" /* for DAG_on_visible_update */
75 #include "BKE_global.h"
77 #include "BKE_material.h"
78 #include "BKE_packedFile.h"
79 #include "BKE_scene.h"
81 #include "BKE_report.h"
82 #include "BKE_sound.h"
83 #include "BKE_image.h"
85 #include "IMB_imbuf.h" /* for IMB_init */
88 #include "BPY_extern.h"
91 #include "RE_engine.h"
92 #include "RE_pipeline.h"
94 //XXX #include "playanim_ext.h"
95 #include "ED_datafiles.h"
99 #include "RNA_define.h"
101 #include "GPU_draw.h"
102 #include "GPU_extensions.h"
104 #include "BLI_scanfill.h" /* for BLI_setErrorCallBack, TODO, move elsewhere */
106 #ifdef WITH_BUILDINFO_HEADER
110 /* for passing information between creator and gameengine */
111 #ifdef WITH_GAMEENGINE
112 # include "BL_System.h"
114 # define SYS_SystemHandle int
120 # include <sys/types.h>
121 # include <floatingpoint.h>
122 # include <sys/rtprio.h>
126 # include "binreloc.h"
130 # include "libmv-capi.h"
133 /* from buildinfo.c */
135 extern char build_date[];
136 extern char build_time[];
137 extern char build_rev[];
138 extern char build_platform[];
139 extern char build_type[];
140 extern char build_cflags[];
141 extern char build_cxxflags[];
142 extern char build_linkflags[];
143 extern char build_system[];
146 /* Local Function prototypes */
147 #ifndef WITH_PYTHON_MODULE
148 static int print_help(int argc, const char **argv, void *data);
149 static int print_version(int argc, const char **argv, void *data);
152 /* for the callbacks: */
154 #define BLEND_VERSION_STRING_FMT \
155 "Blender %d.%02d (sub %d)\n", \
156 BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION \
158 /* Initialize callbacks for the modules that need them */
159 static void setCallbacks(void);
161 #ifndef WITH_PYTHON_MODULE
163 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
164 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
165 static void fpe_handler(int UNUSED(sig))
167 // printf("SIGFPE trapped\n");
171 /* handling ctrl-c event in console */
172 static void blender_esc(int sig)
174 static int count = 0;
176 G.is_break = TRUE; /* forces render loop to read queue, not sure if its needed */
180 printf("\nBlender killed\n");
183 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
188 static int print_version(int UNUSED(argc), const 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), const 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");
240 BLI_argsPrintArgDoc(ba, "--start-console");
243 printf("Game Engine Specific Options:\n");
244 BLI_argsPrintArgDoc(ba, "-g");
247 printf("Misc Options:\n");
248 BLI_argsPrintArgDoc(ba, "--debug");
249 BLI_argsPrintArgDoc(ba, "--debug-fpe");
252 BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
256 BLI_argsPrintArgDoc(ba, "--debug-libmv");
260 BLI_argsPrintArgDoc(ba, "--factory-startup");
262 BLI_argsPrintArgDoc(ba, "--env-system-config");
263 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
264 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
265 BLI_argsPrintArgDoc(ba, "--env-system-python");
267 BLI_argsPrintArgDoc(ba, "-nojoystick");
268 BLI_argsPrintArgDoc(ba, "-noglsl");
269 BLI_argsPrintArgDoc(ba, "-noaudio");
270 BLI_argsPrintArgDoc(ba, "-setaudio");
274 BLI_argsPrintArgDoc(ba, "--help");
278 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
279 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
283 BLI_argsPrintArgDoc(ba, "--python");
284 BLI_argsPrintArgDoc(ba, "--python-console");
285 BLI_argsPrintArgDoc(ba, "--addons");
288 BLI_argsPrintArgDoc(ba, "-R");
289 BLI_argsPrintArgDoc(ba, "-r");
291 BLI_argsPrintArgDoc(ba, "--version");
293 BLI_argsPrintArgDoc(ba, "--");
295 printf("Other Options:\n");
296 BLI_argsPrintOtherDoc(ba);
298 printf("Argument Parsing:\n");
299 printf("\targuments must be separated by white space. eg\n");
300 printf("\t\t\"blender -ba test.blend\"\n");
301 printf("\t...will ignore the 'a'\n");
302 printf("\t\t\"blender -b test.blend -f8\"\n");
303 printf("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
305 printf("Argument Order:\n");
306 printf("Arguments are executed in the order they are given. eg\n");
307 printf("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
308 printf("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
309 printf("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
310 printf("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
311 printf("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
313 printf("\nEnvironment Variables:\n");
314 printf(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
315 printf(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
316 printf(" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
317 printf(" $Directory for user data files (icons, translations, ..).\n");
318 printf(" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
319 printf(" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
321 printf(" $TEMP Store temporary files here.\n");
323 printf(" $TMP or $TMPDIR Store temporary files here.\n");
326 printf(" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
328 printf(" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
335 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
340 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
342 G.f |= G_SCRIPT_AUTOEXEC;
343 G.f |= G_SCRIPT_OVERRIDE_PREF;
347 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
349 G.f &= ~G_SCRIPT_AUTOEXEC;
350 G.f |= G_SCRIPT_OVERRIDE_PREF;
354 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
360 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
362 G.debug |= G_DEBUG; /* std output printf's */
363 printf(BLEND_VERSION_STRING_FMT);
364 MEM_set_memory_debug();
366 #ifdef WITH_BUILDINFO
367 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
368 #endif // WITH_BUILDINFO
374 static int debug_mode_generic(int UNUSED(argc), const char **UNUSED(argv), void *data)
376 G.debug |= GET_INT_FROM_POINTER(data);
381 static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
383 libmv_startDebugLogging();
389 static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
392 G.debug_value = atoi(argv[1]);
397 printf("\nError: you must specify debug value to set.\n");
402 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
404 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
405 /* zealous but makes float issues a heck of a lot easier to find!
406 * set breakpoints on fpe_handler */
407 signal(SIGFPE, fpe_handler);
409 # if defined(__linux__) && defined(__GNUC__)
410 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
411 # endif /* defined(__linux__) && defined(__GNUC__) */
412 # if defined(OSX_SSE_FPE)
413 /* OSX uses SSE for floating point by default, so here
414 * use SSE instructions to throw floating point exceptions */
415 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK & ~
416 (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO));
417 # endif /* OSX_SSE_FPE */
418 # if defined(_WIN32) && defined(_MSC_VER)
419 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
420 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
421 # endif /* _WIN32 && _MSC_VER */
427 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
429 G.factory_startup = 1;
433 static int set_env(int argc, const char **argv, void *UNUSED(data))
435 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
437 char env[64] = "BLENDER";
438 char *ch_dst = env + 7; /* skip BLENDER */
439 const char *ch_src = argv[0] + 5; /* skip --env */
442 printf("%s requires one argument\n", argv[0]);
446 for (; *ch_src; ch_src++, ch_dst++) {
447 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
451 BLI_setenv(env, argv[1]);
455 static int playback_mode(int argc, const char **argv, void *UNUSED(data))
457 extern void playanim(int argc, const char **argv);
459 /* not if -b was given first */
460 if (G.background == 0) {
461 playanim(argc, argv); /* not the same argc and argv as before */
462 exit(0); /* 2.4x didn't do this */
468 static int prefsize(int argc, const char **argv, void *UNUSED(data))
470 int stax, stay, sizx, sizy;
473 fprintf(stderr, "-p requires four arguments\n");
477 stax = atoi(argv[1]);
478 stay = atoi(argv[2]);
479 sizx = atoi(argv[3]);
480 sizy = atoi(argv[4]);
482 WM_init_state_size_set(stax, stay, sizx, sizy);
487 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
489 WM_init_state_normal_set();
493 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
495 WM_init_state_fullscreen_set();
499 extern int wm_start_with_console; /* wm_init_exit.c */
500 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
502 wm_start_with_console = 1;
506 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
511 RegisterBlendExtension();
513 (void)data; /* unused */
518 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
520 #ifndef WITH_GAMEENGINE
523 SYS_SystemHandle *syshandle = data;
526 * don't initialize joysticks if user doesn't want to use joysticks
527 * failed joystick initialization delays over 5 seconds, before game engine start
529 SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
530 if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
536 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
538 GPU_extensions_disable();
542 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
544 sound_force_device(0);
548 static int set_audio(int argc, const char **argv, void *UNUSED(data))
551 fprintf(stderr, "-setaudio require one argument\n");
555 sound_force_device(sound_define_from_str(argv[1]));
559 static int set_output(int argc, const char **argv, void *data)
563 Scene *scene = CTX_data_scene(C);
565 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
568 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
573 printf("\nError: you must specify a path after '-o / --render-output'.\n");
578 static int set_engine(int argc, const char **argv, void *data)
582 if (!strcmp(argv[1], "help")) {
583 RenderEngineType *type = NULL;
584 printf("Blender Engine Listing:\n");
585 for (type = R_engines.first; type; type = type->next) {
586 printf("\t%s\n", type->idname);
591 Scene *scene = CTX_data_scene(C);
593 RenderData *rd = &scene->r;
595 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
596 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
600 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
607 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
612 static int set_image_type(int argc, const char **argv, void *data)
616 const char *imtype = argv[1];
617 Scene *scene = CTX_data_scene(C);
619 const char imtype_new = BKE_imtype_from_arg(imtype);
621 if (imtype_new == R_IMF_IMTYPE_INVALID) {
622 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
625 scene->r.im_format.imtype = imtype_new;
629 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
634 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
639 static int set_threads(int argc, const char **argv, void *UNUSED(data))
643 RE_set_max_threads(atoi(argv[1]));
646 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_verbosity(int argc, const char **argv, void *UNUSED(data))
659 int level = atoi(argv[1]);
662 libmv_setLoggingVerbosity(level);
670 printf("\nError: you must specify a verbosity level.\n");
675 static int set_extension(int argc, const char **argv, void *data)
679 Scene *scene = CTX_data_scene(C);
681 if (argv[1][0] == '0') {
682 scene->r.scemode &= ~R_EXTENSION;
684 else if (argv[1][0] == '1') {
685 scene->r.scemode |= R_EXTENSION;
688 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
692 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
697 printf("\nError: you must specify a path after '- '.\n");
702 static int set_ge_parameters(int argc, const char **argv, void *data)
705 #ifdef WITH_GAMEENGINE
706 SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
712 * gameengine parameters are automatically put into system
713 * -g [paramname = value]
717 * -g maxvertexarraysize = 512
721 const char *paramname = argv[a];
722 /* check for single value versus assignment */
723 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
728 #ifdef WITH_GAMEENGINE
729 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
733 printf("error: argument assignment (%s) without value.\n", paramname);
740 #ifdef WITH_GAMEENGINE
741 SYS_WriteCommandLineInt(syshandle, argv[a], 1);
744 if (!strcmp(argv[a], "nomipmap")) {
745 GPU_set_mipmap(0); //doMipMap = 0;
748 if (!strcmp(argv[a], "linearmipmap")) {
749 GPU_set_linear_mipmap(1); //linearMipMap = 1;
753 } /* if (*(argv[a+1]) == '=') */
759 static int render_frame(int argc, const char **argv, void *data)
762 Scene *scene = CTX_data_scene(C);
764 Main *bmain = CTX_data_main(C);
767 Render *re = RE_NewRender(scene->id.name);
773 frame = scene->r.sfra + atoi(argv[1] + 1);
776 frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
779 frame = atoi(argv[1]);
783 BKE_reports_init(&reports, RPT_PRINT);
785 frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
787 RE_SetReports(re, &reports);
788 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
789 RE_SetReports(re, NULL);
793 printf("\nError: frame number must follow '-f / --render-frame'.\n");
798 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
803 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
806 Scene *scene = CTX_data_scene(C);
808 Main *bmain = CTX_data_main(C);
809 Render *re = RE_NewRender(scene->id.name);
811 BKE_reports_init(&reports, RPT_PRINT);
812 RE_SetReports(re, &reports);
813 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
814 RE_SetReports(re, NULL);
817 printf("\nError: no blend loaded. cannot use '-a'.\n");
822 static int set_scene(int argc, const char **argv, void *data)
826 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
828 CTX_data_scene_set(C, scene);
833 printf("\nError: Scene name must follow '-S / --scene'.\n");
838 static int set_start_frame(int argc, const char **argv, void *data)
841 Scene *scene = CTX_data_scene(C);
844 int frame = atoi(argv[1]);
845 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
849 printf("\nError: frame number must follow '-s / --frame-start'.\n");
854 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
859 static int set_end_frame(int argc, const char **argv, void *data)
862 Scene *scene = CTX_data_scene(C);
865 int frame = atoi(argv[1]);
866 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
870 printf("\nError: frame number must follow '-e / --frame-end'.\n");
875 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
880 static int set_skip_frame(int argc, const char **argv, void *data)
883 Scene *scene = CTX_data_scene(C);
886 int frame = atoi(argv[1]);
887 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
891 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
896 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
901 /* macro for ugly context setup/reset */
903 #define BPY_CTX_SETUP(_cmd) \
905 wmWindowManager *wm = CTX_wm_manager(C); \
906 wmWindow *prevwin = CTX_wm_window(C); \
907 Scene *prevscene = CTX_data_scene(C); \
908 if (wm->windows.first) { \
909 CTX_wm_window_set(C, wm->windows.first); \
911 CTX_wm_window_set(C, prevwin); \
914 fprintf(stderr, "Python script \"%s\" " \
915 "running with missing context data.\n", argv[1]); \
918 CTX_data_scene_set(C, prevscene); \
921 #endif /* WITH_PYTHON */
923 static int run_python(int argc, const char **argv, void *data)
928 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
930 /* Make the path absolute because its needed for relative linked blends to be found */
931 char filename[FILE_MAX];
932 BLI_strncpy(filename, argv[1], sizeof(filename));
933 BLI_path_cwd(filename);
935 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
940 printf("\nError: you must specify a Python script after '-P / --python'.\n");
944 (void)argc; (void)argv; (void)data; /* unused */
945 printf("This blender was built without python support\n");
947 #endif /* WITH_PYTHON */
950 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
955 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
959 (void)argv; (void)data; /* unused */
960 printf("This blender was built without python support\n");
962 #endif /* WITH_PYTHON */
965 static int set_addons(int argc, const char **argv, void *data)
967 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
970 const int slen = strlen(argv[1]) + 128;
971 char *str = malloc(slen);
973 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
974 BPY_CTX_SETUP(BPY_string_exec(C, str));
977 (void)argv; (void)data; /* unused */
978 #endif /* WITH_PYTHON */
982 printf("\nError: you must specify a comma separated list after '--addons'.\n");
987 static int load_file(int UNUSED(argc), const char **argv, void *data)
991 /* Make the path absolute because its needed for relative linked blends to be found */
992 char filename[FILE_MAX];
994 /* note, we could skip these, but so far we always tried to load these files */
995 if (argv[0][0] == '-') {
996 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
999 BLI_strncpy(filename, argv[0], sizeof(filename));
1000 BLI_path_cwd(filename);
1003 int retval = BKE_read_file(C, filename, NULL);
1005 /* we successfully loaded a blend file, get sure that
1006 * pointcache works */
1007 if (retval != BKE_READ_FILE_FAIL) {
1008 wmWindowManager *wm = CTX_wm_manager(C);
1010 /* special case, 2.4x files */
1011 if (wm == NULL && CTX_data_main(C)->wm.first == NULL) {
1012 extern void wm_add_default(bContext *C);
1014 /* wm_add_default() needs the screen to be set. */
1015 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
1019 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1021 G.relbase_valid = 1;
1022 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
1024 DAG_on_visible_update(CTX_data_main(C), TRUE);
1027 /* failed to load file, stop processing arguments */
1031 /* WM_file_read() runs normally but since we're in background mode do here */
1033 /* run any texts that were loaded in and flagged as modules */
1035 BPY_app_handlers_reset(FALSE);
1036 BPY_modules_load_user(C);
1039 /* happens for the UI on file reading too (huh? (ton))*/
1040 // XXX BKE_reset_undo();
1041 // BKE_write_undo("original"); /* save current state */
1044 /* we are not running in background mode here, but start blender in UI mode with
1045 * a file - this should do everything a 'load file' does */
1047 BKE_reports_init(&reports, RPT_PRINT);
1048 WM_file_read(C, filename, &reports);
1049 BKE_reports_clear(&reports);
1057 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1059 static char output_doc[] = "<path>"
1060 "\n\tSet the render path and file name."
1061 "\n\tUse // at the start of the path to"
1062 "\n\t\trender relative to the blend file."
1063 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1064 "\n\t\tani_##_test.png becomes ani_01_test.png"
1065 "\n\t\ttest-######.png becomes test-000001.png"
1066 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1067 "\n\tThe frame number will be added at the end of the filename."
1068 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1069 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1071 static char format_doc[] = "<format>"
1072 "\n\tSet the render format, Valid options are..."
1073 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1074 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1075 "\n\t(formats that can be compiled into blender, not available on all systems)"
1076 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1078 static char playback_doc[] = "<options> <file(s)>"
1079 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1080 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1081 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1082 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1083 "\n\t\t-j <frame>\tSet frame step to <frame>";
1085 static char game_doc[] = "Game Engine specific options"
1086 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1087 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1088 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1089 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1091 static char debug_doc[] = "\n\tTurn debugging on\n"
1092 "\n\t* Prints every operator call and their arguments"
1093 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1094 "\n\t* Keeps python sys.stdin rather than setting it to None";
1096 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1098 /* end argument processing after -- */
1099 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1101 /* first pass: background mode, disable python and commands that exit after usage */
1102 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1104 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1106 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1108 /* only to give help message */
1109 #ifndef WITH_PYTHON_SECURITY /* default */
1110 # define PY_ENABLE_AUTO ", (default)"
1111 # define PY_DISABLE_AUTO ""
1113 # define PY_ENABLE_AUTO ""
1114 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1117 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1118 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1120 #undef PY_ENABLE_AUTO
1121 #undef PY_DISABLE_AUTO
1123 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1125 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1127 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1130 BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1132 BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1133 BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1134 BLI_argsAdd(ba, 1, NULL, "--debug-wm", "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1135 BLI_argsAdd(ba, 1, NULL, "--debug-all", "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1137 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1140 BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1143 BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1144 BLI_argsAdd(ba, 1, NULL, "--debug-jobs", "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1146 BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1148 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1150 /* TODO, add user env vars? */
1151 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1152 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1153 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1155 /* second pass: custom window stuff */
1156 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);
1157 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1158 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1159 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1160 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1161 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1163 /* third pass: disabling things and forcing settings */
1164 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1165 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1166 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1167 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1169 /* fourth pass: processing arguments */
1170 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1171 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);
1172 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1173 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1174 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1175 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1176 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1177 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1178 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1179 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1181 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1182 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1184 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1185 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);
1186 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);
1189 #endif /* WITH_PYTHON_MODULE */
1191 #ifdef WITH_PYTHON_MODULE
1192 /* allow python module to call main */
1193 # define main main_python_enter
1194 static void *evil_C = NULL;
1197 /* environ is not available in mac shared libraries */
1198 # include <crt_externs.h>
1199 char **environ = NULL;
1205 int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
1207 int main(int argc, const char **argv)
1210 bContext *C = CTX_create();
1211 SYS_SystemHandle syshandle;
1213 #ifndef WITH_PYTHON_MODULE
1218 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1220 char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
1221 for (argci = 0; argci < argc; argci++) {
1222 argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
1227 #ifdef WITH_PYTHON_MODULE
1229 environ = *_NSGetEnviron();
1238 #ifdef WITH_BINRELOC
1243 libmv_initLogging(argv[0]);
1247 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1248 /* patch to ignore argument finder gives us (pid?) */
1249 if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
1250 extern int GHOST_HACK_getFirstFile(char buf[]);
1251 static char firstfilebuf[512];
1255 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1257 argv[1] = firstfilebuf;
1267 /* initialize path to executable */
1268 BLI_init_program_path(argv[0]);
1270 BLI_threadapi_init();
1272 initglobals(); /* blender.c */
1280 BLI_callback_global_init();
1282 #ifdef WITH_GAMEENGINE
1283 syshandle = SYS_GetSystem();
1288 /* first test for background */
1289 #ifndef WITH_PYTHON_MODULE
1290 ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1291 setupArguments(C, ba, &syshandle);
1293 BLI_argsParse(ba, 1, NULL, NULL);
1297 /* after level 1 args, this is so playanim skips RNA init */
1302 /* end second init */
1305 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1306 G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */
1308 /* for all platforms, even windos has it! */
1309 if (G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1312 /* background render uses this font too */
1313 BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
1315 /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1316 * rendered via ffmpeg */
1319 init_def_material();
1321 if (G.background == 0) {
1322 #ifndef WITH_PYTHON_MODULE
1323 BLI_argsParse(ba, 2, NULL, NULL);
1324 BLI_argsParse(ba, 3, NULL, NULL);
1326 WM_init(C, argc, (const char **)argv);
1328 /* this is properly initialized with user defs, but this is default */
1329 /* call after loading the startup.blend so we can read U.tempdir */
1330 BLI_init_temporary_dir(U.tempdir);
1333 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1337 #ifndef WITH_PYTHON_MODULE
1338 BLI_argsParse(ba, 3, NULL, NULL);
1341 WM_init(C, argc, (const char **)argv);
1343 /* don't use user preferences temp dir */
1344 BLI_init_temporary_dir(NULL);
1348 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1349 * so we provide the BPY_ function below to append the user defined
1350 * python-dir to Python's sys.path at this point. Simply putting
1351 * WM_init() before #BPY_python_start() crashes Blender at startup.
1354 /* TODO - U.pythondir */
1356 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1359 CTX_py_init_set(C, 1);
1362 /* OK we are ready for it */
1363 #ifndef WITH_PYTHON_MODULE
1364 BLI_argsParse(ba, 4, load_file, C);
1367 #ifndef WITH_PYTHON_MODULE
1373 free(argv[--argci]);
1379 #ifdef WITH_PYTHON_MODULE
1380 return 0; /* keep blender in background mode running */
1384 /* actually incorrect, but works for now (ton) */
1388 if ((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC)) {
1389 if (WM_init_game(C))
1392 else if (!G.file_loaded) {
1400 } /* end of int main(argc,argv) */
1402 #ifdef WITH_PYTHON_MODULE
1403 void main_python_exit(void)
1405 WM_exit((bContext *)evil_C);
1410 static void error_cb(const char *err)
1413 printf("%s\n", err); /* XXX do this in WM too */
1416 static void mem_error_cb(const char *errorStr)
1418 fputs(errorStr, stderr);
1422 static void setCallbacks(void)
1424 /* Error output from the alloc routines: */
1425 MEM_set_error_callback(mem_error_cb);
1430 BLI_setErrorCallBack(error_cb); /* */
1431 // XXX BLI_setInterruptCallBack(blender_test_break);