import static uk.co.nickthecoder.foocad.chamferedextrude.v1.ChamferedExtrude.* import static uk.co.nickthecoder.foocad.changefilament.v1.ChangeFilament.* import static uk.co.nickthecoder.foocad.layout.Layout2d.* import static uk.co.nickthecoder.foocad.layout.Layout3d.* class PlantLabel2 : Model { //@Custom(about="Length, width and thickness os the main part (does not include the text)") var size = Vector3( 80, 12.6, 1.2 ) //@Custom( about="1 or 2 layers is normal" ) var textThickness = 0.6 //@Custom(about="Should be about doub-le the wire's diameter") var holeD = 5.0 //@Custom(about="Length and width of the slot. Y should be just less than the wire's diameter") var slotSize = Vector2( 10, 2 ) //@Custom var style = TextStyle("Liberation Sans:style=Bold", 8) //@Custom(about="Should we add automatic printer pauses to change filament?") var changeColor = true @Custom( about="Text to appear on the labels (separated by new lines)", lines=10 ) var names = """Lettuce Mustard Rocket Spinach Swiss Chard Basil Chamomile Coriander Fennel Parsley Thyme""" @Custom var columns = 2 @Custom( about="Add extra to labels to help bed adhesion" ) var ears = true //@Custom var slotMargin = 2.0 //@Custom(about="The slack. The Y value is slack in the z direction!") var slack = Vector2( 1.0, 0.5 ) var stakeExtra = 40 var tStakeExtra = 40 @Piece fun label() = label("") @Piece fun labels() : Shape3d { var y = 0 var x = 0 var column = 1 var union : Shape3d = Union3d() for ( name in names.split("\n") ) { val label : Shape3d = label( name ).frontTo( y ).leftTo(x) if (column < columns) { x = label.right + 3 column ++ } else { x = 0 column = 1 y = label.back + 3 } union = union + label } return union } fun labels( gcode: GCode ) { if ( changeColor && names != "" ) { pauseAtHeight( gcode, size.z, "Change Filament" ) } } fun hole() : Shape2d { return (Circle( holeD/2 ).sides(4).translateX(slotSize.x/2) hull Square(slotSize.x/2, slotSize.y).centerY()) .mirrorX().also().rightTo(size.x+holeD/2) } fun label( name : String ) : Shape3d { val outline = labelOutline() val hole : Shape2d = hole() val main = (outline-hole).extrude(size.z) val result = if (name == "" ) { main } else { val text = Text( name, style ) .centerXTo(main.middle.x) .centerY() .extrude( size.z + textThickness ) .color( "Black" ) if (text.right > hole.left) { main + text.rightTo( hole.left ) } else { main + text } } return if (ears) { val ears = Circle( size.y*0.8 ).roundAllCorners(3).extrude( 0.3 ) .rightTo(3).centerYTo(result.middle.y) .mirrorX().leftTo(result.right-3).also(2) .margin( -size.y*0.8-1.5, -size.y, 0 ) .color("Green") result + ears } else { result } } fun labelOutline() = Square( size.x, size.y ).roundAllCorners(size.y/3).centerY() @Piece fun slotSide() : Shape3d { val outline = labelOutline().offset(slack.x) val window = outline.offset(-slotMargin/2) val outside = outline.offset(slotMargin) val inside = outline.extrude( size.z + textThickness + slack.y + 1).bottomTo( size.z ) return (outside-window).extrude(size.z * 2 + textThickness + slack.y ) - (inside.translateX(-10).also()) } @Piece fun slotTop() : Shape3d { val outline = labelOutline().offset(slack.x) val window = outline.offset(-slotMargin/2) val outside = outline.offset(slotMargin) val inside = outline.extrude( size.z + textThickness + slack.y + 1).bottomTo( size.z ) .translate(-10, -6, 0).also() return (outside-window).extrude(size.z * 2 + textThickness + slack.y ) - inside } @Piece fun stake() : Shape3d { val slot = slotSide() val width = slot.size.y val length = slot.size.x + stakeExtra val outline = PolygonBuilder().apply { radius(width/3) moveTo(0,0) lineTo(0,width) lineTo(length,width) radius(1) lineTo(length + width*1.5, width/2) radius(5) lineTo(length,0) }.build().centerY() return outline.extrude(size.z) } @Piece fun tStake() : Shape3d { val slot = slotSide() val width = slot.size.y val length = tStakeExtra val vertical = PolygonBuilder().apply { radius(width/3) moveTo(0,0) lineTo(0,width) lineTo(length,width) radius(1) lineTo(length + width*1.5, width/2) radius(5) lineTo(length,0) }.build().rotate(-90).centerX() val outline = labelOutline().offset(slack.x + slotMargin).centerX() + vertical return outline.extrude(size.z) } @Piece fun nStake() : Shape3d { val slot = slotSide() val width = slot.size.y * 2/3 val length = tStakeExtra val vertical = PolygonBuilder().apply { radius(width/3) moveTo(0,0) lineTo(0,width) lineTo(length,width) radius(1) lineTo(length + width*1.5, width/2) radius(5) lineTo(length,0) }.build().rotate(-90).translateX(size.x * 0.6).also().centerX() val outline = labelOutline().offset(slack.x + slotMargin).centerX() + vertical return outline.extrude(size.z) } /* To cover up the rough end of a piece of wire that the labels are threaded onto. */ @Piece fun endStop() : Shape3d { val solid = Square( 10, 5 ).roundCorner(2,1).roundCorner(1,1) .chamferedExtrude( 5, 1 ) .center() val hole = Cylinder.hole(10,2.4/2).rotateY(90).center() .rightTo(0) return (solid - hole).bottomTo(0) } override fun build() : Shape3d { return label("Example").centerX() + slotSide().color("Orange").mirrorZ().leftTo(0).bottomTo(0) + stake().topTo(0).color("Blue") + slotSide().color("LightGreen").mirrorZ().bottomTo(0).centerX().backTo(-20) + tStake().topTo(0).color("Green").backTo(-20) } }