diff --git a/FlatCAM.py b/FlatCAM.py index 3a10da4d..2f82859e 100644 --- a/FlatCAM.py +++ b/FlatCAM.py @@ -25,6 +25,7 @@ from camlib import * import sys import urllib import copy +import random ######################################## @@ -980,10 +981,17 @@ class App: :rtype: None """ - # Check for existing name + ### Check for existing name if name in self.stuff: - self.info("Rename " + name + " in project first.") - return None + ## Create a new name + # Ends with number? + match = re.search(r'(.*[^\d])?(\d+)$', name) + if match: # Yes: Increment the number! + base = match.group(1) or '' + num = int(match.group(2)) + name = base + str(num + 1) + else: # No: add a number! + name += "_1" # Create object classdict = { @@ -2690,26 +2698,76 @@ class App: return +class BaseDraw: + def __init__(self, plotcanvas, name=None): + """ + + :param plotcanvas: The PlotCanvas where the drawing tool will operate. + :type plotcanvas: PlotCanvas + """ + + self.plotcanvas = plotcanvas + + # Must have unique axes + charset = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890" + self.name = name or [random.choice(charset) for i in range(20)] + self.axes = self.plotcanvas.new_axes(self.name) + + +class DrawingObject(BaseDraw): + def __init__(self, plotcanvas, name=None): + """ + Possible objects are: + + * Point + * Line + * Rectangle + * Circle + * Polygon + """ + + BaseDraw.__init__(self, plotcanvas) + self.properties = {} + + def plot(self): + return + + def update_plot(self): + self.axes.cla() + self.plot() + self.plotcanvas.auto_adjust_axes() + + +class DrawingPoint(DrawingObject): + def __init__(self, plotcanvas, name=None, coord=None): + DrawingObject.__init__(self, plotcanvas) + + self.properties.update({ + "coordinate": coord + }) + + def plot(self): + x, y = self.properties["coordinate"] + self.axes.plot(x, y, 'o') + + class Measurement: def __init__(self, container, axes, click_subscibers, move_subscribers, update=None): self.update = update self.container = container self.frame = None self.label = None - self.axes = axes self.click_subscribers = click_subscibers self.move_subscribers = move_subscribers self.point1 = None self.point2 = None self.active = False - # self.at = None # AnchoredText object on plot def toggle_active(self, *args): if self.active: # Deactivate self.active = False self.move_subscribers.pop("meas") self.click_subscribers.pop("meas") - # self.at.remove() self.container.remove(self.frame) if self.update is not None: self.update() @@ -2726,34 +2784,24 @@ class Measurement: align.set(0, 0.5, 0, 0) align.set_padding(4, 4, 4, 4) self.label = Gtk.Label() - self.label.set_label("Measuring tool...") - align.add(self.label) + self.label.set_label("Click on a reference point...") + abox = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 10) + abox.pack_start(Gtk.Image.new_from_file('share/measure16.png'), False, False, 0) + abox.pack_start(self.label, False, False, 0) + align.add(abox) self.frame.add(align) - self.frame.set_size_request(200, 30) - self.frame.set_hexpand(True) self.container.pack_end(self.frame, False, True, 1) self.frame.show_all() - align.show_all() - self.label.show_all() - self.container.queue_draw() return True def on_move(self, event): - # try: - # self.at.remove() - # except: - # pass if self.point1 is None: - # self.at = AnchoredText("Click on a reference point...") self.label.set_label("Click on a reference point...") else: dx = event.xdata - self.point1[0] dy = event.ydata - self.point1[1] d = sqrt(dx**2 + dy**2) - # self.at = AnchoredText("D = %.4f\nD(x) = %.4f\nD(y) = %.4f" % (d, dx, dy), - # loc=2, prop={'size': 14}, frameon=False) self.label.set_label("D = %.4f D(x) = %.4f D(y) = %.4f" % (d, dx, dy)) - # self.axes.add_artist(self.at) if self.update is not None: self.update() diff --git a/FlatCAM.ui b/FlatCAM.ui index ef716d78..9d2f8647 100644 --- a/FlatCAM.ui +++ b/FlatCAM.ui @@ -57,6 +57,21 @@ THE SOFTWARE. + + True + False + gtk-open + + + True + False + gtk-page-setup + + + True + False + gtk-info + True False @@ -97,21 +112,6 @@ THE SOFTWARE. False gtk-open - - True - False - gtk-open - - - True - False - gtk-page-setup - - - True - False - gtk-info - False @@ -472,6 +472,397 @@ THE SOFTWARE. + + False + + + True + True + never + in + + + True + False + + + True + False + 5 + 5 + 5 + 5 + vertical + + + True + False + + + True + False + share/cnc32.png + + + False + True + 0 + + + + + True + False + 3 + CNC Job Object + + + + + + True + True + 1 + + + + + False + True + 0 + + + + + True + False + + + True + False + 3 + Name: + + + False + True + 0 + + + + + True + True + + True + + + False + True + 1 + + + + + False + True + 1 + + + + + True + False + 5 + 0 + 3 + Plot Options: + + + + + + False + True + 2 + + + + + Plot + True + True + False + 0 + True + True + + + + False + True + 3 + + + + + + + + + + + True + False + 3 + 3 + 3 + + + True + False + 1 + Tool diam: + + + False + True + 0 + + + + + True + True + + True + + + + False + True + 1 + + + + + False + True + 6 + + + + + Update Plot + True + True + True + + + + + False + True + 7 + + + + + True + False + 3 + 0 + 3 + Export G-Code: + + + + + + False + True + 8 + + + + + Export + True + True + True + + + + + False + True + 9 + + + + + True + False + 3 + 0 + 3 + Scale: + + + + + + False + True + 10 + + + + + True + False + 3 + 3 + 3 + + + True + False + 1 + Factor: + + + False + True + 0 + + + + + True + True + + 1.0 + True + + + False + True + 1 + + + + + False + True + 11 + + + + + Scale + True + True + True + + + + + False + True + 12 + + + + + True + False + 3 + 0 + 3 + Offset: + + + + + + False + True + 13 + + + + + True + False + 3 + 3 + 3 + + + True + False + 1 + Offset Vector: + + + False + True + 0 + + + + + True + True + + (0.0, 0.0) + True + + + False + True + 1 + + + + + False + True + 14 + + + + + Offset + True + True + True + + + + + False + True + 15 + + + + + + + + + + + + + + + + + + False @@ -2552,397 +2943,6 @@ this object. - - False - - - True - True - never - in - - - True - False - - - True - False - 5 - 5 - 5 - 5 - vertical - - - True - False - - - True - False - share/cnc32.png - - - False - True - 0 - - - - - True - False - 3 - CNC Job Object - - - - - - True - True - 1 - - - - - False - True - 0 - - - - - True - False - - - True - False - 3 - Name: - - - False - True - 0 - - - - - True - True - - True - - - False - True - 1 - - - - - False - True - 1 - - - - - True - False - 5 - 0 - 3 - Plot Options: - - - - - - False - True - 2 - - - - - Plot - True - True - False - 0 - True - True - - - - False - True - 3 - - - - - - - - - - - True - False - 3 - 3 - 3 - - - True - False - 1 - Tool diam: - - - False - True - 0 - - - - - True - True - - True - - - - False - True - 1 - - - - - False - True - 6 - - - - - Update Plot - True - True - True - - - - - False - True - 7 - - - - - True - False - 3 - 0 - 3 - Export G-Code: - - - - - - False - True - 8 - - - - - Export - True - True - True - - - - - False - True - 9 - - - - - True - False - 3 - 0 - 3 - Scale: - - - - - - False - True - 10 - - - - - True - False - 3 - 3 - 3 - - - True - False - 1 - Factor: - - - False - True - 0 - - - - - True - True - - 1.0 - True - - - False - True - 1 - - - - - False - True - 11 - - - - - Scale - True - True - True - - - - - False - True - 12 - - - - - True - False - 3 - 0 - 3 - Offset: - - - - - - False - True - 13 - - - - - True - False - 3 - 3 - 3 - - - True - False - 1 - Offset Vector: - - - False - True - 0 - - - - - True - True - - (0.0, 0.0) - True - - - False - True - 1 - - - - - False - True - 14 - - - - - Offset - True - True - True - - - - - False - True - 15 - - - - - - - - - - - - - - - - - - 600 400 @@ -4331,7 +4331,7 @@ to overlap each pass. True False - 4 + 5 <b>Excellon Objects</b> True @@ -4707,7 +4707,7 @@ to overlap each pass. True False - 4 + 5 <b>Geometry Objects</b> True @@ -4813,6 +4813,7 @@ to overlap each pass. True False + 5 <b>CNC Job Objects</b> True diff --git a/camlib.py b/camlib.py index 478e507c..76c5e403 100644 --- a/camlib.py +++ b/camlib.py @@ -818,23 +818,21 @@ class Gerber (Geometry): self.flash_geometry.append(obround) continue - if aperture['type'] == 'P': #Regular polygon + if aperture['type'] == 'P': # Regular polygon loc = flash['loc'] diam = aperture['diam'] nVertices = aperture['nVertices'] points = [] - for i in range(0,nVertices): + for i in range(0, nVertices): x = loc[0] + diam * (cos(2 * pi * i / nVertices)) y = loc[1] + diam * (sin(2 * pi * i / nVertices)) - points.append((x,y)) + points.append((x, y)) ply = Polygon(points) if 'rotation' in aperture: ply = affinity.rotate(ply, aperture['rotation']) self.flash_geometry.append(ply) continue - - print "WARNING: Aperture type %s not implemented" % (aperture['type']) def create_geometry(self): @@ -1433,12 +1431,12 @@ class CNCjob(Geometry): # Current path: temporary storage until tool is # lifted or lowered. - path = [] + path = [(0, 0)] # Process every instruction for gobj in gobjs: - # Changing height: + ## Changing height if 'Z' in gobj: if ('X' in gobj or 'Y' in gobj) and gobj['Z'] != current['Z']: print "WARNING: Non-orthogonal motion: From", current @@ -1490,6 +1488,13 @@ class CNCjob(Geometry): for code in gobj: current[code] = gobj[code] + # There might not be a change in height at the + # end, therefore, see here too if there is + # a final path. + if len(path) > 1: + geometry.append({"geom": LineString(path), + "kind": kind}) + self.gcode_parsed = geometry return geometry