Every time I post pictures of a project I’ve completed, someone will ask if I have plans I can share. I never do. I have sketches with numbers near them, but I am confident that no one would be able to interpret them. If it has been too long since I made the project, I might have trouble interpreting them myself!
I’ve started an experiment to correct my lack of sharable plans. Diagrams and how-tos for many of my most recent projects are now available at http://woodworking-plans.beerriot.com/. Other projects from this blog’s history should show up there in the future.
While I gather sketches and measurements of past projects, I think it’s also a good time to explain what tools I’ve used, and why. Most of them are new to me, so I’m hoping this post might generate some discussion on better ways to approach this.
What I’ve settled on for diagramming is OpenSCAD. It’s a 3D modeler, controlled by a programming language that supports basic shape manipulation. I chose a CAD system because I thought that, if I had a full model of the project, I could generate component and assembly diagrams from different, partially-completed views of that model.
I chose a 3D modeler that is programmable because … well, let’s be honest, a good deal of it is because programming is how I interact with computers. But the secondary reason is that I believe the model, itself, is not enough to explain how to build a project. Sure, someone could pull apart a model in whatever tool I used, and inspect it for themselves. But if the point of making the model is to explain the project’s construction, then the product of my process shouldn’t just be the model, but should also include descriptions of the model: diagrams of sizes and angles, and natural language telling a person how to make it.
The model isn’t going to generate natural language build instructions, but if the sizes and angles it uses are available in code, they can also be templated into English written along with the model. To accomplish the templating, I’ve chosen the Jekyll website generator. Via a small script, I can export variable names and values from the model, making them available to include in a templated webpage.
An additional benefit of programmability that I’m excited about is standard version control. That’s exciting because I can develop models iteratively, and improve things over time … and you can help me! The models, the diagrams, and the how-tos are all open-source on Github.
Since you can see my source code, that’s what I’d like to spend the rest of this post talking about. I started learning OpenSCAD only about six weeks ago. If you look through the code repository’s history, you’ll see how I’ve adapted my approach over time. Overall, it has been amazing how quickly I could get useful results from the tool.
There are also places I still feel like I’m fighting the tool. Most of these are places where I would really like the model’s code to somewhat read like a natural description of the creation of the project (start with a piece this size, cut this much off here, attach that other part there), but the details of making the tool render that clearly get in the way (rotate this around x and z, move it an infinitesimal amount to the side to prevent rendering conflicts, color this here so the cut is colored like so, by the way this can be animated). Finding the right abstractions are taking time.
Some abstractions are simple things, like getting used to expressing most things in vectors, instead of individual scalars along (or around) each axis. You can see that I learned that in the perfume display, and then forgot it when I started the toddler tower.
Other things aren’t so much abstractions as they are conventions. For example, which orientation should a component be described in? The way I would think about holding it while making it seems most natural in some ways, but the way it fits into the assembly seems most natural in others. I think the currently popularity of CNC and 3D printing means that most CAD models are described in the orientation that the machine will operate on them. Should I endeavor to describe my components such that they could potentially be made via CNC or 3D printing? Muddled in this decision are which way is up, and where should the origin point be?
Some abstractions seem like more complex concepts. Take, for example, these few notes:
- Nodes in the scene cannot be referenced by variables.
- No introspection can be done on nodes (size, position, color, etc. are all hidden to the language after creation).
- Modules, which look a little like functions in some other programming languages, can create nodes in the scene, but cannot otherwise return values.
- Nodes can’t be passed to modules, but there is a facility called “children”, which allows the effects of modules to be chained together.
- Functions, which also look like functions in some other programming languages, can not create or alter nodes in the scene.
These notes have strong influence on composability. You can write a module that creates a cube of a certain size, and you can write a module that moves whatever its children are up and to the right, and you can chain them together so that you get a cube of a certain size that is moved up and to the right. But, the mover module can’t base the amount that it moves the children on anything about the children. You have to pass parameterization information like that as arguments to the mover module.
It seems like thinking about nodes in the scene similar to the way one would think about side-effects in other languages is the near the right model. My struggle with it is part of why you’ll see many modules and many functions in each model. Since I want to make diagrams showing each component at different stages of its completion, I need the ability to selectively apply each stage. The best I’ve found so far is to define each step of the creation as another module, so that I can apply them in different combinations. That solution came after being unsatisfied by parameterizing the modules with “do this step” or “don’t do that step” arguments. Functions and variables for every value help to make it possible to keep the many modules in sync without threading all of the information through arguments, though it does make for a lot of names to keep track of.
There are a hundred other little things I’ve learned and experimented with along the way, I’m sure, but I’ll save them for another spew session. The OpenSCAD code is only part of the repository. There’s fun things like Liquid templating and the Pure.CSS layout framework that made building the website relatively quick, which I may write about some day as well. For now, if you have time and interest to look around, read some of the code, and let me know what you think. Or better yet, if you have time, material, and interest, have a go at building one of the projects, and let me know what you think of the instructions!