def stitchMultiExtruder(outputList, resultFile): print "Stitching %i files for multi-extrusion" % (len(outputList)) currentExtruder = 0 resultFile.write('T%d\n' % (currentExtruder)) layerNr = -1 hasLine = True outputList = map(lambda o: o.split('\n'), outputList) outputOrder = range(0, len(outputList)) while hasLine: hasLine = False outputOrder.reverse() for outputIdx in outputOrder: layerHasLine = False while len(outputList[outputIdx]) > 0: line = outputList[outputIdx].pop(0) hasLine = True if line.startswith(';LAYER:'): break if 'Z' in line: lastZ = float(re.search('Z([^\s]+)', line).group(1)) if not layerHasLine: nextExtruder = outputIdx resultFile.write(';LAYER:%d\n' % (layerNr)) resultFile.write(';EXTRUDER:%d\n' % (nextExtruder)) if nextExtruder != currentExtruder: resultFile.write(';TYPE:CUSTOM\n') profile.setTempOverride('extruder', nextExtruder) resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n') profile.resetTempOverride() currentExtruder = nextExtruder layerHasLine = True resultFile.write(line) resultFile.write('\n') layerNr += 1
def _stitchMultiExtruder(self): files = [] resultFile = open(sliceRun.getExportFilename(self.filelist[0]), "w") resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('start.gcode')) for filename in self.filelist: if os.path.isfile(sliceRun.getExportFilename(filename, 'multi_extrude_tmp')): files.append(open(sliceRun.getExportFilename(filename, 'multi_extrude_tmp'), "r")) else: return currentExtruder = 0 resultFile.write('T%d\n' % (currentExtruder)) layerNr = -1 hasLine = True filesOrder = files[:] while hasLine: hasLine = False filesOrder.reverse() for f in filesOrder: layerHasLine = False for line in f: hasLine = True if line.startswith(';LAYER:'): break if 'Z' in line: lastZ = float(re.search('Z([^\s]+)', line).group(1)) if not layerHasLine: nextExtruder = files.index(f) resultFile.write(';LAYER:%d\n' % (layerNr)) resultFile.write(';EXTRUDER:%d\n' % (nextExtruder)) if nextExtruder != currentExtruder: resultFile.write(';TYPE:CUSTOM\n') profile.setTempOverride('extruder', nextExtruder) resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n') profile.resetTempOverride() currentExtruder = nextExtruder layerHasLine = True resultFile.write(line) layerNr += 1 for f in files: f.close() for filename in self.filelist: os.remove(sliceRun.getExportFilename(filename, 'multi_extrude_tmp')) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close()
def cancelPrint(self): if not self.isPrinting()or self._process is None: return self._process.stdin.write('STOP\n') endgcode = profile.getAlterationFileContents('end.gcode', 1).splitlines() for line in endgcode: if not line.startswith(";"): self._process.stdin.write('G:%s\n' % (line.replace("\{travel_speed\}", "6000"))) self._process.stdin.write('CANCEL\n') self._printProgress = 0
def cancelPrint(self): if not self.isPrinting() or self._process is None: return self._process.stdin.write('STOP\n') endgcode = profile.getAlterationFileContents('end.gcode', 1).splitlines() for line in endgcode: if not line.startswith(";"): self._process.stdin.write( 'G:%s\n' % (line.replace("\{travel_speed\}", "6000"))) self._process.stdin.write('CANCEL\n') self._printProgress = 0
def main(): parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print 'Missing output filename' sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(',')) if len(position) < 9 + 2: position = position[0:2] position += [1,0,0] position += [0,1,0] position += [0,0,1] filenames = fixUTF8(args[idx + 1]).split('|') profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) if idx == 0: resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('start.gcode', len(filenames)).replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) else: resultFile.write(';TYPE:CUSTOM\n') n = output[-1].rfind('Z')+1 zString = output[-1][n:n+20] zString = zString[0:zString.find(' ')] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride('clear_z', clearZ) print position print profile.getAlterationFileContents('nextobject.gcode') resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr))) profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))) profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('alternative_center', filenames[0]) else: profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11]))) if extruderNr > 0: if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0: profile.setTempOverride('filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1))) print extruderNr, profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)), profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output)) if profile.getPreference('submit_slice_information') == 'True': filenames = fixUTF8(args[idx + 1]).split('|') for filename in filenames: m = hashlib.sha512() f = open(filename, "rb") while True: chunk = f.read(1024) if not chunk: break m.update(chunk) f.close() data = { 'processor': platform.processor(), 'machine': platform.machine(), 'platform': platform.platform(), 'profile': profile.getGlobalProfileString(), 'preferences': profile.getGlobalPreferencesString(), 'modelhash': m.hexdigest(), 'version': version.getVersion(), } try: f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data = urllib.urlencode(data), timeout = 5); f.read() f.close() except: pass
def OnRun(self): resultFile = open(self.resultFilename, "w") put = profile.setTempOverride self.progressLog = [] for action in self.actionList: wx.CallAfter(self.SetTitle, "Building: [%d/%d]" % (self.actionList.index(action) + 1, len(self.actionList))) if not action.usePreviousSlice: p = sliceRun.startSliceCommandProcess(action.sliceCmd) line = p.stdout.readline() maxValue = 1 while(len(line) > 0): line = line.rstrip() if line[0:9] == "Progress[" and line[-1:] == "]": progress = line[9:-1].split(":") if len(progress) > 2: maxValue = int(progress[2]) wx.CallAfter(self.SetProgress, progress[0], int(progress[1]), maxValue) else: self.progressLog.append(line) wx.CallAfter(self.statusText.SetLabel, line) if self.abort: p.terminate() wx.CallAfter(self.statusText.SetLabel, "Aborted by user.") resultFile.close() return line = p.stdout.readline() self.returnCode = p.wait() put('object_center_x', action.centerX - self.extruderOffset[action.extruder][0]) put('object_center_y', action.centerY - self.extruderOffset[action.extruder][1]) put('clear_z', action.clearZ) put('extruder', action.extruder) put('print_temperature', action.temperature) if action == self.actionList[0]: resultFile.write(';TYPE:CUSTOM\n') resultFile.write('T%d\n' % (action.extruder)) currentExtruder = action.extruder prevTemp = action.temperature startGCode = profile.getAlterationFileContents('start.gcode') startGCode = startGCode.replace('?filename?', 'Multiple files') resultFile.write(startGCode) else: #reset the extrusion length, and move to the next object center. resultFile.write(';TYPE:CUSTOM\n') if prevTemp != action.temperature and action.temperature > 0: resultFile.write('M104 S%d\n' % (int(action.temperature))) prevTemp = action.temperature resultFile.write(profile.getAlterationFileContents('nextobject.gcode')) resultFile.write(';PRINTNR:%d\n' % self.actionList.index(action)) profile.resetTempOverride() if not action.usePreviousSlice: f = open(sliceRun.getExportFilename(action.filename, "project_tmp"), "r") data = f.read(4096) while data != '': resultFile.write(data) data = f.read(4096) f.close() savedCenterX = action.centerX savedCenterY = action.centerY else: f = open(sliceRun.getExportFilename(action.filename, "project_tmp"), "r") for line in f: if line[0] != ';': if 'X' in line: line = self._adjustNumberInLine(line, 'X', action.centerX - savedCenterX) if 'Y' in line: line = self._adjustNumberInLine(line, 'Y', action.centerY - savedCenterY) resultFile.write(line) f.close() if not action.leaveResultForNextSlice: os.remove(sliceRun.getExportFilename(action.filename, "project_tmp")) wx.CallAfter(self.progressGauge.SetValue, 10000) self.totalDoneFactor = 0.0 wx.CallAfter(self.progressGauge2.SetValue, self.actionList.index(action) + 1) resultFile.write(';TYPE:CUSTOM\n') if len(self.actionList) > 1 and self.actionList[-1].clearZ > 1: #only move to higher Z if we have sliced more then 1 object. This solves the "move into print after printing" problem with the print-all-at-once option. resultFile.write('G1 Z%f F%f\n' % (self.actionList[-1].clearZ, profile.getProfileSettingFloat('max_z_speed') * 60)) resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() gcode = gcodeInterpreter.gcode() gcode.load(self.resultFilename) self.abort = True sliceTime = time.time() - self.sliceStartTime status = "Build: %s" % (self.resultFilename) status += "\nSlicing took: %02d:%02d" % (sliceTime / 60, sliceTime % 60) status += "\nFilament: %.2fm %.2fg" % (gcode.extrusionAmount / 1000, gcode.calculateWeight() * 1000) status += "\nPrint time: %02d:%02d" % (int(gcode.totalMoveTimeMinute / 60), int(gcode.totalMoveTimeMinute % 60)) cost = gcode.calculateCost() self.totalMoveTimeMinute = gcode.totalMoveTimeMinute if cost != False: status += "\nCost: %s" % (cost) profile.replaceGCodeTags(self.resultFilename, gcode) wx.CallAfter(self.statusText.SetLabel, status) wx.CallAfter(self.OnSliceDone)
def main(): parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print 'Missing output filename' sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(',')) if len(position) < 9 + 2: position = position[0:2] position += [1,0,0] position += [0,1,0] position += [0,0,1] filenames = fixUTF8(args[idx + 1]).split('|') profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) if idx == 0: resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('start.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) else: resultFile.write(';TYPE:CUSTOM\n') n = output[-1].rfind('Z')+1 zString = output[-1][n:n+20] zString = zString[0:zString.find(' ')] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride('clear_z', clearZ) resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr))) profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))) profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('alternative_center', filenames[0]) else: profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11]))) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output))
def stitchMultiExtruder(outputList, resultFile): print "Stitching %i files for multi-extrusion" % (len(outputList)) currentExtruder = 0 resultFile.write('T%d\n' % (currentExtruder)) layerNr = 0 hasLine = True outputList = map(lambda o: o.split('\n'), outputList) outputOrder = range(0, len(outputList)) outputSlice = [] for n in xrange(0, len(outputList)): outputSlice.append([0, 0]) currentX = 0 currentY = 0 currentZ = 0 currentF = 60 while hasLine: hasLine = layerNr < 1000 for n in xrange(0, len(outputList)): outputSlice[n][0] = outputSlice[n][1] + 1 outputSlice[n][1] = outputSlice[n][0] while outputSlice[n][1] < len(outputList[n]) and not outputList[n][ outputSlice[n][1]].startswith(';LAYER:'): outputSlice[n][1] += 1 outputOrder = range(currentExtruder, len(outputList)) + range( 0, currentExtruder) for n in outputOrder: if outputSlice[n][1] > outputSlice[n][0] + 1: nextExtruder = n resultFile.write(';LAYER:%d\n' % (layerNr)) resultFile.write(';EXTRUDER:%d\n' % (nextExtruder)) startSlice = outputSlice[n][0] endSlice = outputSlice[n][1] currentE = 0 while startSlice < len(outputList[n]) and not isPrintingLine( outputList[n][startSlice]): currentE = getCodeFloat(outputList[n][startSlice], 'E', currentE) currentX = getCodeFloat(outputList[n][startSlice], 'X', currentX) currentY = getCodeFloat(outputList[n][startSlice], 'Y', currentY) currentZ = getCodeFloat(outputList[n][startSlice], 'Z', currentZ) currentF = getCodeFloat(outputList[n][startSlice], 'F', currentF) startSlice += 1 while not isPrintingLine(outputList[n][endSlice - 1]): endSlice -= 1 if nextExtruder != currentExtruder: profile.setTempOverride('extruder', nextExtruder) profile.setTempOverride('new_x', currentX) profile.setTempOverride('new_y', currentY) profile.setTempOverride('new_z', currentZ) resultFile.write( profile.getAlterationFileContents( 'switchExtruder.gcode') + '\n') profile.resetTempOverride() currentExtruder = nextExtruder for idx in xrange(outputSlice[n][0], startSlice): if not 'G1' in outputList[n][idx]: resultFile.write(outputList[n][idx]) resultFile.write('\n') resultFile.write( 'G1 X%f Y%f Z%f F%f\n' % (currentX, currentY, currentZ, profile.getProfileSettingFloat('travel_speed') * 60)) resultFile.write('G1 F%f\n' % (currentF)) resultFile.write('G92 E%f\n' % (currentE)) for idx in xrange(startSlice, endSlice): resultFile.write(outputList[n][idx]) resultFile.write('\n') currentX = getCodeFloat(outputList[n][idx], 'X', currentX) currentY = getCodeFloat(outputList[n][idx], 'Y', currentY) currentZ = getCodeFloat(outputList[n][idx], 'Z', currentZ) hasLine = True resultFile.write('G92 E0\n') layerNr += 1
def main(): parser = OptionParser( usage= "usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print 'Missing output filename' sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(',')) if len(position) < 9 + 2: position = position[0:2] position += [1, 0, 0] position += [0, 1, 0] position += [0, 0, 1] filenames = fixUTF8(args[idx + 1]).split('|') profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) if idx == 0: resultFile.write(';TYPE:CUSTOM\n') resultFile.write( profile.getAlterationFileContents( 'start.gcode', len(filenames)).replace( '?filename?', ' '.join(filenames).encode('ascii', 'replace'))) else: resultFile.write(';TYPE:CUSTOM\n') n = output[-1].rfind('Z') + 1 zString = output[-1][n:n + 20] zString = zString[0:zString.find(' ')] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride('clear_z', clearZ) print position print profile.getAlterationFileContents('nextobject.gcode') resultFile.write( profile.getAlterationFileContents('nextobject.gcode').replace( '?filename?', ' '.join(filenames).encode('ascii', 'replace'))) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride( 'object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr))) profile.setTempOverride( 'object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))) profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('alternative_center', filenames[0]) else: profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11]))) if extruderNr > 0: if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0: profile.setTempOverride( 'filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1))) print extruderNr, profile.getPreferenceFloat( 'extruder_offset_x%d' % (extruderNr)), profile.getPreferenceFloat( 'extruder_offset_y%d' % (extruderNr)) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output)) if profile.getPreference('submit_slice_information') == 'True': filenames = fixUTF8(args[idx + 1]).split('|') for filename in filenames: m = hashlib.sha512() f = open(filename, "rb") while True: chunk = f.read(1024) if not chunk: break m.update(chunk) f.close() data = { 'processor': platform.processor(), 'machine': platform.machine(), 'platform': platform.platform(), 'profile': profile.getGlobalProfileString(), 'preferences': profile.getGlobalPreferencesString(), 'modelhash': m.hexdigest(), 'version': version.getVersion(), } try: f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data=urllib.urlencode(data), timeout=5) f.read() f.close() except: pass
def getAlterationFile(fileName): return profile.getAlterationFileContents(fileName)
def _engineSettings(self, extruderCount): settings = { 'layerThickness': int(profile.getProfileSettingFloat('layer_height') * 1000), 'initialLayerThickness': int(profile.getProfileSettingFloat('bottom_thickness') * 1000) if profile.getProfileSettingFloat('bottom_thickness') > 0.0 else int( profile.getProfileSettingFloat('layer_height') * 1000), 'filamentDiameter': int(profile.getProfileSettingFloat('filament_diameter') * 1000), 'filamentFlow': int(profile.getProfileSettingFloat('filament_flow')), 'extrusionWidth': int(profile.calculateEdgeWidth() * 1000), 'insetCount': int(profile.calculateLineCount()), 'downSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_bottom') == 'True' else 0, 'upSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_top') == 'True' else 0, 'infillOverlap': int(profile.getProfileSettingFloat('fill_overlap')), 'initialSpeedupLayers': int(4), 'initialLayerSpeed': int(profile.getProfileSettingFloat('bottom_layer_speed')), 'printSpeed': int(profile.getProfileSettingFloat('print_speed')), 'infillSpeed': int(profile.getProfileSettingFloat('infill_speed')) if int(profile.getProfileSettingFloat('infill_speed')) > 0 else int( profile.getProfileSettingFloat('print_speed')), 'inset0Speed': int(profile.getProfileSettingFloat('inset0_speed')) if int(profile.getProfileSettingFloat('inset0_speed')) > 0 else int( profile.getProfileSettingFloat('print_speed')), 'insetXSpeed': int(profile.getProfileSettingFloat('insetx_speed')) if int(profile.getProfileSettingFloat('insetx_speed')) > 0 else int( profile.getProfileSettingFloat('print_speed')), 'moveSpeed': int(profile.getProfileSettingFloat('travel_speed')), 'fanSpeedMin': int(profile.getProfileSettingFloat('fan_speed')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'fanSpeedMax': int(profile.getProfileSettingFloat('fan_speed_max')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'supportAngle': int(-1) if profile.getProfileSetting('support') == 'None' else int( profile.getProfileSettingFloat('support_angle')), 'supportEverywhere': int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0), 'supportLineDistance': int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('support_fill_rate')) if profile.getProfileSettingFloat('support_fill_rate') > 0 else -1, 'supportXYDistance': int(1000 * profile.getProfileSettingFloat('support_xy_distance')), 'supportZDistance': int(1000 * profile.getProfileSettingFloat('support_z_distance')), 'supportExtruder': 0 if profile.getProfileSetting('support_dual_extrusion') == 'First extruder' else (1 if profile.getProfileSetting('support_dual_extrusion') == 'Second extruder' and profile.minimalExtruderCount() > 1 else -1), 'retractionAmount': int(profile.getProfileSettingFloat('retraction_amount') * 1000) if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'retractionSpeed': int(profile.getProfileSettingFloat('retraction_speed')), 'retractionMinimalDistance': int( profile.getProfileSettingFloat('retraction_min_travel') * 1000), 'retractionAmountExtruderSwitch': int( profile.getProfileSettingFloat('retraction_dual_amount') * 1000), 'retractionZHop': int(profile.getProfileSettingFloat('retraction_hop') * 1000), 'minimalExtrusionBeforeRetraction': int( profile.getProfileSettingFloat('retraction_minimal_extrusion') * 1000), 'enableCombing': 1 if profile.getProfileSetting('retraction_combing') == 'True' else 0, 'multiVolumeOverlap': int(profile.getProfileSettingFloat('overlap_dual') * 1000), 'objectSink': max(0, int(profile.getProfileSettingFloat('object_sink') * 1000)), 'minimalLayerTime': int(profile.getProfileSettingFloat('cool_min_layer_time')), 'minimalFeedrate': int(profile.getProfileSettingFloat('cool_min_feedrate')), 'coolHeadLift': 1 if profile.getProfileSetting('cool_head_lift') == 'True' else 0, 'startCode': profile.getAlterationFileContents('start.gcode', extruderCount), 'endCode': profile.getAlterationFileContents('end.gcode', extruderCount), 'relativeE': 1 if profile.getMachineSetting('relative_extrusion') == 'True' else 0, 'perimInset': int(profile.getProfileSettingFloat('perimeter_inset') * 1000), 'extruderOffset[1].X': int(profile.getMachineSettingFloat('extruder_offset_x1') * 1000), 'extruderOffset[1].Y': int(profile.getMachineSettingFloat('extruder_offset_y1') * 1000), 'extruderOffset[2].X': int(profile.getMachineSettingFloat('extruder_offset_x2') * 1000), 'extruderOffset[2].Y': int(profile.getMachineSettingFloat('extruder_offset_y2') * 1000), 'extruderOffset[3].X': int(profile.getMachineSettingFloat('extruder_offset_x3') * 1000), 'extruderOffset[3].Y': int(profile.getMachineSettingFloat('extruder_offset_y3') * 1000), 'fixHorrible': 0, } fanFullHeight = int( profile.getProfileSettingFloat('fan_full_height') * 1000) settings['fanFullOnLayerNr'] = (fanFullHeight - settings['initialLayerThickness'] - 1) / settings['layerThickness'] + 1 if settings['fanFullOnLayerNr'] < 0: settings['fanFullOnLayerNr'] = 0 if profile.getProfileSetting('support_type') == 'Lines': settings['supportType'] = 1 if profile.getProfileSettingFloat('fill_density') == 0: settings['sparseInfillLineDistance'] = -1 elif profile.getProfileSettingFloat('fill_density') == 100: settings['sparseInfillLineDistance'] = settings['extrusionWidth'] #Set the up/down skins height to 10000 if we want a 100% filled object. # This gives better results then normal 100% infill as the sparse and up/down skin have some overlap. settings['downSkinCount'] = 10000 settings['upSkinCount'] = 10000 else: settings['sparseInfillLineDistance'] = int( 100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('fill_density')) if profile.getProfileSetting('platform_adhesion') == 'Brim': settings['skirtDistance'] = 0 settings['skirtLineCount'] = int( profile.getProfileSettingFloat('brim_line_count')) elif profile.getProfileSetting('platform_adhesion') == 'Raft': settings['skirtDistance'] = 0 settings['skirtLineCount'] = 0 settings['raftMargin'] = int( profile.getProfileSettingFloat('raft_margin') * 1000) settings['raftLineSpacing'] = int( profile.getProfileSettingFloat('raft_line_spacing') * 1000) settings['raftBaseThickness'] = int( profile.getProfileSettingFloat('raft_base_thickness') * 1000) settings['raftBaseLinewidth'] = int( profile.getProfileSettingFloat('raft_base_linewidth') * 1000) settings['raftInterfaceThickness'] = int( profile.getProfileSettingFloat('raft_interface_thickness') * 1000) settings['raftInterfaceLinewidth'] = int( profile.getProfileSettingFloat('raft_interface_linewidth') * 1000) else: settings['skirtDistance'] = int( profile.getProfileSettingFloat('skirt_gap') * 1000) settings['skirtLineCount'] = int( profile.getProfileSettingFloat('skirt_line_count')) settings['skirtMinLength'] = int( profile.getProfileSettingFloat('skirt_minimal_length') * 1000) if profile.getProfileSetting( 'fix_horrible_union_all_type_a') == 'True': settings['fixHorrible'] |= 0x01 if profile.getProfileSetting( 'fix_horrible_union_all_type_b') == 'True': settings['fixHorrible'] |= 0x02 if profile.getProfileSetting('fix_horrible_use_open_bits') == 'True': settings['fixHorrible'] |= 0x10 if profile.getProfileSetting( 'fix_horrible_extensive_stitching') == 'True': settings['fixHorrible'] |= 0x04 if settings['layerThickness'] <= 0: settings['layerThickness'] = 1000 if profile.getMachineSetting('gcode_flavor') == 'UltiGCode': settings['gcodeFlavor'] = 1 elif profile.getMachineSetting('gcode_flavor') == 'MakerBot': settings['gcodeFlavor'] = 2 if profile.getProfileSetting('spiralize') == 'True': settings['spiralizeMode'] = 1 if profile.getProfileSetting( 'wipe_tower') == 'True' and extruderCount > 1: settings['wipeTowerSize'] = int( math.sqrt( profile.getProfileSettingFloat('wipe_tower_volume') * 1000 * 1000 * 1000 / settings['layerThickness'])) if profile.getProfileSetting('ooze_shield') == 'True': settings['enableOozeShield'] = 1 return settings
def main(): parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option( "-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print" ) parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print "Missing output filename" sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(",")) if len(position) < 9 + 2: position = position[0:2] position += [1, 0, 0] position += [0, 1, 0] position += [0, 0, 1] filenames = fixUTF8(args[idx + 1]).split("|") profile.setTempOverride("object_center_x", position[0]) profile.setTempOverride("object_center_y", position[1]) if idx == 0: resultFile.write(";TYPE:CUSTOM\n") resultFile.write( profile.getAlterationFileContents("start.gcode").replace( "?filename?", " ".join(filenames).encode("ascii", "replace") ) ) else: resultFile.write(";TYPE:CUSTOM\n") n = output[-1].rfind("Z") + 1 zString = output[-1][n : n + 20] zString = zString[0 : zString.find(" ")] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride("clear_z", clearZ) print position print profile.getAlterationFileContents("nextobject.gcode") resultFile.write( profile.getAlterationFileContents("nextobject.gcode").replace( "?filename?", " ".join(filenames).encode("ascii", "replace") ) ) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride( "object_center_x", position[0] - profile.getPreferenceFloat("extruder_offset_x%d" % (extruderNr)) ) profile.setTempOverride( "object_center_y", position[1] - profile.getPreferenceFloat("extruder_offset_y%d" % (extruderNr)) ) profile.setTempOverride("fan_enabled", "False") profile.setTempOverride("skirt_line_count", "0") profile.setTempOverride("alternative_center", filenames[0]) else: profile.setTempOverride("object_center_x", position[0]) profile.setTempOverride("object_center_y", position[1]) profile.setTempOverride("object_matrix", ",".join(map(str, position[2:11]))) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(";TYPE:CUSTOM\n") resultFile.write(profile.getAlterationFileContents("end.gcode")) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output)) if profile.getPreference("submit_slice_information") == "True": filenames = fixUTF8(args[idx + 1]).split("|") for filename in filenames: m = hashlib.sha512() f = open(filename, "rb") while True: chunk = f.read(1024) if not chunk: break m.update(chunk) f.close() data = { "processor": platform.processor(), "machine": platform.machine(), "platform": platform.platform(), "profile": profile.getGlobalProfileString(), "preferences": profile.getGlobalPreferencesString(), "modelhash": m.hexdigest(), "version": version.getVersion(), } try: f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data=urllib.urlencode(data), timeout=5) f.read() f.close() except: pass
def _engineSettings(self, extruderCount): settings = { 'layerThickness': int(profile.getProfileSettingFloat('layer_height') * 1000), 'initialLayerThickness': int(profile.getProfileSettingFloat('bottom_thickness') * 1000) if profile.getProfileSettingFloat('bottom_thickness') > 0.0 else int(profile.getProfileSettingFloat('layer_height') * 1000), 'filamentDiameter': int(profile.getProfileSettingFloat('filament_diameter') * 1000), 'filamentFlow': int(profile.getProfileSettingFloat('filament_flow')), 'extrusionWidth': int(profile.calculateEdgeWidth() * 1000), 'insetCount': int(profile.calculateLineCount()), 'downSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_bottom') == 'True' else 0, 'upSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_top') == 'True' else 0, 'infillOverlap': int(profile.getProfileSettingFloat('fill_overlap')), 'initialSpeedupLayers': int(4), 'initialLayerSpeed': int(profile.getProfileSettingFloat('bottom_layer_speed')), 'printSpeed': int(profile.getProfileSettingFloat('print_speed')), 'infillSpeed': int(profile.getProfileSettingFloat('infill_speed')) if int(profile.getProfileSettingFloat('infill_speed')) > 0 else int(profile.getProfileSettingFloat('print_speed')), 'moveSpeed': int(profile.getProfileSettingFloat('travel_speed')), 'fanSpeedMin': int(profile.getProfileSettingFloat('fan_speed')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'fanSpeedMax': int(profile.getProfileSettingFloat('fan_speed_max')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'supportAngle': int(-1) if profile.getProfileSetting('support') == 'None' else int(60), 'supportEverywhere': int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0), 'supportLineDistance': int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('support_fill_rate')) if profile.getProfileSettingFloat('support_fill_rate') > 0 else -1, 'supportXYDistance': int(1000 * profile.getProfileSettingFloat('support_xy_distance')), 'supportZDistance': int(1000 * profile.getProfileSettingFloat('support_z_distance')), 'supportExtruder': 0 if profile.getProfileSetting('support_dual_extrusion') == 'First extruder' else (1 if profile.getProfileSetting('support_dual_extrusion') == 'Second extruder' else -1), 'retractionAmount': int(profile.getProfileSettingFloat('retraction_amount') * 1000) if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'retractionSpeed': int(profile.getProfileSettingFloat('retraction_speed')), 'retractionMinimalDistance': int(profile.getProfileSettingFloat('retraction_min_travel') * 1000), 'retractionAmountExtruderSwitch': int(profile.getProfileSettingFloat('retraction_dual_amount') * 1000), 'minimalExtrusionBeforeRetraction': int(profile.getProfileSettingFloat('retraction_minimal_extrusion') * 1000), 'enableCombing': 1 if profile.getProfileSetting('retraction_combing') == 'True' else 0, 'multiVolumeOverlap': int(profile.getProfileSettingFloat('overlap_dual') * 1000), 'objectSink': int(profile.getProfileSettingFloat('object_sink') * 1000), 'minimalLayerTime': int(profile.getProfileSettingFloat('cool_min_layer_time')), 'minimalFeedrate': int(profile.getProfileSettingFloat('cool_min_feedrate')), 'coolHeadLift': 1 if profile.getProfileSetting('cool_head_lift') == 'True' else 0, 'startCode': profile.getAlterationFileContents('start.gcode', extruderCount), 'endCode': profile.getAlterationFileContents('end.gcode', extruderCount), 'extruderOffset[1].X': int(profile.getMachineSettingFloat('extruder_offset_x1') * 1000), 'extruderOffset[1].Y': int(profile.getMachineSettingFloat('extruder_offset_y1') * 1000), 'extruderOffset[2].X': int(profile.getMachineSettingFloat('extruder_offset_x2') * 1000), 'extruderOffset[2].Y': int(profile.getMachineSettingFloat('extruder_offset_y2') * 1000), 'extruderOffset[3].X': int(profile.getMachineSettingFloat('extruder_offset_x3') * 1000), 'extruderOffset[3].Y': int(profile.getMachineSettingFloat('extruder_offset_y3') * 1000), 'fixHorrible': 0, } fanFullHeight = int(profile.getProfileSettingFloat('fan_full_height') * 1000) settings['fanFullOnLayerNr'] = (fanFullHeight - settings['initialLayerThickness'] - 1) / settings['layerThickness'] + 1 if settings['fanFullOnLayerNr'] < 0: settings['fanFullOnLayerNr'] = 0 if profile.getProfileSettingFloat('fill_density') == 0: settings['sparseInfillLineDistance'] = -1 elif profile.getProfileSettingFloat('fill_density') == 100: settings['sparseInfillLineDistance'] = settings['extrusionWidth'] #Set the up/down skins height to 10000 if we want a 100% filled object. # This gives better results then normal 100% infill as the sparse and up/down skin have some overlap. settings['downSkinCount'] = 10000 settings['upSkinCount'] = 10000 else: settings['sparseInfillLineDistance'] = int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('fill_density')) if profile.getProfileSetting('platform_adhesion') == 'Brim': settings['skirtDistance'] = 0 settings['skirtLineCount'] = int(profile.getProfileSettingFloat('brim_line_count')) elif profile.getProfileSetting('platform_adhesion') == 'Raft': settings['skirtDistance'] = 0 settings['skirtLineCount'] = 0 settings['raftMargin'] = int(profile.getProfileSettingFloat('raft_margin') * 1000) settings['raftLineSpacing'] = int(profile.getProfileSettingFloat('raft_line_spacing') * 1000) settings['raftBaseThickness'] = int(profile.getProfileSettingFloat('raft_base_thickness') * 1000) settings['raftBaseLinewidth'] = int(profile.getProfileSettingFloat('raft_base_linewidth') * 1000) settings['raftInterfaceThickness'] = int(profile.getProfileSettingFloat('raft_interface_thickness') * 1000) settings['raftInterfaceLinewidth'] = int(profile.getProfileSettingFloat('raft_interface_linewidth') * 1000) else: settings['skirtDistance'] = int(profile.getProfileSettingFloat('skirt_gap') * 1000) settings['skirtLineCount'] = int(profile.getProfileSettingFloat('skirt_line_count')) settings['skirtMinLength'] = int(profile.getProfileSettingFloat('skirt_minimal_length') * 1000) if profile.getProfileSetting('fix_horrible_union_all_type_a') == 'True': settings['fixHorrible'] |= 0x01 if profile.getProfileSetting('fix_horrible_union_all_type_b') == 'True': settings['fixHorrible'] |= 0x02 if profile.getProfileSetting('fix_horrible_use_open_bits') == 'True': settings['fixHorrible'] |= 0x10 if profile.getProfileSetting('fix_horrible_extensive_stitching') == 'True': settings['fixHorrible'] |= 0x04 if settings['layerThickness'] <= 0: settings['layerThickness'] = 1000 if profile.getMachineSetting('gcode_flavor') == 'UltiGCode': settings['gcodeFlavor'] = 1 if profile.getProfileSetting('spiralize') == 'True': settings['spiralizeMode'] = 1 if profile.getProfileSetting('wipe_tower') == 'True': settings['enableWipeTower'] = 1 if profile.getProfileSetting('ooze_shield') == 'True': settings['enableOozeShield'] = 1 return settings
def stitchMultiExtruder(outputList, resultFile): print "Stitching %i files for multi-extrusion" % (len(outputList)) currentExtruder = 0 resultFile.write('T%d\n' % (currentExtruder)) layerNr = 0 hasLine = True outputList = map(lambda o: o.split('\n'), outputList) outputOrder = range(0, len(outputList)) outputSlice = [] for n in xrange(0, len(outputList)): outputSlice.append([0, 0]) currentX = 0 currentY = 0 currentZ = 0 currentF = 60 while hasLine: hasLine = layerNr < 1000 for n in xrange(0, len(outputList)): outputSlice[n][0] = outputSlice[n][1] + 1 outputSlice[n][1] = outputSlice[n][0] while outputSlice[n][1] < len(outputList[n]) and not outputList[n][outputSlice[n][1]].startswith(';LAYER:'): outputSlice[n][1] += 1 outputOrder = range(currentExtruder, len(outputList)) + range(0, currentExtruder) for n in outputOrder: if outputSlice[n][1] > outputSlice[n][0] + 1: nextExtruder = n resultFile.write(';LAYER:%d\n' % (layerNr)) resultFile.write(';EXTRUDER:%d\n' % (nextExtruder)) startSlice = outputSlice[n][0] endSlice = outputSlice[n][1] currentE = 0 while not isPrintingLine(outputList[n][startSlice]): currentE = getCodeFloat(outputList[n][startSlice], 'E', currentE) currentX = getCodeFloat(outputList[n][startSlice], 'X', currentX) currentY = getCodeFloat(outputList[n][startSlice], 'Y', currentY) currentZ = getCodeFloat(outputList[n][startSlice], 'Z', currentZ) currentF = getCodeFloat(outputList[n][startSlice], 'F', currentF) startSlice += 1 while not isPrintingLine(outputList[n][endSlice-1]): endSlice -= 1 if nextExtruder != currentExtruder: profile.setTempOverride('extruder', nextExtruder) profile.setTempOverride('new_x', currentX) profile.setTempOverride('new_y', currentY) profile.setTempOverride('new_z', currentZ) resultFile.write(profile.getAlterationFileContents('switchExtruder.gcode') + '\n') profile.resetTempOverride() currentExtruder = nextExtruder for idx in xrange(outputSlice[n][0], startSlice): if not 'G1' in outputList[n][idx]: resultFile.write(outputList[n][idx]) resultFile.write('\n') resultFile.write('G1 X%f Y%f Z%f F%f\n' % (currentX, currentY, currentZ, profile.getProfileSettingFloat('travel_speed') * 60)) resultFile.write('G1 F%f\n' % (currentF)) resultFile.write('G92 E%f\n' % (currentE)) for idx in xrange(startSlice, endSlice): resultFile.write(outputList[n][idx]) resultFile.write('\n') currentX = getCodeFloat(outputList[n][idx], 'X', currentX) currentY = getCodeFloat(outputList[n][idx], 'Y', currentY) currentZ = getCodeFloat(outputList[n][idx], 'Z', currentZ) hasLine = True resultFile.write('G92 E0\n') layerNr += 1
def pause(self, value): if not (self.isPrinting() or self.isPaused()) or self._process is None: return if value: start_gcode = profile.getAlterationFileContents('start.gcode') start_gcode_lines = len(start_gcode.split("\n")) parkX = profile.getMachineSettingFloat('machine_width') - 10 parkY = profile.getMachineSettingFloat('machine_depth') - 10 maxZ = profile.getMachineSettingFloat('machine_height') - 10 #retract_amount = profile.getProfileSettingFloat('retraction_amount') retract_amount = 5.0 moveZ = 10.0 self._process.stdin.write("PAUSE\n") if self._printProgress - 5 > start_gcode_lines: # Substract 5 because of the marlin queue x = None y = None e = None f = None for i in xrange(self._printProgress - 1, start_gcode_lines, -1): line = self._gcodeData[i] if ('G0' in line or 'G1' in line) and 'X' in line and x is None: x = float(re.search('X(-?[0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'Y' in line and y is None: y = float(re.search('Y(-?[0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'E' in line and e is None: e = float(re.search('E(-?[0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'F' in line and f is None: f = int(re.search('F(-?[0-9\.]*)', line).group(1)) if x is not None and y is not None and f is not None and e is not None: break if f is None: f = 1200 if x is not None and y is not None: # Set E relative positioning self.sendCommand("M83") # Retract 1mm retract = ("E-%f" % retract_amount) #Move the toolhead up newZ = self._ZPosition + moveZ if maxZ < newZ: newZ = maxZ if newZ > self._ZPosition: move = ("Z%f " % (newZ)) else: #No z movement, too close to max height move = "" retract_and_move = "G1 {} {}F120".format(retract, move) self.sendCommand(retract_and_move) #Move the head away self.sendCommand("G1 X%f Y%f F9000" % (parkX, parkY)) #Disable the E steppers self.sendCommand("M84 E0") # Set E absolute positioning self.sendCommand("M82") self._pausePosition = (x, y, self._ZPosition, f, e) else: if self._pausePosition: retract_amount = profile.getProfileSettingFloat('retraction_amount') # Set E relative positioning self.sendCommand("M83") #Prime the nozzle when changing filament self.sendCommand("G1 E%f F120" % (retract_amount)) #Push the filament out self.sendCommand("G1 E-%f F120" % (retract_amount)) #retract again # Position the toolhead to the correct position again self.sendCommand("G1 X%f Y%f Z%f F%d" % self._pausePosition[0:4]) # Prime the nozzle again self.sendCommand("G1 E%f F120" % (retract_amount)) # Set proper feedrate self.sendCommand("G1 F%d" % (self._pausePosition[3])) # Set E absolute position to cancel out any extrude/retract that occured self.sendCommand("G92 E%f" % (self._pausePosition[4])) # Set E absolute positioning self.sendCommand("M82") self._process.stdin.write("RESUME\n") self._pausePosition = None
def _engineSettings(self, extruderCount): settings = { 'layerThickness': int(profile.getProfileSettingFloat('layer_height') * 1000), 'initialLayerThickness': int(profile.getProfileSettingFloat('bottom_thickness') * 1000) if profile.getProfileSettingFloat('bottom_thickness') > 0.0 else int( profile.getProfileSettingFloat('layer_height') * 1000), 'filamentDiameter': int(profile.getProfileSettingFloat('filament_diameter') * 1000), 'filamentFlow': int(profile.getProfileSettingFloat('filament_flow')), 'extrusionWidth': int(profile.calculateEdgeWidth() * 1000), 'insetCount': int(profile.calculateLineCount()), 'downSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_bottom') == 'True' else 0, 'upSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_top') == 'True' else 0, 'sparseInfillLineDistance': int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('fill_density')) if profile.getProfileSettingFloat('fill_density') > 0 else -1, 'infillOverlap': int(profile.getProfileSettingFloat('fill_overlap')), 'initialSpeedupLayers': int(4), 'initialLayerSpeed': int(profile.getProfileSettingFloat('bottom_layer_speed')), 'printSpeed': int(profile.getProfileSettingFloat('print_speed')), 'infillSpeed': int(profile.getProfileSettingFloat('infill_speed')) if int(profile.getProfileSettingFloat('infill_speed')) > 0 else int( profile.getProfileSettingFloat('print_speed')), 'moveSpeed': int(profile.getProfileSettingFloat('travel_speed')), 'fanOnLayerNr': int(profile.getProfileSettingFloat('fan_layer')), 'fanSpeedMin': int(profile.getProfileSettingFloat('fan_speed')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'fanSpeedMax': int(profile.getProfileSettingFloat('fan_speed_max')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'supportAngle': int(-1) if profile.getProfileSetting('support') == 'None' else int(60), 'supportEverywhere': int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0), 'supportLineWidth': int( profile.getProfileSettingFloat('support_rate') * profile.calculateEdgeWidth() * 1000 / 100), 'retractionAmount': int(profile.getProfileSettingFloat('retraction_amount') * 1000) if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'retractionSpeed': int(profile.getProfileSettingFloat('retraction_speed')), 'retractionAmountExtruderSwitch': int( profile.getProfileSettingFloat('retraction_dual_amount') * 1000), 'multiVolumeOverlap': int(profile.getProfileSettingFloat('overlap_dual') * 1000), 'objectSink': int(profile.getProfileSettingFloat('object_sink') * 1000), 'minimalLayerTime': int(profile.getProfileSettingFloat('cool_min_layer_time')), 'minimalFeedrate': int(profile.getProfileSettingFloat('cool_min_feedrate')), 'coolHeadLift': 1 if profile.getProfileSetting('cool_head_lift') == 'True' else 0, 'startCode': profile.getAlterationFileContents('start.gcode', extruderCount), 'endCode': profile.getAlterationFileContents('end.gcode', extruderCount), 'extruderOffset[1].X': int(profile.getPreferenceFloat('extruder_offset_x1') * 1000), 'extruderOffset[1].Y': int(profile.getPreferenceFloat('extruder_offset_y1') * 1000), 'extruderOffset[2].X': int(profile.getPreferenceFloat('extruder_offset_x2') * 1000), 'extruderOffset[2].Y': int(profile.getPreferenceFloat('extruder_offset_y2') * 1000), 'extruderOffset[3].X': int(profile.getPreferenceFloat('extruder_offset_x3') * 1000), 'extruderOffset[3].Y': int(profile.getPreferenceFloat('extruder_offset_y3') * 1000), 'fixHorrible': 0, } if profile.getProfileSetting('platform_adhesion') == 'Brim': settings['skirtDistance'] = 0 settings['skirtLineCount'] = int( profile.getProfileSettingFloat('brim_line_count')) elif profile.getProfileSetting('platform_adhesion') == 'Raft': settings['skirtDistance'] = 0 settings['skirtLineCount'] = 0 settings['raftMargin'] = int( profile.getProfileSettingFloat('raft_margin') * 1000) settings['raftBaseThickness'] = int( profile.getProfileSettingFloat('raft_base_thickness') * 1000) settings['raftBaseLinewidth'] = int( profile.getProfileSettingFloat('raft_base_linewidth') * 1000) settings['raftInterfaceThickness'] = int( profile.getProfileSettingFloat('raft_interface_thickness') * 1000) settings['raftInterfaceLinewidth'] = int( profile.getProfileSettingFloat('raft_interface_linewidth') * 1000) else: settings['skirtDistance'] = int( profile.getProfileSettingFloat('skirt_gap') * 1000) settings['skirtLineCount'] = int( profile.getProfileSettingFloat('skirt_line_count')) if profile.getProfileSetting( 'fix_horrible_union_all_type_a') == 'True': settings['fixHorrible'] |= 0x01 if profile.getProfileSetting( 'fix_horrible_union_all_type_b') == 'True': settings['fixHorrible'] |= 0x02 if profile.getProfileSetting('fix_horrible_use_open_bits') == 'True': settings['fixHorrible'] |= 0x10 if profile.getProfileSetting( 'fix_horrible_extensive_stitching') == 'True': settings['fixHorrible'] |= 0x04 if settings['layerThickness'] <= 0: settings['layerThickness'] = 1000 return settings
def pause(self, value): if not (self.isPrinting() or self.isPaused()) or self._process is None: return if value: start_gcode = profile.getAlterationFileContents('start.gcode') start_gcode_lines = len(start_gcode.split("\n")) parkX = profile.getMachineSettingFloat('machine_width') - 10 parkY = profile.getMachineSettingFloat('machine_depth') - 10 maxZ = profile.getMachineSettingFloat('machine_height') - 10 #retract_amount = profile.getProfileSettingFloat('retraction_amount') retract_amount = 5.0 moveZ = 10.0 self._process.stdin.write("PAUSE\n") if self._printProgress - 5 > start_gcode_lines: # Substract 5 because of the marlin queue x = None y = None e = None f = None for i in xrange(self._printProgress - 1, start_gcode_lines, -1): line = self._gcodeData[i] if ('G0' in line or 'G1' in line) and 'X' in line and x is None: x = float(re.search('X(-?[0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'Y' in line and y is None: y = float(re.search('Y(-?[0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'E' in line and e is None: e = float(re.search('E(-?[0-9\.]*)', line).group(1)) if ('G0' in line or 'G1' in line) and 'F' in line and f is None: f = int(re.search('F(-?[0-9\.]*)', line).group(1)) if x is not None and y is not None and f is not None and e is not None: break if f is None: f = 1200 if x is not None and y is not None: # Set E relative positioning self.sendCommand("M83") # Retract 1mm retract = ("E-%f" % retract_amount) #Move the toolhead up newZ = self._ZPosition + moveZ if maxZ < newZ: newZ = maxZ if newZ > self._ZPosition: move = ("Z%f " % (newZ)) else: #No z movement, too close to max height move = "" retract_and_move = "G1 {} {}F120".format(retract, move) self.sendCommand(retract_and_move) #Move the head away self.sendCommand("G1 X%f Y%f F9000" % (parkX, parkY)) #Disable the E steppers self.sendCommand("M84 E0") # Set E absolute positioning self.sendCommand("M82") self._pausePosition = (x, y, self._ZPosition, f, e) else: if self._pausePosition: retract_amount = profile.getProfileSettingFloat( 'retraction_amount') # Set E relative positioning self.sendCommand("M83") #Prime the nozzle when changing filament self.sendCommand("G1 E%f F120" % (retract_amount)) #Push the filament out self.sendCommand("G1 E-%f F120" % (retract_amount)) #retract again # Position the toolhead to the correct position again self.sendCommand("G1 X%f Y%f Z%f F%d" % self._pausePosition[0:4]) # Prime the nozzle again self.sendCommand("G1 E%f F120" % (retract_amount)) # Set proper feedrate self.sendCommand("G1 F%d" % (self._pausePosition[3])) # Set E absolute position to cancel out any extrude/retract that occured self.sendCommand("G92 E%f" % (self._pausePosition[4])) # Set E absolute positioning self.sendCommand("M82") self._process.stdin.write("RESUME\n") self._pausePosition = None
def getAlterationFile(fileName): return profile.getAlterationFileContents(fileName)
def _engineSettings(self, extruderCount): #not used! settings = { 'layerThickness': int(profile.getProfileSettingFloat('layer_height') * 1000), 'initialLayerThickness': int(profile.getProfileSettingFloat('bottom_thickness') * 1000) if profile.getProfileSettingFloat('bottom_thickness') > 0.0 else int(profile.getProfileSettingFloat('layer_height') * 1000), 'filamentDiameter': int(profile.getProfileSettingFloat('filament_diameter') * 1000), 'filamentFlow': int(profile.getProfileSettingFloat('filament_flow')), 'extrusionWidth': int(profile.calculateEdgeWidth() * 1000), 'insetCount': int(profile.calculateLineCount()), 'downSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_bottom') == 'True' else 0, 'upSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_top') == 'True' else 0, 'sparseInfillLineDistance': int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('fill_density')) if profile.getProfileSettingFloat('fill_density') > 0 else -1, 'infillOverlap': int(profile.getProfileSettingFloat('fill_overlap')), 'initialSpeedupLayers': int(4), 'initialLayerSpeed': int(profile.getProfileSettingFloat('bottom_layer_speed')), 'printSpeed': int(profile.getProfileSettingFloat('print_speed')), 'infillSpeed': int(profile.getProfileSettingFloat('infill_speed')) if int(profile.getProfileSettingFloat('infill_speed')) > 0 else int(profile.getProfileSettingFloat('print_speed')), 'moveSpeed': int(profile.getProfileSettingFloat('travel_speed')), 'fanOnLayerNr': int(profile.getProfileSettingFloat('fan_layer')), 'fanSpeedMin': int(profile.getProfileSettingFloat('fan_speed')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'fanSpeedMax': int(profile.getProfileSettingFloat('fan_speed_max')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'supportAngle': int(-1) if profile.getProfileSetting('support') == 'None' else int(60), 'supportEverywhere': int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0), 'supportLineWidth': int(profile.getProfileSettingFloat('support_rate') * profile.calculateEdgeWidth() * 1000 / 100), 'retractionAmount': int(profile.getProfileSettingFloat('retraction_amount') * 1000) if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'retractionSpeed': int(profile.getProfileSettingFloat('retraction_speed')), 'retractionAmountExtruderSwitch': int(profile.getProfileSettingFloat('retraction_dual_amount') * 1000), 'multiVolumeOverlap': int(profile.getProfileSettingFloat('overlap_dual') * 1000), 'objectSink': int(profile.getProfileSettingFloat('object_sink') * 1000), 'minimalLayerTime': int(profile.getProfileSettingFloat('cool_min_layer_time')), 'minimalFeedrate': int(profile.getProfileSettingFloat('cool_min_feedrate')), 'coolHeadLift': 1 if profile.getProfileSetting('cool_head_lift') == 'True' else 0, 'startCode': profile.getAlterationFileContents('start.gcode', extruderCount), 'endCode': profile.getAlterationFileContents('end.gcode', extruderCount), 'extruderOffset[1].X': int(profile.getPreferenceFloat('extruder_offset_x1') * 1000), 'extruderOffset[1].Y': int(profile.getPreferenceFloat('extruder_offset_y1') * 1000), 'extruderOffset[2].X': int(profile.getPreferenceFloat('extruder_offset_x2') * 1000), 'extruderOffset[2].Y': int(profile.getPreferenceFloat('extruder_offset_y2') * 1000), 'extruderOffset[3].X': int(profile.getPreferenceFloat('extruder_offset_x3') * 1000), 'extruderOffset[3].Y': int(profile.getPreferenceFloat('extruder_offset_y3') * 1000), 'fixHorrible': 0, } if profile.getProfileSetting('platform_adhesion') == 'Brim': settings['skirtDistance'] = 0 settings['skirtLineCount'] = int(profile.getProfileSettingFloat('brim_line_count')) elif profile.getProfileSetting('platform_adhesion') == 'Raft': settings['skirtDistance'] = 0 settings['skirtLineCount'] = 0 settings['raftMargin'] = int(profile.getProfileSettingFloat('raft_margin') * 1000) settings['raftBaseThickness'] = int(profile.getProfileSettingFloat('raft_base_thickness') * 1000) settings['raftBaseLinewidth'] = int(profile.getProfileSettingFloat('raft_base_linewidth') * 1000) settings['raftInterfaceThickness'] = int(profile.getProfileSettingFloat('raft_interface_thickness') * 1000) settings['raftInterfaceLinewidth'] = int(profile.getProfileSettingFloat('raft_interface_linewidth') * 1000) else: settings['skirtDistance'] = int(profile.getProfileSettingFloat('skirt_gap') * 1000) settings['skirtLineCount'] = int(profile.getProfileSettingFloat('skirt_line_count')) if profile.getProfileSetting('fix_horrible_union_all_type_a') == 'True': settings['fixHorrible'] |= 0x01 if profile.getProfileSetting('fix_horrible_union_all_type_b') == 'True': settings['fixHorrible'] |= 0x02 if profile.getProfileSetting('fix_horrible_use_open_bits') == 'True': settings['fixHorrible'] |= 0x10 if profile.getProfileSetting('fix_horrible_extensive_stitching') == 'True': settings['fixHorrible'] |= 0x04 if settings['layerThickness'] <= 0: settings['layerThickness'] = 1000 return settings
def _engineSettings(self, extruderCount): settings = { "layerThickness": int(profile.getProfileSettingFloat("layer_height") * 1000), "initialLayerThickness": int(profile.getProfileSettingFloat("bottom_thickness") * 1000) if profile.getProfileSettingFloat("bottom_thickness") > 0.0 else int(profile.getProfileSettingFloat("layer_height") * 1000), "filamentDiameter": int(profile.getProfileSettingFloat("filament_diameter") * 1000), "filamentFlow": int(profile.getProfileSettingFloat("filament_flow")), "extrusionWidth": int(profile.calculateEdgeWidth() * 1000), "insetCount": int(profile.calculateLineCount()), "downSkinCount": int(profile.calculateSolidLayerCount()) if profile.getProfileSetting("solid_bottom") == "True" else 0, "upSkinCount": int(profile.calculateSolidLayerCount()) if profile.getProfileSetting("solid_top") == "True" else 0, "infillOverlap": int(profile.getProfileSettingFloat("fill_overlap")), "initialSpeedupLayers": int(4), "initialLayerSpeed": int(profile.getProfileSettingFloat("bottom_layer_speed")), "printSpeed": int(profile.getProfileSettingFloat("print_speed")), "infillSpeed": int(profile.getProfileSettingFloat("infill_speed")) if int(profile.getProfileSettingFloat("infill_speed")) > 0 else int(profile.getProfileSettingFloat("print_speed")), "moveSpeed": int(profile.getProfileSettingFloat("travel_speed")), "fanSpeedMin": int(profile.getProfileSettingFloat("fan_speed")) if profile.getProfileSetting("fan_enabled") == "True" else 0, "fanSpeedMax": int(profile.getProfileSettingFloat("fan_speed_max")) if profile.getProfileSetting("fan_enabled") == "True" else 0, "supportAngle": int(-1) if profile.getProfileSetting("support") == "None" else int(60), "supportEverywhere": int(1) if profile.getProfileSetting("support") == "Everywhere" else int(0), "supportLineDistance": int( 100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat("support_fill_rate") ) if profile.getProfileSettingFloat("support_fill_rate") > 0 else -1, "supportXYDistance": int(1000 * profile.getProfileSettingFloat("support_xy_distance")), "supportZDistance": int(1000 * profile.getProfileSettingFloat("support_z_distance")), "supportExtruder": 0 if profile.getProfileSetting("support_dual_extrusion") == "First extruder" else (1 if profile.getProfileSetting("support_dual_extrusion") == "Second extruder" else -1), "retractionAmount": int(profile.getProfileSettingFloat("retraction_amount") * 1000) if profile.getProfileSetting("retraction_enable") == "True" else 0, "retractionSpeed": int(profile.getProfileSettingFloat("retraction_speed")), "retractionMinimalDistance": int(profile.getProfileSettingFloat("retraction_min_travel") * 1000), "retractionAmountExtruderSwitch": int(profile.getProfileSettingFloat("retraction_dual_amount") * 1000), "minimalExtrusionBeforeRetraction": int( profile.getProfileSettingFloat("retraction_minimal_extrusion") * 1000 ), "enableCombing": 1 if profile.getProfileSetting("retraction_combing") == "True" else 0, "multiVolumeOverlap": int(profile.getProfileSettingFloat("overlap_dual") * 1000), "objectSink": int(profile.getProfileSettingFloat("object_sink") * 1000), "minimalLayerTime": int(profile.getProfileSettingFloat("cool_min_layer_time")), "minimalFeedrate": int(profile.getProfileSettingFloat("cool_min_feedrate")), "coolHeadLift": 1 if profile.getProfileSetting("cool_head_lift") == "True" else 0, "startCode": profile.getAlterationFileContents("start.gcode", extruderCount), "endCode": profile.getAlterationFileContents("end.gcode", extruderCount), "extruderOffset[1].X": int(profile.getMachineSettingFloat("extruder_offset_x1") * 1000), "extruderOffset[1].Y": int(profile.getMachineSettingFloat("extruder_offset_y1") * 1000), "extruderOffset[2].X": int(profile.getMachineSettingFloat("extruder_offset_x2") * 1000), "extruderOffset[2].Y": int(profile.getMachineSettingFloat("extruder_offset_y2") * 1000), "extruderOffset[3].X": int(profile.getMachineSettingFloat("extruder_offset_x3") * 1000), "extruderOffset[3].Y": int(profile.getMachineSettingFloat("extruder_offset_y3") * 1000), "fixHorrible": 0, } fanFullHeight = int(profile.getProfileSettingFloat("fan_full_height") * 1000) settings["fanFullOnLayerNr"] = (fanFullHeight - settings["initialLayerThickness"]) / settings[ "layerThickness" ] + 1 if settings["fanFullOnLayerNr"] < 0: settings["fanFullOnLayerNr"] = 0 if profile.getProfileSettingFloat("fill_density") == 0: settings["sparseInfillLineDistance"] = -1 elif profile.getProfileSettingFloat("fill_density") == 100: settings["sparseInfillLineDistance"] = settings["extrusionWidth"] # Set the up/down skins height to 10000 if we want a 100% filled object. # This gives better results then normal 100% infill as the sparse and up/down skin have some overlap. settings["downSkinCount"] = 10000 settings["upSkinCount"] = 10000 else: settings["sparseInfillLineDistance"] = int( 100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat("fill_density") ) if profile.getProfileSetting("platform_adhesion") == "Brim": settings["skirtDistance"] = 0 settings["skirtLineCount"] = int(profile.getProfileSettingFloat("brim_line_count")) elif profile.getProfileSetting("platform_adhesion") == "Raft": settings["skirtDistance"] = 0 settings["skirtLineCount"] = 0 settings["raftMargin"] = int(profile.getProfileSettingFloat("raft_margin") * 1000) settings["raftLineSpacing"] = int(profile.getProfileSettingFloat("raft_line_spacing") * 1000) settings["raftBaseThickness"] = int(profile.getProfileSettingFloat("raft_base_thickness") * 1000) settings["raftBaseLinewidth"] = int(profile.getProfileSettingFloat("raft_base_linewidth") * 1000) settings["raftInterfaceThickness"] = int(profile.getProfileSettingFloat("raft_interface_thickness") * 1000) settings["raftInterfaceLinewidth"] = int(profile.getProfileSettingFloat("raft_interface_linewidth") * 1000) else: settings["skirtDistance"] = int(profile.getProfileSettingFloat("skirt_gap") * 1000) settings["skirtLineCount"] = int(profile.getProfileSettingFloat("skirt_line_count")) settings["skirtMinLength"] = int(profile.getProfileSettingFloat("skirt_minimal_length") * 1000) if profile.getProfileSetting("fix_horrible_union_all_type_a") == "True": settings["fixHorrible"] |= 0x01 if profile.getProfileSetting("fix_horrible_union_all_type_b") == "True": settings["fixHorrible"] |= 0x02 if profile.getProfileSetting("fix_horrible_use_open_bits") == "True": settings["fixHorrible"] |= 0x10 if profile.getProfileSetting("fix_horrible_extensive_stitching") == "True": settings["fixHorrible"] |= 0x04 if settings["layerThickness"] <= 0: settings["layerThickness"] = 1000 if profile.getMachineSetting("gcode_flavor") == "UltiGCode": settings["gcodeFlavor"] = 1 return settings