From 74eccc7c8f312a9c2f2ee1b624d2aff0e075f4cd Mon Sep 17 00:00:00 2001 From: "nor..67" Date: Wed, 30 Jan 2013 03:09:22 +0000 Subject: [PATCH] SDK: - add model import via blender - add support dor 3ds, dae to SDK git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10237 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../BlenderAssetManagerConfigurator.java | 1 + .../src/com/jme3/gde/blender/BlenderTool.java | 96 ++++++++++++++++--- .../AbstractBlenderAssetDataObject.java | 91 ++++++++++++++++++ .../filetypes/Blender3dsDataObject.java | 89 +++++++++++++++++ .../filetypes/BlenderDaeDataObject.java | 92 ++++++++++++++++++ .../com/jme3/gde/blender/scripts/Scripts.java | 64 +++++++++++++ .../jme3/gde/blender/scripts/import_3ds.py | 86 +++++++++++++++++ .../jme3/gde/blender/scripts/import_dae.py | 86 +++++++++++++++++ 8 files changed, 593 insertions(+), 12 deletions(-) create mode 100644 sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/AbstractBlenderAssetDataObject.java create mode 100644 sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/Blender3dsDataObject.java create mode 100644 sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/BlenderDaeDataObject.java create mode 100644 sdk/jme3-blender/src/com/jme3/gde/blender/scripts/Scripts.java create mode 100644 sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_3ds.py create mode 100644 sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_dae.py diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderAssetManagerConfigurator.java b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderAssetManagerConfigurator.java index 71d7e774a..b9e4225f2 100644 --- a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderAssetManagerConfigurator.java +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderAssetManagerConfigurator.java @@ -16,5 +16,6 @@ public class BlenderAssetManagerConfigurator implements AssetManagerConfigurator public void prepareManager(AssetManager manager) { manager.registerLoader(com.jme3.scene.plugins.blender.BlenderModelLoader.class, "blend"); + manager.registerLoader(com.jme3.scene.plugins.blender.BlenderModelLoader.class, BlenderTool.TEMP_SUFFIX); } } diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java index 4f7c10494..3ba6d63dc 100644 --- a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java @@ -116,6 +116,7 @@ */ package com.jme3.gde.blender; +import com.jme3.gde.blender.scripts.Scripts; import com.jme3.math.Vector3f; import java.awt.Frame; import java.awt.Window; @@ -133,15 +134,18 @@ 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 { + public static final String TEMP_SUFFIX = "blend"; private static final String mainFolderName = "blender"; private static final String configFolderName = mainFolderName + "/config"; private static final String scriptsFolderName = mainFolderName + "/scripts"; + private static final String jmeScriptsFolderName = mainFolderName + "/jmescripts"; private static final String userScriptsFolderName = mainFolderName + "/userscripts"; private static final String tempFolderName = mainFolderName + "/temp"; private static final Logger logger = Logger.getLogger(BlenderTool.class.getName()); @@ -171,32 +175,42 @@ public class BlenderTool { 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 scriptsFileObject = fileObject.getFileObject(scriptsFolderName); + FileObject jmeScriptsFileObject = fileObject.getFileObject(jmeScriptsFolderName); FileObject userScriptsFileObject = fileObject.getFileObject(userScriptsFolderName); if (configFileObject == null) { try { - FileUtil.createFolder(fileObject, configFolderName); + configFileObject = FileUtil.createFolder(fileObject, configFolderName); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + return false; + } + } + if (scriptsFileObject == null) { + try { + scriptsFileObject = FileUtil.createFolder(fileObject, scriptsFolderName); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + return false; + } + } + if (jmeScriptsFileObject == null) { + try { + jmeScriptsFileObject = FileUtil.createFolder(fileObject, jmeScriptsFolderName); } 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); + userScriptsFileObject = FileUtil.createFolder(fileObject, userScriptsFolderName); } catch (IOException ex) { Exceptions.printStackTrace(ex); return false; } } + Scripts.copyToFolder(jmeScriptsFileObject); } else { logger.log(Level.SEVERE, "No global settings folder found!"); return false; @@ -224,6 +238,18 @@ public class BlenderTool { return ret; } + private static String getJmeUserScriptPath(String scriptName) { + String ret = System.getProperty("netbeans.user") + "/" + jmeScriptsFolderName + "/" + scriptName; + ret = ret.replace("/", File.separator); + return ret; + } + + private static String getImportScriptPath(String scriptName) { + String ret = System.getProperty("netbeans.user") + "/" + jmeScriptsFolderName + "/" + "import_" + scriptName + ".py"; + ret = ret.replace("/", File.separator); + return ret; + } + private static File getBlenderExecutable() { File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/" + getBlenderExeName(), null, false); if (blender == null) { @@ -234,7 +260,7 @@ public class BlenderTool { } private static File getBlenderSettingsFolder() { - File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.64", null, false); + File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/2.65", null, false); if (blender == null) { DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings")); logger.log(Level.SEVERE, "Error finding Blender settings"); @@ -255,6 +281,52 @@ public class BlenderTool { blenderWindow = win; } + public static boolean runConversionScript(String type, FileObject input) { + if (!checkBlenderFolders()) { + logger.log(Level.SEVERE, "Could not create blender settings folders!"); + } + final File exe = getBlenderExecutable(); + if (exe == null) { + logger.log(Level.SEVERE, "Could not find blender executable!"); + return false; + } + logger.log(Level.INFO, "Try running blender as converter for file {0}", input.getPath()); + String scriptPath = getImportScriptPath(type); + String inputPath = input.getPath().replace("/", File.separator); + String inputFolder = input.getParent().getPath().replace("/", File.separator) + File.separator; + String outputPath = inputFolder + input.getName() + "." + TEMP_SUFFIX; + try { + String command = exe.getAbsolutePath(); + ProcessBuilder buildr = new ProcessBuilder(command, "-b", + "--factory-startup", + "-P", scriptPath, + "--", + "-i", inputPath, + "-o", outputPath); + 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(); + errReader.start(); + try { + proc.waitFor(); + } catch (InterruptedException ex) { + Exceptions.printStackTrace(ex); + } + if (proc.exitValue() != 0) { + logger.log(Level.SEVERE, "Error running blender!"); + return false; + } + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + return true; + } + private static boolean runBlender(final String options, boolean async) { if (!checkBlenderFolders()) { logger.log(Level.SEVERE, "Could not create blender settings folders!"); diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/AbstractBlenderAssetDataObject.java b/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/AbstractBlenderAssetDataObject.java new file mode 100644 index 000000000..1d6db7f23 --- /dev/null +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/AbstractBlenderAssetDataObject.java @@ -0,0 +1,91 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.blender.filetypes; + +import com.jme3.gde.blender.BlenderTool; +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.assets.SpatialAssetDataObject; +import com.jme3.scene.Spatial; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.logging.Level; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.filesystems.FileLock; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.loaders.DataObjectExistsException; +import org.openide.loaders.MultiFileLoader; +import org.openide.util.Exceptions; + +/** + * + * @author normenhansen + */ +public abstract class AbstractBlenderAssetDataObject extends SpatialAssetDataObject { + + protected String SUFFIX; + + public AbstractBlenderAssetDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { + super(pf, loader); + } + + @Override + public Spatial loadAsset() { + if (SUFFIX == null) { + throw new IllegalStateException("Suffix for blender filetype is null! Set SUFFIX = \"sfx\" in constructor!"); + } + ProjectAssetManager mgr = getLookup().lookup(ProjectAssetManager.class); + if (mgr == null) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("File is not part of a project!\nCannot load without ProjectAssetManager.")); + return null; + } + FileObject mainFile = getPrimaryFile(); + BlenderTool.runConversionScript(SUFFIX, mainFile); + FileObject outFile = FileUtil.findBrother(mainFile, BlenderTool.TEMP_SUFFIX); + if (outFile == null) { + logger.log(Level.SEVERE, "Failed to create model, blend file cannot be found"); + return null; + } + String assetKey = mgr.getRelativeAssetPath(outFile.getPath()); + FileLock lock = null; + try { + lock = getPrimaryFile().lock(); + listListener.start(); + Spatial spatial = mgr.loadModel(assetKey); + replaceFiles(); + listListener.stop(); + savable = spatial; + return spatial; + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } finally { + if (lock != null) { + lock.releaseLock(); + } + try { + outFile.delete(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + return null; + } + + protected void replaceFiles() { + for (int i = 0; i < assetList.size(); i++) { + FileObject fileObject = assetList.get(i); + if (fileObject.hasExt(BlenderTool.TEMP_SUFFIX)) { + assetList.remove(i); + assetKeyList.remove(i); + assetList.add(i, getPrimaryFile()); + assetKeyList.add(getAssetKey()); + return; + } + } + } +} diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/Blender3dsDataObject.java b/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/Blender3dsDataObject.java new file mode 100644 index 000000000..614b2008d --- /dev/null +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/Blender3dsDataObject.java @@ -0,0 +1,89 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.blender.filetypes; + +import com.jme3.gde.core.assets.SpatialAssetDataObject; +import java.io.IOException; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectExistsException; +import org.openide.loaders.MultiFileLoader; +import org.openide.util.NbBundle.Messages; + +@Messages({ + "LBL_Blender3ds_LOADER=3DS Files (via Blender)" +}) +@MIMEResolver.ExtensionRegistration( + displayName = "#LBL_Blender3ds_LOADER", +mimeType = "application/x-3ds", +extension = {"3ds", "3DS"}) +@DataObject.Registration( + mimeType = "application/x-3ds", +iconBase = "com/jme3/gde/blender/blender.png", +displayName = "#LBL_Blender3ds_LOADER", +position = 300) +@ActionReferences({ + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.OpenAction"), + position = 100, + separatorAfter = 200), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.CutAction"), + position = 300), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"), + position = 400, + separatorAfter = 500), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"), + position = 600), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.RenameAction"), + position = 700, + separatorAfter = 800), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"), + position = 900, + separatorAfter = 1000), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"), + position = 1100, + separatorAfter = 1200), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.ToolsAction"), + position = 1300), + @ActionReference( + path = "Loaders/application/x-3ds/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"), + position = 1400) +}) +public class Blender3dsDataObject extends AbstractBlenderAssetDataObject { + + public Blender3dsDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { + super(pf, loader); + SUFFIX = "3ds"; + } +} diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/BlenderDaeDataObject.java b/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/BlenderDaeDataObject.java new file mode 100644 index 000000000..6248d06af --- /dev/null +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/filetypes/BlenderDaeDataObject.java @@ -0,0 +1,92 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.blender.filetypes; + +import java.io.IOException; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.MIMEResolver; +import org.openide.loaders.DataObject; +import org.openide.loaders.DataObjectExistsException; +import org.openide.loaders.MultiFileLoader; +import org.openide.util.NbBundle.Messages; + +/** + * + * @author normenhansen + */ +@Messages({ + "LBL_BlenderDae_LOADER=Collada Files (via Blender)" +}) +@MIMEResolver.ExtensionRegistration( + displayName = "#LBL_BlenderDae_LOADER", +mimeType = "model/vnd.collada+xml", +extension = {"dae", "DAE"}) +@DataObject.Registration( + mimeType = "model/vnd.collada+xml", +iconBase = "com/jme3/gde/blender/blender.png", +displayName = "#LBL_BlenderDae_LOADER", +position = 300) +@ActionReferences({ + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.OpenAction"), + position = 100, + separatorAfter = 200), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.CutAction"), + position = 300), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.CopyAction"), + position = 400, + separatorAfter = 500), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "Edit", id = "org.openide.actions.DeleteAction"), + position = 600), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.RenameAction"), + position = 700, + separatorAfter = 800), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.SaveAsTemplateAction"), + position = 900, + separatorAfter = 1000), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.FileSystemAction"), + position = 1100, + separatorAfter = 1200), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.ToolsAction"), + position = 1300), + @ActionReference( + path = "Loaders/model/vnd.collada+xml/Actions", + id = + @ActionID(category = "System", id = "org.openide.actions.PropertiesAction"), + position = 1400) +}) +public class BlenderDaeDataObject extends AbstractBlenderAssetDataObject { + + public BlenderDaeDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException { + super(pf, loader); + SUFFIX = "dae"; + } +} diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/Scripts.java b/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/Scripts.java new file mode 100644 index 000000000..116d424b5 --- /dev/null +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/Scripts.java @@ -0,0 +1,64 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +package com.jme3.gde.blender.scripts; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.Exceptions; + +/** + * + * @author normenhansen + */ +public class Scripts { + + private static final Logger logger = Logger.getLogger(Scripts.class.getName()); + private final static String root = "com/jme3/gde/blender/scripts/"; + + public static void copyToFolder(FileObject folder) { + if (folder == null) { + logger.log(Level.WARNING, "Got null folder for scripts check"); + return; + } + checkScript(folder, "import_3ds.py"); + checkScript(folder, "import_dae.py"); + } + + private static void checkScript(FileObject folder, String name) { + FileObject file = folder.getFileObject(name); + //TODO:check version! + if (file == null) { + try { + InputStream in = null; + OutputStream out = null; + try { + URL url = new URL("nbres:" + root + name); + file = FileUtil.createData(folder, name); + in = url.openStream(); + out = file.getOutputStream(); + FileUtil.copy(in, out); + } catch (IOException e) { + Exceptions.printStackTrace(e); + } finally { + if (in != null) { + in.close(); + } + if (out != null) { + out.close(); + } + } + logger.log(Level.INFO, "Extracted script {0}", file.getPath()); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + } +} diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_3ds.py b/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_3ds.py new file mode 100644 index 000000000..8a5433a1c --- /dev/null +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_3ds.py @@ -0,0 +1,86 @@ +# This script is an example of how you can run blender from the command line +# (in background mode with no interface) to automate tasks, in this example it +# creates a text object, camera and light, then renders and/or saves it. +# This example also shows how you can parse command line options to scripts. +# +# Example usage for this test. +# blender --background --factory-startup --python $HOME/background_job.py -- \ +# --text="Hello World" \ +# --render="/tmp/hello" \ +# --save="/tmp/hello.blend" +# +# Notice: +# '--factory-startup' is used to avoid the user default settings from +# interfearing with automated scene generation. +# +# '--' causes blender to ignore all following arguments so python can use them. +# +# See blender --help for details. + +import bpy + + +def convert_file(file_path, save_path): + bpy.ops.import_scene.autodesk_3ds(filepath = file_path) + + scene = bpy.context.scene + + try: + f = open(save_path, 'w') + f.close() + ok = True + except: + print("Cannot save to path %r" % save_path) + + import traceback + traceback.print_exc() + + if ok: + bpy.ops.wm.save_as_mainfile(filepath=save_path) + +def main(): + import sys # to get command line args + import argparse # to parse options for us and print a nice help message + + # get the args passed to blender after "--", all of which are ignored by + # blender so scripts may receive their own arguments + argv = sys.argv + + if "--" not in argv: + argv = [] # as if no args are passed + else: + argv = argv[argv.index("--") + 1:] # get all args after "--" + + # When --help or no args are given, print this help + usage_text = \ + "Run blender in background mode with this script:" + " blender --background --factory-startup --python " + __file__ + " -- [options]" + + parser = argparse.ArgumentParser(description=usage_text) + + # Possible types are: string, int, long, choice, float and complex. + parser.add_argument("-i", "--input", dest="file_path", metavar='FILE', + help="Import the specified file") + parser.add_argument("-o", "--output", dest="save_path", metavar='FILE', + help="Save the generated file to the specified path") + + args = parser.parse_args(argv) # In this example we wont use the args + + if not argv: + parser.print_help() + return + + # Clear existing objects. + scene = bpy.context.scene + scene.camera = None + for obj in scene.objects: + scene.objects.unlink(obj) + + # Run the conversion + convert_file(args.file_path, args.save_path) + + print("batch job finished, exiting") + + +if __name__ == "__main__": + main() diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_dae.py b/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_dae.py new file mode 100644 index 000000000..147b93a08 --- /dev/null +++ b/sdk/jme3-blender/src/com/jme3/gde/blender/scripts/import_dae.py @@ -0,0 +1,86 @@ +# This script is an example of how you can run blender from the command line +# (in background mode with no interface) to automate tasks, in this example it +# creates a text object, camera and light, then renders and/or saves it. +# This example also shows how you can parse command line options to scripts. +# +# Example usage for this test. +# blender --background --factory-startup --python $HOME/background_job.py -- \ +# --text="Hello World" \ +# --render="/tmp/hello" \ +# --save="/tmp/hello.blend" +# +# Notice: +# '--factory-startup' is used to avoid the user default settings from +# interfearing with automated scene generation. +# +# '--' causes blender to ignore all following arguments so python can use them. +# +# See blender --help for details. + +import bpy + + +def convert_file(file_path, save_path): + bpy.ops.wm.collada_import(filepath = file_path) + + scene = bpy.context.scene + + try: + f = open(save_path, 'w') + f.close() + ok = True + except: + print("Cannot save to path %r" % save_path) + + import traceback + traceback.print_exc() + + if ok: + bpy.ops.wm.save_as_mainfile(filepath=save_path) + +def main(): + import sys # to get command line args + import argparse # to parse options for us and print a nice help message + + # get the args passed to blender after "--", all of which are ignored by + # blender so scripts may receive their own arguments + argv = sys.argv + + if "--" not in argv: + argv = [] # as if no args are passed + else: + argv = argv[argv.index("--") + 1:] # get all args after "--" + + # When --help or no args are given, print this help + usage_text = \ + "Run blender in background mode with this script:" + " blender --background --python " + __file__ + " -- [options]" + + parser = argparse.ArgumentParser(description=usage_text) + + # Possible types are: string, int, long, choice, float and complex. + parser.add_argument("-i", "--input", dest="file_path", metavar='FILE', + help="Import the specified file") + parser.add_argument("-o", "--output", dest="save_path", metavar='FILE', + help="Save the generated file to the specified path") + + args = parser.parse_args(argv) # In this example we wont use the args + + if not argv: + parser.print_help() + return + + # Clear existing objects. + scene = bpy.context.scene + scene.camera = None + for obj in scene.objects: + scene.objects.unlink(obj) + + # Run the conversion + convert_file(args.file_path, args.save_path) + + print("batch job finished, exiting") + + +if __name__ == "__main__": + main()