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 */
463 exit(0); /* 2.4x didn't do this */
469 static int prefsize(int argc, const char **argv, void *UNUSED(data))
471 int stax, stay, sizx, sizy;
474 fprintf(stderr, "-p requires four arguments\n");
478 stax = atoi(argv[1]);
479 stay = atoi(argv[2]);
480 sizx = atoi(argv[3]);
481 sizy = atoi(argv[4]);
483 WM_setprefsize(stax, stay, sizx, sizy);
488 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
490 WM_setinitialstate_normal();
494 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
496 WM_setinitialstate_fullscreen();
500 extern int wm_start_with_console; /* wm_init_exit.c */
501 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
503 wm_start_with_console = 1;
507 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
512 RegisterBlendExtension();
514 (void)data; /* unused */
519 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
521 #ifndef WITH_GAMEENGINE
524 SYS_SystemHandle *syshandle = data;
527 * don't initialize joysticks if user doesn't want to use joysticks
528 * failed joystick initialization delays over 5 seconds, before game engine start
530 SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
531 if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
537 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
539 GPU_extensions_disable();
543 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
545 sound_force_device(0);
549 static int set_audio(int argc, const char **argv, void *UNUSED(data))
552 fprintf(stderr, "-setaudio require one argument\n");
556 sound_force_device(sound_define_from_str(argv[1]));
560 static int set_output(int argc, const char **argv, void *data)
564 Scene *scene = CTX_data_scene(C);
566 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
569 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
574 printf("\nError: you must specify a path after '-o / --render-output'.\n");
579 static int set_engine(int argc, const char **argv, void *data)
583 if (!strcmp(argv[1], "help")) {
584 RenderEngineType *type = NULL;
585 printf("Blender Engine Listing:\n");
586 for (type = R_engines.first; type; type = type->next) {
587 printf("\t%s\n", type->idname);
592 Scene *scene = CTX_data_scene(C);
594 RenderData *rd = &scene->r;
596 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
597 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
601 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
608 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
613 static int set_image_type(int argc, const char **argv, void *data)
617 const char *imtype = argv[1];
618 Scene *scene = CTX_data_scene(C);
620 const char imtype_new = BKE_imtype_from_arg(imtype);
622 if (imtype_new == R_IMF_IMTYPE_INVALID) {
623 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
626 scene->r.im_format.imtype = imtype_new;
630 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
635 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
640 static int set_threads(int argc, const char **argv, void *UNUSED(data))
644 RE_set_max_threads(atoi(argv[1]));
647 printf("Warning: threads can only be set in background mode\n");
652 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
657 static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
660 int level = atoi(argv[1]);
663 libmv_setLoggingVerbosity(level);
671 printf("\nError: you must specify a verbosity level.\n");
676 static int set_extension(int argc, const char **argv, void *data)
680 Scene *scene = CTX_data_scene(C);
682 if (argv[1][0] == '0') {
683 scene->r.scemode &= ~R_EXTENSION;
685 else if (argv[1][0] == '1') {
686 scene->r.scemode |= R_EXTENSION;
689 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
693 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
698 printf("\nError: you must specify a path after '- '.\n");
703 static int set_ge_parameters(int argc, const char **argv, void *data)
706 #ifdef WITH_GAMEENGINE
707 SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
713 * gameengine parameters are automatically put into system
714 * -g [paramname = value]
718 * -g maxvertexarraysize = 512
722 const char *paramname = argv[a];
723 /* check for single value versus assignment */
724 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
729 #ifdef WITH_GAMEENGINE
730 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
734 printf("error: argument assignment (%s) without value.\n", paramname);
741 #ifdef WITH_GAMEENGINE
742 SYS_WriteCommandLineInt(syshandle, argv[a], 1);
745 if (!strcmp(argv[a], "nomipmap")) {
746 GPU_set_mipmap(0); //doMipMap = 0;
749 if (!strcmp(argv[a], "linearmipmap")) {
750 GPU_set_linear_mipmap(1); //linearMipMap = 1;
754 } /* if (*(argv[a+1]) == '=') */
760 static int render_frame(int argc, const char **argv, void *data)
763 Scene *scene = CTX_data_scene(C);
765 Main *bmain = CTX_data_main(C);
768 Render *re = RE_NewRender(scene->id.name);
774 frame = scene->r.sfra + atoi(argv[1] + 1);
777 frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
780 frame = atoi(argv[1]);
784 BKE_reports_init(&reports, RPT_PRINT);
786 frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
788 RE_SetReports(re, &reports);
789 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
790 RE_SetReports(re, NULL);
794 printf("\nError: frame number must follow '-f / --render-frame'.\n");
799 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
804 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
807 Scene *scene = CTX_data_scene(C);
809 Main *bmain = CTX_data_main(C);
810 Render *re = RE_NewRender(scene->id.name);
812 BKE_reports_init(&reports, RPT_PRINT);
813 RE_SetReports(re, &reports);
814 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
815 RE_SetReports(re, NULL);
818 printf("\nError: no blend loaded. cannot use '-a'.\n");
823 static int set_scene(int argc, const char **argv, void *data)
827 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
829 CTX_data_scene_set(C, scene);
834 printf("\nError: Scene name must follow '-S / --scene'.\n");
839 static int set_start_frame(int argc, const char **argv, void *data)
842 Scene *scene = CTX_data_scene(C);
845 int frame = atoi(argv[1]);
846 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
850 printf("\nError: frame number must follow '-s / --frame-start'.\n");
855 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
860 static int set_end_frame(int argc, const char **argv, void *data)
863 Scene *scene = CTX_data_scene(C);
866 int frame = atoi(argv[1]);
867 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
871 printf("\nError: frame number must follow '-e / --frame-end'.\n");
876 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
881 static int set_skip_frame(int argc, const char **argv, void *data)
884 Scene *scene = CTX_data_scene(C);
887 int frame = atoi(argv[1]);
888 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
892 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
897 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
902 /* macro for ugly context setup/reset */
904 #define BPY_CTX_SETUP(_cmd) \
906 wmWindowManager *wm = CTX_wm_manager(C); \
907 wmWindow *prevwin = CTX_wm_window(C); \
908 Scene *prevscene = CTX_data_scene(C); \
909 if (wm->windows.first) { \
910 CTX_wm_window_set(C, wm->windows.first); \
912 CTX_wm_window_set(C, prevwin); \
915 fprintf(stderr, "Python script \"%s\" " \
916 "running with missing context data.\n", argv[1]); \
919 CTX_data_scene_set(C, prevscene); \
922 #endif /* WITH_PYTHON */
924 static int run_python(int argc, const char **argv, void *data)
929 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
931 /* Make the path absolute because its needed for relative linked blends to be found */
932 char filename[FILE_MAX];
933 BLI_strncpy(filename, argv[1], sizeof(filename));
934 BLI_path_cwd(filename);
936 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
941 printf("\nError: you must specify a Python script after '-P / --python'.\n");
945 (void)argc; (void)argv; (void)data; /* unused */
946 printf("This blender was built without python support\n");
948 #endif /* WITH_PYTHON */
951 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
956 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
960 (void)argv; (void)data; /* unused */
961 printf("This blender was built without python support\n");
963 #endif /* WITH_PYTHON */
966 static int set_addons(int argc, const char **argv, void *data)
968 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
971 const int slen = strlen(argv[1]) + 128;
972 char *str = malloc(slen);
974 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
975 BPY_CTX_SETUP(BPY_string_exec(C, str));
978 (void)argv; (void)data; /* unused */
979 #endif /* WITH_PYTHON */
983 printf("\nError: you must specify a comma separated list after '--addons'.\n");
988 static int load_file(int UNUSED(argc), const char **argv, void *data)
992 /* Make the path absolute because its needed for relative linked blends to be found */
993 char filename[FILE_MAX];
995 /* note, we could skip these, but so far we always tried to load these files */
996 if (argv[0][0] == '-') {
997 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1000 BLI_strncpy(filename, argv[0], sizeof(filename));
1001 BLI_path_cwd(filename);
1004 int retval = BKE_read_file(C, filename, NULL);
1006 /* we successfully loaded a blend file, get sure that
1007 * pointcache works */
1008 if (retval != BKE_READ_FILE_FAIL) {
1009 wmWindowManager *wm = CTX_wm_manager(C);
1011 /* special case, 2.4x files */
1012 if (wm == NULL && CTX_data_main(C)->wm.first == NULL) {
1013 extern void wm_add_default(bContext *C);
1015 /* wm_add_default() needs the screen to be set. */
1016 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
1020 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1022 G.relbase_valid = 1;
1023 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
1025 DAG_on_visible_update(CTX_data_main(C), TRUE);
1028 /* failed to load file, stop processing arguments */
1032 /* WM_read_file() runs normally but since we're in background mode do here */
1034 /* run any texts that were loaded in and flagged as modules */
1036 BPY_app_handlers_reset(FALSE);
1037 BPY_modules_load_user(C);
1040 /* happens for the UI on file reading too (huh? (ton))*/
1041 // XXX BKE_reset_undo();
1042 // BKE_write_undo("original"); /* save current state */
1045 /* we are not running in background mode here, but start blender in UI mode with
1046 * a file - this should do everything a 'load file' does */
1048 BKE_reports_init(&reports, RPT_PRINT);
1049 WM_read_file(C, filename, &reports);
1050 BKE_reports_clear(&reports);
1058 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1060 static char output_doc[] = "<path>"
1061 "\n\tSet the render path and file name."
1062 "\n\tUse // at the start of the path to"
1063 "\n\t\trender relative to the blend file."
1064 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1065 "\n\t\tani_##_test.png becomes ani_01_test.png"
1066 "\n\t\ttest-######.png becomes test-000001.png"
1067 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1068 "\n\tThe frame number will be added at the end of the filename."
1069 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1070 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1072 static char format_doc[] = "<format>"
1073 "\n\tSet the render format, Valid options are..."
1074 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1075 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1076 "\n\t(formats that can be compiled into blender, not available on all systems)"
1077 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1079 static char playback_doc[] = "<options> <file(s)>"
1080 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1081 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1082 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1083 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1084 "\n\t\t-j <frame>\tSet frame step to <frame>";
1086 static char game_doc[] = "Game Engine specific options"
1087 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1088 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1089 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1090 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1092 static char debug_doc[] = "\n\tTurn debugging on\n"
1093 "\n\t* Prints every operator call and their arguments"
1094 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1095 "\n\t* Keeps python sys.stdin rather than setting it to None";
1097 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1099 /* end argument processing after -- */
1100 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1102 /* first pass: background mode, disable python and commands that exit after usage */
1103 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1105 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1107 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1109 /* only to give help message */
1110 #ifndef WITH_PYTHON_SECURITY /* default */
1111 # define PY_ENABLE_AUTO ", (default)"
1112 # define PY_DISABLE_AUTO ""
1114 # define PY_ENABLE_AUTO ""
1115 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1118 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1119 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1121 #undef PY_ENABLE_AUTO
1122 #undef PY_DISABLE_AUTO
1124 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1126 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1128 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1131 BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1133 BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1134 BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1135 BLI_argsAdd(ba, 1, NULL, "--debug-wm", "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1136 BLI_argsAdd(ba, 1, NULL, "--debug-all", "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1138 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1141 BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1144 BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1145 BLI_argsAdd(ba, 1, NULL, "--debug-jobs", "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1147 BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1149 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1151 /* TODO, add user env vars? */
1152 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1153 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1154 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1156 /* second pass: custom window stuff */
1157 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);
1158 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1159 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1160 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1161 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1162 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1164 /* third pass: disabling things and forcing settings */
1165 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1166 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1167 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1168 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1170 /* fourth pass: processing arguments */
1171 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1172 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);
1173 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1174 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1175 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1176 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1177 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1178 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1179 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1180 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1182 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1183 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1185 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1186 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);
1187 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);
1190 #endif /* WITH_PYTHON_MODULE */
1192 #ifdef WITH_PYTHON_MODULE
1193 /* allow python module to call main */
1194 # define main main_python_enter
1195 static void *evil_C = NULL;
1198 /* environ is not available in mac shared libraries */
1199 # include <crt_externs.h>
1200 char **environ = NULL;
1206 int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
1208 int main(int argc, const char **argv)
1211 bContext *C = CTX_create();
1212 SYS_SystemHandle syshandle;
1214 #ifndef WITH_PYTHON_MODULE
1219 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1221 char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
1222 for (argci = 0; argci < argc; argci++) {
1223 argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
1228 #ifdef WITH_PYTHON_MODULE
1230 environ = *_NSGetEnviron();
1239 #ifdef WITH_BINRELOC
1244 libmv_initLogging(argv[0]);
1248 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1249 /* patch to ignore argument finder gives us (pid?) */
1250 if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
1251 extern int GHOST_HACK_getFirstFile(char buf[]);
1252 static char firstfilebuf[512];
1256 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1258 argv[1] = firstfilebuf;
1268 /* initialize path to executable */
1269 BLI_init_program_path(argv[0]);
1271 BLI_threadapi_init();
1278 initglobals(); /* blender.c */
1282 BLI_callback_global_init();
1284 #ifdef WITH_GAMEENGINE
1285 syshandle = SYS_GetSystem();
1290 /* first test for background */
1291 #ifndef WITH_PYTHON_MODULE
1292 ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1293 setupArguments(C, ba, &syshandle);
1295 BLI_argsParse(ba, 1, NULL, NULL);
1298 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1299 G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */
1301 /* for all platforms, even windos has it! */
1302 if (G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1305 /* background render uses this font too */
1306 BKE_vfont_builtin_register(datatoc_Bfont, datatoc_Bfont_size);
1308 /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1309 * rendered via ffmpeg */
1312 init_def_material();
1314 if (G.background == 0) {
1315 #ifndef WITH_PYTHON_MODULE
1316 BLI_argsParse(ba, 2, NULL, NULL);
1317 BLI_argsParse(ba, 3, NULL, NULL);
1319 WM_init(C, argc, (const char **)argv);
1321 /* this is properly initialized with user defs, but this is default */
1322 /* call after loading the startup.blend so we can read U.tempdir */
1323 BLI_init_temporary_dir(U.tempdir);
1326 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1330 #ifndef WITH_PYTHON_MODULE
1331 BLI_argsParse(ba, 3, NULL, NULL);
1334 WM_init(C, argc, (const char **)argv);
1336 /* don't use user preferences temp dir */
1337 BLI_init_temporary_dir(NULL);
1341 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1342 * so we provide the BPY_ function below to append the user defined
1343 * python-dir to Python's sys.path at this point. Simply putting
1344 * WM_init() before #BPY_python_start() crashes Blender at startup.
1347 /* TODO - U.pythondir */
1349 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1352 CTX_py_init_set(C, 1);
1355 /* OK we are ready for it */
1356 #ifndef WITH_PYTHON_MODULE
1357 BLI_argsParse(ba, 4, load_file, C);
1360 #ifndef WITH_PYTHON_MODULE
1366 free(argv[--argci]);
1372 #ifdef WITH_PYTHON_MODULE
1373 return 0; /* keep blender in background mode running */
1377 /* actually incorrect, but works for now (ton) */
1381 if ((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC)) {
1382 if (WM_init_game(C))
1385 else if (!G.file_loaded) {
1393 } /* end of int main(argc,argv) */
1395 #ifdef WITH_PYTHON_MODULE
1396 void main_python_exit(void)
1398 WM_exit((bContext *)evil_C);
1403 static void error_cb(const char *err)
1406 printf("%s\n", err); /* XXX do this in WM too */
1409 static void mem_error_cb(const char *errorStr)
1411 fputs(errorStr, stderr);
1415 static void setCallbacks(void)
1417 /* Error output from the alloc routines: */
1418 MEM_set_error_callback(mem_error_cb);
1423 BLI_setErrorCallBack(error_cb); /* */
1424 // XXX BLI_setInterruptCallBack(blender_test_break);