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>
45 # include <process.h> /* getpid */
47 # include <unistd.h> /* getpid */
51 # include <execinfo.h>
64 /* This little block needed for linking to Blender... */
66 #include "MEM_guardedalloc.h"
69 # include "BLI_winstuff.h"
73 #include "BLI_threads.h"
74 #include "BLI_utildefines.h"
75 #include "BLI_callbacks.h"
78 #include "DNA_scene_types.h"
79 #include "DNA_userdef_types.h"
81 #include "BLI_blenlib.h"
83 #include "BKE_blender.h"
84 #include "BKE_context.h"
85 #include "BKE_depsgraph.h" /* for DAG_on_visible_update */
87 #include "BKE_global.h"
89 #include "BKE_material.h"
90 #include "BKE_packedFile.h"
91 #include "BKE_scene.h"
93 #include "BKE_report.h"
94 #include "BKE_sound.h"
95 #include "BKE_image.h"
97 #include "IMB_imbuf.h" /* for IMB_init */
100 #include "BPY_extern.h"
103 #include "RE_engine.h"
104 #include "RE_pipeline.h"
106 #include "ED_datafiles.h"
110 #include "RNA_define.h"
112 #include "GPU_draw.h"
113 #include "GPU_extensions.h"
115 #include "BLI_scanfill.h" /* for BLI_setErrorCallBack, TODO, move elsewhere */
117 #ifdef WITH_BUILDINFO_HEADER
121 /* for passing information between creator and gameengine */
122 #ifdef WITH_GAMEENGINE
123 # include "BL_System.h"
125 # define SYS_SystemHandle int
131 # include <sys/types.h>
132 # include <floatingpoint.h>
133 # include <sys/rtprio.h>
137 # include "binreloc.h"
141 # include "libmv-capi.h"
144 /* from buildinfo.c */
146 extern char build_date[];
147 extern char build_time[];
148 extern char build_rev[];
149 extern char build_platform[];
150 extern char build_type[];
151 extern char build_cflags[];
152 extern char build_cxxflags[];
153 extern char build_linkflags[];
154 extern char build_system[];
157 /* Local Function prototypes */
158 #ifndef WITH_PYTHON_MODULE
159 static int print_help(int argc, const char **argv, void *data);
160 static int print_version(int argc, const char **argv, void *data);
163 /* for the callbacks: */
165 #define BLEND_VERSION_STRING_FMT \
166 "Blender %d.%02d (sub %d)\n", \
167 BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION \
169 /* Initialize callbacks for the modules that need them */
170 static void setCallbacks(void);
172 static bool use_crash_handler = true;
174 #ifndef WITH_PYTHON_MODULE
176 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
177 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
178 static void fpe_handler(int UNUSED(sig))
180 // printf("SIGFPE trapped\n");
184 /* handling ctrl-c event in console */
185 static void blender_esc(int sig)
187 static int count = 0;
189 G.is_break = TRUE; /* forces render loop to read queue, not sure if its needed */
193 printf("\nBlender killed\n");
196 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
201 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
203 printf(BLEND_VERSION_STRING_FMT);
205 printf("\tbuild date: %s\n", build_date);
206 printf("\tbuild time: %s\n", build_time);
207 printf("\tbuild revision: %s\n", build_rev);
208 printf("\tbuild platform: %s\n", build_platform);
209 printf("\tbuild type: %s\n", build_type);
210 printf("\tbuild c flags: %s\n", build_cflags);
211 printf("\tbuild c++ flags: %s\n", build_cxxflags);
212 printf("\tbuild link flags: %s\n", build_linkflags);
213 printf("\tbuild system: %s\n", build_system);
220 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
222 bArgs *ba = (bArgs *)data;
224 printf(BLEND_VERSION_STRING_FMT);
225 printf("Usage: blender [args ...] [file] [args ...]\n\n");
227 printf("Render Options:\n");
228 BLI_argsPrintArgDoc(ba, "--background");
229 BLI_argsPrintArgDoc(ba, "--render-anim");
230 BLI_argsPrintArgDoc(ba, "--scene");
231 BLI_argsPrintArgDoc(ba, "--render-frame");
232 BLI_argsPrintArgDoc(ba, "--frame-start");
233 BLI_argsPrintArgDoc(ba, "--frame-end");
234 BLI_argsPrintArgDoc(ba, "--frame-jump");
235 BLI_argsPrintArgDoc(ba, "--render-output");
236 BLI_argsPrintArgDoc(ba, "--engine");
239 printf("Format Options:\n");
240 BLI_argsPrintArgDoc(ba, "--render-format");
241 BLI_argsPrintArgDoc(ba, "--use-extension");
242 BLI_argsPrintArgDoc(ba, "--threads");
245 printf("Animation Playback Options:\n");
246 BLI_argsPrintArgDoc(ba, "-a");
249 printf("Window Options:\n");
250 BLI_argsPrintArgDoc(ba, "--window-border");
251 BLI_argsPrintArgDoc(ba, "--window-borderless");
252 BLI_argsPrintArgDoc(ba, "--window-geometry");
253 BLI_argsPrintArgDoc(ba, "--start-console");
256 printf("Game Engine Specific Options:\n");
257 BLI_argsPrintArgDoc(ba, "-g");
260 printf("Misc Options:\n");
261 BLI_argsPrintArgDoc(ba, "--debug");
262 BLI_argsPrintArgDoc(ba, "--debug-fpe");
263 BLI_argsPrintArgDoc(ba, "--disable-crash-handler");
266 BLI_argsPrintArgDoc(ba, "--debug-ffmpeg");
270 BLI_argsPrintArgDoc(ba, "--debug-libmv");
274 BLI_argsPrintArgDoc(ba, "--factory-startup");
276 BLI_argsPrintArgDoc(ba, "--env-system-config");
277 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
278 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
279 BLI_argsPrintArgDoc(ba, "--env-system-python");
281 BLI_argsPrintArgDoc(ba, "-nojoystick");
282 BLI_argsPrintArgDoc(ba, "-noglsl");
283 BLI_argsPrintArgDoc(ba, "-noaudio");
284 BLI_argsPrintArgDoc(ba, "-setaudio");
288 BLI_argsPrintArgDoc(ba, "--help");
292 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
293 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
297 BLI_argsPrintArgDoc(ba, "--python");
298 BLI_argsPrintArgDoc(ba, "--python-console");
299 BLI_argsPrintArgDoc(ba, "--addons");
302 BLI_argsPrintArgDoc(ba, "-R");
303 BLI_argsPrintArgDoc(ba, "-r");
305 BLI_argsPrintArgDoc(ba, "--version");
307 BLI_argsPrintArgDoc(ba, "--");
309 printf("Other Options:\n");
310 BLI_argsPrintOtherDoc(ba);
312 printf("Argument Parsing:\n");
313 printf("\targuments must be separated by white space. eg\n");
314 printf("\t\t\"blender -ba test.blend\"\n");
315 printf("\t...will ignore the 'a'\n");
316 printf("\t\t\"blender -b test.blend -f8\"\n");
317 printf("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
319 printf("Argument Order:\n");
320 printf("Arguments are executed in the order they are given. eg\n");
321 printf("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
322 printf("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
323 printf("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
324 printf("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
325 printf("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
327 printf("\nEnvironment Variables:\n");
328 printf(" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
329 printf(" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
330 printf(" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
331 printf(" $Directory for user data files (icons, translations, ..).\n");
332 printf(" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
333 printf(" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
335 printf(" $TEMP Store temporary files here.\n");
337 printf(" $TMP or $TMPDIR Store temporary files here.\n");
340 printf(" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
342 printf(" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
349 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
354 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
356 G.f |= G_SCRIPT_AUTOEXEC;
357 G.f |= G_SCRIPT_OVERRIDE_PREF;
361 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
363 G.f &= ~G_SCRIPT_AUTOEXEC;
364 G.f |= G_SCRIPT_OVERRIDE_PREF;
368 static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
370 use_crash_handler = false;
374 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
380 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
382 G.debug |= G_DEBUG; /* std output printf's */
383 printf(BLEND_VERSION_STRING_FMT);
384 MEM_set_memory_debug();
386 #ifdef WITH_BUILDINFO
387 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
388 #endif // WITH_BUILDINFO
394 static int debug_mode_generic(int UNUSED(argc), const char **UNUSED(argv), void *data)
396 G.debug |= GET_INT_FROM_POINTER(data);
401 static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
403 libmv_startDebugLogging();
409 static int set_debug_value(int argc, const char **argv, void *UNUSED(data))
412 G.debug_value = atoi(argv[1]);
417 printf("\nError: you must specify debug value to set.\n");
422 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
424 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
425 /* zealous but makes float issues a heck of a lot easier to find!
426 * set breakpoints on fpe_handler */
427 signal(SIGFPE, fpe_handler);
429 # if defined(__linux__) && defined(__GNUC__)
430 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
431 # endif /* defined(__linux__) && defined(__GNUC__) */
432 # if defined(OSX_SSE_FPE)
433 /* OSX uses SSE for floating point by default, so here
434 * use SSE instructions to throw floating point exceptions */
435 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK & ~
436 (_MM_MASK_OVERFLOW | _MM_MASK_INVALID | _MM_MASK_DIV_ZERO));
437 # endif /* OSX_SSE_FPE */
438 # if defined(_WIN32) && defined(_MSC_VER)
439 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
440 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
441 # endif /* _WIN32 && _MSC_VER */
447 static void blender_crash_handler_backtrace(FILE *fp)
456 fputs("\n# backtrace\n", fp);
458 /* include a backtrace for good measure */
459 nptrs = backtrace(buffer, SIZE);
460 strings = backtrace_symbols(buffer, nptrs);
461 for (i = 0; i < nptrs; i++) {
462 fputs(strings[i], fp);
473 static void blender_crash_handler(int signum)
478 char fname[FILE_MAX];
480 if (!G.main->name[0]) {
481 BLI_make_file_string("/", fname, BLI_temporary_dir(), "crash.blend");
484 BLI_strncpy(fname, G.main->name, sizeof(fname));
485 BLI_replace_extension(fname, sizeof(fname), ".crash.blend");
488 printf("Writing: %s\n", fname);
491 BKE_undo_save_file(fname);
497 wmWindowManager *wm = G.main->wm.first;
499 char fname[FILE_MAX];
501 if (!G.main->name[0]) {
502 BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt");
505 BLI_strncpy(fname, G.main->name, sizeof(fname));
506 BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
509 printf("Writing: %s\n", fname);
512 BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT);
514 /* open the crash log */
516 fp = BLI_fopen(fname, "wb");
518 fprintf(stderr, "Unable to save '%s': %s\n",
519 fname, errno ? strerror(errno) : "Unknown error opening file");
522 BKE_report_write_file_fp(fp, &wm->reports, header);
524 blender_crash_handler_backtrace(fp);
531 signal(signum, SIG_DFL);
532 kill(getpid(), signum);
536 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
538 G.factory_startup = 1;
542 static int set_env(int argc, const char **argv, void *UNUSED(data))
544 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
546 char env[64] = "BLENDER";
547 char *ch_dst = env + 7; /* skip BLENDER */
548 const char *ch_src = argv[0] + 5; /* skip --env */
551 printf("%s requires one argument\n", argv[0]);
555 for (; *ch_src; ch_src++, ch_dst++) {
556 *ch_dst = (*ch_src == '-') ? '_' : (*ch_src) - 32; /* toupper() */
560 BLI_setenv(env, argv[1]);
564 static int playback_mode(int argc, const char **argv, void *UNUSED(data))
566 /* not if -b was given first */
567 if (G.background == 0) {
568 WM_main_playanim(argc, argv); /* not the same argc and argv as before */
569 exit(0); /* 2.4x didn't do this */
575 static int prefsize(int argc, const char **argv, void *UNUSED(data))
577 int stax, stay, sizx, sizy;
580 fprintf(stderr, "-p requires four arguments\n");
584 stax = atoi(argv[1]);
585 stay = atoi(argv[2]);
586 sizx = atoi(argv[3]);
587 sizy = atoi(argv[4]);
589 WM_init_state_size_set(stax, stay, sizx, sizy);
594 static int native_pixels(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
596 WM_init_native_pixels(0);
600 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
602 WM_init_state_normal_set();
606 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
608 WM_init_state_fullscreen_set();
612 extern int wm_start_with_console; /* wm_init_exit.c */
613 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
615 wm_start_with_console = 1;
619 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
624 RegisterBlendExtension();
626 (void)data; /* unused */
631 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
633 #ifndef WITH_GAMEENGINE
636 SYS_SystemHandle *syshandle = data;
639 * don't initialize joysticks if user doesn't want to use joysticks
640 * failed joystick initialization delays over 5 seconds, before game engine start
642 SYS_WriteCommandLineInt(*syshandle, "nojoystick", 1);
643 if (G.debug & G_DEBUG) printf("disabling nojoystick\n");
649 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
651 GPU_extensions_disable();
655 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
657 sound_force_device(0);
661 static int set_audio(int argc, const char **argv, void *UNUSED(data))
664 fprintf(stderr, "-setaudio require one argument\n");
668 sound_force_device(sound_define_from_str(argv[1]));
672 static int set_output(int argc, const char **argv, void *data)
676 Scene *scene = CTX_data_scene(C);
678 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
681 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
686 printf("\nError: you must specify a path after '-o / --render-output'.\n");
691 static int set_engine(int argc, const char **argv, void *data)
695 if (!strcmp(argv[1], "help")) {
696 RenderEngineType *type = NULL;
697 printf("Blender Engine Listing:\n");
698 for (type = R_engines.first; type; type = type->next) {
699 printf("\t%s\n", type->idname);
704 Scene *scene = CTX_data_scene(C);
706 RenderData *rd = &scene->r;
708 if (BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
709 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
713 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
720 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
725 static int set_image_type(int argc, const char **argv, void *data)
729 const char *imtype = argv[1];
730 Scene *scene = CTX_data_scene(C);
732 const char imtype_new = BKE_imtype_from_arg(imtype);
734 if (imtype_new == R_IMF_IMTYPE_INVALID) {
735 printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
738 scene->r.im_format.imtype = imtype_new;
742 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
747 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
752 static int set_threads(int argc, const char **argv, void *UNUSED(data))
756 RE_set_max_threads(atoi(argv[1]));
759 printf("Warning: threads can only be set in background mode\n");
764 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
769 static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
772 int level = atoi(argv[1]);
775 libmv_setLoggingVerbosity(level);
783 printf("\nError: you must specify a verbosity level.\n");
788 static int set_extension(int argc, const char **argv, void *data)
792 Scene *scene = CTX_data_scene(C);
794 if (argv[1][0] == '0') {
795 scene->r.scemode &= ~R_EXTENSION;
797 else if (argv[1][0] == '1') {
798 scene->r.scemode |= R_EXTENSION;
801 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
805 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
810 printf("\nError: you must specify a path after '- '.\n");
815 static int set_ge_parameters(int argc, const char **argv, void *data)
818 #ifdef WITH_GAMEENGINE
819 SYS_SystemHandle syshandle = *(SYS_SystemHandle *)data;
825 * gameengine parameters are automatically put into system
826 * -g [paramname = value]
830 * -g maxvertexarraysize = 512
834 const char *paramname = argv[a];
835 /* check for single value versus assignment */
836 if (a + 1 < argc && (*(argv[a + 1]) == '=')) {
841 #ifdef WITH_GAMEENGINE
842 SYS_WriteCommandLineString(syshandle, paramname, argv[a]);
846 printf("error: argument assignment (%s) without value.\n", paramname);
853 #ifdef WITH_GAMEENGINE
854 SYS_WriteCommandLineInt(syshandle, argv[a], 1);
857 if (!strcmp(argv[a], "nomipmap")) {
858 GPU_set_mipmap(0); //doMipMap = 0;
861 if (!strcmp(argv[a], "linearmipmap")) {
862 GPU_set_linear_mipmap(1); //linearMipMap = 1;
866 } /* if (*(argv[a+1]) == '=') */
872 static int render_frame(int argc, const char **argv, void *data)
875 Scene *scene = CTX_data_scene(C);
877 Main *bmain = CTX_data_main(C);
880 Render *re = RE_NewRender(scene->id.name);
886 frame = scene->r.sfra + atoi(argv[1] + 1);
889 frame = (scene->r.efra - atoi(argv[1] + 1)) + 1;
892 frame = atoi(argv[1]);
896 BKE_reports_init(&reports, RPT_PRINT);
898 frame = CLAMPIS(frame, MINAFRAME, MAXFRAME);
900 RE_SetReports(re, &reports);
901 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
902 RE_SetReports(re, NULL);
906 printf("\nError: frame number must follow '-f / --render-frame'.\n");
911 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
916 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
919 Scene *scene = CTX_data_scene(C);
921 Main *bmain = CTX_data_main(C);
922 Render *re = RE_NewRender(scene->id.name);
924 BKE_reports_init(&reports, RPT_PRINT);
925 RE_SetReports(re, &reports);
926 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
927 RE_SetReports(re, NULL);
930 printf("\nError: no blend loaded. cannot use '-a'.\n");
935 static int set_scene(int argc, const char **argv, void *data)
939 Scene *scene = BKE_scene_set_name(CTX_data_main(C), argv[1]);
941 CTX_data_scene_set(C, scene);
946 printf("\nError: Scene name must follow '-S / --scene'.\n");
951 static int set_start_frame(int argc, const char **argv, void *data)
954 Scene *scene = CTX_data_scene(C);
957 int frame = atoi(argv[1]);
958 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
962 printf("\nError: frame number must follow '-s / --frame-start'.\n");
967 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
972 static int set_end_frame(int argc, const char **argv, void *data)
975 Scene *scene = CTX_data_scene(C);
978 int frame = atoi(argv[1]);
979 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
983 printf("\nError: frame number must follow '-e / --frame-end'.\n");
988 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
993 static int set_skip_frame(int argc, const char **argv, void *data)
996 Scene *scene = CTX_data_scene(C);
999 int frame = atoi(argv[1]);
1000 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
1004 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
1009 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
1014 /* macro for ugly context setup/reset */
1016 #define BPY_CTX_SETUP(_cmd) \
1018 wmWindowManager *wm = CTX_wm_manager(C); \
1019 wmWindow *prevwin = CTX_wm_window(C); \
1020 Scene *prevscene = CTX_data_scene(C); \
1021 if (wm->windows.first) { \
1022 CTX_wm_window_set(C, wm->windows.first); \
1024 CTX_wm_window_set(C, prevwin); \
1027 fprintf(stderr, "Python script \"%s\" " \
1028 "running with missing context data.\n", argv[1]); \
1031 CTX_data_scene_set(C, prevscene); \
1034 #endif /* WITH_PYTHON */
1036 static int run_python(int argc, const char **argv, void *data)
1041 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1043 /* Make the path absolute because its needed for relative linked blends to be found */
1044 char filename[FILE_MAX];
1045 BLI_strncpy(filename, argv[1], sizeof(filename));
1046 BLI_path_cwd(filename);
1048 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
1053 printf("\nError: you must specify a Python script after '-P / --python'.\n");
1057 (void)argc; (void)argv; (void)data; /* unused */
1058 printf("This blender was built without python support\n");
1060 #endif /* WITH_PYTHON */
1063 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
1068 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
1072 (void)argv; (void)data; /* unused */
1073 printf("This blender was built without python support\n");
1075 #endif /* WITH_PYTHON */
1078 static int set_addons(int argc, const char **argv, void *data)
1080 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
1083 const int slen = strlen(argv[1]) + 128;
1084 char *str = malloc(slen);
1086 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
1087 BPY_CTX_SETUP(BPY_string_exec(C, str));
1090 (void)argv; (void)data; /* unused */
1091 #endif /* WITH_PYTHON */
1095 printf("\nError: you must specify a comma separated list after '--addons'.\n");
1100 static int load_file(int UNUSED(argc), const char **argv, void *data)
1104 /* Make the path absolute because its needed for relative linked blends to be found */
1105 char filename[FILE_MAX];
1107 /* note, we could skip these, but so far we always tried to load these files */
1108 if (argv[0][0] == '-') {
1109 fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]);
1112 BLI_strncpy(filename, argv[0], sizeof(filename));
1113 BLI_path_cwd(filename);
1116 int retval = BKE_read_file(C, filename, NULL);
1118 /* we successfully loaded a blend file, get sure that
1119 * pointcache works */
1120 if (retval != BKE_READ_FILE_FAIL) {
1121 wmWindowManager *wm = CTX_wm_manager(C);
1123 /* special case, 2.4x files */
1124 if (wm == NULL && CTX_data_main(C)->wm.first == NULL) {
1125 extern void wm_add_default(bContext *C);
1127 /* wm_add_default() needs the screen to be set. */
1128 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
1132 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
1134 G.relbase_valid = 1;
1135 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
1137 DAG_on_visible_update(CTX_data_main(C), TRUE);
1140 /* failed to load file, stop processing arguments */
1144 /* WM_file_read() runs normally but since we're in background mode do here */
1146 /* run any texts that were loaded in and flagged as modules */
1148 BPY_app_handlers_reset(FALSE);
1149 BPY_modules_load_user(C);
1152 /* happens for the UI on file reading too (huh? (ton))*/
1153 // XXX BKE_reset_undo();
1154 // BKE_write_undo("original"); /* save current state */
1157 /* we are not running in background mode here, but start blender in UI mode with
1158 * a file - this should do everything a 'load file' does */
1160 BKE_reports_init(&reports, RPT_PRINT);
1161 WM_file_read(C, filename, &reports);
1162 BKE_reports_clear(&reports);
1170 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1172 static char output_doc[] = "<path>"
1173 "\n\tSet the render path and file name."
1174 "\n\tUse // at the start of the path to"
1175 "\n\t\trender relative to the blend file."
1176 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1177 "\n\t\tani_##_test.png becomes ani_01_test.png"
1178 "\n\t\ttest-######.png becomes test-000001.png"
1179 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1180 "\n\tThe frame number will be added at the end of the filename."
1181 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1182 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1184 static char format_doc[] = "<format>"
1185 "\n\tSet the render format, Valid options are..."
1186 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1187 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1188 "\n\t(formats that can be compiled into blender, not available on all systems)"
1189 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1191 static char playback_doc[] = "<options> <file(s)>"
1192 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1193 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1194 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1195 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1196 "\n\t\t-j <frame>\tSet frame step to <frame>"
1197 "\n\t\t-s <frame>\tPlay from <frame>"
1198 "\n\t\t-e <frame>\tPlay until <frame>";
1200 static char game_doc[] = "Game Engine specific options"
1201 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1202 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1203 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1204 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1206 static char debug_doc[] = "\n\tTurn debugging on\n"
1207 "\n\t* Prints every operator call and their arguments"
1208 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1209 "\n\t* Keeps python sys.stdin rather than setting it to None";
1211 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1213 /* end argument processing after -- */
1214 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1216 /* first pass: background mode, disable python and commands that exit after usage */
1217 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1219 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1221 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1223 /* only to give help message */
1224 #ifndef WITH_PYTHON_SECURITY /* default */
1225 # define PY_ENABLE_AUTO ", (default)"
1226 # define PY_DISABLE_AUTO ""
1228 # define PY_ENABLE_AUTO ""
1229 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1232 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1233 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL);
1235 BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL);
1237 #undef PY_ENABLE_AUTO
1238 #undef PY_DISABLE_AUTO
1240 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1242 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1244 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1247 BLI_argsAdd(ba, 1, NULL, "--debug-ffmpeg", "\n\tEnable debug messages from FFmpeg library", debug_mode_generic, (void *)G_DEBUG_FFMPEG);
1249 BLI_argsAdd(ba, 1, NULL, "--debug-python", "\n\tEnable debug messages for python", debug_mode_generic, (void *)G_DEBUG_PYTHON);
1250 BLI_argsAdd(ba, 1, NULL, "--debug-events", "\n\tEnable debug messages for the event system", debug_mode_generic, (void *)G_DEBUG_EVENTS);
1251 BLI_argsAdd(ba, 1, NULL, "--debug-handlers", "\n\tEnable debug messages for event handling", debug_mode_generic, (void *)G_DEBUG_HANDLERS);
1252 BLI_argsAdd(ba, 1, NULL, "--debug-wm", "\n\tEnable debug messages for the window manager", debug_mode_generic, (void *)G_DEBUG_WM);
1253 BLI_argsAdd(ba, 1, NULL, "--debug-all", "\n\tEnable all debug messages (excludes libmv)", debug_mode_generic, (void *)G_DEBUG_ALL);
1255 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1258 BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
1261 BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
1262 BLI_argsAdd(ba, 1, NULL, "--debug-jobs", "\n\tEnable time profiling for background jobs.", debug_mode_generic, (void *)G_DEBUG_JOBS);
1264 BLI_argsAdd(ba, 1, NULL, "--verbose", "<verbose>\n\tSet logging verbosity level.", set_verbosity, NULL);
1266 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY (BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1268 /* TODO, add user env vars? */
1269 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1270 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1271 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG (BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1273 /* second pass: custom window stuff */
1274 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);
1275 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1276 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1277 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1278 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1279 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1280 BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", "\n\tDo not use native pixel size, for high resolution displays (MacBook 'Retina')", native_pixels, ba);
1282 /* third pass: disabling things and forcing settings */
1283 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1284 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1285 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1286 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1288 /* fourth pass: processing arguments */
1289 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1290 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);
1291 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1292 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1293 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1294 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1295 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1296 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1297 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1298 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1300 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1301 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1303 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1304 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);
1305 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);
1308 #endif /* WITH_PYTHON_MODULE */
1310 #ifdef WITH_PYTHON_MODULE
1311 /* allow python module to call main */
1312 # define main main_python_enter
1313 static void *evil_C = NULL;
1316 /* environ is not available in mac shared libraries */
1317 # include <crt_externs.h>
1318 char **environ = NULL;
1324 int main(int argc, const char **UNUSED(argv_c)) /* Do not mess with const */
1326 int main(int argc, const char **argv)
1329 bContext *C = CTX_create();
1330 SYS_SystemHandle syshandle;
1332 #ifndef WITH_PYTHON_MODULE
1337 wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
1339 char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
1340 for (argci = 0; argci < argc; argci++) {
1341 argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
1346 #ifdef WITH_PYTHON_MODULE
1348 environ = *_NSGetEnviron();
1357 #ifdef WITH_BINRELOC
1362 libmv_initLogging(argv[0]);
1366 #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
1367 /* patch to ignore argument finder gives us (pid?) */
1368 if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
1369 extern int GHOST_HACK_getFirstFile(char buf[]);
1370 static char firstfilebuf[512];
1374 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1376 argv[1] = firstfilebuf;
1386 /* initialize path to executable */
1387 BLI_init_program_path(argv[0]);
1389 BLI_threadapi_init();
1391 initglobals(); /* blender.c */
1400 BLI_callback_global_init();
1402 #ifdef WITH_GAMEENGINE
1403 syshandle = SYS_GetSystem();
1408 /* first test for background */
1409 #ifndef WITH_PYTHON_MODULE
1410 ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
1411 setupArguments(C, ba, &syshandle);
1413 BLI_argsParse(ba, 1, NULL, NULL);
1416 if (use_crash_handler) {
1417 /* after parsing args */
1418 signal(SIGSEGV, blender_crash_handler);
1421 /* after level 1 args, this is so playanim skips RNA init */
1426 /* end second init */
1429 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1430 G.background = 1; /* python module mode ALWAYS runs in background mode (for now) */
1432 /* for all platforms, even windos has it! */
1433 if (G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1436 /* background render uses this font too */
1437 BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);
1439 /* Initialize ffmpeg if built in, also needed for bg mode if videos are
1440 * rendered via ffmpeg */
1443 init_def_material();
1445 if (G.background == 0) {
1446 #ifndef WITH_PYTHON_MODULE
1447 BLI_argsParse(ba, 2, NULL, NULL);
1448 BLI_argsParse(ba, 3, NULL, NULL);
1450 WM_init(C, argc, (const char **)argv);
1452 /* this is properly initialized with user defs, but this is default */
1453 /* call after loading the startup.blend so we can read U.tempdir */
1454 BLI_init_temporary_dir(U.tempdir);
1457 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1461 #ifndef WITH_PYTHON_MODULE
1462 BLI_argsParse(ba, 3, NULL, NULL);
1465 WM_init(C, argc, (const char **)argv);
1467 /* don't use user preferences temp dir */
1468 BLI_init_temporary_dir(NULL);
1472 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1473 * so we provide the BPY_ function below to append the user defined
1474 * python-dir to Python's sys.path at this point. Simply putting
1475 * WM_init() before #BPY_python_start() crashes Blender at startup.
1478 /* TODO - U.pythondir */
1480 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1483 CTX_py_init_set(C, 1);
1486 /* OK we are ready for it */
1487 #ifndef WITH_PYTHON_MODULE
1488 BLI_argsParse(ba, 4, load_file, C);
1491 #ifndef WITH_PYTHON_MODULE
1497 free(argv[--argci]);
1503 #ifdef WITH_PYTHON_MODULE
1504 return 0; /* keep blender in background mode running */
1508 /* actually incorrect, but works for now (ton) */
1512 if ((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC)) {
1513 if (WM_init_game(C))
1516 else if (!G.file_loaded) {
1524 } /* end of int main(argc, argv) */
1526 #ifdef WITH_PYTHON_MODULE
1527 void main_python_exit(void)
1529 WM_exit((bContext *)evil_C);
1534 static void error_cb(const char *err)
1537 printf("%s\n", err); /* XXX do this in WM too */
1540 static void mem_error_cb(const char *errorStr)
1542 fputs(errorStr, stderr);
1546 static void setCallbacks(void)
1548 /* Error output from the alloc routines: */
1549 MEM_set_error_callback(mem_error_cb);
1554 BLI_setErrorCallBack(error_cb); /* */
1555 // XXX BLI_setInterruptCallBack(blender_test_break);