summaryrefslogtreecommitdiff
path: root/gerbonara/layers.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerbonara/layers.py')
-rw-r--r--gerbonara/layers.py43
1 files changed, 20 insertions, 23 deletions
diff --git a/gerbonara/layers.py b/gerbonara/layers.py
index e200e62..f98adee 100644
--- a/gerbonara/layers.py
+++ b/gerbonara/layers.py
@@ -39,6 +39,7 @@ from .cam import FileSettings, LazyCamFile
from .layer_rules import MATCH_RULES
from .utils import sum_bounds, setup_svg, MM, Tag, convex_hull
from . import graphic_objects as go
+from . import apertures as ap
from . import graphic_primitives as gp
@@ -273,7 +274,7 @@ def _layername_autoguesser(fn):
elif re.search('film', fn):
use = 'copper'
- elif re.search('out(line)?|board.?geometry', fn):
+ elif re.search('out(line)?|board.?geom(etry)?', fn):
use = 'outline'
side = 'mechanical'
@@ -303,6 +304,9 @@ def _sort_layername(val):
assert side.startswith('inner_')
return int(side[len('inner_'):])
+def convex_hull_to_lines(points, unit=MM):
+ for (x1, y1), (x2, y2) in zip(points, points[1:] + points):
+ yield go.Line(x1, y1, x2, y2, aperture=ap.CircleAperture(unit(0.1, MM), unit=unit), unit=unit)
class LayerStack:
""" :py:class:`LayerStack` represents a set of Gerber files that describe different layers of the same board.
@@ -949,7 +953,7 @@ class LayerStack:
id=f'l-mechanical-outline', **stroke_attrs, **inkscape_attrs(f'outline'),
transform=layer_transform))
- sc_y, tl_y = -1, (bounds[0][1] + bounds[1][1])
+ sc_y, tl_y = 1, 0
if side == 'bottom':
sc_x, tl_x = -1, (bounds[0][0] + bounds[1][0])
else:
@@ -1184,22 +1188,6 @@ class LayerStack:
polys.append(' '.join(poly.path_d()) + ' Z')
return ' '.join(polys)
- def outline_convex_hull(self, tol=0.01, unit=MM):
- points = []
- for obj in self.outline.instance.objects:
- if isinstance(obj, go.Line):
- line = obj.as_primitive(unit)
- points.append((line.x1, line.y1))
- points.append((line.x2, line.y2))
-
- elif isinstance(obj, go.Arc):
- for obj in obj.approximate(tol, unit):
- line = obj.as_primitive(unit)
- points.append((line.x1, line.y1))
- points.append((line.x2, line.y2))
-
- return convex_hull(points)
-
def outline_polygons(self, tol=0.01, unit=MM):
""" Iterator yielding this boards outline as a list of ordered :py:class:`~.graphic_objects.Arc` and
:py:class:`~.graphic_objects.Line` objects. This method first sorts all lines and arcs on the outline layer into
@@ -1214,6 +1202,14 @@ class LayerStack:
:param tol: :py:obj:`float` setting the tolerance below which two points are considered equal
:param unit: :py:class:`.LengthUnit` or str (``'mm'`` or ``'inch'``). SVG document unit. Default: mm
"""
+
+ if not self.outline:
+ warnings.warn("Board has no outline layer, or the outline layer could not be identified by file name. Using the copper layers' convex hull instead.")
+ points = sum((layer.instance.convex_hull(tol, unit) for (_side, _use), layer in self.copper_layers), start=[])
+ yield list(convex_hull_to_lines(convex_hull(points), unit))
+ return
+
+ maybe_allegro_hint = '' if self.generator != 'allegro' else ' This file looks like it was generated by Allegro/OrCAD. These tools produce quite mal-formed gerbers, and often export text on the outline layer. If you generated this file yourself, maybe try twiddling with the export settings.'
polygons = []
lines = [ obj.as_primitive(unit) for obj in self.outline.instance.objects if isinstance(obj, (go.Line, go.Arc)) ]
@@ -1242,13 +1238,14 @@ class LayerStack:
j = 0 if d1 < d2 else 1
if (nearest, j) in joins and joins[(nearest, j)] != (cur, i):
- warnings.warn(f'Three-way intersection on outline layer at: {(nearest, j)}; {(cur, i)}; and {joins[(nearest, j)]}. Falling back to returning the convex hull of the outline layer.')
- return self.outline_convex_hull(tol, unit)
+ warnings.warn(f'Three-way intersection on outline layer at: {(nearest, j)}; {(cur, i)}; and {joins[(nearest, j)]}. Falling back to returning the convex hull of the outline layer.{maybe_allegro_hint}')
+ yield list(convex_hull_to_lines(self.outline.instance.convex_hull(tol, unit), unit))
+ return
if (cur, i) in joins and joins[(cur, i)] != (nearest, j):
- warnings.warn(f'three-way intersection on outline layer at: {(nearest, j)}; {(cur, i)}; and {joins[(nearest, j)]}. Falling back to returning the convex hull of the outline layer.')
- return self.outline_convex_hull(tol, unit)
-
+ warnings.warn(f'Three-way intersection on outline layer at: {(nearest, j)}; {(cur, i)}; and {joins[(nearest, j)]}. Falling back to returning the convex hull of the outline layer.{maybe_allegro_hint}')
+ yield list(convex_hull_to_lines(self.outline.instance.convex_hull(tol, unit), unit))
+ return
joins[(cur, i)] = (nearest, j)
joins[(nearest, j)] = (cur, i)