class CountersinkBitHolder : Model { @Custom var length = 30 @Custom var thickness = 1.8 @Custom var baseThickness = 0.6 @Custom var gap = 3 @Custom var maxDiameter = 21 @Custom( lines = 4 ) var bits = """5 6.3 6 8.3 6 10.4 8 12.4 10 18.5 10 20.5""" meth bits() : List { val result = listOf() val lines = bits.split("\n") for ( line in lines ) { if (line.trim() == "") continue try { val parts = line.trim().split(" ") val diameter = parts[0].parseDouble() val text = if (parts.size() > 1) { parts[1] } else { "$diameter" } result.add( BitInfo( diameter, text ) ) } catch (e : Exception) { println( "Skipping bit info : '$line'" ) } } return result } meth clip( diameter : double ) : Shape3d { val rect = Square( diameter + 2, maxDiameter/2 + baseThickness + diameter*0.2 ).centerX() val shape = rect - Circle( diameter/2 ).centerYTo( rect.back - diameter*0.2 ) val one = shape.extrude(thickness) .rotateX(90).bottomTo(0) val both = one.translateY(length-thickness).also().centerXY() val wall = Cube( thickness, both.size.y, both.size.z ).centerY() .rightTo( both.left ) .leftTo( both.right ).also() return both + wall } meth press( diameter : double ) : Shape3d { val rect = Square( diameter + 2, maxDiameter/2 + baseThickness - diameter*0.2 - 1 ).centerX() val shape = rect - Circle( diameter/2 ).centerYTo( rect.back + diameter*0.2 + 1 ) val one = shape.extrude(thickness) .rotateX(90).bottomTo(0) val both = one.translateY(length-thickness).also().centerXY() val wall = Cube( thickness, both.size.y, both.size.z ).centerY() .rightTo( both.left ) .leftTo( both.right ).also() return both + wall } @Piece meth clip() = row( true ) @Piece meth press() = row( false ) meth row( clip : bool ) : Shape3d { var row : Shape3d = Cube(0).rightTo(-gap) for (bit in bits()) { val one = if (clip) { clip( bit.diameter ) } else { press( bit.diameter ) }.leftTo( row.right + gap ) val txt = Text( bit.text, 8 ).rotate(90).extrude(0.4) .color("Green") .bottomTo( baseThickness ) .centerXTo( one.middle.x ) .centerYTo( one.middle.y ) row = row + one + txt } val base = Square( row.size.x - gap, row.size.y ).centerY() .extrude( 0.8 ) return base + row } override meth build() : Shape3d { val clip = clip().color("LightGreen") val press = press().rotateX(180).topTo( maxDiameter + baseThickness*2 ) return clip + press } } class BitInfo( val diameter : double, val text : String ) { }