-
Notifications
You must be signed in to change notification settings - Fork 0
/
frep.py
executable file
·103 lines (91 loc) · 2.55 KB
/
frep.py
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python
#
# frep.py
# functional representation solver
#
# usage:
# pcb.py | frep.py [dpi [filename]]
#
# Neil Gershenfeld 9/30/19
# (c) Massachusetts Institute of Technology 2019
#
# Modified by Francisco Sanchez Arroyo 2020
#
# 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
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 100 DPI')
filename = 'out.png'
dpi = 100
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)
#
# evaluate
#
print('evaluating')
xmin = frep['xmin']
xmax = frep['xmax']
ymin = frep['ymin']
ymax = frep['ymax']
units = float(frep['mm_per_unit'])
delta = (25.4/dpi)/units
x = arange(xmin,xmax,delta) # arange creates a int32 array by default
y = flip(arange(ymin,ymax,delta),0)
X = outer(ones(y.size),x)
Y = outer(y,ones(x.size))
if (len(frep['layers']) == 1):
Z = frep['layers'][0]
print(" z =",Z)
f = eval(frep['function']).astype(uint32) # evals and stores as 32 bit integer
else:
f = zeros((y.size,x.size),dtype=uint32)
zmin = min(frep['layers'])
zmax = max(frep['layers'])
for Z in frep['layers']:
print(" z =",Z)
i = int(255*(Z-zmin)/(zmax-zmin)) | (255 << 8) | (255 << 16)
flayer = i & (eval(frep['function'])).astype(uint32)
f = f + flayer
#
# construct image
#
# create an array of 3 matrix made of 8 bits unsigned integers, each one y rows and x columns, populate with zeroes (black)
# each matrix holds values or R,G,B. Using channels-last convention
m = zeros((y.size,x.size,3),dtype=uint8)
# put back the 24 bit decimal value to R, G and B channels
# is f made out of zeros and ones?
m[:,:,0] = (f & 255) # Red channel. 255 = 1111 1111 operator & is a mask to get the 8 first bits
m[:,:,1] = ((f >> 8) & 255) # Green
m[:,:,2] = ((f >> 16) & 255) # Blue
# generates a RGB image from the matrix
im = Image.fromarray(m,'RGB')
# save the image, and append the xy dpi values
im.save(filename,dpi=[dpi,dpi])