Exit Full View
ZipUp

/Hardware/CableHoleCover.foocad

CableHoleCover

Cable management for tables/desks.

Drill/cut a hole in the tabletop, and glue in an "insert". Feed the cables though the hole, and then snap on the "cover".

I recomment PETG (or other semi-flexible filamenet) for the cover. PLA will probably break, as it is too stiff.

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

class CableHoleCover : Model {

    @Custom
    var holeDiameter = 50.0

    @Custom
    var tableThickness = 18

    @Custom
    var wallThickness = 1.8

    @Custom
    var baseThickness = 1.8

    @Custom
    var lipWidth = 5

    @Custom
    var cableHoleDiameter = 10

    @Custom( about="1,2 or 4. Other values will interfere with the clips" )
    var cableHoleCount = 1

    @Custom( about="Width and height of the clip. Thickness is calculated from the height." )
    var clipSize = Vector2( 6, 4 )

    @Custom
    var clearance = 0.3

    @Piece
    meth insert() : Shape3d {
        val hole = Circle( holeDiameter/2 - clearance )
        val large = hole.offset( lipWidth )
        val base = (large - hole.offset(-wallThickness) )
            .smartExtrude(baseThickness )
                .insideBottom( Chamfer(0.5) )
                .outsideBottom( Chamfer(0.5) )

        val ring = hole - hole.offset(-wallThickness)
        //val gaps = Square( holeDiameter/2, 4 ).centerY().repeatAround(8)
        val ribs = (ring).extrude( tableThickness + 1 )
            .bottomTo( base.top )        

        val clipHole = Cube( holeDiameter, clipSize.x+2, tableThickness ).centerY()
            .bottomTo( ribs.top - clipSize.y-baseThickness -1 )
            .rotateZ(45)
            .repeatAroundZ( 4 )
    
        return base + ribs - clipHole
    }

    @Piece
    meth cover() : Shape3d {
        val hole = Circle( holeDiameter/2 - clearance )
        val large = hole.offset( lipWidth )

        val gap = Circle( cableHoleDiameter/2 ).translateX( large.right )
            .hull( Circle( cableHoleDiameter/2 ).rightTo( hole.right - wallThickness ) )
        val gaps = gap.repeatAround( cableHoleCount )
        val base = (large - gaps)
            .smartExtrude(baseThickness)
                .bottom( Chamfer(0.5) )

        val ringOuter = hole.offset(-wallThickness-clearance)
        val ring = ( ringOuter - ringOuter.offset(-wallThickness-clearance) - gaps )
            .extrude(tableThickness + baseThickness ) 
            .bottomTo( base.top )

        val clip = (ringOuter.offset(clipSize.y/2) - ringOuter.offset(-1))
            .smartExtrude( clipSize.y )
                .outside( Chamfer( clipSize.y/2-clearance ) )
            .topTo( ring.top - 1 )
            .intersection( Cube( holeDiameter, clipSize.x, ring.top ).centerY() )
            .rotateZ(45)
            .repeatAroundZ(4)
        val clipGap = Cube( holeDiameter, 1, ring.top )
            .frontTo( clipSize.x/2 )
            .bottomTo( base.top + 1 )
            .mirrorY().also()
            .rotateZ(45)
            .repeatAroundZ( 4 )

        return base + ring + clip - clipGap
    }

    override fun build() : Shape3d {
        val insert = insert().mirrorZ().topTo( baseThickness )
        val cover = cover().mirrorZ().color("Green").topTo( baseThickness*2 )

        return insert + cover
    }

}