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 while hasLine: hasLine = False for f in files: 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')) 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 _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 while hasLine: hasLine = False for f in files: 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')) 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 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 = subprocess.Popen(action.sliceCmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 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: print line 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('machine_center_x', action.centerX - self.extruderOffset[action.extruder][0]) put('machine_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 resultFile.write(profile.getAlterationFileContents('start.gcode')) else: #reset the extrusion length, and move to the next object center. resultFile.write(';TYPE:CUSTOM\n') if prevTemp != action.temperature: 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') 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() if cost != False: status += "\nCost: %s" % (cost) profile.replaceGCodeTags(self.resultFilename, gcode) wx.CallAfter(self.statusText.SetLabel, status) wx.CallAfter(self.OnSliceDone)
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')), '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), '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['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 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('machine_center_x', action.centerX - self.extruderOffset[action.extruder][0]) put('machine_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() if cost != False: status += "\nCost: %s" % (cost) profile.replaceGCodeTags(self.resultFilename, gcode) wx.CallAfter(self.statusText.SetLabel, status) wx.CallAfter(self.OnSliceDone)