def OnResume(self, e): feedZ = profile.getProfileSettingFloat('max_z_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.getPreferenceFloat('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.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth') - 20, 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.getPreferenceFloat('machine_width'), 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 self.resumeButton.Enable(False)
def _load_profile_settings(self): self._layer_height = profile.getProfileSettingFloat('layer_height') self._spiralize = profile.getProfileSetting('spiralize') self._filament_diameter = profile.getProfileSetting('filament_diameter') self._filament_physical_density = profile.getPreferenceFloat('filament_physical_density') self._filament_cost_kg = profile.getPreferenceFloat('filament_cost_kg') self._filament_cost_meter = profile.getPreferenceFloat('filament_cost_meter')
def OnClose(self, e): self.parent.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0]) self.parent.headSizeMax = numpy.array([profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0]) self.parent.Refresh() self.MakeModal(False) self.Destroy()
def __init__(self): super(flatSlicerWindow, self).__init__(None, title='Cura - ' + version.getVersion()) self.machineSize = util3d.Vector3(profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.filename = None self.svg = None wx.EVT_CLOSE(self, self.OnClose) self.panel = wx.Panel(self, -1) self.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND) self.toolbar = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar, self.OnOpenSVG, 'open.png', 'Open SVG') self.toolbar.AddSeparator() group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner') self.toolbar.Realize() sizer = wx.GridBagSizer(2,2) self.panel.SetSizer(sizer) self.preview = PreviewGLCanvas(self.panel, self) sizer.Add(self.toolbar, (0,0), span=(1,1), flag=wx.EXPAND|wx.LEFT|wx.RIGHT) sizer.Add(self.preview, (1,0), span=(5,1), flag=wx.EXPAND) sizer.AddGrowableCol(0) sizer.AddGrowableRow(1) self.SetSize((600,400))
def OnOpenSVG(self, e): dlg=wx.FileDialog(self, "Open SVG file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_OPEN|wx.FD_FILE_MUST_EXIST) dlg.SetWildcard("SVG files (*.svg)|*.svg;*.SVG") if dlg.ShowModal() == wx.ID_OK: self.filename = dlg.GetPath() self.svg = svg.SVG(self.filename) self.svg.center(complex(profile.getPreferenceFloat('machine_width')/2, profile.getPreferenceFloat('machine_depth')/2)) self.preview.Refresh() dlg.Destroy()
def _drawMachine(self): glEnable(GL_CULL_FACE) glEnable(GL_BLEND) if profile.getPreference('machine_type') == 'ultimaker': glColor4f(1,1,1,0.5) self._objectShader.bind() self._renderObject(self._platformMesh, False, False) self._objectShader.unbind() size = [profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')] v0 = [ size[0] / 2, size[1] / 2, size[2]] v1 = [ size[0] / 2,-size[1] / 2, size[2]] v2 = [-size[0] / 2, size[1] / 2, size[2]] v3 = [-size[0] / 2,-size[1] / 2, size[2]] v4 = [ size[0] / 2, size[1] / 2, 0] v5 = [ size[0] / 2,-size[1] / 2, 0] v6 = [-size[0] / 2, size[1] / 2, 0] v7 = [-size[0] / 2,-size[1] / 2, 0] vList = [v0,v1,v3,v2, v1,v0,v4,v5, v2,v3,v7,v6, v0,v2,v6,v4, v3,v1,v5,v7] glEnableClientState(GL_VERTEX_ARRAY) glVertexPointer(3, GL_FLOAT, 3*4, vList) glColor4ub(5, 171, 231, 64) glDrawArrays(GL_QUADS, 0, 4) glColor4ub(5, 171, 231, 96) glDrawArrays(GL_QUADS, 4, 8) glColor4ub(5, 171, 231, 128) glDrawArrays(GL_QUADS, 12, 8) glDisableClientState(GL_VERTEX_ARRAY) sx = self._machineSize[0] sy = self._machineSize[1] for x in xrange(-int(sx/20)-1, int(sx / 20) + 1): for y in xrange(-int(sx/20)-1, int(sy / 20) + 1): x1 = x * 10 x2 = x1 + 10 y1 = y * 10 y2 = y1 + 10 x1 = max(min(x1, sx/2), -sx/2) y1 = max(min(y1, sy/2), -sy/2) x2 = max(min(x2, sx/2), -sx/2) y2 = max(min(y2, sy/2), -sy/2) if (x & 1) == (y & 1): glColor4ub(5, 171, 231, 127) else: glColor4ub(5 * 8 / 10, 171 * 8 / 10, 231 * 8 / 10, 128) glBegin(GL_QUADS) glVertex3f(x1, y1, -0.02) glVertex3f(x2, y1, -0.02) glVertex3f(x2, y2, -0.02) glVertex3f(x1, y2, -0.02) glEnd() glDisable(GL_BLEND) glDisable(GL_CULL_FACE)
def getFilamentCost(self, e=0): cost_kg = profile.getPreferenceFloat('filament_cost_kg') cost_meter = profile.getPreferenceFloat('filament_cost_meter') if cost_kg > 0.0 and cost_meter > 0.0: return "%.2f / %.2f" % (self.getFilamentWeight(e) * cost_kg, self._filamentMM[e] / 1000.0 * cost_meter) elif cost_kg > 0.0: return "%.2f" % (self.getFilamentWeight(e) * cost_kg) elif cost_meter > 0.0: return "%.2f" % (self._filamentMM[e] / 1000.0 * cost_meter) return None
def calculateCost(self): cost_kg = profile.getPreferenceFloat('filament_cost_kg') cost_meter = profile.getPreferenceFloat('filament_cost_meter') if cost_kg > 0.0 and cost_meter > 0.0: return "%.2f / %.2f" % (self.calculateWeight() * cost_kg, self.extrusionAmount / 1000 * cost_meter) elif cost_kg > 0.0: return "%.2f" % (self.calculateWeight() * cost_kg) elif cost_meter > 0.0: return "%.2f" % (self.extrusionAmount / 1000 * cost_meter) return None
def getFilamentCost(self): cost_kg = profile.getPreferenceFloat('filament_cost_kg') cost_meter = profile.getPreferenceFloat('filament_cost_meter') if cost_kg > 0.0 and cost_meter > 0.0: return "%.2f / %.2f" % (self.getFilamentWeight() * cost_kg, self._filamentMM / 1000.0 * cost_meter) elif cost_kg > 0.0: return "%.2f" % (self.getFilamentWeight() * cost_kg) elif cost_meter > 0.0: return "%.2f" % (self._filamentMM / 1000.0 * cost_meter) return None
def _load_profile_settings(self): self._layer_height = profile.getProfileSettingFloat('layer_height') self._spiralize = profile.getProfileSetting('spiralize') self._filament_diameter = profile.getProfileSetting( 'filament_diameter') self._filament_physical_density = profile.getPreferenceFloat( 'filament_physical_density') self._filament_cost_kg = profile.getPreferenceFloat('filament_cost_kg') self._filament_cost_meter = profile.getPreferenceFloat( 'filament_cost_meter')
def getFilamentCost(self): cost_kg = profile.getPreferenceFloat("filament_cost_kg") cost_meter = profile.getPreferenceFloat("filament_cost_meter") if cost_kg > 0.0 and cost_meter > 0.0: return "%.2f / %.2f" % (self.getFilamentWeight() * cost_kg, self._filamentMM / 1000.0 * cost_meter) elif cost_kg > 0.0: return "%.2f" % (self.getFilamentWeight() * cost_kg) elif cost_meter > 0.0: return "%.2f" % (self._filamentMM / 1000.0 * cost_meter) return None
def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp): if self._wizardState == 1: self._wizardState = 2 wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.') wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 3: self._wizardState = 4 wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.') wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 5: self._wizardState = 6 wx.CallAfter(self.infoBox.SetAttention, 'Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.') wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 7: self._wizardState = 8 wx.CallAfter(self.infoBox.SetAttention, 'Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.') wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 9: if temp < profile.getProfileSettingFloat('print_temperature') - 5: wx.CallAfter(self.infoBox.SetInfo, 'Heating up printer: %d/%d' % (temp, profile.getProfileSettingFloat('print_temperature'))) else: self._wizardState = 10 wx.CallAfter(self.infoBox.SetInfo, 'Printing a square on the printer bed at 0.3mm height.') feedZ = profile.getProfileSettingFloat('max_z_speed') * 60 feedPrint = profile.getProfileSettingFloat('print_speed') * 60 feedTravel = profile.getProfileSettingFloat('travel_speed') * 60 w = profile.getPreferenceFloat('machine_width') d = profile.getPreferenceFloat('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; gcodeList.append('G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60)) for i in xrange(0, 3): dist = 5.0 + 0.4 * i eValue += (d - 2*dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (dist, d - dist, eValue, feedPrint)) eValue += (w - 2*dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (w - dist, d - dist, eValue, feedPrint)) eValue += (d - 2*dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (w - dist, dist, eValue, feedPrint)) eValue += (w - 2*dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (dist, dist, eValue, feedPrint)) gcodeList.append('M400') self.comm.printGCode(gcodeList)
def __init__(self): super(flatSlicerWindow, self).__init__(None, title='Cura - ' + version.getVersion()) self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.filename = None self.svg = None wx.EVT_CLOSE(self, self.OnClose) self.panel = wx.Panel(self, -1) self.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND) self.toolbar = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar, self.OnOpenSVG, 'open.png', 'Open SVG') self.toolbar.AddSeparator() group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(True) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner') self.toolbar.Realize() sizer = wx.GridBagSizer(2, 2) self.panel.SetSizer(sizer) self.preview = PreviewGLCanvas(self.panel, self) sizer.Add(self.toolbar, (0, 0), span=(1, 1), flag=wx.EXPAND | wx.LEFT | wx.RIGHT) sizer.Add(self.preview, (1, 0), span=(5, 1), flag=wx.EXPAND) sizer.AddGrowableCol(0) sizer.AddGrowableRow(1) self.SetSize((600, 400))
def OnClose(self, e): self.parent.headSizeMin = numpy.array([ profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'), 0 ]) self.parent.headSizeMax = numpy.array([ profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'), 0 ]) self.parent.Refresh() self.MakeModal(False) self.Destroy()
def calculateWeight(self): #Calculates the weight of the filament in kg radius = float(profile.getProfileSetting('filament_diameter')) / 2 volumeM3 = (self.extrusionAmount * (math.pi * radius * radius)) / (1000 * 1000 * 1000) return volumeM3 * profile.getPreferenceFloat( 'filament_physical_density')
def updateMachineMenu(self): #Remove all items so we can rebuild the menu. Inserting items seems to cause crashes, so this is the safest way. for item in self.machineMenu.GetMenuItems(): self.machineMenu.RemoveItem(item) #Add a menu item for each machine configuration. for n in xrange(0, profile.getMachineCount()): i = self.machineMenu.Append(n + 0x1000, profile.getMachineSetting( 'machine_name', n).title(), kind=wx.ITEM_RADIO) if n == int(profile.getPreferenceFloat('active_machine')): i.Check(True) self.Bind(wx.EVT_MENU, lambda e: self.OnSelectMachine(e.GetId() - 0x1000), i) self.machineMenu.AppendSeparator() i = self.machineMenu.Append(-1, _("Machine settings...")) self.Bind(wx.EVT_MENU, self.OnMachineSettings, i) #Add tools for machines. self.machineMenu.AppendSeparator() self.defaultFirmwareInstallMenuItem = self.machineMenu.Append( -1, _("Install default firmware...")) self.Bind(wx.EVT_MENU, self.OnDefaultMarlinFirmware, self.defaultFirmwareInstallMenuItem) i = self.machineMenu.Append(-1, _("Install custom firmware...")) self.Bind(wx.EVT_MENU, self.OnCustomFirmware, i)
def OnOpenSVG(self, e): dlg = wx.FileDialog(self, "Open SVG file", os.path.split( profile.getPreference('lastFile'))[0], style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) dlg.SetWildcard("SVG files (*.svg)|*.svg;*.SVG") if dlg.ShowModal() == wx.ID_OK: self.filename = dlg.GetPath() self.svg = svg.SVG(self.filename) self.svg.center( complex( profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2)) self.preview.Refresh() dlg.Destroy()
def getFilamentWeight(self, e=0): #Calculates the weight of the filament in kg radius = float(profile.getProfileSetting('filament_diameter')) / 2 volumeM3 = (self._filamentMM[e] * (math.pi * radius * radius)) / (1000 * 1000 * 1000) return volumeM3 * profile.getPreferenceFloat( 'filament_physical_density')
def getDefaultFirmware(): if profile.getPreference('machine_type') == 'ultimaker': if profile.getPreference('has_heated_bed') == 'True': return None if profile.getPreferenceFloat('extruder_amount') > 2: return None if profile.getPreferenceFloat('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 updateMachineMenu(self): #Remove all items so we can rebuild the menu. Inserting items seems to cause crashes, so this is the safest way. for item in self.machineMenu.GetMenuItems(): self.machineMenu.RemoveItem(item) #Add a menu item for each machine configuration. for n in xrange(0, profile.getMachineCount()): i = self.machineMenu.Append(n + 0x1000, profile.getMachineSetting('machine_name', n).title(), kind=wx.ITEM_RADIO) if n == int(profile.getPreferenceFloat('active_machine')): i.Check(True) self.Bind(wx.EVT_MENU, lambda e: self.OnSelectMachine(e.GetId() - 0x1000), i) self.machineMenu.AppendSeparator() i = self.machineMenu.Append(-1, _("Add new machine...")) self.Bind(wx.EVT_MENU, self.OnAddNewMachine, i) i = self.machineMenu.Append(-1, _("Machine settings...")) self.Bind(wx.EVT_MENU, self.OnMachineSettings, i) #Add tools for machines. self.machineMenu.AppendSeparator() self.defaultFirmwareInstallMenuItem = self.machineMenu.Append(-1, _("Install default firmware...")) self.Bind(wx.EVT_MENU, self.OnDefaultMarlinFirmware, self.defaultFirmwareInstallMenuItem) i = self.machineMenu.Append(-1, _("Install custom firmware...")) self.Bind(wx.EVT_MENU, self.OnCustomFirmware, i)
def getDefaultFirmware(): if profile.getPreference('machine_type') == 'ultimaker': if profile.getPreference('has_heated_bed') == 'True': return None if profile.getPreferenceFloat('extruder_amount') > 2: return None if profile.getPreferenceFloat('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 __init__(self, mainWindow, parent, filelist): wx.Panel.__init__(self, parent, -1) self.mainWindow = mainWindow self.filelist = filelist self.abort = False box = wx.StaticBox(self, -1, filelist[0]) self.sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(self.sizer, 0, flag=wx.EXPAND) self.statusText = wx.StaticText(self, -1, "Starting...") self.progressGauge = wx.Gauge(self, -1) self.progressGauge.SetRange(10000 * len(filelist)) self.abortButton = wx.Button(self, -1, "X", style=wx.BU_EXACTFIT) self.sizer.Add(self.statusText, 2, flag=wx.ALIGN_CENTER ) self.sizer.Add(self.progressGauge, 2) self.sizer.Add(self.abortButton, 0) self.Bind(wx.EVT_BUTTON, self.OnAbort, self.abortButton) self.SetSizer(mainSizer) self.prevStep = 'start' self.totalDoneFactor = 0.0 self.startTime = time.time() if profile.getPreference('save_profile') == 'True': profile.saveGlobalProfile(self.filelist[0][: self.filelist[0].rfind('.')] + "_profile.ini") cmdList = [] for filename in self.filelist: idx = self.filelist.index(filename) #print filename, idx if idx > 0: profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('object_center_x', profile.getPreferenceFloat('machine_width') / 2 - profile.getPreferenceFloat('extruder_offset_x%d' % (idx))) profile.setTempOverride('object_center_y', profile.getPreferenceFloat('machine_depth') / 2 - profile.getPreferenceFloat('extruder_offset_y%d' % (idx))) profile.setTempOverride('alternative_center', self.filelist[0]) if len(self.filelist) > 1: profile.setTempOverride('add_start_end_gcode', 'False') profile.setTempOverride('gcode_extension', 'multi_extrude_tmp') cmdList.append(sliceRun.getSliceCommand(filename)) profile.resetTempOverride() self.thread = WorkerThread(self, filelist, cmdList)
def OnResume(self, e): feedZ = profile.getProfileSettingFloat('max_z_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.getPreferenceFloat('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.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('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.getPreferenceFloat('machine_width'), 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 self.resumeButton.Enable(False)
def updateProfileToControls(self): oldSimpleMode = self._isSimpleMode self._isSimpleMode = profile.getPreference('startMode') == 'Simple' if self._isSimpleMode and not oldSimpleMode: self._scene.arrangeAll() self.sceneUpdated() self._machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')]) self._objColors[0] = profile.getPreferenceColour('model_colour') self._objColors[1] = profile.getPreferenceColour('model_colour2') self._objColors[2] = profile.getPreferenceColour('model_colour3') self._objColors[3] = profile.getPreferenceColour('model_colour4') self._scene.setMachineSize(self._machineSize) self._scene.setSizeOffsets(numpy.array(profile.calculateObjectSizeOffsets(), numpy.float32)) self._scene.setHeadSize(profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_min_y'), profile.getPreferenceFloat('extruder_head_size_max_y'), profile.getPreferenceFloat('extruder_head_size_height')) if self._selectedObj is not None: scale = self._selectedObj.getScale() size = self._selectedObj.getSize() self.scaleXctrl.setValue(round(scale[0], 2)) self.scaleYctrl.setValue(round(scale[1], 2)) self.scaleZctrl.setValue(round(scale[2], 2)) self.scaleXmmctrl.setValue(round(size[0], 2)) self.scaleYmmctrl.setValue(round(size[1], 2)) self.scaleZmmctrl.setValue(round(size[2], 2))
def OnChangeToolheadButton(self, e): self.Hide() self.parent.Hide() old_active = int(profile.getPreferenceFloat('active_machine')) profile.setActiveMachine(self.nb.GetSelection()) configWizard.LulzbotChangeToolheadWizard() profile.setActiveMachine(old_active) self.parent.Show() self.parent.reloadSettingPanels() self.parent.updateMachineMenu() prefDialog = machineSettingsDialog(self.parent) prefDialog.Centre() prefDialog.Show() wx.CallAfter(self.Close)
def __init__(self, addNew = False): super(ConfigFirmware, self).__init__(None, -1, _("Machine Firmware Updater")) self._old_machine_index = int(profile.getPreferenceFloat('active_machine')) if addNew: profile.setActiveMachine(profile.getMachineCount()) self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged) self.Bind(wx.wizard.EVT_WIZARD_PAGE_CHANGING, self.OnPageChanging) self.Bind(wx.wizard.EVT_WIZARD_CANCEL, self.OnCancel) self.Bind(wx.wizard.EVT_WIZARD_FINISHED, self.OnFinish) self.machineSelectPage = MachineSelectPage(self) self.decidetoupdatesigma = decideToUpdateSigma(self) self.firstconnectprintersigma = FirstConnectPrinterSigma(self) self.decidetoupdateplus = decideToUpdatePlus(self) self.firstconnectprinterplus = FirstConnectPrinterPlus(self) self.decidetoupdater = decideToUpdateR(self) self.firstconnectprinterr = FirstConnectPrinterR(self) if profile.getMachineSetting('machine_type') == 'BCN3DSigma': wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.decidetoupdatesigma) wx.wizard.WizardPageSimple.Chain(self.decidetoupdatesigma, self.firstconnectprintersigma) if profile.getMachineSetting('machine_type') == 'BCN3DPlus': wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.decidetoupdateplus) wx.wizard.WizardPageSimple.Chain(self.decidetoupdateplus, self.firstconnectprinterplus) if profile.getMachineSetting('machine_type') == 'BCN3DR': wx.wizard.WizardPageSimple.Chain(self.machineSelectPage, self.decidetoupdater) wx.wizard.WizardPageSimple.Chain(self.decidetoupdater, self.firstconnectprinterr) self.FitToPage(self.machineSelectPage) self.GetPageAreaSizer().Add(self.machineSelectPage) self.RunWizard(self.machineSelectPage) self.Hide()
def __init__(self, progressCallback): self._process = None self._thread = None self._callback = progressCallback self._binaryStorageFilename = getTempFilename() self._exportFilename = getTempFilename() self._progressSteps = ['inset', 'skin', 'export'] self._objCount = 0 self._sliceLog = [] #self._printTimeSeconds = None self._totalMoveTimeMinute = None self._basicSettings = [] self._extrusionAmount = None self._filamentMM = None self._modelHash = None self.extruderOffset = [ numpy.array([0,0,0]), numpy.array([profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0]), numpy.array([profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0]), numpy.array([profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0])] self._pspw = None
def storedPreferenceFloat(name): return lambda setting: profile.getPreferenceFloat(name)
def __init__(self, parent): super(previewPanel, self).__init__(parent, -1) self.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DDKSHADOW)) self.SetMinSize((440, 320)) self.objectList = [] self.errorList = [] self.gcode = None self.objectsMinV = None self.objectsMaxV = None self.objectsBoundaryCircleSize = None self.loadThread = None self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.machineCenter = util3d.Vector3(self.machineSize.x / 2, self.machineSize.y / 2, 0) self.glCanvas = PreviewGLCanvas(self) #Create the popup window self.warningPopup = wx.PopupWindow(self, flags=wx.BORDER_SIMPLE) self.warningPopup.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK)) self.warningPopup.text = wx.StaticText( self.warningPopup, -1, 'Reset scale, rotation and mirror?') self.warningPopup.yesButton = wx.Button(self.warningPopup, -1, 'yes', style=wx.BU_EXACTFIT) self.warningPopup.noButton = wx.Button(self.warningPopup, -1, 'no', style=wx.BU_EXACTFIT) self.warningPopup.sizer = wx.BoxSizer(wx.HORIZONTAL) self.warningPopup.SetSizer(self.warningPopup.sizer) self.warningPopup.sizer.Add(self.warningPopup.text, 1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=1) self.warningPopup.sizer.Add(self.warningPopup.yesButton, 0, flag=wx.EXPAND | wx.ALL, border=1) self.warningPopup.sizer.Add(self.warningPopup.noButton, 0, flag=wx.EXPAND | wx.ALL, border=1) self.warningPopup.Fit() self.warningPopup.Layout() self.warningPopup.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnHideWarning, self.warningPopup.timer) self.Bind(wx.EVT_BUTTON, self.OnWarningPopup, self.warningPopup.yesButton) self.Bind(wx.EVT_BUTTON, self.OnHideWarning, self.warningPopup.noButton) parent.Bind(wx.EVT_MOVE, self.OnMove) parent.Bind(wx.EVT_SIZE, self.OnMove) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.glCanvas, 1, flag=wx.EXPAND) self.SetSizer(sizer) self.checkReloadFileTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnCheckReloadFile, self.checkReloadFileTimer) self.checkReloadFileTimer.Start(1000) group = [] self.rotateToolButton = openglGui.glRadioButton( self.glCanvas, 8, 'Rotate', (0, -1), group, self.OnToolSelect) self.scaleToolButton = openglGui.glRadioButton(self.glCanvas, 9, 'Scale', (1, -1), group, self.OnToolSelect) self.mirrorToolButton = openglGui.glRadioButton( self.glCanvas, 10, 'Mirror', (2, -1), group, self.OnToolSelect) self.resetRotationButton = openglGui.glButton(self.glCanvas, 12, 'Reset', (0, -2), self.OnRotateReset) self.layFlatButton = openglGui.glButton(self.glCanvas, 16, 'Lay flat', (0, -3), self.OnLayFlat) self.resetScaleButton = openglGui.glButton(self.glCanvas, 13, 'Reset', (1, -2), self.OnScaleReset) self.scaleMaxButton = openglGui.glButton(self.glCanvas, 17, 'To max', (1, -3), self.OnScaleMax) self.mirrorXButton = openglGui.glButton(self.glCanvas, 14, 'Mirror X', (2, -2), lambda: self.OnMirror(0)) self.mirrorYButton = openglGui.glButton(self.glCanvas, 18, 'Mirror Y', (2, -3), lambda: self.OnMirror(1)) self.mirrorZButton = openglGui.glButton(self.glCanvas, 22, 'Mirror Z', (2, -4), lambda: self.OnMirror(2)) self.openFileButton = openglGui.glButton( self.glCanvas, 4, 'Load', (0, 0), lambda: self.GetParent().GetParent().GetParent( )._showModelLoadDialog(1)) self.sliceButton = openglGui.glButton( self.glCanvas, 5, 'Prepare', (1, 0), lambda: self.GetParent().GetParent().GetParent().OnSlice(None)) self.printButton = openglGui.glButton( self.glCanvas, 6, 'Print', (2, 0), lambda: self.GetParent().GetParent().GetParent().OnPrint(None)) self.rotateToolButton.setExpandArrow(True) self.scaleToolButton.setExpandArrow(True) self.mirrorToolButton.setExpandArrow(True) extruderCount = int(profile.getPreference('extruder_amount')) if extruderCount > 1: openglGui.glButton( self.glCanvas, 4, 'Load dual', (0, 1), lambda: self.GetParent( ).GetParent().GetParent()._showModelLoadDialog(2)) if extruderCount > 2: openglGui.glButton( self.glCanvas, 4, 'Load triple', (0, 2), lambda: self. GetParent().GetParent().GetParent()._showModelLoadDialog(3)) if extruderCount > 3: openglGui.glButton( self.glCanvas, 4, 'Load quad', (0, 3), lambda: self.GetParent( ).GetParent().GetParent()._showModelLoadDialog(4)) self.scaleForm = openglGui.glFrame(self.glCanvas, (2, -2)) openglGui.glGuiLayoutGrid(self.scaleForm) openglGui.glLabel(self.scaleForm, 'Scale X', (0, 0)) self.scaleXctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 0), lambda value: self.OnScaleEntry(value, 0)) openglGui.glLabel(self.scaleForm, 'Scale Y', (0, 1)) self.scaleYctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 1), lambda value: self.OnScaleEntry(value, 1)) openglGui.glLabel(self.scaleForm, 'Scale Z', (0, 2)) self.scaleZctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 2), lambda value: self.OnScaleEntry(value, 2)) openglGui.glLabel(self.scaleForm, 'Size X (mm)', (0, 4)) self.scaleXmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 4), lambda value: self.OnScaleEntryMM(value, 0)) openglGui.glLabel(self.scaleForm, 'Size Y (mm)', (0, 5)) self.scaleYmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 5), lambda value: self.OnScaleEntryMM(value, 1)) openglGui.glLabel(self.scaleForm, 'Size Z (mm)', (0, 6)) self.scaleZmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 6), lambda value: self.OnScaleEntryMM(value, 2)) openglGui.glLabel(self.scaleForm, 'Uniform scale', (0, 8)) self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1, 8), None) self.viewSelection = openglGui.glComboButton( self.glCanvas, 'View mode', [7, 11, 15, 19, 23], ['Normal', 'Transparent', 'X-Ray', 'Overhang', 'Layers'], (-1, 0), self.OnViewChange) self.layerSelect = openglGui.glSlider(self.glCanvas, 0, 0, 100, (-1, -2), lambda: self.Refresh()) self.OnViewChange() self.OnToolSelect() self.updateModelTransform() self.matrix = numpy.matrix( numpy.array(profile.getObjectMatrix(), numpy.float64).reshape(( 3, 3, )))
def mcTempUpdate(self, temp, bedTemp, targetTemp, bedTargetTemp): if self._wizardState == 1: self._wizardState = 2 wx.CallAfter( self.infoBox.SetAttention, 'Adjust the front left screw of your printer bed\nSo the nozzle just hits the bed.' ) wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 3: self._wizardState = 4 wx.CallAfter( self.infoBox.SetAttention, 'Adjust the back left screw of your printer bed\nSo the nozzle just hits the bed.' ) wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 5: self._wizardState = 6 wx.CallAfter( self.infoBox.SetAttention, 'Adjust the back right screw of your printer bed\nSo the nozzle just hits the bed.' ) wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 7: self._wizardState = 8 wx.CallAfter( self.infoBox.SetAttention, 'Adjust the front right screw of your printer bed\nSo the nozzle just hits the bed.' ) wx.CallAfter(self.resumeButton.Enable, True) elif self._wizardState == 9: if temp < profile.getProfileSettingFloat('print_temperature') - 5: wx.CallAfter( self.infoBox.SetInfo, 'Heating up printer: %d/%d' % (temp, profile.getProfileSettingFloat('print_temperature'))) else: self._wizardState = 10 wx.CallAfter( self.infoBox.SetInfo, 'Printing a square on the printer bed at 0.3mm height.') feedZ = profile.getProfileSettingFloat('max_z_speed') * 60 feedPrint = profile.getProfileSettingFloat('print_speed') * 60 feedTravel = profile.getProfileSettingFloat( 'travel_speed') * 60 w = profile.getPreferenceFloat('machine_width') d = profile.getPreferenceFloat('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 gcodeList.append( 'G1 E%f F%d' % (eValue, profile.getProfileSettingFloat('retraction_speed') * 60)) for i in xrange(0, 3): dist = 5.0 + 0.4 * i eValue += (d - 2 * dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (dist, d - dist, eValue, feedPrint)) eValue += (w - 2 * dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (w - dist, d - dist, eValue, feedPrint)) eValue += (d - 2 * dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (w - dist, dist, eValue, feedPrint)) eValue += (w - 2 * dist) * ePerMM gcodeList.append('G1 X%d Y%d E%f F%d' % (dist, dist, eValue, feedPrint)) gcodeList.append('M400') self.comm.printGCode(gcodeList)
def getProfileInformation(): #NOTE TO MYSELF# #Skeinforge uses these variables, but has them converted first #In skeinforge, in carve.py, there is- 'Edge Width (mm):' which corresponds to the- 'Edge_Width_mm' below. #So it takes the 'Edge Width (mm):' and removed all spaces and brackets and puts a '_' between each word. return { 'carve': { 'Add_Layer_Template_to_SVG': "true", 'Edge_Width_mm': storedSettingFloat("edge_width_mm"), #'Edge_Width_mm': 2.2*0.2, #'Edge_Width_mm': "0.36", #100 micron 'Extra_Decimal_Places_float': "2.0", 'Import_Coarseness_ratio': "1.0", 'Layer_Height_mm': storedSettingFloat("layer_height"), 'Layers_From_index': "0", 'Layers_To_index': "912345678", 'Correct_Mesh': "True", 'Unproven_Mesh': "False", 'SVG_Viewer': "webbrowser", 'FlipX': storedSetting("flip_x"), 'FlipY': storedSetting("flip_y"), 'FlipZ': storedSetting("flip_z"), 'SwapXZ': storedSetting("swap_xz"), 'SwapYZ': storedSetting("swap_yz"), 'Scale': storedSettingFloat("model_scale"), 'Rotate': storedSettingFloat("model_rotate_base"), 'CenterX': lambda setting: profile.getProfileSettingFloat('object_center_x') if profile.getProfileSettingFloat('object_center_x') > 0 else profile.getPreferenceFloat("machine_width") / 2, 'CenterY': lambda setting: profile.getProfileSettingFloat('object_center_y') if profile.getProfileSettingFloat('object_center_y') > 0 else profile.getPreferenceFloat("machine_depth") / 2, 'AlternativeCenterFile': storedSetting("alternative_center"), },'scale': { 'Activate_Scale': "False", 'XY_Plane_Scale_ratio': "1.01", 'Z_Axis_Scale_ratio': "1", 'SVG_Viewer': "webbrowser", },'bottom': { 'Activate_Bottom': "True", 'Additional_Height_over_Layer_Thickness_ratio': "0.5", 'Altitude_mm': "0.0", 'SVG_Viewer': "webbrowser", },'preface': { 'Meta': DEFSET, 'Set_Positioning_to_Absolute': "True", 'Set_Units_to_Millimeters': "True", 'Start_at_Home': "False", 'Turn_Extruder_Off_at_Shut_Down': "True", 'Turn_Extruder_Off_at_Start_Up': "True", },'widen': { 'Activate_Widen': "False", 'Widen_Width_over_Edge_Width_ratio': "2", },'inset': { 'Add_Custom_Code_for_Temperature_Reading': "False", 'Infill_in_Direction_of_Bridge': profile.getProfileSetting('bridge_direction'), #'Infill_Width': "0.3", #100 micron 'Infill_Width': storedSettingFloat("infill_width"), 'Loop_Order_Choice': DEFSET, 'Overlap_Removal_Width_over_Perimeter_Width_ratio': "0.6", 'Turn_Extruder_Heater_Off_at_Shut_Down': "True", 'Volume_Fraction_ratio': "0.82", },'fill': { 'Activate_Fill': "True", 'Solid_Surface_Top': "False", 'Override_First_Layer_Sequence': storedSetting("force_first_layer_sequence"), 'Diaphragm_Period_layers': "160000", 'Diaphragm_Thickness_layers': "0", 'Extra_Shells_on_Alternating_Solid_Layer_layers': calculateShells, 'Extra_Shells_on_Base_layers': calculateShellsBase, 'Extra_Shells_on_Sparse_Layer_layers': calculateShells, 'Grid_Circle_Separation_over_Perimeter_Width_ratio': "0.2", 'Grid_Extra_Overlap_ratio': "0.1", 'Grid_Junction_Separation_Band_Height_layers': "10", 'Grid_Junction_Separation_over_Octogon_Radius_At_End_ratio': "0.0", 'Grid_Junction_Separation_over_Octogon_Radius_At_Middle_ratio': "0.0", 'Infill_Begin_Rotation_degrees': "0", 'Infill_Begin_Rotation_Repeat_layers': "1", 'Infill_Odd_Layer_Extra_Rotation_degrees': "90.0", 'Grid_Circular': ifSettingIs('infill_type', 'Grid Circular'), 'Grid_Hexagonal': ifSettingIs('infill_type', 'Grid Hexagonal'), 'Grid_Rectangular': ifSettingIs('infill_type', 'Grid Rectangular'), 'Line': ifSettingIs('infill_type', 'Line'), 'Infill_Perimeter_Overlap_ratio': storedPercentSetting('fill_overlap'), 'Infill_Solidity_ratio': storedPercentSetting('fill_density'), 'Infill_Width': "0.4", 'Sharpest_Angle_degrees': "60", 'Solid_Surface_Thickness_layers': calculateSolidLayerCount, 'Bottom_Surface_Thickness_layers': profile.getProfileSetting('bottom_surface_thickness_layers'), 'Top_Surface_Thickness_layers': profile.getProfileSetting('top_surface_thickness_layers'), 'Start_From_Choice': DEFSET, 'Surrounding_Angle_degrees': "60", 'Thread_Sequence_Choice': storedSetting('sequence'), },'multiply': { 'Activate_Multiply': "False", 'Center_X_mm': lambda setting: profile.getProfileSettingFloat('object_center_x') if profile.getProfileSettingFloat('object_center_x') > 0 else profile.getPreferenceFloat("machine_width") / 2, 'Center_Y_mm': lambda setting: profile.getProfileSettingFloat('object_center_y') if profile.getProfileSettingFloat('object_center_y') > 0 else profile.getPreferenceFloat("machine_depth") / 2, 'Number_of_Columns_integer': storedSetting('model_multiply_x'), 'Number_of_Rows_integer': storedSetting('model_multiply_y'), 'Reverse_Sequence_every_Odd_Layer': False, 'Separation_over_Perimeter_Width_ratio': calculateMultiplyDistance, },'speed': { 'Activate_Speed': "True", 'Add_Flow_Rate': "True", #'Bridge_Feed_Rate_Multiplier_ratio': "0.7", #100 micron #'Bridge_Flow_Rate_Multiplier_ratio': "2.0", #100 micron #'Bridge_Feed_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'), #'Bridge_Flow_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'), 'Bridge_Feed_Rate_Multiplier_ratio': storedPercentSetting("bridge_feed_ratio"), 'Bridge_Flow_Rate_Multiplier_ratio': storedPercentSetting("bridge_flow_ratio"), 'Duty_Cyle_at_Beginning_portion': "1.0", 'Duty_Cyle_at_Ending_portion': "0.0", 'Feed_Rate_mm/s': storedSettingFloat("print_speed"), 'Flow_Rate_Setting_float': calcFlowRate, #'Flow_Rate_Setting_float': storedSettingFloat("print_speed"), #'Flow_Rate_Setting_float': storedSettingFloat("print_flow"), 'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': DEFSET, 'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': "0.5", 'Maximum_Z_Feed_Rate_mm/s': "60.0", 'Perimeter_Feed_Rate_Multiplier_ratio': storedPercentSetting("perimeter_speed_ratio"), #'Perimeter_Flow_Rate_Multiplier_ratio': storedPercentSetting("perimeter_flow_ratio"), 'Perimeter_Flow_Rate_Multiplier_ratio': storedPercentSetting("perimeter_flow_ratio"), 'Travel_Feed_Rate_mm/s': storedSettingFloat("travel_speed"), 'Bottom_layer_flow_rate_ratio': calcBottomLayerFlowRateRatio, 'Top_layer_flow_rate_ratio': storedSettingFloat("top_surface_flow"), },'temperature': { 'Activate_Temperature': "True",#ifSettingAboveZero('print_temperature'), 'Cooling_Rate_Celcius/second': "3.0", 'Heating_Rate_Celcius/second': "10.0", 'Base_Temperature_Celcius': storedSettingFloat("print_temperature"), 'Interface_Temperature_Celcius': storedSettingFloat("print_temperature"), 'Object_First_Layer_Infill_Temperature_Celcius': storedSettingFloat("first_layer_print_temperature"), 'Object_First_Layer_Perimeter_Temperature_Celcius': storedSettingFloat("first_layer_print_temperature"), 'Object_Next_Layers_Temperature_Celcius': storedSettingFloat("print_temperature"), 'Support_Layers_Temperature_Celcius': storedSettingFloat("print_temperature"), 'Supported_Layers_Temperature_Celcius': storedSettingFloat("print_temperature"), },'raft': { 'Activate_Raft': "True", 'Add_Raft,_Elevate_Nozzle,_Orbit': DEFSET, 'Base_Feed_Rate_Multiplier_ratio': "1.0", 'Base_Flow_Rate_Multiplier_ratio': "1.0", 'Base_Infill_Density_ratio': "0.5", 'Base_Layer_Thickness_over_Layer_Thickness': "2.0", 'Base_Layers_integer': raftLayerCount, 'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': "0.4", 'Initial_Circling': "False", 'Infill_Overhang_over_Extrusion_Width_ratio': "0.0", 'Interface_Feed_Rate_Multiplier_ratio': "1.0", 'Interface_Flow_Rate_Multiplier_ratio': "1.0", 'Interface_Infill_Density_ratio': storedSettingFloat("support_density"), 'Interface_Layer_Thickness_over_Layer_Thickness': "1.0", 'Interface_Layers_integer': raftLayerCount, 'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': "0.45", 'Name_of_Support_End_File': DEFSET, 'Name_of_Support_Start_File': DEFSET, 'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': "0.5", 'Raft_Additional_Margin_over_Length_%': "1.0", 'Raft_Margin_mm': "3.0", 'Support_Cross_Hatch': lambda setting: 'True' if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else 'False', 'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': storedSettingFloat("support_extrusion"), 'Support_Gap_over_Perimeter_Extrusion_Width_ratio': "1.2", 'Support_Material_Choice_': storedSetting('support'), 'Support_Minimum_Angle_degrees': storedSettingFloat("support_angle"), 'Support_Margin_mm': '3.0', 'Support_Offset_X_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_x1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0', 'Support_Offset_Y_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_y1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0', },'skirt': { 'Skirt_line_count': storedSetting("skirt_line_count"), 'Convex': lambda setting: "True" if profile.getProfileSettingFloat('skirt_gap') > 0.0 else "False", 'Gap_Width_mm': storedSetting("skirt_gap"), 'Layers_To_index': "1", },'joris': { 'Activate_Joris': storedSetting("joris"), 'Layers_From_index': calculateSolidLayerCount, },'chamber': { 'Activate_Chamber': "False", 'Bed_Temperature_Celcius': DEFSET, 'Bed_Temperature_Begin_Change_Height_mm': DEFSET, 'Bed_Temperature_End_Change_Height_mm': DEFSET, 'Bed_Temperature_End_Celcius': DEFSET, 'Chamber_Temperature_Celcius': DEFSET, 'Holding_Force_bar': DEFSET, },'tower': { 'Activate_Tower': "False", 'Extruder_Possible_Collision_Cone_Angle_degrees': "60", 'Maximum_Tower_Height_layers': "5", 'Tower_Start_Layer_integer': "1", },'jitter': { 'Activate_Jitter': profile.getProfileSetting('organic_clip'), 'Jitter_Over_Perimeter_Width_ratio': DEFSET, },'clip': { 'Activate_Clip': "False", 'Clip_Over_Perimeter_Width_ratio': storedSettingFloat("clip"), 'Maximum_Connection_Distance_Over_Perimeter_Width_ratio': "10.0", },'smooth': { 'Activate_Smooth': "True", 'Layers_From_index': "1", 'Maximum_Shortening_over_Width_float': "1.2", },'stretch': { 'Activate_Stretch': "False", 'Cross_Limit_Distance_Over_Perimeter_Width_ratio': DEFSET, 'Loop_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Path_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Perimeter_Inside_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Stretch_From_Distance_Over_Perimeter_Width_ratio': DEFSET, },'skin': { 'Activate_Skin': storedSetting("enable_skin"), 'Horizontal_Infill_Divisions_integer': "1", 'Horizontal_Perimeter_Divisions_integer': "1", 'Vertical_Divisions_integer': "2", 'Hop_When_Extruding_Infill': "False", 'Layers_From_index': "1", },'comb': { 'Activate_Comb': "False", 'Running_Jump_Space_mm': "2.0", },'cool': { 'Activate_Cool': "True", 'Bridge_Cool_Celcius': "1.0", 'Cool_Type': DEFSET, 'Maximum_Cool_Celcius': "2.0", 'Minimum_Layer_Time_seconds': storedSettingFloat("cool_min_layer_time"), 'Minimum_Orbital_Radius_millimeters': DEFSET, 'Name_of_Cool_End_File': DEFSET, 'Name_of_Cool_Start_File': DEFSET, 'Orbital_Outset_millimeters': DEFSET, 'Turn_Fan_On_at_Beginning': storedSetting("fan_enabled"), 'Turn_Fan_Off_at_Ending': storedSetting("fan_enabled"), 'Minimum_feed_rate_mm/s': storedSettingFloat("cool_min_feedrate"), 'Fan_on_at_layer': storedSettingInt('fan_layer'), 'Fan_speed_min_%': storedSettingInt('fan_speed'), 'Fan_speed_max_%': storedSettingInt('fan_speed_max'), },'hop': { 'Activate_Hop': storedSetting('hop_on_move'), 'Hop_Over_Layer_Thickness_ratio': lambda setting: 0.2 / profile.getProfileSettingFloat('layer_height'), 'Minimum_Hop_Angle_degrees': DEFSET, },'wipe': { 'Activate_Wipe': "False", 'Arrival_X_mm': DEFSET, 'Arrival_Y_mm': DEFSET, 'Arrival_Z_mm': DEFSET, 'Departure_X_mm': DEFSET, 'Departure_Y_mm': DEFSET, 'Departure_Z_mm': DEFSET, 'Wipe_X_mm': DEFSET, 'Wipe_Y_mm': DEFSET, 'Wipe_Z_mm': DEFSET, 'Wipe_Period_layers': DEFSET, },'oozebane': { 'Activate_Oozebane': "False", 'After_Startup_Distance_millimeters': DEFSET, 'Early_Shutdown_Distance_millimeters': DEFSET, 'Early_Startup_Distance_Constant_millimeters': DEFSET, 'Early_Startup_Maximum_Distance_millimeters': DEFSET, 'First_Early_Startup_Distance_millimeters': DEFSET, 'Minimum_Distance_for_Early_Startup_millimeters': DEFSET, 'Minimum_Distance_for_Early_Shutdown_millimeters': DEFSET, 'Slowdown_Startup_Steps_positive_integer': DEFSET, },'dwindle': { 'Activate_Dwindle': "False", 'End_Rate_Multiplier_ratio': '0.5', 'Pent_Up_Volume_cubic_millimeters': "0.4", 'Slowdown_Steps_positive_integer': '5', 'Slowdown_Volume_cubic_millimeters': "5.0", },'splodge': { 'Activate_Splodge': "False", 'Initial_Lift_over_Extra_Thickness_ratio': DEFSET, 'Initial_Splodge_Feed_Rate_mm/s': DEFSET, 'Operating_Splodge_Feed_Rate_mm/s': DEFSET, 'Operating_Splodge_Quantity_Length_millimeters': DEFSET, 'Initial_Splodge_Quantity_Length_millimeters': DEFSET, 'Operating_Lift_over_Extra_Thickness_ratio': DEFSET, },'home': { 'Activate_Home': "False", 'Name_of_Home_File': DEFSET, },'lash': { 'Activate_Lash': "False", 'X_Backlash_mm': DEFSET, 'Y_Backlash_mm': DEFSET, },'fillet': { 'Activate_Fillet': "False", 'Arc_Point': DEFSET, 'Arc_Radius': DEFSET, 'Arc_Segment': DEFSET, 'Bevel': DEFSET, 'Corner_Feed_Rate_Multiplier_ratio': DEFSET, 'Fillet_Radius_over_Perimeter_Width_ratio': DEFSET, 'Reversal_Slowdown_Distance_over_Perimeter_Width_ratio': DEFSET, 'Use_Intermediate_Feed_Rate_in_Corners': DEFSET, },'limit': { 'Activate_Limit': "True", 'Maximum_Initial_Feed_Rate_mm/s': "100.0", },'unpause': { 'Activate_Unpause': "False", 'Delay_milliseconds': DEFSET, 'Maximum_Speed_ratio': DEFSET, },'dimension': { 'Activate_Dimension': "True", 'Absolute_Extrusion_Distance': "True", 'Relative_Extrusion_Distance': "False", 'Extruder_Retraction_Speed_mm/s': storedSettingFloat('retraction_speed'), 'Filament_Diameter_mm': storedSettingFloat("filament_diameter"), 'Filament_Packing_Density_ratio': storedSettingFloat('filament_density'), 'Maximum_E_Value_before_Reset_float': "91234.0", 'Minimum_Travel_for_Retraction_millimeters': "0.5", 'Retract_Within_Island': storedSettingInvertBoolean("retract_on_jumps_only"), 'Retraction_Distance_millimeters': storedSettingFloat('retraction_amount'), 'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'), },'alteration': { 'Activate_Alteration': storedSetting('add_start_end_gcode'), 'Name_of_End_File': "end.gcode", 'Name_of_Start_File': "start.gcode", 'Remove_Redundant_Mcode': "True", 'Replace_Variable_with_Setting': DEFSET, },'export': { 'Activate_Export': "True", 'Add_Descriptive_Extension': DEFSET, 'Add_Export_Suffix': "False", 'Add_Profile_Extension': DEFSET, 'Add_Timestamp_Extension': DEFSET, 'Also_Send_Output_To': DEFSET, 'Analyze_Gcode': DEFSET, 'Comment_Choice': DEFSET, 'Do_Not_Change_Output': DEFSET, 'binary_16_byte': DEFSET, 'gcode_step': DEFSET, 'gcode_time_segment': DEFSET, 'gcode_small': DEFSET, 'File_Extension': storedSetting('gcode_extension'), 'Name_of_Replace_File': DEFSET, 'Save_Penultimate_Gcode': "False", } }
def __init__(self, parent, callback): super(simpleModePanel, self).__init__(parent) self._callback = callback self.SetBackgroundColour( wx.Colour( 255, 255, 255 ) ) self._nozzle_size_options = [0.25, 0.4, 0.5, 0.6, 0.8] self._print_profile_options = [] self._print_material_options = [] printTypePanel = wx.Panel(self) for filename in resources.getSimpleModeProfiles(): cp = configparser.ConfigParser() cp.read(filename) base_filename = os.path.splitext(os.path.basename(filename))[0] name = base_filename if cp.has_option('info', 'name'): name = cp.get('info', 'name') button = wx.RadioButton(printTypePanel, -1, name, wx.DefaultPosition, wx.Size( -1,25 ), style=wx.RB_GROUP if len(self._print_profile_options) == 0 else 0) button.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) button.base_filename = base_filename button.filename = filename self._print_profile_options.append(button) if profile.getPreference('simpleModeProfile') == base_filename: button.SetValue(True) printMaterialPanel = wx.Panel(self) for filename in resources.getSimpleModeMaterials(): cp = configparser.ConfigParser() cp.read(filename) base_filename = os.path.splitext(os.path.basename(filename))[0] name = base_filename if cp.has_option('info', 'name'): name = cp.get('info', 'name') button = wx.RadioButton(printMaterialPanel, -1, name, wx.DefaultPosition, wx.Size( -1,25 ), style=wx.RB_GROUP if len(self._print_material_options) == 0 else 0) button.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) button.base_filename = base_filename button.filename = filename self._print_material_options.append(button) if profile.getPreference('simpleModeMaterial') == base_filename: button.SetValue(True) if profile.getMachineSetting('gcode_flavor') == 'UltiGCode': printMaterialPanel.Show(False) self.nozzle_size_panel = wx.Panel(self) self.nozzle_size_label = wx.StaticText(self.nozzle_size_panel, -1, _("Diameter (mm):")) self.nozzle_size_label.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) choices = [] for i in self._nozzle_size_options: choices.append(_(str(i))) self.nozzle_size_combo = wx.ComboBox(self.nozzle_size_panel, -1, '', choices=choices, style=wx.CB_DROPDOWN|wx.CB_READONLY) self.nozzle_size_combo.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) index = 1 # fallback index try: nozzle = profile.getPreferenceFloat("active_nozzle") if nozzle is None or nozzle <= 0: nozzle = 0.4 index = self._nozzle_size_options.index(nozzle) except: pass self.nozzle_size_combo.SetSelection(index) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.nozzle_size_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 10) sizer.Add(self.nozzle_size_combo, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.EXPAND, 10) self.nozzle_size_panel.SetSizer(sizer) # self.printSupport = wx.CheckBox(self, -1, _("Print support structure")) # self.printSupport.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) self.platform_adhesion_panel = wx.Panel(self) self.platform_adhesion_label = wx.StaticText(self.platform_adhesion_panel, -1, _("Platform adhesion: ")) self.platform_adhesion_label.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) self.platform_adhesion_combo = wx.ComboBox(self.platform_adhesion_panel, -1, '', choices=[_("None"), _("Brim"), _("Raft")], style=wx.CB_DROPDOWN|wx.CB_READONLY) self.platform_adhesion_combo.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) self.platform_adhesion_combo.SetSelection(int(profile.getPreference('simpleModePlatformAdhesion'))) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.platform_adhesion_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 10) sizer.Add(self.platform_adhesion_combo, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.EXPAND, 10) self.platform_adhesion_panel.SetSizer(sizer) self.platform_support_panel = wx.Panel(self) self.platform_support_label = wx.StaticText(self.platform_support_panel, -1, _("Support Type:")) self.platform_support_label.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) self.platform_support_combo = wx.ComboBox(self.platform_support_panel, -1, '', choices=[_("None"), _("Touching buildplate"), _("Everywhere")], style=wx.CB_DROPDOWN|wx.CB_READONLY) self.platform_support_combo.SetFont( wx.Font( 12, 74, 90, 90, False, "Sans" ) ) self.platform_support_combo.SetSelection(int(profile.getPreference('simpleModeSupportType'))) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.platform_support_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 10) sizer.Add(self.platform_support_combo, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.EXPAND, 10) self.platform_support_panel.SetSizer(sizer) sizer = wx.GridBagSizer() self.SetSizer(sizer) sizer.Add((15, 15), (0, 0)) sb = wx.StaticBox(self, label=_("Nozzle:")) sb.SetFont( wx.Font( 12, 74, 90, 92, False, "Sans" ) ) boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) boxsizer.Add(self.nozzle_size_panel) sizer.Add(boxsizer, (1,0), flag=wx.EXPAND) sizer.Add((20, 20), (2, 0)) sb = wx.StaticBox(printTypePanel, label=_("Print Quality:")) sb.SetFont( wx.Font( 12, 74, 90, 92, False, "Sans" ) ) boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) for button in self._print_profile_options: boxsizer.Add(button) printTypePanel.SetSizer(wx.BoxSizer(wx.VERTICAL)) printTypePanel.GetSizer().Add(boxsizer, flag=wx.EXPAND) sizer.Add(printTypePanel, (3,0), flag=wx.EXPAND) sizer.Add((20, 20), (4, 0)) sb = wx.StaticBox(printMaterialPanel, label=_("Material:")) sb.SetFont( wx.Font( 12, 74, 90, 92, False, "Sans" ) ) boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) for button in self._print_material_options: boxsizer.Add(button) printMaterialPanel.SetSizer(wx.BoxSizer(wx.VERTICAL)) printMaterialPanel.GetSizer().Add(boxsizer, flag=wx.EXPAND) sizer.Add(printMaterialPanel, (5,0), flag=wx.EXPAND) sizer.Add((20, 20), (6, 0)) sb = wx.StaticBox(self, label=_("Other:")) sb.SetFont( wx.Font( 12, 74, 90, 92, False, "Sans" ) ) boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) # boxsizer.Add(self.printSupport) boxsizer.Add(self.platform_adhesion_panel) boxsizer.Add(self.platform_support_panel) sizer.Add(boxsizer, (7,0), flag=wx.EXPAND) for button in self._print_profile_options: button.Bind(wx.EVT_RADIOBUTTON, self._update) for button in self._print_material_options: button.Bind(wx.EVT_RADIOBUTTON, self._update) # self.printSupport.Bind(wx.EVT_CHECKBOX, self._update) self.nozzle_size_combo.Bind(wx.EVT_COMBOBOX, self._update) self.platform_adhesion_combo.Bind(wx.EVT_COMBOBOX, self._update) self.platform_support_combo.Bind(wx.EVT_COMBOBOX, self._update)
def _load(self, gcodeFile): filePos = 0 pos = util3d.Vector3() posOffset = util3d.Vector3() 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 layerThickness = 0.1 pathType = 'CUSTOM' startCodeDone = False currentLayer = [] currentPath = gcodePath('move', pathType, layerThickness, pos.copy()) currentPath.list[0].e = totalExtrusion currentPath.list[0].extrudeAmountMultiply = extrudeAmountMultiply currentLayer.append(currentPath) for line in gcodeFile: if type(line) is tuple: line = line[0] if self.progressCallback != None: if filePos != gcodeFile.tell(): filePos = gcodeFile.tell() self.progressCallback( float(filePos) / float(self._fileSize)) #Parse Cura_SF comments if line.startswith(';TYPE:'): pathType = line[6:].strip() if pathType != "CUSTOM": startCodeDone = True 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:'): self.layerList.append(currentLayer) currentLayer = [] if pathType != "CUSTOM": startCodeDone = True line = line[0:line.find(';')] T = self.getCodeInt(line, 'T') if T is not None: if currentExtruder > 0: posOffset.x -= profile.getPreferenceFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset.y -= profile.getPreferenceFloat( 'extruder_offset_y%d' % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset.x += profile.getPreferenceFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset.y += profile.getPreferenceFloat( 'extruder_offset_y%d' % (currentExtruder)) G = self.getCodeInt(line, 'G') if G is not None: if G == 0 or G == 1: #Move x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') e = self.getCodeFloat(line, 'E') f = self.getCodeFloat(line, 'F') oldPos = pos.copy() if x is not None: if posAbs: pos.x = x * scale + posOffset.x else: pos.x += x * scale if y is not None: if posAbs: pos.y = y * scale + posOffset.y else: pos.y += y * scale if z is not None: if posAbs: pos.z = z * scale + posOffset.z else: pos.z += z * scale if f is not None: feedRate = f if x is not None or y is not None or z is not None: totalMoveTimeMinute += (oldPos - pos).vsize() / feedRate moveType = 'move' if e is not None: if not absoluteE: e += currentE if posAbs: if e > currentE: moveType = 'extrude' if e < currentE: moveType = 'retract' else: if e > 0: moveType = 'extrude' if e < 0: moveType = 'retract' totalExtrusion += e - currentE currentE = e if totalExtrusion > maxExtrusion: maxExtrusion = totalExtrusion if moveType == 'move' and oldPos.z != pos.z: if oldPos.z > pos.z and abs( oldPos.z - pos.z) > 5.0 and pos.z < 1.0: oldPos.z = 0.0 layerThickness = abs(oldPos.z - pos.z) if currentPath.type != moveType or currentPath.pathType != pathType: currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.list[-1]) currentLayer.append(currentPath) newPos = pos.copy() newPos.e = totalExtrusion newPos.extrudeAmountMultiply = extrudeAmountMultiply currentPath.list.append(newPos) elif G == 4: #Delay S = self.getCodeFloat(line, 'S') if S is not None: totalMoveTimeMinute += S / 60 P = self.getCodeFloat(line, 'P') if P is not None: totalMoveTimeMinute += P / 60 / 1000 elif G == 20: #Units are inches scale = 25.4 elif G == 21: #Units are mm scale = 1.0 elif G == 28: #Home x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') if x is None and y is None and z is None: pos = util3d.Vector3() else: if x is not None: pos.x = 0.0 if y is not None: pos.y = 0.0 if z is not None: pos.z = 0.0 elif G == 90: #Absolute position posAbs = True elif G == 91: #Relative position posAbs = False elif G == 92: x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') e = self.getCodeFloat(line, 'E') if e is not None: currentE = e if x is not None: posOffset.x = pos.x - x if y is not None: posOffset.y = pos.y - y if z is not None: posOffset.z = pos.z - z else: print "Unknown G code:" + str(G) else: M = self.getCodeInt(line, 'M') if M is not None: if 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 == 140: #Set bed temperature pass elif M == 190: #Set bed temperature & wait pass elif M == 221: #Extrude amount multiplier s = self.getCodeFloat(line, 'S') if s != None: extrudeAmountMultiply = s / 100.0 else: print "Unknown M code:" + str(M) self.layerList.append(currentLayer) self.extrusionAmount = maxExtrusion self.totalMoveTimeMinute = totalMoveTimeMinute
def _engineSettings(self, extruderCount): settings = { 'layerThickness': int(profile.getProfileSettingFloat('layer_height') * 1000), 'initialLayerThickness': int(profile.getProfileSettingFloat('bottom_thickness') * 1000) if profile.getProfileSettingFloat('bottom_thickness') > 0.0 else int( profile.getProfileSettingFloat('layer_height') * 1000), 'filamentDiameter': int(profile.getProfileSettingFloat('filament_diameter') * 1000), 'filamentFlow': int(profile.getProfileSettingFloat('filament_flow')), 'extrusionWidth': int(profile.calculateEdgeWidth() * 1000), 'insetCount': int(profile.calculateLineCount()), 'downSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_bottom') == 'True' else 0, 'upSkinCount': int(profile.calculateSolidLayerCount()) if profile.getProfileSetting('solid_top') == 'True' else 0, 'sparseInfillLineDistance': int(100 * profile.calculateEdgeWidth() * 1000 / profile.getProfileSettingFloat('fill_density')) if profile.getProfileSettingFloat('fill_density') > 0 else -1, 'infillOverlap': int(profile.getProfileSettingFloat('fill_overlap')), 'initialSpeedupLayers': int(4), 'initialLayerSpeed': int(profile.getProfileSettingFloat('bottom_layer_speed')), 'printSpeed': int(profile.getProfileSettingFloat('print_speed')), 'infillSpeed': int(profile.getProfileSettingFloat('infill_speed')) if int(profile.getProfileSettingFloat('infill_speed')) > 0 else int( profile.getProfileSettingFloat('print_speed')), 'moveSpeed': int(profile.getProfileSettingFloat('travel_speed')), 'fanOnLayerNr': int(profile.getProfileSettingFloat('fan_layer')), 'fanSpeedMin': int(profile.getProfileSettingFloat('fan_speed')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'fanSpeedMax': int(profile.getProfileSettingFloat('fan_speed_max')) if profile.getProfileSetting('fan_enabled') == 'True' else 0, 'supportAngle': int(-1) if profile.getProfileSetting('support') == 'None' else int(60), 'supportEverywhere': int(1) if profile.getProfileSetting('support') == 'Everywhere' else int(0), 'supportLineWidth': int( profile.getProfileSettingFloat('support_rate') * profile.calculateEdgeWidth() * 1000 / 100), 'retractionAmount': int(profile.getProfileSettingFloat('retraction_amount') * 1000) if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'retractionSpeed': int(profile.getProfileSettingFloat('retraction_speed')), 'retractionAmountExtruderSwitch': int( profile.getProfileSettingFloat('retraction_dual_amount') * 1000), 'multiVolumeOverlap': int(profile.getProfileSettingFloat('overlap_dual') * 1000), 'objectSink': int(profile.getProfileSettingFloat('object_sink') * 1000), 'minimalLayerTime': int(profile.getProfileSettingFloat('cool_min_layer_time')), 'minimalFeedrate': int(profile.getProfileSettingFloat('cool_min_feedrate')), 'coolHeadLift': 1 if profile.getProfileSetting('cool_head_lift') == 'True' else 0, 'startCode': profile.getAlterationFileContents('start.gcode', extruderCount), 'endCode': profile.getAlterationFileContents('end.gcode', extruderCount), 'extruderOffset[1].X': int(profile.getPreferenceFloat('extruder_offset_x1') * 1000), 'extruderOffset[1].Y': int(profile.getPreferenceFloat('extruder_offset_y1') * 1000), 'extruderOffset[2].X': int(profile.getPreferenceFloat('extruder_offset_x2') * 1000), 'extruderOffset[2].Y': int(profile.getPreferenceFloat('extruder_offset_y2') * 1000), 'extruderOffset[3].X': int(profile.getPreferenceFloat('extruder_offset_x3') * 1000), 'extruderOffset[3].Y': int(profile.getPreferenceFloat('extruder_offset_y3') * 1000), 'fixHorrible': 0, } if profile.getProfileSetting('platform_adhesion') == 'Brim': settings['skirtDistance'] = 0 settings['skirtLineCount'] = int( profile.getProfileSettingFloat('brim_line_count')) elif profile.getProfileSetting('platform_adhesion') == 'Raft': settings['skirtDistance'] = 0 settings['skirtLineCount'] = 0 settings['raftMargin'] = int( profile.getProfileSettingFloat('raft_margin') * 1000) settings['raftBaseThickness'] = int( profile.getProfileSettingFloat('raft_base_thickness') * 1000) settings['raftBaseLinewidth'] = int( profile.getProfileSettingFloat('raft_base_linewidth') * 1000) settings['raftInterfaceThickness'] = int( profile.getProfileSettingFloat('raft_interface_thickness') * 1000) settings['raftInterfaceLinewidth'] = int( profile.getProfileSettingFloat('raft_interface_linewidth') * 1000) else: settings['skirtDistance'] = int( profile.getProfileSettingFloat('skirt_gap') * 1000) settings['skirtLineCount'] = int( profile.getProfileSettingFloat('skirt_line_count')) if profile.getProfileSetting( 'fix_horrible_union_all_type_a') == 'True': settings['fixHorrible'] |= 0x01 if profile.getProfileSetting( 'fix_horrible_union_all_type_b') == 'True': settings['fixHorrible'] |= 0x02 if profile.getProfileSetting('fix_horrible_use_open_bits') == 'True': settings['fixHorrible'] |= 0x10 if profile.getProfileSetting( 'fix_horrible_extensive_stitching') == 'True': settings['fixHorrible'] |= 0x04 if settings['layerThickness'] <= 0: settings['layerThickness'] = 1000 return settings
def __init__(self, parent): super(machineSettingsDialog, self).__init__(parent, title=_("Machine settings")) wx.EVT_CLOSE(self, self.OnClose) self.parent = parent self.panel = configBase.configPanelBase(self) self.SetSizer(wx.BoxSizer(wx.HORIZONTAL)) self.GetSizer().Add(self.panel, 1, wx.EXPAND) self.nb = wx.Notebook(self.panel) self.panel.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.panel.GetSizer().Add(self.nb, 1, wx.EXPAND) for idx in xrange(0, profile.getMachineCount()): printer_type = profile.getMachineSetting('machine_type', idx) extruderCount = int( profile.getMachineSetting('extruder_amount', idx)) left, right, main = self.panel.CreateConfigPanel(self.nb) configBase.TitleRow(left, _("Machine settings")) configBase.SettingRow(left, 'steps_per_e', index=idx) configBase.SettingRow(left, 'machine_width', index=idx) configBase.SettingRow(left, 'machine_depth', index=idx) configBase.SettingRow(left, 'machine_height', index=idx) if not printer_type.startswith( 'lulzbot_TAZ_6' ): #Disabled for TAZ 6, use LCD controller instead configBase.SettingRow(left, 'extruder_z_offset', index=idx) configBase.SettingRow(left, 'extruder_amount', index=idx) configBase.SettingRow(left, 'has_heated_bed', index=idx) configBase.SettingRow(left, 'machine_center_is_zero', index=idx) configBase.SettingRow(left, 'machine_shape', index=idx) configBase.SettingRow(left, 'gcode_flavor', index=idx) configBase.SettingRow(left, 'machine_startup_energy_PLA', index=idx) configBase.SettingRow(left, 'machine_run_energy_PLA', index=idx) configBase.SettingRow(left, 'machine_startup_energy_ABS', index=idx) configBase.SettingRow(left, 'machine_run_energy_ABS', index=idx) configBase.SettingRow(left, 'machine_startup_energy_HIPS', index=idx) configBase.SettingRow(left, 'machine_run_energy_HIPS', index=idx) configBase.SettingRow(left, 'machine_startup_energy_PETT', index=idx) configBase.SettingRow(left, 'machine_run_energy_PETT', index=idx) configBase.SettingRow(left, 'machine_startup_energy_Nylon', index=idx) configBase.SettingRow(left, 'machine_run_energy_Nylon', index=idx) configBase.SettingRow(left, 'machine_startup_energy_Other', index=idx) configBase.SettingRow(left, 'machine_run_energy_Other', index=idx) if printer_type.startswith('lulzbot_'): configBase.TitleRow(right, _("Tool Head")) row = configBase.ToolHeadRow(right, 'toolhead', index=idx) row.button.Bind(wx.EVT_BUTTON, self.OnChangeToolheadButton) configBase.TitleRow(right, _("Printer head size")) configBase.SettingRow(right, 'extruder_head_size_min_x', index=idx) configBase.SettingRow(right, 'extruder_head_size_min_y', index=idx) configBase.SettingRow(right, 'extruder_head_size_max_x', index=idx) configBase.SettingRow(right, 'extruder_head_size_max_y', index=idx) configBase.SettingRow(right, 'extruder_head_size_height', index=idx) for i in xrange(1, extruderCount): configBase.TitleRow(left, _("Extruder %d") % (i + 1)) configBase.SettingRow(left, 'extruder_offset_x%d' % (i), index=idx) configBase.SettingRow(left, 'extruder_offset_y%d' % (i), index=idx) configBase.TitleRow(right, _("Communication settings")) serial_list = ['AUTO'] + machineCom.serialList() serial_list_labels = serial_list[:] if profile.getMachineSetting('serial_port') not in serial_list: serial_list.append(profile.getMachineSetting('serial_port')) serial_list_labels.append( profile.getMachineSetting('serial_port') + _(" (Currently unavailable)")) configBase.SettingRow(right, 'serial_port', serial_list, serial_list_labels, index=idx) configBase.SettingRow(right, 'serial_baud', ['AUTO'] + map(str, machineCom.baudrateList()), index=idx) machine_name = profile.getMachineName(idx) machine_title = machine_name.title() machine_title = machine_title.replace('Taz', 'TAZ') machine_title = machine_title.replace('Lulzbot', 'LulzBot') self.nb.AddPage(main, machine_title) self.nb.SetSelection(int(profile.getPreferenceFloat('active_machine'))) self.buttonPanel = wx.Panel(self.panel) self.panel.GetSizer().Add(self.buttonPanel) self.buttonPanel.SetSizer(wx.BoxSizer(wx.HORIZONTAL)) self.okButton = wx.Button(self.buttonPanel, -1, _('Ok')) self.okButton.Bind(wx.EVT_BUTTON, lambda e: self.Close()) self.buttonPanel.GetSizer().Add(self.okButton, flag=wx.ALL, border=5) self.addButton = wx.Button(self.buttonPanel, -1, _('Add new machine')) self.addButton.Bind(wx.EVT_BUTTON, self.OnAddMachine) self.buttonPanel.GetSizer().Add(self.addButton, flag=wx.ALL, border=5) self.remButton = wx.Button(self.buttonPanel, -1, _('Remove machine')) self.remButton.Bind(wx.EVT_BUTTON, self.OnRemoveMachine) self.buttonPanel.GetSizer().Add(self.remButton, flag=wx.ALL, border=5) self.renButton = wx.Button(self.buttonPanel, -1, _('Change machine name')) self.renButton.Bind(wx.EVT_BUTTON, self.OnRenameMachine) self.buttonPanel.GetSizer().Add(self.renButton, flag=wx.ALL, border=5) main.Fit() self.Fit()
def __init__(self): super(projectPlanner, self).__init__(None, title='Cura - Project Planner') wx.EVT_CLOSE(self, self.OnClose) self.panel = wx.Panel(self, -1) self.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND) self.SetDropTarget( dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.supportedExtensions())) self.list = [] self.selection = None self.printMode = 0 self.alwaysAutoPlace = profile.getPreference( 'planner_always_autoplace') == 'True' self.machineSize = numpy.array([ profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height') ]) self.headSizeMin = numpy.array([ profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'), 0 ]) self.headSizeMax = numpy.array([ profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'), 0 ]) self.extruderOffset = [ numpy.array([0, 0, 0]), numpy.array([ profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0 ]), numpy.array([ profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0 ]), numpy.array([ profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0 ]) ] self.toolbar = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar, self.OnLoadProject, 'open.png', 'Open project') toolbarUtil.NormalButton(self.toolbar, self.OnSaveProject, 'save.png', 'Save project') self.toolbar.AddSeparator() group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick).SetValue( self.alwaysAutoPlace) toolbarUtil.RadioButton( self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(not self.alwaysAutoPlace) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences') self.toolbar.AddSeparator() toolbarUtil.NormalButton( self.toolbar, self.OnCutMesh, 'cut-mesh.png', 'Cut a plate STL into multiple STL files, and add those files to the project.\nNote: Splitting up plates sometimes takes a few minutes.' ) toolbarUtil.NormalButton( self.toolbar, self.OnSaveCombinedSTL, 'save-combination.png', 'Save all the combined STL files into a single STL file as a plate.' ) self.toolbar.AddSeparator() group = [] self.printOneAtATime = toolbarUtil.RadioButton( self.toolbar, group, 'view-normal-on.png', 'view-normal-off.png', 'Print one object at a time', callback=self.OnPrintTypeChange) self.printAllAtOnce = toolbarUtil.RadioButton( self.toolbar, group, 'all-at-once-on.png', 'all-at-once-off.png', 'Print all the objects at once', callback=self.OnPrintTypeChange) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner') self.toolbar.Realize() self.toolbar2 = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar2, self.OnAddModel, 'object-add.png', 'Add model') toolbarUtil.NormalButton(self.toolbar2, self.OnRemModel, 'object-remove.png', 'Remove model') self.toolbar2.AddSeparator() toolbarUtil.NormalButton(self.toolbar2, self.OnMoveUp, 'move-up.png', 'Move model up in print list') toolbarUtil.NormalButton(self.toolbar2, self.OnMoveDown, 'move-down.png', 'Move model down in print list') toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object') toolbarUtil.NormalButton( self.toolbar2, self.OnSetCustomProfile, 'set-profile.png', 'Set a custom profile to be used to prepare a specific object.') self.toolbar2.AddSeparator() if not self.alwaysAutoPlace: toolbarUtil.NormalButton( self.toolbar2, self.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.') toolbarUtil.NormalButton(self.toolbar2, self.OnSlice, 'slice.png', 'Prepare to project into a gcode file.') self.toolbar2.Realize() sizer = wx.GridBagSizer(2, 2) self.panel.SetSizer(sizer) self.glCanvas = PreviewGLCanvas(self.panel, self) self.listbox = wx.ListBox(self.panel, -1, choices=[]) self.addButton = wx.Button(self.panel, -1, "Add") self.remButton = wx.Button(self.panel, -1, "Remove") self.sliceButton = wx.Button(self.panel, -1, "Prepare") if not self.alwaysAutoPlace: self.autoPlaceButton = wx.Button(self.panel, -1, "Auto Place") sizer.Add(self.toolbar, (0, 0), span=(1, 1), flag=wx.EXPAND | wx.LEFT | wx.RIGHT) sizer.Add(self.toolbar2, (0, 1), span=(1, 2), flag=wx.EXPAND | wx.LEFT | wx.RIGHT) sizer.Add(self.glCanvas, (1, 0), span=(5, 1), flag=wx.EXPAND) sizer.Add(self.listbox, (1, 1), span=(1, 2), flag=wx.EXPAND) sizer.Add(self.addButton, (2, 1), span=(1, 1)) sizer.Add(self.remButton, (2, 2), span=(1, 1)) sizer.Add(self.sliceButton, (3, 1), span=(1, 1)) if not self.alwaysAutoPlace: sizer.Add(self.autoPlaceButton, (3, 2), span=(1, 1)) sizer.AddGrowableCol(0) sizer.AddGrowableRow(1) self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel) self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel) self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice) if not self.alwaysAutoPlace: self.autoPlaceButton.Bind(wx.EVT_BUTTON, self.OnAutoPlace) self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect) panel = wx.Panel(self.panel, -1) sizer.Add(panel, (5, 1), span=(1, 2)) sizer = wx.GridBagSizer(2, 2) panel.SetSizer(sizer) self.rotateToolButton = openglGui.glButton(self.glCanvas, 1, 'Rotate', (0, 1), self.OnRotateSelect) self.scaleToolButton = openglGui.glButton(self.glCanvas, 2, 'Scale', (0, 2), self.OnScaleSelect) self.SetSize((800, 600)) self.tool = previewTools.toolInfo(self.glCanvas)
def calculateWeight(self): #Calculates the weight of the filament in kg radius = float(profile.getProfileSetting('filament_diameter')) / 2 volumeM3 = (self.extrusionAmount * (math.pi * radius * radius)) / (1000*1000*1000) return volumeM3 * profile.getPreferenceFloat('filament_density')
def getFilamentWeight(self, e=0): #Calculates the weight of the filament in kg radius = float(profile.getProfileSetting('filament_diameter')) / 2 volumeM3 = (self._filamentMM[e] * (math.pi * radius * radius)) / (1000*1000*1000) return volumeM3 * profile.getPreferenceFloat('filament_physical_density')
def main(): parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print 'Missing output filename' sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(',')) if len(position) < 9 + 2: position = position[0:2] position += [1,0,0] position += [0,1,0] position += [0,0,1] filenames = fixUTF8(args[idx + 1]).split('|') profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) if idx == 0: resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('start.gcode', len(filenames)).replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) else: resultFile.write(';TYPE:CUSTOM\n') n = output[-1].rfind('Z')+1 zString = output[-1][n:n+20] zString = zString[0:zString.find(' ')] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride('clear_z', clearZ) print position print profile.getAlterationFileContents('nextobject.gcode') resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr))) profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))) profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('alternative_center', filenames[0]) else: profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11]))) if extruderNr > 0: if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0: profile.setTempOverride('filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1))) print extruderNr, profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)), profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output)) if profile.getPreference('submit_slice_information') == 'True': filenames = fixUTF8(args[idx + 1]).split('|') for filename in filenames: m = hashlib.sha512() f = open(filename, "rb") while True: chunk = f.read(1024) if not chunk: break m.update(chunk) f.close() data = { 'processor': platform.processor(), 'machine': platform.machine(), 'platform': platform.platform(), 'profile': profile.getGlobalProfileString(), 'preferences': profile.getGlobalPreferencesString(), 'modelhash': m.hexdigest(), 'version': version.getVersion(), } try: f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data = urllib.urlencode(data), timeout = 5); f.read() f.close() except: pass
def __init__(self, parent): super(machineSettingsDialog, self).__init__(None, title=_("Machine settings")) wx.EVT_CLOSE(self, self.OnClose) self.parent = parent self.panel = configBase.configPanelBase(self) self.SetSizer(wx.BoxSizer(wx.HORIZONTAL)) self.GetSizer().Add(self.panel, 1, wx.EXPAND) self.nb = wx.Notebook(self.panel) self.panel.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.panel.GetSizer().Add(self.nb, 1, wx.EXPAND) for idx in xrange(0, profile.getMachineCount()): extruderCount = int(profile.getMachineSetting('extruder_amount', idx)) left, right, main = self.panel.CreateConfigPanel(self.nb) configBase.TitleRow(left, _("Machine settings")) #configBase.SettingRow(left, 'steps_per_e', index=idx) configBase.SettingRow(left, 'machine_width', index=idx) configBase.SettingRow(left, 'machine_depth', index=idx) configBase.SettingRow(left, 'machine_height', index=idx) configBase.SettingRow(left, 'extruder_amount', index=idx) # configBase.SettingRow(left, 'has_heated_bed', index=idx) #configBase.SettingRow(left, 'machine_center_is_zero', index=idx) #configBase.SettingRow(left, 'machine_shape', index=idx) #configBase.SettingRow(left, 'gcode_flavor', index=idx) # configBase.TitleRow(right, _("Printer head size")) # configBase.SettingRow(right, 'extruder_head_size_min_x', index=idx) # configBase.SettingRow(right, 'extruder_head_size_min_y', index=idx) # configBase.SettingRow(right, 'extruder_head_size_max_x', index=idx) # configBase.SettingRow(right, 'extruder_head_size_max_y', index=idx) # configBase.SettingRow(right, 'extruder_head_size_height', index=idx) for i in xrange(1, extruderCount): configBase.TitleRow(left, _("Extruder %d") % (i + 1)) configBase.SettingRow(left, 'extruder_offset_x%d' % (i), index=idx) configBase.SettingRow(left, 'extruder_offset_y%d' % (i), index=idx) # configBase.TitleRow(right, _("Communication settings")) # configBase.SettingRow(right, 'serial_port', ['AUTO'] + machineCom.serialList(), index=idx) # configBase.SettingRow(right, 'serial_baud', ['AUTO'] + map(str, machineCom.baudrateList()), index=idx) self.nb.AddPage(main, profile.getMachineSetting('machine_name', idx).title()) self.nb.SetSelection(int(profile.getPreferenceFloat('active_machine'))) self.buttonPanel = wx.Panel(self.panel) self.panel.GetSizer().Add(self.buttonPanel) self.buttonPanel.SetSizer(wx.BoxSizer(wx.HORIZONTAL)) self.okButton = wx.Button(self.buttonPanel, -1, 'Ok') self.okButton.Bind(wx.EVT_BUTTON, lambda e: self.Close()) self.buttonPanel.GetSizer().Add(self.okButton, flag=wx.ALL, border=5) self.addButton = wx.Button(self.buttonPanel, -1, _('Add new machine')) self.addButton.Bind(wx.EVT_BUTTON, self.OnAddMachine) self.buttonPanel.GetSizer().Add(self.addButton, flag=wx.ALL, border=5) self.remButton = wx.Button(self.buttonPanel, -1, _('Remove machine')) self.remButton.Bind(wx.EVT_BUTTON, self.OnRemoveMachine) self.buttonPanel.GetSizer().Add(self.remButton, flag=wx.ALL, border=5) self.renButton = wx.Button(self.buttonPanel, -1, _('Change machine name')) self.renButton.Bind(wx.EVT_BUTTON, self.OnRenameMachine) self.buttonPanel.GetSizer().Add(self.renButton, flag=wx.ALL, border=5) main.Fit() self.Fit()
def main(): parser = OptionParser( usage= "usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print 'Missing output filename' sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(',')) if len(position) < 9 + 2: position = position[0:2] position += [1, 0, 0] position += [0, 1, 0] position += [0, 0, 1] filenames = fixUTF8(args[idx + 1]).split('|') profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) if idx == 0: resultFile.write(';TYPE:CUSTOM\n') resultFile.write( profile.getAlterationFileContents( 'start.gcode', len(filenames)).replace( '?filename?', ' '.join(filenames).encode('ascii', 'replace'))) else: resultFile.write(';TYPE:CUSTOM\n') n = output[-1].rfind('Z') + 1 zString = output[-1][n:n + 20] zString = zString[0:zString.find(' ')] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride('clear_z', clearZ) print position print profile.getAlterationFileContents('nextobject.gcode') resultFile.write( profile.getAlterationFileContents('nextobject.gcode').replace( '?filename?', ' '.join(filenames).encode('ascii', 'replace'))) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride( 'object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr))) profile.setTempOverride( 'object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))) profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('alternative_center', filenames[0]) else: profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11]))) if extruderNr > 0: if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0: profile.setTempOverride( 'filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1))) print extruderNr, profile.getPreferenceFloat( 'extruder_offset_x%d' % (extruderNr)), profile.getPreferenceFloat( 'extruder_offset_y%d' % (extruderNr)) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output)) if profile.getPreference('submit_slice_information') == 'True': filenames = fixUTF8(args[idx + 1]).split('|') for filename in filenames: m = hashlib.sha512() f = open(filename, "rb") while True: chunk = f.read(1024) if not chunk: break m.update(chunk) f.close() data = { 'processor': platform.processor(), 'machine': platform.machine(), 'platform': platform.platform(), 'profile': profile.getGlobalProfileString(), 'preferences': profile.getGlobalPreferencesString(), 'modelhash': m.hexdigest(), 'version': version.getVersion(), } try: f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data=urllib.urlencode(data), timeout=5) f.read() f.close() except: pass
def getProfileInformation(): return { 'carve': { 'Add_Layer_Template_to_SVG': 'False', 'Edge_Width_mm': calculateEdgeWidth, 'Extra_Decimal_Places_float': DEFSET, 'Import_Coarseness_ratio': DEFSET, 'Layer_Height_mm': storedSettingFloat("layer_height"), 'Layers_From_index': calcLayerSkip, 'Layers_To_index': DEFSET, 'Correct_Mesh': DEFSET, 'Unproven_Mesh': DEFSET, 'SVG_Viewer': DEFSET, 'ObjectMatrix': storedSetting("object_matrix"), 'CenterX': lambda setting: profile.getProfileSettingFloat('object_center_x'), 'CenterY': lambda setting: profile.getProfileSettingFloat('object_center_y'), 'AlternativeCenterFile': storedSetting("alternative_center"), }, 'scale': { 'Activate_Scale': "False", 'XY_Plane_Scale_ratio': DEFSET, 'Z_Axis_Scale_ratio': DEFSET, 'SVG_Viewer': DEFSET, }, 'bottom': { 'Activate_Bottom': DEFSET, 'Additional_Height_over_Layer_Thickness_ratio': DEFSET, 'Altitude_mm': calcExtraBottomThickness, 'SVG_Viewer': DEFSET, }, 'preface': { 'Meta': DEFSET, 'Set_Positioning_to_Absolute': "False", 'Set_Units_to_Millimeters': "False", 'Start_at_Home': DEFSET, 'Turn_Extruder_Off_at_Shut_Down': DEFSET, 'Turn_Extruder_Off_at_Start_Up': DEFSET, }, 'widen': { 'Activate_Widen': DEFSET, 'Widen_Width_over_Edge_Width_ratio': DEFSET, }, 'inset': { 'Add_Custom_Code_for_Temperature_Reading': "False", 'Infill_in_Direction_of_Bridge': ifSettingAboveZero('fill_density'), 'Infill_Width': storedSettingFloat("nozzle_size"), 'Loop_Order_Choice': DEFSET, 'Overlap_Removal_Width_over_Perimeter_Width_ratio': DEFSET, 'Turn_Extruder_Heater_Off_at_Shut_Down': "False", 'Volume_Fraction_ratio': DEFSET, }, 'fill': { 'Activate_Fill': "True", 'Solid_Surface_Top': storedSetting("solid_top"), 'Override_First_Layer_Sequence': storedSetting("force_first_layer_sequence"), 'Diaphragm_Period_layers': DEFSET, 'Diaphragm_Thickness_layers': DEFSET, 'Extra_Shells_on_Alternating_Solid_Layer_layers': calculateShells, 'Extra_Shells_on_Base_layers': calculateShellsBase, 'Extra_Shells_on_Sparse_Layer_layers': calculateShells, 'Grid_Circle_Separation_over_Perimeter_Width_ratio': DEFSET, 'Grid_Extra_Overlap_ratio': DEFSET, 'Grid_Junction_Separation_Band_Height_layers': DEFSET, 'Grid_Junction_Separation_over_Octogon_Radius_At_End_ratio': DEFSET, 'Grid_Junction_Separation_over_Octogon_Radius_At_Middle_ratio': DEFSET, 'Infill_Begin_Rotation_degrees': DEFSET, 'Infill_Begin_Rotation_Repeat_layers': DEFSET, 'Infill_Odd_Layer_Extra_Rotation_degrees': DEFSET, 'Grid_Circular': ifSettingIs('infill_type', 'Grid Circular'), 'Grid_Hexagonal': ifSettingIs('infill_type', 'Grid Hexagonal'), 'Grid_Rectangular': ifSettingIs('infill_type', 'Grid Rectangular'), 'Line': ifSettingIs('infill_type', 'Line'), 'Infill_Perimeter_Overlap_ratio': storedPercentSetting('fill_overlap'), 'Infill_Solidity_ratio': storedPercentSetting('fill_density'), 'Infill_Width': storedSettingFloat("nozzle_size"), 'Sharpest_Angle_degrees': DEFSET, 'Solid_Surface_Thickness_layers': calculateSolidLayerCount, 'Start_From_Choice': DEFSET, 'Surrounding_Angle_degrees': DEFSET, 'Thread_Sequence_Choice': storedSetting('sequence'), }, 'multiply': { 'Activate_Multiply': "False", 'Center_X_mm': DEFSET, 'Center_Y_mm': DEFSET, 'Number_of_Columns_integer': DEFSET, 'Number_of_Rows_integer': DEFSET, 'Reverse_Sequence_every_Odd_Layer': DEFSET, 'Separation_over_Perimeter_Width_ratio': DEFSET, }, 'speed': { 'Activate_Speed': "True", 'Add_Flow_Rate': "True", 'Bridge_Feed_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'), 'Bridge_Flow_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'), 'Duty_Cyle_at_Beginning_portion': DEFSET, 'Duty_Cyle_at_Ending_portion': DEFSET, 'Feed_Rate_mm/s': storedSettingFloat("print_speed"), 'Flow_Rate_Setting_float': storedSettingFloat("print_speed"), 'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio, 'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': DEFSET, 'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': DEFSET, 'Maximum_Z_Feed_Rate_mm/s': DEFSET, 'Perimeter_Feed_Rate_Multiplier_ratio': DEFSET, 'Perimeter_Flow_Rate_Multiplier_ratio': DEFSET, 'Travel_Feed_Rate_mm/s': storedSettingFloat("travel_speed"), 'Bottom_layer_flow_rate_ratio': calcBottomLayerFlowRateRatio, }, 'temperature': { 'Activate_Temperature': DEFSET, #ifSettingAboveZero('print_temperature'), 'Cooling_Rate_Celcius/second': DEFSET, 'Heating_Rate_Celcius/second': DEFSET, 'Base_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), 'Interface_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), 'Object_First_Layer_Infill_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), 'Object_First_Layer_Perimeter_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), 'Object_Next_Layers_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), 'Support_Layers_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), 'Supported_Layers_Temperature_Celcius': DEFSET, #storedSettingFloat("print_temperature"), }, 'raft': { 'Activate_Raft': "True", 'Add_Raft,_Elevate_Nozzle,_Orbit': DEFSET, 'Base_Feed_Rate_Multiplier_ratio': DEFSET, 'Base_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_base_material_amount'), 'Base_Infill_Density_ratio': DEFSET, 'Base_Layer_Thickness_over_Layer_Thickness': DEFSET, 'Base_Layers_integer': raftLayerCount, 'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': DEFSET, 'Initial_Circling': DEFSET, 'Infill_Overhang_over_Extrusion_Width_ratio': DEFSET, 'Interface_Feed_Rate_Multiplier_ratio': DEFSET, 'Interface_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_interface_material_amount'), 'Interface_Infill_Density_ratio': DEFSET, 'Interface_Layer_Thickness_over_Layer_Thickness': DEFSET, 'Interface_Layers_integer': raftLayerCount, 'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': DEFSET, 'Name_of_Support_End_File': DEFSET, 'Name_of_Support_Start_File': DEFSET, 'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': DEFSET, 'Raft_Additional_Margin_over_Length_%': DEFSET, 'Raft_Margin_mm': storedSettingFloat('raft_margin'), 'Support_Cross_Hatch': lambda setting: 'True' if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else 'False', 'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': storedPercentSetting('support_rate'), 'Support_Gap_over_Perimeter_Extrusion_Width_ratio': calcSupportDistanceRatio, 'Support_Material_Choice_': storedSetting('support'), 'Support_Minimum_Angle_degrees': DEFSET, 'Support_Margin_mm': '3.0', 'Support_Offset_X_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_x1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0', 'Support_Offset_Y_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_y1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0', }, 'skirt': { 'Skirt_line_count': storedSetting("skirt_line_count"), 'Convex': lambda setting: "True" if profile.getProfileSettingFloat('skirt_gap') > 0.0 else "False", 'Gap_Width_mm': storedSetting("skirt_gap"), 'Layers_To_index': "1", }, 'joris': { 'Activate_Joris': storedSetting("joris"), 'Layers_From_index': calculateSolidLayerCount, }, 'chamber': { 'Activate_Chamber': "False", 'Bed_Temperature_Celcius': DEFSET, 'Bed_Temperature_Begin_Change_Height_mm': DEFSET, 'Bed_Temperature_End_Change_Height_mm': DEFSET, 'Bed_Temperature_End_Celcius': DEFSET, 'Chamber_Temperature_Celcius': DEFSET, 'Holding_Force_bar': DEFSET, }, 'tower': { 'Activate_Tower': "False", 'Extruder_Possible_Collision_Cone_Angle_degrees': DEFSET, 'Maximum_Tower_Height_layers': DEFSET, 'Tower_Start_Layer_integer': DEFSET, }, 'jitter': { 'Activate_Jitter': "False", 'Jitter_Over_Perimeter_Width_ratio': DEFSET, }, 'clip': { 'Activate_Clip': "False", 'Clip_Over_Perimeter_Width_ratio': DEFSET, 'Maximum_Connection_Distance_Over_Perimeter_Width_ratio': DEFSET, }, 'smooth': { 'Activate_Smooth': "False", 'Layers_From_index': DEFSET, 'Maximum_Shortening_over_Width_float': DEFSET, }, 'stretch': { 'Activate_Stretch': "False", 'Cross_Limit_Distance_Over_Perimeter_Width_ratio': DEFSET, 'Loop_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Path_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Perimeter_Inside_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': DEFSET, 'Stretch_From_Distance_Over_Perimeter_Width_ratio': DEFSET, }, 'skin': { 'Activate_Skin': storedSetting("enable_skin"), 'Horizontal_Infill_Divisions_integer': "1", 'Horizontal_Perimeter_Divisions_integer': "1", 'Vertical_Divisions_integer': "2", 'Hop_When_Extruding_Infill': "False", 'Layers_From_index': "1", }, 'comb': { 'Activate_Comb': "True", 'Running_Jump_Space_mm': DEFSET, }, 'cool': { 'Activate_Cool': "True", 'Bridge_Cool_Celcius': DEFSET, 'Cool_Type': DEFSET, 'Maximum_Cool_Celcius': DEFSET, 'Minimum_Layer_Time_seconds': storedSettingFloat("cool_min_layer_time"), 'Minimum_Orbital_Radius_millimeters': DEFSET, 'Name_of_Cool_End_File': DEFSET, 'Name_of_Cool_Start_File': DEFSET, 'Orbital_Outset_millimeters': DEFSET, 'Turn_Fan_On_at_Beginning': storedSetting("fan_enabled"), 'Turn_Fan_Off_at_Ending': storedSetting("fan_enabled"), 'Minimum_feed_rate_mm/s': storedSettingFloat("cool_min_feedrate"), 'Fan_on_at_layer': storedSettingInt('fan_layer'), 'Fan_speed_min_%': storedSettingInt('fan_speed'), 'Fan_speed_max_%': storedSettingInt('fan_speed_max'), }, 'hop': { 'Activate_Hop': storedSetting('hop_on_move'), 'Hop_Over_Layer_Thickness_ratio': lambda setting: 0.2 / profile.getProfileSettingFloat('layer_height' ), 'Minimum_Hop_Angle_degrees': DEFSET, }, 'wipe': { 'Activate_Wipe': "False", 'Arrival_X_mm': DEFSET, 'Arrival_Y_mm': DEFSET, 'Arrival_Z_mm': DEFSET, 'Departure_X_mm': DEFSET, 'Departure_Y_mm': DEFSET, 'Departure_Z_mm': DEFSET, 'Wipe_X_mm': DEFSET, 'Wipe_Y_mm': DEFSET, 'Wipe_Z_mm': DEFSET, 'Wipe_Period_layers': DEFSET, }, 'oozebane': { 'Activate_Oozebane': "False", 'After_Startup_Distance_millimeters': DEFSET, 'Early_Shutdown_Distance_millimeters': DEFSET, 'Early_Startup_Distance_Constant_millimeters': DEFSET, 'Early_Startup_Maximum_Distance_millimeters': DEFSET, 'First_Early_Startup_Distance_millimeters': DEFSET, 'Minimum_Distance_for_Early_Startup_millimeters': DEFSET, 'Minimum_Distance_for_Early_Shutdown_millimeters': DEFSET, 'Slowdown_Startup_Steps_positive_integer': DEFSET, }, 'dwindle': { 'Activate_Dwindle': "False", 'End_Rate_Multiplier_ratio': '0.5', 'Pent_Up_Volume_cubic_millimeters': "0.4", 'Slowdown_Steps_positive_integer': '5', 'Slowdown_Volume_cubic_millimeters': "5.0", }, 'splodge': { 'Activate_Splodge': "False", 'Initial_Lift_over_Extra_Thickness_ratio': DEFSET, 'Initial_Splodge_Feed_Rate_mm/s': DEFSET, 'Operating_Splodge_Feed_Rate_mm/s': DEFSET, 'Operating_Splodge_Quantity_Length_millimeters': DEFSET, 'Initial_Splodge_Quantity_Length_millimeters': DEFSET, 'Operating_Lift_over_Extra_Thickness_ratio': DEFSET, }, 'home': { 'Activate_Home': "False", 'Name_of_Home_File': DEFSET, }, 'lash': { 'Activate_Lash': "False", 'X_Backlash_mm': DEFSET, 'Y_Backlash_mm': DEFSET, }, 'fillet': { 'Activate_Fillet': "False", 'Arc_Point': DEFSET, 'Arc_Radius': DEFSET, 'Arc_Segment': DEFSET, 'Bevel': DEFSET, 'Corner_Feed_Rate_Multiplier_ratio': DEFSET, 'Fillet_Radius_over_Perimeter_Width_ratio': DEFSET, 'Reversal_Slowdown_Distance_over_Perimeter_Width_ratio': DEFSET, 'Use_Intermediate_Feed_Rate_in_Corners': DEFSET, }, 'limit': { 'Activate_Limit': "False", 'Maximum_Initial_Feed_Rate_mm/s': DEFSET, }, 'unpause': { 'Activate_Unpause': "False", 'Delay_milliseconds': DEFSET, 'Maximum_Speed_ratio': DEFSET, }, 'dimension': { 'Activate_Dimension': "True", 'Absolute_Extrusion_Distance': "True", 'Relative_Extrusion_Distance': "False", 'Extruder_Retraction_Speed_mm/s': storedSettingFloat('retraction_speed'), 'Filament_Diameter_mm': storedSettingFloat("filament_diameter"), 'Filament_Packing_Density_ratio': storedSettingFloat("filament_density"), 'Maximum_E_Value_before_Reset_float': DEFSET, 'Minimum_Travel_for_Retraction_millimeters': storedSettingFloat("retraction_min_travel"), 'Retract_Within_Island': storedSettingInvertBoolean("retract_on_jumps_only"), 'Retraction_Distance_millimeters': lambda setting: profile.getProfileSettingFloat('retraction_amount') if profile.getProfileSetting('retraction_enable') == 'True' else 0, 'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'), }, 'alteration': { 'Activate_Alteration': "False", 'Name_of_End_File': "end.gcode", 'Name_of_Start_File': "start.gcode", 'Remove_Redundant_Mcode': "True", 'Replace_Variable_with_Setting': DEFSET, }, 'export': { 'Activate_Export': "True", 'Add_Descriptive_Extension': DEFSET, 'Add_Export_Suffix': "False", 'Add_Profile_Extension': DEFSET, 'Add_Timestamp_Extension': DEFSET, 'Also_Send_Output_To': DEFSET, 'Analyze_Gcode': DEFSET, 'Comment_Choice': DEFSET, 'Do_Not_Change_Output': DEFSET, 'binary_16_byte': DEFSET, 'gcode_step': DEFSET, 'gcode_time_segment': DEFSET, 'gcode_small': DEFSET, 'File_Extension': storedSetting('gcode_extension'), 'Name_of_Replace_File': DEFSET, 'Save_Penultimate_Gcode': "False", } }
def getSliceCommand(filename): if profile.getPreference('slicer').startswith('Slic3r') and getSlic3rExe() != False: slic3rExe = getSlic3rExe() if slic3rExe == False: return False cmd = [slic3rExe, '--output-filename-format', '[input_filename_base].gcode', '--nozzle-diameter', str(profile.calculateEdgeWidth()), '--print-center', '%s,%s' % (profile.getPreferenceFloat('machine_width') / 2, profile.getPreferenceFloat('machine_depth') / 2), '--z-offset', '0', '--gcode-flavor', 'reprap', '--gcode-comments', '--filament-diameter', profile.getProfileSetting('filament_diameter'), '--extrusion-multiplier', str(1.0 / float(profile.getProfileSetting('filament_density'))), '--temperature', profile.getProfileSetting('print_temperature'), '--travel-speed', profile.getProfileSetting('travel_speed'), '--perimeter-speed', profile.getProfileSetting('print_speed'), '--small-perimeter-speed', profile.getProfileSetting('print_speed'), '--infill-speed', profile.getProfileSetting('print_speed'), '--solid-infill-speed', profile.getProfileSetting('print_speed'), '--bridge-speed', profile.getProfileSetting('print_speed'), '--bottom-layer-speed-ratio', str(float(profile.getProfileSetting('bottom_layer_speed')) / float(profile.getProfileSetting('print_speed'))), '--layer-height', profile.getProfileSetting('layer_height'), '--first-layer-height-ratio', '1.0', '--infill-every-layers', '1', '--perimeters', str(profile.calculateLineCount()), '--solid-layers', str(profile.calculateSolidLayerCount()), '--fill-density', str(float(profile.getProfileSetting('fill_density'))/100), '--fill-angle', '45', '--fill-pattern', 'rectilinear', #rectilinear line concentric hilbertcurve archimedeanchords octagramspiral '--solid-fill-pattern', 'rectilinear', '--start-gcode', profile.getAlterationFilePath('start.gcode'), '--end-gcode', profile.getAlterationFilePath('end.gcode'), '--retract-length', profile.getProfileSetting('retraction_amount'), '--retract-speed', str(int(float(profile.getProfileSetting('retraction_speed')))), '--retract-restart-extra', profile.getProfileSetting('retraction_extra'), '--retract-before-travel', profile.getProfileSetting('retraction_min_travel'), '--retract-lift', '0', '--slowdown-below-layer-time', profile.getProfileSetting('cool_min_layer_time'), '--min-print-speed', profile.getProfileSetting('cool_min_feedrate'), '--skirts', profile.getProfileSetting('skirt_line_count'), '--skirt-distance', str(int(float(profile.getProfileSetting('skirt_gap')))), '--skirt-height', '1', '--scale', profile.getProfileSetting('model_scale'), '--rotate', profile.getProfileSetting('model_rotate_base'), '--duplicate-x', profile.getProfileSetting('model_multiply_x'), '--duplicate-y', profile.getProfileSetting('model_multiply_y'), '--duplicate-distance', '10'] if profile.getProfileSetting('support') != 'None': cmd.extend(['--support-material']) cmd.extend([filename]) return cmd else: pypyExe = getPyPyExe() if pypyExe == False: pypyExe = sys.executable #In case we have a frozen exe, then argv[0] points to the executable, but we want to give pypy a real script file. if hasattr(sys, 'frozen'): mainScriptFile = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../..", "cura_sf.zip")) else: mainScriptFile = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", os.path.split(sys.argv[0])[1])) cmd = [pypyExe, mainScriptFile, '-p', profile.getGlobalProfileString(), '-s'] if platform.system() == "Windows": try: cmd.append(str(filename)) except UnicodeEncodeError: cmd.append("#UTF8#" + filename.encode("utf-8")) else: cmd.append(filename) return cmd
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.getPreferenceFloat('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.getPreferenceFloat('machine_width') - 5.0, profile.getPreferenceFloat('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.getPreferenceFloat('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.getPreferenceFloat('machine_width') d = profile.getPreferenceFloat('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 OnResume(self, e): if self._wizardState == 2: self._wizardState = 3 wx.CallAfter(self.infoBox.SetBusy, 'Printing initial calibration cross') w = profile.getPreferenceFloat('machine_width') d = profile.getPreferenceFloat('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.getPreferenceFloat('extruder_offset_x1') y = profile.getPreferenceFloat('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.getPreferenceFloat('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.getPreferenceFloat('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.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'))) self.infoBox.SetReadyIndicator() self._wizardState = 8 self.comm.close() self.resumeButton.Enable(False)
def __init__(self, parent): super(machineSettingsDialog, self).__init__(None, title="Machine settings") wx.EVT_CLOSE(self, self.OnClose) self.parent = parent extruderCount = int(profile.getMachineSetting('extruder_amount')) self.panel = configBase.configPanelBase(self) self.SetSizer(wx.BoxSizer(wx.HORIZONTAL)) self.GetSizer().Add(self.panel, 1, wx.EXPAND) self.nb = wx.Notebook(self.panel) self.panel.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.panel.GetSizer().Add(self.nb, 1, wx.EXPAND) for idx in xrange(0, profile.getMachineCount()): left, right, main = self.panel.CreateConfigPanel(self.nb) configBase.TitleRow(left, _("Machine settings")) configBase.SettingRow(left, 'steps_per_e', index=idx) configBase.SettingRow(left, 'machine_width', index=idx) configBase.SettingRow(left, 'machine_depth', index=idx) configBase.SettingRow(left, 'machine_height', index=idx) configBase.SettingRow(left, 'extruder_amount', index=idx) configBase.SettingRow(left, 'has_heated_bed', index=idx) configBase.SettingRow(left, 'machine_center_is_zero', index=idx) configBase.SettingRow(left, 'gcode_flavor', index=idx) configBase.TitleRow(right, _("Printer head size")) configBase.SettingRow(right, 'extruder_head_size_min_x', index=idx) configBase.SettingRow(right, 'extruder_head_size_min_y', index=idx) configBase.SettingRow(right, 'extruder_head_size_max_x', index=idx) configBase.SettingRow(right, 'extruder_head_size_max_y', index=idx) configBase.SettingRow(right, 'extruder_head_size_height', index=idx) for i in xrange(1, extruderCount): configBase.TitleRow(left, _("Extruder %d") % (i+1)) configBase.SettingRow(left, 'extruder_offset_x%d' % (i), index=idx) configBase.SettingRow(left, 'extruder_offset_y%d' % (i), index=idx) configBase.TitleRow(right, _("Communication settings")) configBase.SettingRow(right, 'serial_port', ['AUTO'] + machineCom.serialList(), index=idx) configBase.SettingRow(right, 'serial_baud', ['AUTO'] + map(str, machineCom.baudrateList()), index=idx) self.nb.AddPage(main, profile.getMachineSetting('machine_name', idx).title()) self.nb.SetSelection(int(profile.getPreferenceFloat('active_machine'))) self.buttonPanel = wx.Panel(self.panel) self.panel.GetSizer().Add(self.buttonPanel) self.buttonPanel.SetSizer(wx.BoxSizer(wx.HORIZONTAL)) self.okButton = wx.Button(self.buttonPanel, -1, 'Ok') self.okButton.Bind(wx.EVT_BUTTON, lambda e: self.Close()) self.buttonPanel.GetSizer().Add(self.okButton, flag=wx.ALL, border=5) self.addButton = wx.Button(self.buttonPanel, -1, 'Add new machine') self.addButton.Bind(wx.EVT_BUTTON, self.OnAddMachine) self.buttonPanel.GetSizer().Add(self.addButton, flag=wx.ALL, border=5) self.remButton = wx.Button(self.buttonPanel, -1, 'Remove machine') self.remButton.Bind(wx.EVT_BUTTON, self.OnRemoveMachine) self.buttonPanel.GetSizer().Add(self.remButton, flag=wx.ALL, border=5) main.Fit() self.Fit()
def __init__( self, parent ): wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 353,600 ), style = wx.DEFAULT_DIALOG_STYLE ) self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize ) bSizer1 = wx.BoxSizer( wx.VERTICAL ) self.m_staticText1 = wx.StaticText( self, wx.ID_ANY, u"Services Request Complaint", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText1.Wrap( -1 ) self.m_staticText1.SetFont( wx.Font( 18, 74, 90, 90, False, "Arial" ) ) bSizer1.Add( self.m_staticText1, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) self.m_staticline1 = wx.StaticLine( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ) bSizer1.Add( self.m_staticline1, 0, wx.EXPAND |wx.ALL, 5 ) self.m_staticText6 = wx.StaticText( self, wx.ID_ANY, u"Name/Company", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText6.Wrap( -1 ) bSizer1.Add( self.m_staticText6, 0, wx.ALL, 5 ) self.name = wx.TextCtrl( self, wx.ID_ANY,str(profile.getMachineSetting('name',int(profile.getPreferenceFloat('active_machine')) )), wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.name, 0, wx.ALL|wx.EXPAND, 5 ) self.m_staticText9 = wx.StaticText( self, wx.ID_ANY, u"Email id", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText9.Wrap( -1 ) bSizer1.Add( self.m_staticText9, 0, wx.ALL, 5 ) self.email = wx.TextCtrl( self, wx.ID_ANY, str(profile.getMachineSetting('email',int(profile.getPreferenceFloat('active_machine')) )), wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.email, 0, wx.ALL|wx.EXPAND, 5 ) self.m_staticText7 = wx.StaticText( self, wx.ID_ANY, u"Phone no", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText7.Wrap( -1 ) bSizer1.Add( self.m_staticText7, 0, wx.ALL, 5 ) self.phone = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.phone, 0, wx.ALL|wx.EXPAND, 5 ) self.m_staticText8 = wx.StaticText( self, wx.ID_ANY, u"Address", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText8.Wrap( -1 ) bSizer1.Add( self.m_staticText8, 0, wx.ALL, 5 ) self.address = wx.TextCtrl( self, wx.ID_ANY, str(profile.getMachineSetting('address',int(profile.getPreferenceFloat('active_machine')) )), wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.address, 0, wx.ALL|wx.EXPAND, 5 ) self.m_staticText11 = wx.StaticText( self, wx.ID_ANY, u"Serial #", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText11.Wrap( -1 ) bSizer1.Add( self.m_staticText11, 0, wx.ALL, 5 ) self.serial_no = wx.TextCtrl( self, wx.ID_ANY, str(profile.getMachineSetting('sn_number',int(profile.getPreferenceFloat('active_machine')) )), wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.serial_no, 0, wx.ALL|wx.EXPAND, 5 ) self.m_staticText10 = wx.StaticText( self, wx.ID_ANY, u"Problem type", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText10.Wrap( -1 ) bSizer1.Add( self.m_staticText10, 0, wx.ALL, 5 ) problem_choiceChoices = [ u"Nozzel Jam", u"Bed Level", u"Printer not moving", u"Bad quality prints", u"Print not sticking to bed", u"Bed/Nozzel not heating", u"Other..." ] self.problem_choice = wx.Choice( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, problem_choiceChoices, 0 ) self.problem_choice.SetSelection( 6 ) bSizer1.Add( self.problem_choice, 0, wx.ALL|wx.EXPAND, 5 ) self.m_staticText12 = wx.StaticText( self, wx.ID_ANY, u"Detailed description ", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText12.Wrap( -1 ) bSizer1.Add( self.m_staticText12, 0, wx.ALL, 5 ) self.detail_desc = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.detail_desc, 1, wx.ALL|wx.EXPAND, 5 ) self.submit_complaint = wx.Button( self, wx.ID_ANY, u"Submit request", wx.DefaultPosition, wx.DefaultSize, 0 ) bSizer1.Add( self.submit_complaint, 1, wx.ALL|wx.EXPAND, 5 ) self.submit_complaint.Bind( wx.EVT_BUTTON, self.OnComplaint ) self.SetSizer( bSizer1 ) self.Layout() self.Centre( wx.BOTH )
def _load(self, gcodeFile): filePos = 0 pos = util3d.Vector3() posOffset = util3d.Vector3() 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 layerThickness = 0.1 pathType = 'CUSTOM'; startCodeDone = False currentLayer = [] currentPath = gcodePath('move', pathType, layerThickness, pos.copy()) currentPath.list[0].e = totalExtrusion currentPath.list[0].extrudeAmountMultiply = extrudeAmountMultiply 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 pathType != "CUSTOM": startCodeDone = True 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:'): self.layerList.append(currentLayer) if self.progressCallback is not None: if filePos != gcodeFile.tell(): filePos = gcodeFile.tell() if self.progressCallback(float(filePos) / float(self._fileSize)): #Abort the loading, we can safely return as the results here will be discarded gcodeFile.close() return currentLayer = [] if pathType != "CUSTOM": startCodeDone = True line = line[0:line.find(';')] T = self.getCodeInt(line, 'T') if T is not None: if currentExtruder > 0: posOffset.x -= profile.getPreferenceFloat('extruder_offset_x%d' % (currentExtruder)) posOffset.y -= profile.getPreferenceFloat('extruder_offset_y%d' % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset.x += profile.getPreferenceFloat('extruder_offset_x%d' % (currentExtruder)) posOffset.y += profile.getPreferenceFloat('extruder_offset_y%d' % (currentExtruder)) G = self.getCodeInt(line, 'G') if G is not None: if G == 0 or G == 1: #Move x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') e = self.getCodeFloat(line, 'E') f = self.getCodeFloat(line, 'F') oldPos = pos.copy() if x is not None: if posAbs: pos.x = x * scale + posOffset.x else: pos.x += x * scale if y is not None: if posAbs: pos.y = y * scale + posOffset.y else: pos.y += y * scale if z is not None: if posAbs: pos.z = z * scale + posOffset.z else: pos.z += z * scale if f is not None: feedRate = f if x is not None or y is not None or z is not None: totalMoveTimeMinute += (oldPos - pos).vsize() / feedRate moveType = 'move' if e is not None: if not absoluteE: e += currentE if posAbs: if e > currentE: moveType = 'extrude' if e < currentE: moveType = 'retract' else: if e > 0: moveType = 'extrude' if e < 0: moveType = 'retract' totalExtrusion += e - currentE currentE = e if totalExtrusion > maxExtrusion: maxExtrusion = totalExtrusion if moveType == 'move' and oldPos.z != pos.z: if oldPos.z > pos.z and abs(oldPos.z - pos.z) > 5.0 and pos.z < 1.0: oldPos.z = 0.0 layerThickness = abs(oldPos.z - pos.z) if currentPath.type != moveType or currentPath.pathType != pathType: currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.list[-1]) currentLayer.append(currentPath) newPos = pos.copy() newPos.e = totalExtrusion newPos.extrudeAmountMultiply = extrudeAmountMultiply currentPath.list.append(newPos) elif G == 4: #Delay S = self.getCodeFloat(line, 'S') if S is not None: totalMoveTimeMinute += S / 60 P = self.getCodeFloat(line, 'P') if P is not None: totalMoveTimeMinute += P / 60 / 1000 elif G == 20: #Units are inches scale = 25.4 elif G == 21: #Units are mm scale = 1.0 elif G == 28: #Home x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') if x is None and y is None and z is None: pos = util3d.Vector3() else: if x is not None: pos.x = 0.0 if y is not None: pos.y = 0.0 if z is not None: pos.z = 0.0 elif G == 90: #Absolute position posAbs = True elif G == 91: #Relative position posAbs = False elif G == 92: x = self.getCodeFloat(line, 'X') y = self.getCodeFloat(line, 'Y') z = self.getCodeFloat(line, 'Z') e = self.getCodeFloat(line, 'E') if e is not None: currentE = e if x is not None: posOffset.x = pos.x - x if y is not None: posOffset.y = pos.y - y if z is not None: posOffset.z = pos.z - z else: print "Unknown G code:" + str(G) else: M = self.getCodeInt(line, 'M') if M is not None: if 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 == 140: #Set bed temperature pass elif M == 190: #Set bed temperature & wait pass elif M == 221: #Extrude amount multiplier s = self.getCodeFloat(line, 'S') if s != None: extrudeAmountMultiply = s / 100.0 else: print "Unknown M code:" + str(M) self.layerList.append(currentLayer) self.extrusionAmount = maxExtrusion self.totalMoveTimeMinute = totalMoveTimeMinute
def OnSlice(self, e): dlg=wx.FileDialog(self, "Save project gcode file", os.path.split(profile.getPreference('lastFile'))[0], style=wx.FD_SAVE) dlg.SetWildcard("GCode file (*.gcode)|*.gcode") if dlg.ShowModal() != wx.ID_OK: dlg.Destroy() return resultFilename = dlg.GetPath() dlg.Destroy() put = profile.setTempOverride oldProfile = profile.getGlobalProfileString() put('add_start_end_gcode', 'False') put('gcode_extension', 'project_tmp') if self.printMode == 0: clearZ = 0 actionList = [] for item in self.list: if item.profile != None and os.path.isfile(item.profile): profile.loadGlobalProfile(item.profile) put('object_center_x', item.centerX - self.extruderOffset[item.extruder][0]) put('object_center_y', item.centerY - self.extruderOffset[item.extruder][1]) put('model_scale', item.scale) put('flip_x', item.flipX) put('flip_y', item.flipY) put('flip_z', item.flipZ) put('model_rotate_base', item.rotate) put('swap_xz', item.swapXZ) put('swap_yz', item.swapYZ) action = Action() action.sliceCmd = sliceRun.getSliceCommand(item.filename) print action.sliceCmd action.centerX = item.centerX action.centerY = item.centerY action.temperature = profile.getProfileSettingFloat('print_temperature') action.extruder = item.extruder action.filename = item.filename clearZ = max(clearZ, item.getSize()[2] * item.scale + 5.0) action.clearZ = clearZ action.leaveResultForNextSlice = False action.usePreviousSlice = False actionList.append(action) if self.list.index(item) > 0 and item.isSameExceptForPosition(self.list[self.list.index(item)-1]): actionList[-2].leaveResultForNextSlice = True actionList[-1].usePreviousSlice = True if item.profile != None: profile.loadGlobalProfileFromString(oldProfile) else: self._saveCombinedSTL(resultFilename + "_temp_.stl") put('model_scale', 1.0) put('flip_x', False) put('flip_y', False) put('flip_z', False) put('model_rotate_base', 0) put('swap_xz', False) put('swap_yz', False) actionList = [] action = Action() action.sliceCmd = sliceRun.getSliceCommand(resultFilename + "_temp_.stl") action.centerX = profile.getPreferenceFloat('machine_width') / 2 action.centerY = profile.getPreferenceFloat('machine_depth') / 2 action.temperature = profile.getProfileSettingFloat('print_temperature') action.extruder = 0 action.filename = resultFilename + "_temp_.stl" action.clearZ = 0 action.leaveResultForNextSlice = False action.usePreviousSlice = False actionList.append(action) #Restore the old profile. profile.resetTempOverride() pspw = ProjectSliceProgressWindow(actionList, resultFilename) pspw.extruderOffset = self.extruderOffset pspw.Centre() pspw.Show(True)
def __init__(self): super(projectPlanner, self).__init__(None, title='Cura - Project Planner') wx.EVT_CLOSE(self, self.OnClose) self.panel = wx.Panel(self, -1) self.SetSizer(wx.BoxSizer(wx.VERTICAL)) self.GetSizer().Add(self.panel, 1, flag=wx.EXPAND) self.SetDropTarget(dropTarget.FileDropTarget(self.OnDropFiles, meshLoader.supportedExtensions())) self.list = [] self.selection = None self.printMode = 0 self.alwaysAutoPlace = True self.machineSize = numpy.array([profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')]) self.headSizeMin = numpy.array([profile.getPreferenceFloat('extruder_head_size_min_x'), profile.getPreferenceFloat('extruder_head_size_min_y'),0]) self.headSizeMax = numpy.array([profile.getPreferenceFloat('extruder_head_size_max_x'), profile.getPreferenceFloat('extruder_head_size_max_y'),0]) self.extruderOffset = [ numpy.array([0,0,0]), numpy.array([profile.getPreferenceFloat('extruder_offset_x1'), profile.getPreferenceFloat('extruder_offset_y1'), 0]), numpy.array([profile.getPreferenceFloat('extruder_offset_x2'), profile.getPreferenceFloat('extruder_offset_y2'), 0]), numpy.array([profile.getPreferenceFloat('extruder_offset_x3'), profile.getPreferenceFloat('extruder_offset_y3'), 0])] self.toolbar = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar, self.OnLoadProject, 'open.png', 'Open project') toolbarUtil.NormalButton(self.toolbar, self.OnSaveProject, 'save.png', 'Save project') self.toolbar.AddSeparator() group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick).SetValue(self.alwaysAutoPlace) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick).SetValue(not self.alwaysAutoPlace) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnPreferences, 'preferences.png', 'Project planner preferences') self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnCutMesh, 'cut-mesh.png', 'Cut a plate STL into multiple STL files, and add those files to the project.\nNote: Splitting up plates sometimes takes a few minutes.') toolbarUtil.NormalButton(self.toolbar, self.OnSaveCombinedSTL, 'save-combination.png', 'Save all the combined STL files into a single STL file as a plate.') self.toolbar.AddSeparator() group = [] self.printOneAtATime = toolbarUtil.RadioButton(self.toolbar, group, 'view-normal-on.png', 'view-normal-off.png', 'Print one object at a time', callback=self.OnPrintTypeChange) self.printAllAtOnce = toolbarUtil.RadioButton(self.toolbar, group, 'all-at-once-on.png', 'all-at-once-off.png', 'Print all the objects at once', callback=self.OnPrintTypeChange) self.toolbar.AddSeparator() toolbarUtil.NormalButton(self.toolbar, self.OnQuit, 'exit.png', 'Close project planner') self.toolbar.Realize() self.toolbar2 = toolbarUtil.Toolbar(self.panel) toolbarUtil.NormalButton(self.toolbar2, self.OnAddModel, 'object-add.png', 'Add model') toolbarUtil.NormalButton(self.toolbar2, self.OnRemModel, 'object-remove.png', 'Remove model') self.toolbar2.AddSeparator() toolbarUtil.NormalButton(self.toolbar2, self.OnMoveUp, 'move-up.png', 'Move model up in print list') toolbarUtil.NormalButton(self.toolbar2, self.OnMoveDown, 'move-down.png', 'Move model down in print list') toolbarUtil.NormalButton(self.toolbar2, self.OnCopy, 'copy.png', 'Make a copy of the current selected object') toolbarUtil.NormalButton(self.toolbar2, self.OnSetCustomProfile, 'set-profile.png', 'Set a custom profile to be used to prepare a specific object.') self.toolbar2.AddSeparator() if not self.alwaysAutoPlace: toolbarUtil.NormalButton(self.toolbar2, self.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.') toolbarUtil.NormalButton(self.toolbar2, self.OnSlice, 'slice.png', 'Prepare to project into a gcode file.') self.toolbar2.Realize() self.toolbar3 = toolbarUtil.Toolbar(self.panel) self.mirrorX = toolbarUtil.ToggleButton(self.toolbar3, 'flip_x', 'object-mirror-x-on.png', 'object-mirror-x-off.png', 'Mirror X', callback=self.OnMirrorChange) self.mirrorY = toolbarUtil.ToggleButton(self.toolbar3, 'flip_y', 'object-mirror-y-on.png', 'object-mirror-y-off.png', 'Mirror Y', callback=self.OnMirrorChange) self.mirrorZ = toolbarUtil.ToggleButton(self.toolbar3, 'flip_z', 'object-mirror-z-on.png', 'object-mirror-z-off.png', 'Mirror Z', callback=self.OnMirrorChange) self.toolbar3.AddSeparator() # Swap self.swapXZ = toolbarUtil.ToggleButton(self.toolbar3, 'swap_xz', 'object-swap-xz-on.png', 'object-swap-xz-off.png', 'Swap XZ', callback=self.OnMirrorChange) self.swapYZ = toolbarUtil.ToggleButton(self.toolbar3, 'swap_yz', 'object-swap-yz-on.png', 'object-swap-yz-off.png', 'Swap YZ', callback=self.OnMirrorChange) self.toolbar3.Realize() sizer = wx.GridBagSizer(2,2) self.panel.SetSizer(sizer) self.preview = PreviewGLCanvas(self.panel, self) self.listbox = wx.ListBox(self.panel, -1, choices=[]) self.addButton = wx.Button(self.panel, -1, "Add") self.remButton = wx.Button(self.panel, -1, "Remove") self.sliceButton = wx.Button(self.panel, -1, "Prepare") if not self.alwaysAutoPlace: self.autoPlaceButton = wx.Button(self.panel, -1, "Auto Place") sizer.Add(self.toolbar, (0,0), span=(1,1), flag=wx.EXPAND|wx.LEFT|wx.RIGHT) sizer.Add(self.toolbar2, (0,1), span=(1,2), flag=wx.EXPAND|wx.LEFT|wx.RIGHT) sizer.Add(self.preview, (1,0), span=(5,1), flag=wx.EXPAND) sizer.Add(self.listbox, (1,1), span=(1,2), flag=wx.EXPAND) sizer.Add(self.toolbar3, (2,1), span=(1,2), flag=wx.EXPAND|wx.LEFT|wx.RIGHT) sizer.Add(self.addButton, (3,1), span=(1,1)) sizer.Add(self.remButton, (3,2), span=(1,1)) sizer.Add(self.sliceButton, (4,1), span=(1,1)) if not self.alwaysAutoPlace: sizer.Add(self.autoPlaceButton, (4,2), span=(1,1)) sizer.AddGrowableCol(0) sizer.AddGrowableRow(1) self.addButton.Bind(wx.EVT_BUTTON, self.OnAddModel) self.remButton.Bind(wx.EVT_BUTTON, self.OnRemModel) self.sliceButton.Bind(wx.EVT_BUTTON, self.OnSlice) if not self.alwaysAutoPlace: self.autoPlaceButton.Bind(wx.EVT_BUTTON, self.OnAutoPlace) self.listbox.Bind(wx.EVT_LISTBOX, self.OnListSelect) panel = wx.Panel(self.panel, -1) sizer.Add(panel, (5,1), span=(1,2)) sizer = wx.GridBagSizer(2,2) panel.SetSizer(sizer) self.scaleCtrl = wx.TextCtrl(panel, -1, '') self.rotateCtrl = wx.SpinCtrl(panel, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS) self.rotateCtrl.SetRange(0, 360) sizer.Add(wx.StaticText(panel, -1, 'Scale'), (0,0), flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.scaleCtrl, (0,1), flag=wx.ALIGN_BOTTOM|wx.EXPAND) sizer.Add(wx.StaticText(panel, -1, 'Rotate'), (1,0), flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.rotateCtrl, (1,1), flag=wx.ALIGN_BOTTOM|wx.EXPAND) if int(profile.getPreference('extruder_amount')) > 1: self.extruderCtrl = wx.ComboBox(panel, -1, '1', choices=map(str, range(1, int(profile.getPreference('extruder_amount'))+1)), style=wx.CB_DROPDOWN|wx.CB_READONLY) sizer.Add(wx.StaticText(panel, -1, 'Extruder'), (2,0), flag=wx.ALIGN_CENTER_VERTICAL) sizer.Add(self.extruderCtrl, (2,1), flag=wx.ALIGN_BOTTOM|wx.EXPAND) self.extruderCtrl.Bind(wx.EVT_COMBOBOX, self.OnExtruderChange) self.scaleCtrl.Bind(wx.EVT_TEXT, self.OnScaleChange) self.rotateCtrl.Bind(wx.EVT_SPINCTRL, self.OnRotateChange) self.SetSize((800,600))
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 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.getPreferenceFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset[1] -= profile.getPreferenceFloat( 'extruder_offset_y%d' % (currentExtruder)) currentExtruder = T if currentExtruder > 0: posOffset[0] += profile.getPreferenceFloat( 'extruder_offset_x%d' % (currentExtruder)) posOffset[1] += profile.getPreferenceFloat( '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[:] 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 == 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') if profile.getPreference( 'machine_center_is_zero') == 'True': center = [ profile.getProfileSettingFloat('machine_width') / 2, profile.getProfileSettingFloat('machine_depth') / 2, 0.0 ] else: center = [0.0, 0.0, 0.0] if x is None and y is None and z is None: pos = center else: if x is not None: pos[0] = center[0] if y is not None: pos[0] = center[1] if z is not None: pos[0] = 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 main(): parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]") parser.add_option("-p", "--profile", action="store", type="string", dest="profile", help="Encoded profile to use for the print") parser.add_option("-o", "--output", action="store", type="string", dest="output", help="Output filename") (options, args) = parser.parse_args() if options.output is None: print 'Missing output filename' sys.exit(1) if options.profile is not None: profile.loadGlobalProfileFromString(options.profile) options.output = fixUTF8(options.output) clearZ = 0 resultFile = open(options.output, "w") for idx in xrange(0, len(args), 2): position = map(float, args[idx].split(',')) if len(position) < 9 + 2: position = position[0:2] position += [1,0,0] position += [0,1,0] position += [0,0,1] filenames = fixUTF8(args[idx + 1]).split('|') profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) if idx == 0: resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('start.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) else: resultFile.write(';TYPE:CUSTOM\n') n = output[-1].rfind('Z')+1 zString = output[-1][n:n+20] zString = zString[0:zString.find(' ')] clearZ = max(clearZ, float(zString) + 10) profile.setTempOverride('clear_z', clearZ) resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace'))) output = [] for filename in filenames: extruderNr = filenames.index(filename) profile.resetTempOverride() if extruderNr > 0: profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr))) profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))) profile.setTempOverride('fan_enabled', 'False') profile.setTempOverride('skirt_line_count', '0') profile.setTempOverride('alternative_center', filenames[0]) else: profile.setTempOverride('object_center_x', position[0]) profile.setTempOverride('object_center_y', position[1]) profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11]))) output.append(export.getOutput(filename)) profile.resetTempOverride() if len(output) == 1: resultFile.write(output[0]) else: stitchMultiExtruder(output, resultFile) resultFile.write(';TYPE:CUSTOM\n') resultFile.write(profile.getAlterationFileContents('end.gcode')) resultFile.close() print "Running plugins" ret = profile.runPostProcessingPlugins(options.output) if ret is not None: print ret print "Finalizing %s" % (os.path.basename(options.output))
def __init__(self, parent): super(previewPanel, self).__init__(parent, -1) self.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DDKSHADOW)) self.SetMinSize((440, 320)) self.objectList = [] self.errorList = [] self.gcode = None self.objectsMinV = None self.objectsMaxV = None self.objectsBoundaryCircleSize = None self.loadThread = None self.machineSize = util3d.Vector3( profile.getPreferenceFloat('machine_width'), profile.getPreferenceFloat('machine_depth'), profile.getPreferenceFloat('machine_height')) self.machineCenter = util3d.Vector3(self.machineSize.x / 2, self.machineSize.y / 2, 0) self.glCanvas = PreviewGLCanvas(self) #Create the popup window self.warningPopup = wx.PopupWindow(self, flags=wx.BORDER_SIMPLE) self.warningPopup.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_INFOBK)) self.warningPopup.text = wx.StaticText( self.warningPopup, -1, 'Reset scale, rotation and mirror?') self.warningPopup.yesButton = wx.Button(self.warningPopup, -1, 'yes', style=wx.BU_EXACTFIT) self.warningPopup.noButton = wx.Button(self.warningPopup, -1, 'no', style=wx.BU_EXACTFIT) self.warningPopup.sizer = wx.BoxSizer(wx.HORIZONTAL) self.warningPopup.SetSizer(self.warningPopup.sizer) self.warningPopup.sizer.Add(self.warningPopup.text, 1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=1) self.warningPopup.sizer.Add(self.warningPopup.yesButton, 0, flag=wx.EXPAND | wx.ALL, border=1) self.warningPopup.sizer.Add(self.warningPopup.noButton, 0, flag=wx.EXPAND | wx.ALL, border=1) self.warningPopup.Fit() self.warningPopup.Layout() self.warningPopup.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnHideWarning, self.warningPopup.timer) self.Bind(wx.EVT_BUTTON, self.OnWarningPopup, self.warningPopup.yesButton) self.Bind(wx.EVT_BUTTON, self.OnHideWarning, self.warningPopup.noButton) parent.Bind(wx.EVT_MOVE, self.OnMove) parent.Bind(wx.EVT_SIZE, self.OnMove) self.toolbar = toolbarUtil.Toolbar(self) group = [] toolbarUtil.RadioButton(self.toolbar, group, 'object-3d-on.png', 'object-3d-off.png', '3D view', callback=self.On3DClick) toolbarUtil.RadioButton(self.toolbar, group, 'object-top-on.png', 'object-top-off.png', 'Topdown view', callback=self.OnTopClick) self.toolbar.AddSeparator() self.showBorderButton = toolbarUtil.ToggleButton( self.toolbar, '', 'view-border-on.png', 'view-border-off.png', 'Show model borders', callback=self.OnViewChange) self.showSteepOverhang = toolbarUtil.ToggleButton( self.toolbar, '', 'steepOverhang-on.png', 'steepOverhang-off.png', 'Show steep overhang', callback=self.OnViewChange) self.toolbar.AddSeparator() group = [] self.normalViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-normal-on.png', 'view-normal-off.png', 'Normal model view', callback=self.OnViewChange) self.transparentViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-transparent-on.png', 'view-transparent-off.png', 'Transparent model view', callback=self.OnViewChange) self.xrayViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-xray-on.png', 'view-xray-off.png', 'X-Ray view', callback=self.OnViewChange) self.gcodeViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-gcode-on.png', 'view-gcode-off.png', 'GCode view', callback=self.OnViewChange) self.mixedViewButton = toolbarUtil.RadioButton( self.toolbar, group, 'view-mixed-on.png', 'view-mixed-off.png', 'Mixed model/GCode view', callback=self.OnViewChange) self.toolbar.AddSeparator() self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21 * 4, 21), style=wx.SP_ARROW_KEYS) self.toolbar.AddControl(self.layerSpin) self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.toolbar, 0, flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border=1) sizer.Add(self.glCanvas, 1, flag=wx.EXPAND) self.SetSizer(sizer) self.checkReloadFileTimer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnCheckReloadFile, self.checkReloadFileTimer) self.checkReloadFileTimer.Start(1000) group = [] self.rotateToolButton = openglGui.glRadioButton( self.glCanvas, 1, 'Rotate', (0, 1), group, self.OnToolSelect) self.scaleToolButton = openglGui.glRadioButton(self.glCanvas, 2, 'Scale', (0, 2), group, self.OnToolSelect) self.mirrorToolButton = openglGui.glRadioButton( self.glCanvas, 12, 'Mirror', (0, 3), group, self.OnToolSelect) self.resetRotationButton = openglGui.glButton(self.glCanvas, 4, 'Reset rotation', (1, 1), self.OnRotateReset) self.layFlatButton = openglGui.glButton(self.glCanvas, 5, 'Lay flat', (1, 2), self.OnLayFlat) self.resetScaleButton = openglGui.glButton(self.glCanvas, 8, 'Scale reset', (1, 1), self.OnScaleReset) self.scaleMaxButton = openglGui.glButton(self.glCanvas, 9, 'Scale to machine size', (1, 2), self.OnScaleMax) self.mirrorXButton = openglGui.glButton(self.glCanvas, 12, 'Mirror X', (1, 1), lambda: self.OnMirror(0)) self.mirrorYButton = openglGui.glButton(self.glCanvas, 13, 'Mirror Y', (1, 2), lambda: self.OnMirror(1)) self.mirrorZButton = openglGui.glButton(self.glCanvas, 14, 'Mirror Z', (1, 3), lambda: self.OnMirror(2)) self.openFileButton = openglGui.glButton( self.glCanvas, 3, 'Load model', (0, 0), lambda: self.GetParent(). GetParent().GetParent()._showModelLoadDialog(1)) self.sliceButton = openglGui.glButton( self.glCanvas, 6, 'Prepare model', (0, -2), lambda: self.GetParent().GetParent().GetParent().OnSlice(None)) self.printButton = openglGui.glButton( self.glCanvas, 7, 'Print model', (0, -1), lambda: self.GetParent().GetParent().GetParent().OnPrint(None)) extruderCount = int(profile.getPreference('extruder_amount')) if extruderCount > 1: openglGui.glButton( self.glCanvas, 3, 'Load dual model', (1, 0), lambda: self.GetParent().GetParent( ).GetParent()._showModelLoadDialog(2)) if extruderCount > 2: openglGui.glButton( self.glCanvas, 3, 'Load triple model', (2, 0), lambda: self. GetParent().GetParent().GetParent()._showModelLoadDialog(3)) if extruderCount > 3: openglGui.glButton( self.glCanvas, 3, 'Load quad model', (3, 0), lambda: self.GetParent().GetParent( ).GetParent()._showModelLoadDialog(4)) self.scaleForm = openglGui.glFrame(self.glCanvas, (1, 3)) openglGui.glGuiLayoutGrid(self.scaleForm) openglGui.glLabel(self.scaleForm, 'Scale X', (0, 0)) self.scaleXctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 0), lambda value: self.OnScaleEntry(value, 0)) openglGui.glLabel(self.scaleForm, 'Scale Y', (0, 1)) self.scaleYctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 1), lambda value: self.OnScaleEntry(value, 1)) openglGui.glLabel(self.scaleForm, 'Scale Z', (0, 2)) self.scaleZctrl = openglGui.glNumberCtrl( self.scaleForm, '1.0', (1, 2), lambda value: self.OnScaleEntry(value, 2)) openglGui.glLabel(self.scaleForm, 'Size X (mm)', (0, 4)) self.scaleXmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 4), lambda value: self.OnScaleEntryMM(value, 0)) openglGui.glLabel(self.scaleForm, 'Size Y (mm)', (0, 5)) self.scaleYmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 5), lambda value: self.OnScaleEntryMM(value, 1)) openglGui.glLabel(self.scaleForm, 'Size Z (mm)', (0, 6)) self.scaleZmmctrl = openglGui.glNumberCtrl( self.scaleForm, '0.0', (1, 6), lambda value: self.OnScaleEntryMM(value, 2)) openglGui.glLabel(self.scaleForm, 'Uniform scale', (0, 8)) self.scaleUniform = openglGui.glCheckbox(self.scaleForm, True, (1, 8), None) self.OnViewChange() self.OnToolSelect() self.returnToModelViewAndUpdateModel() self.matrix = numpy.matrix( numpy.array(profile.getObjectMatrix(), numpy.float64).reshape(( 3, 3, )))