An interesting project requires a handful of 9 mm Luger (aka 9 mm NATO) dummy cartridges with real brass. You can buy exact form / fit / weight dummies or plastic training rounds, but these will suit my simple needs:

That’s a snap cap on the left and a real 9 mm Luger cartridge on the right. The holes in the dummy brass indicate that they are absolutely, positively, unquestionably not loaded cartridges.
Start by drilling a 1/8 inch hole in the side of each unfired, primerless case:

I set up the chuck on the rotary table, thinking I might drill three holes in each cartridge, but came to my senses. It’s lined up by eye, flush with the end of the jaws, and the hole is just above the inside of the base.
The solid model has the same overall length and proportion as a 115 grain FMJ bullet, but doesn’t match the proper ogive or base diameter. Basically, I stretched a 9 mm sphere and stuck it atop a slightly tapered base cylinder:

For reasons I don’t profess to understand, the sphere has a slightly different diameter at its equator than the top of the cylinder, even though they’re both the same BulletOD
diameter with the same number of faces. Fortunately, that didn’t affect the final results.
Print up a handful of the things:

The shadow from the flash makes the bases look slightly fatter than they really are.
Using a thinner layer would look better in this orientation. They’d definitely look better if they were split, printed with the long axis parallel to the plate, and glued together, as the grain would run lengthwise; I’m not sure there’s enough room for alignment pins, though.
At this diameter and number of faces, the M2 produces almost perfectly accurate dimensions, so the bullets press-fit just like you’d expect. They’re twisted into a dab of urethane glue inside the brass that foams just enough to hold them place.
Rather than use a real seating die, I deployed a closed chuck on the drill press. The trick is to set the depth stop to produce slightly too-long cartridges, then shim the platform without changing the stop and seat the bullet to the proper depth:

The OAL tolerance for various 9 mm Luger cartridges seems to range from 1.08 inch to 1.17 inch, so anything in that range should be fine. I used 1.10 inch.
These are not intended for firing. You could fire them with just a primer (in a non-drilled case) and (maybe) not melt or shatter the plastic, but they’re slightly larger than the nominal 8.82 mm land diameter and won’t obturate or spin-stabilize worth diddly: expect short range and keyholing.
The sectional density is a whopping 0.008, should you keep track of such things: 0.47 gram = 7.2 grain. Note that the US small arms definition of sectional density has units of pound/inch2, not the pound/foot2 you’ll find right next to values computed using inches; the magic number 1/7000 just converts from grains to pounds. In the rest of the (metric) world, it’s entirely different.
The OpenSCAD source code:
// Dummy 9mm Luger bullet // Ed Nisley KE4ZNU November 2013 //---------------------- // Dimensions BulletOD = 9.05; // main diameter BulletBaseOD = 8.8; // ... easy insertion BulletOAL = 14.0; // overall length BaseLength = 8.0; // cylindrical base length NoseLength = BulletOAL - BaseLength; NumSides = 8*4; //---------------------- // Useful routines module ShowPegGrid(Space = 10.0,Size = 1.0) { Range = floor(50 / Space); for (x=[-Range:Range]) for (y=[-Range:Range]) translate([x*Space,y*Space,Size/2]) %cube(Size,center=true); } //------------------- // Build it... ShowPegGrid(); color("Orange") cylinder(r1=BulletBaseOD/2,r2=BulletOD/2,h=BaseLength,$fn=NumSides); color("DarkOrange") translate([0,0,BaseLength]) resize([0,0,2*NoseLength]) sphere(BulletOD/2,$fn=NumSides);