#!/usr/bin/python # -*- coding: utf-8 -*- #################################################################################### # 3D-printing transparent "shades" for the workshop # # Ver = "1.0"; Date = "2016-11-19" # Initial version # Ver = "1.01"; Date = "2016-11-21" # Parameters updated # Ver = "1.02"; Date = "2016-11-22" # Parameters updated Ver = "1.1"; Date = "2016-12-1" # CGI version # # Copyright (C) 2016 by Yasusi Kanada #################################################################################### import cgi import draw3dp, copy, sys from math import sin, cos, sqrt, asin, log ## Mathematical constants ## PI = 3.14159265359 ## Extrusion parameters ## defaultCrossSection = 0.20 # Kossel # defaultCrossSection = 0.42 # Rostock thickCrossSection = 0.20 # Kossel FilamentDiameter = 1.75 # FilamentDiameter = 3.00 ## Default velocity ## DefaultVelocity = 40 / 1.3 ## Temperature parameters ## HeadTemperature = 250 HeadTemperature1 = 225 HeadTemperature2 = 205 BedTemperature = 32 ### # Thickness modulation function ### # def modulate(theta, phi, thetaFac, thetaFac2, phiFac, cosFac, div): if (thetaFac * theta + phiFac * phi + \ cosFac * cos(PI / 45 * (thetaFac2 * theta + phiFac * phi))) % div > (div / 2): c = 0.75 else: c = 1.4 # print('; c={} thetaFac={} thetaFac2={} phiFac={} cosFac={} div={}'.\ # format(c, thetaFac, thetaFac2, phiFac, cosFac, div)) return c ### # Seletion of shade type # def get_selection(): print('''Select shade type:













''') ### # Input shade parameters # def get_parameters(form): print('''Input parameters:

e.g.,''') if form["type"].value == '2002' or form["type"].value == '1002': print(''' 4: 16: 96: ''') elif form["type"].value == '2003' or form["type"].value == '1003': print(''' 4: 16: 96: ''') elif form["type"].value == '2004' or form["type"].value == '1004': print(''' 8: 24: 96: ''') elif form["type"].value == '1005' or form["type"].value == '3005': print(''' 16: 64: ''') elif form["type"].value == '2006' or form["type"].value == '1006' or \ form["type"].value == '2007' or form["type"].value == '1007': print(''' 4: 8: 16: ''') else: # form["type"].value == '2005' etc. print(''' 4: 16: 64: ''') print('''
''') ### # Print skirt # def skirt(obj, size = 20, z = 0.4): obj.comment("skirt") obj.lineto(-size, size, z) obj.lineto( size, size, z) obj.lineto( size, -size, z) obj.lineto(-size, -size, z) obj.lineto( size, size, z) obj.lineto( 0, size, z) obj.lineto( 0, -size, z) obj.lineto( size, -size, z) obj.lineto(-size, size, z) obj.lineto(-size, 0, z) obj.lineto( size, 0, z) obj.moveto(0, 0, z) return ### # Generate G-code def gen_gcode(form): case = int(form["type"].value) # 1000 (modulation = 1) -- Modulation only # 1002, 2002 (Nrep = 6..16, modulation = 0) -- Stripes # # 2002 (Nrep = 6..16, modulation = 1, ...) -- Stripes with modulation # 1003, 2003 (Nrep = 6..16, modulation = 0) -- Stripes (reversed) # # 2003 (Nrep = 6..16, modulation = 1, ...) -- Stripes with modulation # 1004, 2004 (Nrep = 6..16, modulation = 0) -- Mesh # 1005, 2005 (Nrep = 6..16, modulation = 0) -- Analog mesh # 3005 (Nrep = 6..16, modulation = 0) -- Grid # 1006, 2006 (Nrep = 4..16, modulation = 0) -- Circle-like pattern # 1007, 2007 (Nrep = 4..16, modulation = 0) -- Circle-like pattern modulation = int(form["modulation"].value) # Modulation parameters thetaFac = modulation / 10000 % 10 # 0, 1, 2 thetaFac2 = modulation / 1000 % 10 # 0, 1 cosFac = (modulation / 100 % 10) * 15 # 0, 1, 2, 3, 4 phiFac = (modulation / 10 % 10) # 0, 1 div = (modulation % 10 + 1) * 10 # 0, 1, 2, 3 fileName = '{}{}-{}-{}-{}-{}.gcode'.\ format(form["filePrefix"].value, form["type"].value, 0, form["pattern"].value, form["waveCyc"].value, form["waveAmp"].value) # sys.stdout = open(fileName, 'w') print('; Shade for the workshop 2016-12-3') print('; ' + fileName) Nrep = int(form["pattern"].value) # 8, 12, 16 vWaveThetaFac = int(form["waveCyc"].value) # 2, 3, 4, 5 vWaveFac = float(form["waveAmp"].value) # 0 to 15 (0 to 0.0015) rfac = 1 zfac = 1 Steps = 360 VPower = 1.25 # 1.5 2.0 CPower = 1.25 # 1.5 2.0 ## Printbed parameters ## x0 = 0 y0 = 0 ## Main ## draw3dp.init(FilamentDiameter, 250, BedTemperature, DefaultVelocity) sk = draw3dp.Trace(thickCrossSection, 0, 0, 0.2) skirt(sk, 20, 0.1) sk.draw(0.4) obj = draw3dp.Trace(defaultCrossSection, x0, y0, 0.0) radius = 30; height = 3.0 * radius; vpitch = 0.4 #-- w/o hole # radius = 30; height = 2.8 * radius; vpitch = 0.4 #-- with hole # radius = 40; height = 3.0 * radius; vpitch = 0.4 #-- w/o hole # radius = 40; height = 2.8 * radius; vpitch = 0.4 #-- with hole vfacout = 1.2; vfacin = 0.15; cfacout = 0.66; cfacin = 0.28 # 161125 # vfacout = 1.2; vfacin = 0.15; cfacout = 0.60; cfacin = 0.25 # vfacout = 1.2; vfacin = 0.10; cfacout = 0.60; cfacin = 0.25 height1 = 1.5 * radius radius1 = radius + 1 z1 = 1.5 * radius cdfac = 6.0 if case % 1000 == 0: fr = lambda theta, z: 1.0 elif case % 1000 == 2 or case % 1000 == 3:# Reversed distorted bowl sign = -1 if case % 1000 == 2 else 1 thetaFac = Nrep rfac = 0.5 / Nrep zfac = sign * Nrep / 30.0 vfacout = 1.0 + thetaFac / 120.0 # vfacout = 0.8 * vfacout + thetaFac / 200.0 fr = lambda theta, z: 1 + rfac * sin(zfac*z + thetaFac*theta) elif case % 1000 == 4:# Mesh thetaFac = Nrep rfac = 0.03 * (12.0/Nrep)**0.3 zfac = Nrep / 30.0 thetaFac2 = 1 - Nrep / 240.0 vfacout = 0.4 + log(Nrep) / 3.0 if case == 1004: vfacout = 1.0 fr = lambda theta, z: 1.0 + \ (rfac if sin(zfac*z+thetaFac*theta) > thetaFac2 or \ sin(zfac*z-thetaFac*theta) > thetaFac2 \ else 0.0) elif case % 1000 == 5:# Analog "mesh" thetaFac = Nrep rfac = 0.03 * (12.0/Nrep)**0.3 zfac = Nrep / 30.0 if case == 2005: vfacout = 0.7 + log(Nrep) / 8.0 elif case == 1005 or case == 3005: vfacout = 1.1 fr = lambda theta, z: \ 1.0 + rfac * (sin(zfac*z+thetaFac*theta) + sin(zfac*z-thetaFac*theta)) elif case % 1000 == 6 or case % 1000 == 7: # Circle-like pattern (by thickness) thetaFac = Nrep cosFac = Nrep / 30.0 rfac = 0.02 if case == 2006 or case == 2007: vfacout *= 0.9 else: vfacout *= 0.8 if case % 1000 == 6: # amod fr = lambda theta, z: ( 1.0 + (rfac if 10 * abs(cos(thetaFac*theta) * cos(cosFac*z)) % 4 < 1 else 0.0) ) else: # 7 (amod2) fr = lambda theta, z: ( 1.0 + (rfac if 10.5 * abs(cos(thetaFac*theta) * cos(cosFac*z) - 1) % 4 < 1 else 0.0) ) elif case % 1000 == 12:# Sin waved fr = lambda theta, z: \ 4 * (1.05 - sin(0.25*PI+0.2*PI*z/height)) * (1 + rfac * sin(zfac*z + thetaFac*theta)) # 2 * (1.1 - sin(0.25*PI+0.3*PI*z/height)) * (1 + rfac * sin(zfac*z + thetaFac*theta)) x0 = 0; y0 = 0 obj.helix(radius, height, vpitch, x0, y0, 0, minlen=0.2) if modulation != 0: obj.modulate_cylinder(lambda theta, z: modulate(theta * 180 / PI, z - 90, thetaFac, thetaFac2, phiFac, cosFac, div)) vfacout *= 0.8 obj.deform_cylinder( lambda r, theta, z: (r, theta, z + (height - z) * z * cos(vWaveThetaFac * theta) * vWaveFac), lambda v, r, theta, z: v, lambda c, r, theta, z: c) z0 = radius * sin(0.5*PI*z1/height1) + 0.4 if 2000 <= case and case < 3000: obj.deform_cylinder( lambda r, theta, z: (r if r > radius1 else r * cos(0.5*PI*(z-z1)/height1) * fr(theta, z), theta, z if r > radius1 else r * sin(0.5*PI*(z-z1)/height1) + z0), lambda v, r, theta, z: v, lambda c, r, theta, z: c if z > 0.05 * radius else 1.5 * c) elif 1000 <= case and case < 2000: obj.modulate_cylinder(lambda theta, z: 1.25 if fr(theta, z) > 1.0 else 0.85) obj.deform_cylinder( lambda r, theta, z: (r if r > radius1 else r * cos(0.5*PI*(z-z1)/height1), theta, z if r > radius1 else r * sin(0.5*PI*(z-z1)/height1) + z0), lambda v, r, theta, z: v, lambda c, r, theta, z: c if z > 0.05 * radius else 1.5 * c) elif 3000 <= case and case < 4000: obj.modulate_cylinder(lambda theta, z: 1.0 + cdfac * (fr(theta, z) - 1.0)) obj.deform_cylinder( lambda r, theta, z: (r if r > radius1 else r * cos(0.5*PI*(z-z1)/height1), theta, z if r > radius1 else r * sin(0.5*PI*(z-z1)/height1) + z0), lambda v, r, theta, z: v, lambda c, r, theta, z: c if z > 0.05 * radius else 1.5 * c) obj.deform_cylinder_t( lambda r, theta, z: (r, theta, z), lambda v, r, theta, z: (vfacout * (r/radius)**VPower + vfacin * (1 - (r/radius)**VPower)) * v * 1.3, lambda c, r, theta, z: (cfacout * (r/radius)**CPower + cfacin * (1 - (r/radius)**CPower)) * c, lambda t, r, theta, z: \ HeadTemperature2 if r < radius * 0.5 \ else HeadTemperature1 if r < radius * 0.75 else HeadTemperature) obj.draw(minMotion = 0.4) sys.stdout.close() ### Main ### form = cgi.FieldStorage() if form.has_key("phase") and form["phase"].value == 'parameters': print('''Content-Type: text/plain ''') else: print('''Content-Type: text/html 3D-printing-shade workshop

3D-printing-shade workshop

''' + Date + ', ver. ' + Ver + '''

''') if not form.has_key("phase"): # First step get_selection() elif form["phase"].value == 'type': # Second step get_parameters(form) else: # Third step gen_gcode(form) print(''' ''')