From 4c4ba0762b30fdd4633a6d2868c508184d681b7d Mon Sep 17 00:00:00 2001 From: Hiroshi Murayama Date: Mon, 9 Sep 2019 21:52:52 +0900 Subject: fix issue #2: single quadrant mode is supported --- gerberex/rs274x.py | 47 ++++++++++++++++++++----------- tests/data/ref_gerber_single_quadrant.gtl | 40 ++++++++++++++++++++++++++ tests/expects/RS2724x_single_quadrant.gtl | 35 +++++++++++++++++++++++ tests/test_rs274x.py | 7 +++++ 4 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 tests/data/ref_gerber_single_quadrant.gtl create mode 100644 tests/expects/RS2724x_single_quadrant.gtl diff --git a/gerberex/rs274x.py b/gerberex/rs274x.py index fae0b32..42ae17d 100644 --- a/gerberex/rs274x.py +++ b/gerberex/rs274x.py @@ -208,6 +208,7 @@ class GerberContext(FileSettings): 1, 0, 1, 1) + self.in_single_quadrant_mode = False self.op = None self.interpolation = self.IP_LINEAR self.direction = self.DIR_CLOCKWISE @@ -237,6 +238,9 @@ class GerberContext(FileSettings): elif isinstance(stmt, ADParamStmt) and not isinstance(stmt, AMParamStmtEx): stmt = ADParamStmtEx.from_stmt(stmt) return (self.TYPE_AD, [stmt]) + elif isinstance(stmt, QuadrantModeStmt): + self.in_single_quadrant_mode = stmt.mode == 'single-quadrant' + stmt.mode = 'multi-quadrant' elif isinstance(stmt, CoordStmt): self._normalize_coordinate(stmt) @@ -262,22 +266,23 @@ class GerberContext(FileSettings): self.scale[1] * mx, self.scale[0] * my) def _normalize_coordinate(self, stmt): + if stmt.function == 'G01' or stmt.function == 'G1': + self.interpolation = self.IP_LINEAR + elif stmt.function == 'G02' or stmt.function == 'G2': + self.interpolation = self.IP_ARC + self.direction = self.DIR_CLOCKWISE + if self.mirror[0] != self.mirror[1]: + stmt.function = 'G03' + elif stmt.function == 'G03' or stmt.function == 'G3': + self.interpolation = self.IP_ARC + self.direction = self.DIR_COUNTERCLOCKWISE + if self.mirror[0] != self.mirror[1]: + stmt.function = 'G02' if stmt.only_function: - if stmt.function == 'G01' or stmt.function == 'G1': - self.interpolation = self.IP_LINEAR - elif stmt.function == 'G02' or stmt.function == 'G2': - self.interpolation = self.IP_ARC - self.direction = self.DIR_CLOCKWISE - if self.mirror[0] != self.mirror[1]: - self.direction = self.DIR_COUNTERCLOCKWISE - stmt.function = 'G03' - elif stmt.function == 'G03' or stmt.function == 'G3': - self.interpolation = self.IP_ARC - self.direction = self.DIR_COUNTERCLOCKWISE - if self.mirror[0] != self.mirror[1]: - self.direction = self.DIR_CLOCKWISE - stmt.function = 'G02' return + + last_x = self.x + last_y = self.y if self.notation == 'absolute': x = stmt.x if stmt.x is not None else self.x y = stmt.y if stmt.y is not None else self.y @@ -291,5 +296,15 @@ class GerberContext(FileSettings): stmt.x = self.matrix[0] * x + self.matrix[1] stmt.y = self.matrix[2] * y + self.matrix[3] if stmt.op == 'D01' and self.interpolation == self.IP_ARC: - stmt.i = self.matrix[4] * stmt.i if stmt.i is not None else 0 - stmt.j = self.matrix[5] * stmt.j if stmt.j is not None else 0 + qx, qy = 1, 1 + if self.in_single_quadrant_mode: + if self.direction == self.DIR_CLOCKWISE: + qx = 1 if y > last_y else -1 + qy = 1 if x < last_x else -1 + else: + qx = 1 if y < last_y else -1 + qy = 1 if x > last_x else -1 + if last_x == x and last_y == y: + qx, qy = 0, 0 + stmt.i = qx * self.matrix[4] * stmt.i if stmt.i is not None else 0 + stmt.j = qy * self.matrix[5] * stmt.j if stmt.j is not None else 0 diff --git a/tests/data/ref_gerber_single_quadrant.gtl b/tests/data/ref_gerber_single_quadrant.gtl new file mode 100644 index 0000000..f31f1e7 --- /dev/null +++ b/tests/data/ref_gerber_single_quadrant.gtl @@ -0,0 +1,40 @@ +%MOMM*% +%FSLAX34Y34*% +%IPPOS*% +%ADD10C,0.1*% +G74* +%LPD*% + +D10* + +G36* +G01* +X0Y10000D02* +Y90000D01* +G02* +X10000Y100000I10000* +X20000Y90000J10000* +G01* +Y20000* +X40000* +G02* +X50000Y10000J10000* +X40000Y0I10000* +G01* +X10000* +G02* +X0Y10000J10000* +G37* + +G03* +X70000Y50000D02* +X60000Y60000I10000D01* +X50000Y50000J10000* +X60000Y40000I10000* +X70000Y50000J10000* + +G02* +X60000Y90000D02* +X60000Y90000I10000D01* + +M02* diff --git a/tests/expects/RS2724x_single_quadrant.gtl b/tests/expects/RS2724x_single_quadrant.gtl new file mode 100644 index 0000000..dbec705 --- /dev/null +++ b/tests/expects/RS2724x_single_quadrant.gtl @@ -0,0 +1,35 @@ +%MOMM*% +%FSLAX34Y34*% +%IPPOS*% +%ADD10C,0.1*% +G75* +%LPD*% +D10* +G36* +G01* +X0Y10000D02* +X0Y90000D01* +G02* +X10000Y100000I10000J0D01* +X20000Y90000I0J-10000D01* +G01* +X20000Y20000D01* +X40000Y20000D01* +G02* +X50000Y10000I0J-10000D01* +X40000Y0I-10000J0D01* +G01* +X10000Y0D01* +G02* +X0Y10000I0J10000D01* +G37* +G03* +X70000Y50000D02* +X60000Y60000I-10000J0D01* +X50000Y50000I0J-10000D01* +X60000Y40000I10000J0D01* +X70000Y50000I0J10000D01* +G02* +X60000Y90000D02* +X60000Y90000I0J0D01* +M02* diff --git a/tests/test_rs274x.py b/tests/test_rs274x.py index 3e44066..dbb5f62 100644 --- a/tests/test_rs274x.py +++ b/tests/test_rs274x.py @@ -17,6 +17,7 @@ class TestRs274x(unittest.TestCase): cls.OUTPREFIX = 'RS2724x_' cls.METRIC_FILE = os.path.join(cls.INDIR, 'ref_gerber_metric.gtl') cls.INCH_FILE = os.path.join(cls.INDIR, 'ref_gerber_inch.gtl') + cls.SQ_FILE = os.path.join(cls.INDIR, 'ref_gerber_single_quadrant.gtl') try: os.mkdir(cls.OUTDIR) except FileExistsError: @@ -65,5 +66,11 @@ class TestRs274x(unittest.TestCase): gerber.write(outfile) self._checkResult(outfile) + def test_single_quadrant(self): + outfile = os.path.join(self.OUTDIR, self.OUTPREFIX + 'single_quadrant.gtl') + gerber = gerberex.read(self.SQ_FILE) + gerber.write(outfile) + self._checkResult(outfile) + if __name__ == '__main__': unittest.main() -- cgit