OGRECave / blender2ogre

Blender exporter for the OGRE 3D engine
GNU Lesser General Public License v2.1
207 stars 69 forks source link

Speed up export, skip xml #190

Open cryham opened 7 months ago

cryham commented 7 months ago

Well since it already came up on forum, I think this should be an issue. https://forums.ogre3d.org/viewtopic.php?p=555617#p555617 Exporting isn't fast. It's okay for single mesh (not too big) and exporting once a while. Anything more and it's a notable delay. Best would be already wrting from python to .mesh binary not using xml.

sercero commented 7 months ago

That would be nice, but there should be also an option to export the xml to inspect the resulting mesh and check for errors.

Do you know how to export from phyton to .mesh directly?

cryham commented 7 months ago

Right. I don't know much about Blender's Python, but isn't it just like regular Python writing to binary file? E.g. https://diveintopython.org/learn/file-handling/binary-files So the rest I think would be using OgreNext code as reference for 2.1 format of .mesh file.

paroj commented 7 months ago

So the rest I think would be using OgreNext code as reference for 2.1 format of .mesh file.

that would be a bad idea. OgreNext can load v1 meshes, but Ogre cannot load v2 meshes, so you loose compatibility.

Also, instead of re-implementing the binary format in python, you can just use the C++ implementation through the bindings: https://ogrecave.github.io/ogre/api/14/working-with-numpy.html

sercero commented 6 months ago

Hey guys, I did some tests to probe the waters before diving in too deep into exporting without going through the XML exporting process.

TEST

Exporting a Blenders base Sphere mesh with level 1 SubDiv: 11904 exported vertices

After profiling with cProfile it became clear that writing to the console was a mayor point of contention. So, I tried the test again removing the progress indicators with the following results:

Progress indicators commented out:

Exporting a Blenders base Sphere mesh with level 1 SubDiv: 11904 exported vertices

CONCLUSIONS:

sercero commented 6 months ago

As a result of the profiling, I have already found something to optimize: #199

paroj commented 6 months ago

nice findings! this shows that all optimization should start with profiling.

For me bpy.context.window_manager.progress_update is the slow thing and sys.stdout.write() is largely irrelevant. The issue here is that someone thought that reporting progress with sub-decimal precision is a good idea, so we update progress for each triangle! If we switch to updating when progress moved by 1% performance is good: #200

As for the profiling: while introducing MockSaxWriter is a good start, it does not give a fair picture of the expected speedup as one of the major bottlenecks is constructing this string dict here: https://github.com/OGRECave/blender2ogre/blob/b0c9578481f00ed3a19dfcd73a60f81cb7ffdfff/io_ogre/ogre/mesh.py#L323-L327

where both the dict and the string parts are slow to do per vertex. Without XML, we could keep everything as binary numpy buffers. However, as we already are sub-second with the progress issue gone, we need to be sure that this is worth the hassle..

sercero commented 6 months ago

@paroj regarding switching to using OGRE directly to create the VertexBuffer, I think that there is some problem when trying to serialize the mesh to disk:

Ogre.MeshSerializer.exportMesh(mesh, "test.mesh", Ogre.Serializer.ENDIAN_NATIVE)
TypeError: descriptor 'exportMesh' for 'Ogre.Ogre.MeshSerializer' objects doesn't apply to a 'Ogre.Ogre.MeshPtr' object

It seems that the function wants a *Ogre::Mesh, but I only have a Ogre::MeshPtr (a sharedptr) and the method getPointer() is deprecated (and missing) and the method get() (from sharedptr) is missing also.

paroj commented 6 months ago
Ogre.MeshSerializer().exportMesh(..
sercero commented 6 months ago
Ogre.MeshSerializer().exportMesh(..

?

paroj commented 6 months ago

note the extra parentheses to create a MeshSerializer instance instead of assuming a static method