diff --git a/FlatCAMApp.py b/FlatCAMApp.py index 78de965..c3bde7d 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -1637,7 +1637,7 @@ class App(QtCore.QObject): raise IOError('Failed to open file: ' + filename) except ParseError, e: - app_obj.inform.emit("[error] Failed to parse file: " + filename) + app_obj.inform.emit("[error] Failed to parse file: " + filename + ". " + e[0]) app_obj.progress.emit(0) self.log.error(str(e)) raise diff --git a/FlatCAMDraw.py b/FlatCAMDraw.py index 659506e..29eb478 100644 --- a/FlatCAMDraw.py +++ b/FlatCAMDraw.py @@ -457,6 +457,11 @@ class FCPolygon(FCShapeTool): self.geometry = DrawToolShape(Polygon(self.points)) self.complete = True + def on_key(self, key): + if key == 'backspace': + if len(self.points) > 0: + self.points = self.points[0:-1] + class FCPath(FCPolygon): """ @@ -468,13 +473,18 @@ class FCPath(FCPolygon): self.complete = True def utility_geometry(self, data=None): - if len(self.points) > 1: + if len(self.points) > 0: temp_points = [x for x in self.points] temp_points.append(data) return DrawToolUtilityShape(LineString(temp_points)) return None + def on_key(self, key): + if key == 'backspace': + if len(self.points) > 0: + self.points = self.points[0:-1] + class FCSelect(DrawTool): def __init__(self, draw_app): @@ -1001,6 +1011,7 @@ class FlatCAMDraw(QtCore.QObject): self.active_tool.make() if self.active_tool.complete: self.on_shape_complete() + self.app.info("Done.") return ### Abort the current action @@ -1027,12 +1038,14 @@ class FlatCAMDraw(QtCore.QObject): self.move_btn.setChecked(True) self.on_tool_select('move') self.active_tool.set_origin(self.snap(event.xdata, event.ydata)) + self.app.info("Click on target point.") ### Copy if event.key == 'c': self.copy_btn.setChecked(True) self.on_tool_select('copy') self.active_tool.set_origin(self.snap(event.xdata, event.ydata)) + self.app.info("Click on target point.") ### Snap if event.key == 'g': diff --git a/FlatCAMGUI.py b/FlatCAMGUI.py index f466b6b..ccd71e0 100644 --- a/FlatCAMGUI.py +++ b/FlatCAMGUI.py @@ -300,6 +300,7 @@ class FlatCAMInfoBar(QtGui.QWidget): self.text = QtGui.QLabel(self) self.text.setText("Hello!") + self.text.setToolTip("Hello!") layout.addWidget(self.text) @@ -307,6 +308,7 @@ class FlatCAMInfoBar(QtGui.QWidget): def set_text_(self, text): self.text.setText(text) + self.text.setToolTip(text) def set_status(self, text, level="info"): level = str(level) diff --git a/GUIElements.py b/GUIElements.py index 831379b..ba240ad 100644 --- a/GUIElements.py +++ b/GUIElements.py @@ -85,15 +85,19 @@ class LengthEntry(QtGui.QLineEdit): def get_value(self): raw = str(self.text()).strip(' ') - match = self.format_re.search(raw) + # match = self.format_re.search(raw) - if not match: - return None try: - if match.group(2) is not None and match.group(2).upper() in self.scales: - return float(eval(match.group(1)))*float(self.scales[self.output_units][match.group(2).upper()]) - else: - return float(eval(match.group(1))) + units = raw[-2:] + units = self.scales[self.output_units][units.upper()] + value = raw[:-2] + return float(eval(value))*units + except IndexError: + value = raw + return float(eval(value)) + except KeyError: + value = raw + return float(eval(value)) except: log.warning("Could not parse value in entry: %s" % str(raw)) return None diff --git a/camlib.py b/camlib.py index 5748635..ae85dda 100644 --- a/camlib.py +++ b/camlib.py @@ -14,6 +14,8 @@ from numpy import arctan2, Inf, array, sqrt, pi, ceil, sin, cos, dot, float32, \ from numpy.linalg import solve, norm from matplotlib.figure import Figure import re +import sys +import traceback import collections import numpy as np @@ -2054,9 +2056,12 @@ class Gerber (Geometry): self.solid_geometry = self.solid_geometry.difference(new_poly) except Exception, err: + ex_type, ex, tb = sys.exc_info() + traceback.print_tb(tb) #print traceback.format_exc() + log.error("PARSING FAILED. Line %d: %s" % (line_num, gline)) - raise ParseError("%s\nLine %d: %s" % (repr(err), line_num, gline)) + raise ParseError("Line %d: %s" % (line_num, gline), repr(err)) @staticmethod def create_flash_geometry(location, aperture): @@ -2733,6 +2738,9 @@ class CNCjob(Geometry): :param append: :param tooldia: :param tolerance: + :param multidepth: If True, use multiple passes to reach + the desired depth. + :param depthpercut: Maximum depth in each pass. :return: None """ assert isinstance(geometry, Geometry), \ @@ -2800,6 +2808,7 @@ class CNCjob(Geometry): if pt != geo.coords[0] and pt == geo.coords[-1]: geo.coords = list(geo.coords)[::-1] + #---------- Single depth/pass -------- if not multidepth: # G-code # Note: self.linear2gcode() and self.point2gcode() will @@ -2819,14 +2828,17 @@ class CNCjob(Geometry): depth = 0 reverse = False while depth > self.z_cut: - depth -= depthpercut - log.debug("DEPTH: %f" % depth) - # TODO: Working... - # G-code - # Note: self.linear2gcode() and self.point2gcode() will - # lower and raise the tool every time. - # Cut at specific depth and do not leave the tool. + # Increase depth. Limit to z_cut. + depth -= depthpercut + if depth < self.z_cut: + depth = self.z_cut + + # Cut at specific depth and do not lift the tool. + # Note: linear2gcode() will use G00 to move to the + # first point in the path, but it should be already + # at the first point if the tool is down (in the material). + # So, an extra G00 should show up but is inconsequential. if type(geo) == LineString or type(geo) == LinearRing: self.gcode += self.linear2gcode(geo, tolerance=tolerance, zcut=depth,