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():