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