Exit Full View
ZipUp

/Phone/HiFi.foocad

HiFi

I have an old Samsung tablet and a Sony bluetooth speaker. Together they are my bedroom "hifi", and this is a stand which sits on my bedside table.

I don't normally design things so unnecessarily chunky. Use a low infill percentage. 10% or less ?

Cover the "inlay" regions with felt (to protect the tablet from scratches and give slightly more friction).

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

class HiFi : Model {

    @Custom( about="Size of the phone/table, which determines the overall size of the model" )
    var tabletSize = Vector2( 190, 110 )

    @Custom( about="Thickness of the base, shelf and back" )
    var thickness = 10

    @Custom( about="The sides are thinner than other parts" )
    var sideThickness = 5

    @Custom( about="Y distance of the shelf" )
    var shelfDepth = 65

    @Custom( about="Distance bwetween the base and the shelf" )
    var shelfHeight = 23

    @Custom( about="Height above the shelf" )
    var extraZ = 10

    @Custom( about="Helps align felt on the shelves and the feet on the base" )
    var inlayDepth = 1.0

    @Custom( about="Optional feet printed in TPU" )
    var footSize = Vector2( 20, 4 )

    @Custom( about="Radius of fillets" )
    var round = 10

    @Custom( about="Size of chamfers" )
    var chamfer = 1
    


    meth size() = tabletSize + Vector2( sideThickness * 2 + 5, thickness + sideThickness + 3 )

    meth tablet() = Square( tabletSize )
        .center().roundAllCorners(10)
        .extrude( 10 )

    meth speaker() = Square( 170, 70 )
        .center().roundAllCorners( 34 )
        .extrude( 57 )
        .rotateX(90).bottomTo(0).centerXY()

    meth indent( x : double, y : double ) = (
            Square( x, y ).centerX() +
            Square( x*2, y * 2 ).centerX().backTo(0)
        ).toPolygon().roundAllCorners(y / 2 - 0.01)

    meth baseShape() : Shape2d {
        val size = size()

        // A gap near the front to aid lifting up the tablet.
        val baseIndent = indent( size.x/2, round*2 )

        return (Square( size() ).centerX().roundCorners(listOf<int>(0,1), round) - baseIndent).center()
            .toPolygon()
    }

    meth inlayShape() = baseShape().offset( -sideThickness )

    @Piece
    meth inlayPattern() = (inlayShape() - Square(1000).centerX()).extrude(0.2)

    @Piece( print="print" )
    meth stand() : Shape3d {
        val size = size()

        val base = baseShape()
            .smartExtrude( thickness )        
                .edges( Chamfer( chamfer ) )

        val back = Square( size.x, thickness ).centerX().roundAllCorners(chamfer, 1)
            .smartExtrude( shelfHeight + thickness *2 + extraZ )
                .edges(Chamfer(chamfer))
            .backTo( base.back + chamfer )

        // Big enough to fit 4 fingers when moving the hifi to other parts of the house.
        val backGap = Square( size.x*0.5, 18 ).centerX().roundAllCorners(8.5)
            .smartExtrude( back.size.y + 0.02 )
                .edges( Chamfer(chamfer).reverse() )
            .rotateX(90)
            .topTo( thickness + shelfHeight )
            .backTo( back.back + 0.01 )
    
        val shelfShape = Square( size.x, shelfDepth + thickness ).centerX().backTo( back.back - chamfer )
            .roundCorners( listOf<int>(0,1), round )
        val shelf = shelfShape
            .smartExtrude( thickness )
                .edges( Chamfer( chamfer ) )
            .topTo( back.top - thickness )

        val sideDepth = Math.min( shelfDepth, size.y / 2 - 6 )
        val sides = Square( back.size.z )
                .roundCorner(0,back.size.z - thickness)
                .scaleY( sideDepth / back.size.z )
            .smartExtrude( sideThickness )
                .edges( Chamfer( chamfer ) )
            .rotateY(90)
            .bottomTo(0).backTo( back.back - chamfer ).leftTo( back.left )
            .mirrorX().also()

        // For a USB cable plugged into the back of the speaker.
        val backIndent = indent( size.x/4, extraZ )
            .extrude( thickness + 0.02 )
            .rotateX(-90)
            .bottomTo( shelf.top + 0.01 )
            .backTo( back.back + 0.01 )

        val baseInlay = if (inlayDepth > 0 ) {
            inlayShape()
                .smartExtrude(inlayDepth)
                    .bottom( Chamfer(inlayDepth/2,inlayDepth) )
                .topTo( base.top + 0.01 )
        } else {
            null
        }

        val shelfInlay = if ( inlayDepth > 0 ) {
            shelfShape.offset( -sideThickness )
                .smartExtrude( inlayDepth )
                    .bottom( Chamfer(inlayDepth/2,inlayDepth) )
                .topTo( shelf.top + 0.01 )
        } else {
            null
        }

        val feetIndents = if ( inlayDepth > 0 ) {
            positionFeet(
                Circle( footSize.x / 2 + 1 )
                .smartExtrude( inlayDepth )
                    .top( Chamfer(inlayDepth/2,inlayDepth) )
                .bottomTo( -0.01 )
                .color("Red")
            )
        } else {
            null
        }

        return base + shelf + sides - baseInlay - shelfInlay + back - backGap - backIndent - feetIndents
    }

    meth positionFeet( foot : Shape3d ) : Shape3d {
        return foot
            .translateX( size().x/2 - footSize.x /2 - 5 )
            .translateY( size().y/2 - footSize.x /2 - 5 )
            .mirrorX().also()
            .mirrorY().also()
    }

    @Piece
    meth print() = stand().rotateX(-90).bottomTo(0)

    @Piece
    meth foot() = Circle( footSize.x / 2 )
        .smartExtrude( footSize.y )
        .top( Chamfer( footSize.y * 0.7 ) )

    @Piece( print="print")
    override fun build() : Shape3d {
        val stand = stand()
        val tablet = tablet().previewOnly()
            .bottomTo( thickness )
            .backTo( stand.back - thickness - 2 )

        val speaker = speaker().previewOnly()
            .bottomTo( tablet.top + thickness * 2 )
            .backTo( stand.back - thickness - 2 )

        val feet = positionFeet( foot().mirrorZ().topTo( 0 ) )
            .color( "Black" )

        return tablet + speaker + stand + feet
    }

}