import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.* import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.* /** */ class Freeplunk : Model { var inner = 80 var steps = 5 var stepHeight = 4 var margin = 5 var holesGap = 10 var holeRows = 6 var holesPerRow = 10 var holeWidth = 6 var holeHeight = 4 var wallT = 2.0 var chamfer = 1.0 override fun build() : Shape3d { var baseHeight = margin * 2 + holeRows * holesGap var outer = inner + steps * stepHeight * 2 val solid = ExtrusionBuilder().apply { crossSection( Circle( inner /2 + wallT - chamfer ).sides(40) ) forward( chamfer ) crossSection( chamfer ) forward( baseHeight - chamfer ) crossSection() forward( steps * stepHeight ) crossSection( outer/2 - inner/2 ) forward( stepHeight-chamfer*2 ) crossSection() forward( chamfer ) crossSection( -chamfer ) crossSection( -stepHeight + chamfer*2 ) forward( -chamfer ) crossSection( -chamfer ) forward( -stepHeight ) for ( i in steps-1 downTo 0 ) { val size = inner + (outer - inner)/steps * i crossSection() crossSection( -stepHeight ) forward( -stepHeight ) } crossSection() val foo = stepHeight - wallT forward( -foo) crossSection( foo ) forward( -baseHeight + stepHeight ) crossSection() }.build() val row = Square( holeWidth, holeHeight ).extrude( outer ).center() .rotateX(90) .repeatAroundZ(holesPerRow, 180/holesPerRow) val twoRows = row + row.rotateZ( 90/holesPerRow ).translateZ( holesGap ) val rows = twoRows.repeatZ( holeRows / 2, holesGap*2 ) val inside = Cylinder( 10, inner / 2 ).translateZ(-1) val result = solid - inside - rows.translateZ( baseHeight-margin - rows.size.z ) return result // Cube( 300, 1, 500 ).center() } }