chiark / gitweb /
66f20db12e9bcab3556cbf4e8274a0224bc959cc
[cura.git] / Cura / slice / __main__.py
1 from __future__ import absolute_import
2
3 from optparse import OptionParser
4 import sys
5 import re
6 import os
7 import urllib
8 import urllib2
9 import platform
10 import hashlib
11
12 if not hasattr(sys, 'frozen'):
13         cura_sf_path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "./cura_sf/"))
14         if cura_sf_path not in sys.path:
15                 sys.path.append(cura_sf_path)
16
17 from Cura.util import profile
18 from Cura.slice.cura_sf.skeinforge_application.skeinforge_plugins.craft_plugins import export
19
20 def fixUTF8(input):
21         if input.startswith('#UTF8#'):
22                 return input[6:].decode('utf-8')
23         return input
24
25 def main():
26         parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
27         parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
28                                           help="Encoded profile to use for the print")
29         parser.add_option("-o", "--output", action="store", type="string", dest="output",
30                                           help="Output filename")
31         (options, args) = parser.parse_args()
32         if options.output is None:
33                 print 'Missing output filename'
34                 sys.exit(1)
35         if options.profile is not None:
36                 profile.loadGlobalProfileFromString(options.profile)
37         options.output = fixUTF8(options.output)
38
39         clearZ = 0
40         resultFile = open(options.output, "w")
41         for idx in xrange(0, len(args), 2):
42                 position = map(float, args[idx].split(','))
43                 if len(position) < 9 + 2:
44                         position = position[0:2]
45                         position += [1,0,0]
46                         position += [0,1,0]
47                         position += [0,0,1]
48                 filenames = fixUTF8(args[idx + 1]).split('|')
49
50                 profile.setTempOverride('object_center_x', position[0])
51                 profile.setTempOverride('object_center_y', position[1])
52                 if idx == 0:
53                         resultFile.write(';TYPE:CUSTOM\n')
54                         resultFile.write(profile.getAlterationFileContents('start.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
55                 else:
56                         resultFile.write(';TYPE:CUSTOM\n')
57                         n = output[-1].rfind('Z')+1
58                         zString = output[-1][n:n+20]
59                         zString = zString[0:zString.find(' ')]
60                         clearZ = max(clearZ, float(zString) + 10)
61                         profile.setTempOverride('clear_z', clearZ)
62                         resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
63
64                 output = []
65                 for filename in filenames:
66                         extruderNr = filenames.index(filename)
67                         profile.resetTempOverride()
68                         if extruderNr > 0:
69                                 profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)))
70                                 profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)))
71                                 profile.setTempOverride('fan_enabled', 'False')
72                                 profile.setTempOverride('skirt_line_count', '0')
73                                 profile.setTempOverride('alternative_center', filenames[0])
74                         else:
75                                 profile.setTempOverride('object_center_x', position[0])
76                                 profile.setTempOverride('object_center_y', position[1])
77                         profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11])))
78                         output.append(export.getOutput(filename))
79                         profile.resetTempOverride()
80                 if len(output) == 1:
81                         resultFile.write(output[0])
82                 else:
83                         stitchMultiExtruder(output, resultFile)
84         resultFile.write(';TYPE:CUSTOM\n')
85         resultFile.write(profile.getAlterationFileContents('end.gcode'))
86         resultFile.close()
87
88         print "Running plugins"
89         ret = profile.runPostProcessingPlugins(options.output)
90         if ret is not None:
91                 print ret
92         print "Finalizing %s" % (os.path.basename(options.output))
93         if profile.getPreference('submit_slice_information') == 'True':
94                 filenames = fixUTF8(args[idx + 1]).split('|')
95                 for filename in filenames:
96                         m = hashlib.sha512()
97                         f = open(filename, "rb")
98                         while True:
99                                 chunk = f.read(1024)
100                                 if not chunk:
101                                         break
102                                 m.update(chunk)
103                         f.close()
104                         data = {
105                                 'processor': platform.processor(),
106                                 'machine': platform.machine(),
107                                 'platform': platform.platform(),
108                                 'profile': profile.getGlobalProfileString(),
109                                 'modelhash': m.hexdigest(),
110                         }
111                         try:
112                                 f = urllib2.urlopen("http://software.ultimaker.com/upload_stats.php", data = urllib.urlencode(data), timeout = 5);
113                                 f.read()
114                                 f.close()
115                         except:
116                                 pass
117
118
119 def stitchMultiExtruder(outputList, resultFile):
120         print "Stitching %i files for multi-extrusion" % (len(outputList))
121         currentExtruder = 0
122         resultFile.write('T%d\n' % (currentExtruder))
123         layerNr = -1
124         hasLine = True
125         outputList = map(lambda o: o.split('\n'), outputList)
126         outputOrder = range(0, len(outputList))
127         while hasLine:
128                 hasLine = False
129                 outputOrder.reverse()
130                 for outputIdx in outputOrder:
131                         layerHasLine = False
132                         while len(outputList[outputIdx]) > 0:
133                                 line = outputList[outputIdx].pop(0)
134                                 hasLine = True
135                                 if line.startswith(';LAYER:'):
136                                         break
137                                 if 'Z' in line:
138                                         lastZ = float(re.search('Z([^\s]+)', line).group(1))
139                                 if not layerHasLine:
140                                         nextExtruder = outputIdx
141                                         resultFile.write(';LAYER:%d\n' % (layerNr))
142                                         resultFile.write(';EXTRUDER:%d\n' % (nextExtruder))
143                                         if nextExtruder != currentExtruder:
144                                                 resultFile.write(';TYPE:CUSTOM\n')
145                                                 profile.setTempOverride('extruder', nextExtruder)
146                                                 resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n')
147                                                 profile.resetTempOverride()
148                                                 currentExtruder = nextExtruder
149                                         layerHasLine = True
150                                 resultFile.write(line)
151                                 resultFile.write('\n')
152                 layerNr += 1
153
154 if __name__ == '__main__':
155         main()