diff --git a/CHANGELOG.md b/CHANGELOG.md index 1af5a80e..96d5e9a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - The KiBoM and internal BoM generators now support configuring the separator used for the list of references. +- Support for new `pcbnew_do export` options. ## [0.7.0] - 2020-09-11 ### Added diff --git a/Makefile b/Makefile index 67595c10..b3b726fe 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ #!/usr/bin/make PY_COV=python3-coverage PYTEST=pytest-3 -REFDIR=tests/reference/ +REFDIR=tests/reference/5_1_7/ REFILL=tests/board_samples/zone-refill.kicad_pcb CWD := $(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))) USER_ID=$(shell id -u) @@ -103,6 +103,7 @@ deb_clean: gen_ref: # Reference outputs, must be manually inspected if regenerated + pcbnew_do export --output_name bom-F_Cu+F_SilkS.pdf --scaling 4 --pads 0 --no-title --monochrome --separate tests/board_samples/bom.kicad_pcb $(REFDIR) F.Cu F.SilkS cp -a $(REFILL).refill $(REFILL) src/kibot -c tests/yaml_samples/pdf_zone-refill.kibot.yaml -b tests/board_samples/zone-refill.kicad_pcb -d $(REFDIR) src/kibot -c tests/yaml_samples/print_pcb_zone-refill.kibot.yaml -b tests/board_samples/zone-refill.kicad_pcb -d $(REFDIR) diff --git a/README.md b/README.md index 1d6084c7..c4543704 100644 --- a/README.md +++ b/README.md @@ -996,8 +996,13 @@ Next time you need this list just use an alias, like this: * Valid keys: - `dnf_filter`: [string|list(string)=''] Name of the filter to mark components as not fitted. A short-cut to use for simple cases where a variant is an overkill. + - `drill_marks`: [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale). + - `monochrome`: [boolean=false] print in black and white. - `output`: [string='%f-%i%v.%x'] filename for the output PDF (%i=layers, %x=pdf). Affected by global options. - *output_name*: Alias for output. + - `plot_sheet_reference`: [boolean=true] include the title-block. + - `scaling`: [number=1.0] scale factor (0 means autoscaling). + - `separated`: [boolean=false] print layers in separated pages. - `variant`: [string=''] Board variant to apply. * PDF Schematic Print (Portable Document Format) diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 3b85aa34..2d570300 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -655,9 +655,19 @@ outputs: # [string|list(string)=''] Name of the filter to mark components as not fitted. # A short-cut to use for simple cases where a variant is an overkill dnf_filter: '' + # [string='full'] what to use to indicate the drill places, can be none, small or full (for real scale) + drill_marks: 'full' + # [boolean=false] print in black and white + monochrome: false # [string='%f-%i%v.%x'] filename for the output PDF (%i=layers, %x=pdf). Affected by global options output: '%f-%i%v.%x' # `output_name` is an alias for `output` + # [boolean=true] include the title-block + plot_sheet_reference: true + # [number=1.0] scale factor (0 means autoscaling) + scaling: 1.0 + # [boolean=false] print layers in separated pages + separated: false # [string=''] Board variant to apply variant: '' layers: all diff --git a/kibot/out_pdf_pcb_print.py b/kibot/out_pdf_pcb_print.py index 5d456249..e0a3f5f6 100644 --- a/kibot/out_pdf_pcb_print.py +++ b/kibot/out_pdf_pcb_print.py @@ -19,14 +19,41 @@ logger = log.get_logger(__name__) class PDF_Pcb_PrintOptions(VariantOptions): + # Mappings to KiCad config values. They should be the same used in drill_marks.py + _drill_marks_map = {'none': 0, 'small': 1, 'full': 2} + def __init__(self): with document: self.output = GS.def_global_output """ filename for the output PDF (%i=layers, %x=pdf)""" self.output_name = None """ {output} """ + self.scaling = 1.0 + """ scale factor (0 means autoscaling)""" + self._drill_marks = 'full' + """ what to use to indicate the drill places, can be none, small or full (for real scale) """ + self.plot_sheet_reference = True + """ include the title-block """ + self.monochrome = False + """ print in black and white """ + self.separated = False + """ print layers in separated pages """ super().__init__() + @property + def drill_marks(self): + return self._drill_marks + + @drill_marks.setter + def drill_marks(self, val): + if val not in self._drill_marks_map: + raise KiPlotConfigurationError("Unknown drill mark type: {}".format(val)) + self._drill_marks = val + + def config(self): + super().config() + self._drill_marks = PDF_Pcb_PrintOptions._drill_marks_map[self._drill_marks] + def filter_components(self, board): if not self._comps: return GS.pcb_file @@ -44,7 +71,7 @@ class PDF_Pcb_PrintOptions(VariantOptions): def run(self, output_dir, board, layers): super().run(board, layers) - check_script(CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, '1.4.1') + check_script(CMD_PCBNEW_PRINT_LAYERS, URL_PCBNEW_PRINT_LAYERS, '1.5.1') layers = Layer.solve(layers) # Output file name id = '+'.join([la.suffix for la in layers]) @@ -52,6 +79,13 @@ class PDF_Pcb_PrintOptions(VariantOptions): cmd = [CMD_PCBNEW_PRINT_LAYERS, 'export', '--output_name', output] if BasePreFlight.get_option('check_zone_fills'): cmd.append('-f') + cmd.extend(['--scaling', str(self.scaling), '--pads', str(self._drill_marks)]) + if not self.plot_sheet_reference: + cmd.append('--no-title') + if self.monochrome: + cmd.append('--monochrome') + if self.separated: + cmd.append('--separate') board_name = self.filter_components(board) cmd.extend([board_name, output_dir]) if GS.debug_enabled: diff --git a/tests/reference/PCB_Bot.pdf b/tests/reference/5_1_6/PCB_Bot.pdf similarity index 100% rename from tests/reference/PCB_Bot.pdf rename to tests/reference/5_1_6/PCB_Bot.pdf diff --git a/tests/reference/5_1_6/bom-F_Cu+F_SilkS.pdf b/tests/reference/5_1_6/bom-F_Cu+F_SilkS.pdf new file mode 100644 index 00000000..c2f234b1 Binary files /dev/null and b/tests/reference/5_1_6/bom-F_Cu+F_SilkS.pdf differ diff --git a/tests/reference/kibom-variant_3-F_Fab.pdf b/tests/reference/5_1_6/kibom-variant_3-F_Fab.pdf similarity index 100% rename from tests/reference/kibom-variant_3-F_Fab.pdf rename to tests/reference/5_1_6/kibom-variant_3-F_Fab.pdf diff --git a/tests/reference/kibom-variant_3-top-C1.png b/tests/reference/5_1_6/kibom-variant_3-top-C1.png similarity index 100% rename from tests/reference/kibom-variant_3-top-C1.png rename to tests/reference/5_1_6/kibom-variant_3-top-C1.png diff --git a/tests/reference/kibom-variant_3-top.png b/tests/reference/5_1_6/kibom-variant_3-top.png similarity index 100% rename from tests/reference/kibom-variant_3-top.png rename to tests/reference/5_1_6/kibom-variant_3-top.png diff --git a/tests/reference/kibom-variant_4-B_Fab.pdf b/tests/reference/5_1_6/kibom-variant_4-B_Fab.pdf similarity index 100% rename from tests/reference/kibom-variant_4-B_Fab.pdf rename to tests/reference/5_1_6/kibom-variant_4-B_Fab.pdf diff --git a/tests/reference/kibom-variant_4-F_Fab.pdf b/tests/reference/5_1_6/kibom-variant_4-F_Fab.pdf similarity index 100% rename from tests/reference/kibom-variant_4-F_Fab.pdf rename to tests/reference/5_1_6/kibom-variant_4-F_Fab.pdf diff --git a/tests/reference/5_1_6/pcbnew_export_screencast.ogv b/tests/reference/5_1_6/pcbnew_export_screencast.ogv new file mode 100644 index 00000000..8b8cef7a Binary files /dev/null and b/tests/reference/5_1_6/pcbnew_export_screencast.ogv differ diff --git a/tests/reference/test_v5-schematic_(no_L).pdf b/tests/reference/5_1_6/test_v5-schematic_(no_L).pdf similarity index 100% rename from tests/reference/test_v5-schematic_(no_L).pdf rename to tests/reference/5_1_6/test_v5-schematic_(no_L).pdf diff --git a/tests/reference/test_v5-schematic_(no_L).svg b/tests/reference/5_1_6/test_v5-schematic_(no_L).svg similarity index 100% rename from tests/reference/test_v5-schematic_(no_L).svg rename to tests/reference/5_1_6/test_v5-schematic_(no_L).svg diff --git a/tests/reference/zone-refill-B_Cu.pdf b/tests/reference/5_1_6/zone-refill-B_Cu.pdf similarity index 100% rename from tests/reference/zone-refill-B_Cu.pdf rename to tests/reference/5_1_6/zone-refill-B_Cu.pdf diff --git a/tests/reference/5_1_7/PCB_Bot.pdf b/tests/reference/5_1_7/PCB_Bot.pdf new file mode 100644 index 00000000..4e8fa80f Binary files /dev/null and b/tests/reference/5_1_7/PCB_Bot.pdf differ diff --git a/tests/reference/5_1_7/bom-F_Cu+F_SilkS.pdf b/tests/reference/5_1_7/bom-F_Cu+F_SilkS.pdf new file mode 120000 index 00000000..b13e9f94 --- /dev/null +++ b/tests/reference/5_1_7/bom-F_Cu+F_SilkS.pdf @@ -0,0 +1 @@ +../5_1_6/bom-F_Cu+F_SilkS.pdf \ No newline at end of file diff --git a/tests/reference/5_1_7/kibom-variant_3-F_Fab.pdf b/tests/reference/5_1_7/kibom-variant_3-F_Fab.pdf new file mode 100644 index 00000000..5bb6c9c2 Binary files /dev/null and b/tests/reference/5_1_7/kibom-variant_3-F_Fab.pdf differ diff --git a/tests/reference/5_1_7/kibom-variant_3-top-C1.png b/tests/reference/5_1_7/kibom-variant_3-top-C1.png new file mode 120000 index 00000000..2cab1845 --- /dev/null +++ b/tests/reference/5_1_7/kibom-variant_3-top-C1.png @@ -0,0 +1 @@ +../5_1_6/kibom-variant_3-top-C1.png \ No newline at end of file diff --git a/tests/reference/5_1_7/kibom-variant_3-top.png b/tests/reference/5_1_7/kibom-variant_3-top.png new file mode 120000 index 00000000..f63c343c --- /dev/null +++ b/tests/reference/5_1_7/kibom-variant_3-top.png @@ -0,0 +1 @@ +../5_1_6/kibom-variant_3-top.png \ No newline at end of file diff --git a/tests/reference/5_1_7/kibom-variant_4-B_Fab.pdf b/tests/reference/5_1_7/kibom-variant_4-B_Fab.pdf new file mode 120000 index 00000000..50f3bf6d --- /dev/null +++ b/tests/reference/5_1_7/kibom-variant_4-B_Fab.pdf @@ -0,0 +1 @@ +../5_1_6/kibom-variant_4-B_Fab.pdf \ No newline at end of file diff --git a/tests/reference/5_1_7/kibom-variant_4-F_Fab.pdf b/tests/reference/5_1_7/kibom-variant_4-F_Fab.pdf new file mode 120000 index 00000000..a38467fb --- /dev/null +++ b/tests/reference/5_1_7/kibom-variant_4-F_Fab.pdf @@ -0,0 +1 @@ +../5_1_6/kibom-variant_4-F_Fab.pdf \ No newline at end of file diff --git a/tests/reference/5_1_7/test_v5-schematic_(no_L).pdf b/tests/reference/5_1_7/test_v5-schematic_(no_L).pdf new file mode 120000 index 00000000..f148f72d --- /dev/null +++ b/tests/reference/5_1_7/test_v5-schematic_(no_L).pdf @@ -0,0 +1 @@ +../5_1_6/test_v5-schematic_(no_L).pdf \ No newline at end of file diff --git a/tests/reference/5_1_7/test_v5-schematic_(no_L).svg b/tests/reference/5_1_7/test_v5-schematic_(no_L).svg new file mode 120000 index 00000000..d5a7ee72 --- /dev/null +++ b/tests/reference/5_1_7/test_v5-schematic_(no_L).svg @@ -0,0 +1 @@ +../5_1_6/test_v5-schematic_(no_L).svg \ No newline at end of file diff --git a/tests/reference/5_1_7/zone-refill-B_Cu.pdf b/tests/reference/5_1_7/zone-refill-B_Cu.pdf new file mode 120000 index 00000000..d7b8c911 --- /dev/null +++ b/tests/reference/5_1_7/zone-refill-B_Cu.pdf @@ -0,0 +1 @@ +../5_1_6/zone-refill-B_Cu.pdf \ No newline at end of file diff --git a/tests/test_plot/test_print_pcb.py b/tests/test_plot/test_print_pcb.py index 71655ed0..b68a4d71 100644 --- a/tests/test_plot/test_print_pcb.py +++ b/tests/test_plot/test_print_pcb.py @@ -25,7 +25,7 @@ PDF_FILE_B = 'PCB_Bot.pdf' def test_print_pcb_simple(): prj = 'bom' - ctx = context.TestContext('PrPCB', prj, 'print_pcb', PDF_DIR) + ctx = context.TestContext('print_pcb_simple', prj, 'print_pcb', PDF_DIR) ctx.run() # Check all outputs are there ctx.expect_out_file(os.path.join(PDF_DIR, PDF_FILE)) @@ -34,19 +34,29 @@ def test_print_pcb_simple(): def test_print_pcb_refill(): prj = 'zone-refill' - ctx = context.TestContext('PrPCB_Refill', prj, 'print_pcb_zone-refill', '') + ctx = context.TestContext('print_pcb_refill', prj, 'print_pcb_zone-refill', '') ctx.run() - ctx.expect_out_file(PDF_FILE_B) ctx.compare_image(PDF_FILE_B) + ctx.clean_up() def test_print_variant_1(): prj = 'kibom-variant_3' - ctx = context.TestContext('test_print_variant_1', prj, 'print_pcb_variant_1', '') + ctx = context.TestContext('print_variant_1', prj, 'print_pcb_variant_1', '') ctx.run() # Check all outputs are there fname = prj+'-F_Fab.pdf' ctx.expect_out_file(fname) ctx.compare_pdf(fname) ctx.clean_up() + + +def test_print_pcb_options(): + prj = 'bom' + ctx = context.TestContext('print_pcb_options', prj, 'print_pcb_options', PDF_DIR) + ctx.run() + # Check all outputs are there + ctx.expect_out_file(PDF_FILE) + ctx.compare_pdf(PDF_FILE) + ctx.clean_up() diff --git a/tests/utils/context.py b/tests/utils/context.py index ffd5e550..084dc044 100644 --- a/tests/utils/context.py +++ b/tests/utils/context.py @@ -1,4 +1,5 @@ import os +import sys import shutil import tempfile import logging @@ -13,9 +14,9 @@ import xml.etree.ElementTree as ET COVERAGE_SCRIPT = 'python3-coverage' KICAD_PCB_EXT = '.kicad_pcb' KICAD_SCH_EXT = '.sch' -REF_DIR = 'tests/reference' BOARDS_DIR = 'tests/board_samples' - +KICAD_VERSION_5_99 = 5099000 +KICAD_VERSION_5_1_7 = 5001007 MODE_SCH = 1 MODE_PCB = 0 @@ -24,9 +25,32 @@ def quote(s): return '"'+s+'"' +def usable_cmd(cmd): + return ' '.join(cmd) + + class TestContext(object): def __init__(self, test_name, board_name, yaml_name, sub_dir, yaml_compressed=False): + ng_ver = os.environ.get('KIAUS_USE_NIGHTLY') + if ng_ver: + # Path to the Python module + sys.path.insert(0, '/usr/lib/kicad-nightly/lib/python3/dist-packages') + self.kicad_cfg_dir = os.path.join(os.environ['HOME'], '.config/kicadnightly/'+ng_ver) + else: + self.kicad_cfg_dir = os.path.join(os.environ['HOME'], '.config/kicad') + import pcbnew + # Detect version + m = re.match(r'(\d+)\.(\d+)\.(\d+)', pcbnew.GetBuildVersion()) + major = int(m.group(1)) + minor = int(m.group(2)) + patch = int(m.group(3)) + self.kicad_version = major*1000000+minor*1000+patch + logging.debug('Detected KiCad v{}.{}.{} ({})'.format(major, minor, patch, self.kicad_version)) + if self.kicad_version == KICAD_VERSION_5_1_7: + self.ref_dir = 'tests/reference/5_1_7' + else: + self.ref_dir = 'tests/reference/5_1_6' if not hasattr(self, 'mode'): # We are using PCBs self.mode = MODE_PCB @@ -317,7 +341,7 @@ class TestContext(object): if ref_out_dir: reference = self.get_out_path(reference) else: - reference = os.path.join(REF_DIR, reference) + reference = os.path.join(self.ref_dir, reference) image = self.get_out_path(image) png_ref = None if reference[-3:] == 'svg': @@ -340,7 +364,7 @@ class TestContext(object): '-crop', '100%x87%+0+0', '+repage', '-colorspace', 'RGB', self.get_out_path(diff)] - logging.debug('Comparing images with: '+str(cmd)) + logging.debug('Comparing images with: '+usable_cmd(cmd)) res = subprocess.check_output(cmd, stderr=subprocess.STDOUT) # m = re.match(r'([\d\.e-]+) \(([\d\.e-]+)\)', res.decode()) # assert m @@ -361,7 +385,7 @@ class TestContext(object): # Split the reference logging.debug('Splitting '+reference) cmd = ['convert', '-density', '150', - os.path.join(REF_DIR, reference), + os.path.join(self.ref_dir, reference), self.get_out_path('ref-%d.png')] subprocess.check_call(cmd) # Split the generated @@ -382,9 +406,9 @@ class TestContext(object): def compare_txt(self, text, reference=None, diff='diff.txt'): if reference is None: reference = text - cmd = ['/bin/sh', '-c', 'diff -ub '+os.path.join(REF_DIR, reference)+' ' + + cmd = ['/bin/sh', '-c', 'diff -ub '+os.path.join(self.ref_dir, reference)+' ' + self.get_out_path(text)+' > '+self.get_out_path(diff)] - logging.debug('Comparing texts with: '+str(cmd)) + logging.debug('Comparing texts with: '+usable_cmd(cmd)) res = subprocess.call(cmd) assert res == 0 diff --git a/tests/yaml_samples/print_pcb_options.kibot.yaml b/tests/yaml_samples/print_pcb_options.kibot.yaml new file mode 100644 index 00000000..66f6f454 --- /dev/null +++ b/tests/yaml_samples/print_pcb_options.kibot.yaml @@ -0,0 +1,18 @@ +# Example KiBot config file +kibot: + version: 1 + +outputs: + - name: 'print_front' + comment: "Print F.Cu+F.SilkS" + type: pdf_pcb_print + options: + scaling: 4 + drill_marks: none + plot_sheet_reference: false + monochrome: true + separated: true + layers: + - layer: F.Cu + - layer: F.SilkS +