Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python3
#
# frep-C.py
# functional representation to C++ solver
#
# usage:
# pcb.py | frep-C.py [dpi [filename]]
#
# Neil Gershenfeld 8/23/21
# (c) Massachusetts Institute of Technology 2021
#
# This work may be reproduced, modified, distributed,
# performed, and displayed for any purpose, but must
# acknowledge this project. Copyright is retained and
# must be preserved. The work is provided as is; no
# warranty is provided, and users accept all liability.
#
#
# import
#
import json,sys,os
from numpy import *
from PIL import Image
#
# read input
#
frep = json.load(sys.stdin)
#
# check arguments
#
if (frep['type'] != 'RGB'):
print('types other than RGB not (yet) supported')
sys.exit()
if (len(sys.argv) == 1):
print('output to out.png at 300 DPI')
filename = 'out.png'
dpi = 300
elif (len(sys.argv) == 2):
dpi = sys.argv[1]
filename = 'out.png'
print('output to out.png at '+dpi+'DPI')
dpi = int(dpi)
elif (len(sys.argv) == 3):
dpi = sys.argv[1]
filename = sys.argv[2]
print('output to '+filename+' at '+dpi+' DPI')
dpi = int(dpi)
#
# define variables
#
xmin = frep['xmin']
xmax = frep['xmax']
ymin = frep['ymin']
ymax = frep['ymax']
zmin = min(frep['layers'])
zmax = max(frep['layers'])
units = float(frep['mm_per_unit'])
delta = (25.4/dpi)/units
fn = frep['function']
fn = fn.replace('math.','')
layers = str(frep['layers'][0])
nlayers = len(frep['layers'])
for i in range(1,nlayers):
layers += ','+str(frep['layers'][i])
#
# write program
#
file = open("frep-C.cpp",'w')
file.write(
f"""
#include <iostream>
#include <cmath>
#include <png.h>
using namespace std;
int fn(float X,float Y,float Z) {{
return ({fn});
}}
int main(int argc, char** argv) {{
float xmin = {xmin};
float xmax = {xmax};
float ymin = {ymin};
float ymax = {ymax};
float zmin = {zmin};
float zmax = {zmax};
float units = {units};
int dpi = {dpi};
float delta = (25.4/dpi)/units;
int nx = (xmax-xmin)/delta;
int ny = (ymax-ymin)/delta;
int *m = (int*) calloc(nx*ny,sizeof(int));
float layers[] = {{{layers}}};
int intensity;
for (int layer = 0; layer < {nlayers}; ++layer) {{
float z = layers[layer];
cout << " z =" << z << endl;
if (zmin == zmax)
intensity = 0xFFFFFF;
else
intensity = ((int) (255*(z-zmin)/(zmax-zmin))) | (255 << 8) | (255 << 16);
for (int iy = 0; iy < ny; ++iy) {{
float y = ymin+iy*delta;
for (int ix = 0; ix < nx; ++ix) {{
float x = xmin+ix*delta;
m[iy*nx+ix] += intensity & fn(x,y,z);
}}
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
}}
}}
FILE *file;
file = fopen("{filename}","wb");
png_structp pngfile;
png_infop pnginfo;
png_bytep pngrow;
pngfile = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
pnginfo = png_create_info_struct(pngfile);
png_init_io(pngfile,file);
png_set_IHDR(pngfile,pnginfo,nx,ny,
8,PNG_COLOR_TYPE_RGBA,PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE,PNG_FILTER_TYPE_BASE);
png_set_pHYs(pngfile,pnginfo,{1000*dpi/25.4},{1000*dpi/25.4},PNG_RESOLUTION_METER);
png_write_info(pngfile,pnginfo);
pngrow = (png_bytep) malloc(4*nx*sizeof(png_byte));
for (int iy = (ny-1); iy >= 0; --iy) {{
for (int ix = 0; ix < nx; ++ix) {{
pngrow[4*ix] = m[iy*nx+ix] & 255;
pngrow[4*ix+1] = (m[iy*nx+ix] >> 8) & 255;
pngrow[4*ix+2] = (m[iy*nx+ix] >> 16) & 255;
pngrow[4*ix+3] = 255;
}}
png_write_row(pngfile,pngrow);
}}
png_write_end(pngfile,NULL);
fclose(file);
}}
""")
file.close()
#
# compile
#
print("compile ...")
os.system("time g++ frep-C.cpp -o frep-C -lm -lpng -O -ffast-math")
#
# execute
#
print("execute ...")
os.system("time ./frep-C")
#
# clean up
#
os.system("rm -f frep-C.cpp frep-C")