import uk.co.nickthecoder.foocad.smartextrusion.v1.* import static uk.co.nickthecoder.foocad.smartextrusion.v1.SmartExtrusion.* import static uk.co.nickthecoder.foocad.circular.v1.Circular.* class BottleTop : AbstractModel() { @Custom var capHeight = 15 @Custom var capRadius = 36/2 @Custom var extraHeight = 4 @Custom var thickness = 2 @Custom var chamfer = 1.5 @Custom var text = "SLOE GIN" @Custom var fontSize = 12 fun internal() : Shape2d { return Circle(capRadius) } fun exterior() : Shape2d { return Circle(capRadius + thickness) } fun around( str : String ) :Shape3d { val text = Text( str, BOLD, fontSize).center() val extrudedText = text.offset(0.5).smartExtrude(1).bottom( Chamfer(1) ) val result = extrudedText .mirrorX() .rotateX(90) .aroundCylinder( capRadius + thickness + 1 ).color("Red") .rotateX(-90) return result.rotateX(90) } override fun build() : Shape3d { val cap = ExtrusionBuilder().apply { forward(capHeight) crossSection(internal()) // Inside forward(-capHeight) crossSection() // Bottom inside crossSection(exterior().offset(-chamfer)) // Bottom outside pre chamfer forward(chamfer) crossSection(exterior()) // Bottom outside post chamfer forward(capHeight+extraHeight-chamfer) crossSection() // Top pre-chamfer forward(chamfer) crossSection(exterior().offset(-chamfer)) // Top post chamfer }.build() val text2d = around(text).translateZ((capHeight+extraHeight)/2+1) // Flip it upside down, so that the top of the cap is on the print bed. return (cap + text2d).rotateX(180).toOriginZ() } }