We normally use XMesh for char work and caches where point counts change, but today we ran into a shot where we were hoping to use XMesh to make external refs for ~500 child objects (single fr/XM per obj) linked to animated helpers (we set XM to be ‘linked to sources parent’ etc)…
We were surprised to see that once the XMeshes had cooked it was significantly slower (unusably so) in the viewport than the original scene geo (obviously we cleared the old geo out etc).
After this we’re considering going with XRef Obj instead (since we’re using 2016), before we do does anyone have any tips/things we should look out for in this scenario that might help avoid the lag we’re seeing in this scenario with Xmesh MX?
So you have about 500 XMesh Loaders, linked to helpers?
XMesh was mainly designed to bake complex animations to a single unchangeable file that can be sent from the Animation department to the Lighting and Rendering department. (Historically speaking as a fun fact, it was first used for animating the growing of thousands of crystals on Superman’s ship in a sequence that was later cut from the movie “Superman Returns”). The ability to bake in object space and link to helpers was really an afterthought (it is mostly implemented via the scripted UI), and you should not expect it to scale that well performance-wise.
If you have just the typical mesh channels (Vertex list, Face list, Smoothing Groups, Texture Coordinates, Material IDs, Edge Visibility), you have at least 3000 binary ZIP streams that need to be loaded and decompressed just to display the mesh, in addition to 500 XML header files.
XMesh Loader reads the binary streams in parallel, so I would expect 6 threads running for each XMesh Loader, but it is still a lot of file access and the loaders need to be evaluated sequentially because 3ds Max is not asynchronous. If you would switch to vertex cloud display in the viewport, it would still need to open, read and close 500 XML files and open, read, unzip and close 500 vertex lists on each frame.
However, you said SINGLE FRAME. So you have a static non-changing mesh that is animated only via the helpers?
When the XMesh Loader is set to “Load Single Frame Only”, or “Limit to Custom Range” with Start and End set to the same value, it should load the data only once, and then keep that mesh in memory. So I would expect it to be very fast and not hit the disk at all once it is loaded on the first frame.
Is there anything else on the modifier stack that could affect the validity interval of the XMesh Loader, forcing it to re-read the data from disk on every frame?
Thanks so much for the quick reply, (crazy production day here), as you say this isn’t normally how I would use XMesh (mostly for cooking and and combined cool dynamics stuff into one file).
These originated as Maya files then exported as FBX imported into Max, there are no modifiers, could there be something else in the mix Maya/FBX is introducing?
In other tests we’ve tried we’re getting this same result (single Obj, single fr, very slow in viewport), I have yet to try something as nice and simple as 500 distinct spheres as Xmeshes (which will likely be my next test when I can squeeze it in).
Out of curiosity, what is the total polygon count of all 500 XMeshes combined?
I want to set up some tests, and need to know how heavy I should make my meshes…
I made a test with 500 teapots parented to 500 animated point helpers.
With 4 segment teapots (1024 faces), the performance was 30 fps.
The same performance was achieved when the primitive was collapsed to Editable Mesh.
With the same teapot saved as single frame XMesh, loaded in Single Frame Only mode and cloned 500 times, linked to the point helpers, it was 17 fps.
When I collapsed the XMeshes to Editable Mesh, it went back to 30 fps.
Then I increased the number of of segments to 32 (65536 faces), and tested both primitives and XMesh.
The primitive teapots run between 13 and 15 fps.
The XMesh teapots played back at around 10.9 - 11 fps.
However, when I made the XMesh with “Load Single Frame Only” unchecked, the performance went down to 0.29 fps!!!
So I went back and tested with the 4 segments XMesh but with “Load Single Frame Only” unchecked, and it went down to 3.8 fps…
I have to ask - are your XMesh Loaders set to “Load Single Frame Only”?
It appears to make a big difference when loading multiple heavy meshes (it is much less obvious when loading a single XMesh set to Custom Range with the same start and end values).
If they are not, you can run the following MAXScript expression to switch them all to “Load Single Frame Only” mode:
for o in getClassInstances XMeshLoader do o.loadSingleFrame = true
See if that solves the issue…
Of course, you could collapse them all to EditableMesh, but then you won’t be able to use them as external references.
Thank for the followup, good points Bobo, a few stats from our scene:
polys: ~5mill
vert ~10mill
loadSingleFrame = false -> .02 fps
loadSingleFrame = true -> 2fps (like you said significant)
Original Max geo -> 12-13fps
One potential difference is that these are distinct/individual meshes, could the cloning operation be speeding up XMesh redraw in your test? (expecting I could be wrong about this bc I haven’t tried a test with simpler assets at this point.
Thanks again for taking the time to look into this,