From ddd90f9f33330c6aa4e2d3f6f5a2d9974be3d417 Mon Sep 17 00:00:00 2001 From: Juan Pablo Caram Date: Tue, 6 Jan 2015 13:06:01 -0500 Subject: [PATCH] Solves Gerber parser bug in Issue #92 (Incorrect Flashes). --- FlatCAMApp.py | 18 +++++++++++++++--- camlib.py | 36 ++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/FlatCAMApp.py b/FlatCAMApp.py index c6a5677..0d053e0 100644 --- a/FlatCAMApp.py +++ b/FlatCAMApp.py @@ -12,6 +12,7 @@ import os import Tkinter import re from PyQt4 import QtCore +import time ######################################## ## Imports part of FlatCAM ## @@ -52,8 +53,8 @@ class App(QtCore.QObject): ## Logging ## log = logging.getLogger('base') - #log.setLevel(logging.DEBUG) - log.setLevel(logging.WARNING) + log.setLevel(logging.DEBUG) + #log.setLevel(logging.WARNING) formatter = logging.Formatter('[%(levelname)s][%(threadName)s] %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) @@ -717,6 +718,8 @@ class App(QtCore.QObject): App.log.debug("new_object()") + t0 = time.time() # Debug + ### Check for existing name while name in self.collection.get_names(): ## Create a new name @@ -745,19 +748,25 @@ class App(QtCore.QObject): # Set default options from self.options for option in self.options: if option.find(kind + "_") == 0: - oname = option[len(kind)+1:] + oname = option[len(kind) + 1:] obj.options[oname] = self.options[option] # Initialize as per user request # User must take care to implement initialize # in a thread-safe way as is is likely that we # have been invoked in a separate thread. + t1 = time.time() + self.log.debug("%f seconds before initialize()." % (t1 - t0)) initialize(obj, self) + t2 = time.time() + self.log.debug("%f seconds executing initialize()." % (t2 - t1)) # Check units and convert if necessary if self.options["units"].upper() != obj.units.upper(): self.inform.emit("Converting units to " + self.options["units"] + ".") obj.convert_units(self.options["units"]) + t3 = time.time() + self.log.debug("%f seconds converting units." % (t3 - t2)) FlatCAMApp.App.log.debug("Moving new object back to main thread.") @@ -1206,11 +1215,14 @@ class App(QtCore.QObject): :param obj: The newly created FlatCAM object. :return: None """ + t0 = time.time() # DEBUG self.log.debug("on_object_created()") self.inform.emit("Object (%s) created: %s" % (obj.kind, obj.options['name'])) self.collection.append(obj) obj.plot() self.on_zoom_fit(None) + t1 = time.time() # DEBUG + self.log.debug("%f seconds adding object and plotting." % (t1 - t0)) def on_zoom_fit(self, event): """ diff --git a/camlib.py b/camlib.py index 8b17d57..f4aac04 100644 --- a/camlib.py +++ b/camlib.py @@ -42,8 +42,8 @@ import simplejson as json import logging log = logging.getLogger('base2') -#log.setLevel(logging.DEBUG) -log.setLevel(logging.WARNING) +log.setLevel(logging.DEBUG) +#log.setLevel(logging.WARNING) #log.setLevel(logging.INFO) formatter = logging.Formatter('[%(levelname)s] %(message)s') handler = logging.StreamHandler() @@ -1194,6 +1194,8 @@ class Gerber (Geometry): ### Cleanup gline = gline.strip(' \r\n') + #log.debug("%3s %s" % (line_num, gline)) + ### Aperture Macros # Having this at the beggining will slow things down # but macros can have complicated statements than could @@ -1268,7 +1270,7 @@ class Gerber (Geometry): if follow: geo = LineString(path) else: - geo = LineString(path).buffer(width/2) + geo = LineString(path).buffer(width / 2) poly_buffer.append(geo) path = [[current_x, current_y]] # Start new path @@ -1332,7 +1334,7 @@ class Gerber (Geometry): # --- BUFFERED --- width = self.apertures[last_path_aperture]["size"] - buffered = LineString(path).buffer(width/2) + buffered = LineString(path).buffer(width / 2) poly_buffer.append(buffered) current_x = x @@ -1384,11 +1386,11 @@ class Gerber (Geometry): valid = False log.debug("I: %f J: %f" % (i, j)) for center in center_candidates: - radius = sqrt(i**2 + j**2) + radius = sqrt(i ** 2 + j ** 2) # Make sure radius to start is the same as radius to end. - radius2 = sqrt((center[0] - x)**2 + (center[1] - y)**2) - if radius2 < radius*0.95 or radius2 > radius*1.05: + radius2 = sqrt((center[0] - x) ** 2 + (center[1] - y) ** 2) + if radius2 < radius * 0.95 or radius2 > radius * 1.05: continue # Not a valid center. # Correct i and j and continue as with multi-quadrant. @@ -1401,10 +1403,10 @@ class Gerber (Geometry): log.debug("ARC START: %f, %f CENTER: %f, %f STOP: %f, %f" % (current_x, current_y, center[0], center[1], x, y)) log.debug("START Ang: %f, STOP Ang: %f, DIR: %s, ABS: %.12f <= %.12f: %s" % - (start*180/pi, stop*180/pi, arcdir[current_interpolation_mode], - angle*180/pi, pi/2*180/pi, angle <= (pi+1e-6)/2)) + (start * 180 / pi, stop * 180 / pi, arcdir[current_interpolation_mode], + angle * 180 / pi, pi / 2 * 180 / pi, angle <= (pi + 1e-6) / 2)) - if angle <= (pi+1e-6)/2: + if angle <= (pi + 1e-6) / 2: log.debug("########## ACCEPTING ARC ############") this_arc = arc(center, radius, start, stop, arcdir[current_interpolation_mode], @@ -1431,7 +1433,10 @@ class Gerber (Geometry): ## --- Buffered --- try: - flash = Gerber.create_flash_geometry(Point(path[-1]), + log.debug("Bare op-code %d." % current_operation_code) + # flash = Gerber.create_flash_geometry(Point(path[-1]), + # self.apertures[current_aperture]) + flash = Gerber.create_flash_geometry(Point(current_x, current_y), self.apertures[current_aperture]) poly_buffer.append(flash) except IndexError: @@ -1511,14 +1516,15 @@ class Gerber (Geometry): # Example: D12* match = self.tool_re.search(gline) if match: - log.debug("Line %d: Aperture change to (%s)" % (line_num, match.group(1))) current_aperture = match.group(1) + log.debug("Line %d: Aperture change to (%s)" % (line_num, match.group(1))) + log.debug(self.apertures[current_aperture]) # Take care of the current path with the previous tool if len(path) > 1: # --- Buffered ---- width = self.apertures[last_path_aperture]["size"] - geo = LineString(path).buffer(width/2) + geo = LineString(path).buffer(width / 2) poly_buffer.append(geo) path = [path[-1]] @@ -1617,11 +1623,13 @@ class Gerber (Geometry): @staticmethod def create_flash_geometry(location, aperture): + log.debug('Flashing @%s, Aperture: %s' % (location, aperture)) + if type(location) == list: location = Point(location) if aperture['type'] == 'C': # Circles - return location.buffer(aperture['size']/2) + return location.buffer(aperture['size'] / 2) if aperture['type'] == 'R': # Rectangles loc = location.coords[0]