FooCAD Source Codeimport static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*
/**
Use a ratchet tie down strap to glue up woodworking projects.
Print Notes
High perimeters (4?) and fill percentage (30%) for strength.
4 top and bottom layers.
The optional "jaw" pieces should be printed in TPU (or other flexible filament)
*/
class BandClampCorner : Model {
@Custom( about="Larger than the width of the band" )
var width = 26
@Custom( about="Length of the internal corner" )
var length = 40
@Custom( about="How chunky")
var depth = 16
// The x value must be larger than the strap's thickness
@Custom( about="Width and thickness of the overhang, which keeps the band in place")
var overhang = Vector2(3, 1.6)
@Custom
var tabSize = Vector2( 12, 2 )
@Custom
var jawThickness = 2.2
fun profile() = PolygonBuilder().apply {
moveTo(0,0)
lineBy( length, 0 )
lineBy( 0, depth )
radius( depth *2 )
lineBy( -length - depth, 0 )
radius( 0 )
lineBy( 0, -length -depth )
lineBy( depth, 0 )
}.build()
@Piece
fun squareCorner() : Shape3d {
val profile : Shape2d = profile()
val larger = profile.offset( overhang.x/2 ).translate(-overhang.x/2, overhang.x/2)
val main = ExtrusionBuilder().apply {
crossSection( larger )
forward( overhang.y )
crossSection()
crossSection( profile )
forward( width )
crossSection(profile)
forward( overhang.x * 0.6 ) // Angle the overhang, so that it is printable.
crossSection( larger )
forward( overhang.y )
crossSection()
}.build()
// Holes amy improve strength, by forcing additional material around the hole
// so we get compression of solid plastic, not infill.
val hole = Cylinder( depth + 2, 3 ).sides(8)
.rotateX(90).centerZTo( main.size.z / 2 )
.frontTo(-1)
val holes = hole
.leftTo(depth/2)
.spreadX(3, length-depth)
.rotateZ(90).mirrorY().also(2) +
hole.rotateZ(45)
val tab = Cube( tabSize.x, tabSize.y, main.size.z )
.rightTo( main.right ).frontTo(main.back )
val tab2 = tab.rotateZ(90).mirrorY()
val clearance = Cylinder( main.size.z + 2, 2 ).translate(1,-1, -1)
return main - holes - clearance + tab + tab2
}
@Piece
fun jaw() : Shape3d {
val main = squareCorner()
return Square(length-jawThickness, main.size.z+jawThickness*2)
.roundAllCorners(1)
.chamferedExtrude( jawThickness*2, 0.8,0 ).centerY() -
Cube(length-jawThickness*2, main.size.z, jawThickness+1 ).centerY().bottomTo( jawThickness )
}
override fun build() : Shape3d {
val main = squareCorner().color("Orange")
val jaw : Shape3d = jaw().rotateX(90).mirrorY()
.backTo(jawThickness).bottomTo(-jawThickness).rightTo(length+jawThickness)
.color("Yellow")
val jaws = jaw + jaw.rotateZ(90).mirrorY()
return main + jaws
}
}