- improve BlenderTool

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10224 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
nor..67 12 years ago
parent 9486205419
commit 0617e63637
  1. 269
      sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java

@ -1,6 +1,118 @@
/* /*
* To change this template, choose Tools | Templates Blender Options:
* and open the template in the editor. -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; package com.jme3.gde.blender;
@ -14,17 +126,24 @@ import java.util.logging.Logger;
import org.openide.DialogDisplayer; import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor; import org.openide.NotifyDescriptor;
import org.openide.filesystems.FileObject; import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.modules.InstalledFileLocator; import org.openide.modules.InstalledFileLocator;
import org.openide.util.Exceptions; import org.openide.util.Exceptions;
import org.openide.util.Utilities; import org.openide.util.Utilities;
import org.openide.windows.WindowManager; import org.openide.windows.WindowManager;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
/** /**
* *
* @author normenhansen * @author normenhansen
*/ */
public class BlenderTool { 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 final Logger logger = Logger.getLogger(BlenderTool.class.getName());
private static boolean running = false; private static boolean running = false;
private static Window blenderWindow = null; private static Window blenderWindow = null;
@ -37,58 +156,109 @@ public class BlenderTool {
} }
} }
public static File getBlenderExecutable() { private static String getBlenderOsPath() {
File blender = InstalledFileLocator.getDefault().locate("../blender/" + getBlenderExeName(), null, false); if (Utilities.isMac()) {
if (blender == null) { return "../blender/blender.app/Contents/MacOS";
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender executable at\n" + blender.getPath())); } else {
logger.log(Level.SEVERE, "Error finding Blender executable at {0}", blender.getPath()); return "../blender";
} }
return blender;
} }
public static File getBlenderSettingsFolder() { private static boolean checkBlenderFolders() {
File blender = InstalledFileLocator.getDefault().locate("../blender/2.64", null, false); 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) { if (blender == null) {
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings at\n" + blender.getPath())); DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender executable"));
logger.log(Level.SEVERE, "Error finding Blender settings at {0}", blender.getPath()); logger.log(Level.SEVERE, "Error finding Blender executable");
} }
return blender; return blender;
} }
public static File getBlenderRootFolder() { private static File getBlenderSettingsFolder() {
// File appFolder = InstalledFileLocator.getDefault().locate("bin", null, false).getParentFile().getParentFile(); File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.64", null, false);
// if (appFolder != null) {
// DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(appFolder.toString()));
// }
File blender = InstalledFileLocator.getDefault().locate("../blender", null, false);
if (blender == null) { if (blender == null) {
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender root folder at\n" + blender.getPath())); DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings"));
logger.log(Level.SEVERE, "Error finding Blender root folder at {0}", blender.getPath()); logger.log(Level.SEVERE, "Error finding Blender settings");
} }
return blender; return blender;
} }
public static boolean openInBlender(FileObject file) { private static File getBlenderRootFolder() {
String path = file.getPath().replace("/", File.separator); File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath(), null, false);
return runBlender(path, true); 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) { private static void setBlendWin(Window win) {
blenderWindow = win; blenderWindow = win;
} }
public static boolean blenderToFront() { private static boolean runBlender(final String options, boolean async) {
Window win = blenderWindow; if (!checkBlenderFolders()) {
if (win != null) { logger.log(Level.SEVERE, "Could not create blender settings folders!");
logger.log(Level.INFO, "Request focus of Blender window {0}", win);
win.requestFocus();
return true;
} }
return false;
}
public static boolean runBlender(final String options, boolean async) {
logger.log(Level.INFO, "Try running blender with options {0}", options); logger.log(Level.INFO, "Try running blender with options {0}", options);
if (running) { if (running) {
logger.log(Level.INFO, "Blender seems to be running"); logger.log(Level.INFO, "Blender seems to be running");
@ -123,13 +293,13 @@ public class BlenderTool {
Runnable r = new Runnable() { Runnable r = new Runnable() {
public void run() { public void run() {
try { try {
String command = null; String command = exe.getAbsolutePath();
if (options != null) { ProcessBuilder buildr = new ProcessBuilder(command, options);
command = exe.getAbsolutePath() + " " + options; buildr.directory(getBlenderRootFolder());
} else { buildr.environment().put("BLENDER_USER_CONFIG", getConfigEnv());
command = exe.getAbsolutePath(); buildr.environment().put("BLENDER_SYSTEM_SCRIPTS", getScriptsEnv());
} buildr.environment().put("BLENDER_USER_SCRIPTS", getUserScriptsEnv());
Process proc = Runtime.getRuntime().exec(command); Process proc = buildr.start();
OutputReader outReader = new OutputReader(proc.getInputStream()); OutputReader outReader = new OutputReader(proc.getInputStream());
OutputReader errReader = new OutputReader(proc.getErrorStream()); OutputReader errReader = new OutputReader(proc.getErrorStream());
outReader.start(); 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() { public static void runBlender() {
if (!runBlender(null, true)) { if (!runBlender(null, true)) {
logger.log(Level.INFO, "Could not run blender, already running? Trying to focus window."); logger.log(Level.INFO, "Could not run blender, already running? Trying to focus window.");

Loading…
Cancel
Save