Exit Full View
Up

/Garden/Layering.foocad

Layering

Layering is a technique which creates genetic clones of plants. Take a branch, and bend it over so that it touches the soil. Now secure it in place using a brick, or a tent peg. That's it! The plant may send out roots, and you can the branch from the parent plant. To speed up the process, you could slice the outer layer of bark where it will touch the ground. Note that the roots tend to begin just below a "left node" i.e. where a leaf produded from the branch.

This model lets you layer plants without having to bend the branch to the ground. Place the gromet (printed with TPU, or just use a piece of foam) around the prepared branch. Slide on the cylinder, and slide the "join". Fill with growing medium (soil, compost, moss, vermiculite). Add a little water and pop on the lid.

FooCAD Source Code
import static uk.co.nickthecoder.foocad.layout.v1.Layout2d.*
import static uk.co.nickthecoder.foocad.layout.v1.Layout3d.*

class Layering : Model {

    // The length of the cylinder    
    @Custom
    var length = 50

    // The diameter of the cylinder
    @Custom
    var diameter = 30

    // The thickness of the walls
    @Custom
    var thickness = 1.2

    // The width of the gap (must be bigger than the diameter of the branch)
    @Custom
    var gap = 12

    // The diameter of the hole in the gromet. Should be about the size of the branch.
    // If you use the piece name "gromets", it will produce a range of sizes, and ignore this value.
    @Custom
    var gromet = 5

    @Custom
    var slack = 0.3

    fun profile() = Circle( diameter/2 )//.sides(8).rotate(45/2)

    fun cylinder() : Shape3d {
        val profile : Shape2d = profile()
        val thin = profile - profile.offset(-thickness)
        val cylinder = thin.extrude(length)

        // The small holes ensure that water doesn't pool in the bottom.
        val hole = Circle( gap/2 )
        val holes = Circle( thickness ).translateY(diameter/2-thickness*3).repeatAround( 9 )
        val bottom = (profile - hole - holes).extrude(thickness)

        val slot = Cube( diameter, gap, length + 2 ).centerY().translateZ(-1)
        
        return (cylinder + bottom).color("Orange") - slot
    }

    @Piece
    fun join() : Shape3d {
        val profile : Shape2d = profile()
        val fat = (profile.offset(thickness+slack) - profile.offset(-thickness*2-slack)) /
            Square(diameter, gap).centerY().translateX(gap/2)
        
        val overlap = thickness*4
        val thin1 = (profile.offset(thickness+slack) - profile.offset(+slack)) /
            Square(diameter, gap+overlap).centerY().translateX(gap/2)
        val thin2 = (profile.offset(-thickness-slack) - profile.offset(-thickness*2-slack*2)) /
            Square(diameter, gap+overlap).centerY().translateX(gap/2)


        val hole = Circle( gap/2 )
        val slot = Square( diameter, gap ).centerY().mirrorX()
        val bottom = (profile.offset(-thickness-slack) - hole - slot).extrude(thickness)

        val foo = (fat + thin1 + thin2).extrude(length-thickness*4-slack*2)
        
        return (foo+bottom).color("yellow")
    }

    @Piece
    fun top() : Shape3d {
        val profile : Shape2d = profile()
        val hole = Circle( gap/2) + Square( diameter, gap ).centerY()

        val outerRing = (profile.offset(thickness+slack) - profile.offset(slack) - hole)
            .extrude(thickness*4)

        val innerRing = (profile.offset(-thickness-slack) - profile.offset(-thickness*2-slack) - hole)
            .extrude(thickness*4)

        val base1 = (profile.offset(thickness+slack) - profile.offset(-thickness-slack) - hole)
            .extrude(thickness).translateZ(thickness*3)

        val base2 = (profile.offset(-thickness-slack) - hole)
            .extrude(thickness)

        return (innerRing + outerRing+ base1 + base2).color("Green")
    }

    @Piece
    fun gromet( size : double ) : Shape3d {
        val envelope = Circle( diameter/2 - thickness*3 - slack )
        val profile = ( Square(diameter,gap-slack*2).centerY() / envelope ) +
            Circle( gap/2 - slack ) -
            Square( diameter,2).centerY() -
            Circle( size/2 )
        val bigger = ( Square(diameter,gap+thickness*2).centerY() / envelope ) +
            Circle( gap/2 +thickness ) -
            Square( diameter,2).centerY() -
            Circle( size/2 )

        return profile.extrude( 6 ) + bigger.extrude( 3 )                  
    }

    @Piece
    fun gromets() : Shape3d {
        val dy = gap + thickness*3
        return gromet(4) +
            gromet(5).translateY(dy) + 
            gromet(6).translateY(dy*2) +
            gromet(7).translateY(dy*3) +
            gromet(8).translateY(dy*4)
    }

    @Piece
    fun all() : Shape3d {

        return cylinder() +
            join().translateX(-diameter-thickness*2) +
            top().translateX(diameter+thickness*2)
    }
        
    override fun build() : Shape3d {
        return cylinder()+
            join().mirrorZ().bottomTo(thickness+slack) +
            top().topTo( length + thickness ) +
            gromet(gromet).topTo( thickness -slack )
    }
}