Replacement Muntin Clips

Terminology I had to look up:

  • Window: something in a wall you can see through
  • Sash: a sliding panel in a window
  • Mullion: vertical post separating two windows
  • Muntin: strips separating glass panes in a sash

TIL: Muntin, which I’d always known was called a Mullion.

With that as preface, one of Mary’s quilting cronies lives in a very old house updated with vinyl windows sporting wood muntins arranged in a grille. The wood strips forming the grille end in plastic clips that snap into the sash, thereby holding the grill in place to make the window look more-or-less historically correct, while not being a dead loss as far as winter heating goes.

Time passed, sun-drenched plastic became brittle, and eventually enough clips broke that the grilles fell out. An afternoon quilting bee produced a question about the possibility of making a 3D printed clip, as the original manufacturer is either defunct or no longer offers that particular style of clip as a replacement part.

Well, I can do that:

Window Muntin Clips
Window Muntin Clips

The original is (obviously) the transparent injection-molded part in the upper left. The other two come hot off the M2’s platform, with the one on the right showing the support material under the sash pin.

The solid model looks about like you’d expect:

Window Muntin Clip - solid model
Window Muntin Clip – solid model

There is obviously no way to build it without support material, so I painted the bottom facet of the sash pin with a PrusaSlicer support enforcer:

Window Muntin Clip - PrusaSlicer
Window Muntin Clip – PrusaSlicer

The pin comes out slightly elongated top-to-bottom, but it’s still within the tolerances of the original part and ought to pop right into the sash. We’ll know how well it works shortly after the next quilting bee.

The doodle with useful measurements amid some ideas that did not work out:

Window Muntin Clip - Dimension Doodle
Window Muntin Clip – Dimension Doodle

The OpenSCAD source code as a GitHub Gist:

// Window Muntin Clips
// Ed Nisley KE4ZNU June 2022
Layout = "Show"; // [Build, Show]
/* [Hidden] */
ThreadThick = 0.25;
ThreadWidth = 0.40;
HoleWindage = 0.2;
Protrusion = 0.1; // make holes end cleanly
inch = 25.4;
ID = 0;
OD = 1;
LENGTH = 2;
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
//----------------------
// Dimensions
ClipOA = [13.0,18.7,8.0];
TongueAngle = 70;
TongueOA = [14.0,10.0,1.8 - 0.2]; // minus Z windage for angular slices
BuildGap = 5.0;
//----------------------
// Useful routines
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);
}
//----------------------
// Pieces
module Shell() {
// Clip base as 2D polygon
// Magic numbers from measurements
cx = ClipOA.x;
cy = ClipOA.y;
cz = ClipOA.z;
ClipPts = [
[0,0],[0,cz],[0.3,cz],
[1.0,cz-1.0],[2.0,cz-2.3],[2.0,cz-3.0],[1.3,cz-3.5],
[1.3,1.6],[17.4,1.6],
[17.4,cz-3.5],[16.7,cz-3.0],[16.7,cz-2.3],[17.7,cz-1.0],
[18.4,cz],[18.7,cz],[18.7,0.0],[0,0]
];
difference() {
translate([-ClipOA.x,-ClipOA.y/2,0])
rotate([90,0,90])
linear_extrude(height=ClipOA.x,convexity=3)
polygon(convexity=3,points=ClipPts);
translate([-(ClipOA.x - 3.0/2 + Protrusion),0,0])
cube([3.0 + Protrusion,ClipOA.y - 2*1.3,4*1.6],center=true);
}
}
module Tongue() {
tx = TongueOA.x;
ty = TongueOA.y;
tz = TongueOA.z;
tt = ty - 2*sqrt(2)*tz; // width at top of tapers
td = ThreadWidth; // min size of features
intersection() {
rotate([0,-TongueAngle,0]) {
difference() {
union() {
hull() {
for (j=[-1,1]) {
translate([td/2,j*(ty - td)/2,td/2])
cube(td,center=true);
translate([td/2,j*(tt - td)/2,tz - td/2])
cube(td,center=true);
}
translate([10.0,0,0])
rotate(180/12)
cylinder(d=ty,h=td,center=false,$fn=12);
translate([10.0,0,tz - td/2])
rotate(180/12)
cylinder(d=tt,h=td,center=false,$fn=12);
};
translate([10.0,0,-5.2])
rotate(180/12)
cylinder(d=5.0,h=5.2,center=false,$fn=12);
translate([10.0,0,-5.2])
rotate(180/12)
resize([0,0,2.0])
sphere(d=5.0/cos(180/12),$fn=12);
}
if (false)
translate([10.0,0,-10]) // stiffening hole
rotate(180/6)
PolyCyl(0.1,20,6);
}
}
cube([2*ClipOA.x,2*ClipOA.y,2*IntegerMultiple(13.0,ThreadThick)],center=true);
}
}
module Clip() {
Shell();
Tongue();
}
//----------------------
// Build it
if (Layout == "Show") {
Clip();
}
if (Layout == "Build") {
Clip();
}

Comments are closed.