24 """ |
24 """ |
25 def __init__(self, cylinders, space_min=10): |
25 def __init__(self, cylinders, space_min=10): |
26 self.cylinders = cylinders |
26 self.cylinders = cylinders |
27 self.space_min = space_min |
27 self.space_min = space_min |
28 self.font = FONTBASE + "arial.ttf" |
28 self.font = FONTBASE + "arial.ttf" |
29 self.scad = "// Color support only in compile mode (F5)\n" |
29 self.width = 0 # will be calculated |
|
30 self.scad = { |
|
31 "tmpl": """// Color support only in compile mode (F5) |
|
32 // cylindertransport.py OpenSCAD script |
|
33 module tank(x, r, h) { |
|
34 color("SteelBlue") render() { //rotate([90,0,0]) { |
|
35 translate([x, r, r]) { |
|
36 sphere(r = r); // bottom |
|
37 cylinder(h = h-2*r, r = r); |
|
38 } |
|
39 translate([x, r, h-r]) { |
|
40 sphere(r = r); // top |
|
41 cylinder(h = r*1.4, r = r*0.25); |
|
42 } |
|
43 } |
|
44 } |
|
45 |
|
46 module spacer(x, r, rcyl, h) { |
|
47 color("DarkGrey") render() { //rotate([90,0,0]) { |
|
48 translate([x, r, rcyl]) { |
|
49 difference() { |
|
50 cylinder(h = h-2*rcyl, r = r); |
|
51 cylinder(h = h-2*rcyl, r = r*0.8); |
|
52 } |
|
53 } |
|
54 } |
|
55 } |
|
56 $fn = 10; |
|
57 """, |
|
58 "spacer": "", |
|
59 "cylinder": "" |
|
60 } |
30 self.circles = [] |
61 self.circles = [] |
31 self.spacings = [] |
62 self.spacings = [] |
32 self.margin = 20 |
63 self.margin = 20 |
|
64 self.scale3d = 0.1 |
33 |
65 |
34 def calc_min(self, r_1, r_2): |
66 def calc_min(self, r_1, r_2): |
35 """ |
67 """ |
36 stupider annaehreungsversuch, bis sich die beiden |
68 stupider annaehreungsversuch, bis sich die beiden |
37 Tauchflaschen r_1 und r_2 nicht mehr beruehren |
69 Tauchflaschen r_1 und r_2 nicht mehr beruehren |
65 r_1 = CYLINDER[self.cylinders[0]][0] / 2 |
97 r_1 = CYLINDER[self.cylinders[0]][0] / 2 |
66 r_2 = CYLINDER[self.cylinders[1]][0] / 2 |
98 r_2 = CYLINDER[self.cylinders[1]][0] / 2 |
67 r_1, r_2, r_3, label = self.calc_min(r_1, r_2) |
99 r_1, r_2, r_3, label = self.calc_min(r_1, r_2) |
68 posx = self.margin + r_2 # start offset x |
100 posx = self.margin + r_2 # start offset x |
69 self._circle(posx, r_2, label, 0.5) |
101 self._circle(posx, r_2, label, 0.5) |
70 self.scad += "spacer(%i, %i, %i, %i);\n" % ( |
102 self.scad["spacer"] += "spacer(%f, %f, %f, %f);\n" % ( |
71 posx, r_2, r_3, CYLINDER[self.cylinders[0]][1]) |
103 posx * self.scale3d, r_2 * self.scale3d, r_3 * self.scale3d, |
|
104 CYLINDER[self.cylinders[0]][1] * self.scale3d) |
72 posx += offset(r_2, r_3) |
105 posx += offset(r_2, r_3) |
73 |
106 |
74 for i in range(0, len(self.cylinders) - 1): |
107 for i in range(0, len(self.cylinders) - 1): |
75 r_1 = CYLINDER[self.cylinders[i]][0] / 2 |
108 r_1 = CYLINDER[self.cylinders[i]][0] / 2 |
76 r_2 = CYLINDER[self.cylinders[i+1]][0] / 2 |
109 r_2 = CYLINDER[self.cylinders[i+1]][0] / 2 |
77 r_1, r_2, r_3, label = self.calc_min(r_1, r_2) |
110 r_1, r_2, r_3, label = self.calc_min(r_1, r_2) |
78 # draw cylinder |
111 # draw cylinder |
79 self._circle(posx, r_1, "Tank " + self.cylinders[i]) |
112 self._circle(posx, r_1, "Tank " + self.cylinders[i]) |
80 self.scad += "tank(%i, %i, %i);\n" % ( |
113 self.scad["cylinder"] += "tank(%f, %f, %f);\n" % ( |
81 posx, r_1, CYLINDER[self.cylinders[i]][1]) |
114 posx * self.scale3d, r_1 * self.scale3d, |
|
115 CYLINDER[self.cylinders[i]][1] * self.scale3d) |
82 sx1 = posx + r_1 |
116 sx1 = posx + r_1 |
83 posx += offset(r_1, r_2) |
117 posx += offset(r_1, r_2) |
84 # draw right spacer |
118 # draw right spacer |
85 self._circle(posx, r_2, label, 0.5) |
119 self._circle(posx, r_2, label, 0.5) |
86 self.scad += "spacer(%i, %i, %i, %i);\n" % ( |
120 self.scad["spacer"] += "spacer(%f, %f, %f, %f);\n" % ( |
87 posx, r_2, r_1, CYLINDER[self.cylinders[i]][1]) |
121 posx * self.scale3d, r_2 * self.scale3d, r_1 * self.scale3d, |
|
122 CYLINDER[self.cylinders[i]][1] * self.scale3d) |
88 posx += offset(r_2, r_3) |
123 posx += offset(r_2, r_3) |
89 sx2 = posx - r_3 |
124 sx2 = posx - r_3 |
90 if i == (len(self.cylinders) - 2): |
125 if i == (len(self.cylinders) - 2): |
91 # draw last bottle |
126 # draw last bottle |
92 self._circle(posx, r_3, "Tank " + self.cylinders[i + 1]) |
127 self._circle(posx, r_3, "Tank " + self.cylinders[i + 1]) |
93 self.scad += "tank(%i, %i, %i);\n" % ( |
128 self.scad["cylinder"] += "tank(%f, %f, %f);\n" % ( |
94 posx, r_3, CYLINDER[self.cylinders[i + 1]][1]) |
129 posx * self.scale3d, r_3 * self.scale3d, |
|
130 CYLINDER[self.cylinders[i + 1]][1] * self.scale3d) |
95 posx += offset(r_2, r_3) |
131 posx += offset(r_2, r_3) |
96 |
132 |
97 self.spacings.append([sx1, sx2]) |
133 self.spacings.append([sx1, sx2]) |
98 |
134 |
99 # last bottle spacer pipe |
135 # last bottle spacer pipe |
100 self._circle(posx, r_2, label, 0.5) |
136 self._circle(posx, r_2, label, 0.5) |
101 self.scad += "spacer(%i, %i, %i, %i);\n" % ( |
137 self.scad["spacer"] += "spacer(%f, %f, %f, %f);\n" % ( |
102 posx, r_2, r_3, CYLINDER[self.cylinders[-1]][1]) |
138 posx * self.scale3d, r_2 * self.scale3d, r_3 * self.scale3d, |
|
139 CYLINDER[self.cylinders[-1]][1] * self.scale3d) |
103 return int(posx + r_2 + self.margin) |
140 return int(posx + r_2 + self.margin) |
104 |
141 |
105 def centertext(self, draw, posx, posy, txt, size): |
142 def centertext(self, draw, posx, posy, txt, size): |
106 """ |
143 """ |
107 Centers text at position horizontally and vertically |
144 Centers text at position horizontally and vertically |
113 |
150 |
114 def render_image(self): |
151 def render_image(self): |
115 """ |
152 """ |
116 Start the calculation and return rendered PIL image object |
153 Start the calculation and return rendered PIL image object |
117 """ |
154 """ |
118 width = self._calculate() |
155 self.width = self._calculate() |
119 image = Image.new('1', (width, 250)) # create new image |
156 image = Image.new('1', (self.width, 250)) # create new image |
120 draw = ImageDraw.Draw(image) |
157 draw = ImageDraw.Draw(image) |
121 # draw calculated circles |
158 # draw calculated circles |
122 for posx, radius, txt, size in self.circles: |
159 for posx, radius, txt, size in self.circles: |
123 draw.arc([posx - radius, self.margin, \ |
160 draw.arc([posx - radius, self.margin, \ |
124 posx + radius, 2 * radius + self.margin], \ |
161 posx + radius, 2 * radius + self.margin], \ |
166 img = worker.render_image() |
203 img = worker.render_image() |
167 img.show() |
204 img.show() |
168 |
205 |
169 if (options.scad != ""): |
206 if (options.scad != ""): |
170 with open(options.scad, "w") as fd: |
207 with open(options.scad, "w") as fd: |
171 fd.write("""// cylindertransport.py OpenSCAD script |
208 fd.write(worker.scad["tmpl"]) |
172 module tank(x, r, h) { |
209 fd.write("translate([%f,0,0]) {\n" % (((worker.width - 2 * worker.margin) / -2)*worker.scale3d)) # center the object |
173 cap = r; |
210 fd.write(worker.scad["cylinder"]) |
174 color("SteelBlue") render() rotate([90,0,0]) { |
211 fd.write(worker.scad["spacer"]) |
175 translate([x, r, cap]) { |
212 fd.write("}\n") |
176 sphere(r = r); // bottom |
|
177 cylinder(h = h-2*cap, r = r); |
|
178 } |
|
179 translate([x, r, h-cap]) { |
|
180 sphere(r = r); // top |
|
181 cylinder(h = 30+cap, r = 25); |
|
182 } |
|
183 } |
|
184 } |
|
185 |
|
186 module spacer(x, r, rcylinder, h) { |
|
187 cap = rcylinder; |
|
188 |
|
189 color("DarkGrey") render() rotate([90,0,0]) |
|
190 translate([x, r, cap]) { |
|
191 difference() { |
|
192 cylinder(h = h-2*cap, r = r); |
|
193 cylinder(h = h-2*cap, r = r-5); |
|
194 } |
|
195 } |
|
196 } |
|
197 $fn = 20;\n""") |
|
198 fd.write(worker.scad) |
|
199 |
213 |
200 if __name__ == "__main__": |
214 if __name__ == "__main__": |
201 run() |
215 run() |