Reorganize around function/purpose rather than file type.
This commit is contained in:
BIN
functional/FilamentClipC_175.stl
Normal file
BIN
functional/FilamentClipC_175.stl
Normal file
Binary file not shown.
54
functional/HFF_standalone_H_RGB.svg
Normal file
54
functional/HFF_standalone_H_RGB.svg
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="179.61107"
|
||||
height="182.11235"
|
||||
viewBox="0 0 47.522094 48.183894"
|
||||
version="1.1"
|
||||
id="svg885"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
||||
sodipodi:docname="HFF_standalone_H_RGB.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<sodipodi:namedview
|
||||
id="namedview887"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:document-units="mm"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
fit-margin-top="20"
|
||||
fit-margin-left="20"
|
||||
fit-margin-right="20"
|
||||
fit-margin-bottom="20"
|
||||
inkscape:zoom="4"
|
||||
inkscape:cx="117.25"
|
||||
inkscape:cy="64.500001"
|
||||
inkscape:window-width="3440"
|
||||
inkscape:window-height="1410"
|
||||
inkscape:window-x="2560"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<defs
|
||||
id="defs882" />
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-5.2916665,-5.2916667)">
|
||||
<path
|
||||
id="path8331"
|
||||
style="fill:#f7ca1f;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.0330729"
|
||||
d="m 35.795231,10.587984 c -0.391558,0.01859 -0.787358,0.0956 -1.175122,0.236678 l -20.753255,7.553544 c -1.247426,0.454104 -2.125988,1.467608 -2.464966,2.653068 l -5.17e-4,5.17e-4 c -0.793281,1.043029 -1.058632,2.453324 -0.577226,3.775997 l 7.553544,20.753255 c 0.752143,2.0681 3.038984,3.13418 5.106666,2.38177 l 20.753771,-7.55406 c 1.247178,-0.45372 2.126301,-1.467 2.464966,-2.65256 0.793536,-1.04297 1.059191,-2.45394 0.577743,-3.77703 L 39.726774,13.205912 C 39.11555,11.525894 37.49198,10.507437 35.795231,10.587984 Z m -1.700671,5.050855 c 0.120081,0.0061 0.230796,0.08227 0.274401,0.202571 l 7.113261,19.543513 c 0.05814,0.1598 -0.02468,0.33671 -0.184485,0.39481 l -4.297412,1.56424 c -0.159807,0.0584 -0.336554,-0.0245 -0.395324,-0.18448 l -2.962093,-8.140076 -7.331336,2.668055 2.96261,8.140591 c 0.05877,0.16044 -0.02403,0.33722 -0.183968,0.39532 l -4.296896,1.56373 c -0.160171,0.0581 -0.33707,-0.0239 -0.395841,-0.18448 L 17.284733,22.059635 c -0.05814,-0.160435 0.02416,-0.337214 0.183968,-0.395324 l 4.297412,-1.564246 c 0.159941,-0.05814 0.336951,0.02417 0.395325,0.185002 l 2.624129,7.208862 7.330819,-2.668571 -2.624129,-7.208862 c -0.05837,-0.160602 0.02403,-0.337185 0.183968,-0.395325 l 4.297412,-1.564246 c 0.04004,-0.01455 0.08089,-0.02013 0.120923,-0.01809 z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
BIN
functional/UniversalDualFilamentDragonClip.stl
Normal file
BIN
functional/UniversalDualFilamentDragonClip.stl
Normal file
Binary file not shown.
BIN
functional/clean-dirty-slider/Knob.STL
Normal file
BIN
functional/clean-dirty-slider/Knob.STL
Normal file
Binary file not shown.
BIN
functional/clean-dirty-slider/Letter_Plate.STL
Normal file
BIN
functional/clean-dirty-slider/Letter_Plate.STL
Normal file
Binary file not shown.
BIN
functional/clean-dirty-slider/Letters_For_Multi_Material.STL
Normal file
BIN
functional/clean-dirty-slider/Letters_For_Multi_Material.STL
Normal file
Binary file not shown.
BIN
functional/clean-dirty-slider/Retainer.STL
Normal file
BIN
functional/clean-dirty-slider/Retainer.STL
Normal file
Binary file not shown.
BIN
functional/clean-dirty-slider/Suction_Bracket.STL
Normal file
BIN
functional/clean-dirty-slider/Suction_Bracket.STL
Normal file
Binary file not shown.
BIN
functional/clean-dirty-slider/Window_Plate.STL
Normal file
BIN
functional/clean-dirty-slider/Window_Plate.STL
Normal file
Binary file not shown.
1
functional/corner-stabilizer.scad
Normal file
1
functional/corner-stabilizer.scad
Normal file
@ -0,0 +1 @@
|
||||
cube([3, 6, 1]);
|
BIN
functional/corner-stabilizer.stl
Normal file
BIN
functional/corner-stabilizer.stl
Normal file
Binary file not shown.
BIN
functional/drawer-slide-support.stl
Normal file
BIN
functional/drawer-slide-support.stl
Normal file
Binary file not shown.
58219
functional/drawer-slide-support_2h56m_0.20mm_200C_PLA_ENDER3V2.gcode
Normal file
58219
functional/drawer-slide-support_2h56m_0.20mm_200C_PLA_ENDER3V2.gcode
Normal file
File diff suppressed because it is too large
Load Diff
1
functional/filament_box_label.scad
Normal file
1
functional/filament_box_label.scad
Normal file
@ -0,0 +1 @@
|
||||
cube([10, 30, 1.5]);
|
BIN
functional/filament_box_label.stl
Normal file
BIN
functional/filament_box_label.stl
Normal file
Binary file not shown.
23349
functional/filament_label_and_clip.gcode
Normal file
23349
functional/filament_label_and_clip.gcode
Normal file
File diff suppressed because it is too large
Load Diff
BIN
functional/glue gun stand.stl
Normal file
BIN
functional/glue gun stand.stl
Normal file
Binary file not shown.
28
functional/headphone_cord_clip.scad
Normal file
28
functional/headphone_cord_clip.scad
Normal file
@ -0,0 +1,28 @@
|
||||
include <../lib/cable_sleeve.scad>;
|
||||
include <table_edge_clip.scad>;
|
||||
|
||||
epsilon = 0.01;
|
||||
sleeveLen = 20;
|
||||
wall = 4;
|
||||
clipLen = 8;
|
||||
|
||||
translate([0, 0, clipLen/2]) rotate([90, 0, 0])
|
||||
union() {
|
||||
translate([6, 2, sleeveLen/-2])
|
||||
rotate([0, 0, 127])
|
||||
cableSleeve(cableDiameter = 3, length = sleeveLen);
|
||||
|
||||
translate([wall - epsilon, -clipLen/2, sleeveLen/-2])
|
||||
cube([0.75*wall + epsilon, wall, sleeveLen]);
|
||||
|
||||
translate([1.32*wall, -clipLen/2 + 1.02, sleeveLen/-2])
|
||||
rotate([0, 0, -31.1])
|
||||
cube([wall/2, wall + 0.1, sleeveLen]);
|
||||
|
||||
tableEdgeClip(
|
||||
length = clipLen,
|
||||
depth = 24,
|
||||
thickness = wall,
|
||||
tableDepth = 21.58,
|
||||
clampAngle = 4);
|
||||
}
|
BIN
functional/headphone_cord_clip.stl
Normal file
BIN
functional/headphone_cord_clip.stl
Normal file
Binary file not shown.
BIN
functional/hotglue gun stand-ext.stl
Normal file
BIN
functional/hotglue gun stand-ext.stl
Normal file
Binary file not shown.
BIN
functional/mac-power-cable-clip.stl
Normal file
BIN
functional/mac-power-cable-clip.stl
Normal file
Binary file not shown.
BIN
functional/mac-power-cable-holder.stl
Normal file
BIN
functional/mac-power-cable-holder.stl
Normal file
Binary file not shown.
32
functional/mac_power_cable_clip.scad
Normal file
32
functional/mac_power_cable_clip.scad
Normal file
@ -0,0 +1,32 @@
|
||||
include <lib/cable_sleeve.scad>;
|
||||
|
||||
epsilon = 0.01;
|
||||
laptopThickness = 16.35;
|
||||
clipLength = 6;
|
||||
cableDiameter = 3.75;
|
||||
wallThickness = 3;
|
||||
|
||||
rotate([0, 0, 30])
|
||||
cableSleeve(cableDiameter = cableDiameter, length = clipLength);
|
||||
|
||||
translate([-2, 3, 0])
|
||||
color("SlateGrey")
|
||||
cube([wallThickness, wallThickness, clipLength]);
|
||||
|
||||
translate([laptopThickness/-2 - wallThickness, 5, 0])
|
||||
color("DarkOliveGreen")
|
||||
cube([laptopThickness + 2*wallThickness, wallThickness, clipLength]);
|
||||
|
||||
translate([laptopThickness/-2, 5, 8])
|
||||
color("LightSalmon")
|
||||
cube([laptopThickness, wallThickness, clipLength]);
|
||||
|
||||
translate([laptopThickness/-2 - wallThickness - 0.2, 5, 0])
|
||||
color("RoyalBlue")
|
||||
//rotate([0, 0, -2])
|
||||
cube([wallThickness, 4*wallThickness, clipLength]);
|
||||
|
||||
translate([laptopThickness/2 + 0.2, 5, 0])
|
||||
color("RoyalBlue")
|
||||
//rotate([0, 0, 2])
|
||||
cube([wallThickness, 4*wallThickness, clipLength]);
|
50
functional/mac_power_cable_holder.scad
Normal file
50
functional/mac_power_cable_holder.scad
Normal file
@ -0,0 +1,50 @@
|
||||
include <lib/arc_cylinder.scad>
|
||||
|
||||
epsilon = 0.01;
|
||||
laptopThickness = 16.35;
|
||||
laptopWidth = 358;
|
||||
standWidth = 152;
|
||||
cableDiameter = 3.75;
|
||||
supportLength = 10;
|
||||
|
||||
|
||||
module cableSleeve(cableDiameter, length) {
|
||||
innerRadius = (cableDiameter + 1) / 2; // give 1mm clearence for the cable
|
||||
|
||||
arcCylinder(
|
||||
height = length,
|
||||
outerRadius = innerRadius + 2,
|
||||
innerRadius = innerRadius,
|
||||
degrees = 360 - (2 * asin(cableDiameter / (cableDiameter + 2))));
|
||||
}
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
translate([0, standWidth / 2, cableDiameter + 0.51])
|
||||
rotate([90, 0, 0])
|
||||
cableSleeve(cableDiameter = cableDiameter, length = standWidth);
|
||||
|
||||
translate([-4, standWidth/2 - epsilon, -3])
|
||||
cube([4, supportLength + epsilon, 7]);
|
||||
|
||||
translate([ -4, standWidth/-2 - supportLength + epsilon, -3])
|
||||
cube([4, supportLength + epsilon, 7]);
|
||||
}
|
||||
|
||||
translate([0, 97, cableDiameter + 0.51])
|
||||
rotate([90, 0, 0])
|
||||
//color("SteelBlue")
|
||||
cylinder(r = (cableDiameter + 1) / 2, h = 194);
|
||||
}
|
||||
|
||||
translate([-8 - laptopThickness - 7, standWidth/2, -4])
|
||||
cube([4 + 4 + laptopThickness + 7, supportLength, 3]);
|
||||
|
||||
translate([-8 - laptopThickness - 7, standWidth/-2 - supportLength, -4])
|
||||
cube([4 + 4 + laptopThickness + 7, supportLength, 3]);
|
||||
|
||||
translate([-8 - laptopThickness - 7, standWidth/2, -4])
|
||||
cube([4, supportLength, 16]);
|
||||
|
||||
translate([-8 - laptopThickness - 7, standWidth/-2 - supportLength, -4])
|
||||
cube([4, supportLength, 16]);
|
BIN
functional/metric_ruler_10mm.stl
Normal file
BIN
functional/metric_ruler_10mm.stl
Normal file
Binary file not shown.
BIN
functional/microsd_storage_min_clearance_0_4mm.stl
Normal file
BIN
functional/microsd_storage_min_clearance_0_4mm.stl
Normal file
Binary file not shown.
BIN
functional/microsd_storage_min_clearance_0_5mm.stl
Normal file
BIN
functional/microsd_storage_min_clearance_0_5mm.stl
Normal file
Binary file not shown.
212
functional/over-door-clothes-hanger.scad
Normal file
212
functional/over-door-clothes-hanger.scad
Normal file
@ -0,0 +1,212 @@
|
||||
ep = 0.01;
|
||||
t = 3; // thickness
|
||||
w = 32; // width
|
||||
dt = 36; // door thickness
|
||||
|
||||
hookDescent = 100;
|
||||
backDescent = dt / 2;
|
||||
|
||||
module backSupport(descent, rakeAngle = 20, includeKicker = true) {
|
||||
topExt = sin(rakeAngle)*descent;
|
||||
|
||||
difference() {
|
||||
union() {
|
||||
cube([t, descent, w]);
|
||||
|
||||
if (includeKicker) {
|
||||
cube([topExt, t, w]);
|
||||
|
||||
translate([topExt, -1, 0])
|
||||
rotate([0, 0, rakeAngle])
|
||||
translate([0, -t, 0])
|
||||
cube([t, descent + t, w]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
union() {
|
||||
translate([-ep, -2*t, -ep])
|
||||
cube([topExt + 2*t, 2*t, w + 2*ep]);
|
||||
|
||||
translate([topExt + 2*t/3, -ep, -ep])
|
||||
cube([t, descent, w + 2*ep]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module hookAndSupport(descent, hookSize = 32, angle = 45, debug=false) {
|
||||
hw = hookSize / 2;
|
||||
hookDist = hookSize * 2.5;
|
||||
hookOffsetX = sin(angle) * hookDist;
|
||||
hookOffsetY = cos(angle) * hookDist;
|
||||
|
||||
fpr = 2/5; // frame attachment point ratio
|
||||
aBAF = (90 - angle)/2;
|
||||
l = hookDist;
|
||||
lAC = hookDist * fpr;
|
||||
lCG = lAC * sin(angle);
|
||||
lCD = hookOffsetX;
|
||||
lCE = lCG/cos(angle);
|
||||
lAF = lAC*cos(angle) / cos(aBAF);
|
||||
lGE = lCE*sin(angle);
|
||||
lGF = lAF*sin(aBAF);
|
||||
lCF = lCG + lGF;
|
||||
lEF = sqrt(lGE*lGE + lGF*lGF);
|
||||
lCI = lCF*cos(angle);
|
||||
lFI = lCF*sin(angle);
|
||||
lDI = lCD - lCI;
|
||||
lDF = sqrt(lDI*lDI + lEF*lEF);
|
||||
aGEF = atan(lGF/lGE);
|
||||
aCAE = 90 - angle;
|
||||
aCEF = aCAE + aGEF;
|
||||
aEDF = atan(lFI/lDI) + 1;
|
||||
|
||||
phi = (90 - angle)/2;
|
||||
g0 = l*fpr;
|
||||
g1 = g0*sin(angle);
|
||||
g2 = (g0 * cos(angle) * sin(phi))/cos(phi);
|
||||
o = (g0 * cos(angle))/cos(phi);
|
||||
p1 = (g0 * sin(angle))/cos(angle);
|
||||
|
||||
translate([t/4, descent - t, 0])
|
||||
union() {
|
||||
color("Salmon")
|
||||
translate([-hookOffsetX, -hookOffsetY, 0])
|
||||
sphere(hookSize / 2);
|
||||
|
||||
translate([0, 0, -hw/2])
|
||||
union() {
|
||||
color("LightBlue")
|
||||
rotate([0, 0, 270 - angle])
|
||||
translate([-t/2, -t/2, 0])
|
||||
cube([hookDist + t, t, hw]);
|
||||
|
||||
color("LightGreen")
|
||||
translate([0, -lAC, 0])
|
||||
rotate([0, 0, 180 - angle])
|
||||
translate([-t/2, -t/2, 0])
|
||||
cube([lCF + t/2, t, hw]);
|
||||
|
||||
color("Orange")
|
||||
rotate([0, 0, aBAF + 180])
|
||||
translate([-t/2, -t/2, 0])
|
||||
cube([lAF + t/2, t, hw]);
|
||||
|
||||
color("Plum")
|
||||
translate([-lCD, -g0 -t/2, 0])
|
||||
cube([lCD + t/2, t, hw]);
|
||||
|
||||
color("Turquoise")
|
||||
translate([-lCE, -lAC, 0])
|
||||
rotate([0, 0, aCEF])
|
||||
translate([-t/2, -t/2, 0])
|
||||
cube([lEF + t/2, t, hw]);
|
||||
|
||||
color("SlateBlue")
|
||||
translate([-lCD + t/2, -lAC, 0])
|
||||
rotate([0, 0, aEDF])
|
||||
translate([-t/2, -t/2, 0])
|
||||
cube([lDF + t/2, t, hw]);
|
||||
|
||||
color("Linen")
|
||||
translate([-lCD, -2*lAC, 0])
|
||||
cube([t, lAC, hw]);
|
||||
|
||||
$fn=32;
|
||||
color("DodgerBlue")
|
||||
linear_extrude(height=hw)
|
||||
circle(r = t);
|
||||
|
||||
translate([-lCI, -lAC + lFI, 0])
|
||||
color("DodgerBlue")
|
||||
linear_extrude(height=hw)
|
||||
circle(r = t);
|
||||
|
||||
translate([-lCD + t/2, -lAC, 0])
|
||||
color("DodgerBlue")
|
||||
linear_extrude(height=hw)
|
||||
circle(r = t);
|
||||
|
||||
}
|
||||
|
||||
// Point Labels
|
||||
if (debug) {
|
||||
color("Red")
|
||||
translate([0, 0, w/2+1])
|
||||
union() {
|
||||
translate([-t/2, 0, 0])
|
||||
rotate([180, 0, 0])
|
||||
linear_extrude(height=1) text(text = "A",size = 4);
|
||||
|
||||
translate([-hookOffsetX + t/2, -hookOffsetY + t/2, 0])
|
||||
rotate([0, 0, 180])
|
||||
linear_extrude(height=1) text(text = "B",size = 4);
|
||||
|
||||
translate([t/2, -lAC + t/2, 0])
|
||||
rotate([0, 0, 180])
|
||||
linear_extrude(height=1) text(text = "C",size = 4);
|
||||
|
||||
translate([-hookOffsetX + t/2, -lAC, 0]) union() {
|
||||
translate([0, -hookOffsetY + lAC, 0])
|
||||
cube([0.5, hookOffsetY - lAC, 1]);
|
||||
|
||||
translate([0, t/2, 0])
|
||||
rotate([0, 0, 180])
|
||||
linear_extrude(height=1) text(text = "D",size = 4);
|
||||
}
|
||||
|
||||
translate([-lCE + t/2, -lAC + t/2, 0])
|
||||
rotate([0, 0, 180])
|
||||
linear_extrude(height=1) text(text = "E",size = 4);
|
||||
|
||||
translate([-t/2, 0, 0])
|
||||
rotate([0, 0, aBAF])
|
||||
translate([-lAF + t/2, 0, 0])
|
||||
rotate([0, 0, 180 - aBAF])
|
||||
linear_extrude(height=1) text(text = "F",size = 4);
|
||||
|
||||
translate([0, -lAC + t/2, 0])
|
||||
rotate([0, 0, -angle])
|
||||
translate([-lCG + t/2, 0, 0])
|
||||
rotate([0, 0, 180 + angle])
|
||||
linear_extrude(height=1) text(text = "G",size = 4);
|
||||
|
||||
translate([-lCE, 0, 0])
|
||||
union() {
|
||||
rotate([0, 0, 180])
|
||||
linear_extrude(height=1) text(text = "H",size = 4);
|
||||
|
||||
translate([0, -lAC, 0])
|
||||
cube([0.5, lAC, 1]);
|
||||
|
||||
cube([lCE, 0.5, 1]);
|
||||
}
|
||||
|
||||
union() {
|
||||
translate([-lCI - t, -lAC + t/2, 0])
|
||||
rotate([0, 0, 180])
|
||||
linear_extrude(height=1) text(text = "I",size = 4);
|
||||
translate([-lCI, -lAC, 0])
|
||||
cube([0.5, lFI, 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
union() {
|
||||
translate([0, 0, -w/2]) union() {
|
||||
color("Moccasin")
|
||||
translate([t, 0, 0])
|
||||
cube([dt + 2*ep, t, w]);
|
||||
|
||||
color("WhiteSmoke")
|
||||
cube([t, hookDescent, w]);
|
||||
|
||||
color("WhiteSmoke")
|
||||
translate([dt + t, 0, 0])
|
||||
backSupport(descent = backDescent, rakeAngle = 36, includeKicker = false);
|
||||
}
|
||||
|
||||
hookAndSupport(descent = hookDescent, hookSize = w, angle = 36, debug=false);
|
||||
}
|
BIN
functional/over-door-clothes-hanger.stl
Normal file
BIN
functional/over-door-clothes-hanger.stl
Normal file
Binary file not shown.
16
functional/table_edge_clip.scad
Normal file
16
functional/table_edge_clip.scad
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
module tableEdgeClip(length = 4, depth = 20, thickness = 4, tableDepth = 21.58, clampAngle = 3) {
|
||||
translate([0, length/-2, tableDepth/-2 - thickness])
|
||||
cube([thickness, length, tableDepth + 2*thickness]);
|
||||
|
||||
translate([0.01, length/-2, tableDepth/-2 - thickness])
|
||||
mirror([1, 0, 0])
|
||||
rotate([0, -clampAngle, 0])
|
||||
cube([depth + 0.01, length, thickness]);
|
||||
|
||||
mirror([0, 0, 1])
|
||||
translate([0.01, length/-2, tableDepth/-2 - thickness])
|
||||
mirror([1, 0, 0])
|
||||
rotate([0, -clampAngle, 0])
|
||||
cube([depth + 0.01, length, thickness]);
|
||||
}
|
3
functional/test.scad
Normal file
3
functional/test.scad
Normal file
@ -0,0 +1,3 @@
|
||||
include <table_edge_clip.scad>;
|
||||
|
||||
tableEdgeClip(length = 8, depth = 40);
|
BIN
functional/umo_bluray_lid.stl
Normal file
BIN
functional/umo_bluray_lid.stl
Normal file
Binary file not shown.
BIN
functional/umo_cubby.stl
Normal file
BIN
functional/umo_cubby.stl
Normal file
Binary file not shown.
BIN
functional/umo_hdd_drawer.stl
Normal file
BIN
functional/umo_hdd_drawer.stl
Normal file
Binary file not shown.
BIN
functional/umo_shell1.stl
Normal file
BIN
functional/umo_shell1.stl
Normal file
Binary file not shown.
BIN
functional/umo_shell2_bot.stl
Normal file
BIN
functional/umo_shell2_bot.stl
Normal file
Binary file not shown.
BIN
functional/umo_shell2_top.stl
Normal file
BIN
functional/umo_shell2_top.stl
Normal file
Binary file not shown.
608
functional/under_monitor_organizer.scad
Normal file
608
functional/under_monitor_organizer.scad
Normal file
@ -0,0 +1,608 @@
|
||||
// Enable/Disable parts of the composite model
|
||||
showBoundBox = false;
|
||||
showBluRay = false;
|
||||
showBluRayLid = false;
|
||||
showHddDrawer = false;
|
||||
showCubby = false;
|
||||
showRightDrawer = true;
|
||||
showLetterShelf = false;
|
||||
showShell1 = false;
|
||||
showShell2Top = false;
|
||||
showShell2Bot = false;
|
||||
|
||||
epsilon = 0.01;
|
||||
|
||||
maxAvailWidth = 303.43; // width will be on X
|
||||
maxAvailDepth = 225.63; // depth will be on Y
|
||||
maxAvailHeigth = 104; // height will be on Z
|
||||
wall = 2;
|
||||
outerWall = 3;
|
||||
slideGap = 1;
|
||||
lapDepth = 20;
|
||||
|
||||
fullWidth = 300;
|
||||
fullDepth = 225;
|
||||
fullHeight = 96;
|
||||
|
||||
// full-size base and walls
|
||||
if (showBoundBox) {
|
||||
translate([0, 0, -(wall + outerWall)])
|
||||
color("DimGray")
|
||||
cube([fullWidth, fullDepth, outerWall]);
|
||||
|
||||
translate([0, fullDepth + (wall + outerWall), 0])
|
||||
color("DimGray")
|
||||
cube([fullWidth, outerWall, fullHeight]);
|
||||
|
||||
translate([-(wall + outerWall), 0, 0])
|
||||
color("DimGray")
|
||||
cube([outerWall, fullDepth, fullHeight]);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Blu-Ray Drive holder
|
||||
// ===========================================================================
|
||||
bluRayWidth = 140;
|
||||
bluRayDepth = 151;
|
||||
bluRayHeight = 20;
|
||||
bluRaySidedoor = 5;
|
||||
bluRayBackWindow = bluRayWidth - 100;
|
||||
|
||||
// test fit pieces
|
||||
/*
|
||||
|
||||
// Lap joint
|
||||
translate([0, 30, 0])
|
||||
difference() {
|
||||
color("SeaGreen") union() {
|
||||
cube([20, 20, wall]);
|
||||
cube([wall, 20, 20]);
|
||||
}
|
||||
|
||||
translate([wall-epsilon, -epsilon, -epsilon])
|
||||
cube([20 + 2*epsilon - wall, lapDepth/2 + 2*epsilon, wall/2 + 2*epsilon]);
|
||||
|
||||
translate([wall/2 + epsilon, -epsilon, -epsilon])
|
||||
cube([wall/2 + 2*epsilon, lapDepth/2 + 2*epsilon, 20 + 2*epsilon]);
|
||||
}
|
||||
|
||||
difference() {
|
||||
color("SandyBrown") union() {
|
||||
cube([20, 20, wall]);
|
||||
cube([wall, 20, 20]);
|
||||
}
|
||||
|
||||
translate([0, 10, 0]) union() {
|
||||
translate([-epsilon, -epsilon, wall/2])
|
||||
cube([20 + 2*epsilon, lapDepth/2 + 2*epsilon, wall/2 + 2*epsilon]);
|
||||
|
||||
translate([-epsilon, -epsilon, -epsilon])
|
||||
cube([wall/2 + 2*epsilon, lapDepth/2 + 2*epsilon, 20 + 2*epsilon]);
|
||||
}
|
||||
}
|
||||
|
||||
// Bluray width
|
||||
color("Pink") union() {
|
||||
cube([ bluRayWidth + 2*wall, 4*wall, wall]);
|
||||
cube([wall, 4*wall, 4*wall]);
|
||||
translate([bluRayWidth + wall, 0, 0, ]) cube([wall, 4*wall, 4*wall]);
|
||||
}
|
||||
|
||||
// Bluray depth
|
||||
color("Salmon") translate([0, 5*wall, 0]) union() {
|
||||
cube([ bluRayDepth + 2*wall, 4*wall, wall]);
|
||||
cube([wall, 4*wall, 4*wall]);
|
||||
translate([bluRayDepth + wall, 0, 0, ]) cube([wall, 4*wall, 4*wall]);
|
||||
}
|
||||
|
||||
// Bluray height
|
||||
color("MistyRose") translate([0, 10*wall, 0]) union() {
|
||||
cube([ bluRayHeight + 2*wall, 4*wall, wall]);
|
||||
cube([wall, 4*wall, 4*wall]);
|
||||
translate([bluRayHeight + wall, 0, 0, ]) cube([wall, 4*wall, 4*wall]);
|
||||
}
|
||||
*/
|
||||
|
||||
translate([fullWidth - (outerWall + 4*wall + bluRayWidth + slideGap), wall, 0])
|
||||
union() {
|
||||
// Blu-Ray box
|
||||
if (showBluRay) {
|
||||
color("DodgerBlue")
|
||||
difference() {
|
||||
union() {
|
||||
cube([ // floor
|
||||
bluRayWidth + 2*wall,
|
||||
bluRayDepth + 2*wall,
|
||||
outerWall]);
|
||||
|
||||
translate([0, bluRayDepth + wall, 0])
|
||||
cube([ // +y wall
|
||||
bluRayWidth + 2*wall,
|
||||
wall,
|
||||
bluRayHeight + outerWall]);
|
||||
|
||||
cube([ // -x wall
|
||||
wall,
|
||||
bluRayDepth + 2*wall,
|
||||
bluRayHeight + outerWall]);
|
||||
|
||||
translate([bluRayWidth + wall, 0, 0])
|
||||
cube([ // +x wall
|
||||
wall,
|
||||
bluRayDepth + 2*wall,
|
||||
bluRayHeight + outerWall]);
|
||||
|
||||
cube([ // -y front sidedoor 1
|
||||
bluRaySidedoor + wall,
|
||||
wall,
|
||||
bluRayHeight + outerWall]);
|
||||
|
||||
translate([bluRayWidth + wall - bluRaySidedoor, 0, 0])
|
||||
cube([ // -y sidedoor 2
|
||||
bluRaySidedoor + wall,
|
||||
wall,
|
||||
bluRayHeight + outerWall]);
|
||||
|
||||
translate([bluRayWidth - 3, wall - 0.5, 0])
|
||||
rotate([0, 0, -15])
|
||||
cube([0.4, 20, bluRayHeight + outerWall]);
|
||||
|
||||
translate([6.6, wall - 0.5, 0])
|
||||
rotate([0, 0, 15])
|
||||
cube([0.4, 20, bluRayHeight + outerWall]);
|
||||
}
|
||||
|
||||
translate([80, bluRayDepth + wall - epsilon, outerWall])
|
||||
cube([ // +y window cutout
|
||||
bluRayBackWindow,
|
||||
wall + 2*epsilon,
|
||||
bluRayHeight + epsilon]);
|
||||
}
|
||||
}
|
||||
|
||||
// Blu-Ray lid
|
||||
if (showBluRayLid) {
|
||||
color("CornflowerBlue")
|
||||
translate([-wall, -wall, bluRayHeight + outerWall])
|
||||
// translate([0, -20, 0]) // for printing
|
||||
// rotate([180, 0, 0])
|
||||
union() {
|
||||
cube([ // ceiling
|
||||
bluRayWidth + 4*wall,
|
||||
bluRayDepth + 4*wall,
|
||||
wall]);
|
||||
|
||||
translate([0, 0, -wall])
|
||||
cube([ // -x lip
|
||||
wall - 0.2,
|
||||
bluRayDepth + 4*wall,
|
||||
2*wall]);
|
||||
|
||||
translate([bluRayWidth + 3*wall + 0.2, 0, -wall])
|
||||
cube([ // +x lip
|
||||
wall - 0.2,
|
||||
bluRayDepth + 4*wall,
|
||||
2*wall]);
|
||||
|
||||
translate([0, 0, -wall])
|
||||
cube([ // -y lip
|
||||
bluRayWidth + 4*wall,
|
||||
wall - 0.2,
|
||||
2*wall]);
|
||||
|
||||
translate([0, bluRayDepth + 3*wall + 0.2, -wall])
|
||||
cube([ // +y lip
|
||||
bluRayWidth + 4*wall,
|
||||
wall - 0.2,
|
||||
2*wall]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// HDD Drawer + Cubby
|
||||
// ===========================================================================
|
||||
hddMinDepth = 110;
|
||||
hddMinHeight = 80;
|
||||
hddDepth = 134;
|
||||
hddHeight = 84;
|
||||
hddLargeWidth = 22;
|
||||
hddSmallWidth = 12;
|
||||
|
||||
ccDepth = 88;
|
||||
ccWidth = 56;
|
||||
fingerWidth = 24;
|
||||
|
||||
module hddSlot(width) {
|
||||
cube([ // floor
|
||||
width + 2*wall,
|
||||
hddDepth + wall,
|
||||
wall]);
|
||||
|
||||
translate([width + wall, hddDepth*0.25, 0])
|
||||
cube([ // +x wall
|
||||
wall,
|
||||
hddDepth*0.75 + wall,
|
||||
hddHeight/2 + wall]);
|
||||
|
||||
translate([0, hddDepth*0.25, 0])
|
||||
cube([ // -x wall
|
||||
wall,
|
||||
hddDepth*0.75 + wall,
|
||||
hddHeight/2 + wall]);
|
||||
|
||||
translate([0, hddDepth, 0])
|
||||
cube([ // +y wall
|
||||
width + 2*wall,
|
||||
wall,
|
||||
hddHeight/2 + wall]);
|
||||
}
|
||||
|
||||
cubbyFullWidth = 2*(hddLargeWidth + wall) + 6*(hddSmallWidth + wall) + wall;
|
||||
translate([outerWall + slideGap, 0, outerWall + slideGap])
|
||||
union() {
|
||||
|
||||
// HDD Slots
|
||||
if (showHddDrawer) {
|
||||
translate([0, fullDepth - (hddDepth + wall + outerWall + slideGap),0])
|
||||
difference() {
|
||||
color("IndianRed")
|
||||
union() {
|
||||
for (i = [0:5]) {
|
||||
translate([(hddSmallWidth + wall)*i, 0, 0])
|
||||
hddSlot(hddSmallWidth);
|
||||
}
|
||||
|
||||
for (i = [0:1]) {
|
||||
translate([(hddLargeWidth + wall)*i + 6*(hddSmallWidth + wall), 0, 0])
|
||||
hddSlot(hddLargeWidth);
|
||||
}
|
||||
|
||||
// +y wall
|
||||
translate([0, hddDepth, 0])
|
||||
cube([cubbyFullWidth, wall, hddHeight]);
|
||||
|
||||
// -x wall
|
||||
cube([wall, hddDepth, hddHeight]);
|
||||
|
||||
// +x wall
|
||||
translate([cubbyFullWidth - wall, 0, ])
|
||||
cube([wall, hddDepth, hddHeight]);
|
||||
|
||||
// floor toungue for assembly
|
||||
translate([0, (wall-lapDepth)/2, 0])
|
||||
cube([ cubbyFullWidth, lapDepth, wall/2 ]);
|
||||
|
||||
// -x wall toungue
|
||||
translate([wall/2, -lapDepth/2 + wall/2, 0])
|
||||
cube([wall/2, lapDepth, hddHeight]);
|
||||
|
||||
// +x wall toungue
|
||||
translate([cubbyFullWidth - wall, -lapDepth/2 + wall/2, 0])
|
||||
cube([wall/2, lapDepth, hddHeight]);
|
||||
}
|
||||
|
||||
// floor toungue cut-out
|
||||
translate([-epsilon, (wall-lapDepth)/2 - epsilon, wall/2 - epsilon])
|
||||
cube([cubbyFullWidth + 2*epsilon, lapDepth + 2*epsilon, wall/2 + 2*epsilon]);
|
||||
|
||||
// -x wall toungue cutout
|
||||
translate([-epsilon, -lapDepth/2 - epsilon + wall/2, -epsilon])
|
||||
cube([wall/2 + 2*epsilon, lapDepth + 2*epsilon, hddHeight + 2*epsilon]);
|
||||
|
||||
// +x wall toungue cutout
|
||||
translate([cubbyFullWidth - (wall/2 + epsilon), -lapDepth/2 - epsilon + wall/2, -epsilon])
|
||||
cube([wall/2 + 2*epsilon, lapDepth + 2*epsilon, hddHeight + 2*epsilon]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Cubby drawer
|
||||
if (showCubby) {
|
||||
color("FireBrick")
|
||||
difference() {
|
||||
union() {
|
||||
cube([ // base
|
||||
cubbyFullWidth,
|
||||
fullDepth - (hddDepth + outerWall + wall + slideGap),
|
||||
wall]);
|
||||
|
||||
cube([ // -x wall
|
||||
wall,
|
||||
fullDepth - (hddDepth + outerWall + wall + slideGap),
|
||||
hddHeight]);
|
||||
|
||||
translate([cubbyFullWidth - wall, 0, 0])
|
||||
cube([ // +x wall
|
||||
wall,
|
||||
fullDepth - (hddDepth + outerWall + wall + slideGap),
|
||||
hddHeight]);
|
||||
|
||||
cube([ // -y wall
|
||||
cubbyFullWidth,
|
||||
wall,
|
||||
hddHeight]);
|
||||
|
||||
translate([
|
||||
(cubbyFullWidth - ccDepth - 2*wall)/2,
|
||||
(fullDepth - (hddDepth + outerWall + 3*wall + slideGap + ccWidth)),
|
||||
0])
|
||||
difference() {
|
||||
// cc well walls
|
||||
union() {
|
||||
cube([ // -y wall
|
||||
ccDepth + 2*wall,
|
||||
wall,
|
||||
hddHeight/2]);
|
||||
|
||||
translate([0, ccWidth + wall, 0])
|
||||
cube([ // +y wall
|
||||
ccDepth + 2*wall,
|
||||
wall,
|
||||
hddHeight/2]);
|
||||
|
||||
cube([ // -x wall
|
||||
wall,
|
||||
ccWidth + 2*wall,
|
||||
hddHeight/2]);
|
||||
|
||||
translate([ccDepth + wall, 0, 0])
|
||||
cube([ // +x wall
|
||||
wall,
|
||||
ccWidth + 2*wall,
|
||||
hddHeight/2]);
|
||||
}
|
||||
|
||||
// finger cut-out for picking up credit cards
|
||||
union() {
|
||||
translate([ccDepth/2 + wall, ccWidth + 2*wall + epsilon, fingerWidth/2 + wall])
|
||||
rotate([90, 0, 0])
|
||||
cylinder(h=ccWidth + 2*wall + 2*epsilon, r=fingerWidth/2);
|
||||
|
||||
translate([ccDepth/2 - fingerWidth/2 + wall, -epsilon, fingerWidth/2 + epsilon])
|
||||
cube([
|
||||
fingerWidth,
|
||||
ccWidth + 2*wall + 2*epsilon,
|
||||
hddHeight/2 - fingerWidth/2]);
|
||||
}
|
||||
}
|
||||
|
||||
// floor toungue for assembly
|
||||
translate([0, fullDepth - (hddDepth + outerWall + wall + lapDepth/2), wall/2])
|
||||
cube([cubbyFullWidth, lapDepth, wall/2 ]);
|
||||
|
||||
// -w wall toungue
|
||||
translate([0, fullDepth - (hddDepth + outerWall + wall + lapDepth/2), 0])
|
||||
cube([wall/2, lapDepth, hddHeight]);
|
||||
|
||||
// +w wall toungue
|
||||
translate([cubbyFullWidth - wall/2, fullDepth - (hddDepth + outerWall + wall + lapDepth/2), 0])
|
||||
cube([wall/2, lapDepth, hddHeight]);
|
||||
}
|
||||
|
||||
// floor toungue cutaway for assembly
|
||||
translate([wall-epsilon, fullDepth - (hddDepth + outerWall + wall + lapDepth/2 - epsilon), -epsilon])
|
||||
cube([cubbyFullWidth + 2*epsilon - 2*wall, lapDepth + 2*epsilon, wall/2 + 2*epsilon ]);
|
||||
|
||||
translate([wall/2 - epsilon, fullDepth - (hddDepth + outerWall + wall + lapDepth/2), -epsilon])
|
||||
cube([wall/2 + 2*epsilon, lapDepth + 2*epsilon, hddHeight + 2*epsilon]);
|
||||
|
||||
translate([cubbyFullWidth - wall - epsilon, fullDepth - (hddDepth + outerWall + wall + lapDepth/2), -epsilon])
|
||||
cube([wall/2 + 2*epsilon, lapDepth + 2*epsilon, hddHeight + 2*epsilon]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Right Drawer
|
||||
// ===========================================================================
|
||||
rightDrawerHeight = 35;
|
||||
rightDrawerDepth = fullDepth - outerWall - slideGap;
|
||||
rightDrawerWidth = fullWidth - cubbyFullWidth - 3*outerWall - 4*slideGap;
|
||||
if (showRightDrawer) {
|
||||
color("MediumSeaGreen")
|
||||
translate([cubbyFullWidth + 2*outerWall + 3*slideGap, 0, bluRayHeight + 2*outerWall])
|
||||
union() {
|
||||
cube([ // floor
|
||||
rightDrawerWidth,
|
||||
rightDrawerDepth,
|
||||
wall]);
|
||||
|
||||
cube([ // -x wall
|
||||
wall,
|
||||
rightDrawerDepth,
|
||||
rightDrawerHeight]);
|
||||
|
||||
translate([rightDrawerWidth - wall, 0, 0])
|
||||
cube([ // +x wall
|
||||
wall,
|
||||
rightDrawerDepth,
|
||||
rightDrawerHeight]);
|
||||
|
||||
cube([ // -y wall
|
||||
rightDrawerWidth,
|
||||
wall,
|
||||
rightDrawerHeight]);
|
||||
|
||||
translate([0, rightDrawerDepth - wall, 0])
|
||||
cube([ // -y wall
|
||||
rightDrawerWidth,
|
||||
wall,
|
||||
rightDrawerHeight]);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Letter Shelf
|
||||
// ===========================================================================
|
||||
letterBoxDepth = 20;
|
||||
letterBoxRecline = 2;
|
||||
if (showLetterShelf) {
|
||||
color("PeachPuff")
|
||||
translate([cubbyFullWidth + outerWall + 2*slideGap, 0, fullHeight - letterBoxDepth])
|
||||
rotate([-letterBoxRecline, 0, 0])
|
||||
union() {
|
||||
cube([
|
||||
fullWidth - cubbyFullWidth - outerWall - 2*slideGap,
|
||||
fullDepth,
|
||||
wall ]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ===========================================================================
|
||||
// Outer Shell
|
||||
// ===========================================================================
|
||||
shell1Width = cubbyFullWidth + outerWall + 2*slideGap;
|
||||
if (showShell1) {
|
||||
color("MidnightBlue")
|
||||
difference() {
|
||||
union() {
|
||||
cube([ // floor
|
||||
shell1Width,
|
||||
fullDepth,
|
||||
outerWall]);
|
||||
|
||||
cube([ // -x wall
|
||||
outerWall,
|
||||
fullDepth,
|
||||
fullHeight/3]);
|
||||
|
||||
translate([0, fullDepth - outerWall, 0])
|
||||
cube([ // +y wall (short)
|
||||
shell1Width,
|
||||
outerWall,
|
||||
fullHeight/3]);
|
||||
|
||||
translate([shell1Width/2, 0, -20])
|
||||
cube([ // printing support
|
||||
wall,
|
||||
fullDepth,
|
||||
20 + epsilon]);
|
||||
}
|
||||
|
||||
union() {
|
||||
translate([shell1Width - lapDepth, fullDepth - outerWall/2 + epsilon, -epsilon])
|
||||
cube([ // +y wall lip cutout
|
||||
lapDepth + epsilon,
|
||||
outerWall/2 + epsilon,
|
||||
fullHeight/3 + 2*epsilon]);
|
||||
|
||||
translate([shell1Width - lapDepth, -epsilon, outerWall/2 + epsilon])
|
||||
cube([ // floor lip cutout
|
||||
lapDepth + 2*epsilon,
|
||||
fullDepth + 2*epsilon,
|
||||
outerWall/2 + epsilon]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shell2Width = fullWidth - cubbyFullWidth - outerWall - 2*slideGap;
|
||||
if (showShell2Top) {
|
||||
color("SlateBlue")
|
||||
translate([cubbyFullWidth + outerWall + 2*slideGap, 0, fullHeight/2])
|
||||
difference() {
|
||||
union() {
|
||||
cube([ // middle x wall
|
||||
outerWall,
|
||||
fullDepth,
|
||||
fullHeight/2]);
|
||||
|
||||
translate([shell2Width - outerWall, 0, 0])
|
||||
cube([ // +x wall
|
||||
outerWall,
|
||||
fullDepth,
|
||||
fullHeight/2]);
|
||||
|
||||
translate([0, fullDepth - outerWall, 0])
|
||||
cube([ // +y wall (tall)
|
||||
shell2Width,
|
||||
outerWall,
|
||||
fullHeight/2]);
|
||||
|
||||
translate([0, 0, fullHeight/2 - outerWall])
|
||||
cube([ // ceiling
|
||||
shell2Width,
|
||||
fullDepth,
|
||||
outerWall ]);
|
||||
}
|
||||
|
||||
union() {
|
||||
translate([-epsilon, fullDepth - outerWall/2 + epsilon, -epsilon])
|
||||
cube([ // +y wall lip cutout
|
||||
shell2Width + 2*epsilon,
|
||||
outerWall/2 + epsilon,
|
||||
lapDepth + 2*epsilon]);
|
||||
|
||||
translate([outerWall/2, -epsilon, -epsilon])
|
||||
cube([ // -x wall lip cutout
|
||||
outerWall/2 + 2*epsilon,
|
||||
fullDepth,
|
||||
lapDepth + 2*epsilon ]);
|
||||
|
||||
translate([shell2Width - outerWall -epsilon, -epsilon, -epsilon])
|
||||
cube([ // +x wall lip cutout
|
||||
outerWall/2 + 2*epsilon,
|
||||
fullDepth,
|
||||
lapDepth + 2*epsilon ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (showShell2Bot) {
|
||||
color("DarkSlateBlue")
|
||||
translate([cubbyFullWidth + outerWall + 2*slideGap, 0, 0])
|
||||
union() {
|
||||
cube([ // floor
|
||||
shell2Width,
|
||||
fullDepth,
|
||||
outerWall]);
|
||||
|
||||
cube([ // middle x wall
|
||||
outerWall,
|
||||
fullDepth,
|
||||
fullHeight/2]);
|
||||
|
||||
translate([shell2Width - outerWall, 0, 0])
|
||||
cube([ // +x wall
|
||||
outerWall,
|
||||
fullDepth,
|
||||
fullHeight/2]);
|
||||
|
||||
translate([0, fullDepth - outerWall, 0])
|
||||
cube([ // +y wall (tall)
|
||||
shell2Width,
|
||||
outerWall,
|
||||
fullHeight/2]);
|
||||
|
||||
translate([-lapDepth, fullDepth - outerWall/2, 0])
|
||||
cube([ // +y wall lip 1 (to shell 1)
|
||||
lapDepth + epsilon,
|
||||
outerWall/2,
|
||||
fullHeight/3]);
|
||||
|
||||
translate([0, fullDepth - outerWall/2, fullHeight/2 - epsilon])
|
||||
cube([ // +y wall lip 2 (to shell 2 top)
|
||||
shell2Width,
|
||||
outerWall/2,
|
||||
lapDepth + epsilon]);
|
||||
|
||||
translate([outerWall/2, 0, fullHeight/2 - epsilon])
|
||||
cube([ // -x wall lip
|
||||
outerWall/2,
|
||||
fullDepth,
|
||||
lapDepth + epsilon ]);
|
||||
|
||||
translate([shell2Width - outerWall, 0, fullHeight/2 - epsilon])
|
||||
cube([ // +x wall lip
|
||||
outerWall/2,
|
||||
fullDepth,
|
||||
lapDepth + epsilon ]);
|
||||
|
||||
translate([-lapDepth, 0, outerWall/2])
|
||||
cube([ // floor lip
|
||||
lapDepth + epsilon,
|
||||
fullDepth,
|
||||
outerWall/2 ]);
|
||||
}
|
||||
}
|
0
functional/wall-key-hanger.scad
Normal file
0
functional/wall-key-hanger.scad
Normal file
Reference in New Issue
Block a user