The objective being to reduce the number of onion maggots in Mary’s Vassar Farm plot without chemical agents, I conjured sticky trap screen frames from the vasty digital deep:

Each one contains half a sheet of yellow sticky plastic, which is easy enough to cut before peeling off the protective covering sheets. The cage is half-inch galvanized hardware cloth snipped with hardened diagonal cutters. A bead of acrylic adhesive around the base holds the cage in place
Although you can deploy sticky sheets without cages, they tend to attract and affix beneficial critters: butterflies, small birds, furry critters, toads, gardeners, and the like. We don’t know how effective the cages will be, but they seemed better than nothing.
They mount on ski poles cut in half:

And on fence posts around the perimeter:

To my untrained eye, some of those doomed critters are, indeed, onion maggot flies. The rest seem to be gnats and other nuisances, so IMO we’re applying population pressure in the right direction.
Each base-and-cap frame takes about three hours to print, so I did them one at a time over the course of a few days while applying continuous product improvement.
The sheets rest on small V blocks intended to keep them centered within the cage:

The ski pole attachment must build with the cap on top, but it bridges well enough for the purpose:

The overhanging hooks on the blocks (just barely) engage the grid to keep the lid in place, while remaining short enough to not droop too badly. You could probably delete the hooks from the bottom plate, but they align the cage while the adhesive cures.
The sheets tend to bend in the middle, so I’ll stick a thin slat or two vertically to keep them straight.
The OpenSCAD source code as a GitHub Gist:
// Sticky Sheet Cage | |
// Ed Nisley KE4ZNU May 2021 | |
Layout = "Build"; // [Build, Show, Cap, Attachment] | |
Bracket = "Ski"; // [Angle, Ski, Post] | |
//- Extrusion parameters must match reality! | |
/* [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 | |
Sheet = [1,100,150]; // sticky sheet | |
Grid = 0.5*inch; | |
Cage = [2*Grid + 5.0, 8*Grid + 5.0, 12*Grid + 2.0]; // grid wire cage bent around sheet | |
CageRad = 2.5; // wire bending radius | |
CageThick = 2.0; // grid thickness | |
WallThick = 3.0; // min wall and bottom thickness | |
Recess = 5.0; // inset to capture cage edge | |
Plate = [Cage.x,Cage.y,Recess] + [2*WallThick,2*WallThick,WallThick]; | |
PlateRad = 5.0; | |
SkiPole = [20.0,20.0 + 2*WallThick,50]; | |
AnglePlate = [30,30,50]; | |
ScrewClear = 5.0; | |
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 Cap() { | |
union() { | |
difference() { | |
hull() | |
for (i=[-1,1], j=[-1,1]) | |
translate([i*(Plate.x/2 - PlateRad),j*(Plate.y/2 - PlateRad),0]) | |
cylinder(r=PlateRad,h=Plate.z,$fn=12); | |
translate([0,0,Plate.z - Recess]) | |
hull() | |
for (i=[-1,1], j=[-1,1]) | |
translate([i*(Cage.x/2 - CageRad),j*(Cage.y/2 - CageRad),0]) | |
cylinder(r=CageRad,h=Plate.z,$fn=12); | |
} | |
difference() { | |
Strut = Cage.x - 2*CageThick; | |
Latch = [Cage.x,WallThick,0.75*Plate.z]; | |
union() { | |
for (j=[-1,1]) | |
translate([0,j*2.5*Grid,Plate.z]) | |
cube([Strut,WallThick,2*Plate.z],center=true); | |
for (j=[-1,1]) | |
translate([0,j*2.5*Grid,2*Plate.z - Latch.z/2]) | |
cube(Latch,center=true); | |
} | |
translate([0,0,2*Plate.z + (Cage.z - Sheet.z)/4]) | |
rotate([0,45,0]) | |
cube([Strut/sqrt(2),Plate.y,Strut/sqrt(2)],center=true); | |
} | |
} | |
} | |
module Attachment() { | |
if (Bracket == "Angle") { | |
translate([0,Plate.y/2,0]) | |
rotate(45) | |
difference() { | |
union() { | |
cube(AnglePlate,center=false); | |
rotate(-45) | |
translate([0,WallThick,Plate.z/2]) | |
cube([Plate.x - 2*PlateRad,4*WallThick,Plate.z],center=true); | |
} | |
translate([WallThick,WallThick,-Protrusion]) | |
cube(AnglePlate + [0,0,2*Protrusion],center=false); | |
translate([AnglePlate.x/2,-Protrusion,2*AnglePlate.z/3]) | |
rotate([-90,0,0]) | |
PolyCyl(ScrewClear,2*AnglePlate.x,6); | |
translate([-Protrusion,AnglePlate.x/2,1*AnglePlate.z/3]) | |
rotate([90,0,90]) | |
PolyCyl(ScrewClear,2*AnglePlate.x,6); | |
} | |
} | |
else if (Bracket == "Ski") { | |
translate([0,Plate.y/2 + SkiPole[OD]/2,0]) | |
difference() { | |
union() { | |
PolyCyl(SkiPole[OD],SkiPole[LENGTH],24); | |
translate([0,-3*WallThick,Plate.z/2]) | |
cube([Plate.x - 2*PlateRad,4*WallThick,Plate.z],center=true); | |
} | |
translate([0,0,-2*WallThick]) | |
PolyCyl(SkiPole[ID],SkiPole[LENGTH],24); | |
} | |
} | |
} | |
//---------------------- | |
// Build it | |
if (Layout == "Cap") | |
Cap(); | |
if (Layout == "Attachment") { | |
Attachment(); | |
} | |
if (Layout == "Show") { | |
translate([0,0,Sheet.z/2 + Plate.z]) | |
color("Yellow") | |
cube(Sheet,center=true); | |
Cap(); | |
Attachment(); | |
translate([0,0,Sheet.z + 2*Plate.z]) | |
rotate([180,0,0]) | |
Cap(); | |
} | |
if (Layout == "Build") { | |
translate([-(Plate.x/2 + BuildGap),0,0]) { | |
Cap(); | |
Attachment(); | |
} | |
translate([(Plate.x/2 + BuildGap),0,0]) | |
Cap(); | |
} |
Tin snips (I like the green-handled shears like steroid-enhanced scissors) make short work of 1/2″ hardware cloth. Haven’t tried the yellow neutral cutters for the same job. My raised beds get a layer of hardware cloth to discourage ground squirrels.
I obviously need a flush hard-wire cutter to eliminate the sharp tips left by the diagonals, but maybe half a dozen traps will get the job done. They definitely look weird out there amid all the mulch …