From 263617ca754fc7b3fc550a33934fcbcbe5ef8acf Mon Sep 17 00:00:00 2001 From: jaseg Date: Sun, 6 Feb 2022 01:10:17 +0100 Subject: Add Zuken tests and fix parsing --- .../zuken-emulated/scripts/drill_log_sample | 74 ++++++++++++++++++++++ .../resources/zuken-emulated/scripts/prepare.sh | 18 ++++++ .../zuken-emulated/scripts/zukenka_excellon.py | 68 ++++++++++++++++++++ .../zuken-emulated/scripts/zukenka_gerber.py | 49 ++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 gerbonara/tests/resources/zuken-emulated/scripts/drill_log_sample create mode 100644 gerbonara/tests/resources/zuken-emulated/scripts/prepare.sh create mode 100644 gerbonara/tests/resources/zuken-emulated/scripts/zukenka_excellon.py create mode 100644 gerbonara/tests/resources/zuken-emulated/scripts/zukenka_gerber.py (limited to 'gerbonara/tests/resources/zuken-emulated/scripts') diff --git a/gerbonara/tests/resources/zuken-emulated/scripts/drill_log_sample b/gerbonara/tests/resources/zuken-emulated/scripts/drill_log_sample new file mode 100644 index 0000000..2b6494c --- /dev/null +++ b/gerbonara/tests/resources/zuken-emulated/scripts/drill_log_sample @@ -0,0 +1,74 @@ + ************************ + ***** DRILL LIST ***** + ************************ + + Date : Sat Feb 05 23:42:05 2022 + Host : Windows_Hostname + User : Windows_User + Output Data : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdr + Output List : C:/TEMP/Not_Actual_Path/DF_Drill_thru_plt.fdl + + Target File : C:/TEMP/Not_Actual_Path/routed.dsgn + From-To : Only through + Object : Round hole + : Slot hole + : Rectangular hole + : Hole in padstack (Round hole) + : Hole in padstack (Slot hole) + : Hole in padstack (Rectangular hole) + Slot Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off) + Rectangular Hole : Alternately from both ends(Migration rate: 0.50000/Odd number: Off) + Diameter/Hole Type : All + Plating Attribute : Plated + Embedded Comp. Via : Do not output + + Reference Point : 0.00000, 0.00000 [mm] + Mirror : Off + Rotate : 0-degree (No rotation) + Scale : 1.00000 + Offset : 0.00000, 0.00000 [mm] + + Toolpath Sorting : N sort + Test Coupon : Timing: 0 / Number of outputs: 1 + + + NCF File : C:/Project_Path/settings/ncf/Excellon2.ncf + NCF Comment : EXCELLON2 FORMAT + Data Type : Excellon2 Type + Character Code : ASCII + EOB Code : LF + EOR Code : SPACE + + Unit : inch + Coordinate Format : 4V4 + Round Unit : 0.00010 + Inc. / Abs. : Absolute + Zero Suppress : Trailing Zero Suppress + Omitting Coordinates : Omit + Zero Return : During Tool Changing: Do not make + + + Assign Code : Auto + Distinguish Tools : Hole type: Off + : Round hole and slot hole(rectangular hole): On + : Plating attribute: Off + : Embedded component via attribute: On + + Tool Table : +============================================================================================ +| No. | Hole | Code | Tool | Diameter | | Corner | Angle | Hole | Plating | +| | Shape | | Shape | Width | Height | Radius | | Type | Attribute | +|-----+-------+------+-------+----------+--------+--------+--------+-----------+-----------| +| 1 | Round | T01 | Round | 0.1000 | ------ | ------ | ------ | Undefined | Plated | +============================================================================================ + + Tool Count : +====================================================================== +| No. | Code | Hit | Test Coupon | Inspection | Moved Dis. | +|-------+------+-------------+-------------+------------+------------| +| 1 | T01 | 100 | 0 | 0 | 1234.56789 | +|-------+------+-------------+-------------+------------+------------| +| Total | 100 | 0 | 0 | 1234.56789 | +====================================================================== + + Data Area : min = ( 1.00000, 1.00000 ), max = ( 101.00000, 101.00000 ) diff --git a/gerbonara/tests/resources/zuken-emulated/scripts/prepare.sh b/gerbonara/tests/resources/zuken-emulated/scripts/prepare.sh new file mode 100644 index 0000000..45b56b7 --- /dev/null +++ b/gerbonara/tests/resources/zuken-emulated/scripts/prepare.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +python3 scripts/zukenka_gerber.py < orig/driver-B_Cu > Gerber/Conductive-2.fph +python3 scripts/zukenka_gerber.py < orig/driver-B_Mask > Gerber/Resist-B.fph +python3 scripts/zukenka_gerber.py < orig/driver-B_Paste > Gerber/MetalMask-B.fph +python3 scripts/zukenka_gerber.py < orig/driver-B_SilkS > Gerber/Symbol-B.fph +python3 scripts/zukenka_gerber.py < orig/driver-F_Cu > Gerber/Conductive-1.fph +python3 scripts/zukenka_gerber.py < orig/driver-F_Mask > Gerber/Resist-A.fph +python3 scripts/zukenka_gerber.py < orig/driver-F_Paste > Gerber/MetalMask-A.fph +python3 scripts/zukenka_gerber.py < orig/driver-F_SilkS > Gerber/Symbol-A.fph + +python3 scripts/zukenka_excellon.py < orig/driver-NPTH > Drill/8seg_Driver__routed_Drill_thru_nplt.fdr +mkdir -p Drill/8seg_Driver__routed_Drill_thru_plt.fdr +python3 scripts/zukenka_excellon.py < orig/driver-PTH > Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdr + +cp scripts/drill_log_sample Drill/8seg_Driver__routed_Drill_thru_plt.fdr/8seg_Driver__routed_Drill_thru_plt.fdl +cp scripts/drill_log_sample Drill/8seg_Driver__routed_Drill_thru_nplt.fdl + diff --git a/gerbonara/tests/resources/zuken-emulated/scripts/zukenka_excellon.py b/gerbonara/tests/resources/zuken-emulated/scripts/zukenka_excellon.py new file mode 100644 index 0000000..b00fb2c --- /dev/null +++ b/gerbonara/tests/resources/zuken-emulated/scripts/zukenka_excellon.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# +# Mess up an Excellon file to look like it was generated by Zuken CR-8000. +# Only meant to work with KiCAD Excellon files. +# + +import re + +class Mapper: + def __init__(self): + self.g05_found = False + + def map_line(self, line): + # Remove comments + if line[0] == ';': + return '' + + # Drop G90 + if line == 'G90': + return '' + + # Drop first G05 + if line == 'G05' and not self.g05_found: + self.g05_found = True + return '' + + # Strip FMAT line (we need to put it in further down) + if line == 'FMAT,2': + return '' + + # Replace unit line with new header + if line in ('METRIC', 'INCH'): + return f'{line},LZ\nICI,OFF\nVER,1\nFMAT,2\nDETECT,ON\nATC,ON\n' + + # Add non-functional M06 to all tool uses after T01 with + if re.fullmatch(r'T[0-9]*', line): + + # Pad tool indices to two digits + if len(line) == 2: + line = f'{line[0]}0{line[1]}' + + return f'M06\n{line}\n' + + # Remove trailing non-functional T0 + if line == 'T0': + return '' + + # Replace M30 EOF with M00 EOF + if line == 'M30': + return 'M00\n' + + # Convert coordinates into fixed-width 4.4 format + if (m := re.fullmatch(r'X([-0-9.]*)Y([-0-9.]*)', line)): + x, y = float(m[1]), float(m[2]) + # sign, four digits, point, four digits = 10 digits + x, y = f'{x: 010.4f}', f'{y: 010.4f}' + x, y = x.strip().replace('.', ''), y.strip().replace('.', '') + return f'X{x}Y{y}\n' + + return f'{line}\n' + +def zukenka(data): + m = Mapper() + return ''.join(m.map_line(line) for line in data.splitlines()) + +if __name__ == '__main__': + import sys + print(zukenka(sys.stdin.read())) diff --git a/gerbonara/tests/resources/zuken-emulated/scripts/zukenka_gerber.py b/gerbonara/tests/resources/zuken-emulated/scripts/zukenka_gerber.py new file mode 100644 index 0000000..b3f9f51 --- /dev/null +++ b/gerbonara/tests/resources/zuken-emulated/scripts/zukenka_gerber.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# +# Mess up a Gerber file to look like it was generated by Zuken CR-8000. +# Only meant to work with KiCAD Gerber files. +# + +import re + +def map_line(line): + # strip layer polarity statement at start of header + if line == '%LPD*%': + return '' + + # Replace end of aperture list comment with empty line and layer polarity statement + if line == 'G04 APERTURE END LIST*': + return '\n%LPD*%\n' # this is the last newline in this file + + # strip comments + if line.startswith('G04'): + return '' + + # add G54 prefix to aperture selection statements + if re.fullmatch(r'D[1-9][0-9]\*', line): + return f'G54{line}' + + # make flash statements more complicated + if (m := re.fullmatch(r'(.*)D03\*', line)): + return f'{m[1]}D02*G55D03*' + + # replace M02 EOF with M00 EOF, and insert X0Y0D02 + if line == 'M02*': + return 'X0Y0D02*M00*' + + # Merge G01/02/03 with following coordinate + if line in ('G01*', 'G02*', 'G03*'): + return line[:-1] + + # Preserve line endings for header lines + if any(line.startswith(cmd) for cmd in ('%FS', '%MO', '%AD')): + return f'{line}\n' + + return line + +def zukenka(data): + return ''.join(map_line(line) for line in data.splitlines()) + +if __name__ == '__main__': + import sys + print(zukenka(sys.stdin.read())) -- cgit