# Day 230 – Sofamaker

## Day 230 – Sofamaker

Day 230 – Sofamaker 150 150 mathgrrl

It’s official; we are moving to NYC this summer! This means downsizing from a house to an apartment, and some interesting furniture decisions. To help sort things out (and to procrastinate actually packing for as long as possible) I wrote a customizable sofa generator in OpenSCAD, and used it to model our sofas:

Settings: Printed on a Replicator 2 with MakerWare .3mm/low.
Technical notes, OpenSCAD flavor: The code below makes sofas in the same way that we made knots in Day 153, by using hulls of collections of spheres. For example, the sofa code starts by forming an upright rectangular solid to make the back of the sofa, with eight spheres placed at the corners and then hull() filling in the space between by taking the convex hull of those eight spheres. Of course we could also have used the cube() command to make the rectangular solid, but taking the hull of spherical corners is what gives our sofas a rounded, comfy look.
We used a scale of 1:50 for these models (meaning that our furniture is fifty times as long, wide, and tall as these models) and a conversion factor that allowed us to enter our dimensions in inches. For example, one of our sofas has depth 59″, length 70″, and height 32″. To convert these to inches we have to multiply by 25.4, since there are 25.4 millimeters in an inch. Then to make the scale 1:50 we divide by scale=50.  In the future we’ll add the ability to scale automatically to certain types of graph paper.
// mathgrrl parametrizable sofa

/////////////////////////////////////////////////////////////
// parameters ///////////////////////////////////////////////

\$fn = 12; // facets
scale = 50;  // enter desired scaling factor here e.g. 50 means 1:50
m = 25.4; // measurement unit conversion
//(m=25.4 does 1:1 scale with inches entered)
//(m=12*25.4 does 1:1 scale with feet entered)
//(m=10 does 1:1 scale with cm entered)
//(m=1000 does 1:1 scale with meters entered)
s = m/scale; // scaling factor
r = 3*s;     // radius for soft bevels depends on scale
tiny = .2;   // radius for sharper edges

/////////////////////////////////////////////////////////////
// renders //////////////////////////////////////////////////

//uncomment the one you want to make

// purple loveseat
//sofa(depth=39,length=70,height=32);

// purple sofa
//sofa(depth=39,length=90,height=32);

// tan sofa
//sofa(depth=36,length=80,height=34);

// brown loveseat
//sofa(depth=36,length=54,height=34);

// spotted chair
//sofa(depth=36,length=35,height=34);

// ottoman
//ottoman(depth=27,length=23,height=16);

/////////////////////////////////////////////////////////////
// module for making sofas //////////////////////////////////

module sofa(depth,length,height){
// back of sofa
hull(){
translate(s*[0,0,0]) sphere(r);
translate(s*[0,0,height]) sphere(r);
translate(s*[0,length,height]) sphere(r);
translate(s*[0,length,0]) sphere(r);
translate(s*[depth/4,length,0]) sphere(r);
translate(s*[depth/4,0,0]) sphere(r);
translate(s*[depth/4,0,height]) sphere(r);
translate(s*[depth/4,length,height]) sphere(r);
}
// left arm of sofa
hull(){
translate(s*[0,0,height/2]) sphere(r);
translate(s*[depth,0,height/2]) sphere(r);
translate(s*[depth,0,0]) sphere(r);
translate(s*[0,0,0]) sphere(r);
translate(s*[0,depth/4,0]) sphere(r);
translate(s*[depth,depth/4,0]) sphere(r);
translate(s*[depth,depth/4,height/2]) sphere(r);
translate(s*[0,depth/4,height/2]) sphere(r);
}
// right arm of sofa
hull(){
translate(s*[0,length,height/2]) sphere(r);
translate(s*[depth,length,height/2]) sphere(r);
translate(s*[depth,length,0]) sphere(r);
translate(s*[0,length,0]) sphere(r);
translate(s*[0,length-depth/4,0]) sphere(r);
translate(s*[depth,length-depth/4,0]) sphere(r);
translate(s*[depth,length-depth/4,height/2]) sphere(r);
translate(s*[0,length-depth/4,height/2]) sphere(r);
}
// cushions of sofa
hull(){
translate(s*[0,0,0]) sphere(r);
translate(s*[depth,0,0]) sphere(r);
translate(s*[depth,length,0]) sphere(r);
translate(s*[0,length,0]) sphere(r);
translate(s*[0,length,height/3]) sphere(r);
translate(s*[depth,length,height/3]) sphere(r);
translate(s*[depth,0,height/3]) sphere(r);
translate(s*[0,0,height/3]) sphere(r);
}
}

/////////////////////////////////////////////////////////////
// module for making ottomans ///////////////////////////////

module ottoman(depth,length,height){
hull(){
translate(s*[0,0,0]) sphere(r);
translate(s*[depth,0,0]) sphere(r);
translate(s*[depth,length,0]) sphere(r);
translate(s*[0,length,0]) sphere(r);
translate(s*[0,length,height]) sphere(r);
translate(s*[depth,length,height]) sphere(r);
translate(s*[depth,0,height]) sphere(r);
translate(s*[0,0,height]) sphere(r);
}
}
• I really love this series – wish we had had a series of units when planning our new kitchen – maybe manufacturers will soon routinely provide printable models.

I would be tempted to refactor (easy to do after you've done the work )

module cuboid(depth,length,height,r=1) {
hull(){
translate([0,0,0]) sphere(r);
translate([depth,0,0]) sphere(r);
translate([depth,length,0]) sphere(r);
translate([0,length,0]) sphere(r);
translate([0,length,height]) sphere(r);
translate([depth,length,height]) sphere(r);
translate([depth,0,height]) sphere(r);
translate([0,0,height]) sphere(r);
}
}

module sofa(depth,length,height,r=2) {
cuboid(depth/4,length,height); //back
cuboid(depth,depth/4,height/2); // left arm
translate([0,length-depth/4,0])
cuboid(depth,depth/4,height/2); //right arm
cuboid(depth,length,height/3); // cushions
}
scale(s)
sofa(39,90,32);

• Really the cuboid should be the following to get accurate external dimensions:

module cuboid(depth,length,height,r=1) {
hull(){
translate([r,r,r]) sphere(r);
translate([depth-r,r,r]) sphere(r);
translate([depth-r,length-r,r]) sphere(r);
translate([r,length-r,r]) sphere(r);
translate([r,length-r,height-r]) sphere(r);
translate([depth-r,length-r,height-r]) sphere(r);
translate([depth-r,r,height-r]) sphere(r);
translate([r,r,height-r]) sphere(r);
}
}

• Yes, I noticed this dimension problem and tried to ignore it… but it did make a noticeable difference so I am going to do what you just suggested when I write the general program for all the furniture on Sunday and post to Thingiverse. I appreciate your refactored code as well – a cuboid module is definitely wise to construct since I have to use it over and over. Thanks!

Share