import uk.co.nickthecoder.foocad.extras.v1.* import static uk.co.nickthecoder.foocad.extras.v1.Extras.* import uk.co.nickthecoder.foocad.screws.v3.* import uk.co.nickthecoder.foocad.threaded.v2.* import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* import uk.co.nickthecoder.foocad.smartextrusion.v1.* import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* class TileCurtain : Model { @Custom var size = Vector3( 20, 20, 0.8 ) @Custom var holeDiameter = 1.0 @Custom var holeThickness = 1.2 @Custom var xGap = 6.0 @Custom var round = 2.5 @Custom( about="For pieces `mount` and `mountCurved`" ) var mountColumns = 2//8 @Custom( about="Only used for piece `mountCurved`" ) var mountRadius = 200 @Custom var holeAngle = 15 @Custom var angleStart = 0.4 meth hole() : Shape3d { val plain = (Square( holeDiameter + holeThickness*2, holeDiameter + holeThickness ) .roundCorner(3,1) .roundCorner(2,1) .centerX() - Square( holeDiameter, holeDiameter+0.2 ).centerX().roundCorners(listOf(2,3),holeDiameter/2-0.1,1) ).extrude( size.y ) .rotateX(90) .centerXTo( size.x/4 + xGap/4 ) .centerY() val chamfer = Cube(10).centerXTo( plain.middle.x ) .rotateX( holeAngle ) .translateY( plain.back ) .translateZ( angleStart ) .mirrorY().also() return plain - chamfer } @Piece meth tile() : Shape3d { val tile = Square( size.x, size.y ) .center() .roundAllCorners( round ) .smartExtrude(size.z) .bottom( Chamfer( size.z/2 ) ) val holes = hole() .bottomTo( tile.top ) .mirrorX().also() return tile + holes } @Piece meth endTile() : Shape3d { val tile = Square( size.x *1.5 + xGap*0.5, size.y ) .center() .roundAllCorners( round ) .smartExtrude(size.z) .bottom( Chamfer( size.z/2 ) ) val hole = hole() .bottomTo( tile.top ) val threeHoles = hole .repeatX(3, size.x /2 + xGap/2 ).centerX() val extraHole = hole.rightTo( threeHoles.right - hole.size.x + holeThickness ) return tile + threeHoles + extraHole } @Piece meth tileWithHole() : Shape3d { val plain = tile() return plain - Cylinder(plain.size.z + 0.2, 4).bottomTo(-0.1) } @Piece meth endTileWithHole() : Shape3d { val plain = endTile() return plain - Cylinder(plain.size.z + 0.2, 4).bottomTo(-0.1) .centerXTo( -size.x/2 + xGap/2 ) } meth lockThread() = Thread(6).rodChamfer(0.7) var mountSize = Vector2( 12, 10 ) @Piece meth mount() : Shape3d { val block = Square( (size.x + xGap) * mountColumns - xGap, mountSize.x ).center() .smartExtrude( mountSize.y ) .top( Chamfer(1) ) val holes = Square( holeDiameter*2 ).center() .extrude( block.size.z*1.6 ) .rotateX(45) .frontTo(block.middle.y - 3) .repeatX( mountColumns * 2, (size.x + xGap)/2 ) .centerX() .color("Red") val lockHoles = lockThread() .threadedHole( block.size.z -0.2 ) .chamferStart(false) .bottomTo(0.4) .repeatX( mountColumns, size.x + xGap ) .centerX() .color("Red") val screwHoles = Countersink() .topTo( block.top ) .repeatX( mountColumns -1, (size.x + xGap) ).centerX() return block - holes - lockHoles - screwHoles } @Piece meth mountCurved() : Shape3d { val outer = Circle( mountRadius ) val inner = outer.offset( - mountSize.x ) val mid = -mountRadius + mountSize.x/2 val anglePer = 306 / ((Math.PI * mountRadius)/(size.x + xGap)) val fromAngle = -90 - anglePer * mountColumns/2 val toAngle = -90 + anglePer * mountColumns/2 val block = CircularArc( mountRadius, mountRadius-mountSize.x, fromAngle, toAngle) .smartExtrude( mountSize.y ) .top( Chamfer(1) ) val holes = Square( holeDiameter*2 ).center() .extrude( block.size.z*1.6 ) .rotateX(-45) .backTo(mid + 3) .repeatAroundZ( mountColumns * 2, anglePer/2 ).rotateZ( -(mountColumns-0.5) * anglePer/2 ) .color("Red") val lockHoles = lockThread() .threadedHole( block.size.z -0.2 ) .chamferStart(false) .bottomTo(0.2) .translateY( mid ) .repeatAroundZ( mountColumns, anglePer ).rotateZ( -(mountColumns/2-0.5) * anglePer ) val screwHoles = Countersink() .topTo( block.top ) .translateY( mid ) .repeatAroundZ( mountColumns-1, anglePer ).rotateZ( -(mountColumns/2-1) * anglePer ) .color("Green") return block - holes - lockHoles - screwHoles } @Piece meth lockBolt() = lockThread().bolt(mountSize.y-0.8) - Cube( 10, 1, 1 ).centerXY().rotateZ(30) @Piece( print="tile" ) override fun build() : Shape3d { val across = 15 val down = 4 val yGap = 1.2 val a = tile().rotateX(-90).color("Orange") val b = tile().rotateX(-90).bottomTo(a.top).leftTo( a.middle.x + xGap/2 ).color("Yellow") val aRow = a.repeatX(across,size.x + xGap) val bRow = b.repeatX(across,size.x + xGap).bottomTo(aRow.top+yGap) val endA = endTile().rotateX(-90).color("Orange").rightTo( bRow.right ) val endB = endTile().rotateX(-90).color("Yellow").bottomTo(bRow.bottom).leftTo( aRow.left ) val twoRows = aRow + bRow + endA + endB return twoRows.tileZ(down, yGap) } @Piece meth vertical() : Shape3d { val yGap = 1 val zCount = 4 val xCount = 4 val tile = tile().rotateX(-90) val endTile = endTile().mirrorX().rotateX(-90).leftTo(tile.left) val leftColumn = (endTile + tile.bottomTo( endTile.top + yGap )) .tileZ(zCount,yGap) .bottomTo(0) val midColumn = ( tile.bottomTo( size.y + yGap ).centerXTo( size.x + xGap ) + tile.leftTo( endTile.right + xGap ).bottomTo(0) ).tileZ(zCount,yGap) val middleColumns = (midColumn.color("Green") + midColumn.translateX(size.x+xGap)) .repeatX( xCount, (size.x + xGap)*2 ) val rightColumn = (endTile.rightTo(tile.right).bottomTo( endTile.top + yGap ) + tile) .tileZ(zCount,yGap) .bottomTo(0) .leftTo( middleColumns.right - size.x/2 + xGap /2 ) .color("Green") return leftColumn + middleColumns + rightColumn } @Piece meth vertical2() : Shape3d { val yGap = 1 val zCount = 4 val xCount = 4 val tile = tile().rotateX(-90) val endTile = endTile().mirrorX().rotateX(-90).leftTo(tile.left) val leftColumn = (endTile + tile.bottomTo( endTile.top + yGap )) .tileZ(zCount,yGap) .bottomTo(0) val midColumn = ( tile.bottomTo( size.y + yGap ).centerXTo( size.x + xGap ).tileX(2, xGap) + tile.leftTo( endTile.right + xGap ).bottomTo(0) ).tileZ(zCount,yGap) val middleColumns = ( midColumn.color("Green") + midColumn.mirrorZ().bottomTo(0).leftTo( leftColumn.right + size.x + xGap*2 ) ) .repeatX( xCount, (size.x + xGap)*3 ) val rightColumn = (endTile.rightTo(tile.right).bottomTo( endTile.top + yGap ) + tile) .tileZ(zCount,yGap) .bottomTo(0) .leftTo( middleColumns.right - size.x/2 + xGap /2 ) .color("Green") return leftColumn + middleColumns + rightColumn } }