Our Larval Engineer practiced fencing for several years, learning the fundamental truth that you should always bring a gun to a knife fight:

It’s time to pass the gear along to someone who can use it, but we discovered one of the ear grommets inside the helmet had broken:

The cylinder in the middle should be attached to the washer on the left, which goes inside the helmet padding. It’s a tight push fit inside the washer on the right, which goes on the outside of the padding. Ridges along the cylinder hold it in place.
Being an injection-molded polyethylene part, no earthly adhesive or solvent will bother it, soooo… the solid model pretty much reproduces the original design:

The top washer goes inside the padding against your (well, her) ear, so I chamfered the edges sorta-kinda like the original.
There are no deliberate ridges on the central cylinder, but printing the parts in the obvious orientation with no additional clearance makes them a very snug push fit and the usual 3D printing ridges work perfectly; you could apply adhesive if you like. The outside washer has a slight chamfer to orient the post and get it moving along.
The posts keep the whole affair from rotating, but I’m not sure they’re really necessary.
Printing a pair doesn’t take much longer than just one:

It doesn’t look like much inside the helmet:

The OpenSCAD source code as a gist from Github:
// Fencing Helmet Ear Grommet | |
// Ed Nisley KE4ZNU December 2015 | |
// Layout options | |
Layout = "Show"; // Base Cap Build Show | |
//- Extrusion parameters must match reality! | |
// Print with +1 shells and 3 solid layers | |
ThreadThick = 0.20; | |
ThreadWidth = 0.40; | |
HoleWindage = 0.2; | |
function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); | |
Protrusion = 0.1; // make holes end cleanly | |
//---------------------- | |
// Dimensions | |
NumSides = 12*4; | |
$fn = NumSides; | |
//---------------------- | |
// 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); | |
} | |
//------------------- | |
// Parts | |
// Base on outside of liner | |
PostOD = 15.5; | |
PostLength = 8.0; | |
BaseOD = 26.0; | |
BaseLength = 3.4; | |
module Base() { | |
difference() { | |
union() { | |
cylinder(d=BaseOD,h=2.0); | |
cylinder(d=20.0,h=BaseLength); | |
for (i=[0:5]) | |
rotate(i*360/6) | |
translate([11.5,0,0]) | |
rotate(180/6) | |
cylinder(d1=2.5,d2=3*ThreadWidth,h=4.0,$fn=6); | |
} | |
translate([0,0,-Protrusion]) | |
// PolyCyl(PostOD,4.0,NumSides/4); | |
cylinder(d=PostOD,h=PostLength,$fn=NumSides/4); | |
translate([0,0,(BaseLength - 4*ThreadThick)]) | |
cylinder(d1=PostOD,d2=(PostOD + 2*ThreadWidth),h=(4*ThreadThick + Protrusion),$fn=NumSides/4); | |
} | |
} | |
// Cap inside liner | |
CapID = 12.0; | |
CapOD = 28.0; | |
CapThick = 3.0; | |
module Cap() { | |
difference() { | |
union() { | |
rotate_extrude(convexity=2) | |
polygon(points=[ | |
[CapID/2 + CapThick/3,0.0], | |
[CapOD/2 - CapThick/3,0.0], | |
[CapOD/2,CapThick/2], | |
[CapOD/2,CapThick], | |
[CapID/2,CapThick], | |
[CapID/2,CapThick - CapThick/3] | |
]); | |
translate([0,0,CapThick - Protrusion]) | |
cylinder(d=PostOD,h=(PostLength - (CapThick - Protrusion)),$fn=NumSides/4); | |
} | |
translate([0,0,-Protrusion]) | |
PolyCyl(CapID,10.0,$fn); | |
} | |
} | |
//---------------------- | |
// Build it! | |
if (Layout == "Base") | |
Base(); | |
if (Layout == "Cap") | |
Cap(); | |
BuildSpace = 30/2; | |
if (Layout == "Build") { | |
for (j=[-1,1]) | |
translate([j*BuildSpace,0,0]) { | |
translate([0,-BuildSpace,0]) | |
Base(); | |
translate([0,BuildSpace,0]) | |
Cap(); | |
} | |
} | |
if (Layout == "Show") { | |
color("LightGreen") Base(); | |
translate([0,0,12]) | |
rotate([180,0,0]) | |
color("LightBlue") Cap(); | |
} |