How can I improve the 3ds Max viewport performance?

I have written some code which exports point cloud data to Krakatoa’s .prt format, but it is too slow to move around the viewport. The point cloud is for the company artists to use as a reference when building objects, so I’m not interested in actually rendering the data.

Is there any way to change the way in which I export the data to .prt so that Max will be more responsive? (Currently I’m using a single .prt file, as there is no animation used). I can’t remove data points as all (about 50 million) are needed by the artists-- is there any way to cull out points that are outside the viewport, or some other way to increase speed?

First of all, loading 50 million points is going to take its time, that’s a given. Drawing all 50 million in the Max (or Maya) viewport is bound to be slow.
You have several options to affect what ends up in the viewport though, so let’s look at them:

*PRT Loader has several options for loading a fraction of the particles, but obviously you don’t want that since you want to see all relevant points. But still, if you want to display 1% of the particles, you could use either First N or Every Nth loading. The former will be very fast, but if your cloud is highly ordered/sorted, only a portion of it will appear. The latter approach will show a good cross-section of the data, but will be as slow to load as reading all particles. Once the particles are cached for viewport display though, showing 500K will be relatively snappy.

*PRT Loader has a built in Particle Culling option based on one or more geometry volumes specified via a Named Selection Set. So you could create a cone frustum geometry object, align it to match the camera, parent it to the camera and use it to cull all particles outside the volume. Obviously, all particles will be read from disk and culled, but once they are removed, you will be left with much less, so navigating the scene should be faster. Moving the time slider or the camera would cause a recalculation though, so that would be slow.

*The PRT Loader also accepts Magma modifiers. You can create a MagmaFlow that selects particles based on their location within the camera frustum (when outside) and then drop a Krakatoa Delete modifier on the stack to delete the ones you wouldn’t see. This is similar to the built-in culling, but you can add your own rules to it.

I just tested a version of the last option using 10 million points reduced to about a million thanks to the frustum culling. Moving the camera around took about a second since the Magma had to go through all 10 million points each time. But once the culling had occurred, rotating any of the other non-camera viewports around the resulting sub-cloud was very fast.

I also tested the geometry culling in the PRT Loader itself - it was slower because the culling is performed early in the loading process, so each time the culling mesh is moved, the whole 10M particles had to be reloaded from disk to be culled again. So the viewport cache contained only the culled particles, while in the Magma approach the viewport cache contained all 10M that were then reduced dynamically on the stack. Thus, the Magma approach updated the culling data much faster since it did not have to reload from disk at all.

Do you have any other data, like normals or density? You could use magmaflows to cull those out, too. Another thing you could do is cull randomly based on distance away from camera or away from camera target. So the further a particle was from a certain point, the more likely it is to be randomly culled. This allows you to have high density where you are looking (or close to the camera) but has only sparse data elsewhere and a smooth transition between.