import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* class SeedModuleGrid2 : Model { @Custom( about="Width of the holes (slightly bigger than the pot width, excluding the rim" ) var width = 67.0 // Was 65 @Custom( about="Gap bewteen the holes" ) var gap = Vector2(5.0, 9.0) // was 4 @Custom( about= "Radius of the pots" ) var cornerRadius = 8 @Custom( about="Quantity of pots in the X direction" ) var gridAcross = 3 @Custom( about="Quantity of pots in the Y direction" ) var gridDown = 2 @Custom( about="External size of the tray" ) var traySize = Vector2( 221, 164) @Custom( about="Radius of the tray's corners") var trayRadius = 18 @Custom( about="Used for an 'exclusion' area where no ribs can be created. Often not needed!" ) var trayLip = 5.0 @Custom( about="Thickness of the top sheet" ) var sheetThickness = 0.9 @Custom( about="Thickness of the ribbing, which gives the grid strength" ) var gridThickness = 1.2 @Custom( about="Height of the ribbing, which gives the grid strength" ) var gridHeight = 6.0 @Custom( about="Print in two halves, and then glue them together" ) var cutAt = 3 @Custom( about="The size of the outer rim. Use a large Y value, to hold pots steady, without a tray" ) var outerSize = Vector2( 1.2, 0 ) fun build( cutAt : int ) : Shape3d { val hole = Square( width ).roundAllCorners( cornerRadius ).center() val holes = hole .tileX( gridAcross, gap.x ) .tileY( gridDown, gap.y ) .center() val sheet = Square( traySize + Vector2( gridThickness, gridThickness ) * 2 ) .roundAllCorners( trayRadius + gridThickness ) .center() val top = (sheet - holes).extrude( sheetThickness ) val edge = (sheet - sheet.offset(-outerSize.x)) val outer = if (outerSize.y > gridHeight ) { val expand = -outerSize.y * 0.15 // Determines the angle. Was 0.172 val outerEdge = ExtrusionBuilder().apply { crossSection( sheet ) forward( outerSize.y ) crossSection(expand) crossSection( -outerSize.x * 3 ) forward( -outerSize.x ) crossSection() forward( -outerSize.x * 3 ) crossSection( outerSize.x * 2) forward( -outerSize.y + outerSize.x * 4 ) crossSection(-expand) }.buildClosed() val handles = Cube( 70, outerEdge.size.y + 2, outerSize.y * 0.7 ).centerXY().centerZTo( outerSize.y / 2 ) + Cube( outerEdge.size.x + 2, 70, outerSize.y * 0.7 ).centerXY().centerZTo( outerSize.y / 2 ) outerEdge - handles } else { Cube(0) } val exclusion : Shape2d = ( Square( traySize ).roundAllCorners(trayRadius).center() - Square( traySize - Vector2( trayLip, trayLip ) * 2 ).roundAllCorners(trayRadius-trayLip).center() ) val rings = (hole.offset(gridThickness) - hole) .repeatX( gridAcross, hole.size.x + gap.x ) .repeatY( gridDown, hole.size.y + gap.y ) .center() val across = Square( gap.x, gridThickness ) .backTo( hole.back - cornerRadius ) .leftTo( hole.right ) .mirrorY().also() .repeatX( gridAcross-1, hole.size.x + gap.x ) .repeatY( gridDown, hole.size.y + gap.y ) .center() val down = Square( gridThickness, gap.y ) .rightTo( hole.right - cornerRadius ) .frontTo( hole.back ) .mirrorX().also() .repeatX( gridAcross, hole.size.x + gap.x ) .repeatY( gridDown-1, hole.size.y + gap.y ) .center() val tray = exclusion.extrude( 2 ).bottomTo( sheetThickness ).previewOnly() val solid = (edge + rings + across + down - exclusion ).extrude( gridHeight ) .bottomTo(0.01) .color("Orange") if (cutAt > 0) { val overlap = Cube( top.size.x, top.size.y + 2, solid.size.z + 2 ) .centerY().bottomTo(-1).rightTo( (cutAt - gridAcross/2) * (width + gap.x) ) val cut = (top + solid) / overlap val extra = Cube( gridThickness*2, holes.size.y + gridThickness, gridHeight*2 ) .centerY().rightTo(overlap.right ) .color("Red") return cut + extra } return top + solid + tray + outer } @Piece fun cutA() = build( cutAt ) @Piece fun cutB() = build( gridAcross - cutAt ) override fun build() = build( 0 ) }