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 /* This little block needed for linking to Blender... */
51 #include "MEM_guardedalloc.h"
54 #include "BLI_winstuff.h"
58 #include "BLI_threads.h"
59 #include "BLI_scanfill.h" // for BLI_setErrorCallBack, TODO, move elsewhere
60 #include "BLI_utildefines.h"
61 #include "BLI_callbacks.h"
64 #include "DNA_scene_types.h"
65 #include "DNA_userdef_types.h"
67 #include "BLI_blenlib.h"
69 #include "BKE_utildefines.h"
70 #include "BKE_blender.h"
71 #include "BKE_context.h"
72 #include "BKE_depsgraph.h" // for DAG_on_visible_update
74 #include "BKE_global.h"
76 #include "BKE_material.h"
77 #include "BKE_packedFile.h"
78 #include "BKE_scene.h"
80 #include "BKE_report.h"
81 #include "BKE_sound.h"
83 #include "IMB_imbuf.h" // for IMB_init
86 #include "BPY_extern.h"
89 #include "RE_pipeline.h"
91 //XXX #include "playanim_ext.h"
92 #include "ED_datafiles.h"
96 #include "RNA_define.h"
99 #include "GPU_extensions.h"
101 #ifdef WITH_BUILDINFO_HEADER
105 /* for passing information between creator and gameengine */
106 #ifdef WITH_GAMEENGINE
107 #include "BL_System.h"
109 #define SYS_SystemHandle int
115 # include <sys/types.h>
116 # include <floatingpoint.h>
117 # include <sys/rtprio.h>
121 #include "binreloc.h"
126 extern char build_date[];
127 extern char build_time[];
128 extern char build_rev[];
129 extern char build_platform[];
130 extern char build_type[];
131 extern char build_cflags[];
132 extern char build_cxxflags[];
133 extern char build_linkflags[];
134 extern char build_system[];
137 /* Local Function prototypes */
138 static int print_help(int argc, const char **argv, void *data);
139 static int print_version(int argc, const char **argv, void *data);
141 /* for the callbacks: */
143 extern int pluginapi_force_ref(void); /* from blenpluginapi:pluginapi.c */
145 #define BLEND_VERSION_STRING_FMT "Blender %d.%02d (sub %d)\n", BLENDER_VERSION/100, BLENDER_VERSION%100, BLENDER_SUBVERSION
147 /* Initialize callbacks for the modules that need them */
148 static void setCallbacks(void);
150 /* set breakpoints here when running in debug mode, useful to catch floating point errors */
151 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
152 static void fpe_handler(int UNUSED(sig))
154 // printf("SIGFPE trapped\n");
158 #ifndef WITH_PYTHON_MODULE
159 /* handling ctrl-c event in console */
160 static void blender_esc(int sig)
162 static int count = 0;
164 G.afbreek = 1; /* forces render loop to read queue, not sure if its needed */
168 printf("\nBlender killed\n");
171 printf("\nSent an internal break event. Press ^C again to kill Blender\n");
177 static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
179 printf (BLEND_VERSION_STRING_FMT);
181 printf ("\tbuild date: %s\n", build_date);
182 printf ("\tbuild time: %s\n", build_time);
183 printf ("\tbuild revision: %s\n", build_rev);
184 printf ("\tbuild platform: %s\n", build_platform);
185 printf ("\tbuild type: %s\n", build_type);
186 printf ("\tbuild c flags: %s\n", build_cflags);
187 printf ("\tbuild c++ flags: %s\n", build_cxxflags);
188 printf ("\tbuild link flags: %s\n", build_linkflags);
189 printf ("\tbuild system: %s\n", build_system);
196 static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
198 bArgs *ba = (bArgs*)data;
200 printf (BLEND_VERSION_STRING_FMT);
201 printf ("Usage: blender [args ...] [file] [args ...]\n\n");
203 printf ("Render Options:\n");
204 BLI_argsPrintArgDoc(ba, "--background");
205 BLI_argsPrintArgDoc(ba, "--render-anim");
206 BLI_argsPrintArgDoc(ba, "--scene");
207 BLI_argsPrintArgDoc(ba, "--render-frame");
208 BLI_argsPrintArgDoc(ba, "--frame-start");
209 BLI_argsPrintArgDoc(ba, "--frame-end");
210 BLI_argsPrintArgDoc(ba, "--frame-jump");
211 BLI_argsPrintArgDoc(ba, "--render-output");
212 BLI_argsPrintArgDoc(ba, "--engine");
215 printf ("Format Options:\n");
216 BLI_argsPrintArgDoc(ba, "--render-format");
217 BLI_argsPrintArgDoc(ba, "--use-extension");
218 BLI_argsPrintArgDoc(ba, "--threads");
221 printf ("Animation Playback Options:\n");
222 BLI_argsPrintArgDoc(ba, "-a");
225 printf ("Window Options:\n");
226 BLI_argsPrintArgDoc(ba, "--window-border");
227 BLI_argsPrintArgDoc(ba, "--window-borderless");
228 BLI_argsPrintArgDoc(ba, "--window-geometry");
229 BLI_argsPrintArgDoc(ba, "--start-console");
232 printf ("Game Engine Specific Options:\n");
233 BLI_argsPrintArgDoc(ba, "-g");
236 printf ("Misc Options:\n");
237 BLI_argsPrintArgDoc(ba, "--debug");
238 BLI_argsPrintArgDoc(ba, "--debug-fpe");
240 BLI_argsPrintArgDoc(ba, "--factory-startup");
242 BLI_argsPrintArgDoc(ba, "--env-system-config");
243 BLI_argsPrintArgDoc(ba, "--env-system-datafiles");
244 BLI_argsPrintArgDoc(ba, "--env-system-scripts");
245 BLI_argsPrintArgDoc(ba, "--env-system-plugins");
246 BLI_argsPrintArgDoc(ba, "--env-system-python");
248 BLI_argsPrintArgDoc(ba, "-nojoystick");
249 BLI_argsPrintArgDoc(ba, "-noglsl");
250 BLI_argsPrintArgDoc(ba, "-noaudio");
251 BLI_argsPrintArgDoc(ba, "-setaudio");
255 BLI_argsPrintArgDoc(ba, "--help");
259 BLI_argsPrintArgDoc(ba, "--enable-autoexec");
260 BLI_argsPrintArgDoc(ba, "--disable-autoexec");
264 BLI_argsPrintArgDoc(ba, "--python");
265 BLI_argsPrintArgDoc(ba, "--python-console");
266 BLI_argsPrintArgDoc(ba, "--addons");
269 BLI_argsPrintArgDoc(ba, "-R");
270 BLI_argsPrintArgDoc(ba, "-r");
272 BLI_argsPrintArgDoc(ba, "--version");
274 BLI_argsPrintArgDoc(ba, "--");
276 printf ("Other Options:\n");
277 BLI_argsPrintOtherDoc(ba);
279 printf ("Argument Parsing:\n");
280 printf ("\targuments must be separated by white space. eg\n");
281 printf ("\t\t\"blender -ba test.blend\"\n");
282 printf ("\t...will ignore the 'a'\n");
283 printf ("\t\t\"blender -b test.blend -f8\"\n");
284 printf ("\t...will ignore 8 because there is no space between the -f and the frame value\n\n");
286 printf ("Argument Order:\n");
287 printf ("Arguments are executed in the order they are given. eg\n");
288 printf ("\t\t\"blender --background test.blend --render-frame 1 --render-output /tmp\"\n");
289 printf ("\t...will not render to /tmp because '--render-frame 1' renders before the output path is set\n");
290 printf ("\t\t\"blender --background --render-output /tmp test.blend --render-frame 1\"\n");
291 printf ("\t...will not render to /tmp because loading the blend file overwrites the render output that was set\n");
292 printf ("\t\t\"blender --background test.blend --render-output /tmp --render-frame 1\" works as expected.\n\n");
294 printf ("\nEnvironment Variables:\n");
295 printf (" $BLENDER_USER_CONFIG Directory for user configuration files.\n");
296 printf (" $BLENDER_USER_SCRIPTS Directory for user scripts.\n");
297 printf (" $BLENDER_SYSTEM_SCRIPTS Directory for system wide scripts.\n");
298 printf (" $BLENDER_USER_DATAFILES Directory for user data files (icons, translations, ..).\n");
299 printf (" $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.\n");
300 printf (" $BLENDER_SYSTEM_PYTHON Directory for system python libraries.\n");
302 printf (" $TEMP Store temporary files here.\n");
304 printf (" $TMP or $TMPDIR Store temporary files here.\n");
307 printf (" $SDL_AUDIODRIVER LibSDL audio driver - alsa, esd, dma.\n");
309 printf (" $PYTHONHOME Path to the python directory, eg. /usr/lib/python.\n\n");
317 double PIL_check_seconds_timer(void);
319 static int end_arguments(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
324 static int enable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
326 G.f |= G_SCRIPT_AUTOEXEC;
327 G.f |= G_SCRIPT_OVERRIDE_PREF;
331 static int disable_python(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
333 G.f &= ~G_SCRIPT_AUTOEXEC;
334 G.f |= G_SCRIPT_OVERRIDE_PREF;
338 static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
344 static int debug_mode(int UNUSED(argc), const char **UNUSED(argv), void *data)
346 G.f |= G_DEBUG; /* std output printf's */
347 printf(BLEND_VERSION_STRING_FMT);
348 MEM_set_memory_debug();
350 #ifdef WITH_BUILDINFO
351 printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
352 #endif // WITH_BUILDINFO
358 static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
360 #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE)
361 /* zealous but makes float issues a heck of a lot easier to find!
362 * set breakpoints on fpe_handler */
363 signal(SIGFPE, fpe_handler);
365 # if defined(__linux__) && defined(__GNUC__)
366 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW );
367 # endif /* defined(__linux__) && defined(__GNUC__) */
368 # if defined(OSX_SSE_FPE)
369 /* OSX uses SSE for floating point by default, so here
370 * use SSE instructions to throw floating point exceptions */
371 _MM_SET_EXCEPTION_MASK(_MM_MASK_MASK &~
372 (_MM_MASK_OVERFLOW|_MM_MASK_INVALID|_MM_MASK_DIV_ZERO));
373 # endif /* OSX_SSE_FPE */
374 # if defined(_WIN32) && defined(_MSC_VER)
375 _controlfp_s(NULL, 0, _MCW_EM); /* enables all fp exceptions */
376 _controlfp_s(NULL, _EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); /* hide the ones we don't care about */
377 # endif /* _WIN32 && _MSC_VER */
383 static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
385 G.factory_startup= 1;
389 static int set_env(int argc, const char **argv, void *UNUSED(data))
391 /* "--env-system-scripts" --> "BLENDER_SYSTEM_SCRIPTS" */
393 char env[64]= "BLENDER";
394 char *ch_dst= env + 7; /* skip BLENDER */
395 const char *ch_src= argv[0] + 5; /* skip --env */
398 printf("%s requires one argument\n", argv[0]);
402 for(; *ch_src; ch_src++, ch_dst++) {
403 *ch_dst= (*ch_src == '-') ? '_' : (*ch_src)-32; /* toupper() */
407 BLI_setenv(env, argv[1]);
411 static int playback_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
413 /* not if -b was given first */
414 if (G.background == 0) {
415 #if 0 /* TODO, bring player back? */
416 playanim(argc, argv); /* not the same argc and argv as before */
418 fprintf(stderr, "Playback mode not supported in blender 2.5x\n");
426 static int prefsize(int argc, const char **argv, void *UNUSED(data))
428 int stax, stay, sizx, sizy;
431 printf ("-p requires four arguments\n");
440 WM_setprefsize(stax, stay, sizx, sizy);
445 static int with_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
447 WM_setinitialstate_normal();
451 static int without_borders(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
453 WM_setinitialstate_fullscreen();
457 extern int wm_start_with_console; // blender/windowmanager/intern/wm_init_exit.c
458 static int start_with_console(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
460 wm_start_with_console = 1;
464 static int register_extension(int UNUSED(argc), const char **UNUSED(argv), void *data)
469 RegisterBlendExtension();
471 (void)data; /* unused */
476 static int no_joystick(int UNUSED(argc), const char **UNUSED(argv), void *data)
478 #ifndef WITH_GAMEENGINE
481 SYS_SystemHandle *syshandle = data;
484 don't initialize joysticks if user doesn't want to use joysticks
485 failed joystick initialization delays over 5 seconds, before game engine start
487 SYS_WriteCommandLineInt(*syshandle, "nojoystick",1);
488 if (G.f & G_DEBUG) printf("disabling nojoystick\n");
494 static int no_glsl(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
496 GPU_extensions_disable();
500 static int no_audio(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
502 sound_force_device(0);
506 static int set_audio(int argc, const char **argv, void *UNUSED(data))
509 printf("-setaudio require one argument\n");
513 sound_force_device(sound_define_from_str(argv[1]));
517 static int set_output(int argc, const char **argv, void *data)
521 Scene *scene= CTX_data_scene(C);
523 BLI_strncpy(scene->r.pic, argv[1], sizeof(scene->r.pic));
525 printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n");
529 printf("\nError: you must specify a path after '-o / --render-output'.\n");
534 static int set_engine(int argc, const char **argv, void *data)
538 if (!strcmp(argv[1], "help")) {
539 RenderEngineType *type = NULL;
540 printf("Blender Engine Listing:\n");
541 for( type = R_engines.first; type; type = type->next ) {
542 printf("\t%s\n", type->idname);
547 Scene *scene= CTX_data_scene(C);
549 RenderData *rd = &scene->r;
551 if(BLI_findstring(&R_engines, argv[1], offsetof(RenderEngineType, idname))) {
552 BLI_strncpy_utf8(rd->engine, argv[1], sizeof(rd->engine));
556 printf("\nError: no blend loaded. order the arguments so '-E / --engine ' is after a blend is loaded.\n");
564 printf("\nEngine not specified, give 'help' for a list of available engines.\n");
569 static int set_image_type(int argc, const char **argv, void *data)
573 const char *imtype = argv[1];
574 Scene *scene= CTX_data_scene(C);
576 if (!strcmp(imtype,"TGA")) scene->r.imtype = R_TARGA;
577 else if (!strcmp(imtype,"IRIS")) scene->r.imtype = R_IRIS;
579 else if (!strcmp(imtype,"DDS")) scene->r.imtype = R_DDS;
581 else if (!strcmp(imtype,"JPEG")) scene->r.imtype = R_JPEG90;
582 else if (!strcmp(imtype,"IRIZ")) scene->r.imtype = R_IRIZ;
583 else if (!strcmp(imtype,"RAWTGA")) scene->r.imtype = R_RAWTGA;
584 else if (!strcmp(imtype,"AVIRAW")) scene->r.imtype = R_AVIRAW;
585 else if (!strcmp(imtype,"AVIJPEG")) scene->r.imtype = R_AVIJPEG;
586 else if (!strcmp(imtype,"PNG")) scene->r.imtype = R_PNG;
587 else if (!strcmp(imtype,"AVICODEC")) scene->r.imtype = R_AVICODEC;
588 else if (!strcmp(imtype,"QUICKTIME")) scene->r.imtype = R_QUICKTIME;
589 else if (!strcmp(imtype,"BMP")) scene->r.imtype = R_BMP;
591 else if (!strcmp(imtype,"HDR")) scene->r.imtype = R_RADHDR;
594 else if (!strcmp(imtype,"TIFF")) scene->r.imtype = R_TIFF;
597 else if (!strcmp(imtype,"EXR")) scene->r.imtype = R_OPENEXR;
598 else if (!strcmp(imtype,"MULTILAYER")) scene->r.imtype = R_MULTILAYER;
600 else if (!strcmp(imtype,"MPEG")) scene->r.imtype = R_FFMPEG;
601 else if (!strcmp(imtype,"FRAMESERVER")) scene->r.imtype = R_FRAMESERVER;
603 else if (!strcmp(imtype,"CINEON")) scene->r.imtype = R_CINEON;
604 else if (!strcmp(imtype,"DPX")) scene->r.imtype = R_DPX;
607 else if (!strcmp(imtype,"JP2")) scene->r.imtype = R_JP2;
609 else printf("\nError: Format from '-F / --render-format' not known or not compiled in this release.\n");
612 printf("\nError: no blend loaded. order the arguments so '-F / --render-format' is after the blend is loaded.\n");
616 printf("\nError: you must specify a format after '-F / --render-foramt'.\n");
621 static int set_threads(int argc, const char **argv, void *UNUSED(data))
625 RE_set_max_threads(atoi(argv[1]));
627 printf("Warning: threads can only be set in background mode\n");
631 printf("\nError: you must specify a number of threads between 0 and 8 '-t / --threads'.\n");
636 static int set_extension(int argc, const char **argv, void *data)
640 Scene *scene= CTX_data_scene(C);
642 if (argv[1][0] == '0') {
643 scene->r.scemode &= ~R_EXTENSION;
644 } else if (argv[1][0] == '1') {
645 scene->r.scemode |= R_EXTENSION;
647 printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n");
650 printf("\nError: no blend loaded. order the arguments so '-o ' is after '-x '.\n");
654 printf("\nError: you must specify a path after '- '.\n");
659 static int set_ge_parameters(int argc, const char **argv, void *data)
662 #ifdef WITH_GAMEENGINE
663 SYS_SystemHandle syshandle = *(SYS_SystemHandle*)data;
669 gameengine parameters are automaticly put into system
670 -g [paramname = value]
674 -g maxvertexarraysize = 512
679 const char *paramname = argv[a];
680 /* check for single value versus assignment */
681 if (a+1 < argc && (*(argv[a+1]) == '='))
688 #ifdef WITH_GAMEENGINE
689 SYS_WriteCommandLineString(syshandle,paramname,argv[a]);
693 printf("error: argument assignment (%s) without value.\n",paramname);
699 #ifdef WITH_GAMEENGINE
700 SYS_WriteCommandLineInt(syshandle,argv[a],1);
703 if (!strcmp(argv[a],"nomipmap"))
705 GPU_set_mipmap(0); //doMipMap = 0;
708 if (!strcmp(argv[a],"linearmipmap"))
710 GPU_set_linear_mipmap(1); //linearMipMap = 1;
714 } /* if (*(argv[a+1]) == '=') */
720 static int render_frame(int argc, const char **argv, void *data)
723 Scene *scene= CTX_data_scene(C);
725 Main *bmain= CTX_data_main(C);
728 Render *re = RE_NewRender(scene->id.name);
734 frame= scene->r.sfra + atoi(argv[1]+1);
737 frame= (scene->r.efra - atoi(argv[1]+1)) + 1;
740 frame= atoi(argv[1]);
744 BKE_reports_init(&reports, RPT_PRINT);
746 frame = MIN2(MAXFRAME, MAX2(MINAFRAME, frame));
748 RE_SetReports(re, &reports);
749 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, frame, frame, scene->r.frame_step);
750 RE_SetReports(re, NULL);
753 printf("\nError: frame number must follow '-f / --render-frame'.\n");
757 printf("\nError: no blend loaded. cannot use '-f / --render-frame'.\n");
762 static int render_animation(int UNUSED(argc), const char **UNUSED(argv), void *data)
765 Scene *scene= CTX_data_scene(C);
767 Main *bmain= CTX_data_main(C);
768 Render *re= RE_NewRender(scene->id.name);
770 BKE_reports_init(&reports, RPT_PRINT);
771 RE_SetReports(re, &reports);
772 RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
773 RE_SetReports(re, NULL);
775 printf("\nError: no blend loaded. cannot use '-a'.\n");
780 static int set_scene(int argc, const char **argv, void *data)
784 Scene *scene= set_scene_name(CTX_data_main(C), argv[1]);
786 CTX_data_scene_set(C, scene);
790 printf("\nError: Scene name must follow '-S / --scene'.\n");
795 static int set_start_frame(int argc, const char **argv, void *data)
798 Scene *scene= CTX_data_scene(C);
801 int frame = atoi(argv[1]);
802 (scene->r.sfra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
805 printf("\nError: frame number must follow '-s / --frame-start'.\n");
809 printf("\nError: no blend loaded. cannot use '-s / --frame-start'.\n");
814 static int set_end_frame(int argc, const char **argv, void *data)
817 Scene *scene= CTX_data_scene(C);
820 int frame = atoi(argv[1]);
821 (scene->r.efra) = CLAMPIS(frame, MINFRAME, MAXFRAME);
824 printf("\nError: frame number must follow '-e / --frame-end'.\n");
828 printf("\nError: no blend loaded. cannot use '-e / --frame-end'.\n");
833 static int set_skip_frame(int argc, const char **argv, void *data)
836 Scene *scene= CTX_data_scene(C);
839 int frame = atoi(argv[1]);
840 (scene->r.frame_step) = CLAMPIS(frame, 1, MAXFRAME);
843 printf("\nError: number of frames to step must follow '-j / --frame-jump'.\n");
847 printf("\nError: no blend loaded. cannot use '-j / --frame-jump'.\n");
852 /* macro for ugly context setup/reset */
854 #define BPY_CTX_SETUP(_cmd) \
856 wmWindowManager *wm= CTX_wm_manager(C); \
857 wmWindow *prevwin= CTX_wm_window(C); \
858 Scene *prevscene= CTX_data_scene(C); \
859 if(wm->windows.first) { \
860 CTX_wm_window_set(C, wm->windows.first); \
862 CTX_wm_window_set(C, prevwin); \
865 fprintf(stderr, "Python script \"%s\" running with missing context data.\n", argv[1]); \
868 CTX_data_scene_set(C, prevscene); \
871 #endif /* WITH_PYTHON */
873 static int run_python(int argc, const char **argv, void *data)
878 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
880 /* Make the path absolute because its needed for relative linked blends to be found */
881 char filename[FILE_MAXDIR + FILE_MAXFILE];
882 BLI_strncpy(filename, argv[1], sizeof(filename));
883 BLI_path_cwd(filename);
885 BPY_CTX_SETUP(BPY_filepath_exec(C, filename, NULL))
889 printf("\nError: you must specify a Python script after '-P / --python'.\n");
893 (void)argc; (void)argv; (void)data; /* unused */
894 printf("This blender was built without python support\n");
896 #endif /* WITH_PYTHON */
899 static int run_python_console(int UNUSED(argc), const char **argv, void *data)
904 BPY_CTX_SETUP(BPY_string_exec(C, "__import__('code').interact()"))
908 (void)argv; (void)data; /* unused */
909 printf("This blender was built without python support\n");
911 #endif /* WITH_PYTHON */
914 static int set_addons(int argc, const char **argv, void *data)
916 /* workaround for scripts not getting a bpy.context.scene, causes internal errors elsewhere */
919 const int slen= strlen(argv[1]) + 128;
920 char *str= malloc(slen);
922 BLI_snprintf(str, slen, "[__import__('addon_utils').enable(i, default_set=False) for i in '%s'.split(',')]", argv[1]);
923 BPY_CTX_SETUP(BPY_string_exec(C, str));
926 (void)argv; (void)data; /* unused */
927 #endif /* WITH_PYTHON */
931 printf("\nError: you must specify a comma separated list after '--addons'.\n");
937 static int load_file(int UNUSED(argc), const char **argv, void *data)
941 /* Make the path absolute because its needed for relative linked blends to be found */
942 char filename[FILE_MAXDIR + FILE_MAXFILE];
943 BLI_strncpy(filename, argv[0], sizeof(filename));
944 BLI_path_cwd(filename);
947 int retval = BKE_read_file(C, filename, NULL);
949 /*we successfully loaded a blend file, get sure that
951 if (retval != BKE_READ_FILE_FAIL) {
952 wmWindowManager *wm= CTX_wm_manager(C);
954 /* special case, 2.4x files */
955 if(wm==NULL && CTX_data_main(C)->wm.first==NULL) {
956 extern void wm_add_default(bContext *C);
958 /* wm_add_default() needs the screen to be set. */
959 CTX_wm_screen_set(C, CTX_data_main(C)->screen.first);
963 CTX_wm_manager_set(C, NULL); /* remove wm to force check */
966 if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */
968 DAG_on_visible_update(CTX_data_main(C), TRUE);
971 /* WM_read_file() runs normally but since we're in background mode do here */
973 /* run any texts that were loaded in and flagged as modules */
975 BPY_app_handlers_reset();
976 BPY_modules_load_user(C);
979 /* happens for the UI on file reading too (huh? (ton))*/
980 // XXX BKE_reset_undo();
981 // BKE_write_undo("original"); /* save current state */
983 /* we are not running in background mode here, but start blender in UI mode with
984 a file - this should do everything a 'load file' does */
986 BKE_reports_init(&reports, RPT_PRINT);
987 WM_read_file(C, filename, &reports);
988 BKE_reports_clear(&reports);
996 static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
998 static char output_doc[] = "<path>"
999 "\n\tSet the render path and file name."
1000 "\n\tUse // at the start of the path to"
1001 "\n\t\trender relative to the blend file."
1002 "\n\tThe # characters are replaced by the frame number, and used to define zero padding."
1003 "\n\t\tani_##_test.png becomes ani_01_test.png"
1004 "\n\t\ttest-######.png becomes test-000001.png"
1005 "\n\t\tWhen the filename does not contain #, The suffix #### is added to the filename"
1006 "\n\tThe frame number will be added at the end of the filename."
1007 "\n\t\teg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a"
1008 "\n\t\t//render_ becomes //render_####, writing frames as //render_0001.png//";
1010 static char format_doc[] = "<format>"
1011 "\n\tSet the render format, Valid options are..."
1012 "\n\t\tTGA IRIS JPEG MOVIE IRIZ RAWTGA"
1013 "\n\t\tAVIRAW AVIJPEG PNG BMP FRAMESERVER"
1014 "\n\t(formats that can be compiled into blender, not available on all systems)"
1015 "\n\t\tHDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS";
1017 static char playback_doc[] = "<options> <file(s)>"
1018 "\n\tPlayback <file(s)>, only operates this way when not running in background."
1019 "\n\t\t-p <sx> <sy>\tOpen with lower left corner at <sx>, <sy>"
1020 "\n\t\t-m\t\tRead from disk (Don't buffer)"
1021 "\n\t\t-f <fps> <fps-base>\t\tSpecify FPS to start with"
1022 "\n\t\t-j <frame>\tSet frame step to <frame>";
1024 static char game_doc[] = "Game Engine specific options"
1025 "\n\t-g fixedtime\t\tRun on 50 hertz without dropping frames"
1026 "\n\t-g vertexarrays\t\tUse Vertex Arrays for rendering (usually faster)"
1027 "\n\t-g nomipmap\t\tNo Texture Mipmapping"
1028 "\n\t-g linearmipmap\t\tLinear Texture Mipmapping instead of Nearest (default)";
1030 static char debug_doc[] = "\n\tTurn debugging on\n"
1031 "\n\t* Prints every operator call and their arguments"
1032 "\n\t* Disables mouse grab (to interact with a debugger in some cases)"
1033 "\n\t* Keeps python sys.stdin rather than setting it to None";
1035 //BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C);
1037 /* end argument processing after -- */
1038 BLI_argsAdd(ba, -1, "--", NULL, "\n\tEnds option processing, following arguments passed unchanged. Access via python's sys.argv", end_arguments, NULL);
1040 /* first pass: background mode, disable python and commands that exit after usage */
1041 BLI_argsAdd(ba, 1, "-h", "--help", "\n\tPrint this help text and exit", print_help, ba);
1043 BLI_argsAdd(ba, 1, "/?", NULL, "\n\tPrint this help text and exit (windows only)", print_help, ba);
1045 BLI_argsAdd(ba, 1, "-v", "--version", "\n\tPrint Blender version and exit", print_version, NULL);
1047 /* only to give help message */
1048 #ifndef WITH_PYTHON_SECURITY /* default */
1049 # define PY_ENABLE_AUTO ", (default)"
1050 # define PY_DISABLE_AUTO ""
1052 # define PY_ENABLE_AUTO ""
1053 # define PY_DISABLE_AUTO ", (compiled as non-standard default)"
1056 BLI_argsAdd(ba, 1, "-y", "--enable-autoexec", "\n\tEnable automatic python script execution" PY_ENABLE_AUTO, enable_python, NULL);
1057 BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers, pyconstraints, pynodes)" PY_DISABLE_AUTO, disable_python, NULL);
1059 #undef PY_ENABLE_AUTO
1060 #undef PY_DISABLE_AUTO
1062 BLI_argsAdd(ba, 1, "-b", "--background", "<file>\n\tLoad <file> in background (often used for UI-less rendering)", background_mode, NULL);
1064 BLI_argsAdd(ba, 1, "-a", NULL, playback_doc, playback_mode, NULL);
1066 BLI_argsAdd(ba, 1, "-d", "--debug", debug_doc, debug_mode, ba);
1067 BLI_argsAdd(ba, 1, NULL, "--debug-fpe", "\n\tEnable floating point exceptions", set_fpe, NULL);
1069 BLI_argsAdd(ba, 1, NULL, "--factory-startup", "\n\tSkip reading the "STRINGIFY(BLENDER_STARTUP_FILE)" in the users home directory", set_factory_startup, NULL);
1071 /* TODO, add user env vars? */
1072 BLI_argsAdd(ba, 1, NULL, "--env-system-datafiles", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_DATAFILES)" environment variable", set_env, NULL);
1073 BLI_argsAdd(ba, 1, NULL, "--env-system-scripts", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_SCRIPTS)" environment variable", set_env, NULL);
1074 BLI_argsAdd(ba, 1, NULL, "--env-system-plugins", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PLUGINS)" environment variable", set_env, NULL);
1075 BLI_argsAdd(ba, 1, NULL, "--env-system-python", "\n\tSet the "STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON)" environment variable", set_env, NULL);
1077 /* second pass: custom window stuff */
1078 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);
1079 BLI_argsAdd(ba, 2, "-w", "--window-border", "\n\tForce opening with borders (default)", with_borders, NULL);
1080 BLI_argsAdd(ba, 2, "-W", "--window-borderless", "\n\tForce opening without borders", without_borders, NULL);
1081 BLI_argsAdd(ba, 2, "-con", "--start-console", "\n\tStart with the console window open (ignored if -b is set)", start_with_console, NULL);
1082 BLI_argsAdd(ba, 2, "-R", NULL, "\n\tRegister .blend extension, then exit (Windows only)", register_extension, NULL);
1083 BLI_argsAdd(ba, 2, "-r", NULL, "\n\tSilently register .blend extension, then exit (Windows only)", register_extension, ba);
1085 /* third pass: disabling things and forcing settings */
1086 BLI_argsAddCase(ba, 3, "-nojoystick", 1, NULL, 0, "\n\tDisable joystick support", no_joystick, syshandle);
1087 BLI_argsAddCase(ba, 3, "-noglsl", 1, NULL, 0, "\n\tDisable GLSL shading", no_glsl, NULL);
1088 BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, "\n\tForce sound system to None", no_audio, NULL);
1089 BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, "\n\tForce sound system to a specific device\n\tNULL SDL OPENAL JACK", set_audio, NULL);
1091 /* fourth pass: processing arguments */
1092 BLI_argsAdd(ba, 4, "-g", NULL, game_doc, set_ge_parameters, syshandle);
1093 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);
1094 BLI_argsAdd(ba, 4, "-a", "--render-anim", "\n\tRender frames from start to end (inclusive)", render_animation, C);
1095 BLI_argsAdd(ba, 4, "-S", "--scene", "<name>\n\tSet the active scene <name> for rendering", set_scene, C);
1096 BLI_argsAdd(ba, 4, "-s", "--frame-start", "<frame>\n\tSet start to frame <frame> (use before the -a argument)", set_start_frame, C);
1097 BLI_argsAdd(ba, 4, "-e", "--frame-end", "<frame>\n\tSet end to frame <frame> (use before the -a argument)", set_end_frame, C);
1098 BLI_argsAdd(ba, 4, "-j", "--frame-jump", "<frames>\n\tSet number of frames to step forward after each rendered frame", set_skip_frame, C);
1099 BLI_argsAdd(ba, 4, "-P", "--python", "<filename>\n\tRun the given Python script (filename or Blender Text)", run_python, C);
1100 BLI_argsAdd(ba, 4, NULL, "--python-console", "\n\tRun blender with an interactive console", run_python_console, C);
1101 BLI_argsAdd(ba, 4, NULL, "--addons", "\n\tComma separated list of addons (no spaces)", set_addons, C);
1103 BLI_argsAdd(ba, 4, "-o", "--render-output", output_doc, set_output, C);
1104 BLI_argsAdd(ba, 4, "-E", "--engine", "<engine>\n\tSpecify the render engine\n\tuse -E help to list available engines", set_engine, C);
1106 BLI_argsAdd(ba, 4, "-F", "--render-format", format_doc, set_image_type, C);
1107 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);
1108 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);
1112 #ifdef WITH_PYTHON_MODULE
1113 /* allow python module to call main */
1114 #define main main_python_enter
1115 static void *evil_C= NULL;
1118 int main(int argc, const char **argv)
1120 SYS_SystemHandle syshandle;
1121 bContext *C= CTX_create();
1124 #ifdef WITH_PYTHON_MODULE
1129 #ifdef WITH_BINRELOC
1135 /* patch to ignore argument finder gives us (pid?) */
1136 if (argc==2 && strncmp(argv[1], "-psn_", 5)==0) {
1137 extern int GHOST_HACK_getFirstFile(char buf[]);
1138 static char firstfilebuf[512];
1142 if (GHOST_HACK_getFirstFile(firstfilebuf)) {
1144 argv[1]= firstfilebuf;
1154 // initialize path to executable
1155 BLI_init_program_path(argv[0]);
1157 BLI_threadapi_init();
1162 /* Hack - force inclusion of the plugin api functions,
1163 * see blenpluginapi:pluginapi.c
1165 pluginapi_force_ref();
1169 initglobals(); /* blender.c */
1175 #ifdef WITH_GAMEENGINE
1176 syshandle = SYS_GetSystem();
1181 /* first test for background */
1182 ba = BLI_argsInit(argc, argv); /* skip binary path */
1183 setupArguments(C, ba, &syshandle);
1185 BLI_argsParse(ba, 1, NULL, NULL);
1187 #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
1188 G.background= 1; /* python module mode ALWAYS runs in background mode (for now) */
1190 /* for all platforms, even windos has it! */
1191 if(G.background) signal(SIGINT, blender_esc); /* ctrl c out bg render */
1194 /* background render uses this font too */
1195 BKE_font_register_builtin(datatoc_Bfont, datatoc_Bfont_size);
1197 /* Initialiaze ffmpeg if built in, also needed for bg mode if videos are
1198 rendered via ffmpeg */
1201 init_def_material();
1203 if(G.background==0) {
1204 BLI_argsParse(ba, 2, NULL, NULL);
1205 BLI_argsParse(ba, 3, NULL, NULL);
1207 WM_init(C, argc, argv);
1209 /* this is properly initialized with user defs, but this is default */
1210 /* call after loading the startup.blend so we can read U.tempdir */
1211 BLI_init_temporary_dir(U.tempdir);
1214 BLI_setenv("SDL_VIDEODRIVER", "dummy");
1218 BLI_argsParse(ba, 3, NULL, NULL);
1220 WM_init(C, argc, argv);
1222 /* don't use user preferences temp dir */
1223 BLI_init_temporary_dir(NULL);
1227 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
1228 * so we provide the BPY_ function below to append the user defined
1229 * pythondir to Python's sys.path at this point. Simply putting
1230 * WM_init() before BPY_python_start() crashes Blender at startup.
1231 * Update: now this function also inits the bpymenus, which also depend
1235 // TODO - U.pythondir
1237 printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
1240 CTX_py_init_set(C, 1);
1243 /* OK we are ready for it */
1244 BLI_argsParse(ba, 4, load_file, C);
1248 #ifdef WITH_PYTHON_MODULE
1249 return 0; /* keep blender in background mode running */
1253 /* actually incorrect, but works for now (ton) */
1258 if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
1263 else if(!G.file_loaded)
1270 /*XXX if (scr_init==0) {
1274 screenmain();*/ /* main display loop */
1277 } /* end of int main(argc,argv) */
1279 #ifdef WITH_PYTHON_MODULE
1280 void main_python_exit(void)
1282 WM_exit((bContext *)evil_C);
1287 static void error_cb(const char *err)
1290 printf("%s\n", err); /* XXX do this in WM too */
1293 static void mem_error_cb(const char *errorStr)
1295 fputs(errorStr, stderr);
1299 static void setCallbacks(void)
1301 /* Error output from the alloc routines: */
1302 MEM_set_error_callback(mem_error_cb);
1307 BLI_setErrorCallBack(error_cb); /* */
1308 // XXX BLI_setInterruptCallBack(blender_test_break);