Exit Full View
Up

/Halloween/HeartGlass.foocad

HeartGlass
FooCAD Source Code
import static uk.co.nickthecoder.foocad.arrange.v1.Arrange.*
/**
    Drill a pair of holes in the top, and fill with blood red (tomato) juice.

    Comprises of three pieces, a hollow heart, a stand and a tiny funnel.
*/
class HeartGlass : Model {
    
    var size = 20
    var thickness = 1.2

    @Custom
    var name = "Nick"

    @Custom
    var name2 = "2020"
    
    fun half( thickness : double ) : Shape3d {
        return Hull3d(
            Sphere(size/3-thickness).translateZ(10),
            Sphere(size-thickness).scaleY(0.8).translate( size * 2/3, 0, size * 2 ),
            Sphere(size-thickness).scaleY(0.85).translate( 0,0,size * 1.7 )
        ).color( "Red" )
    }

    fun outside() = half( 0 ).mirrorX().also()
    fun inside() = half( thickness ).mirrorX().also() 

    @Piece 
    fun heart() = outside() - inside()

    @Piece
    fun stand() : Shape3d {
        return Square( size*2,size * 4 / 3 )
            .center()
            .roundAllCorners( 5 )
            .extrude( size * 4/3 ) -
        half( -0.3 )
            .mirrorX().also()
            .translateZ(2) -
        Cylinder( 10, 11 ).center() - 
        Cylinder( 40, 3 ).center().rotateY(-10).translateX(13).mirrorX().also() -
        Text( name,9 ).centerX().extrude( 2 ).rotateX(90).translate( 0,-12,3 ) -
        Text( name2,9 ).centerX().extrude( 2 ).rotateX(90).translate( 0,-12,3 ).rotateZ(180)
    }

    @Piece
    fun funnel() : Shape3d {
        val outside = Cylinder( 20, 10, 0 ) +
            Cylinder( 20, 3 ).sides( 10 )

        val inside = Cylinder( 20, 10, 0 ).translateZ(-2) +
            Cylinder( 50, 2.3 ).sides( 10 )

        return outside - inside
    }

    override fun build() : Shape3d {
        return arrangeX( 10,
            heart(),
            stand(),
            funnel()
        )
    }
}