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 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
187 printf (BLEND_VERSION_STRING_FMT);
189 printf ("\tbuild date: %s\n", build_date);
190 printf ("\tbuild time: %s\n", build_time);
191 printf ("\tbuild revision: %s\n", build_rev);
192 printf ("\tbuild platform: %s\n", build_platform);
193 printf ("\tbuild type: %s\n", build_type);
194 printf ("\tbuild c flags: %s\n", build_cflags);
195 printf ("\tbuild c++ flags: %s\n", build_cxxflags);
196 printf ("\tbuild link flags: %s\n", build_linkflags);
197 printf ("\tbuild system: %s\n", build_system);
204 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
206 bArgs *ba = (bArgs*)data;
208 printf (BLEND_VERSION_STRING_FMT);
209 printf ("Usage: blender [args ...] [file] [args ...]\n\n");
211 printf ("Render Options:\n");
212 BLI_argsPrintArgDoc(ba, "--background");
213 BLI_argsPrintArgDoc(ba, "--render-anim");
214 BLI_argsPrintArgDoc(ba, "--scene");
215 BLI_argsPrintArgDoc(ba, "--render-frame");
216 BLI_argsPrintArgDoc(ba, "--frame-start");
217 BLI_argsPrintArgDoc(ba, "--frame-end");
218 BLI_argsPrintArgDoc(ba, "--frame-jump");
219 BLI_argsPrintArgDoc(ba, "--render-output");
220 BLI_argsPrintArgDoc(ba, "--engine");
223 printf ("Format Options:\n");
224 BLI_argsPrintArgDoc(ba, "--render-format");
225 BLI_argsPrintArgDoc(ba, "--use-extension");
226 BLI_argsPrintArgDoc(ba, "--threads");
229 printf ("Animation Playback Options:\n");
230 BLI_argsPrintArgDoc(ba, "-a");
233 printf ("Window Options:\n");
234 BLI_argsPrintArgDoc(ba, "--window-border");
235 BLI_argsPrintArgDoc(ba, "--window-borderless");
236 BLI_argsPrintArgDoc(ba, "--window-geometry");
237 BLI_argsPrintArgDoc(ba, "--start-console");
240 printf ("Game Engine Specific Options:\n");
241 BLI_argsPrintArgDoc(ba, "-g");
244 printf ("Misc Options:\n");
245 BLI_argsPrintArgDoc(ba, "--debug");
246 BLI_argsPrintArgDoc(ba, "--debug-fpe");
248 BLI_argsPrintArgDoc(ba, "--factory-startup");
250 BLI_argsPrintArgDoc(ba, "--env-system-config");
251 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
252 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
253 BLI_argsPrintArgDoc(ba, "--env-system-plugins");
254 BLI_argsPrintArgDoc(ba, "--env-system-python");
256 BLI_argsPrintArgDoc(ba, "-nojoystick");
257 BLI_argsPrintArgDoc(ba, "-noglsl");
258 BLI_argsPrintArgDoc(ba, "-noaudio");
259 BLI_argsPrintArgDoc(ba, "-setaudio");
263 BLI_argsPrintArgDoc(ba, "--help");
267 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
268 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
272 BLI_argsPrintArgDoc(ba, "--python");
273 BLI_argsPrintArgDoc(ba, "--python-console");
274 BLI_argsPrintArgDoc(ba, "--addons");
277 BLI_argsPrintArgDoc(ba, "-R");
278 BLI_argsPrintArgDoc(ba, "-r");
280 BLI_argsPrintArgDoc(ba, "--version");
282 BLI_argsPrintArgDoc(ba, "--");
284 printf ("Other Options:\n");
285 BLI_argsPrintOtherDoc(ba);
287 printf ("Argument Parsing:\n");
288 printf ("\targuments must be separated by white space. eg\n");
289 printf ("\t\t\"blender -ba test.blend\"\n");
290 printf ("\t...will ignore the 'a'\n");
291 printf ("\t\t\"blender -b test.blend -f8\"\n");
292 printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
294 printf ("Argument Order:\n");
295 printf ("Arguments are executed in the order they are given. eg\n");
296 printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
297 printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
298 printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
299 printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
300 printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
302 printf ("\nEnvironment Variables:\n");
303 printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
304 printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
305 printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
306 printf (" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
307 printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
308 printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
310 printf (" $TEMP Store temporary files here.\n");
312 printf (" $TMP or $TMPDIR Store temporary files here.\n");
315 printf (" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
317 printf (" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
325 double PIL_check_seconds_timer(void);
327 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
332 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
334 G.f |= G_SCRIPT_AUTOEXEC;
335 G.f |= G_SCRIPT_OVERRIDE_PREF;
339 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
341 G.f &= ~G_SCRIPT_AUTOEXEC;
342 G.f |= G_SCRIPT_OVERRIDE_PREF;
346 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
352 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
354 G.f |= G_DEBUG; /* std output printf's */
355 printf(BLEND_VERSION_STRING_FMT);
356 MEM_set_memory_debug();
358 #ifdef WITH_BUILDINFO
359 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
360 #endif // WITH_BUILDINFO
366 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
368 #if defined(__sgi) || defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
369 /* zealous but makes float issues a heck of a lot easier to find!
370 * set breakpoints on fpe_handler */
371 signal(SIGFPE, fpe_handler);
373 # if defined(__linux__) && defined(__GNUC__)
374 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
375 # endif /* defined(__linux__) && defined(__GNUC__) */
376 # if defined(OSX_SSE_FPE)
377 /* OSX uses SSE for floating point by default, so here
378 * use SSE instructions to throw floating point exceptions */
379 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
380 (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
381 # endif /* OSX_SSE_FPE */
382 # if defined(_WIN32) && defined(_MSC_VER)
383 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
384 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
385 # endif /* _WIN32 && _MSC_VER */
391 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
393 G.factory_startup= 1;
397 static int set_env(int argc, const char **argv, void *UNUSED(data))
399 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
401 char env[64]= "BLENDER";
402 char *ch_dst= env + 7; /* skip BLENDER */
403 const char *ch_src= argv[0] + 5; /* skip --env */
406 printf("%s requires one argument\n", argv[0]);
410 for(; *ch_src; ch_src++, ch_dst++) {
411 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
415 BLI_setenv(env, argv[1]);
419 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
421 /* not if -b was given first */
422 if (G.background == 0) {
423 #if 0 /* TODO, bring player back? */
424 playanim(argc, argv); /* not the same argc and argv as before */
426 fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
434 static int prefsize(int argc, const char **argv, void *UNUSED(data))
436 int stax, stay, sizx, sizy;
439 printf ("-p requires four arguments\n");
448 WM_setprefsize(stax, stay, sizx, sizy);
453 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
455 WM_setinitialstate_normal();
459 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
461 WM_setinitialstate_fullscreen();
465 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
466 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
468 wm_start_with_console = 1;
472 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
477 RegisterBlendExtension();
479 (void)data; /* unused */
484 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
486 #ifndef WITH_GAMEENGINE
489 SYS_SystemHandle *syshandle = data;
492 don't initialize joysticks if user doesn't want to use joysticks
493 failed joystick initialization delays over 5 seconds, before game engine start
495 SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
496 if (G.f & G_DEBUG) printf("disabling nojoystick\n");
502 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
504 GPU_extensions_disable();
508 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
510 sound_force_device(0);
514 static int set_audio(int argc, const char **argv, void *UNUSED(data))
517 printf("-setaudio require one argument\n");
521 sound_force_device(sound_define_from_str(argv[1]));
525 static int set_output(int argc, const char **argv, void *data)
529 if (CTX_data_scene(C)) {
530 Scene *scene= CTX_data_scene(C);
531 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
533 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
537 printf("\nError: you must specify a path after '-o / --render-output'.\n");
542 static int set_engine(int argc, const char **argv, void *data)
546 if (!strcmp(argv[1], "help")) {
547 RenderEngineType *type = NULL;
548 printf("Blender Engine Listing:\n");
549 for( type = R_engines.first; type; type = type->next ) {
550 printf("\t%s\n", type->idname);
555 if (CTX_data_scene(C)==NULL) {
556 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
559 Scene *scene= CTX_data_scene(C);
560 RenderData *rd = &scene->r;
562 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
563 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
572 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
577 static int set_image_type(int argc, const char **argv, void *data)
581 const char *imtype = argv[1];
582 if (CTX_data_scene(C)==NULL) {
583 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
585 Scene *scene= CTX_data_scene(C);
586 if (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
587 else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
589 else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
591 else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
592 else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
593 else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
594 else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
595 else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
596 else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
597 else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
598 else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
599 else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
601 else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
604 else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
607 else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
608 else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
610 else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
611 else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
613 else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
614 else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
617 else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
619 else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
623 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
628 static int set_threads(int argc, const char **argv, void *UNUSED(data))
632 RE_set_max_threads(atoi(argv[1]));
634 printf("Warning: threads can only be set in background mode\n");
638 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
643 static int set_extension(int argc, const char **argv, void *data)
647 if (CTX_data_scene(C)) {
648 Scene *scene= CTX_data_scene(C);
649 if (argv[1][0] == '0') {
650 scene->r.scemode &= ~R_EXTENSION;
651 } else if (argv[1][0] == '1') {
652 scene->r.scemode |= R_EXTENSION;
654 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
657 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
661 printf("\nError: you must specify a path after '- '.\n");
666 static int set_ge_parameters(int argc, const char **argv, void *data)
669 #ifdef WITH_GAMEENGINE
670 SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
676 gameengine parameters are automaticly put into system
677 -g [paramname = value]
681 -g maxvertexarraysize = 512
686 const char *paramname = argv[a];
687 /* check for single value versus assignment */
688 if (a+1 < argc && (*(argv[a+1]) == '='))
695 #ifdef WITH_GAMEENGINE
696 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
700 printf("error: argument assignment (%s) without value.\n",paramname);
706 #ifdef WITH_GAMEENGINE
707 SYS_WriteCommandLineInt(syshandle,argv[a],1);
710 if (!strcmp(argv[a],"nomipmap"))
712 GPU_set_mipmap(0); //doMipMap = 0;
715 if (!strcmp(argv[a],"linearmipmap"))
717 GPU_set_linear_mipmap(1); //linearMipMap = 1;
721 } /* if (*(argv[a+1]) == '=') */
727 static int render_frame(int argc, const char **argv, void *data)
730 if (CTX_data_scene(C)) {
731 Main *bmain= CTX_data_main(C);
732 Scene *scene= CTX_data_scene(C);
735 Render *re = RE_NewRender(scene->id.name);
741 frame= scene->r.sfra + atoi(argv[1]+1);
744 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
747 frame= atoi(argv[1]);
751 BKE_reports_init(&reports, RPT_PRINT);
753 frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
755 RE_SetReports(re, &reports);
756 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
757 RE_SetReports(re, NULL);
760 printf("\nError: frame number must follow '-f / --render-frame'.\n");
764 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
769 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
772 if (CTX_data_scene(C)) {
773 Main *bmain= CTX_data_main(C);
774 Scene *scene= CTX_data_scene(C);
775 Render *re= RE_NewRender(scene->id.name);
777 BKE_reports_init(&reports, RPT_PRINT);
778 RE_SetReports(re, &reports);
779 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
780 RE_SetReports(re, NULL);
782 printf("\nError: no blend loaded. cannot use '-a'.\n");
787 static int set_scene(int argc, const char **argv, void *data)
791 Scene *sce= set_scene_name(CTX_data_main(C), argv[1]);
793 CTX_data_scene_set(C, sce);
797 printf("\nError: Scene name must follow '-S / --scene'.\n");
802 static int set_start_frame(int argc, const char **argv, void *data)
805 if (CTX_data_scene(C)) {
806 Scene *scene= CTX_data_scene(C);
808 int frame = atoi(argv[1]);
809 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
812 printf("\nError: frame number must follow '-s / --frame-start'.\n");
816 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
821 static int set_end_frame(int argc, const char **argv, void *data)
824 if (CTX_data_scene(C)) {
825 Scene *scene= CTX_data_scene(C);
827 int frame = atoi(argv[1]);
828 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
831 printf("\nError: frame number must follow '-e / --frame-end'.\n");
835 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
840 static int set_skip_frame(int argc, const char **argv, void *data)
843 if (CTX_data_scene(C)) {
844 Scene *scene= CTX_data_scene(C);
846 int frame = atoi(argv[1]);
847 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
850 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
854 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
859 /* macro for ugly context setup/reset */
861 #define BPY_CTX_SETUP(_cmd) \
863 wmWindowManager *wm= CTX_wm_manager(C); \
864 wmWindow *prevwin= CTX_wm_window(C); \
865 Scene *prevscene= CTX_data_scene(C); \
866 if(wm->windows.first) { \
867 CTX_wm_window_set(C, wm->windows.first); \
869 CTX_wm_window_set(C, prevwin); \
872 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
875 CTX_data_scene_set(C, prevscene); \
878 #endif /* WITH_PYTHON */
880 static int run_python(int argc, const char **argv, void *data)
885 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
887 /* Make the path absolute because its needed for relative linked blends to be found */
888 char filename[FILE_MAXDIR + FILE_MAXFILE];
889 BLI_strncpy(filename, argv[1], sizeof(filename));
890 BLI_path_cwd(filename);
892 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
896 printf("\nError: you must specify a Python script after '-P / --python'.\n");
900 (void)argc; (void)argv; (void)data; /* unused */
901 printf("This blender was built without python support\n");
903 #endif /* WITH_PYTHON */
906 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
911 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
915 (void)argv; (void)data; /* unused */
916 printf("This blender was built without python support\n");
918 #endif /* WITH_PYTHON */
921 static int set_addons(int argc, const char **argv, void *data)
923 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
926 const int slen= strlen(argv[1]) + 128;
927 char *str= malloc(slen);
929 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
930 BPY_CTX_SETUP(BPY_string_exec(C, str));
933 (void)argv; (void)data; /* unused */
934 #endif /* WITH_PYTHON */
938 printf("\nError: you must specify a comma separated list after '--addons'.\n");
944 static int load_file(int UNUSED(argc), const char **argv, void *data)
948 /* Make the path absolute because its needed for relative linked blends to be found */
949 char filename[FILE_MAXDIR + FILE_MAXFILE];
950 BLI_strncpy(filename, argv[0], sizeof(filename));
951 BLI_path_cwd(filename);
954 int retval = BKE_read_file(C, filename, NULL);
956 /*we successfully loaded a blend file, get sure that
958 if (retval != BKE_READ_FILE_FAIL) {
959 wmWindowManager *wm= CTX_wm_manager(C);
961 /* special case, 2.4x files */
962 if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
963 extern void wm_add_default(bContext *C);
965 /* wm_add_default() needs the screen to be set. */
966 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
970 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
973 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
975 DAG_on_visible_update(CTX_data_main(C), TRUE);
978 /* WM_read_file() runs normally but since we're in background mode do here */
980 /* run any texts that were loaded in and flagged as modules */
982 BPY_app_handlers_reset();
983 BPY_modules_load_user(C);
986 /* happens for the UI on file reading too (huh? (ton))*/
987 // XXX BKE_reset_undo();
988 // BKE_write_undo("original"); /* save current state */
990 /* we are not running in background mode here, but start blender in UI mode with
991 a file - this should do everything a 'load file' does */
993 BKE_reports_init(&reports, RPT_PRINT);
994 WM_read_file(C, filename, &reports);
995 BKE_reports_clear(&reports);
1003 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
1005 static char output_doc[] = "<path>"
1006 "\n\tSet the render path and file name."
1007 "\n\tUse // at the start of the path to"
1008 "\n\t\trender relative to the blend file."
1009 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1010 "\n\t\tani_##_test.png becomes ani_01_test.png"
1011 "\n\t\ttest-######.png becomes test-000001.png"
1012 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1013 "\n\tThe frame number will be added at the end of the filename."
1014 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1015 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1017 static char format_doc[] = "<format>"
1018 "\n\tSet the render format, Valid options are..."
1019 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1020 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1021 "\n\t(formats that can be compiled into blender, not available on all systems)"
1022 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1024 static char playback_doc[] = "<options> <file(s)>"
1025 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1026 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1027 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1028 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1029 "\n\t\t-j <frame>\tSet frame step to <frame>";
1031 static char game_doc[] = "Game Engine specific options"
1032 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1033 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1034 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1035 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1037 static char debug_doc[] = "\n\tTurn debugging on\n"
1038 "\n\t* Prints every operator call and their arguments"
1039 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1040 "\n\t* Keeps python sys.stdin rather than setting it to None";
1042 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1044 /* end argument processing after -- */
1045 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1047 /* first pass: background mode, disable python and commands that exit after usage */
1048 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1050 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1052 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1054 /* only to give help message */
1055 #ifndef WITH_PYTHON_SECURITY /* default */
1056 # define PY_ENABLE_AUTO ", (default)"
1057 # define PY_DISABLE_AUTO ""
1059 # define PY_ENABLE_AUTO ""
1060 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1063 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1064 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1066 #undef PY_ENABLE_AUTO
1067 #undef PY_DISABLE_AUTO
1069 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1071 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1073 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1074 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1076 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1078 /* TODO, add user env vars? */
1079 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1080 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1081 BLI_argsAdd(ba, 1, NULL, "--env-system-plugins", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1082 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1084 /* second pass: custom window stuff */
1085 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);
1086 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1087 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1088 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1089 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1090 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1092 /* third pass: disabling things and forcing settings */
1093 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1094 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1095 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1096 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1098 /* fourth pass: processing arguments */
1099 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1100 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);
1101 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1102 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1103 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1104 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1105 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1106 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1107 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1108 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1110 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1111 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1113 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1114 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);
1115 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);
1119 #ifdef WITH_PYTHON_MODULE
1120 /* allow python module to call main */
1121 #define main main_python_enter
1122 static void *evil_C= NULL;
1125 int main(int argc, const char **argv)
1127 SYS_SystemHandle syshandle;
1128 bContext *C= CTX_create();
1131 #ifdef WITH_PYTHON_MODULE
1136 #ifdef WITH_BINRELOC
1142 /* patch to ignore argument finder gives us (pid?) */
1143 if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1144 extern int GHOST_HACK_getFirstFile(char buf[]);
1145 static char firstfilebuf[512];
1149 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1151 argv[1]= firstfilebuf;
1161 // copy path to executable in bprogname. playanim and creting runtimes
1164 BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
1166 BLI_threadapi_init();
1171 /* Hack - force inclusion of the plugin api functions,
1172 * see blenpluginapi:pluginapi.c
1174 pluginapi_force_ref();
1178 initglobals(); /* blender.c */
1184 #ifdef WITH_GAMEENGINE
1185 syshandle = SYS_GetSystem();
1190 /* first test for background */
1191 ba = BLI_argsInit(argc, argv); /* skip binary path */
1192 setupArguments(C, ba, &syshandle);
1194 BLI_argsParse(ba, 1, NULL, NULL);
1197 setuid(getuid()); /* end superuser */
1200 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1201 G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1203 /* for all platforms, even windos has it! */
1204 if(G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1207 /* background render uses this font too */
1208 BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1210 /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1211 rendered via ffmpeg */
1214 init_def_material();
1216 if(G.background==0) {
1217 BLI_argsParse(ba, 2, NULL, NULL);
1218 BLI_argsParse(ba, 3, NULL, NULL);
1220 WM_init(C, argc, argv);
1222 /* this is properly initialized with user defs, but this is default */
1223 BLI_where_is_temp(btempdir, FILE_MAX, 1); /* call after loading the startup.blend so we can read U.tempdir */
1226 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1230 BLI_argsParse(ba, 3, NULL, NULL);
1232 WM_init(C, argc, argv);
1234 BLI_where_is_temp(btempdir, FILE_MAX, 0); /* call after loading the startup.blend so we can read U.tempdir */
1238 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1239 * so we provide the BPY_ function below to append the user defined
1240 * pythondir to Python's sys.path at this point. Simply putting
1241 * WM_init() before BPY_python_start() crashes Blender at startup.
1242 * Update: now this function also inits the bpymenus, which also depend
1246 // TODO - U.pythondir
1248 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1251 CTX_py_init_set(C, 1);
1254 /* OK we are ready for it */
1255 BLI_argsParse(ba, 4, load_file, C);
1259 #ifdef WITH_PYTHON_MODULE
1260 return 0; /* keep blender in background mode running */
1264 /* actually incorrect, but works for now (ton) */
1269 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1274 else if(!G.file_loaded)
1281 /*XXX if (scr_init==0) {
1285 screenmain();*/ /* main display loop */
1288 } /* end of int main(argc,argv) */
1290 #ifdef WITH_PYTHON_MODULE
1291 void main_python_exit(void)
1293 WM_exit((bContext *)evil_C);
1298 static void error_cb(const char *err)
1301 printf("%s\n", err); /* XXX do this in WM too */
1304 static void mem_error_cb(const char *errorStr)
1306 fputs(errorStr, stderr);
1310 static void setCallbacks(void)
1312 /* Error output from the alloc routines: */
1313 MEM_set_error_callback(mem_error_cb);
1318 BLI_setErrorCallBack(error_cb); /* */
1319 // XXX BLI_setInterruptCallBack(blender_test_break);