Better mesh triangulation for blender importer

Hello everyone,

first of all I’d like to say sorry for being absent for quite a long time. I had lot of stuff on my head and little time for anything else so I used the remaining hours to do as much development work on the importer as I could :wink:

Some time ago one user reported an issue with bad mesh import of mesh with N-gons. And unfortunately the user was right because the importer used the most stupid triangulation algorithm, I could think of :smiley:

I wanted to fix that some time ago but could not find any nice algorithm that would be suitable here.
I thought up such algorithm sitting on some boring GIS conference so the only thing that remained was implementation.

Because the new feature is not a trivial one I decided to do some major refactoring. In the end I found out that the code became much more simple to read an understand than it was before. It is so becaue I now use classes like Face, Edge and Point instead of builder classes that are now at the master branch. In short - I separated data aggregation from mesh building.

I guess it will be ok to get rid of the whole mesh.builders package as it is not in the 3.0 branch and will not be needed any more.
And One class - MeshContext - will be deprecated. If you have arguments against it - please tell me.

These changes will help with adding new modifiers somewhere in the future. The importer now creates an instance of TemporalMesh. This class has N-gons. It gathers data, applies modifiers and does all the crazy stuff :slight_smile: and in the end is transformed into Geometries.

The good point about this approach is the reduction of Nodes count in the final scene tree.

I hope I will be over with it soon. There are some things that still needs doing: TemporalMesh for curves and nurbs loading, some problems with animations and such stuff.

And after that I promise to get on with the improvement of IK constraint algorithm :wink:
I know it is an important feature but I simply did not want to start two things at once and triangulation algorithm turned out a little more difficult than I have predicted.

Please be patient for a while longer.
Cheers,
Marcin

9 Likes

Great news :smiley:

Yeah, you can pretty much do anything you want inside the blender importer, its basically a black box for the rest of the engine and due to the AWT dependency not meant for a game projects runtime anyway, also because the .blend format definitely isn’t a good distribution format. So technically all this isn’t part of the jME API and you’re free to change it. Reducing the class count is a plus too :wink:

Yes I know I could delete the classes. But deleting something being in 3.0 branch would not be good as someone might be using the class for his/hers own purposes :slight_smile: That is why MeshContext will be deprecated.

I will delete it when we move to jme 4 :wink:

@Kaelthas said: Yes I know I could delete the classes. But deleting something being in 3.0 branch would not be good as someone might be using the class for his/hers own purposes :) That is why MeshContext will be deprecated.

I will delete it when we move to jme 4 :wink:

Not to confuse people, you probably mean 3.2 instead of 4. Each new 3.x version can (and generally will) break the previous one.

Great news! Keep up the good work :wink:

This is great news, give me a notify when it is commited,

as I use a buildbot for converting around 1k models and render previews of them, I can quickly see if it makes unexpected new errors in any of them and give feedback.

@Kaelthas said: Yes I know I could delete the classes. But deleting something being in 3.0 branch would not be good as someone might be using the class for his/hers own purposes :) That is why MeshContext will be deprecated.

I will delete it when we move to jme 4 :wink:

The stable branch doesn’t have any of the latest changes to the importer anyway. And as Paul said, jME 3.1 will be what you mean by “jME 4”, so go ahead and delete them :slight_smile:

@normen

OK, cool :slight_smile: One class less to manage.
I hope I will be done with the changes before you release jme 3.1.

@EmpirePhoenix
Good to hear there will be some more tests. :slight_smile:

I have just made a commit of new triangulation modifier :slight_smile:

Please let me know if it works. If you come accross problems - post them here.

There are several things to mention about the commit:

  1. some classes were removed - they were not necessary so no need to keep them; just hope that nobody used them in their code :wink:
  2. the faces should be properly triangulated but there is one condition: the face should be flat. If the vertices are not in one plane then an exception might occur. I added a ‘watchdog’ to prevent occurence of infinite loops in the triangulation modifier. In such case just apply triangulation modifier in blender or make sure you do not have non-planar faces in your model.
  3. There is one big feature to implement - temporal mesh for nurbs and curves. But this was quite big so I have decided to do it separately.
  4. One new setting was added to blender key: the point size. This defines the size of a single points in mesh that do not belong to any edge. By default the size is set to: 1.
  5. I have also optimized the vertex amount while loading edges in mesh (edges that do not belong to a face).
  6. Lamps now have names (minor issue I found by accident) :slight_smile:
  7. I have also found some bugs not connected with triangulation modifier. I will try to fix them as soon as possible.’

I hope that it will work smoothly, but if you report any issues please post your blend files so I could check them myself.

Cheers,
Marcin

2 Likes

As promised I ran it trough my models, and got this one:

The model worked before, it might contain modeling errors, but I guess we should try to give a better error message then.
Either the new version requires several times the memory to do the triangulation or this is an error somewhere in either the loader or the model.

After the initial try,
I added -ea -XX:MaxDirectMemorySize=5000m -Xmx5000m but it did not change anything.
Maybee there is a memory leak? My compiler loaded a few hundred model before this.


Give me your email and I can send you the model, also do you have any other ideas on what to try/test?

2014-08-30T13:03:15.891+0200  SEVERE  Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3181)
	at java.util.ArrayList.grow(ArrayList.java:261)
	at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
	at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
	at java.util.ArrayList.add(ArrayList.java:458)
	at com.jme3.scene.plugins.blender.meshes.IndexesLoop.findPath(IndexesLoop.java:230)
	at com.jme3.scene.plugins.blender.meshes.Face.detachTriangle(Face.java:146)
	at com.jme3.scene.plugins.blender.meshes.Face.triangulate(Face.java:282)
	at com.jme3.scene.plugins.blender.meshes.TemporalMesh.triangulate(TemporalMesh.java:212)
	at com.jme3.scene.plugins.blender.meshes.TemporalMesh.prepareFacesGeometry(TemporalMesh.java:386)
	at com.jme3.scene.plugins.blender.meshes.TemporalMesh.toGeometries(TemporalMesh.java:362)
	at com.jme3.scene.plugins.blender.objects.ObjectHelper.toObject(ObjectHelper.java:242)
	at com.jme3.scene.plugins.blender.BlenderModelLoader.load(BlenderModelLoader.java:74)
	at com.jme3.scene.plugins.blender.BlenderModelLoader.load(BlenderModelLoader.java:57)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:288)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:374)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:378)
	at de.visiongamestudios.compiler.CompileApplication.internalcompile(CompileApplication.java:260)
	at de.visiongamestudios.compiler.CompileApplication.lambda$0(CompileApplication.java:223)
	at de.visiongamestudios.compiler.CompileApplication$$Lambda$18/2144176438.call(Unknown Source)
	at com.jme3.app.AppTask.invoke(AppTask.java:142)
	at com.jme3.app.Application.runQueuedTasks(Application.java:583)
	at com.jme3.app.Application.update(Application.java:596)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:231)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:151)
	at com.jme3.system.lwjgl.LwjglCanvas.runLoop(LwjglCanvas.java:229)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:230)
	at java.lang.Thread.run(Thread.java:745)

The model as loaded with the old loader

1 Like
@Kaelthas said: 2. the faces should be properly triangulated but there is one condition: the face should be flat. If the vertices are not in one plane then an exception might occur. I added a 'watchdog' to prevent occurence of infinite loops in the triangulation modifier. In such case just apply triangulation modifier in blender or make sure you do not have non-planar faces in your model.
That's a huge limitation. I can't think of an organic model where this wouldn't occur. What's the problem with non planar faces?
@nehon said: That's a huge limitation. I can't think of an organic model where this wouldn't occur. What's the problem with non planar faces?

I dont really think so, its just a quick modifiers, triangulate on blender to solve.

Yes but that means having an extra operation in blender, probably having 2 separate files (you don’t want to ruin the quad mesh model if you need to edit it later). All this to work around the loader triangulation algorithm.
Also that means that this algorithm is only capable of triangulating a very small subset of models. In that regard, I guess the old algorithm was better.
So maybe there is a way to alleviate this issue in the algorithm, and if there isn’t, since the loader is capable of detecting such cases, it should fall back to the old algorithm.

I don’t want to sound disrespectful of Kealthas work on the loader, it’s amazing, but IMO this change is gonna prevent the loader to load models that it was capable of loading before with no problem, and will just add an extra step in blender most of the time.
For example Jaime’s model won’t load, because I’m 100% sure it contains non planar quads.

1 Like

@nehon

Non planar quads are not a problem. Quads are always triangulated. Problem occurs with N-gons that are non planar - and still, not with all of them.

But you’re right - it would be better to use previous algorithm in such case just to prevent crashing. At least for now untill I find a better solution.

2 Likes
@Kaelthas said: @nehon

Non planar quads are not a problem. Quads are always triangulated.


Hooooo. Well that changes everything. I thought quads were also considered as n-gons.
ok so this issue is less limitative that I thought. But still I think it would be preferable to fall back to previous implementation when relevant instead of throwing an error (that is if the previous algorithm would give a satisfying result).

I have just commited a fix to the triangulation algorithm.

@nehon
I have followed your advice and the old method is used if the algorithm fails to triangulate the face. A warning is logged with the cause of failure.

@EmpirePhoenix
The same applies to your model it should now load correctly.

Although one element of the mesh is badly shaped so that even blender renders it with artifacts and errors. It contains a face with several loops of vertices. This caused an infinite loop to occur while adding data to the list - that caused OutOfMemoryError.

The failed element is the one at ceiling in the middle of the model. A flat cube with circle hole. Separate it from the model and take a closer look. You will see the errors :slight_smile:

And please check if the textures work fine. I couldn’t see proper textures even in blender so I cannot tell if they are loaded withour errors.

3 Likes

Great :wink: !

@Kaelthas said: I have just commited a fix to the triangulation algorithm.

@nehon
I have followed your advice and the old method is used if the algorithm fails to triangulate the face. A warning is logged with the cause of failure.

@EmpirePhoenix
The same applies to your model it should now load correctly.

Although one element of the mesh is badly shaped so that even blender renders it with artifacts and errors. It contains a face with several loops of vertices. This caused an infinite loop to occur while adding data to the list - that caused OutOfMemoryError.

The failed element is the one at ceiling in the middle of the model. A flat cube with circle hole. Separate it from the model and take a closer look. You will see the errors :slight_smile:

And please check if the textures work fine. I couldn’t see proper textures even in blender so I cannot tell if they are loaded withour errors.

They one work with controll + p in preview mode for whatever reason, never figured out why some of the models do this.