diff --git a/sdk/jme3-blender/nbproject/genfiles.properties b/sdk/jme3-blender/nbproject/genfiles.properties
index 88bad040b..9227dac3e 100644
--- a/sdk/jme3-blender/nbproject/genfiles.properties
+++ b/sdk/jme3-blender/nbproject/genfiles.properties
@@ -1,8 +1,8 @@
-build.xml.data.CRC32=6f271b27
+build.xml.data.CRC32=d6432352
build.xml.script.CRC32=0f77a514
-build.xml.stylesheet.CRC32=a56c6a5b@2.49.1
+build.xml.stylesheet.CRC32=a56c6a5b@2.50.1
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=6f271b27
+nbproject/build-impl.xml.data.CRC32=d6432352
nbproject/build-impl.xml.script.CRC32=5c5042d6
-nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.49.1
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.50.1
diff --git a/sdk/jme3-blender/nbproject/project.xml b/sdk/jme3-blender/nbproject/project.xml
index 769fb02c8..4b078e2ba 100644
--- a/sdk/jme3-blender/nbproject/project.xml
+++ b/sdk/jme3-blender/nbproject/project.xml
@@ -74,6 +74,14 @@
7.0
+
+ org.openide.modules
+
+
+
+ 7.32.1
+
+
org.openide.nodes
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderDataObject.java b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderDataObject.java
index e4b933726..d193cdd47 100644
--- a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderDataObject.java
+++ b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderDataObject.java
@@ -8,10 +8,21 @@ import com.jme3.asset.BlenderKey;
import com.jme3.asset.ModelKey;
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.loaders.DataObject.Registration;
import org.openide.loaders.DataObjectExistsException;
import org.openide.loaders.MultiFileLoader;
+//TODO: move this new way of registering to core
+@Registration(displayName = "CTL_OpenInBlender", iconBase = "com/jme3/gde/blender/blender.png", mimeType = "application/blender")
+@ActionReferences(value = {
+ @ActionReference(id =
+ @ActionID(category = "jMonkeyPlatform", id = "com.jme3.gde.core.assets.actions.ConvertModel"), path = "Loaders/application/blender/Actions", position = 10),
+ @ActionReference(id =
+ @ActionID(category = "jMonkeyPlatform", id = "com.jme3.gde.core.assets.actions.OpenModel"), path = "Loaders/application/blender/Actions", position = 20)})
public class BlenderDataObject extends SpatialAssetDataObject {
public BlenderDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java
new file mode 100644
index 000000000..9cb0dabd8
--- /dev/null
+++ b/sdk/jme3-blender/src/com/jme3/gde/blender/BlenderTool.java
@@ -0,0 +1,130 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.blender;
+
+import com.jme3.math.Vector3f;
+import java.io.File;
+import java.io.IOException;
+import java.util.logging.Logger;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.filesystems.FileObject;
+import org.openide.modules.InstalledFileLocator;
+import org.openide.util.Exceptions;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class BlenderTool {
+
+ private static final Logger logger = Logger.getLogger(BlenderTool.class.getName());
+ private static boolean running = false;
+// private static AtomicBoolean running = new AtomicBoolean(false);
+
+ private static String getBlenderExeName() {
+ if (Utilities.isWindows()) {
+ return "blender.exe";
+ } else {
+ return "blender";
+ }
+ }
+
+ 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!"));
+ }
+ return blender;
+ }
+
+ public static File getBlenderSettingsFolder() {
+ File blender = InstalledFileLocator.getDefault().locate("../blender/2.64", null, false);
+ if (blender == null) {
+ DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender!"));
+ }
+ 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);
+ if (blender == null) {
+ DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message("Error finding Blender!"));
+ }
+ return blender;
+
+ }
+
+ public static boolean openInBlender(FileObject file){
+ String path = file.getPath().replace("/", File.separator);
+ return runBlender(path, true);
+ }
+
+ public static boolean runBlender(final String options, boolean async) {
+ if (running) {
+ return false;
+ }
+ running = true;
+ //TODO: wtf, for some reason i cannot access AtomicBoolean..
+ final Vector3f v = new Vector3f(0, 0, 0);
+ final File exe = getBlenderExecutable();
+ if (exe == null) {
+ return false;
+ }
+ 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);
+ OutputReader outReader = new OutputReader(proc.getInputStream());
+// outReader.setProgress(handle);
+ OutputReader errReader = new OutputReader(proc.getErrorStream());
+// errReader.setProgress(handle);
+ outReader.start();
+ errReader.start();
+ try {
+ proc.waitFor();
+ } catch (InterruptedException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ if (proc.exitValue() != 0) {
+ v.x = 1;
+ }
+ running = false;
+ } catch (IOException ex) {
+ Exceptions.printStackTrace(ex);
+ v.x = 1;
+ running = false;
+ }
+ }
+ };
+ if (async) {
+ new Thread(r).start();
+ } else {
+ r.run();
+ }
+ if (v.x != 1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static void runBlender() {
+ if(!runBlender(null, true)){
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error running Blender."));
+ }
+ }
+}
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/Bundle.properties b/sdk/jme3-blender/src/com/jme3/gde/blender/Bundle.properties
index 177d85515..e9112ba65 100644
--- a/sdk/jme3-blender/src/com/jme3/gde/blender/Bundle.properties
+++ b/sdk/jme3-blender/src/com/jme3/gde/blender/Bundle.properties
@@ -5,4 +5,4 @@ OpenIDE-Module-Long-Description=\
OpenIDE-Module-Name=Blender Support
OpenIDE-Module-Short-Description=Adds support for Blender .blend files
Services/MIMEResolver/BlenderResolver.xml=Blender Files
-Templates/Other/BlenderTemplate.blend=Empty Blender file
+Templates/Other/tpl_box.blend=Basic Box Blender file
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/OpenInBlender.java b/sdk/jme3-blender/src/com/jme3/gde/blender/OpenInBlender.java
new file mode 100644
index 000000000..b6fc7f7f8
--- /dev/null
+++ b/sdk/jme3-blender/src/com/jme3/gde/blender/OpenInBlender.java
@@ -0,0 +1,43 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.blender;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.awt.ActionReferences;
+import org.openide.awt.ActionRegistration;
+import org.openide.util.NbBundle.Messages;
+
+@ActionID(
+ category = "jMonkeyEngine",
+id = "com.jme3.gde.blender.OpenBlender")
+@ActionRegistration(
+ iconBase = "com/jme3/gde/blender/blender.png",
+displayName = "#CTL_OpenInBlender")
+@ActionReferences({
+ @ActionReference(path = "Menu/Tools", position = 3333),
+ @ActionReference(path = "Toolbars/File", position = 335),
+ @ActionReference(path = "Loaders/application/blender/Actions", position = 30)
+})
+@Messages("CTL_OpenInBlender=Open in Blender")
+public final class OpenInBlender implements ActionListener {
+
+ private final BlenderDataObject context;
+
+ public OpenInBlender(BlenderDataObject context) {
+ this.context = context;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent ev) {
+ if (!BlenderTool.openInBlender(context.getPrimaryFile())) {
+ DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error opening Blender with file " + context.getPrimaryFile().getNameExt()));
+ }
+ }
+}
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/OutputReader.java b/sdk/jme3-blender/src/com/jme3/gde/blender/OutputReader.java
new file mode 100644
index 000000000..f363fcd33
--- /dev/null
+++ b/sdk/jme3-blender/src/com/jme3/gde/blender/OutputReader.java
@@ -0,0 +1,60 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.gde.blender;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.netbeans.api.progress.ProgressHandle;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class OutputReader implements Runnable {
+
+ private Thread thread;
+ private BufferedReader in;
+ private ProgressHandle progress;
+
+ public OutputReader(InputStream in) {
+ this.in = new BufferedReader(new InputStreamReader(in));
+ }
+
+ public OutputReader(BufferedReader in) {
+ this.in = in;
+ }
+
+ public void start() {
+ thread = new Thread(this);
+ thread.start();
+ }
+
+ public void run() {
+ try {
+ String line;
+ while ((line = in.readLine()) != null) {
+ if (line.trim().length() > 0) {
+ if (progress != null) {
+ progress.progress(line);
+ } else {
+ Logger.getLogger(OutputReader.class.getName()).log(Level.INFO, "{0}",line);
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * @param progress the progress to set
+ */
+ public void setProgress(ProgressHandle progress) {
+ this.progress = progress;
+ }
+}
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/blender24.png b/sdk/jme3-blender/src/com/jme3/gde/blender/blender24.png
new file mode 100644
index 000000000..b1aa3d40b
Binary files /dev/null and b/sdk/jme3-blender/src/com/jme3/gde/blender/blender24.png differ
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/blender48.png b/sdk/jme3-blender/src/com/jme3/gde/blender/blender48.png
new file mode 100644
index 000000000..4974c3fe4
Binary files /dev/null and b/sdk/jme3-blender/src/com/jme3/gde/blender/blender48.png differ
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/layer.xml b/sdk/jme3-blender/src/com/jme3/gde/blender/layer.xml
index eba718d29..b116aec6f 100644
--- a/sdk/jme3-blender/src/com/jme3/gde/blender/layer.xml
+++ b/sdk/jme3-blender/src/com/jme3/gde/blender/layer.xml
@@ -1,82 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -84,4 +8,12 @@
+
+
+
+
+
+
+
+
diff --git a/sdk/jme3-blender/src/com/jme3/gde/blender/tpl_box.blend b/sdk/jme3-blender/src/com/jme3/gde/blender/tpl_box.blend
new file mode 100644
index 000000000..13a44b23e
Binary files /dev/null and b/sdk/jme3-blender/src/com/jme3/gde/blender/tpl_box.blend differ