Tinkering with hobby projects

Software is so suffuse with money that it can be hard not to think in the "product" mindset. Sometimes the product is just for yourself and it's the journey of making something.

My dad taught me to read by teaching me to code. I was 4 years old, and we'd do Dr. Seuss and TI-99/4A BASIC. I will always code, no matter how much of an "executive" I am at work. I learn new things by coding them, even if the thing I'm learning has nothing to do with code. It's a tool I use for understanding something I'm interested in.

These days I'm diving into woodworking, specifically furniture making. I'll post some pictures in this article, but I want to talk about my newest hobby project. I'm not sure it'll ever see the light of day outside of my own personal use. And that's okay. I think a lot of folks think they have to put it up on GitHub, promote it, try to make a gig out of it or at least use it as an example in their job interviews. I think that mindset is always ends-oriented instead of journey oriented.

A hobby has to be about the journey, not the destination. This is because the point of a hobby is to enjoy doing it. When I was working on the coffee table I made a month ago or the bookshelf I just completed, every step of the journey was interesting, and everything was an opportunity to learn something new. If I was focused on the result, I wouldn't have enjoyed it so much and it's far easier to get frustrated if you're not in the moment, especially with something like woodworking. Johnathan Katz-Moses says, "Woodworking is about fixing mistakes, not not making them."

So when I write a hobby project, I write for myself. I write to understand the thing that I'm doing, and often I don't "finish" the project. It's not because I get distracted, but because the point of the code was to understand something else better. In this case it's woodworking. First, a couple of table pictures:

Cat for scale. Hi, Bitty!

I will probably end up using Blender and Sketchup for my woodworking, because I'd rather spend more time in the shop than on my computer (although there's plenty of time waiting for finishes and glue to dry for me to tinker on code and write blog posts for you all). But the reasons I wanted to write some new code for modeling my woodworking are:

  1. As a kid, I got a shareware catalog, and I'd use my allowance to buy games and tools. My most-used shareware program was POV-Ray and I kind of want something like that for reasons I'll get into.
  2. I wanted to write something where I could come out with a "cut list" and an algorithm for making a piece.
  3. I like to code.

Point 1: POV-Ray, CSG, and Woodworking.

I loved POV-Ray as a kid. With my Packard Bell 386, and the patience to start a render before bed and check it when I got back from school the next day, I could make it do some really impressive things. When we got our first Pentium, I really went nuts with it. The great thing about POV-Ray was CSG or constructive solid geometry and the scene-description-language. You modeled in 3-D by writing a program, which suits me well.

But also, CSG. I think CSG is going to be perfect for modeling woodworking. The basic idea is that you use set-theory functions like intersection, difference, and union to build up geometries (meshes in our case).

So if I want a compound miter cut through a board, that's a rotation and translation of a plane and a difference between a piece of stock and that plane with everything opposite its normal vector considered "inside" the plane. If I want to make a dado, that's a square extruded along the length of the dado cut. If I want to make a complicated router pattern like I would with a CNC, I can load an SVG into my program, extrude it, and then apply the difference to the surface of a board. And so on and so on.

Basically the reason this works so well for woodworking is that I have to express a piece as a series of steps, and these steps are physically-based. I can use CSG operations to model actual tools like a table saw, router, compound miter saw, and drill press. With a program like Blender or SketchUp, I can model something unbuildable, or so impractical that it won't actually hold up once it's put together.

Point 2: CSG makes my work algorithmic and more like working on software.

With CSG I can "play" the piece being made, step by step and make sure that I can make the cuts and the joins, and that they'll be strong, effectively "debugging" the piece like using a step-by-step debugger.

I can also take the same set of steps and write them out as a set of plans, complete with diagrams of what each piece would look like after each step.

I'm going to to back to Logo and make this a bit like "turtle math" My turtle will be where I'm making my cut or adding my stock, and I will move it each time before adding the next piece. This is basically just a way to store translation and rotation on the project so I don't have to pass those parameters into every single geometry operation, and also a way to put a control for that on the screen to be manipulated with the mouse or keyboard controls. This is only my current thinking and I may abandon it if I think it's making it more complicated for me.

Point 3: I like to code.

I won't belabor point #1 above. I think we know I love to code. But what I will do quickly is talk about the tools I'm using. I usually use Python, but this is one case where I'm going to use Typescript. Why? Because the graphics libraries for JS/TS are so much better and more mature, and because it's far easier to build a passable UI when you have a browser to back you.

The core libraries that I'll be using in my project are:

Three.js is pretty well known, so I won't go into that except to say that it has the most robust toolset for the work I'm intending to do.

BVH stands for "bounding volume heirarchy," which is a spatial index of objects that you can query with raycasting and object intersection. It's used by three-bvh-csg for performance. I'm planning to use it as well to help me establish reference faces on work-pieces.

When you measure for woodworking, rulers are not to be trusted. Two different rulers from two manufacturers will provide subtly different measurements. So when you do woodworking, you typically use the workpiece as a component of your measurements. A reference face, from the standpoint of the program I'm writing is the face of an object that I want to measure from, with its surface normal negated. Translations and rotations will all be relative to this negated surface normal (it's negated so the vector is pointing into the piece instead of away from it). My reference faces will be sourced from the piece. They'll be a face on the object, a face on the bounding box, or a face comprised of the average surface normal and chord through a collection of faces (like when measuring from a curved piece).

So where am I with this?

I've only just started. I've spent maybe 4 or 5 hours on it relearning 3d programming and getting familiar with three.js and the CSG library. I don't think it's impressive at all, but I do think it's important in a post like this to show that everything starts small.

It's okay to be bad at something on your way to becoming good, and even the most seasoned programmer is a novice in some ways. Sure, I can write a SaaS ERP system, a calendar system, a chat system or a CMS, but the last time I wrote any graphics code was 2012 or so and that was 2D stuff so I'm dusting off forgotten skills.

A board, a 30 degree compound miter cut off the right face, and the "turtle"

Right now there's not even a github repository. I'm not sure there ever will be. It's really just a project for me that's useful and fun as long as it's teaching me stuff about woodworking, and maybe eventually if it's truly useful in putting together projects.

And that's okay. Not everything is meant to be a showcase of one's amazing skills or a way to win the Geek Lottery (phrase TM my wife).