import static uk.co.nickthecoder.foocad.arrange.v1.Arrange.* import uk.co.nickthecoder.foocad.screws.v3.* import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* class SlideBolt : AbstractModel() { @Custom( about="Size of the main body" ) var size = Vector3(80, 40, 4) @Custom var boltDiameter = 10 @Custom( about="The distance between the open and closed positions" ) var movement = 20 @Custom( about="Length of the catch" ) var otherPartLength = 25 @Custom( about="Elongation of the screw holes. 0 = no adjustment" ) var elongated = 12 @Custom( about="Width and thickness of the two hoops on the main body") var hoopSize = Vector2(10, 2) var flat = 1 var clearance = 0.5 var slack = 1 meth hoop( width : double ) = hoop( width, boltDiameter ) meth hoop( width : double, boltDiameter : double ) : Shape3d { val innerR = boltDiameter/2 + clearance val outerR = innerR + hoopSize.y val profile = Circle( outerR ) + Square( outerR, outerR*2 ).centerY() - Circle( innerR ) val hoop = profile.extrude( width ) .rotateY(90) .centerX() .translateZ( boltDiameter/2 + size.z ) return hoop } meth sliceBottom( shape : Shape3d ) : Shape3d { return shape intersection shape.boundingCube().bottomTo(0) } meth body() : Shape3d { val base = Square( size.x, size.y ).center() .roundAllCorners(3) .extrude(size.z) val retainer = hoop(hoopSize.x) .leftTo(base.left) val guide = Cube( movement - boltDiameter, hoopSize.y*2, boltDiameter * 1.1 ) .bottomTo( base.top ) .leftTo( retainer.right + boltDiameter + clearance * 2 ) .frontTo( boltDiameter / 2 + clearance ) .mirrorY().also() val guideIndent = Cylinder( base.size.y, boltDiameter/2 ) .rotateX(90).centerY() .bottomTo( base.top ) .leftTo( guide.right - boltDiameter * 0.2 ) val longHoop = hoop( base.right - guide.right - boltDiameter - clearance * 2 ) .rightTo( base.right ) val screwHoles = Countersink() .translateX( base.left + 9 ) .translateY( base.front + 7 ) .topTo( base.top ) .mirrorX().also().mirrorY().also() return base + retainer + guide + longHoop - screwHoles - guideIndent } @Piece meth bodyB() : Shape3d { val body = body() val bounding = Cube( body.size.x+2, body.size.y+2, body.size.z + 2 ) .leftTo(body.left - 1) .frontTo(body.front -1 ) .bottomTo( -1 ) val remove = Cube( hoopSize.x + 2 + boltDiameter/2, 100, 100 ) .centerY() .leftTo(body.left - 1) .bottomTo( 1 ) return body intersection (bounding - remove) } @Piece meth bodyA() : Shape3d { val body = body() val remaining = Cube( hoopSize.x + 2 + boltDiameter/2, 100, 100 ) .centerY() .leftTo(body.left - 1) .bottomTo( 1 ) return (body intersection remaining).bottomTo(0) } @Piece meth otherPart() : Shape3d { val base = Square( otherPartLength, size.y ).center() .roundAllCorners(3) .extrude(size.z) val retainer = hoop(otherPartLength, boltDiameter + slack * 2 ) val screwHoles = Countersink() .elongated( elongated ) .translateY( base.front + 7 ) .topTo( base.top ) .mirrorY().also() return base + retainer - screwHoles } @Piece meth bolt() : Shape3d { val bolt = Circle( boltDiameter/2 ) .chamferedExtrude( size.x + movement, 2 ) .rotateY(90) .centerX().translateX( movement/2 ) .bottomTo( -flat ) val arm = Circle( boltDiameter/2 ) .extrude( boltDiameter*2 ) .rotateX(-90) .bottomTo(-flat) .leftTo(bolt.left + movement + hoopSize.x + clearance*3) val knob = Sphere( boltDiameter * 0.7 ) .bottomTo( -boltDiameter * 0.3/2 ) .translate(arm.middle.x,arm.back, -flat) return sliceBottom( bolt + arm + knob ) } @Piece meth all() : Shape3d { return arrangeY( 5, arrangeX( 5, bodyA(), bodyB(), otherPart() ).centerX(), bolt().centerX() ) } @Piece( print="all" ) override meth build() : Shape3d { val bodyA = bodyA().bottomTo(flat+0.1).translate(-0.111, 0.111, 0).color("Green") val bodyB = bodyB().color("LightGreen") val bolt = bolt().bottomTo(flat + size.z) val otherPart = otherPart().leftTo( bodyB.right + 2 ).color("LightGreen") return bolt + bodyA + bodyB + otherPart } }