Introduction: Programmatic Creation of a 3D Model for 3D Printing

One of my favorite hobbies is making rolling ball sculptures.  I usually make RBSs out of copper but being a geek I thought it would be cool to make a virtual sculpture and 3D print it on Shapeways. 

I started first by trying to model an RBS with Blender.  I quickly realized that doing anything in Blender takes quite a time commitment and has a steep learning curve.  I tried evaluating some other 3D modeling programs but every package seemed too difficult to use to build an RBS for my apparently little brain.

I realized quickly that whenever I made a virtual 3D model, I would need to be able to easily build it and modify it.  Well, modifying a rolling ball sculpture has consequences such that any change made higher up will affect a portion of the track lower down.  Being a computer programmer kind of guy, I thought it would be interesting to try to make a virtual model programmactically which would give me the freedom of making something which could be very accurate and forgiving as far as modifying the model.

Step 1: Use VRML to Create a Simple 3D Virtual Model

To start I decided to use VRML (Virtual Reality Modeling Language).  VRML comes in a few flavors.  There's VRML 1.0, 2.0 and then came X3D.  X3D is sort of XML based and the latest and probably last version of VRML.  I had already played with VRML 2.0 before so I went with that because I was too lazy to learn X3D.  Looking at it, though, it's very similar to VRML so it really is that I'm just that I'm too lazy really to try to learn it.

VRML allows you to describe a 3D scene by using primitives like cubes, spheres, extrusions, meshes, etc.  There's options for placing an object or a group of objects in xyz space as well as the ability to scale and rotate them.  VRML is fairly easy to learn and use.  Since it has been around a while, there's plenty of example code on the web so google to your heart's content.

To create a VRML file, you simple create a file using notepad or your favorite text editor and create it with a ".wrl" extension.

On the first line you put:

#VRML V2.0 utf8

Then you put your code for your shape or shapes.  For an RBS I basically use Extrusions for everything.  Here's an example of a RBS Rail:

Transform {
  translation 0 0 0
  children Shape {
    appearance Appearance {
      material Material {
  diffuseColor 0.757827 0.771796 0.771797
  ambientIntensity 0.5
  specularColor 0.708205 0.708205 0.708205
  emissiveColor 0.000000 0.000000 0.000000
  shininess 1
  transparency 0.000000
      } # end material
    } # end appearance
    geometry Extrusion {
      beginCap TRUE
      endCap TRUE
      creaseAngle 0
      solid TRUE
      crossSection [
      0.00150000 0.00000000,
      0.00121353 0.00088168,
      0.00046353 0.00142658,
      -0.00046352 0.00142658,
      -0.00121353 0.00088168,
      -0.00150000 0.00000000,
      -0.00121353 -0.00088168,
      -0.00046353 -0.00142658,
      0.00046352 -0.00142659,
      0.00121352 -0.00088168,
      0.00150000 0.00000000
      ] # end cross section
      spine [
0 0 0,
0 0 -0.01,
0 -0.01 -0.02,
0 -0.02 -0.02
      ] # end spine
    } # end extrusion
  } # end shape

You can end with this code but it's not really necessary usually:

  type "EXAMINE"
} # end NavigationInfo

So what does it all mean?

The first line identifies a VRML file.
The "geometry Extrusion" section defines the extrusion with endcaps, a circular crosssection of xy points, which gets extruded across 4 xyz points.
The "Shape" section defines attributes about the shape which surrounds the geometry Extrusion section.
The "Transform" section defines either where to move the object xyz or scale or rotate the object.  Several Transforms can surround other transforms.  So, for example the inside transform can be for rotation, there could be another that surrounds that transform that could be for scale, and another transform which surrounds both of the others which could be for xyz translation.
The "NavigationInfo" section is for some VRML viewers to know what to do.  You can go into examine mode, or go into flythrough mode, there may be other modes you could do, I don't know them all.

Step 2: Create a Perl Program That Outputs VRML

OK, it doesn't take a genius to realize that writing a bunch of VRML code by hand could get rather tedious and very hard to manage.  So the next step would be to use some language where you could write functions that can output custom VRML code.  What programming language you use is up to you.  I actually use Tcl a lot but that's just a personal preference.  You could just as easily use Perl, C, Java, C# or whatever can output plain text.  Most Linux systems have Perl pre-installed or you can install it easily with yum or apt-get.  You can download  free community edition version of Perl for Windows from

Here's an example of a perl program that outputs a simple 3D model:


open FILEOUT, ">bot_part.wrl" or die;

print FILEOUT "#VRML V2.0 utf8\r\n";
print FILEOUT "\r\n";
print FILEOUT "# by Jim Brown\r\n";
print FILEOUT "\r\n";

$rad = 3.141592 / 180.0;
$meter = 1;
$cm = $meter / 100.0;
$mm = $cm / 10.0;

$back_plane_width = 24.0 * $mm;
$back_plane_height = 40.0 * $mm;

print FILEOUT "# part\r\n";
print FILEOUT "Transform \{ \r\n";
print FILEOUT "  translation 0 0 0\r\n";
print FILEOUT "  children \[\r\n";
print FILEOUT "    Shape \{\r\n";
print FILEOUT "    appearance Appearance \{\r\n";
print FILEOUT "      material Material \{\r\n";
print FILEOUT "        diffuseColor 0.9 0.9 0.9\r\n";
print FILEOUT "      \} # end material\r\n";
print FILEOUT "    \} # end appearance\r\n";
print FILEOUT "    geometry Extrusion \{\r\n";
print FILEOUT "      creaseAngle 0\r\n";
print FILEOUT "      beginCap TRUE\r\n";
print FILEOUT "      endCap TRUE\r\n";
print FILEOUT "      crossSection \[\r\n";

  $x_width = $back_plane_width;
  $y_width = 2 * $mm;

   print FILEOUT "  " . sprintf("%3.8f %3.8f", 0 - ( $x_width / 2.0 ), 0 - ( $y_width / 2.0 )) . "\r\n" ;
   print FILEOUT "  " . sprintf("%3.8f %3.8f", 0 + ( $x_width / 2.0 ), 0 - ( $y_width / 2.0 )). "\r\n" ;
   print FILEOUT "  " . sprintf("%3.8f %3.8f", 0 + ( $x_width / 2.0 ), 0 + ( $y_width / 2.0 )). "\r\n" ;
   print FILEOUT "  " . sprintf("%3.8f %3.8f", 0 - ( $x_width / 2.0 ), 0 + ( $y_width / 2.0 )). "\r\n" ;
   print FILEOUT "  " . sprintf("%3.8f %3.8f", 0 - ( $x_width / 2.0 ), 0 - ( $y_width / 2.0 )). "\r\n" ;

print FILEOUT "    \] # end cross section\r\n";

print FILEOUT "    spine \[\r\n";

  $x = $back_plane_width / 2.0;
  $y = 0;
  $z = 0;
  print FILEOUT " " . sprintf("%3.8f %3.8f %3.8f,", $x, $y, $z) . " \r\n";
  $y = $y - $back_plane_height;
  print FILEOUT " " . sprintf("%3.8f %3.8f %3.8f,", $x, $y, $z) . " \r\n";
  $x = $x + $back_plane_width / 2.0;
  $z = $z + $back_plane_width / 2.0;
  print FILEOUT " " . sprintf("%3.8f %3.8f %3.8f", $x, $y, $z) . " \r\n";
  $x = $x + $back_plane_width / 2.0;
  print FILEOUT " " . sprintf("%3.8f %3.8f %3.8f", $x, $y, $z) . " \r\n";

print FILEOUT "      \] # end spine\r\n";
print FILEOUT "    \} # end extrusion\r\n";
print FILEOUT "  \} # end shape\r\n";
print FILEOUT "\]\r\n";
print FILEOUT "\}\r\n";
print FILEOUT "\r\n";

close FILEOUT;

In the example pics you can see that a 3D model is created.  If you look at the wireframe image, you can tell that I have mitering turned on, or else the model would look squished.  This is a feature of Accutrans3D.

I figure that this step is enough to make many models in 3D.  You can see in the example pics, I made a Raspberry Pi Case and had it printed in 3D using this method of creating a program that outputs vrml.  I ended up with a nice box.  I even added text and a Raspberry Pi logo on top of the box.  You probably can see how using this method could be very powerful for making an exact object with exact measurements without any sort of modeling package other than pure code.

Step 3: Write a Scripting Language and Parser to Build 3D Models

The previous step is usually far enough to build simple and even some complex 3D models with VRML.  However, I wanted to build a Rolling Ball Sculpture.  Trying to build a rolling ball sculpture using perl only seemed pretty tough to me.  So I decided, it would be great to build a RBS scripting language that I could define an RBS then have a parser parse the scripting language and output the appropriate VRML code.

My RBS scripting code would have commands like:  "Create Start Bucket", "Go Straight some amount", "Turn Left some amount", "Turn Right some amount", "Create End Bucket", etc and would have commands for building a frame and supports and such.  For the track rungs I decided to make it automatic where every so often at a set distance it would automatically add a rung.  For the Supports, I needed to be able to tell which rail, left or right, to have the support connect to and which side of the frame to connect to. For the turns, the parser would automatically figure out banking and smoothing.  I can tell it where to place marbles. 

For the banking, if you can imagine, I have an invisible center rail on which I rotate the other two rails. So when I want to turn left, the right rail goes up and in a little and the left rail goes down and in a little according to a z rotation. The track is sort of built in short steps. So the parser sort of figures about 3 steps before the next turn and 3 steps into the next turn to incrementally start banking. After a curve the parser un-banks for about 3 steps before the end of the curve and 3 steps after the curve until it's back to normal no bank for straight track or banked to the next curve for curves.To figure the bank, at first I just guessed and manually set the bank based on the diameter of the curve and that worked. Later, I figured a formula to do the same thing. I figured that this incremental banking was not smoothing so a wrote a function that would smooth the entire track sort of in an Fast Fourier Transform (FFT) sort of and averaging over several steps fashion.

For the frame, I currently have a few choices.  I can choose a rectangle cube frame which calculates its size from the extents of the track height, width and depth and puts the frame just a little larger than that so that the track fits inside those dimensions.  I can choose a spherical frame like the Christmas Ornament sculpture which like the rectangle sculpture calculates its size from the extents of the track inside.  I can choose a central spire frame like the two track rolling ball sculpture with the track going around the spire and the footprint being calculated by the extents of the track.  For short track, I can choose no frame at all but instead just stilts for the track to be supported by.  Each frame comes with its own set of challenges and its own algorithm for connecting the supports form the frame to the track.  I will probably create a few more frame to chose from and perhaps try to make a few that are more artistic than a rectangle cube but that was a start.

What's cool about making a scripting language is that changes are quick and easy.  I can even do testing to make sure the track has the right distance from track passing over a track so that the marble has room to get through.  I can build a sculpture, view it in a 3D modeling program, decide if it looks good, and if something needs to be changed I can change the script, re-parse it and then go back and view the change in the 3D modeling program. 

Step 4: Rendering VRML and Converting to STL

OK, so I have a cool WRL file that I can upload to Shapways.  Shapeways does accept VRML files for upload.  OK, so I upload the file to Shapeways, and lo and behold, they won't accept it!  Ugg.  What's the deal!

There are several reasons why Shapeways won't accept a 3D model file.  The main reason Shapeways won't accept a file is if a file is non-manifold.  Non-Manifold basically means it's not water tight.  This can happen when one beam crosses another beam at an intersection or when a beam bends at too tight an angle that causes weird inside out folding. There are probably more reasons that I can explain that can happen and I've probably encountered many of them.  It's very frustrating. You must fix all non-manifold problems before Shapeways will accept the file.  The good news is that Shapeways will allow you to modify and upload the file as many times as you wish until you get it right!

I ran into a rather weird reason why Shapeways wouldn't allow me upload a WRL file.  It appears that the Shapeways VRML renderer has a bug in it!  I've told them about it but it appears to have fallen on deaf ears.  After several emails back and forth they basically blew me off.  It appears the the Shapeways renderer has an odd twisting behavior of extruded beams that curve around which my RBSs need to do.  In addition, the bends are not very smooth as their VRML renderer doesn't do mitering.  In their defense, mitering is not part of the VRML spec, but the twisting thing is definitely a bug.

So, I went looking for other VRML to STL renderers.  MeshLab says it can render VRML but it apparently only does meshes and fails at extrusions.  I had an old version of TurboCad 14, but it also has the weird twisting problem with extrusions.  I tried Blender, but it doesn't like the multiple objects and also seems to have trouble with the extrusions.  I tried NetFabb but it also has trouble with VRML extrusions.  I tried several other packages but they all either couldn't render VRML at all or they failed at rendering extrusions correctly.

I tried Accutrans3D and at first it couldn't render the VRML extrusions correctly either, but Wayne at Micromouse had pity on my plight and fixed the problem and gave me a working update!  Yea!  Go Wayne and Accutrans3D!  Not only that, but Wayne implemented the mitering I was wanting and it works beautifully!  No other 3D package works for this but Accutrans3D that I could find!  So I was able to import my VRML file and output a STL file and upload that to Shapeways and that works perfectly!

Step 5: Videos and Next Steps Physics Testing Program?

OK, so getting to this point where I have a virtual 3D RBS model that I can upload to Shapeways doesn't mean anything if I can't print it or if it doesn't work after I print it.  Well, I haven't written any physics testing software yet so all I can really do is to make it and try it.  Of course this method is an expensive method because if it doesn't work, it's like $30 bucks down the drain for the 3D printing cost.  I guess that's the price I pay for not having a physics testing program yet.  But hey, most of these sculptures seem to work the first time and some don't. Anyway, check out these videos of some of the sculptures I've made so far:

Make It Real Challenge

Participated in the
Make It Real Challenge