import static uk.co.nickthecoder.foocad.arrange.v1.Arrange.* import static uk.co.nickthecoder.foocad.screws.v3.Screws.* import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* class SlideBolt : Model { var size = Vector3(80, 40, 4) var boltDiameter = 10 var movement = 20 var hoopSize = Vector2(10, 2) var flat = 1 var clearance = 0.5 var slack = 1 fun hoop( width : double ) = hoop( width, boltDiameter ) fun 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 sliceBottom( hoop ) } fun sliceBottom( shape : Shape3d ) : Shape3d { return shape intersection shape.boundingCube().bottomTo(0) } fun 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 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 } @Piece fun 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 fun 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 fun otherPart() : Shape3d { val base = Square( movement, size.y ).center() .roundAllCorners(3) .extrude(size.z) val retainer = hoop(movement, boltDiameter + slack * 2 ) val screwHoles = Countersink() .translateX( base.left + 9 ) .translateY( base.front + 7 ) .topTo( base.top ) .mirrorY().also() return base + retainer - screwHoles } @Piece fun 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 ) } override fun build() : Shape3d { return arrangeY( 5, arrangeX( 5, bodyA(), bodyB(), otherPart() ).centerX(), bolt().centerX() ) } @Piece override fun preview() : 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 } }