Introduction: Creating Personalised 3D Printed Napkin Rings/Place Cards
My Fiancee and I are getting married soon, and we wanted something a bit different for the wedding reception. I've just bought a 3D printer and was unsuccessfully trying to justify its usefulness to her, when luckily she came up with the idea of creating customised napkin rings for everybody instead of using Place Cards!
We'll have maybe 100 guests, so creating that many individual 3D objects could be a nightmare. What we need is a way to automate it!
This instructable will show you how to quickly and easily create hundreds of 3D printed Napkin rings for everybody using completely free software. It could easily be changed to make other types of objects too...
(Please excuse the 3D print quality in the pictures - I'm still getting used to the printer!)
Step 1: What You Need
First off, the obvious bit - you need access to a 3D printer, or to be happy to use one of the many websites that will print off a model for you.
I bought a SUMPOD (www.sumpod.com), because it was cheap, sturdy, and made in England, not very far from where I live. This is like most of the 3D printers you can buy now (MakerBot, UltiMaker, Printrbot) in that it prints upwards in layers using extruded ABS or PLA plastic.
On the software side, I'm using Linux as the Operating System. All the software below is available for Windows and Mac too, but it may be more of a hassle to install it.
OpenSCAD (www.openscad.org)
ImageMagick (www.imagemagick.org)
PoTrace (potrace.sourceforge.net)
pstoedit (www.pstoedit.net)
Bash (comes with Linux and Mac, on Windows you might need MinGW : www.mingw.org)
On Ubuntu Linux, all you need to do is type the following command to install everything:
sudo apt-get install openscad imagemagick potrace pstoedit
On other operating systems you'll probably have to do a lot of googling!
You could always try using a Ubuntu Live CD (http://www.ubuntu.com/download/desktop) to boot up Ubuntu Temporarily and try this out. It's probably a lot easier than the alternatives!
Step 2: First Attempt
The first attempt was by Marianne, designing a napkin ring using the TinkerCAD (www.tinkercad.com) website.
Unfortunately this didn't work:
1. At the time, something about it (the complexity) meant TinkerCAD couldn't 'join' it, so instead of the STL file (that you need to print an object from) being one solid object, it was an object per letter that overlapped - which seems fine but really causes issues with 'Slicing' software. It seems TinkerCad have now fixed that though, so potentially they are an option if you want to do something like this.
2. If you think of the object sliced from bottom to top as the printer prints it, there are lots of separate pieces and in some places there are pieces that have nothing to be printed on top of (for instance if the middle of the 'M' doesn't touch the bottom). Some 3D printer software can insert 'supports' to get around this, but they take time to pull out, and even more time to print!
Also, it would have taken ages to design each napkin ring individually...
Step 3: Second Attempt
So I had an idea that we could add the text around a hollow cylinder - that way we could have gaps between the letters - but more importantly it can be printed quickly as the 3D printer can just print right around the edge on each layer, because everything is joined together by the cylinder.
I did this using OpenSCAD because all the files are just text that you can edit. I could then get something that worked and change it with a script, so that it would do the same thing for everybody's name!
Step 4: First Off: Letters
OpenSCAD is meant for designing engineering-type objects, so it doesn't contain any way to draw text. It will load vector shapes from files though, so I got around this by writing a script to make a file for each letter!
The steps were:
Create an image of each character (with ImageMagick)
Convert the image to a Vector file (with PoTrace)
Convert that Vector file to a file that OpenSCAD can load (a DXF)
The script file for it looks like this:
------------------------------------------- make_fonts.sh
#!/bin/bash
function make_font() {
CHAR=$1
echo Making font for "$CHAR"
convert -background white -fill black -font "Helvetica-Bold" -size 200x200 -gravity center label:"$CHAR" temp.pbm
potrace --resolution 100 -e temp.pbm -o temp.eps
rm char_$CHAR.dxf
pstoedit -dt -f dxf:-polyaslines temp.eps char_$CHAR.dxf
rm temp.pbm temp.eps
}
make_font A
make_font B
make_font C
make_font D
make_font E
make_font F
make_font G
make_font H
make_font I
make_font J
make_font K
make_font L
make_font M
make_font N
make_font O
make_font P
make_font Q
make_font R
make_font S
make_font T
make_font U
make_font V
make_font W
make_font X
make_font Y
make_font Z
-------------------------------------------
All you have to do is run the file './make_fonts.sh' and this will create the letters A to Z for you!
Once you have made the file, you can add it to OpenSCAD with a command like:
import(file="char_A.dxf",origin=[1,1]);
(origin is there to 'centre' the character on the screen)
Step 5: Arranging the Letters
To arrange the letters, you have to do some translation and rotation. To save on writing it out each time, you can write a 'module' in OpenSCAD that you can call multiple times with just the name of the character you want and where you want it...
In the module, we want to do the following steps:
Scale the character to the right size (it comes in about 2mm wide - but we want it much larger!) : scale(textsize)
Make sure we make it 3D (as it came in flat) : linear_extrude(height = 7, center = false)
Rotate it up the right way : rotate([90,0,180])
Move it away from the origin (rotation works around the origin, so doing this before rotating makes like a lot easier! : translate([0,radius,0.8*textsize])
Rotate again depending on where in the word the character is: rotate([0,0,rot*360/7])
And then we're sorted! You end up with a module like this:
height=40;
radius=30;
textsize=20;
module char(rot, name) {
rotate([0,0,rot*360/7]) translate([0,radius,0.8*textsize]) rotate([90,0,180]) linear_extrude(height = 7, center = false) scale(textsize) import(file=name,origin=[1,1]);
}
and then to write a name, you just call it for each letter:
char(0, "char_M.dxf");
char(1, "char_A.dxf");
char(2, "char_R.dxf");
char(3, "char_I.dxf");
char(4, "char_A.dxf");
char(5, "char_N.dxf");
char(6, "char_N.dxf");
char(7, "char_E.dxf");
Now there's just one final bit left, to make the actual 'band'. OpenSCAD uses CSG (Constructive Solid Geometry) so you make shapes by adding or subtracting them. All we need to do is to add (union) all the letters together, as well as a cylinder, and then to subtract (difference) a slightly thinner cylinder so that a hole is made in the middle:
difference() {
union() {
char(0, "char_M.dxf");
char(1, "char_A.dxf");
char(2, "char_R.dxf");
char(3, "char_I.dxf");
char(4, "char_A.dxf");
char(5, "char_N.dxf");
char(6, "char_N.dxf");
char(7, "char_E.dxf");
cylinder(h=height, r=radius+5);
}
translate([0,0,-1]) cylinder(h=height+2, r=radius);
}
And that's it! The full thing is below:
------------------------------------------- text_MARIANNE.scad
height=40;
radius=30;
textsize=20;
module char(rot, name) {
rotate([0,0,rot*360/9]) translate([0,radius,0.8*textsize]) rotate([90,0,180]) linear_extrude(height = 7, center = false) scale(textsize) import(file=name,origin=[1,1]);
}
difference() {
union() {
char(0, "char_M.dxf");
char(1, "char_A.dxf");
char(2, "char_R.dxf");
char(3, "char_I.dxf");
char(4, "char_A.dxf");
char(5, "char_N.dxf");
char(6, "char_N.dxf");
char(7, "char_E.dxf");
cylinder(h=height, r=radius+5);
}
translate([0,0,-1]) cylinder(h=height+2, r=radius);
}
-------------------------------------------
Attachments
Step 6: Automating a Single Napkin Ring
So now all we need is to be able to create those scad files automatically... For this, I'm just using Bash - like the WIndows Batch files.
The process is pretty simple:
1. copy in the first bit of the original SCAD file (up until the 'union' part), changing only one bit - the bit in rotation where the number of characters is stored.
2. for each character, add a line like 'char(0, "char_M.dxf");'
3. copy in the rest of the file
4. send it to OpenSCAD and ask it to create an STL file
The final file (make_scad.sh) looks like this:
------------------------------------------- make_scad.sh
#!/bin/bash
NAME=$1
NAMECHARS=`echo "$NAME" | sed -e "s/\\(.\\)/\\1\n/g"`
NAMECHARCOUNT=`echo "$NAMECHARS" | wc -l `
FILE=text_$NAME.scad
echo "
height=40;
radius=30;
textsize=20;
module char(rot, name) {
rotate([0,0,rot*360/$((NAMECHARCOUNT+1))]) translate([0,radius,0.8*textsize]) rotate([90,0,180]) linear_extrude(height = 7, center = false) scale(textsize) import(file=name,origin=[1,1]);
}
difference() {
union() {
" > $FILE
CHARNUM=0
for CHAR in $NAMECHARS
do
echo "char($CHARNUM, \"char_$CHAR.dxf\");" >> $FILE
CHARNUM=$((CHARNUM+1))
done
echo "
cylinder(h=height, r=radius+5);
}
translate([0,0,-1]) cylinder(h=height+2, r=radius);
}" >> $FILE
openscad $FILE -o text_$NAME.stl
-------------------------------------------
All you do, is at the terminal, write './make_scad.sh YOURNAME' and an STL file will magically be made for you!
Note that YOURNAME must have no spaces, and only the uppercase characters A to Z. You can now load the text_YOURNAME.STL file into your favourite 3D printer software and start printing!
Step 7: Automating Multiple Rings
The final part is getting lots of rings made!
Firstly, we need a file with a name on each line:
------------------------------------ names.txt
FREDERICK
PATRICIA
GORDON
NICOLA
MARIANNE
------------------------------------
Note that longer names work better. Because OpenSCAD will silently skip a file it doesn't know about, you can add spaces by using '_' so you could actually just do 'PAT_PAT' instead of 'PAT' if you wanted to.
Now, a very simple script that just calls make_scad for each name:
------------------------------------ make_all_scad.sh
#!/bin/bash
NAMEFILE=names.txt
for NAPKINNAME in `cat $NAMEFILE`
do
./make_scad.sh $NAPKINNAME
done
------------------------------------
Now, you can run './make_all_scad.sh' and send all the STL files (after checking them!) off to be printed, or can load them into your 3D printer software to print. I use repsnapper, which allows you to multi-select models to print, and which will automatically lay them out on the build area!
A usual build area on these kind of printers is 150mm x 150mm, so you could easily get 9 x 40mm napkin rings printed at once - or more if you lay them out carefully!
Step 8: Finished Product...
You can see in the picture what the finished product looks like... I think it could do with a little bit of tweaking, but it works pretty well...
So what would I change?
* The font is Helvetica at the moment - I think it would be far better if it was a bit more interesting
* I could do non-capitals, and could maybe script something to repeat names that were too short, or make the font smaller for names that were too long!
* If the fonts had smooth edges, they would print better, and could stick out of the cylinder more. OpenSCAD doesn't handle smoothing very well yet (apart from minowski sums, which take ages to compute), so I might end up creating smooth fonts as STL files and importing those instead.
* The 3D printer still needs a lot of tweaking - it's not making good prints at all right now. I might actually just send all of the Napkin Rings off to be printed!
* I'd definitely use a more interesting type of plastic! They do coloured sparkly plastics that would look way more fun.
I've also had a go at creating a 3D model from scratch, by 'embossing' a blurred image of the text onto the napkin ring (see the image). I'll experiment and report back, but this should be a lot faster to print as I can print just just a single line of filament, without making the Napkin ring 'solid'. It also has the advantage of producing a lovely smoothed font, and making it easy to add decoration such as patterns on the edges.
Hope you found that interesting, and please let us know if you decide to use our ideas!

Participated in the
Make It Real Challenge
7 Comments
11 years ago on Introduction
Hi gfwilliams!
Tinkercad here. Congrats on your engagement and WOW! This is going to be some wedding!
We read that there were some issues with joining. If you'd like to post the link to your design, we'll take a look, or send us an email: team@tinkercad.com.
Best,
Tinkercad Team
Reply 11 years ago on Introduction
I've just tried again with TinkerCad and it now appears to join everything just fine. Thanks, it's an awesome tool. I'm amazed how quickly everybody picks it up, even those completely new to 3D!
Reply 11 years ago on Introduction
Sweet. Good to hear =)
We are always impressed, too! It's amazing how changing the design of what is normally a very complex tool making it more user-friendly allows everyone to use it!
Hope to see more of your designs soon.
11 years ago on Step 6
Argh you linux uses and your dam code. :]
Reply 11 years ago on Step 6
Problem is, you can't easily do this kind of thing quickly without scripts or a specially made program! Once you have a napkin ring in OpenSCAD, the actual code to automate it is only maybe 10-15 lines of simple scripting - a small price to pay for being able to knock hundreds of personalised 3D prints out!
Reply 11 years ago on Step 6
And that's why coding and script will always be important.
I'm thinking about trying to learn a computer language to add to my repertoire, but I'm not really sure with one. Python seems good, especially because it can be used in Blender. But I'm terrible at learning languages :[ so should I read a lot of books about it or looking into learning C++ or some similar base language?
Reply 11 years ago on Step 6
It really depends what you want to do... If you just want to automate tasks and build from there then Python is a really good idea... Once you get in the mindset of not being willing to do repetitive point and click tasks yourself then using a computer suddenly becomes a whole load faster and more satisfying!
It'll also be a good step to Raspberry PI (or writing code on other embedded devices, such as ReadyNAS).
I'd say Java was worth a look at. With Eclipse it's got a great IDE that warns you of programming errors as if they were spelling mistakes, the language itself is simple, and it has a good debugger (stepping through code is a great way to help you learn). You're also 90% of the way to writing Android apps, and it's actually quite similar to JavaScript, and a 'nice' subset of C++.
C++ is great, but unforgiving. It's dead easy to get into bad habits and do things which will cause your code to inexplicably not work or to gobble up memory, and the extra speed it provides really isn't that important for most tasks on PCs now. It'll either make you love programming or completely demotivate you :) To be honest I wouldn't recommend it unless you wanted a career in computing...