Gerber support for single quadrant arcs (G74).
This commit is contained in:
Binary file not shown.
@@ -12,7 +12,7 @@ Contents:
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
active
|
active
|
||||||
|
excellonparse
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
==================
|
==================
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<script type="text/javascript" src="_static/underscore.js"></script>
|
<script type="text/javascript" src="_static/underscore.js"></script>
|
||||||
<script type="text/javascript" src="_static/doctools.js"></script>
|
<script type="text/javascript" src="_static/doctools.js"></script>
|
||||||
<link rel="top" title="FlatCAM Bugs 1 documentation" href="index.html" />
|
<link rel="top" title="FlatCAM Bugs 1 documentation" href="index.html" />
|
||||||
|
<link rel="next" title="Excellon Parser" href="excellonparse.html" />
|
||||||
<link rel="prev" title="Welcome to FlatCAM Bugs’s documentation!" href="index.html" />
|
<link rel="prev" title="Welcome to FlatCAM Bugs’s documentation!" href="index.html" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -33,6 +34,9 @@
|
|||||||
<li class="right" style="margin-right: 10px">
|
<li class="right" style="margin-right: 10px">
|
||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
accesskey="I">index</a></li>
|
accesskey="I">index</a></li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="excellonparse.html" title="Excellon Parser"
|
||||||
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="index.html" title="Welcome to FlatCAM Bugs’s documentation!"
|
<a href="index.html" title="Welcome to FlatCAM Bugs’s documentation!"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
@@ -131,6 +135,9 @@ zeros.</p>
|
|||||||
<h4>Previous topic</h4>
|
<h4>Previous topic</h4>
|
||||||
<p class="topless"><a href="index.html"
|
<p class="topless"><a href="index.html"
|
||||||
title="previous chapter">Welcome to FlatCAM Bugs’s documentation!</a></p>
|
title="previous chapter">Welcome to FlatCAM Bugs’s documentation!</a></p>
|
||||||
|
<h4>Next topic</h4>
|
||||||
|
<p class="topless"><a href="excellonparse.html"
|
||||||
|
title="next chapter">Excellon Parser</a></p>
|
||||||
<h3>This Page</h3>
|
<h3>This Page</h3>
|
||||||
<ul class="this-page-menu">
|
<ul class="this-page-menu">
|
||||||
<li><a href="_sources/active.txt"
|
<li><a href="_sources/active.txt"
|
||||||
@@ -159,6 +166,9 @@ zeros.</p>
|
|||||||
<li class="right" style="margin-right: 10px">
|
<li class="right" style="margin-right: 10px">
|
||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
>index</a></li>
|
>index</a></li>
|
||||||
|
<li class="right" >
|
||||||
|
<a href="excellonparse.html" title="Excellon Parser"
|
||||||
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="index.html" title="Welcome to FlatCAM Bugs’s documentation!"
|
<a href="index.html" title="Welcome to FlatCAM Bugs’s documentation!"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
|
|||||||
35
bugs/excellonparse.rst
Normal file
35
bugs/excellonparse.rst
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
Excellon Parser
|
||||||
|
===============
|
||||||
|
|
||||||
|
List of test files and their settings
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
========================== ============== ========= ===================
|
||||||
|
File Settings Parsed Ok Example
|
||||||
|
========================== ============== ========= ===================
|
||||||
|
FlatCAM_Drilling_Test.drl METRIC YES X76324 -> 76mm
|
||||||
|
Drill_All.drl METRIC NO X019708 -> 1.97mm X
|
||||||
|
TFTadapter.drl METRIC,TZ YES? X4.572 -> 4.57mm
|
||||||
|
rfduino dip.drl_ METRIC,TZ NO X236220 -> 23mm X
|
||||||
|
X-Y CONTROLLER - Drill... METRIC YES X76213 -> 76mm
|
||||||
|
ucontrllerBoard.drl INCH,TZ YES X1.96572
|
||||||
|
holes.drl INCH YES Y+019500 -> 1.95in
|
||||||
|
BLDC2003Through.drl INCH YES X+023625 -> 2.3in
|
||||||
|
PlacaReles.drl INCH,TZ YES Y-8200 -> -0.82in
|
||||||
|
AVR_Transistor_Tester.DRL INCH YES X033000 -> 3.3in
|
||||||
|
DRL INCH,00.0000 YES/NO* X004759 -> 0.47in
|
||||||
|
========================== ============== ========= ===================
|
||||||
|
|
||||||
|
(*) The units format is not recognized, thus it is parsed correctly
|
||||||
|
as long as the project is set for inches already.
|
||||||
|
|
||||||
|
Parser was:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def parse_number(self, number_str):
|
||||||
|
if self.zeros == "L":
|
||||||
|
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
|
||||||
@@ -54,6 +54,10 @@
|
|||||||
<li class="toctree-l2"><a class="reference internal" href="active.html#drill-number-parsing">Drill number parsing</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="active.html#drill-number-parsing">Drill number parsing</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="toctree-l1"><a class="reference internal" href="excellonparse.html">Excellon Parser</a><ul>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="excellonparse.html#list-of-test-files-and-their-settings">List of test files and their settings</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Contents:
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
active
|
active
|
||||||
|
excellonparse
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
==================
|
==================
|
||||||
|
|||||||
82
camlib.py
82
camlib.py
@@ -200,7 +200,7 @@ class Geometry(object):
|
|||||||
log.warning("Solid_geometry not computed yet.")
|
log.warning("Solid_geometry not computed yet.")
|
||||||
return 0
|
return 0
|
||||||
bounds = self.bounds()
|
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):
|
def get_empty_area(self, boundary=None):
|
||||||
"""
|
"""
|
||||||
@@ -1164,6 +1164,7 @@ class Gerber (Geometry):
|
|||||||
# 2-clockwise, 3-counterclockwise
|
# 2-clockwise, 3-counterclockwise
|
||||||
match = self.circ_re.search(gline)
|
match = self.circ_re.search(gline)
|
||||||
if match:
|
if match:
|
||||||
|
arcdir = [None, None, "cw", "ccw"]
|
||||||
|
|
||||||
mode, x, y, i, j, d = match.groups()
|
mode, x, y, i, j, d = match.groups()
|
||||||
try:
|
try:
|
||||||
@@ -1224,9 +1225,8 @@ class Gerber (Geometry):
|
|||||||
if quadrant_mode == 'MULTI':
|
if quadrant_mode == 'MULTI':
|
||||||
center = [i + current_x, j + current_y]
|
center = [i + current_x, j + current_y]
|
||||||
radius = sqrt(i**2 + j**2)
|
radius = sqrt(i**2 + j**2)
|
||||||
start = arctan2(-j, -i)
|
start = arctan2(-j, -i) # Start angle
|
||||||
stop = arctan2(-center[1] + y, -center[0] + x)
|
stop = arctan2(-center[1] + y, -center[0] + x) # Stop angle
|
||||||
arcdir = [None, None, "cw", "ccw"]
|
|
||||||
this_arc = arc(center, radius, start, stop,
|
this_arc = arc(center, radius, start, stop,
|
||||||
arcdir[current_interpolation_mode],
|
arcdir[current_interpolation_mode],
|
||||||
self.steps_per_circ)
|
self.steps_per_circ)
|
||||||
@@ -1243,7 +1243,56 @@ class Gerber (Geometry):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if quadrant_mode == 'SINGLE':
|
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
|
||||||
# Operation code alone, usually just D03 (Flash)
|
# Operation code alone, usually just D03 (Flash)
|
||||||
@@ -1786,15 +1835,24 @@ class Excellon(Geometry):
|
|||||||
:rtype: foat
|
:rtype: foat
|
||||||
"""
|
"""
|
||||||
if self.zeros == "L":
|
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*)'
|
# r'^[-\+]?(0*)(\d*)'
|
||||||
# 6 digits are divided by 10^4
|
# 6 digits are divided by 10^4
|
||||||
# If less than size digits, they are automatically added,
|
# 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)
|
match = self.leadingzeros_re.search(number_str)
|
||||||
return float(number_str)/(10**(len(match.group(1)) + len(match.group(2)) - 2))
|
return float(number_str)/(10**(len(match.group(1)) + len(match.group(2)) - 2))
|
||||||
|
|
||||||
else: # Trailing
|
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):
|
def create_geometry(self):
|
||||||
"""
|
"""
|
||||||
@@ -2621,6 +2679,16 @@ def arc(center, radius, start, stop, direction, steps_per_circ):
|
|||||||
return points
|
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):
|
def clear_poly(poly, tooldia, overlap=0.1):
|
||||||
"""
|
"""
|
||||||
Creates a list of Shapely geometry objects covering the inside
|
Creates a list of Shapely geometry objects covering the inside
|
||||||
|
|||||||
Reference in New Issue
Block a user