def updateHeadSize(self, obj=None): xMin = profile.getMachineSettingFloat('extruder_head_size_min_x') xMax = profile.getMachineSettingFloat('extruder_head_size_max_x') yMin = profile.getMachineSettingFloat('extruder_head_size_min_y') yMax = profile.getMachineSettingFloat('extruder_head_size_max_y') gantryHeight = profile.getMachineSettingFloat( 'extruder_head_size_height') objectSink = profile.getProfileSettingFloat("object_sink") self._leftToRight = xMin < xMax self._frontToBack = yMin < yMax self._headSizeOffsets[0] = min(xMin, xMax) self._headSizeOffsets[1] = min(yMin, yMax) self._gantryHeight = gantryHeight self._oneAtATime = self._gantryHeight > 0 and profile.getPreference( 'oneAtATime') == 'True' for obj in self._objectList: if obj.getSize()[2] - objectSink > self._gantryHeight: self._oneAtATime = False headArea = numpy.array( [[-xMin, -yMin], [xMax, -yMin], [xMax, yMax], [-xMin, yMax]], numpy.float32) if obj is None: for obj in self._objectList: obj.setHeadArea(headArea, self._headSizeOffsets) else: obj.setHeadArea(headArea, self._headSizeOffsets)
def updateSizeOffsets(self, force=False): newOffsets = numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32) minExtruderCount = profile.minimalExtruderCount() if not force and numpy.array_equal( self._sizeOffsets, newOffsets) and self._minExtruderCount == minExtruderCount: return self._sizeOffsets = newOffsets self._minExtruderCount = minExtruderCount extends = [ numpy.array([[-newOffsets[0], -newOffsets[1]], [newOffsets[0], -newOffsets[1]], [newOffsets[0], newOffsets[1]], [-newOffsets[0], newOffsets[1]]], numpy.float32) ] for n in xrange(1, 4): headOffset = numpy.array( [[0, 0], [ -profile.getMachineSettingFloat('extruder_offset_x%d' % (n)), -profile.getMachineSettingFloat('extruder_offset_y%d' % (n)) ]], numpy.float32) extends.append(polygon.minkowskiHull(extends[n - 1], headOffset)) if minExtruderCount > 1: extends[0] = extends[1] for obj in self._objectList: obj.setPrintAreaExtends(extends[len(obj._meshList) - 1])
def updateHeadSize(self, obj = None): xMin = profile.getMachineSettingFloat('extruder_head_size_min_x') xMax = profile.getMachineSettingFloat('extruder_head_size_max_x') yMin = profile.getMachineSettingFloat('extruder_head_size_min_y') yMax = profile.getMachineSettingFloat('extruder_head_size_max_y') gantryHeight = profile.getMachineSettingFloat('extruder_head_size_height') self._leftToRight = xMin < xMax self._frontToBack = yMin < yMax self._headSizeOffsets[0] = min(xMin, xMax) self._headSizeOffsets[1] = min(yMin, yMax) self._gantryHeight = gantryHeight self._oneAtATime = profile.getMachineSettingBool('oneAtATime') #self._oneAtATime = False #self._oneAtATime = self._gantryHeight > 0 and profile.getPreference('oneAtATime') == 'True' #for obj in self._objectList: # if obj.getSize()[2] > self._gantryHeight: # self._oneAtATime = False headArea = numpy.array([[-xMin,-yMin],[ xMax,-yMin],[ xMax, yMax],[-xMin, yMax]], numpy.float32) if obj is None: for obj in self._objectList: obj.setHeadArea(headArea, self._headSizeOffsets) else: obj.setHeadArea(headArea, self._headSizeOffsets)
def updateMachineDimensions(self): self._machineSize = numpy.array([ profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth'), profile.getMachineSettingFloat('machine_height') ]) self._machinePolygons = profile.getMachineSizePolygons() self.updateHeadSize()
def updateHeadSize(self, obj=None): xMin = profile.getMachineSettingFloat('extruder_head_size_min_x') xMax = profile.getMachineSettingFloat('extruder_head_size_max_x') yMin = profile.getMachineSettingFloat('extruder_head_size_min_y') yMax = profile.getMachineSettingFloat('extruder_head_size_max_y') gantryHeight = profile.getMachineSettingFloat( 'extruder_head_size_height') objectSink = profile.getProfileSettingFloat("object_sink") self._leftToRight = xMin < xMax self._frontToBack = yMin < yMax self._headSizeOffsets[0] = min(xMin, xMax) self._headSizeOffsets[1] = min(yMin, yMax) self._gantryHeight = gantryHeight printOneAtATime = profile.getPreference('oneAtATime') == 'True' self._oneAtATime = self._gantryHeight > 0 and printOneAtATime if self._oneAtATime: if not self._lastOneAtATime: #print mode was changed by user. We need to reset that value to test with current scene content self._lastResultOneAtATime = True for obj in self._objectList: if obj.getSize()[2] - objectSink > self._gantryHeight: self._oneAtATime = False if self._lastResultOneAtATime: if self._sceneView: self._sceneView.notification.message( "Info: Print one at a time mode disabled. Object too tall." ) break if self._lastOneAtATime and self._oneAtATime and not self._lastResultOneAtATime: if self._sceneView: self._sceneView.notification.message( "Info: Print one at a time mode re-enabled.") self._lastResultOneAtATime = self._oneAtATime self._lastOneAtATime = printOneAtATime headArea = numpy.array( [[-xMin, -yMin], [xMax, -yMin], [xMax, yMax], [-xMin, yMax]], numpy.float32) if obj is None: for obj in self._objectList: obj.setHeadArea(headArea, self._headSizeOffsets) else: obj.setHeadArea(headArea, self._headSizeOffsets)
def getDefaultFirmware(): if profile.getMachineSetting('machine_type') == 'ultimaker': if profile.getMachineSetting('has_heated_bed') == 'True': return None if profile.getMachineSettingFloat('extruder_amount') > 2: return None if profile.getMachineSettingFloat('extruder_amount') > 1: if sys.platform.startswith('linux'): return resources.getPathForFirmware("MarlinUltimaker-115200-dual.hex") else: return resources.getPathForFirmware("MarlinUltimaker-250000-dual.hex") if sys.platform.startswith('linux'): return resources.getPathForFirmware("MarlinUltimaker-115200.hex") else: return resources.getPathForFirmware("MarlinUltimaker-250000.hex") return None
def onOneAtATimeSwitch(self, e): profile.putPreference('oneAtATime', self.oneAtATime.IsChecked()) if self.oneAtATime.IsChecked() and profile.getMachineSettingFloat('extruder_head_size_height') < 1: wx.MessageBox(_('For "One at a time" printing, you need to have entered the correct head size and gantry height in the machine settings'), _('One at a time warning'), wx.OK | wx.ICON_WARNING) self.scene.updateProfileToControls() self.scene._scene.pushFree() self.scene.sceneUpdated()
def validate(self): from Cura.util import profile try: wallThickness = profile.getProfileSettingFloat('wall_thickness') nozzleSize = profile.getMachineSettingFloat('nozzle_size') if wallThickness < 0.01: return SUCCESS, '' if wallThickness <= nozzleSize * 0.5: return ERROR, 'Trying to print walls thinner then the half of your nozzle size, this will not produce anything usable' if wallThickness <= nozzleSize * 0.85: return WARNING, 'Trying to print walls thinner then the 0.8 * nozzle size. Small chance that this will produce usable results' if wallThickness < nozzleSize: return SUCCESS, '' if nozzleSize <= 0: return ERROR, 'Incorrect nozzle size' lineCount = int(wallThickness / nozzleSize) lineWidth = wallThickness / lineCount lineWidthAlt = wallThickness / (lineCount + 1) if lineWidth >= nozzleSize * 1.5 and lineWidthAlt <= nozzleSize * 0.85: return WARNING, 'Current selected wall thickness results in a line thickness of ' + str(lineWidthAlt) + 'mm which is not recommended with your nozzle of ' + str(nozzleSize) + 'mm' return SUCCESS, '' except ValueError: #We already have an error by the int/float validator in this case. return SUCCESS, ''
def updateHeadSize(self, obj=None): xMin = profile.getMachineSettingFloat('extruder_head_size_min_x') xMax = profile.getMachineSettingFloat('extruder_head_size_max_x') yMin = profile.getMachineSettingFloat('extruder_head_size_min_y') yMax = profile.getMachineSettingFloat('extruder_head_size_max_y') gantryHeight = profile.getMachineSettingFloat( 'extruder_head_size_height') objectSink = profile.getProfileSettingFloat("object_sink") if profile.getPreference('startMode') == 'Simple': objectSink = float( profile.settingsDictionary["object_sink"].getDefault()) self._leftToRight = xMin < xMax self._frontToBack = yMin < yMax self._headSizeOffsets[0] = min(xMin, xMax) self._headSizeOffsets[1] = min(yMin, yMax) self._gantryHeight = gantryHeight printOneAtATime = profile.getPreference('oneAtATime') == 'True' self._oneAtATime = self._gantryHeight > 0 and printOneAtATime if self._oneAtATime: if not self._lastOneAtATime: #print mode was changed by user. We need to reset that value to test with current scene content self._lastResultOneAtATime = True for objIter in self._objectList: if objIter.getSize()[2] - objectSink > self._gantryHeight: self._oneAtATime = False if self._lastResultOneAtATime: if self._sceneView: self._sceneView.notification.message( "Object must be shorter than {}mm for this printer/tool head. Reduce object size or swap to \"All at once\" mode. " .format(self._gantryHeight)) break self._lastResultOneAtATime = self._oneAtATime self._lastOneAtATime = printOneAtATime headArea = numpy.array( [[-xMin, -yMin], [xMax, -yMin], [xMax, yMax], [-xMin, yMax]], numpy.float32) if obj is None: for obj in self._objectList: obj.setHeadArea(headArea, self._headSizeOffsets) else: obj.setHeadArea(headArea, self._headSizeOffsets)
def onOneAtATimeSwitch(self, e): profile.putPreference('oneAtATime', self.oneAtATime.IsChecked()) if self.oneAtATime.IsChecked() and profile.getMachineSetting('machine_type').startswith('BCN3D'): wx.MessageBox(_('At BCN3D we do not recommend printing with the "One at a time" option. Proceed with care.'), _('One at a time warning'), wx.OK | wx.ICON_WARNING) if self.oneAtATime.IsChecked() and profile.getMachineSettingFloat('extruder_head_size_height') < 1: wx.MessageBox(_('For "One at a time" printing, you need to have entered the correct head size and gantry height in the machine settings'), _('One at a time warning'), wx.OK | wx.ICON_WARNING) self.scene.updateProfileToControls() self.scene._scene.pushFree() self.scene.sceneUpdated()
def __init__(self, parent): wx.Panel.__init__(self, parent, wx.ID_ANY) self.dual_extrusion_printers = ['DiscoEasy200', 'DiscoUltimate', 'Perso2020'] self.multinozzle_printers = [] if profile.getPreferenceBool('show_magis_options'): self.multinozzle_printers.append('Magis') self.with_options_printers = self.dual_extrusion_printers + self.multinozzle_printers self.extruder_amount = profile.getMachineSettingInt('extruder_amount') self.nozzle_size = profile.getMachineSettingFloat('nozzle_size') self.oSizer = wx.FlexGridSizer(2, 2, 0, 0) self.dualExtrusionChoiceLabel = wx.StaticText(self, wx.ID_ANY, _('Dual extrusion :') + ' ') if sys.platform == 'darwin': #Change Combobox to an Choice cause in MAC OS X Combobox have some bug self.dualExtrusionChoice = wx.Choice(self, wx.ID_ANY, choices = [_('Yes'), _('No')]) else: self.dualExtrusionChoice = wx.ComboBox(self, wx.ID_ANY, choices = [_('Yes'), _('No')] , style=wx.CB_DROPDOWN | wx.CB_READONLY) if self.extruder_amount == 1: self.dualExtrusionChoice.SetSelection(1) else: self.dualExtrusionChoice.SetSelection(0) self.nozzleSizeChoiceLabel = wx.StaticText(self, wx.ID_ANY, _('Nozzle size :') + ' ') if sys.platform == 'darwin': #Change Combobox to an Choice cause in MAC OS X Combobox have some bug self.nozzleSizeChoice = wx.Choice(self, wx.ID_ANY, choices = [_('0.4 mm'), _('0.6 mm'), _('0.8 mm')]) else: self.nozzleSizeChoice = wx.ComboBox(self, wx.ID_ANY, choices = [_('0.4 mm'), _('0.6 mm'), _('0.8 mm')] , style=wx.CB_DROPDOWN | wx.CB_READONLY) if self.nozzle_size == 0.6: self.nozzleSizeChoice.SetSelection(1) elif self.nozzle_size == 0.8: self.nozzleSizeChoice.SetSelection(2) else: self.nozzleSizeChoice.SetSelection(0) self.oSizer.Add(self.dualExtrusionChoiceLabel) self.oSizer.Add(self.dualExtrusionChoice) self.oSizer.Add(self.nozzleSizeChoiceLabel) self.oSizer.Add(self.nozzleSizeChoice) if sys.platform == 'darwin': self.Bind(wx.EVT_CHOICE, self.OnDualExtrusionChanged, self.dualExtrusionChoice) self.Bind(wx.EVT_CHOICE, self.OnNozzleSizeChanged, self.nozzleSizeChoice) else: self.Bind(wx.EVT_COMBOBOX, self.OnDualExtrusionChanged, self.dualExtrusionChoice) self.Bind(wx.EVT_COMBOBOX, self.OnNozzleSizeChanged, self.nozzleSizeChoice) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(wx.StaticLine(self, -1), flag=wx.EXPAND|wx.TOP|wx.BOTTOM, border=5) sizer.Add(wx.StaticText(self, wx.ID_ANY, _("Which option(s) do you use?")), flag=wx.BOTTOM, border=5) sizer.Add(self.oSizer) self.SetAutoLayout(True) self.SetSizerAndFit(sizer) self.Layout()
def getDefaultFirmware(): if profile.getMachineSetting("machine_type") == "ultimaker": if profile.getMachineSetting("has_heated_bed") == "True": return None if profile.getMachineSettingFloat("extruder_amount") > 2: return None if profile.getMachineSettingFloat("extruder_amount") > 1: if sys.platform.startswith("linux"): return resources.getPathForFirmware("MarlinUltimaker-115200-dual.hex") else: return resources.getPathForFirmware("MarlinUltimaker-250000-dual.hex") if sys.platform.startswith("linux"): return resources.getPathForFirmware("MarlinUltimaker-115200.hex") else: return resources.getPathForFirmware("MarlinUltimaker-250000.hex") if profile.getMachineSetting("machine_type") == "ultimaker2": return resources.getPathForFirmware("MarlinUltimaker2.hex") return None
def getDefaultFirmware(machineIndex=None): if profile.getMachineSetting("machine_type", machineIndex) == "ultimaker": name = "MarlinUltimaker" if profile.getMachineSettingFloat("extruder_amount", machineIndex) > 2: return None if profile.getMachineSetting("has_heated_bed", machineIndex) == "True": name += "-HBK" if sys.platform.startswith("linux"): name += "-115200" else: name += "-250000" if profile.getMachineSettingFloat("extruder_amount", machineIndex) > 1: name += "-dual" return resources.getPathForFirmware(name + ".hex") if profile.getMachineSetting("machine_type", machineIndex) == "ultimaker2": return resources.getPathForFirmware("MarlinUltimaker2.hex") return None
def getDefaultFirmware(machineIndex = None): if profile.getMachineSetting('machine_type', machineIndex) == 'ultimaker': if profile.getMachineSetting('has_heated_bed', machineIndex) == 'True': return None if profile.getMachineSettingFloat('extruder_amount', machineIndex) > 2: return None if profile.getMachineSettingFloat('extruder_amount', machineIndex) > 1: if sys.platform.startswith('linux'): return resources.getPathForFirmware("MarlinUltimaker-115200-dual.hex") else: return resources.getPathForFirmware("MarlinUltimaker-250000-dual.hex") if sys.platform.startswith('linux'): return resources.getPathForFirmware("MarlinUltimaker-115200.hex") else: return resources.getPathForFirmware("MarlinUltimaker-250000.hex") if profile.getMachineSetting('machine_type', machineIndex) == 'ultimaker2': return resources.getPathForFirmware("MarlinUltimaker2.hex") return None
def updateHeadSize(self, obj = None): xMin = profile.getMachineSettingFloat('extruder_head_size_min_x') xMax = profile.getMachineSettingFloat('extruder_head_size_max_x') yMin = profile.getMachineSettingFloat('extruder_head_size_min_y') yMax = profile.getMachineSettingFloat('extruder_head_size_max_y') gantryHeight = profile.getMachineSettingFloat('extruder_head_size_height') objectSink = profile.getProfileSettingFloat("object_sink") self._leftToRight = xMin < xMax self._frontToBack = yMin < yMax self._headSizeOffsets[0] = min(xMin, xMax) self._headSizeOffsets[1] = min(yMin, yMax) self._gantryHeight = gantryHeight printOneAtATime = profile.getPreference('oneAtATime') == 'True' self._oneAtATime = self._gantryHeight > 0 and printOneAtATime if self._oneAtATime: if not self._lastOneAtATime: #print mode was changed by user. We need to reset that value to test with current scene content self._lastResultOneAtATime = True for objIter in self._objectList: if objIter.getSize()[2] - objectSink > self._gantryHeight: self._oneAtATime = False if self._lastResultOneAtATime: if self._sceneView: self._sceneView.notification.message("Info: Print one at a time mode disabled. Object too tall.") break if self._lastOneAtATime and self._oneAtATime and not self._lastResultOneAtATime: if self._sceneView: self._sceneView.notification.message("Info: Print one at a time mode re-enabled.") self._lastResultOneAtATime = self._oneAtATime self._lastOneAtATime = printOneAtATime headArea = numpy.array([[-xMin,-yMin],[ xMax,-yMin],[ xMax, yMax],[-xMin, yMax]], numpy.float32) if obj is None: for obj in self._objectList: obj.setHeadArea(headArea, self._headSizeOffsets) else: obj.setHeadArea(headArea, self._headSizeOffsets)
def getDefaultFirmware(machineIndex = None): if profile.getMachineSetting('machine_type', machineIndex) == 'ultimaker': name = 'MarlinUltimaker' if profile.getMachineSettingFloat('extruder_amount', machineIndex) > 2: return None if profile.getMachineSetting('has_heated_bed', machineIndex) == 'True': name += '-HBK' if sys.platform.startswith('linux'): name += '-115200' else: name += '-250000' if profile.getMachineSettingFloat('extruder_amount', machineIndex) > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if profile.getMachineSetting('machine_type', machineIndex) == 'ultimaker2': return resources.getPathForFirmware("MarlinUltimaker2.hex") if profile.getMachineSetting('machine_type', machineIndex) == 'Witbox': return resources.getPathForFirmware("MarlinWitbox.hex") return None
def getDefaultFirmware(machineIndex=None): if profile.getMachineSetting('machine_type', machineIndex) == 'ultimaker': name = 'MarlinUltimaker' if profile.getMachineSettingFloat('extruder_amount', machineIndex) > 2: return None if profile.getMachineSetting('has_heated_bed', machineIndex) == 'True': name += '-HBK' if sys.platform.startswith('linux'): name += '-115200' else: name += '-250000' if profile.getMachineSettingFloat('extruder_amount', machineIndex) > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if profile.getMachineSetting('machine_type', machineIndex) == 'ultimaker2': return resources.getPathForFirmware("MarlinUltimaker2.hex") if profile.getMachineSetting('machine_type', machineIndex) == 'Witbox': return resources.getPathForFirmware("MarlinWitbox.hex") return None
def updateHeadSize(self, obj = None): xMin = profile.getMachineSettingFloat('extruder_head_size_min_x') xMax = profile.getMachineSettingFloat('extruder_head_size_max_x') yMin = profile.getMachineSettingFloat('extruder_head_size_min_y') yMax = profile.getMachineSettingFloat('extruder_head_size_max_y') gantryHeight = profile.getMachineSettingFloat('extruder_head_size_height') objectSink = profile.getProfileSettingFloat("object_sink") if profile.getPreference('startMode') == 'Simple': objectSink = float(profile.settingsDictionary["object_sink"].getDefault()) self._leftToRight = xMin < xMax self._frontToBack = yMin < yMax self._headSizeOffsets[0] = min(xMin, xMax) self._headSizeOffsets[1] = min(yMin, yMax) self._gantryHeight = gantryHeight printOneAtATime = profile.getPreference('oneAtATime') == 'True' self._oneAtATime = self._gantryHeight > 0 and printOneAtATime if self._oneAtATime: if not self._lastOneAtATime: #print mode was changed by user. We need to reset that value to test with current scene content self._lastResultOneAtATime = True for objIter in self._objectList: if objIter.getSize()[2] - objectSink > self._gantryHeight: self._oneAtATime = False if self._lastResultOneAtATime: if self._sceneView: self._sceneView.notification.message("Object must be shorter than {}mm for this printer/tool head. Reduce object size or swap to \"All at once\" mode. ".format(self._gantryHeight)) break self._lastResultOneAtATime = self._oneAtATime self._lastOneAtATime = printOneAtATime headArea = numpy.array([[-xMin,-yMin],[ xMax,-yMin],[ xMax, yMax],[-xMin, yMax]], numpy.float32) if obj is None: for obj in self._objectList: obj.setHeadArea(headArea, self._headSizeOffsets) else: obj.setHeadArea(headArea, self._headSizeOffsets)
def getDefaultFirmware(machineIndex=None): machine_type = profile.getMachineSetting('machine_type', machineIndex) extruders = profile.getMachineSettingFloat('extruder_amount', machineIndex) heated_bed = profile.getMachineSetting('has_heated_bed', machineIndex) == 'True' baudrate = 250000 if sys.platform.startswith('linux'): baudrate = 115200 if machine_type == 'BCN3DSigma': return resources.getPathForFirmware("MarlinBCN3DSigma.hex") if machine_type == 'ultimaker': name = 'MarlinUltimaker' if extruders > 2: return None if heated_bed: name += '-HBK' name += '-%d' % (baudrate) if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker_plus': name = 'MarlinUltimaker-UMOP-%d' % (baudrate) if extruders > 2: return None if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker2': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2.hex") if machine_type == 'ultimaker2go': return resources.getPathForFirmware("MarlinUltimaker2go.hex") if machine_type == 'ultimaker2extended': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware( "MarlinUltimaker2extended-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2extended.hex") if machine_type == 'ultimaker2+': return resources.getPathForFirmware("MarlinUltimaker2Plus.hex") if machine_type == 'ultimaker2+extended': return resources.getPathForFirmware("MarlinUltimaker2PlusExtended.hex") if machine_type == 'Witbox': return resources.getPathForFirmware("MarlinWitbox.hex") return None
def __init__(self): self._feedPrint = profile.getProfileSettingFloat('print_speed') * 60 self._feedTravel = profile.getProfileSettingFloat('travel_speed') * 60 self._feedRetract = profile.getProfileSettingFloat('retraction_speed') * 60 filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentArea = math.pi * filamentRadius * filamentRadius self._ePerMM = (profile.getMachineSettingFloat('nozzle_size') * 0.1) / filamentArea self._eValue = 0.0 self._x = 0 self._y = 0 self._z = 0 self._list = ['M110', 'G92 E0']
def getDefaultFirmware(machineIndex = None): machine_type = profile.getMachineSetting('machine_type', machineIndex) extruders = profile.getMachineSettingFloat('extruder_amount', machineIndex) heated_bed = profile.getMachineSetting('has_heated_bed', machineIndex) == 'True' baudrate = 250000 if sys.platform.startswith('linux'): baudrate = 115200 if machine_type == 'BCN3DSigma': return resources.getPathForFirmware("MarlinBCN3DSigma.hex") if machine_type == 'ultimaker': name = 'MarlinUltimaker' if extruders > 2: return None if heated_bed: name += '-HBK' name += '-%d' % (baudrate) if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker_plus': name = 'MarlinUltimaker-UMOP-%d' % (baudrate) if extruders > 2: return None if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker2': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2.hex") if machine_type == 'ultimaker2go': return resources.getPathForFirmware("MarlinUltimaker2go.hex") if machine_type == 'ultimaker2extended': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2extended-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2extended.hex") if machine_type == 'ultimaker2+': return resources.getPathForFirmware("MarlinUltimaker2Plus.hex") if machine_type == 'ultimaker2+extended': return resources.getPathForFirmware("MarlinUltimaker2PlusExtended.hex") if machine_type == 'Witbox': return resources.getPathForFirmware("MarlinWitbox.hex") return None
def onOneAtATimeSwitch(self, e): profile.putPreference('oneAtATime', self.oneAtATime.IsChecked()) if self.oneAtATime.IsChecked() and profile.getMachineSetting( 'machine_type').startswith('BCN3D'): wx.MessageBox( _('At BCN3D we do not recommend printing with the "One at a time" option. Proceed with care.' ), _('One at a time warning'), wx.OK | wx.ICON_WARNING) if self.oneAtATime.IsChecked( ) and profile.getMachineSettingFloat('extruder_head_size_height') < 1: wx.MessageBox( _('For "One at a time" printing, you need to have entered the correct head size and gantry height in the machine settings' ), _('One at a time warning'), wx.OK | wx.ICON_WARNING) self.scene.updateProfileToControls() self.scene._scene.pushFree() self.scene.sceneUpdated()
def __init__(self): self._feedPrint = profile.getProfileSettingFloat('print_speed') * 60 self._feedTravel = profile.getProfileSettingFloat('travel_speed') * 60 self._feedRetract = profile.getProfileSettingFloat( 'retraction_speed') * 60 filamentRadius = profile.getProfileSettingFloat( 'filament_diameter') / 2 filamentArea = math.pi * filamentRadius * filamentRadius self._ePerMM = (profile.getMachineSettingFloat('nozzle_size') * 0.1) / filamentArea self._eValue = 0.0 self._x = 0 self._y = 0 self._z = 0 self._list = ['M110', 'G92 E0']
def updateSizeOffsets(self, force=False): newOffsets = numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32) minExtruderCount = profile.minimalExtruderCount() if not force and numpy.array_equal(self._sizeOffsets, newOffsets) and self._minExtruderCount == minExtruderCount: return self._sizeOffsets = newOffsets self._minExtruderCount = minExtruderCount extends = [numpy.array([[-newOffsets[0],-newOffsets[1]],[ newOffsets[0],-newOffsets[1]],[ newOffsets[0], newOffsets[1]],[-newOffsets[0], newOffsets[1]]], numpy.float32)] for n in xrange(1, 4): headOffset = numpy.array([[0, 0], [-profile.getMachineSettingFloat('extruder_offset_x%d' % (n)), -profile.getMachineSettingFloat('extruder_offset_y%d' % (n))]], numpy.float32) extends.append(polygon.minkowskiHull(extends[n-1], headOffset)) if minExtruderCount > 1: extends[0] = extends[1] for obj in self._objectList: obj.setPrintAreaExtends(extends[len(obj._meshList) - 1])
def getDefaultFirmware(machineIndex=None): machine_type = profile.getMachineSetting("machine_type", machineIndex) extruders = profile.getMachineSettingFloat("extruder_amount", machineIndex) heated_bed = profile.getMachineSetting("has_heated_bed", machineIndex) == "True" baudrate = 250000 if sys.platform.startswith("linux"): baudrate = 115200 if machine_type == "BCN3DSigma": return resources.getPathForFirmware("MarlinBCN3DSigma.hex") if machine_type == "ultimaker": name = "MarlinUltimaker" if extruders > 2: return None if heated_bed: name += "-HBK" name += "-%d" % (baudrate) if extruders > 1: name += "-dual" return resources.getPathForFirmware(name + ".hex") if machine_type == "ultimaker_plus": name = "MarlinUltimaker-UMOP-%d" % (baudrate) if extruders > 2: return None if extruders > 1: name += "-dual" return resources.getPathForFirmware(name + ".hex") if machine_type == "ultimaker2": if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2.hex") if machine_type == "ultimaker2go": return resources.getPathForFirmware("MarlinUltimaker2go.hex") if machine_type == "ultimaker2extended": if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2extended-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2extended.hex") if machine_type == "Witbox": return resources.getPathForFirmware("MarlinWitbox.hex") return None
def validate(self): from Cura.util import profile try: nozzleSize = profile.getMachineSettingFloat('nozzle_size') layerHeight = profile.getProfileSettingFloat('layer_height') printSpeed = profile.getProfileSettingFloat('print_speed') printVolumePerMM = layerHeight * nozzleSize printVolumePerSecond = printVolumePerMM * printSpeed #Using 10mm3 per second with a 0.4mm nozzle (normal max according to Joergen Geerds) maxPrintVolumePerSecond = 10 / (math.pi*(0.2*0.2)) * (math.pi*(nozzleSize/2*nozzleSize/2)) if printVolumePerSecond > maxPrintVolumePerSecond: return WARNING, 'You are trying to print more then %.1fmm^3 of filament per second. This might cause filament slipping. (You are printing at %0.1fmm^3 per second)' % (maxPrintVolumePerSecond, printVolumePerSecond) return SUCCESS, '' except ValueError: #We already have an error by the int/float validator in this case. return SUCCESS, ''
def updateMachineDimensions(self): self._machineSize = numpy.array([profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth'), profile.getMachineSettingFloat('machine_height')]) self._machinePolygons = profile.getMachineSizePolygons() self.updateHeadSize()
def __init__(self, parent): wx.Panel.__init__(self, parent, wx.ID_ANY) self.disco_addons_printers = ['DiscoEasy200', 'DiscoUltimate'] self.multinozzle_printers = [] if profile.getPreferenceBool('show_magis_options'): self.multinozzle_printers.append('Magis') self.with_options_printers = self.disco_addons_printers + self.multinozzle_printers self.extruder_amount = profile.getMachineSettingInt('extruder_amount') self.machine_width = profile.getMachineSettingFloat('machine_width') self.nozzle_size = profile.getMachineSettingFloat('nozzle_size') self.oSizer = wx.FlexGridSizer(3, 2, 0, 0) self.dualExtrusionChoiceLabel = wx.StaticText( self, wx.ID_ANY, _('Dual extrusion :') + ' ') if sys.platform == 'darwin': #Change Combobox to an Choice cause in MAC OS X Combobox have some bug self.dualExtrusionChoice = wx.Choice(self, wx.ID_ANY, size=(60, -1), choices=[_('Yes'), _('No')]) else: self.dualExtrusionChoice = wx.ComboBox(self, wx.ID_ANY, size=(60, -1), choices=[_('Yes'), _('No')], style=wx.CB_DROPDOWN | wx.CB_READONLY) if self.extruder_amount == 1: self.dualExtrusionChoice.SetSelection(1) else: self.dualExtrusionChoice.SetSelection(0) self.xlChoiceLabel = wx.StaticText(self, wx.ID_ANY, _('XL addon :') + ' ') if sys.platform == 'darwin': #Change Combobox to an Choice cause in MAC OS X Combobox have some bug self.xlChoice = wx.Choice(self, wx.ID_ANY, size=(60, -1), choices=[_('Yes'), _('No')]) else: self.xlChoice = wx.ComboBox(self, wx.ID_ANY, size=(60, -1), choices=[_('Yes'), _('No')], style=wx.CB_DROPDOWN | wx.CB_READONLY) if self.machine_width > 205: self.xlChoice.SetSelection(0) else: self.xlChoice.SetSelection(1) self.nozzleSizeChoiceLabel = wx.StaticText(self, wx.ID_ANY, _('Nozzle size :') + ' ') if sys.platform == 'darwin': #Change Combobox to an Choice cause in MAC OS X Combobox have some bug self.nozzleSizeChoice = wx.Choice( self, wx.ID_ANY, size=(60, -1), choices=[_('0.4 mm'), _('0.6 mm'), _('0.8 mm')]) else: self.nozzleSizeChoice = wx.ComboBox( self, wx.ID_ANY, size=(60, -1), choices=[_('0.4 mm'), _('0.6 mm'), _('0.8 mm')], style=wx.CB_DROPDOWN | wx.CB_READONLY) if self.nozzle_size == 0.6: self.nozzleSizeChoice.SetSelection(1) elif self.nozzle_size == 0.8: self.nozzleSizeChoice.SetSelection(2) else: self.nozzleSizeChoice.SetSelection(0) self.oSizer.Add(self.dualExtrusionChoiceLabel) self.oSizer.Add(self.dualExtrusionChoice) self.oSizer.Add(self.xlChoiceLabel) self.oSizer.Add(self.xlChoice) self.oSizer.Add(self.nozzleSizeChoiceLabel) self.oSizer.Add(self.nozzleSizeChoice) if sys.platform == 'darwin': self.Bind(wx.EVT_CHOICE, self.OnDualExtrusionChanged, self.dualExtrusionChoice) self.Bind(wx.EVT_CHOICE, self.OnXlChanged, self.xlChoice) self.Bind(wx.EVT_CHOICE, self.OnNozzleSizeChanged, self.nozzleSizeChoice) else: self.Bind(wx.EVT_COMBOBOX, self.OnDualExtrusionChanged, self.dualExtrusionChoice) self.Bind(wx.EVT_COMBOBOX, self.OnXlChanged, self.xlChoice) self.Bind(wx.EVT_COMBOBOX, self.OnNozzleSizeChanged, self.nozzleSizeChoice) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(wx.StaticLine(self, -1), flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=5) sizer.Add(wx.StaticText(self, wx.ID_ANY, _("Which option(s) do you use?")), flag=wx.BOTTOM, border=5) sizer.Add(self.oSizer) self.SetAutoLayout(True) self.SetSizerAndFit(sizer) self.Layout()
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
def OnResume(self, e): if self._wizardState == 2: self._wizardState = 3 wx.CallAfter(self.infoBox.SetBusy, 'Printing initial calibration cross') w = profile.getMachineSettingFloat('machine_width') d = profile.getMachineSettingFloat('machine_depth') gcode = gcodeGenerator.gcodeGenerator() gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2) gcode.setPrintSpeed(profile.getProfileSettingFloat('bottom_layer_speed')) gcode.addCmd('T0') gcode.addPrime(15) gcode.addCmd('T1') gcode.addPrime(15) gcode.addCmd('T0') gcode.addMove(w/2, 5) gcode.addMove(z=0.2) gcode.addPrime() gcode.addExtrude(w/2, d-5.0) gcode.addRetract() gcode.addMove(5, d/2) gcode.addPrime() gcode.addExtrude(w-5.0, d/2) gcode.addRetract(15) gcode.addCmd('T1') gcode.addMove(w/2, 5) gcode.addPrime() gcode.addExtrude(w/2, d-5.0) gcode.addRetract() gcode.addMove(5, d/2) gcode.addPrime() gcode.addExtrude(w-5.0, d/2) gcode.addRetract(15) gcode.addCmd('T0') gcode.addMove(z=25) gcode.addMove(0, 0) gcode.addCmd('M400') self.comm.printGCode(gcode.list()) self.resumeButton.Enable(False) elif self._wizardState == 4: try: float(self.textEntry.GetValue()) except ValueError: return profile.putPreference('extruder_offset_x1', self.textEntry.GetValue()) self._wizardState = 5 self.infoBox.SetAttention('Please measure the distance between the horizontal lines in millimeters.') self.textEntry.SetValue('0.0') self.textEntry.Enable(True) elif self._wizardState == 5: try: float(self.textEntry.GetValue()) except ValueError: return profile.putPreference('extruder_offset_y1', self.textEntry.GetValue()) self._wizardState = 6 self.infoBox.SetBusy('Printing the fine calibration lines.') self.textEntry.SetValue('') self.textEntry.Enable(False) self.resumeButton.Enable(False) x = profile.getMachineSettingFloat('extruder_offset_x1') y = profile.getMachineSettingFloat('extruder_offset_y1') gcode = gcodeGenerator.gcodeGenerator() gcode.setExtrusionRate(profile.getProfileSettingFloat('nozzle_size') * 1.5, 0.2) gcode.setPrintSpeed(25) gcode.addHome() gcode.addCmd('T0') gcode.addMove(50, 40, 0.2) gcode.addPrime(15) for n in xrange(0, 10): gcode.addExtrude(50 + n * 10, 150) gcode.addExtrude(50 + n * 10 + 5, 150) gcode.addExtrude(50 + n * 10 + 5, 40) gcode.addExtrude(50 + n * 10 + 10, 40) gcode.addMove(40, 50) for n in xrange(0, 10): gcode.addExtrude(150, 50 + n * 10) gcode.addExtrude(150, 50 + n * 10 + 5) gcode.addExtrude(40, 50 + n * 10 + 5) gcode.addExtrude(40, 50 + n * 10 + 10) gcode.addRetract(15) gcode.addCmd('T1') gcode.addMove(50 - x, 30 - y, 0.2) gcode.addPrime(15) for n in xrange(0, 10): gcode.addExtrude(50 + n * 10.2 - 1.0 - x, 140 - y) gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 140 - y) gcode.addExtrude(50 + n * 10.2 - 1.0 + 5.1 - x, 30 - y) gcode.addExtrude(50 + n * 10.2 - 1.0 + 10 - x, 30 - y) gcode.addMove(30 - x, 50 - y, 0.2) for n in xrange(0, 10): gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 - y) gcode.addExtrude(160 - x, 50 + n * 10.2 - 1.0 + 5.1 - y) gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 5.1 - y) gcode.addExtrude(30 - x, 50 + n * 10.2 - 1.0 + 10 - y) gcode.addRetract(15) gcode.addMove(z=15) gcode.addCmd('M400') gcode.addCmd('M104 T0 S0') gcode.addCmd('M104 T1 S0') self.comm.printGCode(gcode.list()) elif self._wizardState == 7: try: n = int(self.textEntry.GetValue()) - 1 except: return x = profile.getMachineSettingFloat('extruder_offset_x1') x += -1.0 + n * 0.1 profile.putPreference('extruder_offset_x1', '%0.2f' % (x)) self.infoBox.SetAttention('Which horizontal line number lays perfect on top of each other? Front most line is zero.') self.textEntry.SetValue('10') self._wizardState = 8 elif self._wizardState == 8: try: n = int(self.textEntry.GetValue()) - 1 except: return y = profile.getMachineSettingFloat('extruder_offset_y1') y += -1.0 + n * 0.1 profile.putPreference('extruder_offset_y1', '%0.2f' % (y)) self.infoBox.SetInfo('Calibration finished. Offsets are: %s %s' % (profile.getMachineSettingFloat('extruder_offset_x1'), profile.getMachineSettingFloat('extruder_offset_y1'))) self.infoBox.SetReadyIndicator() self._wizardState = 8 self.comm.close() self.resumeButton.Enable(False)
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 _load(self, gcodeFile): self.layerList = [] pos = [0.0, 0.0, 0.0] posOffset = [0.0, 0.0, 0.0] currentE = 0.0 totalExtrusion = 0.0 maxExtrusion = 0.0 currentExtruder = 0 extrudeAmountMultiply = 1.0 totalMoveTimeMinute = 0.0 absoluteE = True scale = 1.0 posAbs = True feedRate = 3600.0 moveType = "move" layerThickness = 0.1 pathType = "CUSTOM" currentLayer = [] currentPath = gcodePath("move", pathType, layerThickness, pos) currentPath["extruder"] = currentExtruder currentLayer.append(currentPath) for line in gcodeFile: if type(line) is tuple: line = line[0] # Parse Cura_SF comments if line.startswith(";TYPE:"): pathType = line[6:].strip() if ";" in line: # Slic3r GCode comment parser comment = line[line.find(";") + 1 :].strip() if comment == "fill": pathType = "FILL" elif comment == "perimeter": pathType = "WALL-INNER" elif comment == "skirt": pathType = "SKIRT" if comment.startswith("LAYER:"): currentPath = gcodePath(moveType, pathType, layerThickness, currentPath["points"][-1]) currentPath["extruder"] = currentExtruder for path in currentLayer: path["points"] = numpy.array(path["points"], numpy.float32) path["extrusion"] = numpy.array(path["extrusion"], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None: if self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)): # Abort the loading, we can safely return as the results here will be discarded gcodeFile.close() return currentLayer = [currentPath] line = line[0 : line.find(";")] T = getCodeInt(line, "T") if T is not None: if currentExtruder > 0: posOffset[0] -= profile.getMachineSettingFloat("extruder_offset_x%d" % (currentExtruder)) posOffset[1] -= profile.getMachineSettingFloat("extruder_offset_y%d" % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset[0] += profile.getMachineSettingFloat("extruder_offset_x%d" % (currentExtruder)) posOffset[1] += profile.getMachineSettingFloat("extruder_offset_y%d" % (currentExtruder)) G = getCodeInt(line, "G") if G is not None: if G == 0 or G == 1: # Move x = getCodeFloat(line, "X") y = getCodeFloat(line, "Y") z = getCodeFloat(line, "Z") e = getCodeFloat(line, "E") # f = getCodeFloat(line, 'F') oldPos = pos pos = pos[:] if posAbs: if x is not None: pos[0] = x * scale + posOffset[0] if y is not None: pos[1] = y * scale + posOffset[1] if z is not None: pos[2] = z * scale + posOffset[2] else: if x is not None: pos[0] += x * scale if y is not None: pos[1] += y * scale if z is not None: pos[2] += z * scale # if f is not None: # feedRate = f # if x is not None or y is not None or z is not None: # diffX = oldPos[0] - pos[0] # diffY = oldPos[1] - pos[1] # totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRate moveType = "move" if e is not None: if absoluteE: e -= currentE if e > 0.0: moveType = "extrude" if e < 0.0: moveType = "retract" totalExtrusion += e currentE += e if totalExtrusion > maxExtrusion: maxExtrusion = totalExtrusion else: e = 0.0 if moveType == "move" and oldPos[2] != pos[2]: if oldPos[2] > pos[2] and abs(oldPos[2] - pos[2]) > 5.0 and pos[2] < 1.0: oldPos[2] = 0.0 layerThickness = abs(oldPos[2] - pos[2]) if currentPath["type"] != moveType or currentPath["pathType"] != pathType: currentPath = gcodePath(moveType, pathType, layerThickness, currentPath["points"][-1]) currentPath["extruder"] = currentExtruder currentLayer.append(currentPath) currentPath["points"].append(pos) currentPath["extrusion"].append(e * extrudeAmountMultiply) elif G == 4: # Delay S = getCodeFloat(line, "S") if S is not None: totalMoveTimeMinute += S / 60.0 P = getCodeFloat(line, "P") if P is not None: totalMoveTimeMinute += P / 60.0 / 1000.0 elif G == 10: # Retract currentPath = gcodePath("retract", pathType, layerThickness, currentPath["points"][-1]) currentPath["extruder"] = currentExtruder currentLayer.append(currentPath) currentPath["points"].append(currentPath["points"][0]) elif G == 11: # Push back after retract pass elif G == 20: # Units are inches scale = 25.4 elif G == 21: # Units are mm scale = 1.0 elif G == 28: # Home x = getCodeFloat(line, "X") y = getCodeFloat(line, "Y") z = getCodeFloat(line, "Z") center = [0.0, 0.0, 0.0] if x is None and y is None and z is None: pos = center else: pos = pos[:] if x is not None: pos[0] = center[0] if y is not None: pos[1] = center[1] if z is not None: pos[2] = center[2] elif G == 90: # Absolute position posAbs = True elif G == 91: # Relative position posAbs = False elif G == 92: x = getCodeFloat(line, "X") y = getCodeFloat(line, "Y") z = getCodeFloat(line, "Z") e = getCodeFloat(line, "E") if e is not None: currentE = e if x is not None: posOffset[0] = pos[0] - x if y is not None: posOffset[1] = pos[1] - y if z is not None: posOffset[2] = pos[2] - z else: print "Unknown G code:" + str(G) else: M = getCodeInt(line, "M") if M is not None: if M == 0: # Message with possible wait (ignored) pass elif M == 1: # Message with possible wait (ignored) pass elif M == 80: # Enable power supply pass elif M == 81: # Suicide/disable power supply pass elif M == 82: # Absolute E absoluteE = True elif M == 83: # Relative E absoluteE = False elif M == 84: # Disable step drivers pass elif M == 92: # Set steps per unit pass elif M == 101: # Enable extruder pass elif M == 103: # Disable extruder pass elif M == 104: # Set temperature, no wait pass elif M == 105: # Get temperature pass elif M == 106: # Enable fan pass elif M == 107: # Disable fan pass elif M == 108: # Extruder RPM (these should not be in the final GCode, but they are) pass elif M == 109: # Set temperature, wait pass elif M == 110: # Reset N counter pass elif M == 113: # Extruder PWM (these should not be in the final GCode, but they are) pass elif M == 117: # LCD message pass elif M == 140: # Set bed temperature pass elif M == 190: # Set bed temperature & wait pass elif M == 221: # Extrude amount multiplier s = getCodeFloat(line, "S") if s is not None: extrudeAmountMultiply = s / 100.0 else: print "Unknown M code:" + str(M) for path in currentLayer: path["points"] = numpy.array(path["points"], numpy.float32) path["extrusion"] = numpy.array(path["extrusion"], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None and self._fileSize > 0: self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)) self.extrusionAmount = maxExtrusion self.totalMoveTimeMinute = totalMoveTimeMinute
def _load(self, gcodeFile): self.layerList = [] pos = [0.0, 0.0, 0.0] posOffset = [0.0, 0.0, 0.0] currentE = 0.0 currentExtruder = 0 extrudeAmountMultiply = 1.0 absoluteE = True scale = 1.0 posAbs = True feedRate = 3600.0 moveType = 'move' layerThickness = 0.1 pathType = 'CUSTOM' currentLayer = [] currentPath = gcodePath('move', pathType, layerThickness, pos) currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) for line in gcodeFile: if type(line) is tuple: line = line[0] #Parse Cura_SF comments if line.startswith(';TYPE:'): pathType = line[6:].strip() if ';' in line: comment = line[line.find(';') + 1:].strip() #Slic3r GCode comment parser if comment == 'fill': pathType = 'FILL' elif comment == 'perimeter': pathType = 'WALL-INNER' elif comment == 'skirt': pathType = 'SKIRT' #Cura layer comments. if comment.startswith('LAYER:'): currentPath = gcodePath(moveType, pathType, layerThickness, currentPath['points'][-1]) layerThickness = 0.0 currentPath['extruder'] = currentExtruder for path in currentLayer: path['points'] = numpy.array(path['points'], numpy.float32) path['extrusion'] = numpy.array( path['extrusion'], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None: if self.progressCallback( float(gcodeFile.tell()) / float(self._fileSize)): #Abort the loading, we can safely return as the results here will be discarded gcodeFile.close() return currentLayer = [currentPath] line = line[0:line.find(';')] T = getCodeInt(line, 'T') if T is not None: if currentExtruder > 0: posOffset[0] -= profile.getMachineSettingFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset[1] -= profile.getMachineSettingFloat( 'extruder_offset_y%d' % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset[0] += profile.getMachineSettingFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset[1] += profile.getMachineSettingFloat( 'extruder_offset_y%d' % (currentExtruder)) G = getCodeInt(line, 'G') if G is not None: if G == 0 or G == 1: #Move x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') e = getCodeFloat(line, 'E') #f = getCodeFloat(line, 'F') oldPos = pos pos = pos[:] if posAbs: if x is not None: pos[0] = x * scale + posOffset[0] if y is not None: pos[1] = y * scale + posOffset[1] if z is not None: pos[2] = z * scale + posOffset[2] else: if x is not None: pos[0] += x * scale if y is not None: pos[1] += y * scale if z is not None: pos[2] += z * scale moveType = 'move' if e is not None: if absoluteE: e -= currentE if e > 0.0: moveType = 'extrude' if e < 0.0: moveType = 'retract' currentE += e else: e = 0.0 if moveType == 'move' and oldPos[2] != pos[2]: if oldPos[2] > pos[2] and abs( oldPos[2] - pos[2]) > 5.0 and pos[2] < 1.0: oldPos[2] = 0.0 if layerThickness == 0.0: layerThickness = abs(oldPos[2] - pos[2]) if currentPath['type'] != moveType or currentPath[ 'pathType'] != pathType: currentPath = gcodePath(moveType, pathType, layerThickness, currentPath['points'][-1]) currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) currentPath['points'].append(pos) currentPath['extrusion'].append(e * extrudeAmountMultiply) elif G == 4: #Delay S = getCodeFloat(line, 'S') P = getCodeFloat(line, 'P') elif G == 10: #Retract currentPath = gcodePath('retract', pathType, layerThickness, currentPath['points'][-1]) currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) currentPath['points'].append(currentPath['points'][0]) elif G == 11: #Push back after retract pass elif G == 20: #Units are inches scale = 25.4 elif G == 21: #Units are mm scale = 1.0 elif G == 28: #Home x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') center = [0.0, 0.0, 0.0] if x is None and y is None and z is None: pos = center else: pos = pos[:] if x is not None: pos[0] = center[0] if y is not None: pos[1] = center[1] if z is not None: pos[2] = center[2] elif G == 90: #Absolute position posAbs = True elif G == 91: #Relative position posAbs = False elif G == 92: x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') e = getCodeFloat(line, 'E') if e is not None: currentE = e #if x is not None: # posOffset[0] = pos[0] - x #if y is not None: # posOffset[1] = pos[1] - y #if z is not None: # posOffset[2] = pos[2] - z else: print "Unknown G code:" + str(G) else: M = getCodeInt(line, 'M') if M is not None: if M == 0: #Message with possible wait (ignored) pass elif M == 1: #Message with possible wait (ignored) pass elif M == 25: #Stop SD printing pass elif M == 80: #Enable power supply pass elif M == 81: #Suicide/disable power supply pass elif M == 82: #Absolute E absoluteE = True elif M == 83: #Relative E absoluteE = False elif M == 84: #Disable step drivers pass elif M == 92: #Set steps per unit pass elif M == 101: #Enable extruder pass elif M == 103: #Disable extruder pass elif M == 104: #Set temperature, no wait pass elif M == 105: #Get temperature pass elif M == 106: #Enable fan pass elif M == 107: #Disable fan pass elif M == 108: #Extruder RPM (these should not be in the final GCode, but they are) pass elif M == 109: #Set temperature, wait pass elif M == 110: #Reset N counter pass elif M == 113: #Extruder PWM (these should not be in the final GCode, but they are) pass elif M == 117: #LCD message pass elif M == 140: #Set bed temperature pass elif M == 190: #Set bed temperature & wait pass elif M == 221: #Extrude amount multiplier s = getCodeFloat(line, 'S') if s is not None: extrudeAmountMultiply = s / 100.0 else: print "Unknown M code:" + str(M) for path in currentLayer: path['points'] = numpy.array(path['points'], numpy.float32) path['extrusion'] = numpy.array(path['extrusion'], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None and self._fileSize > 0: self.progressCallback( float(gcodeFile.tell()) / float(self._fileSize))
def getDefaultFirmware(machineIndex = None): firmwareDict = { 'ultimaker2go':"MarlinUltimaker2go.hex", 'Witbox':"MarlinWitbox.hex", #TAZ Budaschnozzle 'lulzbot_TAZ_4_SingleV1': "TAZ4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_5_SingleV1': "TAZ4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_4_FlexystruderV1': "TAZ4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_5_FlexystruderV1': "TAZ4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_4_DualV1': "TAZ4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_5_DualV1': "TAZ4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_4_FlexyDuallyV1': "TAZ4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_5_FlexyDuallyV1': "TAZ4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", #TAZ Hexagon 'lulzbot_TAZ_4_05nozzle': "TAZ4-5-Standard-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_4_035nozzle': "TAZ4-5-Standard-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_5_05nozzle': "TAZ4-5-Standard-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_5_035nozzle': "TAZ4-5-Standard-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_4_FlexystruderV2': "TAZ4-5-Flexystruder-LBHexagon-1.0.0.2.hex", 'lulzbot_TAZ_5_FlexystruderV2': "TAZ4-5-Flexystruder-LBHexagon-1.0.0.2.hex", 'lulzbot_TAZ_4_DualV2': "TAZ4-5-Dual-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_5_DualV2': "TAZ4-5-Dual-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_4_FlexyDuallyV2': "TAZ4-5-FlexyDually-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_5_FlexyDuallyV2': "TAZ4-5-FlexyDually-LBHexagon-1.0.0.1.hex", 'lulzbot_TAZ_5_Moarstruder': "TAZ5-Moarstruder-LBHexagon-1.0.0.2.hex", #TAZ 6 'lulzbot_TAZ_6_Single_v2.1': "TAZ6_Single_Extruder_v1.0.2.22.hex", 'lulzbot_TAZ_6_Flexystruder_v2': "TAZ6_Flexystruder_v1.0.2.22.hex", 'lulzbot_TAZ_6_Moarstruder': "TAZ6_Moarstruder_v1.0.2.22.hex", 'lulzbot_TAZ_6_Dual_v2': "TAZ6_Dual_v1.0.2.22.hex", 'lulzbot_TAZ_6_FlexyDually_v2': "TAZ6_Dual_v1.0.2.22.hex", #Mini 'lulzbot_mini': "Mini-Single-or-Flexystruder-LBHexagon-v1.1.0.11.hex", 'lulzbot_mini_flexystruder': "Mini-Single-or-Flexystruder-LBHexagon-v1.1.0.11.hex", } machine_type = profile.getMachineSetting('machine_type', machineIndex) extruders = profile.getMachineSettingFloat('extruder_amount', machineIndex) heated_bed = profile.getMachineSetting('has_heated_bed', machineIndex) == 'True' baudrate = 250000 if sys.platform.startswith('linux'): baudrate = 115200 if machine_type == 'ultimaker': name = 'MarlinUltimaker' if extruders > 2: return None if heated_bed: name += '-HBK' name += '-%d' % (baudrate) if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker_plus': name = 'MarlinUltimaker-UMOP-%d' % (baudrate) if extruders > 2: return None if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker2': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2.hex") if machine_type == 'ultimaker2extended': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2extended-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2extended.hex") if firmwareDict.has_key(machine_type): return resources.getPathForFirmware(firmwareDict[machine_type]) return None
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, '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
pauseState = 0 f.write(";TYPE:CUSTOM\n") #Retract f.write("M83\n") f.write("G1 E-%f F6000\n" % (retractAmount)) zChanged = False #Change z before doing the move because the nozzle can hit the glass lock on the UM2 if z + moveZ < 15: zChanged = True f.write("G1 Z15 F300\n") elif moveZ > 0: newZ = z + moveZ maxZ = profile.getMachineSettingFloat('machine_height') - 10 #For Safety Leave a 10mm space (endstop) if maxZ < newZ: newZ = maxZ if newZ > z: zChanged = True f.write("G1 Z%f F300\n" % (newZ)) #Comment to say what we're doing f.write(";PAUSING PRINT\n"); #Move the head away f.write("G1 X%f Y%f F9000\n" % (parkX, parkY)) #Disable the E steppers f.write("M84 E0\n")
def getDefaultFirmware(machineIndex=None): firmwareDict = { 'ultimaker2go': "MarlinUltimaker2go.hex", 'Witbox': "MarlinWitbox.hex", 'lulzbot_mini': "Mini-Single-or-Flexystruder-LBHexagon-2015Q2.hex", 'lulzbot_mini_flexystruder': "Mini-Single-or-Flexystruder-LBHexagon-2015Q2.hex", 'lulzbot_TAZ_4_SingleV1': "Taz4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_5_SingleV1': "Taz4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_4_05nozzle': "Taz4-Single-Extruder-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_5_05nozzle': "Taz5-Single-Extruder-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_4_035nozzle': "Taz4-Single-Extruder-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_5_035nozzle': "Taz5-Single-Extruder-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_4_FlexystruderV1': "Taz4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_5_FlexystruderV1': "Taz4-5-Single-or-Flexystruder-Budaschnozzle-2014Q3.hex", 'lulzbot_TAZ_4_FlexystruderV2': "Taz4-5-Flexystruder-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_5_FlexystruderV2': "Taz4-5-Flexystruder-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_4_DualV1': "Taz4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_5_DualV1': "Taz4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_4_DualV2': "Taz4-5-Dual-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_5_DualV2': "Taz4-5-Dual-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_4_FlexyDuallyV1': "Taz4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_5_FlexyDuallyV1': "Taz4-5-Dual-or-FlexyDually-Budaschnozzle-2015Q1.hex", 'lulzbot_TAZ_4_FlexyDuallyV2': "Taz4-5-FlexyDually-LBHexagon-2015Q3.hex", 'lulzbot_TAZ_5_FlexyDuallyV2': "Taz4-5-FlexyDually-LBHexagon-2015Q3.hex" } machine_type = profile.getMachineSetting('machine_type', machineIndex) extruders = profile.getMachineSettingFloat('extruder_amount', machineIndex) heated_bed = profile.getMachineSetting('has_heated_bed', machineIndex) == 'True' baudrate = 250000 if sys.platform.startswith('linux'): baudrate = 115200 if machine_type == 'ultimaker': name = 'MarlinUltimaker' if extruders > 2: return None if heated_bed: name += '-HBK' name += '-%d' % (baudrate) if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker_plus': name = 'MarlinUltimaker-UMOP-%d' % (baudrate) if extruders > 2: return None if extruders > 1: name += '-dual' return resources.getPathForFirmware(name + '.hex') if machine_type == 'ultimaker2': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware("MarlinUltimaker2-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2.hex") if machine_type == 'ultimaker2extended': if extruders > 2: return None if extruders > 1: return resources.getPathForFirmware( "MarlinUltimaker2extended-dual.hex") return resources.getPathForFirmware("MarlinUltimaker2extended.hex") if firmwareDict.has_key(machine_type): return resources.getPathForFirmware(firmwareDict[machine_type]) return None
def OnDraw(self): if not self._enabled: return self._resultLock.acquire() result = self._result if result is not None: gcodeLayers = result.getGCodeLayers(self._gcodeLoadCallback) if result._polygons is not None and len(result._polygons) > 0: self.layerSelect.setRange(1, len(result._polygons)) elif gcodeLayers is not None and len(gcodeLayers) > 0: self.layerSelect.setRange(1, len(gcodeLayers)) else: gcodeLayers = None glPushMatrix() glEnable(GL_BLEND) if profile.getMachineSetting('machine_center_is_zero') != 'True': glTranslate(-profile.getMachineSettingFloat('machine_width') / 2, -profile.getMachineSettingFloat('machine_depth') / 2, 0) glLineWidth(2) layerNr = self.layerSelect.getValue() if layerNr == self.layerSelect.getMaxValue() and result is not None and len(result._polygons) > 0: layerNr = max(layerNr, len(result._polygons)) if result is not None and len(result._polygons) > layerNr-1 and 'inset0' in result._polygons[layerNr-1] and len(result._polygons[layerNr-1]['inset0']) > 0 and len(result._polygons[layerNr-1]['inset0'][0]) > 0: viewZ = result._polygons[layerNr-1]['inset0'][0][0][2] else: viewZ = (layerNr - 1) * profile.getProfileSettingFloat('layer_height') + profile.getProfileSettingFloat('bottom_thickness') self._parent._viewTarget[2] = viewZ msize = max(profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth')) lineTypeList = [ ('inset0', 'WALL-OUTER', [1,0,0,1]), ('insetx', 'WALL-INNER', [0,1,0,1]), ('openoutline', None, [1,0,0,1]), ('skin', 'SKIN', [1,1,0,1]), ('infill', 'FILL', [1,1,0,1]), ('support', 'SUPPORT', [0,1,1,1]), ('skirt', 'SKIRT', [0,1,1,1]), ('outline', None, [0,0,0,1]) ] n = layerNr - 1 generatedVBO = False if result is not None: while n >= 0: if layerNr - n > 30 and n % 20 == 0 and len(result._polygons) > 0: idx = n / 20 while len(self._layer20VBOs) < idx + 1: self._layer20VBOs.append({}) if result._polygons is not None and n + 20 < len(result._polygons): layerVBOs = self._layer20VBOs[idx] for typeName, typeNameGCode, color in lineTypeList: allow = typeName in result._polygons[n + 19] if typeName == 'skirt': for i in xrange(0, 20): if typeName in result._polygons[n + i]: allow = True if allow: if typeName not in layerVBOs: if generatedVBO: continue polygons = [] for i in xrange(0, 20): if typeName in result._polygons[n + i]: polygons += result._polygons[n + i][typeName] layerVBOs[typeName] = self._polygonsToVBO_lines(polygons) generatedVBO = True glColor4f(color[0]*0.5,color[1]*0.5,color[2]*0.5,color[3]) layerVBOs[typeName].render() n -= 20 else: c = 1.0 - ((layerNr - n) - 1) * 0.05 c = max(0.5, c) while len(self._layerVBOs) < n + 1: self._layerVBOs.append({}) layerVBOs = self._layerVBOs[n] if gcodeLayers is not None and ((layerNr - 10 < n < (len(gcodeLayers) - 1)) or len(result._polygons) < 1): for typeNamePolygons, typeName, color in lineTypeList: if typeName is None: continue if 'GCODE-' + typeName not in layerVBOs: layerVBOs['GCODE-' + typeName] = self._gcodeToVBO_quads(gcodeLayers[n+1:n+2], typeName) glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3]) layerVBOs['GCODE-' + typeName].render() if n == layerNr - 1: if 'GCODE-MOVE' not in layerVBOs: layerVBOs['GCODE-MOVE'] = self._gcodeToVBO_lines(gcodeLayers[n+1:n+2]) glColor4f(0,0,c,1) layerVBOs['GCODE-MOVE'].render() elif n < len(result._polygons): polygons = result._polygons[n] for typeName, typeNameGCode, color in lineTypeList: if typeName in polygons: if typeName not in layerVBOs: layerVBOs[typeName] = self._polygonsToVBO_lines(polygons[typeName]) glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3]) layerVBOs[typeName].render() n -= 1 glPopMatrix() if generatedVBO: self._parent._queueRefresh() if gcodeLayers is not None and self._gcodeLoadProgress != 0.0 and self._gcodeLoadProgress != 1.0: glPushMatrix() glLoadIdentity() glTranslate(0,-0.8,-2) glColor4ub(60,60,60,255) openglHelpers.glDrawStringCenter(_("Loading toolpath for visualization (%d%%)") % (self._gcodeLoadProgress * 100)) glPopMatrix() self._resultLock.release()
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 OnResume(self, e): feedZ = profile.getProfileSettingFloat('print_speed') * 60 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60 if self._wizardState == 2: wx.CallAfter(self.infoBox.SetBusy, 'Moving head to back left corner...') self.comm.sendCommand('G1 Z3 F%d' % (feedZ)) self.comm.sendCommand('G1 X%d Y%d F%d' % (0, profile.getMachineSettingFloat('machine_depth'), feedTravel)) self.comm.sendCommand('G1 Z0 F%d' % (feedZ)) self.comm.sendCommand('M400') self._wizardState = 3 elif self._wizardState == 4: wx.CallAfter(self.infoBox.SetBusy, 'Moving head to back right corner...') self.comm.sendCommand('G1 Z3 F%d' % (feedZ)) self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, profile.getMachineSettingFloat('machine_depth') - 25, feedTravel)) self.comm.sendCommand('G1 Z0 F%d' % (feedZ)) self.comm.sendCommand('M400') self._wizardState = 5 elif self._wizardState == 6: wx.CallAfter(self.infoBox.SetBusy, 'Moving head to front right corner...') self.comm.sendCommand('G1 Z3 F%d' % (feedZ)) self.comm.sendCommand('G1 X%d Y%d F%d' % (profile.getMachineSettingFloat('machine_width') - 5.0, 20, feedTravel)) self.comm.sendCommand('G1 Z0 F%d' % (feedZ)) self.comm.sendCommand('M400') self._wizardState = 7 elif self._wizardState == 8: wx.CallAfter(self.infoBox.SetBusy, 'Heating up printer...') self.comm.sendCommand('G1 Z15 F%d' % (feedZ)) self.comm.sendCommand('M104 S%d' % (profile.getProfileSettingFloat('print_temperature'))) self.comm.sendCommand('G1 X%d Y%d F%d' % (0, 0, feedTravel)) self._wizardState = 9 elif self._wizardState == 10: self._wizardState = 11 wx.CallAfter(self.infoBox.SetInfo, 'Printing a square on the printer bed at 0.3mm height.') feedZ = profile.getProfileSettingFloat('print_speed') * 60 feedPrint = profile.getProfileSettingFloat('print_speed') * 60 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60 w = profile.getMachineSettingFloat('machine_width') d = profile.getMachineSettingFloat('machine_depth') filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2 filamentArea = math.pi * filamentRadius * filamentRadius ePerMM = (profile.calculateEdgeWidth() * 0.3) / filamentArea eValue = 0.0 gcodeList = [ 'G1 Z2 F%d' % (feedZ), 'G92 E0', 'G1 X%d Y%d F%d' % (5, 5, feedTravel), 'G1 Z0.3 F%d' % (feedZ)] eValue += 5.0 gcodeList.append('G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60)) for i in xrange(0, 3): dist = 5.0 + 0.4 * float(i) eValue += (d - 2.0*dist) * ePerMM gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, d - dist, eValue, feedPrint)) eValue += (w - 2.0*dist) * ePerMM gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, d - dist, eValue, feedPrint)) eValue += (d - 2.0*dist) * ePerMM gcodeList.append('G1 X%f Y%f E%f F%d' % (w - dist, dist, eValue, feedPrint)) eValue += (w - 2.0*dist) * ePerMM gcodeList.append('G1 X%f Y%f E%f F%d' % (dist, dist, eValue, feedPrint)) gcodeList.append('M400') self.comm.printGCode(gcodeList) self.resumeButton.Enable(False)
def __init__(self): """ Creates the window which controls the printing process """ super(printWindow, self).__init__(None, -1, title=_("Printing")) t = time.time() self.machineCom = None self.gcode = None self.gcodeList = None self.sendList = [] self.temp = None self.bedTemp = None self.bufferLineCount = 4 self.sendCnt = 0 self.feedrateRatioOuterWall = 1.0 self.feedrateRatioInnerWall = 1.0 self.feedrateRatioFill = 1.0 self.feedrateRatioSupport = 1.0 self.pause = False self.termHistory = [] self.termHistoryIdx = 0 self.cam = None self.height = profile.getMachineSettingFloat('machine_height') self.width = profile.getMachineSettingFloat('machine_width') self.depth = profile.getMachineSettingFloat('machine_depth') self.SetSizer(wx.BoxSizer()) self.panel = wx.Panel(self) self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND) self.sizer = wx.GridBagSizer(2, 2) self.panel.SetSizer(self.sizer) sb = wx.StaticBox(self.panel, label=_("Statistics")) boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) self.powerWarningText = wx.StaticText(parent=self.panel, id=-1, label=_("Your computer is running on battery power.\nConnect your computer to AC power or your print might not finish."), style=wx.ALIGN_CENTER) self.powerWarningText.SetBackgroundColour('red') self.powerWarningText.SetForegroundColour('white') boxsizer.AddF(self.powerWarningText, flags=wx.SizerFlags().Expand().Border(wx.BOTTOM, 10)) self.powerManagement = power.PowerManagement() self.powerWarningTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnPowerWarningChange, self.powerWarningTimer) self.OnPowerWarningChange(None) self.powerWarningTimer.Start(10000) self.statsText = wx.StaticText(self.panel, -1, _("Filament: ####.##m #.##g\nEstimated print time: #####:##\nMachine state:\nDetecting baudrateXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")) boxsizer.Add(self.statsText, flag=wx.LEFT, border=5) self.sizer.Add(boxsizer, pos=(0, 0), span=(7, 1), flag=wx.EXPAND) self.connectButton = wx.Button(self.panel, -1, _("Connect")) #self.loadButton = wx.Button(self.panel, -1, 'Load') self.printButton = wx.Button(self.panel, -1, _("Print")) self.pauseButton = wx.Button(self.panel, -1, _("Pause")) self.elevateButton = wx.Button(self.panel, -1, _("Elevate")) self.cancelButton = wx.Button(self.panel, -1, _("Cancel print")) self.machineLogButton = wx.Button(self.panel, -1, _("Error log")) self.progress = wx.Gauge(self.panel, -1) self.sizer.Add(self.connectButton, pos=(1, 1), flag=wx.EXPAND) #self.sizer.Add(self.loadButton, pos=(1,1), flag=wx.EXPAND) self.sizer.Add(self.printButton, pos=(2, 1), flag=wx.EXPAND) self.sizer.Add(self.pauseButton, pos=(3, 1), flag=wx.EXPAND) self.sizer.Add(self.elevateButton, pos=(4, 1), flag=wx.EXPAND) self.sizer.Add(self.cancelButton, pos=(5, 1), flag=wx.EXPAND) self.sizer.Add(self.machineLogButton, pos=(6, 1), flag=wx.EXPAND) self.sizer.Add(self.progress, pos=(7, 0), span=(1, 7), flag=wx.EXPAND) nb = wx.Notebook(self.panel) self.tabs = nb self.sizer.Add(nb, pos=(0, 2), span=(7, 4), flag=wx.EXPAND) self.temperaturePanel = wx.Panel(nb) sizer = wx.GridBagSizer(2, 2) self.temperaturePanel.SetSizer(sizer) self.temperatureSelect = wx.SpinCtrl(self.temperaturePanel, -1, '0', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.temperatureSelect.SetRange(0, 400) self.temperatureHeatUp = wx.Button(self.temperaturePanel, -1, str(int(profile.getProfileSettingFloat('print_temperature'))) + 'C') self.bedTemperatureLabel = wx.StaticText(self.temperaturePanel, -1, _("BedTemp:")) self.bedTemperatureSelect = wx.SpinCtrl(self.temperaturePanel, -1, '0', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.bedTemperatureSelect.SetRange(0, 400) self.bedTemperatureLabel.Show(False) self.bedTemperatureSelect.Show(False) self.temperatureGraph = temperatureGraph(self.temperaturePanel) sizer.Add(wx.StaticText(self.temperaturePanel, -1, _("Temp:")), pos=(0, 0)) sizer.Add(self.temperatureSelect, pos=(0, 1)) sizer.Add(self.temperatureHeatUp, pos=(0, 2)) sizer.Add(self.bedTemperatureLabel, pos=(1, 0)) sizer.Add(self.bedTemperatureSelect, pos=(1, 1)) sizer.Add(self.temperatureGraph, pos=(2, 0), span=(1, 3), flag=wx.EXPAND) sizer.AddGrowableRow(2) sizer.AddGrowableCol(2) nb.AddPage(self.temperaturePanel, 'Temp') self.directControlPanel = wx.Panel(nb) sizer = wx.GridBagSizer(2, 2) self.directControlPanel.SetSizer(sizer) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y100 F6000', 'G90'], 'print-move-y100.png'), pos=(0, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y10 F6000', 'G90'], 'print-move-y10.png'), pos=(1, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y1 F6000', 'G90'], 'print-move-y1.png'), pos=(2, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y-1 F6000', 'G90'], 'print-move-y-1.png'), pos=(4, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y-10 F6000', 'G90'], 'print-move-y-10.png'), pos=(5, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Y-100 F6000', 'G90'], 'print-move-y-100.png'), pos=(6, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 X-100 F6000', 'G90'], 'print-move-x-100.png'), pos=(3, 0)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 X-10 F6000', 'G90'], 'print-move-x-10.png'), pos=(3, 1)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 X-1 F6000', 'G90'], 'print-move-x-1.png'), pos=(3, 2)) sizer.Add(PrintCommandButton(self, ['G28 X0 Y0'], 'print-move-home.png'), pos=(3, 3)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 X1 F6000', 'G90'], 'print-move-x1.png'), pos=(3, 4)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 X10 F6000', 'G90'], 'print-move-x10.png'), pos=(3, 5)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 X100 F6000', 'G90'], 'print-move-x100.png'), pos=(3, 6)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z10 F200', 'G90'], 'print-move-z10.png'), pos=(0, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z1 F200', 'G90'], 'print-move-z1.png'), pos=(1, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z0.1 F200', 'G90'], 'print-move-z0.1.png'), pos=(2, 8)) sizer.Add(PrintCommandButton(self, ['G28 Z0'], 'print-move-home.png'), pos=(3, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-0.1 F200', 'G90'], 'print-move-z-0.1.png'), pos=(4, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-1 F200', 'G90'], 'print-move-z-1.png'), pos=(5, 8)) sizer.Add(PrintCommandButton(self, ['G91', 'G1 Z-10 F200', 'G90'], 'print-move-z-10.png'), pos=(6, 8)) #Calibration buttons sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (self.width - 10, 20)], 'print-calibrateUL.png'), pos=(1, 9)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (self.width - 10, self.depth - 10)], 'print-calibrateDL.png'), pos=(5, 9)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (20, 20)], 'print-calibrateUR.png'), pos=(1, 13)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (20, self.depth - 10)], 'print-calibrateDR.png'), pos=(5, 13)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (self.width/2, self.depth/2)], 'print-calibrate-center.png'), pos=(3, 11)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (3*self.width/4, self.depth/4)], 'print-calibrate-center-UL.png'), pos=(2, 10)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (3*self.width/4, 3*self.depth/4)], 'print-calibrate-center-DL.png'), pos=(4, 10)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (self.width/4, self.depth/4)], 'print-calibrate-center-UR.png'), pos=(2, 12)) sizer.Add(PrintCommandButton(self, ['G1 X%s Y%s F6000' % (self.width/4, 3*self.depth/4)], 'print-calibrate-center-DR.png'), pos=(4, 12)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E2 F120'], 'extrude.png', size=(60, 20)), pos=(8, 8)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E5 F120'], 'extrude5.png'), pos=(8, 9)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E10 F120'], 'extrude10.png'), pos=(8, 10)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E20 F120'], 'extrude20.png'), pos=(8, 11)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-2 F120'], 'retract.png', size=(60, 20)), pos=(9, 8)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-5 F120'], 'retract5.png'), pos=(9, 9)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-10 F120'], 'retract10.png'), pos=(9, 10)) sizer.Add(PrintCommandButton(self, ['G92 E0', 'G1 E-20 F120'], 'retract20.png'), pos=(9, 11)) nb.AddPage(self.directControlPanel, _("Jog")) self.speedPanel = wx.Panel(nb) sizer = wx.GridBagSizer(2, 2) self.speedPanel.SetSizer(sizer) self.outerWallSpeedSelect = wx.SpinCtrl(self.speedPanel, -1, '100', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.outerWallSpeedSelect.SetRange(5, 1000) self.innerWallSpeedSelect = wx.SpinCtrl(self.speedPanel, -1, '100', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.innerWallSpeedSelect.SetRange(5, 1000) self.fillSpeedSelect = wx.SpinCtrl(self.speedPanel, -1, '100', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.fillSpeedSelect.SetRange(5, 1000) self.supportSpeedSelect = wx.SpinCtrl(self.speedPanel, -1, '100', size=(21 * 3, 21), style=wx.SP_ARROW_KEYS) self.supportSpeedSelect.SetRange(5, 1000) sizer.Add(wx.StaticText(self.speedPanel, -1, _("Outer wall:")), pos=(0, 0)) sizer.Add(self.outerWallSpeedSelect, pos=(0, 1)) sizer.Add(wx.StaticText(self.speedPanel, -1, "%"), pos=(0, 2)) sizer.Add(wx.StaticText(self.speedPanel, -1, _("Inner wall:")), pos=(1, 0)) sizer.Add(self.innerWallSpeedSelect, pos=(1, 1)) sizer.Add(wx.StaticText(self.speedPanel, -1, "%"), pos=(1, 2)) sizer.Add(wx.StaticText(self.speedPanel, -1, _("Fill:")), pos=(2, 0)) sizer.Add(self.fillSpeedSelect, pos=(2, 1)) sizer.Add(wx.StaticText(self.speedPanel, -1, "%"), pos=(2, 2)) sizer.Add(wx.StaticText(self.speedPanel, -1, _("Support:")), pos=(3, 0)) sizer.Add(self.supportSpeedSelect, pos=(3, 1)) sizer.Add(wx.StaticText(self.speedPanel, -1, "%"), pos=(3, 2)) nb.AddPage(self.speedPanel, _("Speed")) self.termPanel = wx.Panel(nb) sizer = wx.GridBagSizer(2, 2) self.termPanel.SetSizer(sizer) f = wx.Font(8, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False) self.termLog = wx.TextCtrl(self.termPanel, style=wx.TE_MULTILINE | wx.TE_DONTWRAP) self.termLog.SetFont(f) self.termLog.SetEditable(0) self.termInput = wx.TextCtrl(self.termPanel, style=wx.TE_PROCESS_ENTER) self.termInput.SetFont(f) sizer.Add(self.termLog, pos=(0, 0), flag=wx.EXPAND) sizer.Add(self.termInput, pos=(1, 0), flag=wx.EXPAND) sizer.AddGrowableCol(0) sizer.AddGrowableRow(0) nb.AddPage(self.termPanel, _("Term")) self.sizer.AddGrowableRow(6) self.sizer.AddGrowableCol(3) self.Bind(wx.EVT_CLOSE, self.OnClose) self.connectButton.Bind(wx.EVT_BUTTON, self.OnConnect) #self.loadButton.Bind(wx.EVT_BUTTON, self.OnLoad) self.printButton.Bind(wx.EVT_BUTTON, self.OnPrint) self.pauseButton.Bind(wx.EVT_BUTTON, self.OnPause) self.elevateButton.Bind(wx.EVT_BUTTON, self.OnElevate) self.cancelButton.Bind(wx.EVT_BUTTON, self.OnCancel) self.machineLogButton.Bind(wx.EVT_BUTTON, self.OnMachineLog) self.Bind(wx.EVT_BUTTON, lambda e: (self.temperatureSelect.SetValue(int(profile.getProfileSettingFloat('print_temperature'))), self.machineCom.sendCommand("M104 S%d" % (int(profile.getProfileSettingFloat('print_temperature'))))), self.temperatureHeatUp) self.Bind(wx.EVT_SPINCTRL, self.OnTempChange, self.temperatureSelect) self.Bind(wx.EVT_SPINCTRL, self.OnBedTempChange, self.bedTemperatureSelect) self.Bind(wx.EVT_SPINCTRL, self.OnSpeedChange, self.outerWallSpeedSelect) self.Bind(wx.EVT_SPINCTRL, self.OnSpeedChange, self.innerWallSpeedSelect) self.Bind(wx.EVT_SPINCTRL, self.OnSpeedChange, self.fillSpeedSelect) self.Bind(wx.EVT_SPINCTRL, self.OnSpeedChange, self.supportSpeedSelect) self.Bind(wx.EVT_TEXT_ENTER, self.OnTermEnterLine, self.termInput) self.termInput.Bind(wx.EVT_CHAR, self.OnTermKey) self.Layout() self.Fit() self.Centre() self.statsText.SetMinSize(self.statsText.GetSize()) self.UpdateButtonStates() #self.UpdateProgress() self._thread = threading.Thread(target=self._stdinMonitor) self._thread.daemon = True self._thread.start() if webcam.hasWebcamSupport() and profile.getPreference('camera_enabled') == 'True': #Need to call the camera class on the GUI thread, or else it won't work. Shame as it hangs the GUI for about 2 seconds. wx.CallAfter(self._webcamCheck)
def OnDraw(self): if not self._enabled: return self._resultLock.acquire() result = self._result if result is not None: gcodeLayers = result.getGCodeLayers(self._gcodeLoadCallback) if result._polygons is not None and len(result._polygons) > 0: self.layerSelect.setRange(1, len(result._polygons)) elif gcodeLayers is not None and len(gcodeLayers) > 0: self.layerSelect.setRange(1, len(gcodeLayers)) else: gcodeLayers = None glPushMatrix() glEnable(GL_BLEND) if profile.getMachineSetting('machine_center_is_zero') != 'True': glTranslate(-profile.getMachineSettingFloat('machine_width') / 2, -profile.getMachineSettingFloat('machine_depth') / 2, 0) glLineWidth(2) layerNr = self.layerSelect.getValue() if layerNr == self.layerSelect.getMaxValue() and result is not None and len(result._polygons) > 0: layerNr = max(layerNr, len(result._polygons)) if result is not None and len(result._polygons) > layerNr-1 and 'inset0' in result._polygons[layerNr-1] and len(result._polygons[layerNr-1]['inset0']) > 0 and len(result._polygons[layerNr-1]['inset0'][0]) > 0: viewZ = result._polygons[layerNr-1]['inset0'][0][0][2] else: viewZ = (layerNr - 1) * profile.getProfileSettingFloat('layer_height') + profile.getProfileSettingFloat('bottom_thickness') self._parent._viewTarget[2] = viewZ msize = max(profile.getMachineSettingFloat('machine_width'), profile.getMachineSettingFloat('machine_depth')) lineTypeList = [ ('inset0', 'WALL-OUTER', [1,0,0,1]), ('insetx', 'WALL-INNER', [0,1,0,1]), ('openoutline', None, [1,0,0,1]), ('skin', 'SKIN', [1,1,0,1]), ('infill', 'FILL', [1,1,0,1]), ('support', 'SUPPORT', [0,1,1,1]), ('skirt', 'SKIRT', [0,1,1,1]), ('outline', None, [0,0,0,1]) ] n = layerNr - 1 generatedVBO = False if result is not None: while n >= 0: if layerNr - n > 30 and n % 20 == 0 and len(result._polygons) > 0: idx = n / 20 while len(self._layer20VBOs) < idx + 1: self._layer20VBOs.append({}) if result._polygons is not None and n + 20 < len(result._polygons): layerVBOs = self._layer20VBOs[idx] for typeName, typeNameGCode, color in lineTypeList: allow = typeName in result._polygons[n + 19] if typeName == 'skirt': for i in xrange(0, 20): if typeName in result._polygons[n + i]: allow = True if allow: if typeName not in layerVBOs: if generatedVBO: continue polygons = [] for i in xrange(0, 20): if typeName in result._polygons[n + i]: polygons += result._polygons[n + i][typeName] layerVBOs[typeName] = self._polygonsToVBO_lines(polygons) generatedVBO = True if not self._singleLayer or n == layerNr - 1: glColor4f(color[0]*0.5,color[1]*0.5,color[2]*0.5,color[3]) layerVBOs[typeName].render() n -= 20 else: c = 1.0 - ((layerNr - n) - 1) * 0.05 c = max(0.5, c) while len(self._layerVBOs) < n + 1: self._layerVBOs.append({}) layerVBOs = self._layerVBOs[n] if gcodeLayers is not None and ((layerNr - 10 < n < (len(gcodeLayers) - 1)) or len(result._polygons) < 1): for typeNamePolygons, typeName, color in lineTypeList: if typeName is None: continue if 'GCODE-' + typeName not in layerVBOs: layerVBOs['GCODE-' + typeName] = self._gcodeToVBO_quads(gcodeLayers[n+1:n+2], typeName) if not self._singleLayer or n == layerNr - 1: glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3]) layerVBOs['GCODE-' + typeName].render() if n == layerNr - 1: if 'GCODE-MOVE' not in layerVBOs: layerVBOs['GCODE-MOVE'] = self._gcodeToVBO_lines(gcodeLayers[n+1:n+2]) glColor4f(0,0,c,1) layerVBOs['GCODE-MOVE'].render() elif n < len(result._polygons): polygons = result._polygons[n] for typeName, typeNameGCode, color in lineTypeList: if typeName in polygons: if typeName not in layerVBOs: layerVBOs[typeName] = self._polygonsToVBO_lines(polygons[typeName]) if not self._singleLayer or n == layerNr - 1: glColor4f(color[0]*c,color[1]*c,color[2]*c,color[3]) layerVBOs[typeName].render() n -= 1 glPopMatrix() if generatedVBO: self._parent._queueRefresh() if gcodeLayers is not None and self._gcodeLoadProgress != 0.0 and self._gcodeLoadProgress != 1.0: glPushMatrix() glLoadIdentity() glTranslate(0,-0.8,-2) glColor4ub(60,60,60,255) openglHelpers.glDrawStringCenter(_("Loading toolpath for visualization (%d%%)") % (self._gcodeLoadProgress * 100)) glPopMatrix() self._resultLock.release()
def _load(self, gcodeFile): self.layerList = [] pos = [0.0,0.0,0.0] posOffset = [0.0, 0.0, 0.0] currentE = 0.0 currentExtruder = 0 extrudeAmountMultiply = 1.0 absoluteE = True scale = 1.0 posAbs = True feedRate = 3600.0 moveType = 'move' layerThickness = 0.1 pathType = 'CUSTOM' currentLayer = [] currentPath = gcodePath('move', pathType, layerThickness, pos) currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) for line in gcodeFile: if type(line) is tuple: line = line[0] #Parse Cura_SF comments if line.startswith(';TYPE:'): pathType = line[6:].strip() if ';' in line: comment = line[line.find(';')+1:].strip() #Slic3r GCode comment parser if comment == 'fill': pathType = 'FILL' elif comment == 'perimeter': pathType = 'WALL-INNER' elif comment == 'skirt': pathType = 'SKIRT' #Cura layer comments. if comment.startswith('LAYER:'): currentPath = gcodePath(moveType, pathType, layerThickness, currentPath['points'][-1]) layerThickness = 0.0 currentPath['extruder'] = currentExtruder for path in currentLayer: path['points'] = numpy.array(path['points'], numpy.float32) path['extrusion'] = numpy.array(path['extrusion'], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None: if self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)): #Abort the loading, we can safely return as the results here will be discarded gcodeFile.close() return currentLayer = [currentPath] line = line[0:line.find(';')] T = getCodeInt(line, 'T') if T is not None: if currentExtruder > 0: posOffset[0] -= profile.getMachineSettingFloat('extruder_offset_x%d' % (currentExtruder)) posOffset[1] -= profile.getMachineSettingFloat('extruder_offset_y%d' % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset[0] += profile.getMachineSettingFloat('extruder_offset_x%d' % (currentExtruder)) posOffset[1] += profile.getMachineSettingFloat('extruder_offset_y%d' % (currentExtruder)) G = getCodeInt(line, 'G') if G is not None: if G == 0 or G == 1: #Move x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') e = getCodeFloat(line, 'E') #f = getCodeFloat(line, 'F') oldPos = pos pos = pos[:] if posAbs: if x is not None: pos[0] = x * scale + posOffset[0] if y is not None: pos[1] = y * scale + posOffset[1] if z is not None: pos[2] = z * scale + posOffset[2] else: if x is not None: pos[0] += x * scale if y is not None: pos[1] += y * scale if z is not None: pos[2] += z * scale moveType = 'move' if e is not None: if absoluteE: e -= currentE if e > 0.0: moveType = 'extrude' if e < 0.0: moveType = 'retract' currentE += e else: e = 0.0 if moveType == 'move' and oldPos[2] != pos[2]: if oldPos[2] > pos[2] and abs(oldPos[2] - pos[2]) > 5.0 and pos[2] < 1.0: oldPos[2] = 0.0 if layerThickness == 0.0: layerThickness = abs(oldPos[2] - pos[2]) if currentPath['type'] != moveType or currentPath['pathType'] != pathType: currentPath = gcodePath(moveType, pathType, layerThickness, currentPath['points'][-1]) currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) currentPath['points'].append(pos) currentPath['extrusion'].append(e * extrudeAmountMultiply) elif G == 4: #Delay S = getCodeFloat(line, 'S') P = getCodeFloat(line, 'P') elif G == 10: #Retract currentPath = gcodePath('retract', pathType, layerThickness, currentPath['points'][-1]) currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) currentPath['points'].append(currentPath['points'][0]) elif G == 11: #Push back after retract pass elif G == 20: #Units are inches scale = 25.4 elif G == 21: #Units are mm scale = 1.0 elif G == 28: #Home x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') center = [0.0,0.0,0.0] if x is None and y is None and z is None: pos = center else: pos = pos[:] if x is not None: pos[0] = center[0] if y is not None: pos[1] = center[1] if z is not None: pos[2] = center[2] elif G == 90: #Absolute position posAbs = True elif G == 91: #Relative position posAbs = False elif G == 92: x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') e = getCodeFloat(line, 'E') if e is not None: currentE = e #if x is not None: # posOffset[0] = pos[0] - x #if y is not None: # posOffset[1] = pos[1] - y #if z is not None: # posOffset[2] = pos[2] - z else: print "Unknown G code:" + str(G) else: M = getCodeInt(line, 'M') if M is not None: if M == 0: #Message with possible wait (ignored) pass elif M == 1: #Message with possible wait (ignored) pass elif M == 25: #Stop SD printing pass elif M == 80: #Enable power supply pass elif M == 81: #Suicide/disable power supply pass elif M == 82: #Absolute E absoluteE = True elif M == 83: #Relative E absoluteE = False elif M == 84: #Disable step drivers pass elif M == 92: #Set steps per unit pass elif M == 101: #Enable extruder pass elif M == 103: #Disable extruder pass elif M == 104: #Set temperature, no wait pass elif M == 105: #Get temperature pass elif M == 106: #Enable fan pass elif M == 107: #Disable fan pass elif M == 108: #Extruder RPM (these should not be in the final GCode, but they are) pass elif M == 109: #Set temperature, wait pass elif M == 110: #Reset N counter pass elif M == 113: #Extruder PWM (these should not be in the final GCode, but they are) pass elif M == 117: #LCD message pass elif M == 140: #Set bed temperature pass elif M == 190: #Set bed temperature & wait pass elif M == 221: #Extrude amount multiplier s = getCodeFloat(line, 'S') if s is not None: extrudeAmountMultiply = s / 100.0 else: print "Unknown M code:" + str(M) for path in currentLayer: path['points'] = numpy.array(path['points'], numpy.float32) path['extrusion'] = numpy.array(path['extrusion'], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None and self._fileSize > 0: self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize))