Blender importer Exception

@Kaelthas , I have an exception when i load a blender scene. Can I switch CustomProperties off somehow?

I use some blender plugins which generate some CustomProperties automatically when i load a blender scene.



Model: https://rise-of-mutants.googlecode.com/hg/dev/trunk/TechDemo/blsets/Scenes/levels/level_01/level_01.blend





LOG:

20.04.2012 1:17:15 com.jme3.system.JmeDesktopSystem initialize

INFO: Running on jMonkeyEngine 3.0.0 Beta

20.04.2012 1:17:15 com.jme3.system.Natives extractNativeLibs

INFO: Extraction Directory: /home/mifth/jMonkeyProjects/rise-of-mutants/dev/trunk/TechDemo

20.04.2012 1:17:15 com.jme3.system.NullContext initInThread

INFO: NullContext created.

20.04.2012 1:17:15 com.jme3.asset.DesktopAssetManager

INFO: DesktopAssetManager created.

20.04.2012 1:17:15 com.jme3.renderer.Camera

INFO: Camera created (W: 640, H: 480)

20.04.2012 1:17:15 com.jme3.renderer.Camera

INFO: Camera created (W: 640, H: 480)

20.04.2012 1:17:16 com.jme3.scene.plugins.blender.objects.ObjectHelper toObject

INFO: Loading obejct: base2

20.04.2012 1:17:16 com.jme3.scene.plugins.blender.objects.ObjectHelper toObject

INFO: Importing mesh.

20.04.2012 1:17:16 com.jme3.scene.plugins.blender.materials.MaterialHelper toMaterial

INFO: Loading material.

20.04.2012 1:17:16 com.jme3.scene.plugins.blender.materials.MaterialHelper toMaterial

INFO: Materials name: {0}

20.04.2012 1:17:16 com.jme3.material.MaterialDef

INFO: Loaded material definition: Phong Lighting

20.04.2012 1:17:16 com.jme3.scene.Node attachChild

INFO: Child (base21) attached to this node (base2)

20.04.2012 1:17:16 com.jme3.app.Application handleError

SEVERE: Uncaught exception thrown in Thread[Headless Application Thread,5,main]

java.lang.IllegalArgumentException: Unsupported type: com.jme3.scene.plugins.blender.objects.Properties

at com.jme3.scene.UserData.getObjectType(UserData.java:98)

at com.jme3.scene.Spatial.setUserData(Spatial.java:1202)

at com.jme3.scene.plugins.blender.objects.ObjectHelper.toObject(ObjectHelper.java:279)

at com.jme3.scene.plugins.blender.AbstractBlenderLoader.toObject(AbstractBlenderLoader.java:134)

at com.jme3.scene.plugins.blender.BlenderLoader.toObject(BlenderLoader.java:70)

at com.jme3.scene.plugins.blender.BlenderModelLoader.load(BlenderModelLoader.java:63)

at com.jme3.scene.plugins.blender.BlenderModelLoader.load(BlenderModelLoader.java:49)

at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:282)

at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:406)

at com.bigboots.scene.SceneLoading.convertNow(SceneLoading.java:37)

at com.bigboots.scene.SceneLoading.(SceneLoading.java:23)

at com.bigboots.J3OConvertor.initialize(J3OConvertor.java:45)

at com.jme3.system.NullContext.initInThread(NullContext.java:85)

at com.jme3.system.NullContext.run(NullContext.java:128)

at java.lang.Thread.run(Thread.java:662)

I’ll take a look at it when I return home. Its probably a bug.

But anyway I may add a variable to BlenderKey to switch off properties loading.

1 Like

You will save me man.

@Momoko_Fan , @Kaelthas , now I cannot open my old j3o files. I suppose it happens because of blender’s Custom Properties. Recently you changed something in JME. I get such an exception with my j3o files:



SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]

java.lang.ClassCastException: com.jme3.scene.plugins.blender.objects.Properties cannot be cast to com.jme3.export.Savable

at com.jme3.export.SavableClassUtil.fromName(SavableClassUtil.java:171)

at com.jme3.export.SavableClassUtil.fromName(SavableClassUtil.java:203)

at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:330)

at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:484)

at com.jme3.export.binary.BinaryInputCapsule.readStringSavableMap(BinaryInputCapsule.java:668)

at com.jme3.scene.Spatial.read(Spatial.java:1297)

at com.jme3.scene.Node.read(Node.java:609)

at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:341)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:243)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:126)

at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:110)

at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:282)

at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:406)

at com.bigboots.scene.BBSceneComposer.loadModelNow(BBSceneComposer.java:274)

at com.bigboots.scene.BBSceneComposer.startCompose(BBSceneComposer.java:113)

at com.bigboots.scene.BBSceneComposer.(BBSceneComposer.java:60)

at com.bigboots.states.BBInGameState.loadScene(BBInGameState.java:437)

at com.bigboots.states.BBInGameState.update(BBInGameState.java:184)

at com.bigboots.states.BBStateManager.update(BBStateManager.java:223)

at com.bigboots.BBApplication.update(BBApplication.java:130)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:149)

at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:182)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:223)

at java.lang.Thread.run(Thread.java:662)





Models folder:

https://code.google.com/p/rise-of-mutants/source/browse/#hg%2Fdev%2Ftrunk%2FTechDemo%2Fassets%2FJ3O%2FModels



base2.j3o, base3.j3o, base4.j3o, base6.j3o have this exception.





Download link to these files:

https://rise-of-mutants.googlecode.com/hg/dev/trunk/TechDemo/assets/J3O/Models/base2.j3o

https://rise-of-mutants.googlecode.com/hg/dev/trunk/TechDemo/assets/J3O/Models/base3.j3o

https://rise-of-mutants.googlecode.com/hg/dev/trunk/TechDemo/assets/J3O/Models/base4.j3o

https://rise-of-mutants.googlecode.com/hg/dev/trunk/TechDemo/assets/J3O/Models/base6.j3o



Nightly build.

the culprit maybe this commit http://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/blender/com/jme3/scene/plugins/blender/objects/Properties.java?spec=svn9299&r=9299



@Momoko_Fan I don’t know what’s the problem with these user properties since it’s managed through userData. User data are per se non core…so what’s the point of this change?

The exception occurs because when the properties are attached to the spatial they are checked if they are savable or not.

If they are savable everything is fine but no-savable objects must be one of the basic types: Boolean, Integer, String, Long etc.



So the solution would be to make the Properties Savable.

Then the exception would disappear.

@Kaelthas: The issue is that these Savables are not part of the core and hence cannot be loaded by the engine when the blender lib isn’t available (which is the case for most normal distributed apps). The model importers should only create core-compatible models so it should only save normal basic types, not special Savables.

OK you’re right.



But now we need to change the way we load properties from the blender file.

I can think of several solutions:

  1. we extend the abilities of com.jme3.scene.UserData class to be able to store more data types (Map for example)
  2. we change the UserData class so that is more like the Properties class and is able to store more specific UserData
  3. we serialize the properties to a String (xml would be fine) but that would require parsing it





    Do you have any more ideas?
1 Like

We can also add a boolean to the BlenderKey that would switch off properties loading as @mifth suggested.

@Kaelthas said:
We can also add a boolean to the BlenderKey that would switch off properties loading as @mifth suggested.


I think it would be cool if CustomProperties will be switched off by default. It will solve the issue now and in future too. As nobody uses with blender's CustomProperties at present. Imho.

OK

I’ve commited the change. BlenderKey has two new methods:

[java]

public void setLoadObjectProperties(boolean loadObjectProperties);

public boolean isLoadObjectProperties();

[/java]



By default the properties are loaded (the variable value = true) so set it to false and the properties should not load.

1 Like

@Kaelthas can you make it false by default? If I convert a blender model through JMP(rightclick mouse) I will get an exception anyway.

@Kaelthas said:
Do you have any more ideas?

Just make a subset that works with jme, e.g. strings and numbers like the Ogre importer does. Whats the issue? Why would you want jme-incompatible data on your models anyway? The importer should convert it to meaningful data for jme, not pipe it through. Thats the point of an importer.

So I was also having this issue and I even posted a thread here (http://hub.jmonkeyengine.org/groups/import-assets/forum/topic/blender-user-data-not-savable/). But I was able to use Kaelthas’ new methods to disable properties loading and now the exception is gone.



Now I want to know the best way to read in saved data about things like world objects. For example, if I have roads, I previously would have stored the name of the road in Blender properties. I want people modifying the game world to be able to easily edit information about objects. I was thinking about using setUserData() on my spatials but I would need to read in the data from somewhere…

I have made a fix today.

The properties are now stored as basic types in the Spatial.

But I have a questions about UserData class.



Why there is no support for basic types like: Character, Byte, Short or Double ??

Since the stored value references an Object there should be no problem with that I belive.



And one other static method would be useful:

[java]

public static boolean isTypeSupported(Object value) {

return value instanceof Integer || value instanceof String;//… and other supported types

}

[/java]



This would help others to store appropriate data without the need of checking if no other types were added that UserData will support in the future.

But that is just a small suggestion :wink:

Thank you for the fix Kaelthas. Unfortunately, I am getting another exception when loading from a Blender file. Here is the code I use (by the way, Default.blend is just the default Blender cube):



[java]

BlenderKey blenderKey = new BlenderKey(“Models/City/Default.blend”);

//blenderKey.setLoadObjectProperties(false);

rawWorld = (Node)app.getAssetManager().loadAsset(blenderKey);[/java]



This results in the following exception:



[java]java.lang.NullPointerException

at com.jme3.scene.plugins.blender.materials.MaterialContext.<init>(MaterialContext.java:143)

at com.jme3.scene.plugins.blender.materials.MaterialHelper.toMaterialContext(MaterialHelper.java:171)

at com.jme3.scene.plugins.blender.materials.MaterialHelper.getMaterials(MaterialHelper.java:341)

at com.jme3.scene.plugins.blender.meshes.MeshHelper.toMesh(MeshHelper.java:274)

at com.jme3.scene.plugins.blender.objects.ObjectHelper.toObject(ObjectHelper.java:157)

at com.jme3.scene.plugins.blender.AbstractBlenderLoader.toObject(AbstractBlenderLoader.java:133)

at com.jme3.scene.plugins.blender.BlenderLoader.toObject(BlenderLoader.java:70)

at com.jme3.scene.plugins.blender.BlenderModelLoader.load(BlenderModelLoader.java:63)

at com.jme3.scene.plugins.blender.BlenderModelLoader.load(BlenderModelLoader.java:49)

at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:282)

at states.MainState.<init>(MainState.java:119)

at nyc3d.NYC3DApplication.initialize(NYC3DApplication.java:62)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:129)

at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:205)

at java.lang.Thread.run(Thread.java:662)[/java]



Judging from the output, this seems to be where the exception occurs (line 143 of MaterialContext.java):

[java]loadedTextures = new HashMap<Number, Texture>(sortedTextures.size());[/java]



I know this is not an issue with how I am loading the .blend file since I cannot even view the .blend file in JMP (I get an “Error opening Default.blend” message) nor convert it to a J3O file. And it looks like this is an issue with how .blend files are loaded since the file is just the default Blender cube. Anybody have any ideas?

Looks like you use really old version of the engine.



If you use the source code update to the newest version or download today’s nightly build.

The line 143 you talk about no longer exists. It was changed at the end of april.

And yesterday I made another fix that solved NPE in the region you just mentioned.



So please update your librares and tell me if the error still occurs :slight_smile:

Okay. The exception is gone. Now I have to figure out how to read properties. I get an empty list when I call getUserDataKeys() on a node that has properties. I used getUserData(“properties”) before to read properties, but this does not work anymore. Also, my properties are Strings, is that a problem?



EDIT: Turns out I was reading from the wrong file :). Properties now work for me. Also, in case anyone is unsure, the way to load properties is: getUserData(“name_of_property_here”) instead of getUserData(“properties”).findValue(“name_of_property_here”).

1 Like

@mifth: The latest version of jME3 can now load your old blender-based models

2 Likes

@Momoko_Fan , sorry for a long delay. Thanks a lot.