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
This commit is contained in:
parent
f158717981
commit
74eccc7c8f
@ -16,5 +16,6 @@ public class BlenderAssetManagerConfigurator implements AssetManagerConfigurator
|
|||||||
|
|
||||||
public void prepareManager(AssetManager manager) {
|
public void prepareManager(AssetManager manager) {
|
||||||
manager.registerLoader(com.jme3.scene.plugins.blender.BlenderModelLoader.class, "blend");
|
manager.registerLoader(com.jme3.scene.plugins.blender.BlenderModelLoader.class, "blend");
|
||||||
|
manager.registerLoader(com.jme3.scene.plugins.blender.BlenderModelLoader.class, BlenderTool.TEMP_SUFFIX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -116,6 +116,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.gde.blender;
|
package com.jme3.gde.blender;
|
||||||
|
|
||||||
|
import com.jme3.gde.blender.scripts.Scripts;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
@ -133,15 +134,18 @@ import org.openide.util.Utilities;
|
|||||||
import org.openide.windows.WindowManager;
|
import org.openide.windows.WindowManager;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.awt.event.WindowFocusListener;
|
import java.awt.event.WindowFocusListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author normenhansen
|
* @author normenhansen
|
||||||
*/
|
*/
|
||||||
public class BlenderTool {
|
public class BlenderTool {
|
||||||
|
|
||||||
|
public static final String TEMP_SUFFIX = "blend";
|
||||||
private static final String mainFolderName = "blender";
|
private static final String mainFolderName = "blender";
|
||||||
private static final String configFolderName = mainFolderName + "/config";
|
private static final String configFolderName = mainFolderName + "/config";
|
||||||
private static final String scriptsFolderName = mainFolderName + "/scripts";
|
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 userScriptsFolderName = mainFolderName + "/userscripts";
|
||||||
private static final String tempFolderName = mainFolderName + "/temp";
|
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());
|
||||||
@ -171,32 +175,42 @@ public class BlenderTool {
|
|||||||
FileObject configFileObject = fileObject.getFileObject(configFolderName);
|
FileObject configFileObject = fileObject.getFileObject(configFolderName);
|
||||||
//TODO: using installed blender scripts folder, make more flexible by moving
|
//TODO: using installed blender scripts folder, make more flexible by moving
|
||||||
//to updateable folder
|
//to updateable folder
|
||||||
// FileObject scriptsFileObject = fileObject.getFileObject(scriptsFolderName);
|
FileObject scriptsFileObject = fileObject.getFileObject(scriptsFolderName);
|
||||||
|
FileObject jmeScriptsFileObject = fileObject.getFileObject(jmeScriptsFolderName);
|
||||||
FileObject userScriptsFileObject = fileObject.getFileObject(userScriptsFolderName);
|
FileObject userScriptsFileObject = fileObject.getFileObject(userScriptsFolderName);
|
||||||
if (configFileObject == null) {
|
if (configFileObject == null) {
|
||||||
try {
|
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) {
|
} catch (IOException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if (scriptsFileObject == null) {
|
|
||||||
// try {
|
|
||||||
// FileUtil.createFolder(fileObject, scriptsFolderName);
|
|
||||||
// } catch (IOException ex) {
|
|
||||||
// Exceptions.printStackTrace(ex);
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (userScriptsFileObject == null) {
|
if (userScriptsFileObject == null) {
|
||||||
try {
|
try {
|
||||||
FileUtil.createFolder(fileObject, userScriptsFolderName);
|
userScriptsFileObject = FileUtil.createFolder(fileObject, userScriptsFolderName);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
Exceptions.printStackTrace(ex);
|
Exceptions.printStackTrace(ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Scripts.copyToFolder(jmeScriptsFileObject);
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.SEVERE, "No global settings folder found!");
|
logger.log(Level.SEVERE, "No global settings folder found!");
|
||||||
return false;
|
return false;
|
||||||
@ -224,6 +238,18 @@ public class BlenderTool {
|
|||||||
return ret;
|
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() {
|
private static File getBlenderExecutable() {
|
||||||
File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/" + getBlenderExeName(), null, false);
|
File blender = InstalledFileLocator.getDefault().locate(getBlenderOsPath() + "/" + getBlenderExeName(), null, false);
|
||||||
if (blender == null) {
|
if (blender == null) {
|
||||||
@ -234,7 +260,7 @@ public class BlenderTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static File getBlenderSettingsFolder() {
|
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) {
|
if (blender == null) {
|
||||||
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings"));
|
DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender settings"));
|
||||||
logger.log(Level.SEVERE, "Error finding Blender settings");
|
logger.log(Level.SEVERE, "Error finding Blender settings");
|
||||||
@ -255,6 +281,52 @@ public class BlenderTool {
|
|||||||
blenderWindow = win;
|
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) {
|
private static boolean runBlender(final String options, boolean async) {
|
||||||
if (!checkBlenderFolders()) {
|
if (!checkBlenderFolders()) {
|
||||||
logger.log(Level.SEVERE, "Could not create blender settings folders!");
|
logger.log(Level.SEVERE, "Could not create blender settings folders!");
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
@ -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";
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
@ -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()
|
Loading…
x
Reference in New Issue
Block a user