Code for the above:
// ===================================================================================
// Replacement Maytag A806 Washing Machine Tub Light Window
// (Maytag Part Number 211723)
// See this formum thread for details:
// "Maytag tub light window A806"
//
https://www.automaticwasher.org/cgi-bin/TD/TD-VIEWTHREAD.cgi?81875_15~1
// ===================================================================================
// Model version: 2
// Change log:
// v1: Dave ("LowEfficiency"): Initial model based on measured dimensions by David ("d-jones").
// v2: Dave ("LowEfficiency"): 3D-printing optimized "snap-in" variant added. (Concept only - not fit tested!)
// Constants:
inchesToMillimeters = 25.4; //Conversion factor
// Measured dimensions (converted to metric for model):
r1 = (1.05/2-0.037) * inchesToMillimeters; //Inner cutout
r2 = (1.05/2) * inchesToMillimeters; //Outer edge of inset surface that protrudes through metal tub cover
r3 = (1.215/2) * inchesToMillimeters; //Top surface flange of the window
windowThickness = 0.050 * inchesToMillimeters;
protrusionDepth = (0.227-0.050) * inchesToMillimeters;
// Calculated dimensions:
// * Shape is assumed to be a pill-shape with perfect half-circle ends
// * Spacing of rounded end center points is equal to the total length minus the end radius*2
// * Using outer edge of inset portion for calculation, as that is the surface profile that matters for tub fitment
circleCenterSpacing = (2.045 * inchesToMillimeters) - r2*2;
// Unusued dimensions:
// * Measured total length of window at flange is 2.218".
// * Calculated total length of window at flange, assuming perfectly circular ends, would be 2.045+((1.215-1.05)/2) = 2.1275"
// * This should be plenty close enough for a part that isn't fit-critical, and simplifies the model to use an equal flange width.
// * (Can be easily changed in the future if desired.)
// Modifiable parameters:
roundness = 120; //Number of facets to use for circle generation. Larger value = smoother. (Should always be a multiple of 4).
// Note: Some consumer 3D printer controllers/firmwares will stutter if given too many tiny segments. If this happens, reduce the number of facets.
// Part Seletion:
generateWindowFactoryDimensions = false;
generateWindowClipIn = true; //A more optimized clip-in part that doesn't need heat-bending or sealant to install
if (generateWindowFactoryDimensions == true)
{
window_FactoryDimensions();
}
if (generateWindowClipIn == true)
{
window_ClipIn();
}
module window_FactoryDimensions()
{
//Window surface and flange
hull()
{
cylinder(windowThickness, r3, r3, false, $fn=roundness);
translate([circleCenterSpacing, 0, 0])
cylinder(windowThickness, r3, r3, false, $fn=roundness);
}
//Window mounting protrusion
difference()
{
//Outer dimensions, overlapping window surface by 0.1 to ensure a solid model
translate([0,0,windowThickness-0.1])
hull()
{
cylinder(0.1+protrusionDepth, r2, r2, false, $fn=roundness);
translate([circleCenterSpacing, 0, 0])
cylinder(0.1+protrusionDepth, r2, r2, false, $fn=roundness);
}
//Inner cutout, overlapping on both ends to ensure a complete cut through without co-planar surfaces
// (This does not cut into the window surface, only the protrusion portion)
translate([0,0,windowThickness-0.1])
hull()
{
cylinder(0.1+protrusionDepth+1, r1, r1, false, $fn=roundness);
translate([circleCenterSpacing, 0, 0])
cylinder(0.1+protrusionDepth+1, r1, r1, false, $fn=roundness);
}
}
}
module window_ClipIn()
{
//Create a clip-in lens by modifying the "factory" version
//Modifiable variables:
slotWidth = 0.5; //Make larger if specific 3D printer tolerances require (ie: if gaps are too close and become connected)
tabWidth = 6;
tabBumpRadius = 0.8;
difference()
{
//Start with the factory shape
window_FactoryDimensions();
//Cut slots to create tabs, facilitating flexing
translate([0,-r2-1,windowThickness+0.5])
cube([slotWidth,r2*2+2,protrusionDepth]);
translate([circleCenterSpacing-slotWidth,-r2-1,windowThickness+0.5])
cube([slotWidth,r2*2+2,protrusionDepth]);
translate([slotWidth+tabWidth,-r2-1,windowThickness+0.5])
cube([slotWidth,r2*2+2,protrusionDepth]);
translate([circleCenterSpacing-slotWidth-tabWidth-slotWidth,-r2-1,windowThickness+0.5])
cube([slotWidth,r2*2+2,protrusionDepth]);
}
//Add the pill-shaped bumps
pillShapedBump(slotWidth, -r2, windowThickness+protrusionDepth-tabBumpRadius, tabBumpRadius, tabWidth);
pillShapedBump(circleCenterSpacing-slotWidth-tabWidth, r2, windowThickness+protrusionDepth-tabBumpRadius, tabBumpRadius, tabWidth);
pillShapedBump(circleCenterSpacing-slotWidth-tabWidth, -r2, windowThickness+protrusionDepth-tabBumpRadius, tabBumpRadius, tabWidth);
pillShapedBump(slotWidth, r2, windowThickness+protrusionDepth-tabBumpRadius, tabBumpRadius, tabWidth);
}
module pillShapedBump(xPosEdge, yPosCenter, zPosCenter, radius, length)
{
translate([xPosEdge+radius,yPosCenter,zPosCenter])
sphere(radius, $fn=32);
translate([xPosEdge+radius,yPosCenter,zPosCenter])
rotate([0,90,0])
cylinder(length-radius*2, radius, radius, false, $fn=32);
translate([xPosEdge+length-radius,yPosCenter,zPosCenter])
sphere(radius, $fn=32);
}