Added support for PcbDraw

This commit is contained in:
Salvador E. Tropea 2020-07-11 13:49:03 -03:00
parent c468dd44e1
commit 52e6bb1b5f
15 changed files with 578 additions and 11 deletions

View File

@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- The layers entry is much more flexible now. - The layers entry is much more flexible now.
Many changes, read the README.md Many changes, read the README.md
- PcbDraw output.
- -e/--schematic option to specify any schematic (not just derived from the PCB - -e/--schematic option to specify any schematic (not just derived from the PCB
name. name.
- -x/--example option to generate a complete configuration example. - -x/--example option to generate a complete configuration example.

View File

@ -321,7 +321,7 @@ Next time you need this list just use an alias, like this:
- `map`: [dict|string] [hpgl,ps,gerber,dxf,svg,pdf] format for a graphical drill map. - `map`: [dict|string] [hpgl,ps,gerber,dxf,svg,pdf] format for a graphical drill map.
Not generated unless a format is specified. Not generated unless a format is specified.
* Valid keys: * Valid keys:
- No available options - `type`: [string='pdf'] [hpgl,ps,gerber,dxf,svg,pdf] format for a graphical drill map.
- `metric_units`: [boolean=true] use metric units instead of inches. - `metric_units`: [boolean=true] use metric units instead of inches.
- `minimal_header`: [boolean=false] use a minimal header in the file. - `minimal_header`: [boolean=false] use a minimal header in the file.
- `mirror_y_axis`: [boolean=false] invert the Y axis. - `mirror_y_axis`: [boolean=false] invert the Y axis.
@ -345,7 +345,7 @@ Next time you need this list just use an alias, like this:
- `map`: [dict|string] [hpgl,ps,gerber,dxf,svg,pdf] format for a graphical drill map. - `map`: [dict|string] [hpgl,ps,gerber,dxf,svg,pdf] format for a graphical drill map.
Not generated unless a format is specified. Not generated unless a format is specified.
* Valid keys: * Valid keys:
- No available options - `type`: [string='pdf'] [hpgl,ps,gerber,dxf,svg,pdf] format for a graphical drill map.
- `report`: [dict|string] name of the drill report. Not generated unless a name is specified. - `report`: [dict|string] name of the drill report. Not generated unless a name is specified.
* Valid keys: * Valid keys:
- `filename`: [string=''] name of the drill report. Not generated unless a name is specified. - `filename`: [string=''] name of the drill report. Not generated unless a name is specified.
@ -448,7 +448,8 @@ Next time you need this list just use an alias, like this:
%r : revision from pcb metadata. %r : revision from pcb metadata.
%d : pcb date from metadata if available, file modification date otherwise. %d : pcb date from metadata if available, file modification date otherwise.
%D : bom generation date. %D : bom generation date.
%T : bom generation time. Extension .html will be added automatically. %T : bom generation time.
Extension .html will be added automatically.
- `netlist_file`: [string=''] Path to netlist or xml file. - `netlist_file`: [string=''] Path to netlist or xml file.
- `no_blacklist_virtual`: [boolean=false] Do not blacklist virtual components. - `no_blacklist_virtual`: [boolean=false] Do not blacklist virtual components.
- `no_redraw_on_drag`: [boolean=false] Do not redraw pcb on drag by default. - `no_redraw_on_drag`: [boolean=false] Do not redraw pcb on drag by default.
@ -479,6 +480,44 @@ Next time you need this list just use an alias, like this:
with a BOM file exported for each variant, separate with a BOM file exported for each variant, separate
variants with the ';' (semicolon) character. variants with the ';' (semicolon) character.
* PcbDraw - Beautiful 2D PCB render
* Type: `pcbdraw`
* Description: Exports the PCB as a 2D model (SVG, PNG or JPG).
Uses configurable colors.
Can also render the components if the 2D models are available
* Valid keys:
- `comment`: [string=''] A comment for documentation purposes.
- `dir`: [string='.'] Output directory for the generated files.
- `name`: [string=''] Used to identify this particular output definition.
- `options`: [dict] Options for the `pcbdraw` output.
* Valid keys:
- `bottom`: [boolean=false] render the bottom side of the board (default is top side).
- `dpi`: [number=300] [10,1200] dots per inch (resolution) of the generated image.
- `format`: [string='svg'] [svg,png,jpg] output format. Only used if no `output` is specified.
- `highlight`: [list(string)] list of components to highlight.
- `libs`: [list(string)] list of libraries.
- `mirror`: [boolean=false] mirror the board.
- `no_drillholes`: [boolean=false] do not make holes transparent.
- `output`: [string='%f-%i.%x'] name for the generated file.
- `placeholder`: [boolean=false] show placeholder for missing components.
- `remap`: [dict|None] replacements for PCB references using components (lib:component).
- `show_components`: [string|list(string)] [none,all] list of components to draw, can be also a string for none or all.
The default is none.
- `style`: [string|dict] PCB style (colors). An internal name, the name of a JSON file or the style options.
* Valid keys:
- `board`: [string='#4ca06c'] color for the board without copper (covered by solder mask).
- `clad`: [string='#9c6b28'] color for the PCB core (not covered by solder mask).
- `copper`: [string='#417e5a'] color for the copper zones (covered by solder mask).
- `highlight_on_top`: [boolean=false] highlight over the component (not under).
- `highlight_padding`: [number=1.5] [0,1000] how much the highlight extends around the component [mm].
- `highlight_style`: [string='stroke:none;fill:#ff0000;opacity:0.5;'] SVG code for the highlight style.
- `outline`: [string='#000000'] color for the outline.
- `pads`: [string='#b5ae30'] color for the exposed pads (metal finish).
- `silk`: [string='#f0f0f0'] color for the silk screen.
- `vcut`: [string='#bf2600'] color for the V-CUTS.
- `vcuts`: [boolean=false] render V-CUTS on the Cmts.User layer.
- `warnings`: [string='visible'] [visible,all,none] using visible only the warnings about components in the visible side are generated.
* PDF (Portable Document Format) * PDF (Portable Document Format)
* Type: `pdf` * Type: `pdf`
* Description: Exports the PCB to the most common exhange format. Suitable for printing. * Description: Exports the PCB to the most common exhange format. Suitable for printing.

View File

@ -221,7 +221,8 @@ outputs:
# %r : revision from pcb metadata. # %r : revision from pcb metadata.
# %d : pcb date from metadata if available, file modification date otherwise. # %d : pcb date from metadata if available, file modification date otherwise.
# %D : bom generation date. # %D : bom generation date.
# %T : bom generation time. Extension .html will be added automatically # %T : bom generation time.
# Extension .html will be added automatically
name_format: 'ibom' name_format: 'ibom'
# [string=''] Path to netlist or xml file # [string=''] Path to netlist or xml file
netlist_file: '' netlist_file: ''
@ -264,6 +265,64 @@ outputs:
# variants with the ';' (semicolon) character # variants with the ';' (semicolon) character
variant: '' variant: ''
# PcbDraw - Beautiful 2D PCB render:
# Uses configurable colors.
# Can also render the components if the 2D models are available
- name: 'pcbdraw_example'
comment: 'Exports the PCB as a 2D model (SVG, PNG or JPG).'
type: 'pcbdraw'
dir: 'Example/pcbdraw_dir'
options:
# [boolean=false] render the bottom side of the board (default is top side)
bottom: false
# [number=300] [10,1200] dots per inch (resolution) of the generated image
dpi: 300
# [string='svg'] [svg,png,jpg] output format. Only used if no `output` is specified
format: 'svg'
# [list(string)] list of components to highlight
highlight:
# [list(string)] list of libraries
libs:
# [boolean=false] mirror the board
mirror: false
# [boolean=false] do not make holes transparent
no_drillholes: false
# [string='%f-%i.%x'] name for the generated file
output: '%f-%i.%x'
# [boolean=false] show placeholder for missing components
placeholder: false
# [dict|None] replacements for PCB references using components (lib:component)
remap:
# [string|list(string)] [none,all] list of components to draw, can be also a string for none or all.
# The default is none
show_components:
# [string|dict] PCB style (colors). An internal name, the name of a JSON file or the style options
style:
# [string='#4ca06c'] color for the board without copper (covered by solder mask)
board: '#4ca06c'
# [string='#9c6b28'] color for the PCB core (not covered by solder mask)
clad: '#9c6b28'
# [string='#417e5a'] color for the copper zones (covered by solder mask)
copper: '#417e5a'
# [boolean=false] highlight over the component (not under)
highlight_on_top: false
# [number=1.5] [0,1000] how much the highlight extends around the component [mm]
highlight_padding: 1.5
# [string='stroke:none;fill:#ff0000;opacity:0.5;'] SVG code for the highlight style
highlight_style: 'stroke:none;fill:#ff0000;opacity:0.5;'
# [string='#000000'] color for the outline
outline: '#000000'
# [string='#b5ae30'] color for the exposed pads (metal finish)
pads: '#b5ae30'
# [string='#f0f0f0'] color for the silk screen
silk: '#f0f0f0'
# [string='#bf2600'] color for the V-CUTS
vcut: '#bf2600'
# [boolean=false] render V-CUTS on the Cmts.User layer
vcuts: false
# [string='visible'] [visible,all,none] using visible only the warnings about components in the visible side are generated
warnings: 'visible'
# PDF (Portable Document Format): # PDF (Portable Document Format):
# Note that this output isn't the best for documating your project. # Note that this output isn't the best for documating your project.
# This output is what you get from the File/Plot menu in pcbnew. # This output is what you get from the File/Plot menu in pcbnew.

View File

@ -175,12 +175,14 @@ def trim(docstring):
def print_output_options(name, cl, indent): def print_output_options(name, cl, indent):
ind_str = indent*' ' ind_str = indent*' '
obj = cl() obj = cl()
print(ind_str+'* Valid keys:')
num_opts = 0 num_opts = 0
for k, v in obj.get_attrs_gen(): for k, v in obj.get_attrs_gen():
if k == 'type': if k == 'type' and indent == 2:
# Type is fixed for an output # Type is fixed for an output
continue continue
if not num_opts:
# We found one, put the title
print(ind_str+'* Valid keys:')
help = getattr(obj, '_help_'+k) help = getattr(obj, '_help_'+k)
if help is None: if help is None:
help = 'Undocumented' # pragma: no cover help = 'Undocumented' # pragma: no cover
@ -194,8 +196,8 @@ def print_output_options(name, cl, indent):
num_opts = num_opts+1 num_opts = num_opts+1
if isinstance(v, type): if isinstance(v, type):
print_output_options('', v, indent+4) print_output_options('', v, indent+4)
if num_opts == 0: # if num_opts == 0:
print(ind_str+' - No available options') # print(ind_str+' - No available options')
def print_one_out_help(details, n, o): def print_one_out_help(details, n, o):

View File

@ -21,6 +21,7 @@ NO_PCBNEW_MODULE = 16
CORRUPTED_PCB = 17 CORRUPTED_PCB = 17
KICAD2STEP_ERR = 18 KICAD2STEP_ERR = 18
WONT_OVERWRITE = 19 WONT_OVERWRITE = 19
PCBDRAW_ERR = 20
CMD_EESCHEMA_DO = 'eeschema_do' CMD_EESCHEMA_DO = 'eeschema_do'
URL_EESCHEMA_DO = 'https://github.com/INTI-CMNB/kicad-automation-scripts' URL_EESCHEMA_DO = 'https://github.com/INTI-CMNB/kicad-automation-scripts'
@ -33,5 +34,6 @@ URL_KIBOM = 'https://github.com/INTI-CMNB/KiBoM'
CMD_IBOM = 'generate_interactive_bom.py' CMD_IBOM = 'generate_interactive_bom.py'
URL_IBOM = 'https://github.com/INTI-CMNB/InteractiveHtmlBom' URL_IBOM = 'https://github.com/INTI-CMNB/InteractiveHtmlBom'
KICAD2STEP = 'kicad2step' KICAD2STEP = 'kicad2step'
PCBDRAW = 'pcbdraw'
EXAMPLE_CFG = 'example.kiplot.yaml' EXAMPLE_CFG = 'example.kiplot.yaml'
AUTO_SCALE = 0 AUTO_SCALE = 0

View File

@ -1,6 +1,10 @@
import os
import re
import inspect import inspect
from re import (compile) from re import compile
from datetime import datetime
from .error import KiPlotConfigurationError from .error import KiPlotConfigurationError
from .gs import GS
from . import log from . import log
logger = log.get_logger(__name__) logger = log.get_logger(__name__)
@ -138,6 +142,39 @@ class Optionable(object):
attrs = self.get_attrs_for() attrs = self.get_attrs_for()
return ((k, v) for k, v in attrs.items() if k[0] != '_') return ((k, v) for k, v in attrs.items() if k[0] != '_')
def expand_filename(self, name, id='', ext=''):
""" Expands %x values in filenames """
if GS.board:
# This is based on InterativeHtmlBom expansion
title_block = GS.board.GetTitleBlock()
file_date = title_block.GetDate()
if not file_date:
file_mtime = os.path.getmtime(GS.pcb_file)
file_date = datetime.fromtimestamp(file_mtime).strftime('%Y-%m-%d_%H-%M-%S')
pcb_file_name = os.path.splitext(os.path.basename(GS.pcb_file))[0]
title = title_block.GetTitle()
if not title:
title = pcb_file_name
revision = title_block.GetRevision()
company = title_block.GetCompany()
n = datetime.now()
today = n.strftime('%Y-%m-%d')
time = n.strftime('%H-%M-%S')
# Do the replacements
name = name.replace('%f', pcb_file_name)
name = name.replace('%p', title)
name = name.replace('%c', company)
name = name.replace('%r', revision)
name = name.replace('%d', file_date)
name = name.replace('%D', today)
name = name.replace('%T', time)
name = name.replace('%i', id)
name = name.replace('%x', ext)
# sanitize the name to avoid characters illegal in file systems
name = name.replace('\\', '/')
name = re.sub(r'[?%*:|"<>]', '_', name)
return name
class BaseOptions(Optionable): class BaseOptions(Optionable):
""" A class to validate and hold output options. """ A class to validate and hold output options.

View File

@ -42,7 +42,8 @@ class IBoMOptions(BaseOptions):
%r : revision from pcb metadata. %r : revision from pcb metadata.
%d : pcb date from metadata if available, file modification date otherwise. %d : pcb date from metadata if available, file modification date otherwise.
%D : bom generation date. %D : bom generation date.
%T : bom generation time. Extension .html will be added automatically """ %T : bom generation time.
Extension .html will be added automatically """
self.include_tracks = False self.include_tracks = False
""" Include track/zone information in output. F.Cu and B.Cu layers only """ """ Include track/zone information in output. F.Cu and B.Cu layers only """
self.include_nets = False self.include_nets = False

245
kiplot/out_pcbdraw.py Normal file
View File

@ -0,0 +1,245 @@
import os
import re
from tempfile import (NamedTemporaryFile)
from subprocess import (check_output, STDOUT, CalledProcessError)
from .misc import (PCBDRAW, PCBDRAW_ERR)
from .error import KiPlotConfigurationError
from .gs import (GS)
from .optionable import (BaseOptions, Optionable)
from kiplot.macros import macros, document, output_class # noqa: F401
from . import log
logger = log.get_logger(__name__)
class PcbDrawStyle(Optionable):
_color_re = re.compile(r"#[A-Fa-f0-9]{6}$")
def __init__(self):
super().__init__()
with document:
self.copper = "#417e5a"
""" color for the copper zones (covered by solder mask) """
self.board = "#4ca06c"
""" color for the board without copper (covered by solder mask) """
self.silk = "#f0f0f0"
""" color for the silk screen """
self.pads = "#b5ae30"
""" color for the exposed pads (metal finish) """
self.outline = "#000000"
""" color for the outline """
self.clad = "#9c6b28"
""" color for the PCB core (not covered by solder mask) """
self.vcut = "#bf2600"
""" color for the V-CUTS """
self.highlight_on_top = False
""" highlight over the component (not under) """
self.highlight_style = "stroke:none;fill:#ff0000;opacity:0.5;"
""" SVG code for the highlight style """
self.highlight_padding = 1.5
""" [0,1000] how much the highlight extends around the component [mm] """ # pragma: no cover
def validate_color(self, name):
color = getattr(self, name)
if not self._color_re.match(color):
raise KiPlotConfigurationError('Invalid color for `{}` use `#rrggbb` with hex digits'.format(name))
def config(self, tree):
super().config(tree)
self.validate_color('board')
self.validate_color('copper')
self.validate_color('board')
self.validate_color('silk')
self.validate_color('pads')
self.validate_color('outline')
self.validate_color('clad')
self.validate_color('vcut')
# Not implemented but required
self.highlight_offset = 0
def to_dict(self):
return {k.replace('_', '-'): v for k, v in self.get_attrs_gen()}
class PcbDrawRemap(Optionable):
""" This class accepts a free form dict.
No validation is done. """
def __init__(self):
super().__init__()
def config(self, tree):
self._tree = tree
class PcbDrawOptions(BaseOptions):
def __init__(self):
super().__init__()
with document:
self.style = PcbDrawStyle
""" [string|dict] PCB style (colors). An internal name, the name of a JSON file or the style options """
self.libs = Optionable
""" [list(string)] list of libraries """
self.placeholder = False
""" show placeholder for missing components """
self.remap = PcbDrawRemap
""" [dict|None] replacements for PCB references using components (lib:component) """
self.no_drillholes = False
""" do not make holes transparent """
self.bottom = False
""" render the bottom side of the board (default is top side) """
self.mirror = False
""" mirror the board """
self.highlight = Optionable
""" [list(string)] list of components to highlight """
self.show_components = Optionable
""" [string|list(string)] [none,all] list of components to draw, can be also a string for none or all.
The default is none """
self.vcuts = False
""" render V-CUTS on the Cmts.User layer """
self.warnings = 'visible'
""" [visible,all,none] using visible only the warnings about components in the visible side are generated """
self.dpi = 300
""" [10,1200] dots per inch (resolution) of the generated image """
self.format = 'svg'
""" [svg,png,jpg] output format. Only used if no `output` is specified """
self.output = '%f-%i.%x'
""" name for the generated file """ # pragma: no cover
def config(self, tree):
super().config(tree)
# Libs
if isinstance(self.libs, type):
self.libs = None
else:
self.libs = ','.join(self.libs)
# Highlight
if isinstance(self.highlight, type):
self.highlight = None
else:
self.highlight = ','.join(self.highlight)
# Filter
if isinstance(self.show_components, type):
self.show_components = ''
elif isinstance(self.show_components, str):
if self.show_components == 'none':
self.show_components = ''
else:
self.show_components = None
else:
self.show_components = ','.join(self.show_components)
# Remap
if isinstance(self.remap, type):
self.remap = None
elif isinstance(self.remap, PcbDrawRemap):
self.remap = self.remap._tree
# Style
if isinstance(self.style, type):
self.style = None
elif isinstance(self.style, PcbDrawStyle):
self.style = self.style.to_dict()
def _create_remap(self):
with NamedTemporaryFile(mode='w', delete=False) as f:
f.write('{\n')
first = True
for k, v in self.remap.items():
if first:
first = False
else:
f.write(',\n')
f.write(' "{}": "{}"'.format(k, v))
f.write('\n}\n')
f.close()
return f.name
def _create_style(self):
with NamedTemporaryFile(mode='w', delete=False) as f:
f.write('{\n')
first = True
for k, v in self.style.items():
if first:
first = False
else:
f.write(',\n')
if isinstance(v, str):
f.write(' "{}": "{}"'.format(k, v))
elif isinstance(v, bool):
f.write(' "{}": {}'.format(k, str(v).lower()))
else:
f.write(' "{}": {}'.format(k, v))
f.write('\n}\n')
f.close()
return f.name
def run(self, output_dir, board):
# Output file name
output = self.expand_filename(self.output, 'bottom' if self.bottom else 'top', self.format)
output = os.path.abspath(os.path.join(output_dir, output))
# Base command with overwrite
cmd = [PCBDRAW]
# Add user options
tmp_style = None
if self.style:
if isinstance(self.style, str):
cmd.extend(['-s', self.style])
else:
tmp_style = self._create_style()
cmd.extend(['-s', tmp_style])
if self.libs:
cmd.extend(['-l', self.libs])
if self.placeholder:
cmd.append('--placeholder')
if self.no_drillholes:
cmd.append('--no-drillholes')
if self.bottom:
cmd.append('-b')
if self.mirror:
cmd.append('--mirror')
if self.highlight:
cmd.extend(['-a', self.highlight])
if self.show_components is not None:
cmd.extend(['-f', self.show_components])
if self.vcuts:
cmd.append('-v')
if self.warnings == 'all':
cmd.append('--warn-back')
elif self.warnings == 'none':
cmd.append('--silent')
if self.dpi:
cmd.extend(['--dpi', str(self.dpi)])
if self.remap:
tmp_remap = self._create_remap()
cmd.extend(['-m', tmp_remap])
else:
tmp_remap = None
# The board & output
cmd.append(GS.pcb_file)
cmd.append(output)
# Execute and inform is successful
logger.debug('Executing: '+str(cmd))
try:
cmd_output = check_output(cmd, stderr=STDOUT)
except CalledProcessError as e:
logger.error('Failed to run %s, error %d', PCBDRAW, e.returncode)
if e.output:
logger.debug('Output from command: '+e.output.decode())
exit(PCBDRAW_ERR)
finally:
if tmp_remap:
os.remove(tmp_remap)
if tmp_style:
os.remove(tmp_style)
logger.debug('Output from command:\n'+cmd_output.decode())
@output_class
class PcbDraw(BaseOutput): # noqa: F821
""" PcbDraw - Beautiful 2D PCB render
Exports the PCB as a 2D model (SVG, PNG or JPG).
Uses configurable colors.
Can also render the components if the 2D models are available """
def __init__(self):
super().__init__()
with document:
self.options = PcbDrawOptions
""" [dict] Options for the `pcbdraw` output """ # pragma: no cover

View File

@ -41,7 +41,8 @@ from utils import context
prev_dir = os.path.dirname(prev_dir) prev_dir = os.path.dirname(prev_dir)
if prev_dir not in sys.path: if prev_dir not in sys.path:
sys.path.insert(0, prev_dir) sys.path.insert(0, prev_dir)
from kiplot.misc import (EXIT_BAD_ARGS, EXIT_BAD_CONFIG, NO_PCB_FILE, NO_SCH_FILE, EXAMPLE_CFG, WONT_OVERWRITE, CORRUPTED_PCB) from kiplot.misc import (EXIT_BAD_ARGS, EXIT_BAD_CONFIG, NO_PCB_FILE, NO_SCH_FILE, EXAMPLE_CFG, WONT_OVERWRITE, CORRUPTED_PCB,
PCBDRAW_ERR)
POS_DIR = 'positiondir' POS_DIR = 'positiondir'
@ -433,3 +434,11 @@ def test_corrupted_pcb():
ctx.run(CORRUPTED_PCB) ctx.run(CORRUPTED_PCB)
assert ctx.search_err('Error loading PCB file') assert ctx.search_err('Error loading PCB file')
ctx.clean_up() ctx.clean_up()
def test_pcbdraw_fail():
prj = 'bom'
ctx = context.TestContext('PcbDrawFail', prj, 'pcbdraw_fail', '')
ctx.run(PCBDRAW_ERR)
assert ctx.search_err('Failed to run')
ctx.clean_up()

View File

@ -0,0 +1,36 @@
"""
Tests for PcbDraw.
For debug information use:
pytest-3 --log-cli-level debug
"""
import os
import sys
# Look for the 'utils' module from where the script is running
prev_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if prev_dir not in sys.path:
sys.path.insert(0, prev_dir)
# Utils import
from utils import context
OUT_DIR = 'PcbDraw'
def test_pcbdraw_3Rs():
prj = '3Rs'
ctx = context.TestContext(OUT_DIR, prj, 'pcbdraw', OUT_DIR)
ctx.run()
ctx.expect_out_file(os.path.join(OUT_DIR, prj+'-top.svg'))
ctx.expect_out_file(os.path.join(OUT_DIR, prj+'-bottom.svg'))
ctx.clean_up()
def test_pcbdraw_simple():
prj = 'bom'
ctx = context.TestContext(OUT_DIR+'_simple', prj, 'pcbdraw_simple', OUT_DIR)
ctx.run()
ctx.expect_out_file(os.path.join(OUT_DIR, prj+'-top.svg'))
ctx.expect_out_file(os.path.join(OUT_DIR, prj+'-bottom.svg'))
ctx.clean_up()

View File

@ -38,6 +38,8 @@ Tests various errors in the config file
- Unknown section - Unknown section
- HPGL wrong pen_number - HPGL wrong pen_number
- KiBoM wrong format - KiBoM wrong format
- PcbDraw
- Wrong color
For debug information use: For debug information use:
pytest-3 --log-cli-level debug pytest-3 --log-cli-level debug
@ -429,3 +431,10 @@ def test_error_print_pcb_no_layer():
ctx.run(EXIT_BAD_CONFIG) ctx.run(EXIT_BAD_CONFIG)
assert ctx.search_err("Missing .?layers.? list") assert ctx.search_err("Missing .?layers.? list")
ctx.clean_up() ctx.clean_up()
def test_error_color():
ctx = context.TestContext('PrPCB', 'bom', 'error_color', '')
ctx.run(EXIT_BAD_CONFIG)
assert ctx.search_err("Invalid color for .?board.?")
ctx.clean_up()

View File

@ -0,0 +1,22 @@
kiplot:
version: 1
outputs:
- name: PcbDraw
comment: "PcbDraw test top"
type: pcbdraw
dir: PcbDraw
options:
format: svg
style:
board: "bogus"
copper: "#00406a"
silk: "#d5dce4"
pads: "#cfb96e"
clad: "#72786c"
outline: "#000000"
vcut: "#bf2600"
highlight_on_top: false
highlight_style: "stroke:none;fill:#ff0000;opacity:0.5;"
highlight_padding: 1.5

View File

@ -0,0 +1,62 @@
kiplot:
version: 1
outputs:
- name: PcbDraw
comment: "PcbDraw test top"
type: pcbdraw
dir: PcbDraw
options: &pcb_draw_ops
format: svg
style:
board: "#1b1f44"
copper: "#00406a"
silk: "#d5dce4"
pads: "#cfb96e"
clad: "#72786c"
outline: "#000000"
vcut: "#bf2600"
highlight_on_top: false
highlight_style: "stroke:none;fill:#ff0000;opacity:0.5;"
highlight_padding: 1.5
libs:
- default
- eagle-default
remap:
L_G1: "LEDs:LED-5MM_green"
L_B1: "LEDs:LED-5MM_blue"
L_Y1: "LEDs:LED-5MM_yellow"
PHOTO1: "yaqwsx:R_PHOTO_7mm"
J8: "yaqwsx:Pin_Header_Straight_1x02_circle"
'REF**': "dummy:dummy"
G***: "dummy:dummy"
svg2mod: "dummy:dummy"
JP1: "dummy:dummy"
JP2: "dummy:dummy"
JP3: "dummy:dummy"
JP4: "dummy:dummy"
no_drillholes: False
mirror: False
highlight:
- L_G1
- L_B1
- R10
- RV1
show_components: all
vcuts: True
warnings: visible
dpi: 600
- name: PcbDraw
comment: "PcbDraw test bottom"
type: pcbdraw
dir: PcbDraw
options:
<<: *pcb_draw_ops
style: set-red-enig
bottom: True
show_components:
- L_G1
- L_B1
remap:

View File

@ -0,0 +1,16 @@
kiplot:
version: 1
outputs:
- name: PcbDraw
comment: "PcbDraw test top"
type: pcbdraw
dir: PcbDraw
options:
format: svg
style: bogus
no_drillholes: True
placeholder: True
mirror: True
vcuts: True
warnings: all

View File

@ -0,0 +1,27 @@
kiplot:
version: 1
outputs:
- name: PcbDraw
comment: "PcbDraw test top"
type: pcbdraw
dir: PcbDraw
options: &pcb_draw_ops
format: svg
no_drillholes: True
placeholder: True
mirror: True
vcuts: True
warnings: all
- name: PcbDraw
comment: "PcbDraw test bottom"
type: pcbdraw
dir: PcbDraw
options:
<<: *pcb_draw_ops
style: set-red-enig
bottom: True
show_components: none
warnings: none