2
0
Эх сурвалжийг харах

SDK:
- improve BlenderTool

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10224 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

nor..67 12 жил өмнө
parent
commit
c10b6e1b52

+ 227 - 42
jme3-blender/src/com/jme3/gde/blender/BlenderTool.java

@@ -1,6 +1,118 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ Blender Options:
+ -b or --background <file>	Load <file> in background (often used for UI-less rendering)
+ -a or --render-anim 	Render frames from start to end (inclusive)
+ -S or --scene <name>	Set the active scene <name> for rendering
+ -f or --render-frame <frame>	Render frame <frame> and save it.	+<frame> start frame relative, -<frame> end frame relative.
+ -s or --frame-start <frame>	Set start to frame <frame> (use before the -a argument)
+ -e or --frame-end <frame>	Set end to frame <frame> (use before the -a argument)
+ -j or --frame-jump <frames>	Set number of frames to step forward after each rendered frame
+ -o or --render-output <path>	Set the render path and file name.	Use // at the start of the path to
+ render relative to the blend file.	The # characters are replaced by the frame number, and used to define zero padding.
+ ani_##_test.png becomes ani_01_test.png
+ test-######.png becomes test-000001.png
+ When the filename does not contain #, The suffix #### is added to the filename	The frame number will be added at the end of the filename.
+ eg: blender -b foobar.blend -o //render_ -F PNG -x 1 -a
+ //render_ becomes //render_####, writing frames as //render_0001.png//
+ -E or --engine <engine>	Specify the render engine	use -E help to list available engines
+
+ Format Options:
+ -F or --render-format <format>	Set the render format, Valid options are...
+ TGA IRIS JPEG MOVIE IRIZ RAWTGA
+ AVIRAW AVIJPEG PNG BMP FRAMESERVER	(formats that can be compiled into blender, not available on all systems)
+ HDR TIFF EXR MULTILAYER MPEG AVICODEC QUICKTIME CINEON DPX DDS
+ -x or --use-extension <bool>	Set option to add the file extension to the end of the file
+ -t or --threads <threads>	Use amount of <threads> for rendering in background	[1-64], 0 for systems processor count.
+
+ Animation Playback Options:
+ -a <options> <file(s)>	Playback <file(s)>, only operates this way when not running in background.
+ -p <sx> <sy>	Open with lower left corner at <sx>, <sy>
+ -m		Read from disk (Don't buffer)
+ -f <fps> <fps-base>		Specify FPS to start with
+ -j <frame>	Set frame step to <frame>
+
+ Window Options:
+ -w or --window-border 	Force opening with borders (default)
+ -W or --window-borderless 	Force opening without borders
+ -p or --window-geometry <sx> <sy> <w> <h>	Open with lower left corner at <sx>, <sy> and width and height as <w>, <h>
+ -con or --start-console 	Start with the console window open (ignored if -b is set)
+
+ Game Engine Specific Options:
+ -g Game Engine specific options
+ -g fixedtime		Run on 50 hertz without dropping frames
+ -g vertexarrays		Use Vertex Arrays for rendering (usually faster)
+ -g nomipmap		No Texture Mipmapping
+ -g linearmipmap		Linear Texture Mipmapping instead of Nearest (default)
+
+ Misc Options:
+ -d or --debug 	Turn debugging on
+ * Prints every operator call and their arguments
+ * Disables mouse grab (to interact with a debugger in some cases)
+ * Keeps python sys.stdin rather than setting it to None
+ --debug-fpe 	Enable floating point exceptions
+ --debug-ffmpeg 	Enable debug messages from FFmpeg library
+ --debug-libmv 	Enable debug messages from libmv library
+
+ --factory-startup 	Skip reading the "startup.blend" in the users home directory
+
+ --env-system-datafiles 	Set the BLENDER_SYSTEM_DATAFILES environment variable
+ --env-system-scripts 	Set the BLENDER_SYSTEM_SCRIPTS environment variable
+ --env-system-python 	Set the BLENDER_SYSTEM_PYTHON environment variable
+
+ -nojoystick 	Disable joystick support
+ -noglsl 	Disable GLSL shading
+ -noaudio 	Force sound system to None
+ -setaudio 	Force sound system to a specific device	NULL SDL OPENAL JACK
+
+ -h or --help 	Print this help text and exit
+
+ -y or --enable-autoexec 	Enable automatic python script execution, (default)
+ -Y or --disable-autoexec 	Disable automatic python script execution (pydrivers & startup scripts)
+
+ -P or --python <filename>	Run the given Python script (filename or Blender Text)
+ --python-console 	Run blender with an interactive console
+ --addons 	Comma separated list of addons (no spaces)
+ -v or --version 	Print Blender version and exit
+ -- 	Ends option processing, following arguments passed unchanged. Access via python's sys.argv
+ Other Options:
+ /? 	Print this help text and exit (windows only)
+ --debug-python 	Enable debug messages for python
+ --debug-events 	Enable debug messages for the event system
+ --debug-wm 	Enable debug messages for the window manager
+ --debug-all 	Enable all debug messages (excludes libmv)
+ --debug-value <value>	Set debug value of <value> on startup
+
+ --debug-jobs 	Enable time profiling for background jobs.
+ --verbose <verbose>	Set logging verbosity level.
+ -R 	Register .blend extension, then exit (Windows only)
+ -r 	Silently register .blend extension, then exit (Windows only)
+ Argument Parsing:	arguments must be separated by white space. eg
+ "blender -ba test.blend"
+ ...will ignore the 'a'
+ "blender -b test.blend -f8"
+ ...will ignore 8 because there is no space between the -f and the frame value
+ Argument Order:
+ Arguments are executed in the order they are given. eg
+ "blender --background test.blend --render-frame 1 --render-output /tmp"
+ ...will not render to /tmp because '--render-frame 1' renders before the output path is set
+ "blender --background --render-output /tmp test.blend --render-frame 1"
+ ...will not render to /tmp because loading the blend file overwrites the render output that was set
+ "blender --background test.blend --render-output /tmp --render-frame 1" works as expected.
+
+ Environment Variables:
+ $BLENDER_USER_CONFIG      Directory for user configuration files.
+ $BLENDER_USER_SCRIPTS     Directory for user scripts.
+ $BLENDER_SYSTEM_SCRIPTS   Directory for system wide scripts.
+ $Directory for user data files (icons, translations, ..).
+ $BLENDER_SYSTEM_DATAFILES Directory for system wide data files.
+ $BLENDER_SYSTEM_PYTHON    Directory for system python libraries.
+ $TMP or $TMPDIR           Store temporary files here.
+ $SDL_AUDIODRIVER          LibSDL audio driver - alsa, esd, dma.
+ $PYTHONHOME               Path to the python directory, eg. /usr/lib/python.
+
+ blender/config
+ blender/scripts
+ blender/userscripts
  */
 package com.jme3.gde.blender;
 
@@ -14,17 +126,24 @@ import java.util.logging.Logger;
 import org.openide.DialogDisplayer;
 import org.openide.NotifyDescriptor;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.modules.InstalledFileLocator;
 import org.openide.util.Exceptions;
 import org.openide.util.Utilities;
 import org.openide.windows.WindowManager;
-
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
 /**
  *
  * @author normenhansen
  */
 public class BlenderTool {
 
+    private static final String mainFolderName = "blender";
+    private static final String configFolderName = mainFolderName + "/config";
+    private static final String scriptsFolderName = mainFolderName + "/scripts";
+    private static final String userScriptsFolderName = mainFolderName + "/userscripts";
+    private static final String tempFolderName = mainFolderName + "/temp";
     private static final Logger logger = Logger.getLogger(BlenderTool.class.getName());
     private static boolean running = false;
     private static Window blenderWindow = null;
@@ -37,58 +156,109 @@ public class BlenderTool {
         }
     }
 
-    public static File getBlenderExecutable() {
-        File blender = InstalledFileLocator.getDefault().locate("../blender/" + getBlenderExeName(), null, false);
-        if (blender == null) {
-            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender executable at\n" + blender.getPath()));
-            logger.log(Level.SEVERE, "Error finding Blender executable at {0}", blender.getPath());
+    private static String getBlenderOsPath() {
+        if (Utilities.isMac()) {
+            return "../blender/blender.app/Contents/MacOS";
+        } else {
+            return "../blender";
         }
-        return blender;
     }
 
-    public static File getBlenderSettingsFolder() {
-        File blender = InstalledFileLocator.getDefault().locate("../blender/2.64", null, false);
+    private static boolean checkBlenderFolders() {
+        String jmpDir = System.getProperty("netbeans.user");
+        FileObject fileObject = FileUtil.toFileObject(new File(jmpDir));
+        if (fileObject != null) {
+            FileObject configFileObject = fileObject.getFileObject(configFolderName);
+            //TODO: using installed blender scripts folder, make more flexible by moving
+            //to updateable folder
+//            FileObject scriptsFileObject = fileObject.getFileObject(scriptsFolderName);
+            FileObject userScriptsFileObject = fileObject.getFileObject(userScriptsFolderName);
+            if (configFileObject == null) {
+                try {
+                    FileUtil.createFolder(fileObject, configFolderName);
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                    return false;
+                }
+            }
+//            if (scriptsFileObject == null) {
+//                try {
+//                    FileUtil.createFolder(fileObject, scriptsFolderName);
+//                } catch (IOException ex) {
+//                    Exceptions.printStackTrace(ex);
+//                    return false;
+//                }
+//            }
+            if (userScriptsFileObject == null) {
+                try {
+                    FileUtil.createFolder(fileObject, userScriptsFolderName);
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                    return false;
+                }
+            }
+        } else {
+            logger.log(Level.SEVERE, "No global settings folder found!");
+            return false;
+        }
+        return true;
+    }
+
+    private static String getConfigEnv() {
+        String ret = System.getProperty("netbeans.user") + "/" + configFolderName;
+        ret = ret.replace("/", File.separator);
+        return ret;
+    }
+
+    private static String getScriptsEnv() {
+        //TODO: using installed blender scripts folder
+        String ret = getBlenderSettingsFolder().getAbsolutePath();
+//        String ret = System.getProperty("netbeans.user") + "/" + scriptsFolderName;
+        ret = ret.replace("/", File.separator);
+        return ret;
+    }
+
+    private static String getUserScriptsEnv() {
+        String ret = System.getProperty("netbeans.user") + "/" + userScriptsFolderName;
+        ret = ret.replace("/", File.separator);
+        return ret;
+    }
+
+    private static File getBlenderExecutable() {
+        File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/" + getBlenderExeName(), null, false);
         if (blender == null) {
-            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings at\n" + blender.getPath()));
-            logger.log(Level.SEVERE, "Error finding Blender settings at {0}", blender.getPath());
+            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender executable"));
+            logger.log(Level.SEVERE, "Error finding Blender executable");
         }
         return blender;
     }
 
-    public static File getBlenderRootFolder() {
-//        File appFolder = InstalledFileLocator.getDefault().locate("bin", null, false).getParentFile().getParentFile();
-//        if (appFolder != null) {
-//            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(appFolder.toString()));
-//        }
-        File blender = InstalledFileLocator.getDefault().locate("../blender", null, false);
+    private static File getBlenderSettingsFolder() {
+        File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.64", null, false);
         if (blender == null) {
-            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender root folder at\n" + blender.getPath()));
-            logger.log(Level.SEVERE, "Error finding Blender root folder at {0}", blender.getPath());
+            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings"));
+            logger.log(Level.SEVERE, "Error finding Blender settings");
         }
         return blender;
-
     }
 
-    public static boolean openInBlender(FileObject file) {
-        String path = file.getPath().replace("/", File.separator);
-        return runBlender(path, true);
+    private static File getBlenderRootFolder() {
+        File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath(), null, false);
+        if (blender == null) {
+            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender root folder"));
+            logger.log(Level.SEVERE, "Error finding Blender root folder");
+        }
+        return blender;
     }
 
     private static void setBlendWin(Window win) {
         blenderWindow = win;
     }
 
-    public static boolean blenderToFront() {
-        Window win = blenderWindow;
-        if (win != null) {
-            logger.log(Level.INFO, "Request focus of Blender window {0}", win);
-            win.requestFocus();
-            return true;
+    private static boolean runBlender(final String options, boolean async) {
+        if (!checkBlenderFolders()) {
+            logger.log(Level.SEVERE, "Could not create blender settings folders!");
         }
-        return false;
-    }
-
-    public static boolean runBlender(final String options, boolean async) {
         logger.log(Level.INFO, "Try running blender with options {0}", options);
         if (running) {
             logger.log(Level.INFO, "Blender seems to be running");
@@ -123,13 +293,13 @@ public class BlenderTool {
         Runnable r = new Runnable() {
             public void run() {
                 try {
-                    String command = null;
-                    if (options != null) {
-                        command = exe.getAbsolutePath() + " " + options;
-                    } else {
-                        command = exe.getAbsolutePath();
-                    }
-                    Process proc = Runtime.getRuntime().exec(command);
+                    String command = exe.getAbsolutePath();
+                    ProcessBuilder buildr = new ProcessBuilder(command, options);
+                    buildr.directory(getBlenderRootFolder());
+                    buildr.environment().put("BLENDER_USER_CONFIG", getConfigEnv());
+                    buildr.environment().put("BLENDER_SYSTEM_SCRIPTS", getScriptsEnv());
+                    buildr.environment().put("BLENDER_USER_SCRIPTS", getUserScriptsEnv());
+                    Process proc = buildr.start();
                     OutputReader outReader = new OutputReader(proc.getInputStream());
                     OutputReader errReader = new OutputReader(proc.getErrorStream());
                     outReader.start();
@@ -174,6 +344,21 @@ public class BlenderTool {
         }
     }
 
+    public static boolean openInBlender(FileObject file) {
+        String path = "'" + file.getPath().replace("/", File.separator) + "'";
+        return runBlender(path, true);
+    }
+
+    public static boolean blenderToFront() {
+        Window win = blenderWindow;
+        if (win != null) {
+            logger.log(Level.INFO, "Request focus of Blender window {0}", win);
+            win.requestFocus();
+            return true;
+        }
+        return false;
+    }
+
     public static void runBlender() {
         if (!runBlender(null, true)) {
             logger.log(Level.INFO, "Could not run blender, already running? Trying to focus window.");