diff options
Diffstat (limited to 'gerbonara/gerber')
-rw-r--r-- | gerbonara/gerber/aperture_macros/expression.py | 2 | ||||
-rw-r--r-- | gerbonara/gerber/gerber_statements.py | 4 | ||||
-rw-r--r-- | gerbonara/gerber/graphic_objects.py | 19 | ||||
-rw-r--r-- | gerbonara/gerber/graphic_primitives.py | 6 | ||||
-rw-r--r-- | gerbonara/gerber/rs274x.py | 14 |
5 files changed, 31 insertions, 14 deletions
diff --git a/gerbonara/gerber/aperture_macros/expression.py b/gerbonara/gerber/aperture_macros/expression.py index 73a2a36..390b7b7 100644 --- a/gerbonara/gerber/aperture_macros/expression.py +++ b/gerbonara/gerber/aperture_macros/expression.py @@ -158,7 +158,7 @@ class OperatorExpression(Expression): op = {operator.add: '+', operator.sub: '-', - operator.mul: 'x', + operator.mul: 'X', operator.truediv: '/'} [self.op] return f'{lval}{op}{rval}' diff --git a/gerbonara/gerber/gerber_statements.py b/gerbonara/gerber/gerber_statements.py index 2bf909f..06aee7a 100644 --- a/gerbonara/gerber/gerber_statements.py +++ b/gerbonara/gerber/gerber_statements.py @@ -170,11 +170,11 @@ class SingleQuadrantModeStmt(InterpolationModeStmt): """ G75 single-quadrant arc interpolation mode statement """ code = 'G75' -class RegionStartStatement(InterpolationModeStmt): +class RegionStartStmt(InterpolationModeStmt): """ G36 Region Mode Start Statement. """ code = 'G36' -class RegionEndStatement(InterpolationModeStmt): +class RegionEndStmt(InterpolationModeStmt): """ G37 Region Mode End Statement. """ code = 'G37' diff --git a/gerbonara/gerber/graphic_objects.py b/gerbonara/gerber/graphic_objects.py index 9902dee..8ee8f57 100644 --- a/gerbonara/gerber/graphic_objects.py +++ b/gerbonara/gerber/graphic_objects.py @@ -34,9 +34,17 @@ class Flash(GerberObject): yield FlashStmt(self.x, self.y) class Region(GerberObject): - def __init__(self, outline=[], arc_centers=None, *, polarity_dark): - super().__init__(self, polarity_dark=polarity_dark) - self.poly = gp.ArcPoly() + def __init__(self, outline=None, arc_centers=None, *, polarity_dark): + super().__init__(polarity_dark=polarity_dark) + outline = [] if outline is None else outline + arc_centers = [] if arc_centers is None else arc_centers + self.poly = gp.ArcPoly(outline, arc_centers) + + def __len__(self): + return len(self.poly) + + def __bool__(self): + return bool(self.poly) def with_offset(self, dx, dy): return Region([ (x+dx, y+dy) for x, y in outline ], radii, polarity_dark=self.polarity_dark) @@ -46,7 +54,8 @@ class Region(GerberObject): self.poly.arc_centers = [ gp.rotate_point(x, y, angle, cx, cy) for x, y in self.poly.arc_centers ] def append(self, obj): - if not self.outline: + print('append', obj) + if not self.poly.outline: self.poly.outline.append(obj.p1) self.poly.outline.append(obj.p2) @@ -64,7 +73,7 @@ class Region(GerberObject): yield from gs.set_current_point(self.poly.outline[0]) - for point, arc_center in zip(self.poly.outline, self.poly.arc_centers): + for point, arc_center in zip(self.poly.outline[1:], self.poly.arc_centers): if arc_center is None: yield from gs.set_interpolation_mode(LinearModeStmt) yield InterpolateStmt(*point) diff --git a/gerbonara/gerber/graphic_primitives.py b/gerbonara/gerber/graphic_primitives.py index 4810066..c917365 100644 --- a/gerbonara/gerber/graphic_primitives.py +++ b/gerbonara/gerber/graphic_primitives.py @@ -82,6 +82,12 @@ class ArcPoly(GraphicPrimitive): for (x1, y1), (x2, y2), radius in self.segments: return + def __len__(self): + return len(self.outline) + + def __bool__(self): + return bool(len(self)) + @dataclass class Line(GraphicPrimitive): diff --git a/gerbonara/gerber/rs274x.py b/gerbonara/gerber/rs274x.py index 364cb43..8715497 100644 --- a/gerbonara/gerber/rs274x.py +++ b/gerbonara/gerber/rs274x.py @@ -297,12 +297,10 @@ class GraphicsState: if not relative: rx, ry = (a*x + b*y + self.image_offset[0]), (c*x + d*y + self.image_offset[1]) - print(f'map {x},{y} to {rx},{ry}') return rx, ry else: # Apply mirroring, scale and rotation, but do not apply offset rx, ry = (a*x + b*y), (c*x + d*y) - print(f'map {x},{y} to {rx},{ry}') return rx, ry def flash(self, x, y): @@ -344,7 +342,6 @@ class GraphicsState: flipped=(direction == 'cw'), aperture=(self.aperture if aperture else None), polarity_dark=self.polarity_dark) def update_point(self, x, y): - print(f'update_point {x=} {y=}') old_point = self.point if x is None: x = self.point[0] @@ -383,7 +380,7 @@ class GerberParser: STATEMENT_REGEXES = { 'unit_mode': r"MO(?P<unit>(MM|IN))", - 'interpolation_mode': r"(?P<code>G0?[123]|G74|G75)", + 'interpolation_mode': r"(?P<code>G0?[123]|G74|G75)$", 'coord': fr"(X(?P<x>{NUMBER}))?(Y(?P<y>{NUMBER}))?" \ fr"(I(?P<i>{NUMBER}))?(J(?P<j>{NUMBER}))?" \ fr"(?P<operation>D0?[123])$", @@ -472,6 +469,7 @@ class GerberParser: for name, le_regex in self.STATEMENT_REGEXES.items(): if (match := le_regex.match(line)): + print(f'match {name}') getattr(self, f'_parse_{name}')(match.groupdict()) line = line[match.end(0):] break @@ -526,8 +524,10 @@ class GerberParser: raise SyntaxError('Circular arc interpolation in multi-quadrant mode (G74) is not implemented.') if self.current_region is None: + print('D01 outside region') self.target.objects.append(self.graphics_state.interpolate(x, y, i, j)) else: + print(f'D01 inside region {id(self.current_region)} of length {len(self.current_region)}') self.current_region.append(self.graphics_state.interpolate(x, y, i, j)) else: @@ -540,7 +540,7 @@ class GerberParser: # Start a new region for every outline. As gerber has no concept of fill rules or winding numbers, # it does not make a graphical difference, and it makes the implementation slightly easier. self.target.objects.append(self.current_region) - self.current_region = gp.Region(polarity_dark=gp.polarity_dark) + self.current_region = go.Region(polarity_dark=self.graphics_state.polarity_dark) else: # D03 if self.current_region is None: @@ -673,13 +673,15 @@ class GerberParser: self.target.comments.append(match["comment"]) def _parse_region_start(self, _match): - self.current_region = gp.Region(polarity_dark=gp.polarity_dark) + self.current_region = go.Region(polarity_dark=self.graphics_state.polarity_dark) + print(f'Region start of {id(self.current_region)}') def _parse_region_end(self, _match): if self.current_region is None: raise SyntaxError('Region end command (G37) outside of region') if self.current_region: # ignore empty regions + print(f'Region end of {id(self.current_region)}') self.target.objects.append(self.current_region) self.current_region = None |