import uk.co.nickthecoder.foocad.smartextrusion.v1.* import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* import static uk.co.nickthecoder.foocad.along.v3.Along.* import uk.co.nickthecoder.foocad.woodworking.v1.* import static uk.co.nickthecoder.foocad.woodworking.v1.Woodworking.* import uk.co.nickthecoder.foocad.screws.v3.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* include BoxConstruction.foocad class Stool : Model { var size = Vector3( 360, 360, 480 ) var linkThickness = 4 var gap = 1 var rodDiameter = 3.1 val lidThickness = 12 var lumberSize = Vector2( 21, 19 ) var quick = false meth wood() = Wood( "main", lumberSize.x, lumberSize.y ).color("DarkGrey") meth screwHole() = if (quick) { Cube(0) } else { Countersink().headDiameter(7).holeDiameter(3.5).recess(0.75).depth(2.8) } meth construction() : BoxConstruction = BoxConstruction().apply { cornerExtra = 17 angleExtra = 10 thickness = 3.0 insideRadius = 2 crossSection = lumberSize screwHole = screwHole() } meth fourOf( shape: Shape3d ) : Shape3d { return shape.leftTo(1).frontTo(1).mirrorX().also().mirrorY().also() } @Piece( about="For base's top corners. Required: 2x2" ) meth corner() : Shape3d { val con = construction() // As the corner will be hidden by the seat, we can add an extra screw... return con.cornerB() - screwHole().mirrorZ() .translateX( con.thickness + wood().thickness/2 ) .translateY( con.thickness + wood().width/2 ) } @Piece meth corners() = fourOf( corner() ) @Piece(about="For bars near the floor. Required: 2x2" ) meth forBar() : Shape3d { val a = construction().straightConnectorA() val b = construction().straightConnectorC() .mirrorY() .mirrorZ().bottomTo(0) .rotateZ(90) .leftTo( a.left ).frontTo( a.front ) return (a and b).rotateX(90).bottomTo(0) } @Piece meth forBars() = fourOf( forBar() ) @Piece meth forRailA() = forBar() @Piece meth forRailB() = construction().straightConnectorC().rotateX(90).bottomTo(0) @Piece meth forRails() : Shape3d { val a = forRailA().leftTo(1).frontTo(1) val b = forRailB().rightTo(-1).frontTo(1) return (a + b).mirrorY().also() } @Piece meth angleA() = construction().angleA(45) @Piece meth angleC() = construction().angleC(45) @Piece meth backAngles() : Shape3d { return fourOf( angleA() ) } @Piece meth frontAngles() : Shape3d { val con = construction() val a = angleA().leftTo(1).mirrorX().also().frontTo(1) val c = angleC().leftTo(1).mirrorX().also().backTo(-1) return a + c } @Piece( about="For Lid's corners. Required: 2x2" ) meth elbow() = construction().jointC() @Piece meth elbows() : Shape3d { return fourOf( elbow() ) } @Piece meth foot() = construction().endStop(20) - screwHole().mirrorZ() @Piece meth feet() = fourOf( foot() ) @Piece( about="Rubber (TPU) glued to piece `foot` (or directly to the leg if you prefer)" ) meth footPad() = Square( wood().width + 2, wood().thickness + 2 ) .center() .roundAllCorners(3) .smartExtrude(2) .top( Chamfer(1.5) ) .color("Purple") meth ply( x : double, y : double, cornerSize: double ) : Shape3d { val sq = Square(x,y).offset(-3).center() val corners = Square( cornerSize -3 ) .roundCorner(2, cornerSize*0.75) .leftTo(sq.left).frontTo(sq.front) .mirrorX().also().mirrorY().also() return (sq-corners).extrude(6) } @Piece( about="A template to draw the corners of the seat" ) meth topCornerJig() = cornerJig( wood().width*2 ) @Piece( about="A template to draw the corners of the shelf" ) meth shelfCornerJig() = cornerJig( wood().width*1.75 ) meth cornerJig( cornerSize : double) : Shape3d { val hole = Square( cornerSize -3 ) .roundCorner(2, cornerSize*0.75 ) val shape = Square( cornerSize*1.5 ).roundCorner(2,cornerSize*2) - hole val walls = Cube( 2, cornerSize/2, 4 ) .rightTo(0) .frontTo( cornerSize ) .rotateZ(-90).backTo(0).also(2) return shape.extrude(0.6) + walls } @Piece( printable=false ) meth seat() : Shape3d { val con = construction() val wood = wood() val extra = con.thickness*4 + 6 val size = Vector2( this.size.x + wood.thickness*2 + extra, this.size.y + wood.thickness*2 + extra ) val sides = wood.cut( size.x ) .label("lidSide") .edgeDownAlongX().centerX().frontTo( -size.y/2 ) .mirrorY().also() val ends = wood.cut( size.y - wood.thickness*2 ) .label("lidEnd") .edgeDownAlongY().centerY().leftTo( -size.x/2 ) .mirrorX().also() val corners = elbow() .rotateX(-90).bottomTo( -con.thickness ) .leftTo( -size.x/2 - con.thickness ) .frontTo( -size.y/2 - con.thickness ) .mirrorX().also().mirrorY().also() .color("Orange") val ply = ply( size.x, size.y, wood.width*2 ) .bottomTo( sides.top ) return sides + ends + corners + ply } meth rail() : Shape3d { val con = construction() val wood = wood() val sideRails = wood.cut( size.y - wood.thickness*2 ) .label("sideRail") .edgeDownAlongY() .centerY() .rightTo( size.x/2 ) .mirrorX().also() val backRail = wood.cut( size.x - wood.width*2 ) .label("endRail") .edgeDownAlongX() .centerX() .backTo( size.y/2 ) .color("LightGrey") val forRailsA = forRailA().rotateX(-90) .rotateZ(180) .rightTo( sideRails.right + con.thickness ) .backTo( backRail.back + con.thickness ) .bottomTo( - con.thickness ) .mirrorX().also() .color("Orange") val forRailsB = forRailB().rotateX(-90) .rotateZ(90) .rightTo( sideRails.right + con.thickness ) .frontTo( -size.y/2 - con.thickness ) .bottomTo( - con.thickness ) .mirrorX().also() .color("Orange") return sideRails + backRail //+ forRailsA + forRailsB } meth shelf() : Shape3d { val con = construction() val wood = wood() val sideBars = wood.cut( size.y - wood.width*2 ) .label("sideBar") .edgeDownAlongX().centerX().frontTo( -size.y/2 ) .mirrorY().also() .color("LightGrey") val endBars = wood.cut( size.x - wood.thickness*2 ) .label("endBar") .edgeDownAlongY().centerY().leftTo( -size.x/2 ) .mirrorX().also() val shelf = ply( size.x -2, size.y-2, wood.width*1.75 ) .bottomTo( sideBars.top ) val forBars = forBar().rotateX(-90) .translateX( -size.x/2 + wood.width ) .frontTo( -size.y/2 - con.thickness ) .translateZ( -con.thickness ) .mirrorX().also().mirrorY().also() .color("Orange") return sideBars + endBars + forBars + shelf } @Piece( printable=false ) override fun build() : Shape3d { quick = true val con = construction() val wood = wood() val barHeight = size.z * 0.2 val railHeight = size.z * 0.6 val corners = corner() .rotateZ(90) .rightTo( size.x/2 + con.thickness ) .frontTo( -size.y/2 - con.thickness ) .mirrorX().also().mirrorY().also() .mirrorZ().translateZ(size.z + con.thickness) .color("Orange") val foot = foot() .leftTo( -size.x/2 -con.thickness ) .frontTo( -size.y/2 - con.thickness ) .translateZ( - con.thickness ) val feet = foot .mirrorX().also().mirrorY().also() .color("Orange") val pad = footPad().mirrorZ() .centerXTo( foot.middle.x ) .centerYTo( foot.middle.y ) .topTo(feet.bottom) val pads = pad .mirrorX().also().mirrorY().also() val strutSide = wood.cut( size.x ) .label("sideStrut") .edgeDownAlongX().centerX().frontTo( -size.y/2 ) .mirrorY().also() .color("DarkGrey").darker() val strutEnds = wood.cut( size.y - wood.thickness*2 ) .label("endStrut") .edgeDownAlongY().centerY().leftTo( -size.x/2 ) .mirrorX().also() val legs = wood.cut( size.z - wood.width ) .label("leg") .leftTo( -size.x/2 ).frontTo( -size.y/2 ) .mirrorX().also().mirrorY().also() .color("DimGray") val struts = legs + (strutSide + strutEnds).translateZ( size.z - wood.width) val seat = seat() .translateZ( size.z - wood.width ) val shelf = shelf().translateZ( barHeight ) val backAngleJoints1 = con.angleA(45) .rotateY(90) .backTo( corners.back ) .topTo( corners.top ) .translateX(10).mirrorX().also() .color("Orange") val backAngleJoints2 = con.angleA(45) .backTo( corners.back ) .leftTo(corners.left).mirrorX().also() .bottomTo( size.z - size.x/2 ) .color("Orange") val frontAngleJoints1 = con.angleC(45) .rotateZ(90) .frontTo( corners.front ) .bottomTo( railHeight - 150 ) .leftTo( corners.left ).mirrorX().also() .color("Orange") val frontAngleJoints2 = con.angleA(45) .rotateZ(-90).rotateX(90) .backTo( -size.y/2 + 150 ) .leftTo( corners.left ).mirrorX().also() .topTo( railHeight + con.thickness ) .color("Orange") val angles = backAngleJoints1 + backAngleJoints2 + frontAngleJoints1 + frontAngleJoints2 val rails = rail().topTo( railHeight ) return struts + corners + rails + angles + seat + feet + pads + shelf } }