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 argc, const char **argv, void *UNUSED(data))
458 extern void playanim(int argc, const char **argv);
460 /* not if -b was given first */
461 if (G.background == 0) {
462 playanim(argc, argv); /* not the same argc and argv as before */
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_setprefsize(stax, stay, sizx, sizy);
487 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
489 WM_setinitialstate_normal();
493 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
495 WM_setinitialstate_fullscreen();
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_read_file() 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_read_file(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();
1277 initglobals(); /* blender.c */
1281 BLI_callback_global_init();
1283 #ifdef WITH_GAMEENGINE
1284 syshandle = SYS_GetSystem();
1289 /* first test for background */
1290 #ifndef WITH_PYTHON_MODULE
1291 ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1292 setupArguments(C, ba, &syshandle);
1294 BLI_argsParse(ba, 1, NULL, NULL);
1297 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1298 G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */
1300 /* for all platforms, even windos has it! */
1301 if (G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1304 /* background render uses this font too */
1305 BKE_vfont_builtin_register(datatoc_Bfont, datatoc_Bfont_size);
1307 /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1308 * rendered via ffmpeg */
1311 init_def_material();
1313 if (G.background == 0) {
1314 #ifndef WITH_PYTHON_MODULE
1315 BLI_argsParse(ba, 2, NULL, NULL);
1316 BLI_argsParse(ba, 3, NULL, NULL);
1318 WM_init(C, argc, (const char **)argv);
1320 /* this is properly initialized with user defs, but this is default */
1321 /* call after loading the startup.blend so we can read U.tempdir */
1322 BLI_init_temporary_dir(U.tempdir);
1325 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1329 #ifndef WITH_PYTHON_MODULE
1330 BLI_argsParse(ba, 3, NULL, NULL);
1333 WM_init(C, argc, (const char **)argv);
1335 /* don't use user preferences temp dir */
1336 BLI_init_temporary_dir(NULL);
1340 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1341 * so we provide the BPY_ function below to append the user defined
1342 * python-dir to Python's sys.path at this point. Simply putting
1343 * WM_init() before #BPY_python_start() crashes Blender at startup.
1346 // TODO - U.pythondir
1348 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1351 CTX_py_init_set(C, 1);
1354 /* OK we are ready for it */
1355 #ifndef WITH_PYTHON_MODULE
1356 BLI_argsParse(ba, 4, load_file, C);
1359 #ifndef WITH_PYTHON_MODULE
1365 free(argv[--argci]);
1371 #ifdef WITH_PYTHON_MODULE
1372 return 0; /* keep blender in background mode running */
1376 /* actually incorrect, but works for now (ton) */
1380 if ((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC)) {
1381 if (WM_init_game(C))
1384 else if (!G.file_loaded) {
1392 } /* end of int main(argc,argv) */
1394 #ifdef WITH_PYTHON_MODULE
1395 void main_python_exit(void)
1397 WM_exit((bContext *)evil_C);
1402 static void error_cb(const char *err)
1405 printf("%s\n", err); /* XXX do this in WM too */
1408 static void mem_error_cb(const char *errorStr)
1410 fputs(errorStr, stderr);
1414 static void setCallbacks(void)
1416 /* Error output from the alloc routines: */
1417 MEM_set_error_callback(mem_error_cb);
1422 BLI_setErrorCallBack(error_cb); /* */
1423 // XXX BLI_setInterruptCallBack(blender_test_break);