diff --git a/bugs/.doctrees/index.doctree b/bugs/.doctrees/index.doctree index 0a6e089..488009d 100644 Binary files a/bugs/.doctrees/index.doctree and b/bugs/.doctrees/index.doctree differ diff --git a/bugs/_sources/index.txt b/bugs/_sources/index.txt index 86df864..5559a9c 100644 --- a/bugs/_sources/index.txt +++ b/bugs/_sources/index.txt @@ -12,7 +12,7 @@ Contents: :maxdepth: 2 active - + excellonparse Indices and tables ================== diff --git a/bugs/active.html b/bugs/active.html index 365a2e3..760cecf 100644 --- a/bugs/active.html +++ b/bugs/active.html @@ -24,6 +24,7 @@ + @@ -33,6 +34,9 @@
  • index
  • +
  • + next |
  • previous |
  • @@ -131,6 +135,9 @@ zeros.

    Previous topic

    Welcome to FlatCAM Bugs’s documentation!

    +

    Next topic

    +

    Excellon Parser

    This Page

    +
  • Excellon Parser +
  • diff --git a/bugs/index.rst b/bugs/index.rst index 86df864..5559a9c 100644 --- a/bugs/index.rst +++ b/bugs/index.rst @@ -12,7 +12,7 @@ Contents: :maxdepth: 2 active - + excellonparse Indices and tables ================== diff --git a/camlib.py b/camlib.py index e642404..514a3fa 100644 --- a/camlib.py +++ b/camlib.py @@ -200,7 +200,7 @@ class Geometry(object): log.warning("Solid_geometry not computed yet.") return 0 bounds = self.bounds() - return (bounds[2]-bounds[0], bounds[3]-bounds[1]) + return bounds[2]-bounds[0], bounds[3]-bounds[1] def get_empty_area(self, boundary=None): """ @@ -1164,6 +1164,7 @@ class Gerber (Geometry): # 2-clockwise, 3-counterclockwise match = self.circ_re.search(gline) if match: + arcdir = [None, None, "cw", "ccw"] mode, x, y, i, j, d = match.groups() try: @@ -1224,9 +1225,8 @@ class Gerber (Geometry): if quadrant_mode == 'MULTI': center = [i + current_x, j + current_y] radius = sqrt(i**2 + j**2) - start = arctan2(-j, -i) - stop = arctan2(-center[1] + y, -center[0] + x) - arcdir = [None, None, "cw", "ccw"] + start = arctan2(-j, -i) # Start angle + stop = arctan2(-center[1] + y, -center[0] + x) # Stop angle this_arc = arc(center, radius, start, stop, arcdir[current_interpolation_mode], self.steps_per_circ) @@ -1243,7 +1243,56 @@ class Gerber (Geometry): continue if quadrant_mode == 'SINGLE': - log.warning("Single quadrant arc are not implemented yet. (%d)" % line_num) + #log.warning("Single quadrant arc are not implemented yet. (%d)" % line_num) + + center_candidates = [ + [i + current_x, j + current_y], + [-i + current_x, j + current_y], + [i + current_x, -j + current_y], + [-i + current_x, -j + current_y] + ] + + valid = False + log.debug("I: %f J: %f" % (i, j)) + for center in center_candidates: + 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: + continue # Not a valid center. + + # Correct i and j and continue as with multi-quadrant. + i = center[0] - current_x + j = center[1] - current_y + + start = arctan2(-j, -i) # Start angle + stop = arctan2(-center[1] + y, -center[0] + x) # Stop angle + angle = abs(arc_angle(start, stop, arcdir[current_interpolation_mode])) + 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)) + + if angle <= (pi+1e-6)/2: + log.debug("########## ACCEPTING ARC ############") + this_arc = arc(center, radius, start, stop, + arcdir[current_interpolation_mode], + self.steps_per_circ) + current_x = this_arc[-1][0] + current_y = this_arc[-1][1] + path += this_arc + last_path_aperture = current_aperture + valid = True + break + + if valid: + continue + else: + log.warning("Invalid arc in line %d." % line_num) + + ### Operation code alone # Operation code alone, usually just D03 (Flash) @@ -1786,15 +1835,24 @@ class Excellon(Geometry): :rtype: foat """ if self.zeros == "L": + # With leading zeros, when you type in a coordinate, + # the leading zeros must always be included. Trailing zeros + # are unneeded and may be left off. The CNC-7 will automatically add them. # r'^[-\+]?(0*)(\d*)' # 6 digits are divided by 10^4 # If less than size digits, they are automatically added, - # 5 digits then are divided by 10^3 + # 5 digits then are divided by 10^3 and so on. match = self.leadingzeros_re.search(number_str) return float(number_str)/(10**(len(match.group(1)) + len(match.group(2)) - 2)) else: # Trailing - return float(number_str)/10000 + # You must show all zeros to the right of the number and can omit + # all zeros to the left of the number. The CNC-7 will count the number + # of digits you typed and automatically fill in the missing zeros. + if self.units.lower() == "in": # Inches is 00.0000 + return float(number_str)/10000 + + return float(number_str)/1000 # Metric is 000.000 def create_geometry(self): """ @@ -2621,6 +2679,16 @@ def arc(center, radius, start, stop, direction, steps_per_circ): return points +def arc_angle(start, stop, direction): + if direction == "ccw" and stop <= start: + stop += 2*pi + if direction == "cw" and stop >= start: + stop -= 2*pi + + angle = abs(stop - start) + return angle + + def clear_poly(poly, tooldia, overlap=0.1): """ Creates a list of Shapely geometry objects covering the inside