summaryrefslogtreecommitdiff
path: root/gerber/rs274x.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerber/rs274x.py')
-rw-r--r--gerber/rs274x.py57
1 files changed, 30 insertions, 27 deletions
diff --git a/gerber/rs274x.py b/gerber/rs274x.py
index e84c161..2f8dfd2 100644
--- a/gerber/rs274x.py
+++ b/gerber/rs274x.py
@@ -98,7 +98,7 @@ class GerberFile(CamFile):
def __init__(self, statements, settings, primitives, apertures, filename=None):
super(GerberFile, self).__init__(statements, settings, primitives, filename)
-
+
self.apertures = apertures
@property
@@ -115,15 +115,18 @@ class GerberFile(CamFile):
def bounds(self):
min_x = min_y = 1000000
max_x = max_y = -1000000
+
for stmt in [stmt for stmt in self.statements if isinstance(stmt, CoordStmt)]:
if stmt.x is not None:
min_x = min(stmt.x, min_x)
max_x = max(stmt.x, max_x)
+
if stmt.y is not None:
min_y = min(stmt.y, min_y)
max_y = max(stmt.y, max_y)
+
return ((min_x, max_x), (min_y, max_y))
-
+
@property
def bounding_box(self):
min_x = min_y = 1000000
@@ -258,7 +261,7 @@ class GerberParser(object):
stmt.units = self.settings.units
return GerberFile(self.statements, self.settings, self.primitives, self.apertures.values(), filename)
-
+
def _split_commands(self, data):
"""
Split the data into commands. Commands end with * (and also newline to help with some badly formatted files)
@@ -267,24 +270,24 @@ class GerberParser(object):
length = len(data)
start = 0
in_header = True
-
+
for cur in range(0, length):
val = data[cur]
-
+
if val == '%' and start == cur:
in_header = True
continue
-
+
if val == '\r' or val == '\n':
if start != cur:
yield data[start:cur]
start = cur + 1
-
+
elif not in_header and val == '*':
yield data[start:cur + 1]
start = cur + 1
-
+
elif in_header and val == '%':
yield data[start:cur + 1]
start = cur + 1
@@ -318,13 +321,13 @@ class GerberParser(object):
did_something = True # make sure we do at least one loop
while did_something and len(line) > 0:
did_something = False
-
+
# consume empty data blocks
if line[0] == '*':
line = line[1:]
did_something = True
continue
-
+
# coord
(coord, r) = _match_one(self.COORD_STMT, line)
if coord:
@@ -332,7 +335,7 @@ class GerberParser(object):
line = r
did_something = True
continue
-
+
# aperture selection
(aperture, r) = _match_one(self.APERTURE_STMT, line)
if aperture:
@@ -485,32 +488,32 @@ class GerberParser(object):
aperture = None
if shape == 'C':
diameter = modifiers[0][0]
-
+
if len(modifiers[0]) >= 2:
hole_diameter = modifiers[0][1]
else:
hole_diameter = None
-
+
aperture = Circle(position=None, diameter=diameter, hole_diameter=hole_diameter, units=self.settings.units)
elif shape == 'R':
width = modifiers[0][0]
height = modifiers[0][1]
-
+
if len(modifiers[0]) >= 3:
hole_diameter = modifiers[0][2]
else:
hole_diameter = None
-
+
aperture = Rectangle(position=None, width=width, height=height, hole_diameter=hole_diameter, units=self.settings.units)
elif shape == 'O':
width = modifiers[0][0]
height = modifiers[0][1]
-
+
if len(modifiers[0]) >= 3:
hole_diameter = modifiers[0][2]
else:
hole_diameter = None
-
+
aperture = Obround(position=None, width=width, height=height, hole_diameter=hole_diameter, units=self.settings.units)
elif shape == 'P':
outer_diameter = modifiers[0][0]
@@ -519,7 +522,7 @@ class GerberParser(object):
rotation = modifiers[0][2]
else:
rotation = 0
-
+
if len(modifiers[0]) > 3:
hole_diameter = modifiers[0][3]
else:
@@ -636,7 +639,7 @@ class GerberParser(object):
units=self.settings.units))
elif self.op == "D02" or self.op == "D2":
-
+
if self.region_mode == "on":
# D02 in the middle of a region finishes that region and starts a new one
if self.current_region and len(self.current_region) > 1:
@@ -663,32 +666,32 @@ class GerberParser(object):
if renderable is not None:
self.primitives.append(renderable)
self.x, self.y = x, y
-
+
def _find_center(self, start, end, offsets):
"""
In single quadrant mode, the offsets are always positive, which means there are 4 possible centers.
The correct center is the only one that results in an arc with sweep angle of less than or equal to 90 degrees
"""
-
+
if self.quadrant_mode == 'single-quadrant':
-
- # The Gerber spec says single quadrant only has one possible center, and you can detect
+
+ # The Gerber spec says single quadrant only has one possible center, and you can detect
# based on the angle. But for real files, this seems to work better - there is usually
# only one option that makes sense for the center (since the distance should be the same
# from start and end). Find the center that makes the most sense
sqdist_diff_min = sys.maxint
center = None
for factors in [(1, 1), (1, -1), (-1, 1), (-1, -1)]:
-
+
test_center = (start[0] + offsets[0] * factors[0], start[1] + offsets[1] * factors[1])
-
+
sqdist_start = sq_distance(start, test_center)
sqdist_end = sq_distance(end, test_center)
-
+
if abs(sqdist_start - sqdist_end) < sqdist_diff_min:
center = test_center
sqdist_diff_min = abs(sqdist_start - sqdist_end)
-
+
return center
else:
return (start[0] + offsets[0], start[1] + offsets[1])