Support for new `pcbnew_do export` options.
This commit is contained in:
parent
5a50477f7c
commit
71fe37cfc6
|
|
@ -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
|
||||
|
|
|
|||
3
Makefile
3
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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 175 KiB |
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/bom-F_Cu+F_SilkS.pdf
|
||||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/kibom-variant_3-top-C1.png
|
||||
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/kibom-variant_3-top.png
|
||||
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/kibom-variant_4-B_Fab.pdf
|
||||
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/kibom-variant_4-F_Fab.pdf
|
||||
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/test_v5-schematic_(no_L).pdf
|
||||
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/test_v5-schematic_(no_L).svg
|
||||
|
|
@ -0,0 +1 @@
|
|||
../5_1_6/zone-refill-B_Cu.pdf
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
Loading…
Reference in New Issue