From 57a8a0595eb08a20e55e069fba88562fcc89d777 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 22 Dec 2023 02:30:27 +0000 Subject: [PATCH] build the actual case --- bits.scad | 11 ++-- case.scad | 148 ++++++++++++++++++++++++++++++++++-------------- defaults.scad | 5 ++ phone.scad | 47 +++++++-------- primitives.scad | 8 ++- 5 files changed, 142 insertions(+), 77 deletions(-) create mode 100644 defaults.scad diff --git a/bits.scad b/bits.scad index 57ee134..f436991 100644 --- a/bits.scad +++ b/bits.scad @@ -1,3 +1,4 @@ +include include use @@ -9,7 +10,7 @@ module Volume_(Depth, Box=false) pillX(Depth, VolumeLength, VolumeHeight, center=false); } } -module Volume(Depth, Box=false) +module Volume(Depth=2, Box=false) { translate([BodyWidth, VolumeMinY, VolumeMinZ]) Volume_(Depth, Box=Box); } @@ -22,7 +23,7 @@ module Power_(Depth, Box=false) pillX(Depth, PowerLength, PowerHeight, center=false); } } -module Power(Depth, Box=false) +module Power(Depth=2, Box=false) { translate([BodyWidth, PowerMinY, PowerMinZ]) Power_(Depth, Box=Box); } @@ -35,7 +36,7 @@ module Camera_(Depth, Box=false) pillZ(CameraWidth, CameraLength, Depth, center=false); } } -module Camera(Depth, Box=false) +module Camera(Depth=2, Box=false) { translate([CameraMinX, CameraMinY, BodyHeight]) Camera_(Depth, Box=Box); } @@ -48,7 +49,7 @@ module Usb_(Depth, Box=false) pillY(UsbWidth, Depth, UsbHeight, center=false); } } -module Usb(Depth, Box=false) +module Usb(Depth=2, Box=false) { translate([BodyWidth/2 - UsbWidth/2, BodyLength-Depth, UsbMinZ]) Usb_(Depth, Box=Box); } @@ -57,7 +58,7 @@ module Aux_(Depth) { cylinderY(d=3.5, h=Depth, center=false); } -module Aux(Depth) +module Aux(Depth=10) { translate([AuxMinX, 0, AuxMinZ]) Aux_(Depth); } diff --git a/case.scad b/case.scad index d038710..4a1e5c3 100644 --- a/case.scad +++ b/case.scad @@ -1,54 +1,116 @@ +include include +use use +use -$fs = 1; +// thickness of case walls +Thickness = 2; +// how large of cuts (radial) to make around each component +MarginCamera = 2; +MarginButtons = 2.5; +MarginPorts = 5.5; +// how far into the xy plane to extend the part of the case which covers the front of the phone. +// the top of the phone contains stuff we don't want to cover (camera); the bottom has more margin +FrontOverhangX = 3; +FrontOverhangTop = 3; +FrontOverhangBot = 6; -module plate(Margin, Thick=Height) +// gives a 1cm margin around the whole body of the phone, but only in the xy plane. +module _PhoneBulkLayer(tol=tol) { - translate([0,0,2]) hull() { - translate([(Length-Height-Margin)/2,(Width-Height-Margin)/2,0]) cylinder(d=Height, h=Thick); - translate([-(Length-Height-Margin)/2,(Width-Height-Margin)/2,0]) cylinder(d=Height, h=Thick); - translate([(Length-Height-Margin)/2,-(Width-Height-Margin)/2,0]) cylinder(d=Height, h=Thick); - translate([-(Length-Height-Margin)/2,-(Width-Height-Margin)/2,0]) cylinder(d=Height, h=Thick); - } + minkowski() { + PhoneBody(); + cube([20, 20, tol], center=true); + } } -difference() { - union() { - difference() { - phone(4); - plate(2); - } - translate([0,0,Height/2-4]) { - minkowski() { - difference() { - plate(3,1); - translate([0,0,-1])plate(3.1,4); - } - sphere(2); - } - } - } - phone(Bits=1); - //translate([0,-50,-50])cube([100,100,100]); +module _FrontFace(tol=tol) { + color("thistle") + difference() { + translate([0, 0, -Thickness]) PhoneBody(); + _PhoneBulkLayer(tol=tol); + }; } -/* -translate([0,0,Height/2-4]) { - minkowski() { - difference() { - plate(3,1); - translate([0,0,-1])plate(3.1,4); - } - sphere(2); - } +/// we want to cutout a portion of the case to expose the touchscreen. +/// but we don't want to cut out the entire front face. +/// so, produce a "mask", of just that front-facing portion of the case we want to preserve: +/// returns a mask which is -Thickness <= z <= 0, within tolerance +module _FrontKeep(tol=tol) { + minkowski() { + // take the outline of the front face of the phone + difference() { + minkowski() { + cylinder(r=2*tol, h=tol, center=true); + _FrontFace(); + }; + minkowski() { + cylinder(r=tol, h=2*tol, center=true); + _FrontFace(); + }; + }; + // and expand it + // cylinder(r=FrontOverhangX, h=tol, center=false); + // translate([0, -0.5*(FrontOverhangBot - FrontOverhangTop), -Thickness]) + pillZ(2*FrontOverhangX, FrontOverhangBot + FrontOverhangTop, tol, center=true); + }; } - minkowski() { - difference() { - cube([Length+0.2, Width+0.2, 0.2], true); - cube([Length, Width, 4], true); - } - sphere(d=3); - } -*/ +/// returns the region which we want to subtract from the case, in order to keep the front screen accessible. +/// the returned cutout is strictly z <= 0, +module _FrontCutout() { + difference() { + _FrontFace(); + _FrontKeep(); + }; +} + +module Case() +{ + color("DarkSlateGray") + difference() { + minkowski() { + sphere(d=Thickness); + // Phone(volume=false, power=false, camera=false); + PhoneBody(); + } + union() { + minkowski() { + sphere(r=MarginCamera); + Camera(); + }; + // restrict these cutouts to just the phone bulk -- don't let them impact the back of the case + intersection() { + _PhoneBulkLayer(); + union() { + minkowski() { + sphere(r=MarginButtons); + union() { + Volume(); + Power(); + }; + } + minkowski() { + sphere(r=MarginPorts); + union() { + Usb(); + Aux(); + }; + }; + }; + }; + Phone(usb=false, aux=false); + translate([0, 0, tol]) _FrontCutout(); + // _FrontCutout(); + } + } +} + +Case(); + +// debugging: +// _FrontFace(); +// _FrontKeep(); +// _FrontCutout(); +// Phone(); diff --git a/defaults.scad b/defaults.scad new file mode 100644 index 0000000..486dd5f --- /dev/null +++ b/defaults.scad @@ -0,0 +1,5 @@ +$fs = 1; + +// tolerance. lining up the extrusions and cuts with zero tolerance causes very thin walls, +// so i offset those to make the model actually contiguous. +tol = 0.01; diff --git a/phone.scad b/phone.scad index b97742b..56dba25 100644 --- a/phone.scad +++ b/phone.scad @@ -1,53 +1,48 @@ +include include use use -$fs = 1; - -// tolerance. lining up the extrusions and cuts with zero tolerance causes very thin walls, -// so i offset those to make the model actually contiguous. -Tol = 0.1; - -// simple box-shaped body; preserve for easier debugging -module BodyBox() { - cube([BodyWidth, BodyLength, BodyHeight], center=false); -} // return the kernel which can be convolved with the box body to produce the actual body -module BodyConvolve(Tol=Tol) { +module _BodyConvolve(tol=tol) { minkowski() { // cylinder rounds the four corners of the phone - cylinder(r=BodyRadXY-BodyRadFrontZ, h=Tol, center=true); + cylinder(r=BodyRadXY-BodyRadFrontZ, h=tol, center=true); // sphere rounds the thickness of the phone // in actuality this shouldn't be symmetric (the screen and back cover have different radii), // but using a single radius is Good Enough sphere(r=BodyRadFrontZ); - // cylinderY(r=BodyRadFrontZ, h=Tol, center=true); - // cylinderX(r=BodyRadFrontZ, h=Tol, center=true); + // cylinderY(r=BodyRadFrontZ, h=tol, center=true); + // cylinderX(r=BodyRadFrontZ, h=tol, center=true); } } -module Body() +module PhoneBody(Box=false) { - translate([BodyRadXY, BodyRadXY, BodyRadFrontZ]) - minkowski() { - cube([BodyWidth-2*BodyRadXY, BodyLength-2*BodyRadXY, BodyHeight-2*BodyRadFrontZ], center=false); - BodyConvolve(); + if (Box) { + cube([BodyWidth, BodyLength, BodyHeight], center=false); + } else { + translate([BodyRadXY, BodyRadXY, BodyRadFrontZ]) + minkowski() { + cube([BodyWidth-2*BodyRadXY, BodyLength-2*BodyRadXY, BodyHeight-2*BodyRadFrontZ], center=false); + _BodyConvolve(); + } } } -module Phone(Box=false) +module Phone(Box=false, volume=true, power=true, camera=true, usb=true, aux=true) { difference() { union() { - if (Box) { BodyBox(); } else { Body(); } - Volume(2, Box=Box); - Power(2, Box=Box); - Camera(2, Box=Box); + PhoneBody(Box=Box); + if (volume) { Volume(Box=Box); } + if (power) { Power(Box=Box); } + if (camera) { Camera(Box=Box); } } union() { - translate([0, Tol, 0])Usb(2, Box=Box); - translate([0, -Tol, 0])Aux(2); + if (usb) { translate([0, tol, 0]) Usb(Box=Box); } + if (aux) { translate([0, -tol, 0]) Aux(); } } } } diff --git a/primitives.scad b/primitives.scad index bafd9d3..bb71c61 100644 --- a/primitives.scad +++ b/primitives.scad @@ -1,5 +1,7 @@ //! general-purpose "primitives" lacking from the OpenSCAD builtins +include + /// cylinder() but with the axis on the x axis instead of the z axis. /// and where `center=false` behaves like for `cube(center=false)`, /// i.e. circle center is not at (0, 0) but (r, r) @@ -27,7 +29,7 @@ module cylinderZ(d=undef, r=undef, h=undef, center=false) { } // a 2d-cylinder extruded along the x-axis -module pillX(dimX, dimY, dimZ, tol=0.01, center=false) { +module pillX(dimX, dimY, dimZ, tol=tol, center=false) { diam = min(dimY, dimZ) - tol; minkowski() { cube([dimX/2, dimY-diam, dimZ-diam], center=center); @@ -36,7 +38,7 @@ module pillX(dimX, dimY, dimZ, tol=0.01, center=false) { } // a 2d-cylinder extruded along the x-axis -module pillY(dimX, dimY, dimZ, tol=0.01, center=false) { +module pillY(dimX, dimY, dimZ, tol=tol, center=false) { diam = min(dimX, dimZ) - tol; minkowski() { cube([dimX-diam, dimY/2, dimZ-diam], center=center); @@ -45,7 +47,7 @@ module pillY(dimX, dimY, dimZ, tol=0.01, center=false) { } // a 2d-cylinder extruded along the z-axis -module pillZ(dimX, dimY, dimZ, tol=0.01, center=false) { +module pillZ(dimX, dimY, dimZ, tol=tol, center=false) { diam = min(dimX, dimY) - tol; minkowski() { cube([dimX-diam, dimY-diam, dimZ/2], center=center);