3D Modeling With Your Terminal

Not long after graduating from college, I was hired by Dreamworks Animation into a program called the FX Challenge. It was a training program where they take entry-level graduates and train them to be effects artists over the course of 6 months. Being a Linux shop, learning the command line was an important lesson at Dreamworks. One of their first assignments was to find a beautiful image and make it more beautiful. Our tools for accomplishing this? A suite of proprietary command-line image manipulation tools. After a basic introduction to the terminal, we were expected to explore what tools we had available to us and use them toward our goal of making a beautiful image more beautiful. It was awesome.

I realized that the subjective nature of the assignment is what made it so successful. We were driven to make something that we thought was beautiful, not to just check off that we’d used all the tools. Our passion drove the desire to find the tool we needed. We explored, we learned and we created.

Anyone with a DIY attitude knows this process. You set out to create something, but there are skills that you need to learn first. You go find a video or tutorial on the needed skill, figure out how to apply it to your project and then create it. The best kind of learning happens as a side effect of creating. As an educator, I think it’s important to find the projects people want to create and weave important lessons into them. The terminal is not something most people would set out to learn about, but if you want to set up a retro gaming table powered by a Raspberry Pi, I bet you’ll learn a few things about it. Similarly, if you just unboxed your new 3D printer, you might want to learn how to make something with it. My goal in this post is to weave how to use a terminal into the project of 3D modeling then printing an object. We'll do this using a suite of commands I developed called stl_cmd.

Threads generated with the stl_threads command.

Threads generated with the stl_threads command.

I first started working on the stl_cmd suite a few years ago. I started with simple commands that display information about STL files, the most common 3D model format used in 3D printing. stl_count prints how many triangles are in the file. stl_bbox displays the bounding box of the file. Then I created stl_cube, which simply outputs a cube at the origin with a given size. stl_transform was the most useful, having the ability to perform any number of translations, scales and rotations on an STL file. Soon after, when I was experimenting with 3D printing screw threads, I wrote stl_threads, which generates screw threads based on the ISO metric screw thread standard. The commands were helpful for a limited number of uses, but for people to really want to use them they needed to do more. Recently, I added stl_boolean which can add, subtract and intersect 3D shapes. In combination with a number of commands that can generate primitive shapes (stl_cube, stl_sphere, stl_cylinder, stl_cone and stl_torus), stl_boolean can be used to 3D model using your terminal!

The technology behind OpenJSCAD was ported to C++ for use in stl_boolean.

The technology behind OpenJSCAD was ported to C++ for use in stl_boolean.

Several of my blog posts use OpenJSCAD to present a 3D widget that can be used to customize a project. OpenJSCAD provides an easy way to create 3D models using JavaScript in a live coding environment. It's a fantastic example of a way to learn to code as a side effect of creating 3D models for 3D printing. I knew that if I could add similar functionality to stl_cmd, I could achieve the same thing with the goal of also learning something about the terminal. The core technology behind OpenJSCAD is CSG.js, which is a JavaScript library. I didn't want to just implement stl_boolean using CSG.js, though, because I didn't want the overhead of, or dependency on Node.js. I decided to port the CSG.js library to C++ so stl_boolean would be fast and standalone like all the other stl_cmds. I only recently finished a bare bones port, so there's still more to do (testing, implementing a couple features), but it's very usable.

If you'd like to try out stl_cmd, you'll need to build it from source, which should be straight forward:

git clone https://github.com/AllwineDesigns/stl_cmd
cd stl_cmd
make # a bin directory is created and can be added to your path, or
make install # installs to /usr/local/bin by default

To generate the same 3D model as the default program that loads in OpenJSCAD you can run the following commands:

stl_cube -w 3 > cube1.stl
stl_sphere -r 2 > sphere1.stl
stl_boolean -a cube1.stl -b sphere1.stl -d diff.stl # -d for difference

stl_sphere -r 1.3 > sphere2.stl
stl_cube -w 2.1 > cube2.stl
stl_boolean -a sphere2.stl -b cube2.stl -i int.stl # -i for intersect

stl_boolean -a diff.stl -b int.stl -u union.stl # -u for union
stl_transform -tz 1.5 -s 10 union.stl out.stl
Screenshot of the final output from the commands above viewed in Blender.

Screenshot of the final output from the commands above viewed in Blender.

You can see some basic redirection to capture the output from the primitive commands (stl_sphere and stl_cube), some command line arguments and file management (and of course you could have a discussion on your path and working directory). I have plans to incorporate additional streaming capabilities in order to pipe output from one command to the next, but I haven't had a chance to yet.

I still haven't used this in any kind of educational setting, but I'm eager to try it out. Let me know if you give it a go!