4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 /** \file creator/creator.c
35 #if defined(__linux__) && defined(__GNUC__)
40 #if (defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)))
42 #include <xmmintrin.h>
49 /* for setuid / getuid */
51 #include <sys/types.h>
55 /* This little block needed for linking to Blender... */
57 #include "MEM_guardedalloc.h"
60 #include "BLI_winstuff.h"
64 #include "BLI_threads.h"
65 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
66 #include "BLI_utildefines.h"
67 #include "BLI_callbacks.h"
70 #include "DNA_scene_types.h"
72 #include "BLI_blenlib.h"
74 #include "BKE_utildefines.h"
75 #include "BKE_blender.h"
76 #include "BKE_context.h"
77 #include "BKE_depsgraph.h" // for DAG_on_visible_update
79 #include "BKE_global.h"
81 #include "BKE_material.h"
82 #include "BKE_packedFile.h"
83 #include "BKE_scene.h"
85 #include "BKE_report.h"
86 #include "BKE_sound.h"
88 #include "IMB_imbuf.h" // for IMB_init
91 #include "BPY_extern.h"
94 #include "RE_pipeline.h"
96 //XXX #include "playanim_ext.h"
97 #include "ED_datafiles.h"
101 #include "RNA_define.h"
103 #include "GPU_draw.h"
104 #include "GPU_extensions.h"
106 #ifdef WITH_BUILDINFO_HEADER
110 /* for passing information between creator and gameengine */
111 #ifdef WITH_GAMEENGINE
112 #include "BL_System.h"
114 #define SYS_SystemHandle int
120 # include <sys/types.h>
121 # include <floatingpoint.h>
122 # include <sys/rtprio.h>
126 #include "binreloc.h"
131 extern char build_date[];
132 extern char build_time[];
133 extern char build_rev[];
134 extern char build_platform[];
135 extern char build_type[];
136 extern char build_cflags[];
137 extern char build_cxxflags[];
138 extern char build_linkflags[];
139 extern char build_system[];
142 /* Local Function prototypes */
143 static int print_help(int argc, const char **argv, void *data);
144 static int print_version(int argc, const char **argv, void *data);
146 /* for the callbacks: */
148 extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */
150 char bprogname[FILE_MAX]; /* from blenpluginapi:pluginapi.c */
151 char btempdir[FILE_MAX];
153 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
155 /* Initialize callbacks for the modules that need them */
156 static void setCallbacks(void);
158 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
159 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
160 static void fpe_handler(int UNUSED(sig))
162 // printf("SIGFPE trapped\n");
166 #ifndef WITH_PYTHON_MODULE
167 /* handling ctrl-c event in console */
168 static void blender_esc(int sig)
170 static int count = 0;
172 G.afbreek = 1; /* forces render loop to read queue, not sure if its needed */
176 printf("\nBlender killed\n");
179 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
185 /* buildinfo can have quotes */
187 static void strip_quotes(char *str)
190 int len= strlen(str) - 1;
191 memmove(str, str+1, len);
192 if(str[len-1] == '"') {
199 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
201 printf (BLEND_VERSION_STRING_FMT);
203 printf ("\tbuild date: %s\n", build_date);
204 printf ("\tbuild time: %s\n", build_time);
205 printf ("\tbuild revision: %s\n", build_rev);
206 printf ("\tbuild platform: %s\n", build_platform);
207 printf ("\tbuild type: %s\n", build_type);
208 printf ("\tbuild c flags: %s\n", build_cflags);
209 printf ("\tbuild c++ flags: %s\n", build_cxxflags);
210 printf ("\tbuild link flags: %s\n", build_linkflags);
211 printf ("\tbuild system: %s\n", build_system);
218 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
220 bArgs *ba = (bArgs*)data;
222 printf (BLEND_VERSION_STRING_FMT);
223 printf ("Usage: blender [args ...] [file] [args ...]\n\n");
225 printf ("Render Options:\n");
226 BLI_argsPrintArgDoc(ba, "--background");
227 BLI_argsPrintArgDoc(ba, "--render-anim");
228 BLI_argsPrintArgDoc(ba, "--scene");
229 BLI_argsPrintArgDoc(ba, "--render-frame");
230 BLI_argsPrintArgDoc(ba, "--frame-start");
231 BLI_argsPrintArgDoc(ba, "--frame-end");
232 BLI_argsPrintArgDoc(ba, "--frame-jump");
233 BLI_argsPrintArgDoc(ba, "--render-output");
234 BLI_argsPrintArgDoc(ba, "--engine");
237 printf ("Format Options:\n");
238 BLI_argsPrintArgDoc(ba, "--render-format");
239 BLI_argsPrintArgDoc(ba, "--use-extension");
240 BLI_argsPrintArgDoc(ba, "--threads");
243 printf ("Animation Playback Options:\n");
244 BLI_argsPrintArgDoc(ba, "-a");
247 printf ("Window Options:\n");
248 BLI_argsPrintArgDoc(ba, "--window-border");
249 BLI_argsPrintArgDoc(ba, "--window-borderless");
250 BLI_argsPrintArgDoc(ba, "--window-geometry");
251 BLI_argsPrintArgDoc(ba, "--start-console");
254 printf ("Game Engine Specific Options:\n");
255 BLI_argsPrintArgDoc(ba, "-g");
258 printf ("Misc Options:\n");
259 BLI_argsPrintArgDoc(ba, "--debug");
260 BLI_argsPrintArgDoc(ba, "--debug-fpe");
262 BLI_argsPrintArgDoc(ba, "--factory-startup");
264 BLI_argsPrintArgDoc(ba, "--env-system-config");
265 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
266 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
267 BLI_argsPrintArgDoc(ba, "--env-system-plugins");
268 BLI_argsPrintArgDoc(ba, "--env-system-python");
270 BLI_argsPrintArgDoc(ba, "-nojoystick");
271 BLI_argsPrintArgDoc(ba, "-noglsl");
272 BLI_argsPrintArgDoc(ba, "-noaudio");
273 BLI_argsPrintArgDoc(ba, "-setaudio");
277 BLI_argsPrintArgDoc(ba, "--help");
281 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
282 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
286 BLI_argsPrintArgDoc(ba, "--python");
287 BLI_argsPrintArgDoc(ba, "--python-console");
288 BLI_argsPrintArgDoc(ba, "--addons");
291 BLI_argsPrintArgDoc(ba, "-R");
292 BLI_argsPrintArgDoc(ba, "-r");
294 BLI_argsPrintArgDoc(ba, "--version");
296 BLI_argsPrintArgDoc(ba, "--");
298 printf ("Other Options:\n");
299 BLI_argsPrintOtherDoc(ba);
301 printf ("Argument Parsing:\n");
302 printf ("\targuments must be separated by white space. eg\n");
303 printf ("\t\t\"blender -ba test.blend\"\n");
304 printf ("\t...will ignore the 'a'\n");
305 printf ("\t\t\"blender -b test.blend -f8\"\n");
306 printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
308 printf ("Argument Order:\n");
309 printf ("Arguments are executed in the order they are given. eg\n");
310 printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
311 printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
312 printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
313 printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
314 printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
316 printf ("\nEnvironment Variables:\n");
317 printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
318 printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
319 printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
320 printf (" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
321 printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
322 printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
324 printf (" $TEMP Store temporary files here.\n");
326 printf (" $TMP or $TMPDIR Store temporary files here.\n");
329 printf (" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
331 printf (" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
339 double PIL_check_seconds_timer(void);
341 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
346 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
348 G.f |= G_SCRIPT_AUTOEXEC;
349 G.f |= G_SCRIPT_OVERRIDE_PREF;
353 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
355 G.f &= ~G_SCRIPT_AUTOEXEC;
356 G.f |= G_SCRIPT_OVERRIDE_PREF;
360 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
366 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
368 G.f |= G_DEBUG; /* std output printf's */
369 printf(BLEND_VERSION_STRING_FMT);
370 MEM_set_memory_debug();
373 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
374 #endif // NAN_BUILDINFO
380 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
382 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
383 /* zealous but makes float issues a heck of a lot easier to find!
384 * set breakpoints on fpe_handler */
385 signal(SIGFPE, fpe_handler);
387 # if defined(__linux__) && defined(__GNUC__)
388 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
389 # endif /* defined(__linux__) && defined(__GNUC__) */
390 # if defined(OSX_SSE_FPE)
391 /* OSX uses SSE for floating point by default, so here
392 * use SSE instructions to throw floating point exceptions */
393 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
394 (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
395 # endif /* OSX_SSE_FPE */
396 # if defined(_WIN32) && defined(_MSC_VER)
397 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
398 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
399 # endif /* _WIN32 && _MSC_VER */
405 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
407 G.factory_startup= 1;
411 static int set_env(int argc, const char **argv, void *UNUSED(data))
413 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
415 char env[64]= "BLENDER";
416 char *ch_dst= env + 7; /* skip BLENDER */
417 const char *ch_src= argv[0] + 5; /* skip --env */
420 printf("%s requires one argument\n", argv[0]);
424 for(; *ch_src; ch_src++, ch_dst++) {
425 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
429 BLI_setenv(env, argv[1]);
433 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
435 /* not if -b was given first */
436 if (G.background == 0) {
438 // XXX playanim(argc, argv); /* not the same argc and argv as before */
445 static int prefsize(int argc, const char **argv, void *UNUSED(data))
447 int stax, stay, sizx, sizy;
450 printf ("-p requires four arguments\n");
459 WM_setprefsize(stax, stay, sizx, sizy);
464 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
466 WM_setinitialstate_normal();
470 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
472 WM_setinitialstate_fullscreen();
476 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
477 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
479 wm_start_with_console = 1;
483 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
488 RegisterBlendExtension();
490 (void)data; /* unused */
495 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
497 #ifndef WITH_GAMEENGINE
500 SYS_SystemHandle *syshandle = data;
503 don't initialize joysticks if user doesn't want to use joysticks
504 failed joystick initialization delays over 5 seconds, before game engine start
506 SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
507 if (G.f & G_DEBUG) printf("disabling nojoystick\n");
513 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
515 GPU_extensions_disable();
519 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
521 sound_force_device(0);
525 static int set_audio(int argc, const char **argv, void *UNUSED(data))
528 printf("-setaudio require one argument\n");
532 sound_force_device(sound_define_from_str(argv[1]));
536 static int set_output(int argc, const char **argv, void *data)
540 if (CTX_data_scene(C)) {
541 Scene *scene= CTX_data_scene(C);
542 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
544 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
548 printf("\nError: you must specify a path after '-o / --render-output'.\n");
553 static int set_engine(int argc, const char **argv, void *data)
558 if (!strcmp(argv[1],"help"))
560 RenderEngineType *type = NULL;
562 for( type = R_engines.first; type; type = type->next )
564 printf("\t%s\n", type->idname);
570 if (CTX_data_scene(C)==NULL)
572 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
575 Scene *scene= CTX_data_scene(C);
576 RenderData *rd = &scene->r;
578 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
579 BLI_strncpy(rd->engine, argv[1], sizeof(rd->engine));
588 printf("\nEngine not specified.\n");
593 static int set_image_type(int argc, const char **argv, void *data)
597 const char *imtype = argv[1];
598 if (CTX_data_scene(C)==NULL) {
599 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
601 Scene *scene= CTX_data_scene(C);
602 if (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
603 else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
605 else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
607 else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
608 else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
609 else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
610 else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
611 else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
612 else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
613 else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
614 else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
615 else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
617 else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
620 else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
623 else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
624 else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
626 else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
627 else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
629 else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
630 else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
633 else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
635 else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
639 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
644 static int set_threads(int argc, const char **argv, void *UNUSED(data))
648 RE_set_max_threads(atoi(argv[1]));
650 printf("Warning: threads can only be set in background mode\n");
654 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
659 static int set_extension(int argc, const char **argv, void *data)
663 if (CTX_data_scene(C)) {
664 Scene *scene= CTX_data_scene(C);
665 if (argv[1][0] == '0') {
666 scene->r.scemode &= ~R_EXTENSION;
667 } else if (argv[1][0] == '1') {
668 scene->r.scemode |= R_EXTENSION;
670 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
673 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
677 printf("\nError: you must specify a path after '- '.\n");
682 static int set_ge_parameters(int argc, const char **argv, void *data)
685 #ifdef WITH_GAMEENGINE
686 SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
692 gameengine parameters are automaticly put into system
693 -g [paramname = value]
697 -g maxvertexarraysize = 512
702 const char *paramname = argv[a];
703 /* check for single value versus assignment */
704 if (a+1 < argc && (*(argv[a+1]) == '='))
711 #ifdef WITH_GAMEENGINE
712 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
716 printf("error: argument assignment (%s) without value.\n",paramname);
722 #ifdef WITH_GAMEENGINE
723 SYS_WriteCommandLineInt(syshandle,argv[a],1);
726 if (!strcmp(argv[a],"nomipmap"))
728 GPU_set_mipmap(0); //doMipMap = 0;
731 if (!strcmp(argv[a],"linearmipmap"))
733 GPU_set_linear_mipmap(1); //linearMipMap = 1;
737 } /* if (*(argv[a+1]) == '=') */
743 static int render_frame(int argc, const char **argv, void *data)
746 if (CTX_data_scene(C)) {
747 Main *bmain= CTX_data_main(C);
748 Scene *scene= CTX_data_scene(C);
751 Render *re = RE_NewRender(scene->id.name);
757 frame= scene->r.sfra + atoi(argv[1]+1);
760 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
763 frame= atoi(argv[1]);
767 BKE_reports_init(&reports, RPT_PRINT);
769 frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
771 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step, &reports);
774 printf("\nError: frame number must follow '-f / --render-frame'.\n");
778 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
783 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
786 if (CTX_data_scene(C)) {
787 Main *bmain= CTX_data_main(C);
788 Scene *scene= CTX_data_scene(C);
789 Render *re= RE_NewRender(scene->id.name);
791 BKE_reports_init(&reports, RPT_PRINT);
792 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step, &reports);
794 printf("\nError: no blend loaded. cannot use '-a'.\n");
799 static int set_scene(int argc, const char **argv, void *data)
803 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
805 CTX_data_scene_set(C, sce);
809 printf("\nError: Scene name must follow '-S / --scene'.\n");
814 static int set_start_frame(int argc, const char **argv, void *data)
817 if (CTX_data_scene(C)) {
818 Scene *scene= CTX_data_scene(C);
820 int frame = atoi(argv[1]);
821 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
824 printf("\nError: frame number must follow '-s / --frame-start'.\n");
828 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
833 static int set_end_frame(int argc, const char **argv, void *data)
836 if (CTX_data_scene(C)) {
837 Scene *scene= CTX_data_scene(C);
839 int frame = atoi(argv[1]);
840 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
843 printf("\nError: frame number must follow '-e / --frame-end'.\n");
847 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
852 static int set_skip_frame(int argc, const char **argv, void *data)
855 if (CTX_data_scene(C)) {
856 Scene *scene= CTX_data_scene(C);
858 int frame = atoi(argv[1]);
859 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
862 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
866 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
871 /* macro for ugly context setup/reset */
873 #define BPY_CTX_SETUP(_cmd) \
875 wmWindowManager *wm= CTX_wm_manager(C); \
876 wmWindow *prevwin= CTX_wm_window(C); \
877 Scene *prevscene= CTX_data_scene(C); \
878 if(wm->windows.first) { \
879 CTX_wm_window_set(C, wm->windows.first); \
881 CTX_wm_window_set(C, prevwin); \
884 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
887 CTX_data_scene_set(C, prevscene); \
890 #endif /* WITH_PYTHON */
892 static int run_python(int argc, const char **argv, void *data)
897 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
899 /* Make the path absolute because its needed for relative linked blends to be found */
900 char filename[FILE_MAXDIR + FILE_MAXFILE];
901 BLI_strncpy(filename, argv[1], sizeof(filename));
902 BLI_path_cwd(filename);
904 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
908 printf("\nError: you must specify a Python script after '-P / --python'.\n");
912 (void)argc; (void)argv; (void)data; /* unused */
913 printf("This blender was built without python support\n");
915 #endif /* WITH_PYTHON */
918 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
923 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
927 (void)argv; (void)data; /* unused */
928 printf("This blender was built without python support\n");
930 #endif /* WITH_PYTHON */
933 static int set_addons(int argc, const char **argv, void *data)
935 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
938 const int slen= strlen(argv[1]) + 128;
939 char *str= malloc(slen);
941 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
942 BPY_CTX_SETUP(BPY_string_exec(C, str));
945 (void)argv; (void)data; /* unused */
946 #endif /* WITH_PYTHON */
950 printf("\nError: you must specify a comma separated list after '--addons'.\n");
956 static int load_file(int UNUSED(argc), const char **argv, void *data)
960 /* Make the path absolute because its needed for relative linked blends to be found */
961 char filename[FILE_MAXDIR + FILE_MAXFILE];
962 BLI_strncpy(filename, argv[0], sizeof(filename));
963 BLI_path_cwd(filename);
966 int retval = BKE_read_file(C, filename, NULL);
968 /*we successfully loaded a blend file, get sure that
970 if (retval != BKE_READ_FILE_FAIL) {
971 wmWindowManager *wm= CTX_wm_manager(C);
973 /* special case, 2.4x files */
974 if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
975 extern void wm_add_default(bContext *C);
977 /* wm_add_default() needs the screen to be set. */
978 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
982 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
985 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
987 DAG_on_visible_update(CTX_data_main(C), TRUE);
990 /* WM_read_file() runs normally but since we're in background mode do here */
992 /* run any texts that were loaded in and flagged as modules */
994 BPY_app_handlers_reset();
995 BPY_modules_load_user(C);
998 /* happens for the UI on file reading too (huh? (ton))*/
999 // XXX BKE_reset_undo();
1000 // BKE_write_undo("original"); /* save current state */
1002 /* we are not running in background mode here, but start blender in UI mode with
1003 a file - this should do everything a 'load file' does */
1005 BKE_reports_init(&reports, RPT_PRINT);
1006 WM_read_file(C, filename, &reports);
1007 BKE_reports_clear(&reports);
1015 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1017 static char output_doc[] = "<path>"
1018 "\n\tSet the render path and file name."
1019 "\n\tUse // at the start of the path to"
1020 "\n\t\trender relative to the blend file."
1021 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1022 "\n\t\tani_##_test.png becomes ani_01_test.png"
1023 "\n\t\ttest-######.png becomes test-000001.png"
1024 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1025 "\n\tThe frame number will be added at the end of the filename."
1026 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1027 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1029 static char format_doc[] = "<format>"
1030 "\n\tSet the render format, Valid options are..."
1031 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1032 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1033 "\n\t(formats that can be compiled into blender, not available on all systems)"
1034 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1036 static char playback_doc[] = "<options> <file(s)>"
1037 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1038 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1039 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1040 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1041 "\n\t\t-j <frame>\tSet frame step to <frame>";
1043 static char game_doc[] = "Game Engine specific options"
1044 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1045 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1046 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1047 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1049 static char debug_doc[] = "\n\tTurn debugging on\n"
1050 "\n\t* Prints every operator call and their arguments"
1051 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1052 "\n\t* Keeps python sys.stdin rather than setting it to None";
1054 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1056 /* end argument processing after -- */
1057 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1059 /* first pass: background mode, disable python and commands that exit after usage */
1060 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1062 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1064 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1066 /* only to give help message */
1067 #ifndef WITH_PYTHON_SECURITY /* default */
1068 # define PY_ENABLE_AUTO ", (default)"
1069 # define PY_DISABLE_AUTO ""
1071 # define PY_ENABLE_AUTO ""
1072 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1075 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1076 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1078 #undef PY_ENABLE_AUTO
1079 #undef PY_DISABLE_AUTO
1081 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1083 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1085 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1086 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1088 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1090 /* TODO, add user env vars? */
1091 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1092 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1093 BLI_argsAdd(ba, 1, NULL, "--env-system-plugins", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1094 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1096 /* second pass: custom window stuff */
1097 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);
1098 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1099 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1100 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1101 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1102 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1104 /* third pass: disabling things and forcing settings */
1105 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1106 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1107 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1108 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1110 /* fourth pass: processing arguments */
1111 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1112 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);
1113 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1114 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1115 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1116 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1117 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1118 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1119 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1120 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1122 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1123 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1125 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1126 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);
1127 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);
1131 #ifdef WITH_PYTHON_MODULE
1132 /* allow python module to call main */
1133 #define main main_python
1136 int main(int argc, const char **argv)
1138 SYS_SystemHandle syshandle;
1139 bContext *C= CTX_create();
1142 #ifdef WITH_PYTHON_MODULE
1146 #ifdef WITH_BINRELOC
1152 /* patch to ignore argument finder gives us (pid?) */
1153 if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1154 extern int GHOST_HACK_getFirstFile(char buf[]);
1155 static char firstfilebuf[512];
1159 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1161 argv[1]= firstfilebuf;
1171 // copy path to executable in bprogname. playanim and creting runtimes
1174 BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
1177 strip_quotes(build_date);
1178 strip_quotes(build_time);
1179 strip_quotes(build_rev);
1180 strip_quotes(build_platform);
1181 strip_quotes(build_type);
1182 strip_quotes(build_cflags);
1183 strip_quotes(build_cxxflags);
1184 strip_quotes(build_linkflags);
1185 strip_quotes(build_system);
1188 BLI_threadapi_init();
1193 /* Hack - force inclusion of the plugin api functions,
1194 * see blenpluginapi:pluginapi.c
1196 pluginapi_force_ref();
1200 initglobals(); /* blender.c */
1206 #ifdef WITH_GAMEENGINE
1207 syshandle = SYS_GetSystem();
1212 /* first test for background */
1213 ba = BLI_argsInit(argc, argv); /* skip binary path */
1214 setupArguments(C, ba, &syshandle);
1216 BLI_argsParse(ba, 1, NULL, NULL);
1219 setuid(getuid()); /* end superuser */
1222 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1223 G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1225 /* for all platforms, even windos has it! */
1226 if(G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1229 /* background render uses this font too */
1230 BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1232 /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1233 rendered via ffmpeg */
1236 init_def_material();
1238 if(G.background==0) {
1239 BLI_argsParse(ba, 2, NULL, NULL);
1240 BLI_argsParse(ba, 3, NULL, NULL);
1242 WM_init(C, argc, argv);
1244 /* this is properly initialized with user defs, but this is default */
1245 BLI_where_is_temp(btempdir, FILE_MAX, 1); /* call after loading the startup.blend so we can read U.tempdir */
1248 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1252 BLI_argsParse(ba, 3, NULL, NULL);
1254 WM_init(C, argc, argv);
1256 BLI_where_is_temp(btempdir, FILE_MAX, 0); /* call after loading the startup.blend so we can read U.tempdir */
1260 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1261 * so we provide the BPY_ function below to append the user defined
1262 * pythondir to Python's sys.path at this point. Simply putting
1263 * WM_init() before BPY_python_start() crashes Blender at startup.
1264 * Update: now this function also inits the bpymenus, which also depend
1268 // TODO - U.pythondir
1270 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1273 CTX_py_init_set(C, 1);
1276 /* OK we are ready for it */
1277 BLI_argsParse(ba, 4, load_file, C);
1281 #ifdef WITH_PYTHON_MODULE
1282 return 0; /* keep blender in background mode running */
1286 /* actually incorrect, but works for now (ton) */
1291 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1296 else if(!G.file_loaded)
1303 /*XXX if (scr_init==0) {
1307 screenmain();*/ /* main display loop */
1310 } /* end of int main(argc,argv) */
1312 static void error_cb(const char *err)
1315 printf("%s\n", err); /* XXX do this in WM too */
1318 static void mem_error_cb(const char *errorStr)
1320 fputs(errorStr, stderr);
1324 static void setCallbacks(void)
1326 /* Error output from the alloc routines: */
1327 MEM_set_error_callback(mem_error_cb);
1332 BLI_setErrorCallBack(error_cb); /* */
1333 // XXX BLI_setInterruptCallBack(blender_test_break);