From a18e00dbc78cfc2b88e16cb69247126145e97147 Mon Sep 17 00:00:00 2001 From: daid Date: Wed, 9 May 2012 14:21:58 +0200 Subject: [PATCH 1/3] Add autoplace toolbar button. Make autoplace work with the fan on the other side of the extruder head. Add code support for slicing different objects in the project plan with different settings (still need to do GUI part). --- Cura/gui/projectPlanner.py | 41 ++++++++++++++++++++++++++++--------- Cura/images/autoplace.png | Bin 0 -> 410 bytes 2 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 Cura/images/autoplace.png diff --git a/Cura/gui/projectPlanner.py b/Cura/gui/projectPlanner.py index 4b5b1ec051..4ab326605e 100644 --- a/Cura/gui/projectPlanner.py +++ b/Cura/gui/projectPlanner.py @@ -46,6 +46,7 @@ class ProjectObject(stl.stlModel): self.swapXZ = False self.swapYZ = False self.extruder = 0 + self.profile = None self.modelDisplayList = None self.modelDirty = False @@ -183,6 +184,7 @@ class projectPlanner(wx.Frame): 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.OnAutoPlace, 'autoplace.png', 'Automaticly organize the objects on the platform.') self.toolbar2.Realize() sizer = wx.GridBagSizer(2,2) @@ -225,7 +227,7 @@ class projectPlanner(wx.Frame): 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) @@ -268,6 +270,8 @@ class projectPlanner(wx.Frame): cp.set(section, 'swapXZ', str(item.swapXZ)) cp.set(section, 'swapYZ', str(item.swapYZ)) cp.set(section, 'extruder', str(item.extruder+1)) + if item.profile != None: + cp.set(section, 'profile', item.profile) i += 1 cp.write(open(dlg.GetPath(), "w")) dlg.Destroy() @@ -295,7 +299,9 @@ class projectPlanner(wx.Frame): item.swapXZ = cp.get(section, 'swapXZ') == 'True' item.swapYZ = cp.get(section, 'swapYZ') == 'True' if cp.has_option(section, 'extruder'): - item.extuder = int(cp.get(section, 'extruder'))-1 + item.extuder = int(cp.get(section, 'extruder')) - 1 + if cp.has_option(section, 'profile'): + item.profile = cp.get(section, 'profile') item.updateModelTransform() i += 1 @@ -419,19 +425,27 @@ class projectPlanner(wx.Frame): extraSizeMin = extraSizeMin + util3d.Vector3(skirtSize, skirtSize, 0) extraSizeMax = extraSizeMax + util3d.Vector3(skirtSize, skirtSize, 0) - posX = self.machineSize.x + if extraSizeMin.x > extraSizeMax.x: + posX = self.machineSize.x + dirX = -1 + else: + posX = 0 + dirX = 1 posY = 0 + dirY = 1 + minX = self.machineSize.x minY = self.machineSize.y maxX = 0 maxY = 0 - dirX = -1 - dirY = 1 for item in self.list: item.centerX = posX + item.getMaximum().x * item.scale * dirX item.centerY = posY + item.getMaximum().y * item.scale * dirY if item.centerY + item.getSize().y >= allowedSizeY: - posX = minX - extraSizeMax.x - 1 + if dirX < 0: + posX = minX - extraSizeMax.x - 1 + else: + posX = maxX + extraSizeMin.x + 1 posY = 0 item.centerX = posX + item.getMaximum().x * item.scale * dirX item.centerY = posY + item.getMaximum().y * item.scale * dirY @@ -442,16 +456,20 @@ class projectPlanner(wx.Frame): maxY = max(maxY, item.centerY + item.getSize().y * item.scale / 2) for item in self.list: - item.centerX -= minX / 2 + if dirX < 0: + item.centerX -= minX / 2 + else: + item.centerX += (self.machineSize.x - maxX) / 2 item.centerY += (self.machineSize.y - maxY) / 2 - if minX < 0: + if minX < 0 or maxX > self.machineSize.x: return ((maxX - minX) + (maxY - minY)) * 100 return (maxX - minX) + (maxY - minY) def OnSlice(self, e): put = profile.setTempOverride + oldProfile = profile.getGlobalProfileString() put('model_multiply_x', '1') put('model_multiply_y', '1') @@ -462,6 +480,8 @@ class projectPlanner(wx.Frame): clearZ = 0 actionList = [] for item in self.list: + if item.profile != None and os.path.isfile(item.profile): + profile.loadGlobalProfile(item.profile) put('machine_center_x', item.centerX - self.extruderOffset[item.extruder].x) put('machine_center_y', item.centerY - self.extruderOffset[item.extruder].y) put('model_scale', item.scale) @@ -481,6 +501,9 @@ class projectPlanner(wx.Frame): clearZ = max(clearZ, item.getMaximum().z * item.scale) action.clearZ = clearZ actionList.append(action) + + if item.profile != None: + profile.loadGlobalProfileFromString(oldProfile) #Restore the old profile. profile.resetTempOverride() @@ -553,8 +576,6 @@ class PreviewGLCanvas(glcanvas.GLCanvas): if self.pitch < 10: self.pitch = 10 else: - #self.offsetX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2 - #self.offsetY -= float(e.GetY() - self.oldY) * self.zoom / self.GetSize().GetHeight() * 2 item = self.parent.selection if item != None: item.centerX += float(e.GetX() - self.oldX) * self.zoom / self.GetSize().GetHeight() * 2 diff --git a/Cura/images/autoplace.png b/Cura/images/autoplace.png new file mode 100644 index 0000000000000000000000000000000000000000..440295c15c6cfc7bbf5fd88641fa81dd30da0a3d GIT binary patch literal 410 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BSE>%y{W;-5;PJdx@v7EBj?eQ7#Ro_F{!43=E9oo-U3d z6}RS2-sr{bDA2b5_Fa*1*&jNYu1~ByPjHx>3N2&1?7p+;;~UXWOkJ(LO&m($9l3Ew zpXuC9)qS$auxtB21D?}HpU>BwR&foC(OUX#*0P84x6& Date: Wed, 9 May 2012 17:30:24 +0200 Subject: [PATCH 2/3] Fix project planner result dialog, so the text is readable. --- Cura/gui/projectPlanner.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Cura/gui/projectPlanner.py b/Cura/gui/projectPlanner.py index 4ab326605e..aae4681c5c 100644 --- a/Cura/gui/projectPlanner.py +++ b/Cura/gui/projectPlanner.py @@ -747,7 +747,7 @@ class ProjectSliceProgressWindow(wx.Frame): self.progressGauge2 = wx.Gauge(self, -1) self.progressGauge2.SetRange(len(self.actionList)) self.abortButton = wx.Button(self, -1, "Abort") - self.sizer.Add(self.statusText, (0,0), flag=wx.ALIGN_CENTER) + self.sizer.Add(self.statusText, (0,0)) self.sizer.Add(self.progressGauge, (1, 0), flag=wx.EXPAND) self.sizer.Add(self.progressGauge2, (2, 0), flag=wx.EXPAND) @@ -785,6 +785,7 @@ class ProjectSliceProgressWindow(wx.Frame): resultFile = open(self.resultFilename, "w") put = profile.setTempOverride for action in self.actionList: + wx.CallAfter(self.SetTitle, "Building: [%d/%d]" % (self.actionList.index(action) + 1, len(self.actionList))) p = subprocess.Popen(action.sliceCmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) line = p.stdout.readline() @@ -847,15 +848,17 @@ class ProjectSliceProgressWindow(wx.Frame): self.abort = True sliceTime = time.time() - self.sliceStartTime - status = "Slicing took: %02d:%02d\n" % (sliceTime / 60, sliceTime % 60) - status = "Filament: %.2fm %.2fg\n" % (gcode.extrusionAmount / 1000, gcode.calculateWeight() * 1000) - status += "Print time: %02d:%02d\n" % (int(gcode.totalMoveTimeMinute / 60), int(gcode.totalMoveTimeMinute % 60)) + status = "Build: %s" % (self.resultFilename) + status += "\nSlicing took: %02d:%02d" % (sliceTime / 60, sliceTime % 60) + status += "\nFilament: %.2fm %.2fg" % (gcode.extrusionAmount / 1000, gcode.calculateWeight() * 1000) + status += "\nPrint time: %02d:%02d" % (int(gcode.totalMoveTimeMinute / 60), int(gcode.totalMoveTimeMinute % 60)) cost = gcode.calculateCost() if cost != False: - status += "Cost: %s\n" % (cost) + status += "\nCost: %s" % (cost) wx.CallAfter(self.statusText.SetLabel, status) - wx.CallAfter(self.abortButton.SetLabel, 'Close') + wx.CallAfter(self.Layout) + wx.CallAfter(self.Fit) class preferencesDialog(configBase.configWindowBase): def __init__(self, parent): From 9fe9117226ab02c13e9976d05ee5d26083cea638 Mon Sep 17 00:00:00 2001 From: Daid Date: Wed, 9 May 2012 20:16:32 +0200 Subject: [PATCH 3/3] If gcode tags have integer values then export them as integer, else export them as float --- Cura/util/profile.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Cura/util/profile.py b/Cura/util/profile.py index 22d30fb0a0..2be195e740 100644 --- a/Cura/util/profile.py +++ b/Cura/util/profile.py @@ -359,12 +359,16 @@ def calculateSolidLayerCount(): def replaceTagMatch(m): tag = m.group(0)[1:-1] if tag in ['print_speed', 'retraction_speed', 'travel_speed', 'max_z_speed', 'bottom_layer_speed', 'cool_min_feedrate']: - return str(getProfileSettingFloat(tag) * 60) - if isProfileSetting(tag): - return str(getProfileSettingFloat(tag)) - if isPreference(tag): - return str(getProfileSettingFloat(tag)) - return tag + f = getProfileSettingFloat(tag) * 60 + elif isProfileSetting(tag): + f = getProfileSettingFloat(tag) + elif isPreference(tag): + f = getProfileSettingFloat(tag) + else: + return tag + if (f % 1) == 0: + return str(int(f)) + return str(f) ### Get aleration raw contents. (Used internally in Cura) def getAlterationFile(filename):