chiark / gitweb /
Update on the 3D window, now with nice icons. Also added some more error logging...
[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                         print position
63                         print profile.getAlterationFileContents('nextobject.gcode')
64                         resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
65
66                 output = []
67                 for filename in filenames:
68                         extruderNr = filenames.index(filename)
69                         profile.resetTempOverride()
70                         if extruderNr > 0:
71                                 profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)))
72                                 profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)))
73                                 profile.setTempOverride('fan_enabled', 'False')
74                                 profile.setTempOverride('skirt_line_count', '0')
75                                 profile.setTempOverride('alternative_center', filenames[0])
76                         else:
77                                 profile.setTempOverride('object_center_x', position[0])
78                                 profile.setTempOverride('object_center_y', position[1])
79                         profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11])))
80                         output.append(export.getOutput(filename))
81                         profile.resetTempOverride()
82                 if len(output) == 1:
83                         resultFile.write(output[0])
84                 else:
85                         stitchMultiExtruder(output, resultFile)
86         resultFile.write(';TYPE:CUSTOM\n')
87         resultFile.write(profile.getAlterationFileContents('end.gcode'))
88         resultFile.close()
89
90         print "Running plugins"
91         ret = profile.runPostProcessingPlugins(options.output)
92         if ret is not None:
93                 print ret
94         print "Finalizing %s" % (os.path.basename(options.output))
95         if profile.getPreference('submit_slice_information') == 'True':
96                 filenames = fixUTF8(args[idx + 1]).split('|')
97                 for filename in filenames:
98                         m = hashlib.sha512()
99                         f = open(filename, "rb")
100                         while True:
101                                 chunk = f.read(1024)
102                                 if not chunk:
103                                         break
104                                 m.update(chunk)
105                         f.close()
106                         data = {
107                                 'processor': platform.processor(),
108                                 'machine': platform.machine(),
109                                 'platform': platform.platform(),
110                                 'profile': profile.getGlobalProfileString(),
111                                 'modelhash': m.hexdigest(),
112                         }
113                         try:
114                                 f = urllib2.urlopen("http://software.ultimaker.com/upload_stats.php", data = urllib.urlencode(data), timeout = 5);
115                                 f.read()
116                                 f.close()
117                         except:
118                                 pass
119
120
121 def stitchMultiExtruder(outputList, resultFile):
122         print "Stitching %i files for multi-extrusion" % (len(outputList))
123         currentExtruder = 0
124         resultFile.write('T%d\n' % (currentExtruder))
125         layerNr = -1
126         hasLine = True
127         outputList = map(lambda o: o.split('\n'), outputList)
128         outputOrder = range(0, len(outputList))
129         while hasLine:
130                 hasLine = False
131                 outputOrder.reverse()
132                 for outputIdx in outputOrder:
133                         layerHasLine = False
134                         while len(outputList[outputIdx]) > 0:
135                                 line = outputList[outputIdx].pop(0)
136                                 hasLine = True
137                                 if line.startswith(';LAYER:'):
138                                         break
139                                 if 'Z' in line:
140                                         lastZ = float(re.search('Z([^\s]+)', line).group(1))
141                                 if not layerHasLine:
142                                         nextExtruder = outputIdx
143                                         resultFile.write(';LAYER:%d\n' % (layerNr))
144                                         resultFile.write(';EXTRUDER:%d\n' % (nextExtruder))
145                                         if nextExtruder != currentExtruder:
146                                                 resultFile.write(';TYPE:CUSTOM\n')
147                                                 profile.setTempOverride('extruder', nextExtruder)
148                                                 resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n')
149                                                 profile.resetTempOverride()
150                                                 currentExtruder = nextExtruder
151                                         layerHasLine = True
152                                 resultFile.write(line)
153                                 resultFile.write('\n')
154                 layerNr += 1
155
156 if __name__ == '__main__':
157         main()