diff --git a/FlatCAMObj.py b/FlatCAMObj.py index 26524067..7599b749 100644 --- a/FlatCAMObj.py +++ b/FlatCAMObj.py @@ -564,7 +564,9 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): "travelz": 0.1, "feedrate": 5.0, # "toolselection": "" - "tooldia": 0.1 + "tooldia": 0.1, + "toolchange": False, + "toolchangez": 1.0 }) # TODO: Document this. @@ -691,7 +693,9 @@ class FlatCAMExcellon(FlatCAMObj, Excellon): # job_obj.options["tooldia"] = tools_csv = ','.join(tools) - job_obj.generate_from_excellon_by_tool(self, tools_csv) + job_obj.generate_from_excellon_by_tool(self, tools_csv, + toolchange=self.options["toolchange"], + toolchangez=self.options["toolchangez"]) app_obj.progress.emit(50) job_obj.gcode_parse() diff --git a/GUIElements.py b/GUIElements.py index 1555a701..3570e331 100644 --- a/GUIElements.py +++ b/GUIElements.py @@ -227,4 +227,29 @@ class VerticalScrollArea(QtGui.QScrollArea): # else: # FlatCAMApp.App.log.debug(" Scroll bar hidden") # self.setMinimumWidth(self.widget().minimumSizeHint().width()) - return QtGui.QWidget.eventFilter(self, source, event) \ No newline at end of file + return QtGui.QWidget.eventFilter(self, source, event) + + +class OptionalInputSection(): + + def __init__(self, cb, optinputs): + assert isinstance(cb, FCCheckBox) + + self.cb = cb + self.optinputs = optinputs + + self.on_cb_change() + self.cb.stateChanged.connect(self.on_cb_change) + + def on_cb_change(self): + + if self.cb.checkState(): + + for widget in self.optinputs: + widget.setEnabled(True) + + else: + + for widget in self.optinputs: + widget.setEnabled(False) + diff --git a/ObjectUI.py b/ObjectUI.py index b1dc543f..18918bf0 100644 --- a/ObjectUI.py +++ b/ObjectUI.py @@ -346,7 +346,8 @@ class ExcellonObjectUI(ObjectUI): def __init__(self, parent=None): ObjectUI.__init__(self, title='Excellon Object', icon_file='share/drill32.png', parent=parent) - ## Plot options + #### Plot options #### + self.plot_options_label = QtGui.QLabel("Plot Options:") self.custom_box.addWidget(self.plot_options_label) @@ -363,7 +364,8 @@ class ExcellonObjectUI(ObjectUI): ) grid0.addWidget(self.solid_cb, 0, 1) - ## Tools + #### Tools #### + self.tools_table_label = QtGui.QLabel('Tools') self.tools_table_label.setToolTip( "Tools in this Excellon object." @@ -373,7 +375,8 @@ class ExcellonObjectUI(ObjectUI): self.tools_table.setFixedHeight(100) self.custom_box.addWidget(self.tools_table) - ## Create CNC Job + #### Create CNC Job #### + self.cncjob_label = QtGui.QLabel('Create CNC Job') self.cncjob_label.setToolTip( "Create a CNC Job object\n" @@ -411,6 +414,28 @@ class ExcellonObjectUI(ObjectUI): self.feedrate_entry = LengthEntry() grid1.addWidget(self.feedrate_entry, 2, 1) + # Tool change: + toolchlabel = QtGui.QLabel("Tool change:") + toolchlabel.setToolTip( + "Include tool-change sequence\n" + "in G-Code (Pause for tool change)." + ) + self.toolchange_cb = FCCheckBox() + grid1.addWidget(toolchlabel, 3, 0) + grid1.addWidget(self.toolchange_cb, 3, 1) + + # Tool change Z: + toolchzlabel = QtGui.QLabel("Tool change Z:") + toolchzlabel.setToolTip( + "Z-axis position (height) for\n" + "tool change." + ) + grid1.addWidget(toolchzlabel, 4, 0) + self.toolchangez_entry = LengthEntry() + grid1.addWidget(self.toolchangez_entry, 4, 1) + self.ois_tcz = OptionalInputSection(self.toolchange_cb, [self.toolchangez_entry]) + + choose_tools_label = QtGui.QLabel( "Select from the tools section above\n" "the tools you want to include." @@ -423,7 +448,7 @@ class ExcellonObjectUI(ObjectUI): ) self.custom_box.addWidget(self.generate_cnc_button) - ## Milling Holes + #### Milling Holes #### self.mill_hole_label = QtGui.QLabel('Mill Holes') self.mill_hole_label.setToolTip( "Create Geometry for milling holes." @@ -453,6 +478,7 @@ class ExcellonObjectUI(ObjectUI): ) self.custom_box.addWidget(self.generate_milling_button) + class GerberObjectUI(ObjectUI): """ User interface for Gerber objects. diff --git a/camlib.py b/camlib.py index 962ff74b..4dbbf1b9 100644 --- a/camlib.py +++ b/camlib.py @@ -2493,7 +2493,8 @@ class CNCjob(Geometry): return factor - def generate_from_excellon_by_tool(self, exobj, tools="all"): + def generate_from_excellon_by_tool(self, exobj, tools="all", + toolchange=False, toolchangez=0.1): """ Creates gcode for this object from an Excellon object for the specified tools. @@ -2508,6 +2509,7 @@ class CNCjob(Geometry): log.debug("Creating CNC Job from Excellon...") + # Tools if tools == "all": tools = [tool for tool in exobj.tools] else: @@ -2515,18 +2517,24 @@ class CNCjob(Geometry): tools = filter(lambda i: i in exobj.tools, tools) log.debug("Tools are: %s" % str(tools)) - points = [] + # Points (Group by tool) + points = {} for drill in exobj.drills: if drill['tool'] in tools: - points.append(drill['point']) + try: + points[drill['tool']].append(drill['point']) + except KeyError: + points[drill['tool']] = [drill['point']] - log.debug("Found %d drills." % len(points)) + #log.debug("Found %d drills." % len(points)) self.gcode = [] + # Basic G-Code macros t = "G00 " + CNCjob.defaults["coordinate_format"] + "\n" down = "G01 Z%.4f\n" % self.z_cut up = "G01 Z%.4f\n" % self.z_move + # Initialization gcode = self.unitcode[self.units.upper()] + "\n" gcode += self.absolutecode + "\n" gcode += self.feedminutecode + "\n" @@ -2535,10 +2543,17 @@ class CNCjob(Geometry): gcode += "M03\n" # Spindle start gcode += self.pausecode + "\n" - for point in points: - x, y = point.coords.xy - gcode += t % (x[0], y[0]) - gcode += down + up + for tool in points: + if toolchange: + gcode += "G00 Z%.4f\n" % toolchangez + gcode += "M5\n" # Spindle Stop + gcode += "M6\n" # Tool change + gcode += "M0\n" # Temporary machine stop + gcode += "M3\n" # Spindle on clockwise + for point in points[tool]: + x, y = point.coords.xy + gcode += t % (x[0], y[0]) + gcode += down + up gcode += t % (0, 0) gcode += "M05\n" # Spindle stop diff --git a/tests/destructor_test.py b/tests/destructor_test.py index 8d7fa791..83476a4c 100644 --- a/tests/destructor_test.py +++ b/tests/destructor_test.py @@ -8,7 +8,7 @@ class MyObj(): pass def __del__(self): - print "##### Distroyed ######" + print "##### Destroyed ######" def parse():