import 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 } }