1 from __future__ import absolute_import
3 from optparse import OptionParser
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)
17 from Cura.util import profile
18 from Cura.util import version
19 from Cura.slice.cura_sf.skeinforge_application.skeinforge_plugins.craft_plugins import export
22 if input.startswith('#UTF8#'):
23 return input[6:].decode('utf-8')
27 parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
28 parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
29 help="Encoded profile to use for the print")
30 parser.add_option("-o", "--output", action="store", type="string", dest="output",
31 help="Output filename")
32 (options, args) = parser.parse_args()
33 if options.output is None:
34 print 'Missing output filename'
36 if options.profile is not None:
37 profile.loadGlobalProfileFromString(options.profile)
38 options.output = fixUTF8(options.output)
41 resultFile = open(options.output, "w")
42 for idx in xrange(0, len(args), 2):
43 position = map(float, args[idx].split(','))
44 if len(position) < 9 + 2:
45 position = position[0:2]
49 filenames = fixUTF8(args[idx + 1]).split('|')
51 profile.setTempOverride('object_center_x', position[0])
52 profile.setTempOverride('object_center_y', position[1])
54 resultFile.write(';TYPE:CUSTOM\n')
55 resultFile.write(profile.getAlterationFileContents('start.gcode', len(filenames)).replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
57 resultFile.write(';TYPE:CUSTOM\n')
58 n = output[-1].rfind('Z')+1
59 zString = output[-1][n:n+20]
60 zString = zString[0:zString.find(' ')]
61 clearZ = max(clearZ, float(zString) + 10)
62 profile.setTempOverride('clear_z', clearZ)
64 print profile.getAlterationFileContents('nextobject.gcode')
65 resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
68 for filename in filenames:
69 extruderNr = filenames.index(filename)
70 profile.resetTempOverride()
72 profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)))
73 profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)))
74 profile.setTempOverride('fan_enabled', 'False')
75 profile.setTempOverride('skirt_line_count', '0')
76 profile.setTempOverride('alternative_center', filenames[0])
78 profile.setTempOverride('object_center_x', position[0])
79 profile.setTempOverride('object_center_y', position[1])
80 profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11])))
82 if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0:
83 profile.setTempOverride('filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1)))
84 print extruderNr, profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)), profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))
85 output.append(export.getOutput(filename))
86 profile.resetTempOverride()
88 resultFile.write(output[0])
90 stitchMultiExtruder(output, resultFile)
91 resultFile.write(';TYPE:CUSTOM\n')
92 resultFile.write(profile.getAlterationFileContents('end.gcode'))
95 print "Running plugins"
96 ret = profile.runPostProcessingPlugins(options.output)
99 print "Finalizing %s" % (os.path.basename(options.output))
100 if profile.getPreference('submit_slice_information') == 'True':
101 filenames = fixUTF8(args[idx + 1]).split('|')
102 for filename in filenames:
104 f = open(filename, "rb")
112 'processor': platform.processor(),
113 'machine': platform.machine(),
114 'platform': platform.platform(),
115 'profile': profile.getGlobalProfileString(),
116 'preferences': profile.getGlobalPreferencesString(),
117 'modelhash': m.hexdigest(),
118 'version': version.getVersion(),
121 f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data = urllib.urlencode(data), timeout = 5);
128 def isPrintingLine(line):
129 if line.startswith("G1") and ('X' in line or 'Y' in line) and 'E' in line:
133 def getCodeFloat(line, code, default):
134 n = line.find(code) + 1
137 m = line.find(' ', n)
140 return float(line[n:])
141 return float(line[n:m])
145 def stitchMultiExtruder(outputList, resultFile):
146 print "Stitching %i files for multi-extrusion" % (len(outputList))
148 resultFile.write('T%d\n' % (currentExtruder))
151 outputList = map(lambda o: o.split('\n'), outputList)
152 outputOrder = range(0, len(outputList))
154 for n in xrange(0, len(outputList)):
155 outputSlice.append([0, 0])
161 hasLine = layerNr < 1000
162 for n in xrange(0, len(outputList)):
163 outputSlice[n][0] = outputSlice[n][1] + 1
164 outputSlice[n][1] = outputSlice[n][0]
165 while outputSlice[n][1] < len(outputList[n]) and not outputList[n][outputSlice[n][1]].startswith(';LAYER:'):
166 outputSlice[n][1] += 1
167 outputOrder = range(currentExtruder, len(outputList)) + range(0, currentExtruder)
168 for n in outputOrder:
169 if outputSlice[n][1] > outputSlice[n][0] + 1:
171 resultFile.write(';LAYER:%d\n' % (layerNr))
172 resultFile.write(';EXTRUDER:%d\n' % (nextExtruder))
174 startSlice = outputSlice[n][0]
175 endSlice = outputSlice[n][1]
177 while not isPrintingLine(outputList[n][startSlice]):
178 currentE = getCodeFloat(outputList[n][startSlice], 'E', currentE)
179 currentX = getCodeFloat(outputList[n][startSlice], 'X', currentX)
180 currentY = getCodeFloat(outputList[n][startSlice], 'Y', currentY)
181 currentZ = getCodeFloat(outputList[n][startSlice], 'Z', currentZ)
182 currentF = getCodeFloat(outputList[n][startSlice], 'F', currentF)
184 while not isPrintingLine(outputList[n][endSlice-1]):
187 if nextExtruder != currentExtruder:
188 profile.setTempOverride('extruder', nextExtruder)
189 profile.setTempOverride('new_x', currentX)
190 profile.setTempOverride('new_y', currentY)
191 profile.setTempOverride('new_z', currentZ)
192 resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n')
193 profile.resetTempOverride()
194 currentExtruder = nextExtruder
196 for idx in xrange(outputSlice[n][0], startSlice):
197 if not 'G1' in outputList[n][idx]:
198 resultFile.write(outputList[n][idx])
199 resultFile.write('\n')
201 resultFile.write('G1 X%f Y%f Z%f F%f\n' % (currentX, currentY, currentZ, profile.getProfileSettingFloat('travel_speed') * 60))
202 resultFile.write('G1 F%f\n' % (currentF))
203 resultFile.write('G92 E%f\n' % (currentE))
204 for idx in xrange(startSlice, endSlice):
205 resultFile.write(outputList[n][idx])
206 resultFile.write('\n')
207 currentX = getCodeFloat(outputList[n][idx], 'X', currentX)
208 currentY = getCodeFloat(outputList[n][idx], 'Y', currentY)
209 currentZ = getCodeFloat(outputList[n][idx], 'Z', currentZ)
211 resultFile.write('G92 E0\n')
214 if __name__ == '__main__':