We just scrapped out the old dish drainer, only to find the gadget bin on the new drainer let the measuring spoons fall over and lie along its bottom. After a week of fishing them out from under paring knives, cheese slicers, and suchlike, I gimmicked up a holder:

One might suggest natural PETG, rather than orange, thereby displaying a shocking ignorance of the MVP concept. We’ll run with orange for the shakedown trials, then build-measure-learn, iterate, and, for all I know, we may even pivot.
A bottom-up view of the solid model shows the trench accommodating the bin lip:

The OpenSCAD source code as a GitHub Gist:
// Measuring spoon drainer | |
// Ed Nisley KE4ZNU - 2018-01-13 | |
/* [Extrusion] */ | |
ThreadThick = 0.25; // [0.20, 0.25] | |
ThreadWidth = 0.40; // [0.40] | |
/* [Hidden] */ | |
Protrusion = 0.1; // [0.01, 0.1] | |
HoleWindage = 0.2; | |
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); | |
ID = 0; | |
OD = 1; | |
LENGTH = 2; | |
//- Adjust hole diameter to make the size come out right | |
module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes | |
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2); | |
FixDia = Dia / cos(180/Sides); | |
cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides); | |
} | |
/* [Spoon] */ | |
SpoonOD = IntegerMultiple(3.3,2); | |
SpoonWidth = IntegerMultiple(16.5,2.0); | |
SpoonOC = 30.0; | |
/* [Drainer] */ | |
Drainer = [52.0,59.5,100.0]; // overall drainer cup | |
DrainerRimWidth = (Drainer[1] - Drainer[0])/2; | |
DrainerRimHeight = 2.5; | |
DrainerExtent = 15.0; | |
/* [Hidden] */ | |
WallThick = 2.0; // basic wall & floor thickness | |
PlateThick = WallThick + 2*DrainerRimHeight; | |
NumSides = 8*4; | |
//----- | |
// Define shapes | |
module CoverPlate() { | |
OD = Drainer[OD] + 2*WallThick; | |
difference() { | |
cylinder(d=OD,h=PlateThick,$fn=NumSides); | |
for (j=[-1,1]) | |
translate([-(OD/2 - Protrusion),j*(Drainer[ID]/2 + DrainerRimWidth/2),WallThick + DrainerRimHeight + Protrusion/2]) | |
cube([OD,DrainerRimWidth,2*DrainerRimHeight + Protrusion],center=true); | |
translate([0,0,WallThick + PlateThick/2]) | |
rotate(-90) | |
rotate_extrude(angle=180,$fn=NumSides) | |
translate([Drainer[ID]/2 + DrainerRimWidth/2,0]) | |
square([DrainerRimWidth,PlateThick],center=true); | |
translate([-(OD/2 + DrainerExtent),0,PlateThick/2]) | |
cube([OD,OD,PlateThick + 2*Protrusion],center=true); | |
} | |
} | |
//----- | |
// Build it | |
difference() { | |
CoverPlate(); | |
for (j=[-1,1]) | |
translate([0,j*(SpoonOC/2),-Protrusion]) | |
linear_extrude(height=PlateThick + 2*Protrusion) | |
hull() | |
for (i=[-1,1]) | |
translate([i*(SpoonWidth - SpoonOD)/2,0]) | |
circle(d=SpoonOD,$fn=8); | |
} | |
The original doodle has useful dimensions, along with the usual over-elaborate features sacrificed in order to get it made:
