Polymino to OpenSCAD
Code by Alain Brobecker

This command line tool converts a polymino given in a textfile into an object description for OpenSCAD.
You can download the source here and a binary for my computer (m$ window$ 10 PC): PolyminoToOpenSCAD.zip

0. Install

Create a directory in which you extract all files from the .zip file. If you have the same machine as me (m$ window$ 10) you're finsihed for this step since you already have the compiled executable PolyminoToOpenSCAD.exe. Otherwise you'll have to compile the PolyminoToOpenSCAD.c file, which also needs the Read2DObjectLib.c file.
If you don't know how to do that maybe it's better to ask a programmer friend or your IT department.

1. Create your polymino in a textfile

Create a textfile PolyminoToOpenSCAD_Input.txt containing the text below. You can modify some parameters, namely the x/y size of a square with PolyminoSquareSize, the z positions with PolyminoZTop and PolyminoZBottom. Those three variables can be integer or decimal numbers.
Last you can modify the look of the polymino with PolyminoType, namely you can have a simple blocky polymino with values 0,1, angular edges with values 2,3 and rounded edges with values 4,5 (see right picture). An important note, if you use even values 1,3,5 for PolyminoType, the generated object description will use a HG (HalfGap) parameter that is used to create a small (half-) gap toward the inner of the piece, so that two pieces will fit better together.
Then you have the desciption of the polymino between the start2d and end2d tags. This description must be given in a rectangular grid containing . and x and must be without holes (normaly the holes will just disappear if you put some into it).
All the text that is outside the start2d and end2d tags and that is not the 3 aforementioned variables is normally ignored, but I've put // here for comments which was not strictly needed.
Two more remarks: pieces with holes (eg a "O") are not supported and the hole will simply disappear, but pieces made of multiple disconnected polyominoes (eg an "i") are supported.

PolyminoSquareSize=10 //In millimeter
PolyminoZTop=10       //In millimeter
PolyminoZBottom=0     //In millimeter
//  0,1: polymino
//  2,3: polymino with angular edges
//  4,5: ! polymino with rounded edges on top and mess on bottom
//  6,7: polymino with rounded edges everywhere
//  8,9: ! polymino with rounded edges on bottom and mess on top
PolyminoType=3

--------- start2d .=0 x=1
..x..
x.x.x
xxxxx
.xxx.
xx.xx
--------- end2d
       

2. Execute the program

If you click on PolyGo.bat on a m$ window$ 10 machine, it will execute the program on the PolyminoToOpenSCAD_Input.txt file and output a file called PolyminoToOpenSCAD_Output.scad that you can load in OpenSCAD by double clicking on it.

Alternatively you can launch the m$do$ prompt (or the command line of your OS) and invoke the program with PolyminoToOpenSCAD.exe InFile.txt OutFile.scad

3. Resulting file

When you double click on PolyminoToOpenSCAD_Output.scad or copy/paste it from your favorite editor into OpenSCAD, you'll see a text file and after rendering (F5) it will normally look like the picture below.
Depending on the PolyminoType chosen, you'll see some parameters that you can change in OpenSCAD:

Below is a view of the PolyminoToOpenSCAD_Output.scad when PolyminoType was changed to 7. Some statistics are in comments at the end of the file.

ER=1;
$fn=40;
HG=0.05;
//PolyminoType=7
//PolyminoSquareSize=10
//PolyminoZTop=10
//PolyminoZBottom=0
polyhedron(
points=[[20+ER+HG,50-ER-HG,0+HG],[20+ER+HG,50-ER-HG,10-HG],[20+HG,50-ER-HG,0+ER+HG],[20+HG,50-ER-HG,10-ER-HG],[20+ER+HG,50-HG,0+ER+HG],[20+ER+HG,50-HG,10-ER-HG],[30-ER-HG,50-ER-HG,0+HG],[30-ER-HG,50-ER-HG,10-HG],[30-ER-HG,50-HG,0+ER+HG],[30-ER-HG,50-HG,10-ER-HG],[30-HG,50-ER-HG,0+ER+HG],[30-HG,50-ER-HG,10-ER-HG],[30-ER-HG,30-ER-HG,0+HG],[30-ER-HG,30-ER-HG,10-HG],[30-HG,30-HG,0+ER+HG],[30-HG,30-HG,10-ER-HG],[40+ER+HG,30-ER-HG,0+HG],[40+ER+HG,30-ER-HG,10-HG],[40+HG,30-HG,0+ER+HG],[40+HG,30-HG,10-ER-HG],[40+ER+HG,40-ER-HG,0+HG],[40+ER+HG,40-ER-HG,10-HG],[40+HG,40-ER-HG,0+ER+HG],[40+HG,40-ER-HG,10-ER-HG],[40+ER+HG,40-HG,0+ER+HG],[40+ER+HG,40-HG,10-ER-HG],[50-ER-HG,40-ER-HG,0+HG],[50-ER-HG,40-ER-HG,10-HG],[50-ER-HG,40-HG,0+ER+HG],[50-ER-HG,40-HG,10-ER-HG],[50-HG,40-ER-HG,0+ER+HG],[50-HG,40-ER-HG,10-ER-HG],[50-ER-HG,20+ER+HG,0+HG],[50-ER-HG,20+ER+HG,10-HG],[50-HG,20+ER+HG,0+ER+HG],[50-HG,20+ER+HG,10-ER-HG],[50-ER-HG,20+HG,0+ER+HG],[50-ER-HG,20+HG,10-ER-HG],[40-ER-HG,20+ER+HG,0+HG],[40-ER-HG,20+ER+HG,10-HG],[40-HG,20+HG,0+ER+HG],[40-HG,20+HG,10-ER-HG],[40-ER-HG,10-ER-HG,0+HG],[40-ER-HG,10-ER-HG,10-HG],[40-HG,10-HG,0+ER+HG],[40-HG,10-HG,10-ER-HG],[50-ER-HG,10-ER-HG,0+HG],[50-ER-HG,10-ER-HG,10-HG],[50-ER-HG,10-HG,0+ER+HG],[50-ER-HG,10-HG,10-ER-HG],[50-HG,10-ER-HG,0+ER+HG],[50-HG,10-ER-HG,10-ER-HG],[50-ER-HG,0+ER+HG,0+HG],[50-ER-HG,0+ER+HG,10-HG],[50-HG,0+ER+HG,0+ER+HG],[50-HG,0+ER+HG,10-ER-HG],[50-ER-HG,0+HG,0+ER+HG],[50-ER-HG,0+HG,10-ER-HG],[30+ER+HG,0+ER+HG,0+HG],[30+ER+HG,0+ER+HG,10-HG],[30+ER+HG,0+HG,0+ER+HG],[30+ER+HG,0+HG,10-ER-HG],[30+HG,0+ER+HG,0+ER+HG],[30+HG,0+ER+HG,10-ER-HG],[30+ER+HG,10+ER+HG,0+HG],[30+ER+HG,10+ER+HG,10-HG],[30+HG,10+HG,0+ER+HG],[30+HG,10+HG,10-ER-HG],[20-ER-HG,10+ER+HG,0+HG],[20-ER-HG,10+ER+HG,10-HG],[20-HG,10+HG,0+ER+HG],[20-HG,10+HG,10-ER-HG],[20-ER-HG,0+ER+HG,0+HG],[20-ER-HG,0+ER+HG,10-HG],[20-HG,0+ER+HG,0+ER+HG],[20-HG,0+ER+HG,10-ER-HG],[20-ER-HG,0+HG,0+ER+HG],[20-ER-HG,0+HG,10-ER-HG],[0+ER+HG,0+ER+HG,0+HG],[0+ER+HG,0+ER+HG,10-HG],[0+ER+HG,0+HG,0+ER+HG],[0+ER+HG,0+HG,10-ER-HG],[0+HG,0+ER+HG,0+ER+HG],[0+HG,0+ER+HG,10-ER-HG],[0+ER+HG,10-ER-HG,0+HG],[0+ER+HG,10-ER-HG,10-HG],[0+HG,10-ER-HG,0+ER+HG],[0+HG,10-ER-HG,10-ER-HG],[0+ER+HG,10-HG,0+ER+HG],[0+ER+HG,10-HG,10-ER-HG],[10+ER+HG,10-ER-HG,0+HG],[10+ER+HG,10-ER-HG,10-HG],[10+HG,10-HG,0+ER+HG],[10+HG,10-HG,10-ER-HG],[10+ER+HG,20+ER+HG,0+HG],[10+ER+HG,20+ER+HG,10-HG],[10+HG,20+HG,0+ER+HG],[10+HG,20+HG,10-ER-HG],[0+ER+HG,20+ER+HG,0+HG],[0+ER+HG,20+ER+HG,10-HG],[0+ER+HG,20+HG,0+ER+HG],[0+ER+HG,20+HG,10-ER-HG],[0+HG,20+ER+HG,0+ER+HG],[0+HG,20+ER+HG,10-ER-HG],[0+ER+HG,40-ER-HG,0+HG],[0+ER+HG,40-ER-HG,10-HG],[0+HG,40-ER-HG,0+ER+HG],[0+HG,40-ER-HG,10-ER-HG],[0+ER+HG,40-HG,0+ER+HG],[0+ER+HG,40-HG,10-ER-HG],[10-ER-HG,40-ER-HG,0+HG],[10-ER-HG,40-ER-HG,10-HG],[10-ER-HG,40-HG,0+ER+HG],[10-ER-HG,40-HG,10-ER-HG],[10-HG,40-ER-HG,0+ER+HG],[10-HG,40-ER-HG,10-ER-HG],[10-ER-HG,30-ER-HG,0+HG],[10-ER-HG,30-ER-HG,10-HG],[10-HG,30-HG,0+ER+HG],[10-HG,30-HG,10-ER-HG],[20+ER+HG,30-ER-HG,0+HG],[20+ER+HG,30-ER-HG,10-HG],[20+HG,30-HG,0+ER+HG],[20+HG,30-HG,10-ER-HG]],
faces=[[120,116,110,104,98,94,90,84,78,72,68,64,58,52,46,42,38,32,26,20,16,12,6,0],[1,7,13,17,21,27,33,39,43,47,53,59,65,69,73,79,85,91,95,99,105,111,117,121],[4,2,0],[1,3,5],[2,4,5,3],[10,8,6],[7,9,11],[8,10,11,9],[24,22,20],[21,23,25],[22,24,25,23],[30,28,26],[27,29,31],[28,30,31,29],[36,34,32],[33,35,37],[34,36,37,35],[50,48,46],[47,49,51],[48,50,51,49],[56,54,52],[53,55,57],[54,56,57,55],[62,60,58],[59,61,63],[60,62,63,61],[76,74,72],[73,75,77],[74,76,77,75],[82,80,78],[79,81,83],[80,82,83,81],[88,86,84],[85,87,89],[86,88,89,87],[102,100,98],[99,101,103],[100,102,103,101],[108,106,104],[105,107,109],[106,108,109,107],[114,112,110],[111,113,115],[112,114,115,113],[0,6,8,4],[5,9,7,1],[4,8,9,5],[6,12,14,10],[11,15,13,7],[10,14,15,11],[12,16,18,14],[15,19,17,13],[14,18,19,15],[16,20,22,18],[19,23,21,17],[18,22,23,19],[20,26,28,24],[25,29,27,21],[24,28,29,25],[26,32,34,30],[31,35,33,27],[30,34,35,31],[32,38,40,36],[37,41,39,33],[36,40,41,37],[38,42,44,40],[41,45,43,39],[40,44,45,41],[42,46,48,44],[45,49,47,43],[44,48,49,45],[46,52,54,50],[51,55,53,47],[50,54,55,51],[52,58,60,56],[57,61,59,53],[56,60,61,57],[58,64,66,62],[63,67,65,59],[62,66,67,63],[64,68,70,66],[67,71,69,65],[66,70,71,67],[68,72,74,70],[71,75,73,69],[70,74,75,71],[72,78,80,76],[77,81,79,73],[76,80,81,77],[78,84,86,82],[83,87,85,79],[82,86,87,83],[84,90,92,88],[89,93,91,85],[88,92,93,89],[90,94,96,92],[93,97,95,91],[92,96,97,93],[94,98,100,96],[97,101,99,95],[96,100,101,97],[98,104,106,102],[103,107,105,99],[102,106,107,103],[104,110,112,108],[109,113,111,105],[108,112,113,109],[110,116,118,114],[115,119,117,111],[114,118,119,115],[116,120,122,118],[119,123,121,117],[118,122,123,119],[120,0,2,122],[123,3,1,121],[122,2,3,123]]);
translate([20+ER+HG,50-ER-HG,0+ER+HG]) sphere(ER); translate([20+ER+HG,50-ER-HG,10-ER-HG]) sphere(ER);
translate([20+ER+HG,50-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([20+ER+HG,50-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(30-20-ER-HG-ER-HG,ER,ER);
translate([20+ER+HG,50-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(30-20-ER-HG-ER-HG,ER,ER);
translate([30-ER-HG,50-ER-HG,0+ER+HG]) sphere(ER); translate([30-ER-HG,50-ER-HG,10-ER-HG]) sphere(ER);
translate([30-ER-HG,50-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([30-ER-HG,30-ER-HG,0+ER+HG]) rotate([-90,0,0]) cylinder(50-30-ER-HG+ER+HG,ER,ER);
translate([30-ER-HG,30-ER-HG,10-ER-HG]) rotate([-90,0,0]) cylinder(50-30-ER-HG+ER+HG,ER,ER);
translate([30-ER-HG,30-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(40-30+ER+HG+ER+HG,ER,ER);
translate([30-ER-HG,30-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(40-30+ER+HG+ER+HG,ER,ER);
translate([40+ER+HG,30-ER-HG,0+ER+HG]) rotate([-90,0,0]) cylinder(40-30+ER+HG-ER-HG,ER,ER);
translate([40+ER+HG,30-ER-HG,10-ER-HG]) rotate([-90,0,0]) cylinder(40-30+ER+HG-ER-HG,ER,ER);
translate([40+ER+HG,40-ER-HG,0+ER+HG]) sphere(ER); translate([40+ER+HG,40-ER-HG,10-ER-HG]) sphere(ER);
translate([40+ER+HG,40-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([40+ER+HG,40-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(50-40-ER-HG-ER-HG,ER,ER);
translate([40+ER+HG,40-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(50-40-ER-HG-ER-HG,ER,ER);
translate([50-ER-HG,40-ER-HG,0+ER+HG]) sphere(ER); translate([50-ER-HG,40-ER-HG,10-ER-HG]) sphere(ER);
translate([50-ER-HG,40-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([50-ER-HG,20+ER+HG,0+ER+HG]) rotate([-90,0,0]) cylinder(40-20-ER-HG-ER-HG,ER,ER);
translate([50-ER-HG,20+ER+HG,10-ER-HG]) rotate([-90,0,0]) cylinder(40-20-ER-HG-ER-HG,ER,ER);
translate([50-ER-HG,20+ER+HG,0+ER+HG]) sphere(ER); translate([50-ER-HG,20+ER+HG,10-ER-HG]) sphere(ER);
translate([50-ER-HG,20+ER+HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([40-ER-HG,20+ER+HG,0+ER+HG]) rotate([0,90,0]) cylinder(50-40-ER-HG+ER+HG,ER,ER);
translate([40-ER-HG,20+ER+HG,10-ER-HG]) rotate([0,90,0]) cylinder(50-40-ER-HG+ER+HG,ER,ER);
translate([40-ER-HG,10-ER-HG,0+ER+HG]) rotate([-90,0,0]) cylinder(20-10+ER+HG+ER+HG,ER,ER);
translate([40-ER-HG,10-ER-HG,10-ER-HG]) rotate([-90,0,0]) cylinder(20-10+ER+HG+ER+HG,ER,ER);
translate([40-ER-HG,10-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(50-40+ER+HG-ER-HG,ER,ER);
translate([40-ER-HG,10-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(50-40+ER+HG-ER-HG,ER,ER);
translate([50-ER-HG,10-ER-HG,0+ER+HG]) sphere(ER); translate([50-ER-HG,10-ER-HG,10-ER-HG]) sphere(ER);
translate([50-ER-HG,10-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([50-ER-HG,0+ER+HG,0+ER+HG]) rotate([-90,0,0]) cylinder(10-0-ER-HG-ER-HG,ER,ER);
translate([50-ER-HG,0+ER+HG,10-ER-HG]) rotate([-90,0,0]) cylinder(10-0-ER-HG-ER-HG,ER,ER);
translate([50-ER-HG,0+ER+HG,0+ER+HG]) sphere(ER); translate([50-ER-HG,0+ER+HG,10-ER-HG]) sphere(ER);
translate([50-ER-HG,0+ER+HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([30+ER+HG,0+ER+HG,0+ER+HG]) rotate([0,90,0]) cylinder(50-30-ER-HG-ER-HG,ER,ER);
translate([30+ER+HG,0+ER+HG,10-ER-HG]) rotate([0,90,0]) cylinder(50-30-ER-HG-ER-HG,ER,ER);
translate([30+ER+HG,0+ER+HG,0+ER+HG]) sphere(ER); translate([30+ER+HG,0+ER+HG,10-ER-HG]) sphere(ER);
translate([30+ER+HG,0+ER+HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([30+ER+HG,0+ER+HG,0+ER+HG]) rotate([-90,0,0]) cylinder(10-0-ER-HG+ER+HG,ER,ER);
translate([30+ER+HG,0+ER+HG,10-ER-HG]) rotate([-90,0,0]) cylinder(10-0-ER-HG+ER+HG,ER,ER);
translate([20-ER-HG,10+ER+HG,0+ER+HG]) rotate([0,90,0]) cylinder(30-20+ER+HG+ER+HG,ER,ER);
translate([20-ER-HG,10+ER+HG,10-ER-HG]) rotate([0,90,0]) cylinder(30-20+ER+HG+ER+HG,ER,ER);
translate([20-ER-HG,0+ER+HG,0+ER+HG]) rotate([-90,0,0]) cylinder(10-0+ER+HG-ER-HG,ER,ER);
translate([20-ER-HG,0+ER+HG,10-ER-HG]) rotate([-90,0,0]) cylinder(10-0+ER+HG-ER-HG,ER,ER);
translate([20-ER-HG,0+ER+HG,0+ER+HG]) sphere(ER); translate([20-ER-HG,0+ER+HG,10-ER-HG]) sphere(ER);
translate([20-ER-HG,0+ER+HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([0+ER+HG,0+ER+HG,0+ER+HG]) rotate([0,90,0]) cylinder(20-0-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,0+ER+HG,10-ER-HG]) rotate([0,90,0]) cylinder(20-0-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,0+ER+HG,0+ER+HG]) sphere(ER); translate([0+ER+HG,0+ER+HG,10-ER-HG]) sphere(ER);
translate([0+ER+HG,0+ER+HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([0+ER+HG,0+ER+HG,0+ER+HG]) rotate([-90,0,0]) cylinder(10-0-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,0+ER+HG,10-ER-HG]) rotate([-90,0,0]) cylinder(10-0-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,10-ER-HG,0+ER+HG]) sphere(ER); translate([0+ER+HG,10-ER-HG,10-ER-HG]) sphere(ER);
translate([0+ER+HG,10-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([0+ER+HG,10-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(10-0-ER-HG+ER+HG,ER,ER);
translate([0+ER+HG,10-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(10-0-ER-HG+ER+HG,ER,ER);
translate([10+ER+HG,10-ER-HG,0+ER+HG]) rotate([-90,0,0]) cylinder(20-10+ER+HG+ER+HG,ER,ER);
translate([10+ER+HG,10-ER-HG,10-ER-HG]) rotate([-90,0,0]) cylinder(20-10+ER+HG+ER+HG,ER,ER);
translate([0+ER+HG,20+ER+HG,0+ER+HG]) rotate([0,90,0]) cylinder(10-0+ER+HG-ER-HG,ER,ER);
translate([0+ER+HG,20+ER+HG,10-ER-HG]) rotate([0,90,0]) cylinder(10-0+ER+HG-ER-HG,ER,ER);
translate([0+ER+HG,20+ER+HG,0+ER+HG]) sphere(ER); translate([0+ER+HG,20+ER+HG,10-ER-HG]) sphere(ER);
translate([0+ER+HG,20+ER+HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([0+ER+HG,20+ER+HG,0+ER+HG]) rotate([-90,0,0]) cylinder(40-20-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,20+ER+HG,10-ER-HG]) rotate([-90,0,0]) cylinder(40-20-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,40-ER-HG,0+ER+HG]) sphere(ER); translate([0+ER+HG,40-ER-HG,10-ER-HG]) sphere(ER);
translate([0+ER+HG,40-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([0+ER+HG,40-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(10-0-ER-HG-ER-HG,ER,ER);
translate([0+ER+HG,40-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(10-0-ER-HG-ER-HG,ER,ER);
translate([10-ER-HG,40-ER-HG,0+ER+HG]) sphere(ER); translate([10-ER-HG,40-ER-HG,10-ER-HG]) sphere(ER);
translate([10-ER-HG,40-ER-HG,0+ER+HG]) cylinder(10-0-2*ER-2*HG,ER,ER);
translate([10-ER-HG,30-ER-HG,0+ER+HG]) rotate([-90,0,0]) cylinder(40-30-ER-HG+ER+HG,ER,ER);
translate([10-ER-HG,30-ER-HG,10-ER-HG]) rotate([-90,0,0]) cylinder(40-30-ER-HG+ER+HG,ER,ER);
translate([10-ER-HG,30-ER-HG,0+ER+HG]) rotate([0,90,0]) cylinder(20-10+ER+HG+ER+HG,ER,ER);
translate([10-ER-HG,30-ER-HG,10-ER-HG]) rotate([0,90,0]) cylinder(20-10+ER+HG+ER+HG,ER,ER);
translate([20+ER+HG,30-ER-HG,0+ER+HG]) rotate([-90,0,0]) cylinder(50-30+ER+HG-ER-HG,ER,ER);
translate([20+ER+HG,30-ER-HG,10-ER-HG]) rotate([-90,0,0]) cylinder(50-30+ER+HG-ER-HG,ER,ER);
//NbSpheres=28
//NbCylinders=48
//NbPoints=124
//NbFaces=116

4. Choosing ER to have an octogon

Also available as EdgeRadiusForARegularOctogon.pdf