I’m very pleased that G-Wizard Editor is one of the Showcase Apps for Away3D, a Flex/Flash 3D graphics library.  It’s been pretty cool to be able to do my CNC software in Flex, and my g-code simulator wouldn’t really have been possible with the Away3D library.  In case you don’t know what I’m talking about here, I made a nice page to explain what a CNC machine is.

Here’s what G-Wizard looks like:

G-Wizard g-code simulator and editor

G-Wizard g-code simulator and editor uses the Away3D library…

At the moment I’m feverishly coding away to build a portability library so I can switch between Away3D 3.6 and Away3D 4.0 Beta.  4.0 uses the new native gpu support introduced with Flash Player 11, but I don’t want to be permanently committed to it until I see that it’s all stable and working well.

I 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 think alike.  Makes me feel like I actually understood how their code works.

Darn that Jackson Dunstan!

Posted: April 18, 2011 in Uncategorized

Darn that Jackson Dunstan.  He’s always coming up with some performance benchmark for Flash/Flex that has me refactoring tons of code to pick up the benefits.  You see, Jackson writes a blog that does nothing but benchmark lots of alternative ways to do the same thing.  And then he publishes the results.  So you read them, and suddenly your fingers are digging deep into your code to fling out the bits that are slow.

Mine just lurched off a minute ago looking to eradicate “push” as a way to add elements to an array or vector.  It reads like nice clean code when I use it, but it’s slower (yes, slower!) than using the index operator.  At least I never use delete, which can instantly incinerate my performance by converting my nice closely packed array into a hash table.  That’s a real comfort.

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.

I’m writing this blog post mostly to get a couple of screenshots where they’re easily accessible by the Away3D community so they can help.

I’m converting my G-Wizard CNC CAD/CAM software, which is an Adobe AIR app running Away3D from version 3.5 to version 3.6.  3.6 is faster and is a precursor to 4.0, which is what I need to work with Flash Player 11 (Molehill), which will be a LOT faster.  There’s never enough speed where graphics are concerned!

Most of the conversion is pretty straightforward.  It largely involves switching a bunch of references from a discontinued Away3D type (Number3D) to a Flash type (Vector3D).  I don’t use many of the API’s because my graphics in this app are wireframe, so a more sophisticated user of Away3D may not have it so easy.

After I got the Vector3D conversion done, which seemed like a good idea just on general principles, I had 2 API issues to deal with.  It is frequently useful to be able to convert from screen 2D (mouse) coordinates to 3D coordinates and back again.  My goto for 2D to 3D had been a utility provided by Fabrice for use with the mouse.  It temporarily lost its ability to convert arbitrary coordinates and initially only wanted to use the mouse, but I talked Fabrice into bringing back the old functionality.  The other route, 3D to 2D, is what I use to do things like automatically zoom the objects so they fit the screen.  I had “borrowed” code from the camera internals, but that turned out to have been a silly idea as there was a perfectly good “screen” method that does the work in both versions.  So I updated my code and was much the better for it.

The latest problem I discovered is more vexing.  It seems that 3.6, for some unknown reason, can be fed all the same inputs for the model being viewed and the position of the camera and it will produce a different result than 3.5.

Here is the Trident under 3.5 showing what it should:

Away3D 3.5 Trident:  Old TridentThe axis Trident as it should appear…

And here is the Trident under 3.6:

3.6 axis Trident:  New Trident

Wot the ‘ell, Archie, wot the ‘ell?

Something’s gotten a bit bollixed up on that second Trident.  It wasn’t hard to set my code up so I can switch between 3.5 and 3.6 easily and with very few changes.  I just simply created a couple of utility routines:

- N2V:  Converts a Number3D to a Vector3D

- V2N:  Converts a Vector3D to a Number3D

Just by changing those two wrappers, I can determine whether I feed Away3D Number3D’s or Vector3D’s.  That’s handy, and it makes it dead simple to verify I’m doing exactly the same thing with both packages and getting a borked Trident back out of 3.6.  It also means I can continue working on other things in the product while I wait for some assistance from the Away3D gang.

I’ll report back what we find out when we get a solution.

The Long Refactoring Slog…

Posted: February 26, 2011 in Uncategorized

Do you ever decide to refactor some part of your software for all the right reasons, only to discover the incredible drugery of refactoring an API or Service that is used a LOT?

Yuck!

I’m going through that right now.  My Flex app uses popup windows like many UI’s.  By default, you can’t guarantee that more than one popup won’t be created unless you explicitly write code for it.  While it doesn’t happen that more than one pops up very often, when it does it can be confusing to the user or worse if your code isn’t expecting it.  The answer is a utility class that checks a list and just doesn’t allow more than one to popup at a time.  But, if you have a lot of popups, that means a LOT of code has to be edited.

Sigh…

Many software companies have adopted the idea of using forums for support.  One of the issues they face is getting everyone to go to the forum.  One mechanism I’ve found that really helps is to put a link back to the forum right on your app in some prominent place.  Make it a bit of a teaser.  For example, in my G-Wizard application, we call the support forum the “User’s Club.”  There’s a contrasting button for it at the top right of the window:

This attracts a very high percentage of users to go join the User’s Club and at least check it out before they have any problems, which is a good thing.  Aside from the user’s club, there is also an indication of whether the software is up to date that changes to a link to update the software when newer releases are available.

Debugging as Code Review

Posted: January 10, 2011 in Uncategorized

Bugs are never where we expect to find them.  If they were, we wouldn’t have made the bugs in the first place.

Most are not so hard to find, but periodically you will find a stumper.  These are bugs that are especially not where you expect.  They may be hiding in plain sight because you’ve convinced yourself things work differently than they do and are ignoring the bug as a result.  They may be in some nook or cranny that is wholly unexpected.  Object oriented and event driven programming seems to excel at giving bugs increasingly novel places to hide.

You’ll know you have a stumper from your soaring frustration level and the fact that finding and fixing it is taking far longer than you had expected.  When that happens, stop.  Start doing a code review on every portion of the program that might even remotely be associated with the problem.  You may not find the problem, but you will be surprised at how many other problems you do find in the process.