Creating Meshes Faster in Away3D Through Bulk Loading

Posted: April 4, 2011 in Uncategorized

For my G-Wizard Editor CNC CAD/CAM software I have to build Meshes consisting of Segments in Away3D that show the toolpath a typical CNC machine tool “g-code” program will follow.  It’s quite a fun application to work on because I create these 3D wire frame models by interpreting the g-code, then they’re displayed and you can zoom, pan, and rotate them in a manner similar to the Rhino3D CAD program.  Here is a typical screen shot:

The app is written in Adobe Flex AIR, and the 3D graphics library I’m using is Away3D.

So far things have worked out well, but this is a very performance-intensive application.  Some g-code files generate hundreds of thousands of Segments.  Today, Away3D 3.5 pretty well starts to choke after 10-15 thousand segments, so any kind of performance enhancement helps.  In the long run, Away3D 4.0 will support Flash Player 11 (Molehill), which directly accesses your GPU’s power and allows for images with potentially millions of polygons.   The initial demos are certainly spectacular!

Meanwhile, I need to make things work for my Beta users without the benefit of the not-even-Beta Flash Player 11.  Hence, I’ve played with a lot of different performance enhancements.  Today’s experiments revolved around modifying the methods inside the Away3D Mesh class to allow the batching up of some operations to improve performance.  Normally, we just call “addSegment” repeatedly and the job gets done.  However, I created a subclass of Mesh that I call “MeshLoader”.  Source code is available here for you to download and look over.  Note that you will have to convert some objects in Away3D’s Geometry.as class to be “arcane” instead of “private” so you can get at them.  I’ve tried to document them in the comment at top, but the list is probably not quite right.  No worries, the Flex compiler will tell you what it can and can’t access.

To use MeshLoader, allocate MeshLoaders instead of Meshes, call MeshLoader.beginLoad() before you start creating Segments, call MeshLoader.addSegment for each Segment, and then call MeshLoader.endLoad().  What’s left is a pretty vanilla Away3D Mesh that loaded a lot faster.

For my program, the cost to interpret the g-code, build the Meshes (including the trident, background grid, and 3D toolholder as well as the actual g-code segments) went from about 9.5 seconds down to 5.2 seconds.  Nearly a 2X speedup–Cool beans!

That’s a pretty huge savings for me and it gets better the larger the file loaded.  This particular file has somewhere between 25,000 and 30,000 Segments in it.  Rendering performance (i.e. framerate) is unaffected since we wind up with the same Mesh data structure we’ve always had.  Also, this is done in Away3D 3.5 since I’ve not yet been able to get 3.6 working right (see my earlier post today).

If I dig into where most of the gain comes from, it is largely due to not checking in AddMaterial for whether the Segment has been added.  We know it is already there because its all part of the batch process.  Given how expensive the check is, it would make for a more maintainable update to Away3D to have an option that “knows” not to perform that check.

There’s more work I can do with this batch loader, but thought I would pass this along since I already have a strong result from it!

Postscript

A little more tuning got the total time down to about 4.9 seconds.  The additional changes are reflected in the source code.  The only loss of functionality I am aware of are the event handlers for changing the dimensions and material are no longer being added since my app doesn’t require these functions.  This is a pretty good improvement for an afternoon’s work.

I have forwarded this to the Away3D mailing list and am hoping that at least a change will be made around the AddMeterial checking on whether the Segment is there or not since that’s the Lion’s share of the savings.  Also, I’d love to try some of this on 3.6 since it uses Vectors instead of Arrays.  I tried using Arrays to batch up the segments until endLoad, but it slowed things down too much.  If I can use Vectors and Away3D uses Vectors then I don’t have to push each element from my Vector to their Array, I can do a concat and it should be even faster.

Advertisements
Comments
  1. […] was amused to see that Away3D 4.0 uses the technique I mention below in my post about creating meshes faster.  I am definitely not claiming to have given them the idea, it’s just neat when great minds […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s