# Six-Speed Gearbox: Generating 3D Graphics

A few days ago I reconstructed my __Lego Six-Speed Gearbox__, with the indispensable help of a Lego Digital Designer model that I had saved when I was considerably younger.

On my webpage I had numerous diagrams to illustrate the power flow through the gearbox. The power-carrying components were highlighted in red, and everything else were made translucent to aid in visualizing their positions; and these images were accompanied by renderings of the power-carrying components alone. It looks something like this, when put together:

The truth was that, I hadn't actually known how to generate imagery like these. Making these diagrams had been quite a journey for me, and this post is to document, and share, the tinkering involved.

Naturally, I wasn't too pleased with the design work of my former self, when I first built the Lego Designer Model for this gearbox seven years ago; and so one of my first steps was to rework it. One of the changes I did was to sandwich the gears at the rear with width-wise spanning beams, to reduce gear cracking, and even so, I managed to somewhat reduce the overall footprint of the unit.

The first problem—how do we get from Lego Digital Designer, a proprietary software with proprietary file formats, to an environment that supports the processing and rendering that we require? Lego Digital Designer does offer the option of exporting models as LDraw files, and therefore what we need is, in essence, a way of converting LDraw models to CAD geometry, say, Wavefront Object files.

A __forum thread at EuroBricks__ offers a neat solution—use LeoCAD for the conversion. __LeoCAD__ is an open-sourced virtual Lego CAD software not unlike Lego Digital Designer. A brief exploration of LeoCAD indicates that it offers much greater control over the generation of building instructions, and possibly much less hassle in the positioning of parts, say, when trying to mesh gears; but a few minutes' usage hardly qualifies me to give reviews.

Opening the LDraw file in LeoCAD reveals that some parts are positioned incorrectly, namely the dog clutches and shift stick. As far as I understand, Lego Digital Designer does not store the model geometry as meshes; it stores only the __positions and orientations__ of parts, as float values—and so I suspect the interpretation of these values by LeoCAD might have been the problem. I might be wrong.

In any case it was quick to fix, and the file conversion was, in the end, rather straightforward. I must admit at this point that generating those graphics might have been easier if I had used Maya, or SketchUp, or in general any CAD program; but I chose to go with Mathematica, for my programming skills were at least passable.

Mathematica accepts __Wavefront Object files for import__, and upon import the model geometry is internally represented as a MeshRegion; the idea was to style and superimpose these geometries to create the red-in-translucent diagrams.

For this to work, I would need to split the geometries into two sets, the load-carrying components, to be styled red, and the overall gearbox save for the dog clutches, to be styled translucent. The reason why the dog clutches have to be excluded from the translucent set is that they move laterally when gear shifting takes place, and hence if we were to superimpose the translucent and red sets without removing the dog clutches, we would see two intersecting dog clutches—clearly not what we desire. The appropriate dog clutch has to be removed when generating graphics for the various speed settings.

The easiest way of separating the gearbox geometry is to create and import distinct files for the translucent and red sets, as opposed to attempting a programmatic split in Mathematica. A particularly streamlined workflow can be achieved using the hide feature of LeoCAD.

This gives a total of 9 Wavefront Object files for the 6 speed settings on the gearbox—6 red geometries and 3 distinct translucent geometries. Now we import the geometries into Mathematica. For brevity, we show the code for importing one set each.

The styling of these geometries can easily be done using the __MeshCellStyle option of MeshRegion__. It is helpful to know that indices of 0 in MeshCellStyle refers to mesh vertices, 1 to mesh edges, and 2 to mesh faces—in our case styling the faces alone would suffice. Further, the translucency we desire can be accomplished using the Opacity graphics directive. The superimposition of the translucent and red geometries can be achieved through Show. Hence, styling of the graphics is straightforward.

What is not straightforward, is finding an appropriate viewpoint from which to render the imagery, so that the relevant components in the gearbox are easily visible. We can interact with the Mathematica graphics and arrive at a good viewpoint by hand; but how do we maintain this viewpoint when exporting our graphics?

If we are able to extract the ViewPoint and ViewVertical properties of the graphics in real-time as we interact with them, we would be able to set corresponding options in our Export to the same values, thereby maintaining the same viewpoint. We introduce two variables, *ViewP* and *ViewV*, and declare them __dynamic__ wherever they're used. We couple them to the properties of the graphics, and include a print statement to display their values. This way we are able to see the ViewPoint and ViewVertical properties in real-time.

We are to generate 6 sets of graphics, for the 6 speed settings on the gearbox. Changing *ViewP* and *ViewV* on one set of graphics would change the viewpoint of all six sets of graphics, since these variables are global—clearly not an ideal behaviour. We would want to be able to tweak the viewpoint of these graphics separately, for the power-carrying components at each speed setting would differ in position. We therefore restrict the scope of *ViewP* and *ViewV* using DynamicModule, localizing them to each set of graphics; and we declare two external variables, *ViewPE* and *ViewVE*, to be set equal to *ViewP* and *ViewV*.

Since it is the localized *ViewP* and *ViewV* that interacts with the graphics, the viewpoints of the various sets are now isolated. And since *ViewPE* and *ViewVE* are set to the most recent *ViewP* and *ViewV*, we can feed them into Export and conveniently maintain our fine-tuned viewpoints when generating our image files.

The complete code now looks like this:

We initialize *ViewP* and *ViewV* to the last-known preferred values, for convenience when re-evaluating the notebook.

Generation of the standalone diagrams for the power-carrying components is now trivial, for we can utilize largely the same code. We specify a Lighting option, so that shading and shadows become more pronounced.

And that was how it was done. This process is repeated for each of the six speed settings, with the viewpoint for each individually fine-tuned.

The complete Mathematica notebook, along with the input Wavefront Object files, can be __downloaded here__.

That is all. Till next time, goodbye!

#Lego #Gearbox #Robotics #CAD #Mathematica #Programming #Graphics