Solid Python and furniture making

So i’ve been looking at Fusion 360 tutorials for flat pack furniture, and though the interface is pretty I find the content severely lacking. Dogbones for every joint? Seriously?

Anyway, I know from experience that OpenSCAD s a crap language, so I tried out Solid Python. Within an hour and 30 lines of code I had a rounded half-blind joint function, and 5 minutes after that I had a bookcase model. I’ll have to see how it actually turns out since it will require 3D milling, but so far it’s really promising.

Ah, that is music to my ears. I tried openSCAD, but the IDE/syntax was terrible. IIRC, the display window didn’t update terribly fast, which I guess you still need to use?

I have seen a few other Python tools that seem useful, but I haven’t got much use out of them yet:


I was thinking of making some quick scripts to check for stupid mistakes in my gcode, or to use as a visual check, or I would even like to have something that generates a separate bounds gcode file that just traces the outside quickly so I can make sure I don’t trash clamps or have the workpiece in the wrong direction.


This has a lot of neat tools.


I saw another box generator that used this to make boxes, after you enter x,y,z then you can load it into your other CAD software, and do something extra.

That looks like it could be really interesting. Let us know how you get on. Would it work for a library of standard joints like box joints, dovetails, tenons etc?

The dxfwrite one looks promising!

And yes, I think it could work as a library. In fact, I’m planning on writing one :slight_smile:

Here’s my sample code from last night. I had a couple drinks before hand, so try not to judge too harshly…

#! /usr/bin/env python
# -*- coding: UTF-8 -*-
from __future__ import division
import os
import sys
import re

# Assumes SolidPython is in site-packages or elsewhwere in sys.path
from solid import *
from solid.utils import *

SEGMENTS = 90

def tabs(height,width,depth,cutDiameter,count,closeSides=True):
    singleTab = hull()(
        cube([width/count,depth,height-cutDiameter/2]),
        translate([cutDiameter/2,0,height-cutDiameter/2])(
            rotate([-90,0,0])(cylinder(cutDiameter/2,depth))
        ),
        translate([width/count-cutDiameter/2,0,height-cutDiameter/2])(
            rotate([-90,0,0])(cylinder(cutDiameter/2,depth))
        )
    )
    d = right(cutDiameter/2)(
        cube([width-cutDiameter,depth,height-cutDiameter])
    )
    neg = cube([0,0,0])
    for i in range(count):
        if i % 2 == 0:
            d += right(i*width/count)(singleTab)
        else: 
            d -=  up(height)(
                right((i+1)*width/count)(
                    rotate([0,180,0])(singleTab)
                )
            )
            
    if closeSides:
        if (count % 2 == 0):
            d += cube([cutDiameter/2,depth,height])
            d -= right(width-cutDiameter/2)(
                cube([cutDiameter/2,depth,height])
            )
        else:
            d += cube([cutDiameter/2,depth,height])
            d += right(width-cutDiameter/2)(
                cube([cutDiameter/2,depth,height])
            )
    return d

def assembly():
    sideHeight = 200
    sideWidth = 100
    ply = 0.47 * 25.4
    topWidth = 150
    tabHeight = 8
    tabCount = 11
    cutterDiameter = 3.125
    sidePanel = cube([sideWidth,ply,sideHeight-ply]);
    sidePanel += up(sideHeight-ply)(
            tabs(tabHeight, sideWidth, ply, cutterDiameter, tabCount)
        )
    leftPanel = right(ply)(
        rotate([0,0,90])(sidePanel)
    )
    rightPanel = right(topWidth)(
       rotate([0,0,90])(sidePanel)
    )
    top = up(sideHeight-ply)(
        cube([topWidth,sideWidth, ply])
    )
    top -= leftPanel
    top -= rightPanel
    return leftPanel + rightPanel

if __name__ == '__main__':
    a = assembly()
    scad_render_to_file(a, file_header='$fn = %s;' % SEGMENTS, include_orig_code=True)

And here’s the renderings… Don’t mind the translucent layer on the second one. It’s a visual rendering bug in OpenSCAD

That’s pretty sweet. I really want to make a place to clamp a board underneath the MPCNC so I can carve the end grain for joints like this. I think might work better than sculpting the second piece. Then you could do a dovetail or jigsaw like pattern instead, which would give you even more strength.

I want to see how it turns out!

@Jeffeb3 I’m hoping to try out the finger joints tonight or tomorrow. If that works out, dovetails are next on my list.

I should also mention I’m very much open to collaboration on this :slight_smile:

OK, You make the first one and I’ll make the second one. Where should I ship it? :smiley:

You want to collaborate, like me doing a code review, OK:

  • Where did top go?
  • Don’t use single letter variable names, it makes them too hard to search for.

How’s that? Feels a bit too much like I’m at work, boo.

In all seriousness, I will help where it fits in, but I have littered the Internet with empty promises of help, I just get hot and cold in terms of how busy I get, and how much time I get for my hobbies, so I always have a big queue of things to do in my spare time. Keep me posted, and let me know if there’s something I can do.

Hah no worries… I was just hoping to offload some of the work :wink:

I’m happy to release it once I get it in a decent state… I do only have so much time for my hobbies though, and I don’t see myself getting around to, say, 3 way puzzle joints any time soon. So I’m hoping to drum up enough interest that someone else does it for me.

I’m also not very familiar with python, CAD, or furniture making (what are these type of joints called anyway? I’m gonna call them “stubby fingers” until I find out)… So I’m guessing I’ll make a lot of noob mistakes. This one’s not gonna be a resume builder – I just want to build some cool furniture, and don’t want to make everyone else reinvent the wheel.

– Don’t use single letter variable names, it makes them too hard to search for.

@Jeff, one of my friends just tweeted this this morning.
“All programming variables and functions will now be Russian words just to screw with people.”

I would call them box joints if they went all the way through, and weren’t round, so I think they would be half blind, rounded box joints. I think we should just call them fat fingers. IMO, github or gist.github would be a better place to collaborate with something like this.

Barry, There was a guy in college that would write his software, make sure it worked, and then replace all the variables and object names with characters from star wars.

I used to adhere to the no-single-letter thing… Then I saw too many instances of “__ProducerWorkerFactoryFactory”.

Check out Haskell… They don’t even limit it to single letters – most concepts are just represented by random keyboard symbols. It actually works out, though, because the code is so short you don’t lose track of what’s going on.

And yeah, planning to use github when I get to that point. Not quite there yet though.

Or BetterCommonObjectForWorkingOnGeneralStuff. A coworker of mine is more into the no single letter things, I think he constantly uses search to read code, so the ‘i’, ‘j’, ‘r’, 'd’s drive him mad. My pet peeve is definitely when names have extra words that don’t add anything. We all have our glitches.

Status report: The 3D printing on the top turned out well aside from the fact that Fusion 360 didn’t cut out the bottom by default (should have looked more closely at the simulation). It took for freaking ever to cut though… I think a lot of this is due to frequent attempts to lift the spindle, move, and then make a very minor cut. Since the spindle speed is pretty limited, this took quite a while. Going to cut a side panel tomorrow to make sure it fits and test out the 2D cutting on Fusion 360, but I’m about 95% sure it’ll fit.

Software will be more of an issue than I had anticipated. Fusion 360 doesn’t handle zero-sized solids as well as most 3D printer slicers do, so it’s going to be a challenge compensating for that in a generalized manner.

Have you seen my post on G00/G01? I’m not sure it will give you a solution for slow travel moves, but it should give you an idea about what’s going on. I wonder if there’s a way to tell 360 to do G00 … F10000 on any travel moves.

G00/G01

Fusion isn’t giving me the weird slow travel movements, it’s just doing a ton of passes. I have my Z move speed set really low because I’ve haf issues with it gringing away the threaded rod in the past, so this likely wouldn’t be a problem if switch to a leadscrew or ballscrew (assuming I can figure out a way to mount it…)

I think a lot has to do with my feeds and speeds settings. Adaptive clearing is really different than contours, and I’m not sure what the right settings should be.

I haven’t gotten around to the other test pieces yet, but I did make some progress on dovetails. Because of the shape they still need a dogbone-like opening, and I’ve tried both calculating the smallest possible hole and calculating the smallest hole without rounded portions on the piece that has sloped sides. So far I’m not really liking either, but dovetails will be nice for when you actually need strong joints.

Well I’ve had a bit of a breakthrough on this… It turns out I can bypass the mesh import problem in Fusion360 by converting the .scad file into a .step file using FreeCAD… But this only works if you completely avoid all usage of the ‘hull()’.

I have a pretty nice parametric bookshelf that is going to take me forever to cut. If anyone’s interested, I posted the code on github. And please ignore the crappiness of the code… I will clean it up later, but I wanted to get it saved somewhere permanent before I start refactoring it.

I also love to try this one, it is very good to know some basic ideas of furniture making. I am also considering this idea… Hopefully, this will be perfectly done, I plan to use this model of door http://caldwells.com/interior-doors/craftsman-doors to my own rendition.