Example #1
0
	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)
Example #2
0
	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()
Example #4
0
	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))
Example #5
0
	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()
Example #6
0
	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)
Example #7
0
	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
Example #8
0
	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
Example #9
0
	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
Example #10
0
 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')
Example #11
0
 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
Example #12
0
	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
Example #13
0
	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)
Example #14
0
    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))
Example #15
0
    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()
Example #16
0
 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')
Example #17
0
    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)
Example #18
0
 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()
Example #19
0
 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')
Example #20
0
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
Example #21
0
	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)
Example #22
0
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
Example #23
0
	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)
Example #24
0
 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)
Example #25
0
	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)
Example #27
0
	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)
Example #28
0
    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)
Example #31
0
    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,
            )))
Example #32
0
    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",
		}
	}
Example #34
0
	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)
Example #35
0
    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
Example #36
0
    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()
Example #38
0
    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)
Example #39
0
	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')
Example #40
0
	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')
Example #41
0
def main():
	parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
	parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
					  help="Encoded profile to use for the print")
	parser.add_option("-o", "--output", action="store", type="string", dest="output",
					  help="Output filename")
	(options, args) = parser.parse_args()
	if options.output is None:
		print 'Missing output filename'
		sys.exit(1)
	if options.profile is not None:
		profile.loadGlobalProfileFromString(options.profile)
	options.output = fixUTF8(options.output)

	clearZ = 0
	resultFile = open(options.output, "w")
	for idx in xrange(0, len(args), 2):
		position = map(float, args[idx].split(','))
		if len(position) < 9 + 2:
			position = position[0:2]
			position += [1,0,0]
			position += [0,1,0]
			position += [0,0,1]
		filenames = fixUTF8(args[idx + 1]).split('|')

		profile.setTempOverride('object_center_x', position[0])
		profile.setTempOverride('object_center_y', position[1])
		if idx == 0:
			resultFile.write(';TYPE:CUSTOM\n')
			resultFile.write(profile.getAlterationFileContents('start.gcode', len(filenames)).replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))
		else:
			resultFile.write(';TYPE:CUSTOM\n')
			n = output[-1].rfind('Z')+1
			zString = output[-1][n:n+20]
			zString = zString[0:zString.find(' ')]
			clearZ = max(clearZ, float(zString) + 10)
			profile.setTempOverride('clear_z', clearZ)
			print position
			print profile.getAlterationFileContents('nextobject.gcode')
			resultFile.write(profile.getAlterationFileContents('nextobject.gcode').replace('?filename?', ' '.join(filenames).encode('ascii', 'replace')))

		output = []
		for filename in filenames:
			extruderNr = filenames.index(filename)
			profile.resetTempOverride()
			if extruderNr > 0:
				profile.setTempOverride('object_center_x', position[0] - profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)))
				profile.setTempOverride('object_center_y', position[1] - profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr)))
				profile.setTempOverride('fan_enabled', 'False')
				profile.setTempOverride('skirt_line_count', '0')
				profile.setTempOverride('alternative_center', filenames[0])
			else:
				profile.setTempOverride('object_center_x', position[0])
				profile.setTempOverride('object_center_y', position[1])
			profile.setTempOverride('object_matrix', ','.join(map(str, position[2:11])))
			if extruderNr > 0:
				if profile.getProfileSettingFloat('filament_diameter%d' % (extruderNr + 1)) > 0:
					profile.setTempOverride('filament_diameter', profile.getProfileSetting('filament_diameter%d' % (extruderNr + 1)))
			print extruderNr, profile.getPreferenceFloat('extruder_offset_x%d' % (extruderNr)), profile.getPreferenceFloat('extruder_offset_y%d' % (extruderNr))
			output.append(export.getOutput(filename))
			profile.resetTempOverride()
		if len(output) == 1:
			resultFile.write(output[0])
		else:
			stitchMultiExtruder(output, resultFile)
	resultFile.write(';TYPE:CUSTOM\n')
	resultFile.write(profile.getAlterationFileContents('end.gcode'))
	resultFile.close()

	print "Running plugins"
	ret = profile.runPostProcessingPlugins(options.output)
	if ret is not None:
		print ret
	print "Finalizing %s" % (os.path.basename(options.output))
	if profile.getPreference('submit_slice_information') == 'True':
		filenames = fixUTF8(args[idx + 1]).split('|')
		for filename in filenames:
			m = hashlib.sha512()
			f = open(filename, "rb")
			while True:
				chunk = f.read(1024)
				if not chunk:
					break
				m.update(chunk)
			f.close()
			data = {
				'processor': platform.processor(),
				'machine': platform.machine(),
				'platform': platform.platform(),
				'profile': profile.getGlobalProfileString(),
				'preferences': profile.getGlobalPreferencesString(),
				'modelhash': m.hexdigest(),
				'version': version.getVersion(),
			}
			try:
				f = urllib2.urlopen("http://platform.ultimaker.com/curastats/", data = urllib.urlencode(data), timeout = 5);
				f.read()
				f.close()
			except:
				pass
	def __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()
Example #43
0
def main():
    parser = OptionParser(
        usage=
        "usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
    parser.add_option("-p",
                      "--profile",
                      action="store",
                      type="string",
                      dest="profile",
                      help="Encoded profile to use for the print")
    parser.add_option("-o",
                      "--output",
                      action="store",
                      type="string",
                      dest="output",
                      help="Output filename")
    (options, args) = parser.parse_args()
    if options.output is None:
        print 'Missing output filename'
        sys.exit(1)
    if options.profile is not None:
        profile.loadGlobalProfileFromString(options.profile)
    options.output = fixUTF8(options.output)

    clearZ = 0
    resultFile = open(options.output, "w")
    for idx in xrange(0, len(args), 2):
        position = map(float, args[idx].split(','))
        if len(position) < 9 + 2:
            position = position[0:2]
            position += [1, 0, 0]
            position += [0, 1, 0]
            position += [0, 0, 1]
        filenames = fixUTF8(args[idx + 1]).split('|')

        profile.setTempOverride('object_center_x', position[0])
        profile.setTempOverride('object_center_y', position[1])
        if idx == 0:
            resultFile.write(';TYPE:CUSTOM\n')
            resultFile.write(
                profile.getAlterationFileContents(
                    'start.gcode', len(filenames)).replace(
                        '?filename?',
                        ' '.join(filenames).encode('ascii', 'replace')))
        else:
            resultFile.write(';TYPE:CUSTOM\n')
            n = output[-1].rfind('Z') + 1
            zString = output[-1][n:n + 20]
            zString = zString[0:zString.find(' ')]
            clearZ = max(clearZ, float(zString) + 10)
            profile.setTempOverride('clear_z', clearZ)
            print position
            print profile.getAlterationFileContents('nextobject.gcode')
            resultFile.write(
                profile.getAlterationFileContents('nextobject.gcode').replace(
                    '?filename?',
                    ' '.join(filenames).encode('ascii', 'replace')))

        output = []
        for filename in filenames:
            extruderNr = filenames.index(filename)
            profile.resetTempOverride()
            if extruderNr > 0:
                profile.setTempOverride(
                    'object_center_x', position[0] -
                    profile.getPreferenceFloat('extruder_offset_x%d' %
                                               (extruderNr)))
                profile.setTempOverride(
                    'object_center_y', position[1] -
                    profile.getPreferenceFloat('extruder_offset_y%d' %
                                               (extruderNr)))
                profile.setTempOverride('fan_enabled', 'False')
                profile.setTempOverride('skirt_line_count', '0')
                profile.setTempOverride('alternative_center', filenames[0])
            else:
                profile.setTempOverride('object_center_x', position[0])
                profile.setTempOverride('object_center_y', position[1])
            profile.setTempOverride('object_matrix',
                                    ','.join(map(str, position[2:11])))
            if extruderNr > 0:
                if profile.getProfileSettingFloat('filament_diameter%d' %
                                                  (extruderNr + 1)) > 0:
                    profile.setTempOverride(
                        'filament_diameter',
                        profile.getProfileSetting('filament_diameter%d' %
                                                  (extruderNr + 1)))
            print extruderNr, profile.getPreferenceFloat(
                'extruder_offset_x%d' %
                (extruderNr)), profile.getPreferenceFloat(
                    'extruder_offset_y%d' % (extruderNr))
            output.append(export.getOutput(filename))
            profile.resetTempOverride()
        if len(output) == 1:
            resultFile.write(output[0])
        else:
            stitchMultiExtruder(output, resultFile)
    resultFile.write(';TYPE:CUSTOM\n')
    resultFile.write(profile.getAlterationFileContents('end.gcode'))
    resultFile.close()

    print "Running plugins"
    ret = profile.runPostProcessingPlugins(options.output)
    if ret is not None:
        print ret
    print "Finalizing %s" % (os.path.basename(options.output))
    if profile.getPreference('submit_slice_information') == 'True':
        filenames = fixUTF8(args[idx + 1]).split('|')
        for filename in filenames:
            m = hashlib.sha512()
            f = open(filename, "rb")
            while True:
                chunk = f.read(1024)
                if not chunk:
                    break
                m.update(chunk)
            f.close()
            data = {
                'processor': platform.processor(),
                'machine': platform.machine(),
                'platform': platform.platform(),
                'profile': profile.getGlobalProfileString(),
                'preferences': profile.getGlobalPreferencesString(),
                'modelhash': m.hexdigest(),
                'version': version.getVersion(),
            }
            try:
                f = urllib2.urlopen("http://platform.ultimaker.com/curastats/",
                                    data=urllib.urlencode(data),
                                    timeout=5)
                f.read()
                f.close()
            except:
                pass
Example #44
0
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",
        }
    }
Example #45
0
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
Example #46
0
	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)
Example #47
0
	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)
Example #48
0
def storedPreferenceFloat(name):
    return lambda setting: profile.getPreferenceFloat(name)
Example #49
0
	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()
Example #50
0
	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 )
Example #51
0
	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))
Example #54
0
    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
Example #55
0
def main():
	parser = OptionParser(usage="usage: %prog [options] <X,Y> <filename>[, <X,Y> <filename>][, ...]")
	parser.add_option("-p", "--profile", action="store", type="string", dest="profile",
					  help="Encoded profile to use for the print")
	parser.add_option("-o", "--output", action="store", type="string", dest="output",
					  help="Output filename")
	(options, args) = parser.parse_args()
	if options.output is None:
		print 'Missing output filename'
		sys.exit(1)
	if options.profile is not None:
		profile.loadGlobalProfileFromString(options.profile)
	options.output = fixUTF8(options.output)

	clearZ = 0
	resultFile = open(options.output, "w")
	for idx in xrange(0, len(args), 2):
		position = map(float, args[idx].split(','))
		if len(position) < 9 + 2:
			position = position[0:2]
			position += [1,0,0]
			position += [0,1,0]
			position += [0,0,1]
		filenames = fixUTF8(args[idx + 1]).split('|')

		profile.setTempOverride('object_center_x', position[0])
		profile.setTempOverride('object_center_y', position[1])
		if idx == 0:
			resultFile.write(';TYPE:CUSTOM\n')
			resultFile.write(profile.getAlterationFileContents('start.gcode').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))
Example #56
0
    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,
            )))