commit
df7b237b0e
10
CHANGELOG.md
10
CHANGELOG.md
|
|
@ -18,7 +18,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Marking components as "Do Not Fit"
|
||||
- Marking components as "Do Not Change"
|
||||
- The internal BoM format supports KiBoM and IBoM style variants
|
||||
- Schematic print to PDF supports variants. Not fitted components are crossed.
|
||||
- Schematic print to PDF support for variants. Not fitted components are crossed.
|
||||
- Position (Pick & Place) support for variants.
|
||||
- All plot formats (gerber, pdf, svg, etc.) support for variants:
|
||||
- Pads removed from *.Paste
|
||||
- Drawings removed from *.Adhes
|
||||
- Components crossed in *.Fab
|
||||
|
||||
### Fixed
|
||||
- Virtual components are always excluded from position files.
|
||||
|
||||
## [0.6.2] - 2020-08-25
|
||||
### Changed
|
||||
|
|
|
|||
1
Makefile
1
Makefile
|
|
@ -109,6 +109,7 @@ gen_ref:
|
|||
src/kibot -c tests/yaml_samples/print_pdf_no_inductors_1.kibot.yaml -e tests/board_samples/test_v5.sch -d $(REFDIR)
|
||||
mv "$(REFDIR)no_inductor/test_v5-schematic_(no_L).pdf" $(REFDIR)
|
||||
rmdir $(REFDIR)no_inductor/
|
||||
src/kibot -b tests/board_samples/kibom-variant_4.kicad_pcb -c tests/yaml_samples/pdf_variant_1.kibot.yaml -d $(REFDIR)
|
||||
cp -a $(REFILL).ok $(REFILL)
|
||||
|
||||
doc:
|
||||
|
|
|
|||
21
README.md
21
README.md
|
|
@ -437,6 +437,8 @@ Next time you need this list just use an alias, like this:
|
|||
- `name`: [string=''] Used to identify this particular output definition.
|
||||
- `options`: [dict] Options for the `dxf` output.
|
||||
* 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).
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
|
|
@ -450,6 +452,7 @@ Next time you need this list just use an alias, like this:
|
|||
- `sketch_plot`: [boolean=false] don't fill objects, just draw the outline.
|
||||
- `tent_vias`: [boolean=true] cover the vias.
|
||||
- `use_aux_axis_as_origin`: [boolean=false] use the auxiliar axis as origin for coordinates.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
|
||||
* Excellon drill format
|
||||
* Type: `excellon`
|
||||
|
|
@ -519,6 +522,8 @@ Next time you need this list just use an alias, like this:
|
|||
* Valid keys:
|
||||
- `create_gerber_job_file`: [boolean=true] creates a file with information about all the generated gerbers.
|
||||
You can use it in gerbview to load all gerbers at once.
|
||||
- `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.
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
- `force_plot_invisible_refs_vals`: [boolean=false] include references and values even when they are marked as invisible.
|
||||
|
|
@ -535,6 +540,7 @@ Next time you need this list just use an alias, like this:
|
|||
- `use_gerber_net_attributes`: [boolean=true] include netlist metadata.
|
||||
- `use_gerber_x2_attributes`: [boolean=true] use the extended X2 format.
|
||||
- `use_protel_extensions`: [boolean=false] use legacy Protel file extensions.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
|
||||
* HPGL (Hewlett & Packard Graphics Language)
|
||||
* Type: `hpgl`
|
||||
|
|
@ -552,6 +558,8 @@ Next time you need this list just use an alias, like this:
|
|||
- `name`: [string=''] Used to identify this particular output definition.
|
||||
- `options`: [dict] Options for the `hpgl` output.
|
||||
* 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).
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
|
|
@ -567,6 +575,7 @@ Next time you need this list just use an alias, like this:
|
|||
- `scaling`: [number=0] scale factor (0 means autoscaling).
|
||||
- `sketch_plot`: [boolean=false] don't fill objects, just draw the outline.
|
||||
- `tent_vias`: [boolean=true] cover the vias.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
|
||||
* IBoM (Interactive HTML BoM)
|
||||
* Type: `ibom`
|
||||
|
|
@ -750,6 +759,8 @@ Next time you need this list just use an alias, like this:
|
|||
* Valid keys:
|
||||
- `comment`: [string=''] A comment for documentation purposes.
|
||||
- `dir`: [string='.'] Output directory for the generated files.
|
||||
- `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).
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
|
|
@ -763,6 +774,8 @@ Next time you need this list just use an alias, like this:
|
|||
- `name`: [string=''] Used to identify this particular output definition.
|
||||
- `options`: [dict] Options for the `pdf` output.
|
||||
* 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).
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
|
|
@ -775,11 +788,13 @@ Next time you need this list just use an alias, like this:
|
|||
- `plot_footprint_values`: [boolean=true] include the footprint values.
|
||||
- `plot_sheet_reference`: [boolean=false] currently without effect.
|
||||
- `tent_vias`: [boolean=true] cover the vias.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
- `output`: [string='%f-%i%v.%x'] output file name, the default KiCad name if empty. Affected by global options.
|
||||
- `plot_footprint_refs`: [boolean=true] include the footprint references.
|
||||
- `plot_footprint_values`: [boolean=true] include the footprint values.
|
||||
- `plot_sheet_reference`: [boolean=false] currently without effect.
|
||||
- `tent_vias`: [boolean=true] cover the vias.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
|
||||
* PDF PCB Print (Portable Document Format)
|
||||
* Type: `pdf_pcb_print`
|
||||
|
|
@ -853,6 +868,8 @@ Next time you need this list just use an alias, like this:
|
|||
- `options`: [dict] Options for the `ps` output.
|
||||
* Valid keys:
|
||||
- `a4_output`: [boolean=true] force A4 paper size.
|
||||
- `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).
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
|
|
@ -869,6 +886,7 @@ Next time you need this list just use an alias, like this:
|
|||
- `scaling`: [number=1] scale factor (0 means autoscaling).
|
||||
- `sketch_plot`: [boolean=false] don't fill objects, just draw the outline.
|
||||
- `tent_vias`: [boolean=true] cover the vias.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
- `width_adjust`: [number=0] this width factor is intended to compensate PS printers/plotters that do not strictly obey line width settings.
|
||||
Only used to plot pads and tracks.
|
||||
|
||||
|
|
@ -923,6 +941,8 @@ Next time you need this list just use an alias, like this:
|
|||
- `name`: [string=''] Used to identify this particular output definition.
|
||||
- `options`: [dict] Options for the `svg` output.
|
||||
* 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).
|
||||
- `exclude_edge_layer`: [boolean=true] do not include the PCB edge layer.
|
||||
- `exclude_pads_from_silkscreen`: [boolean=false] do not plot the component pads in the silk screen.
|
||||
|
|
@ -935,6 +955,7 @@ Next time you need this list just use an alias, like this:
|
|||
- `plot_footprint_values`: [boolean=true] include the footprint values.
|
||||
- `plot_sheet_reference`: [boolean=false] currently without effect.
|
||||
- `tent_vias`: [boolean=true] cover the vias.
|
||||
- `variant`: [string=''] Board variant(s) to apply.
|
||||
|
||||
* SVG Schematic Print
|
||||
* Type: `svg_sch_print`
|
||||
|
|
|
|||
|
|
@ -156,6 +156,9 @@ outputs:
|
|||
type: 'dxf'
|
||||
dir: 'Example/dxf_dir'
|
||||
options:
|
||||
# [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=true] do not include the PCB edge layer
|
||||
|
|
@ -182,6 +185,8 @@ outputs:
|
|||
tent_vias: true
|
||||
# [boolean=false] use the auxiliar axis as origin for coordinates
|
||||
use_aux_axis_as_origin: false
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
layers: all
|
||||
|
||||
# Excellon drill format:
|
||||
|
|
@ -252,6 +257,9 @@ outputs:
|
|||
# [boolean=true] creates a file with information about all the generated gerbers.
|
||||
# You can use it in gerbview to load all gerbers at once
|
||||
create_gerber_job_file: true
|
||||
# [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: ''
|
||||
# [boolean=true] do not include the PCB edge layer
|
||||
exclude_edge_layer: true
|
||||
# [boolean=false] do not plot the component pads in the silk screen
|
||||
|
|
@ -284,6 +292,8 @@ outputs:
|
|||
use_gerber_x2_attributes: true
|
||||
# [boolean=false] use legacy Protel file extensions
|
||||
use_protel_extensions: false
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
layers: all
|
||||
|
||||
# HPGL (Hewlett & Packard Graphics Language):
|
||||
|
|
@ -293,6 +303,9 @@ outputs:
|
|||
type: 'hpgl'
|
||||
dir: 'Example/hpgl_dir'
|
||||
options:
|
||||
# [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=true] do not include the PCB edge layer
|
||||
|
|
@ -323,6 +336,8 @@ outputs:
|
|||
sketch_plot: false
|
||||
# [boolean=true] cover the vias
|
||||
tent_vias: true
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
layers: all
|
||||
|
||||
# IBoM (Interactive HTML BoM):
|
||||
|
|
@ -572,6 +587,9 @@ outputs:
|
|||
type: 'pdf'
|
||||
dir: 'Example/pdf_dir'
|
||||
options:
|
||||
# [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=true] do not include the PCB edge layer
|
||||
|
|
@ -596,6 +614,8 @@ outputs:
|
|||
plot_sheet_reference: false
|
||||
# [boolean=true] cover the vias
|
||||
tent_vias: true
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
layers: all
|
||||
|
||||
# PDF PCB Print (Portable Document Format):
|
||||
|
|
@ -659,6 +679,9 @@ outputs:
|
|||
options:
|
||||
# [boolean=true] force A4 paper size
|
||||
a4_output: true
|
||||
# [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=true] do not include the PCB edge layer
|
||||
|
|
@ -691,6 +714,8 @@ outputs:
|
|||
sketch_plot: false
|
||||
# [boolean=true] cover the vias
|
||||
tent_vias: true
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
# [number=0] this width factor is intended to compensate PS printers/plotters that do not strictly obey line width settings.
|
||||
# Only used to plot pads and tracks
|
||||
width_adjust: 0
|
||||
|
|
@ -739,6 +764,9 @@ outputs:
|
|||
type: 'svg'
|
||||
dir: 'Example/svg_dir'
|
||||
options:
|
||||
# [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=true] do not include the PCB edge layer
|
||||
|
|
@ -763,6 +791,8 @@ outputs:
|
|||
plot_sheet_reference: false
|
||||
# [boolean=true] cover the vias
|
||||
tent_vias: true
|
||||
# [string=''] Board variant(s) to apply
|
||||
variant: ''
|
||||
layers: all
|
||||
|
||||
# SVG Schematic Print:
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ AUTO_SCALE = 0
|
|||
|
||||
# Internal filter names
|
||||
IFILL_MECHANICAL = '_mechanical'
|
||||
# KiCad 5 GUI values for the attribute
|
||||
UI_THT = 0
|
||||
UI_SMD = 1
|
||||
UI_VIRTUAL = 2
|
||||
|
||||
# Supported values for "do not fit"
|
||||
DNF = {
|
||||
|
|
|
|||
|
|
@ -6,18 +6,44 @@
|
|||
# Project: KiBot (formerly KiPlot)
|
||||
# Adapted from: https://github.com/johnbeard/kiplot
|
||||
import os
|
||||
from pcbnew import (GERBER_JOBFILE_WRITER, PLOT_CONTROLLER, IsCopperLayer)
|
||||
from pcbnew import GERBER_JOBFILE_WRITER, PLOT_CONTROLLER, IsCopperLayer, LSET, wxPoint, EDGE_MODULE
|
||||
from .out_base import (BaseOutput)
|
||||
from .error import (PlotError, KiPlotConfigurationError)
|
||||
from .optionable import BaseOptions
|
||||
from .optionable import BaseOptions, Optionable
|
||||
from .registrable import RegOutput
|
||||
from .layer import Layer
|
||||
from .gs import GS
|
||||
from .misc import UI_VIRTUAL
|
||||
from .kiplot import load_sch
|
||||
from .macros import macros, document # noqa: F401
|
||||
from .fil_base import BaseFilter, apply_fitted_filter
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
|
||||
class Rect(object):
|
||||
""" What KiCad returns isn't a real wxWidget's wxRect.
|
||||
Here I add what I really need """
|
||||
def __init__(self):
|
||||
self.x1 = None
|
||||
self.y1 = None
|
||||
self.x2 = None
|
||||
self.y2 = None
|
||||
|
||||
def Union(self, wxRect):
|
||||
if self.x1 is None:
|
||||
self.x1 = wxRect.x
|
||||
self.y1 = wxRect.y
|
||||
self.x2 = wxRect.x+wxRect.width
|
||||
self.y2 = wxRect.y+wxRect.height
|
||||
else:
|
||||
self.x1 = min(self.x1, wxRect.x)
|
||||
self.y1 = min(self.y1, wxRect.y)
|
||||
self.x2 = max(self.x2, wxRect.x+wxRect.width)
|
||||
self.y2 = max(self.y2, wxRect.y+wxRect.height)
|
||||
|
||||
|
||||
class AnyLayerOptions(BaseOptions):
|
||||
""" Base class for: DXF, Gerber, HPGL, PDF, PS and SVG """
|
||||
def __init__(self):
|
||||
|
|
@ -38,8 +64,18 @@ class AnyLayerOptions(BaseOptions):
|
|||
""" output file name, the default KiCad name if empty """
|
||||
self.tent_vias = True
|
||||
""" cover the vias """
|
||||
self.variant = ''
|
||||
""" Board variant(s) to apply """
|
||||
self.dnf_filter = Optionable
|
||||
""" [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 """
|
||||
super().__init__()
|
||||
|
||||
def config(self):
|
||||
super().config()
|
||||
self.variant = RegOutput.check_variant(self.variant)
|
||||
self.dnf_filter = BaseFilter.solve_filter(self.dnf_filter, 'dnf_filter')
|
||||
|
||||
def _configure_plot_ctrl(self, po, output_dir):
|
||||
logger.debug("Configuring plot controller for output")
|
||||
po.SetOutputDirectory(output_dir)
|
||||
|
|
@ -55,23 +91,139 @@ class AnyLayerOptions(BaseOptions):
|
|||
# We'll come back to this on a per-layer basis
|
||||
po.SetSkipPlotNPTH_Pads(False)
|
||||
|
||||
@staticmethod
|
||||
def cross_module(m, rect, layer):
|
||||
seg1 = EDGE_MODULE(m)
|
||||
m.Add(seg1)
|
||||
seg1.SetWidth(120000)
|
||||
seg1.SetStart(wxPoint(rect.x1, rect.y1))
|
||||
seg1.SetEnd(wxPoint(rect.x2, rect.y2))
|
||||
seg1.SetLayer(layer)
|
||||
seg2 = EDGE_MODULE(m)
|
||||
m.Add(seg2)
|
||||
seg2.SetWidth(120000)
|
||||
seg2.SetStart(wxPoint(rect.x1, rect.y2))
|
||||
seg2.SetEnd(wxPoint(rect.x2, rect.y1))
|
||||
seg2.SetLayer(layer)
|
||||
return [seg1, seg2]
|
||||
|
||||
def filter_components(self, board):
|
||||
# Apply the variants and filters
|
||||
exclude = None
|
||||
if hasattr(self, 'variant') and (self.dnf_filter or self.variant):
|
||||
load_sch()
|
||||
# Get the components list from the schematic
|
||||
comps = GS.sch.get_components()
|
||||
# Apply the filter
|
||||
apply_fitted_filter(comps, self.dnf_filter)
|
||||
# Apply the variant
|
||||
if self.variant:
|
||||
# Apply the variant
|
||||
self.variant.filter(comps)
|
||||
comps_hash = {c.ref: c for c in comps}
|
||||
# Remove from solder past layers the filtered components
|
||||
exclude = LSET()
|
||||
exclude.addLayer(board.GetLayerID('F.Paste'))
|
||||
exclude.addLayer(board.GetLayerID('B.Paste'))
|
||||
old_layers = []
|
||||
fadhes = board.GetLayerID('F.Adhes')
|
||||
badhes = board.GetLayerID('B.Adhes')
|
||||
old_fadhes = []
|
||||
old_badhes = []
|
||||
ffab = board.GetLayerID('F.Fab')
|
||||
bfab = board.GetLayerID('B.Fab')
|
||||
extra_ffab_lines = []
|
||||
extra_bfab_lines = []
|
||||
for m in board.GetModules():
|
||||
ref = m.GetReference()
|
||||
# Rectangle containing the drawings, no text
|
||||
frect = Rect()
|
||||
brect = Rect()
|
||||
c = comps_hash.get(ref, None)
|
||||
if (c and not c.fitted) or m.GetAttributes() == UI_VIRTUAL:
|
||||
# Remove all pads from *.Paste
|
||||
old_c_layers = []
|
||||
for p in m.Pads():
|
||||
pad_layers = p.GetLayerSet()
|
||||
old_c_layers.append(pad_layers.FmtHex())
|
||||
pad_layers.removeLayerSet(exclude)
|
||||
p.SetLayerSet(pad_layers)
|
||||
old_layers.append(old_c_layers)
|
||||
# Remove any graphical item in the *.Adhes layers
|
||||
# Also: meassure the *.Fab drawings size
|
||||
for gi in m.GraphicalItems():
|
||||
l_gi = gi.GetLayer()
|
||||
if l_gi == fadhes:
|
||||
gi.SetLayer(-1)
|
||||
old_fadhes.append(gi)
|
||||
if l_gi == badhes:
|
||||
gi.SetLayer(-1)
|
||||
old_badhes.append(gi)
|
||||
if gi.GetClass() == 'MGRAPHIC':
|
||||
if l_gi == ffab:
|
||||
frect.Union(gi.GetBoundingBox().getWxRect())
|
||||
if l_gi == bfab:
|
||||
brect.Union(gi.GetBoundingBox().getWxRect())
|
||||
# Cross the graphics in *.Fab
|
||||
if frect.x1 is not None:
|
||||
extra_ffab_lines.append(self.cross_module(m, frect, ffab))
|
||||
else:
|
||||
extra_ffab_lines.append(None)
|
||||
if brect.x1 is not None:
|
||||
extra_bfab_lines.append(self.cross_module(m, brect, bfab))
|
||||
else:
|
||||
extra_bfab_lines.append(None)
|
||||
# Store the data to undo the above actions
|
||||
self.comps_hash = comps_hash
|
||||
self.old_layers = old_layers
|
||||
self.old_fadhes = old_fadhes
|
||||
self.old_badhes = old_badhes
|
||||
self.extra_ffab_lines = extra_ffab_lines
|
||||
self.extra_bfab_lines = extra_bfab_lines
|
||||
return exclude
|
||||
|
||||
def unfilter_components(self, board):
|
||||
for m in board.GetModules():
|
||||
ref = m.GetReference()
|
||||
c = self.comps_hash.get(ref, None)
|
||||
if (c and not c.fitted) or m.GetAttributes() == UI_VIRTUAL:
|
||||
restore = self.old_layers.pop(0)
|
||||
for p in m.Pads():
|
||||
pad_layers = p.GetLayerSet()
|
||||
res = restore.pop(0)
|
||||
pad_layers.ParseHex(res, len(res))
|
||||
p.SetLayerSet(pad_layers)
|
||||
restore = self.extra_ffab_lines.pop(0)
|
||||
if restore:
|
||||
for line in restore:
|
||||
m.Remove(line)
|
||||
restore = self.extra_bfab_lines.pop(0)
|
||||
if restore:
|
||||
for line in restore:
|
||||
m.Remove(line)
|
||||
fadhes = board.GetLayerID('F.Adhes')
|
||||
for gi in self.old_fadhes:
|
||||
gi.SetLayer(fadhes)
|
||||
badhes = board.GetLayerID('B.Adhes')
|
||||
for gi in self.old_badhes:
|
||||
gi.SetLayer(badhes)
|
||||
|
||||
def run(self, output_dir, board, layers):
|
||||
# fresh plot controller
|
||||
plot_ctrl = PLOT_CONTROLLER(board)
|
||||
# set up plot options for the whole output
|
||||
po = plot_ctrl.GetPlotOptions()
|
||||
self._configure_plot_ctrl(po, output_dir)
|
||||
|
||||
# Gerber Job files aren't automagically created
|
||||
# We need to assist KiCad
|
||||
create_job = po.GetCreateGerberJobFile()
|
||||
if create_job:
|
||||
jobfile_writer = GERBER_JOBFILE_WRITER(board)
|
||||
|
||||
plot_ctrl.SetColorMode(True)
|
||||
|
||||
# Apply the variants and filters
|
||||
exclude = self.filter_components(board)
|
||||
# Plot every layer in the output
|
||||
layers = Layer.solve(layers)
|
||||
# plot every layer in the output
|
||||
for la in layers:
|
||||
suffix = la.suffix
|
||||
desc = la.description
|
||||
|
|
@ -82,13 +234,12 @@ class AnyLayerOptions(BaseOptions):
|
|||
# a copper layer
|
||||
is_cu = IsCopperLayer(id)
|
||||
po.SetSkipPlotNPTH_Pads(is_cu)
|
||||
|
||||
# Plot single layer to file
|
||||
logger.debug("Opening plot file for layer `{}` format `{}`".format(la, self._plot_format))
|
||||
if not plot_ctrl.OpenPlotfile(suffix, self._plot_format, desc):
|
||||
# Shouldn't happen
|
||||
raise PlotError("OpenPlotfile failed!") # pragma: no cover
|
||||
|
||||
# Compute the current file name and the one we want
|
||||
k_filename = plot_ctrl.GetPlotFileName()
|
||||
if self.output:
|
||||
filename = self.expand_filename(output_dir, self.output, suffix, os.path.splitext(k_filename)[1][1:])
|
||||
|
|
@ -101,9 +252,12 @@ class AnyLayerOptions(BaseOptions):
|
|||
os.rename(k_filename, filename)
|
||||
if create_job:
|
||||
jobfile_writer.AddGbrFile(id, os.path.basename(filename))
|
||||
|
||||
# Create the job file
|
||||
if create_job:
|
||||
jobfile_writer.CreateJobFile(self.expand_filename(output_dir, po.gerber_job_file, 'job', 'gbrjob'))
|
||||
# Restore the eliminated layers
|
||||
if exclude:
|
||||
self.unfilter_components(board)
|
||||
|
||||
def read_vals_from_po(self, po):
|
||||
# excludeedgelayer
|
||||
|
|
|
|||
|
|
@ -11,16 +11,13 @@ from pcbnew import (IU_PER_MM, IU_PER_MILS)
|
|||
from .optionable import BaseOptions, Optionable
|
||||
from .registrable import RegOutput
|
||||
from .gs import GS
|
||||
from .misc import UI_SMD, UI_VIRTUAL
|
||||
from .kiplot import load_sch
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from .fil_base import BaseFilter, apply_fitted_filter
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
# KiCad 5 GUI values for the attribute
|
||||
UI_THT = 0
|
||||
UI_SMD = 1
|
||||
UI_VIRTUAL = 2
|
||||
|
||||
|
||||
class PositionOptions(BaseOptions):
|
||||
|
|
@ -167,8 +164,6 @@ class PositionOptions(BaseOptions):
|
|||
# Apply any filter or variant data
|
||||
if comps:
|
||||
c = comps_hash.get(ref, None)
|
||||
if c:
|
||||
logger.debug("{} {} {}".format(ref, c.fitted, c.in_bom))
|
||||
if c and not c.fitted:
|
||||
continue
|
||||
# If passed check the position options
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@
|
|||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
|
|
@ -171,6 +172,7 @@
|
|||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
|
|
@ -207,6 +209,7 @@
|
|||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
|
|
@ -242,6 +245,7 @@
|
|||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
|
|
@ -278,6 +282,7 @@
|
|||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,308 @@
|
|||
(kicad_pcb (version 20171130) (host pcbnew 5.1.6+dfsg1-1)
|
||||
|
||||
(general
|
||||
(thickness 1.6)
|
||||
(drawings 5)
|
||||
(tracks 0)
|
||||
(zones 0)
|
||||
(modules 5)
|
||||
(nets 9)
|
||||
)
|
||||
|
||||
(page A4)
|
||||
(layers
|
||||
(0 F.Cu signal)
|
||||
(31 B.Cu signal)
|
||||
(32 B.Adhes user)
|
||||
(33 F.Adhes user)
|
||||
(34 B.Paste user)
|
||||
(35 F.Paste user)
|
||||
(36 B.SilkS user)
|
||||
(37 F.SilkS user)
|
||||
(38 B.Mask user)
|
||||
(39 F.Mask user)
|
||||
(40 Dwgs.User user)
|
||||
(41 Cmts.User user)
|
||||
(42 Eco1.User user)
|
||||
(43 Eco2.User user)
|
||||
(44 Edge.Cuts user)
|
||||
(45 Margin user)
|
||||
(46 B.CrtYd user)
|
||||
(47 F.CrtYd user)
|
||||
(48 B.Fab user)
|
||||
(49 F.Fab user)
|
||||
)
|
||||
|
||||
(setup
|
||||
(last_trace_width 0.25)
|
||||
(trace_clearance 0.2)
|
||||
(zone_clearance 0.508)
|
||||
(zone_45_only no)
|
||||
(trace_min 0.2)
|
||||
(via_size 0.8)
|
||||
(via_drill 0.4)
|
||||
(via_min_size 0.4)
|
||||
(via_min_drill 0.3)
|
||||
(uvia_size 0.3)
|
||||
(uvia_drill 0.1)
|
||||
(uvias_allowed no)
|
||||
(uvia_min_size 0.2)
|
||||
(uvia_min_drill 0.1)
|
||||
(edge_width 0.1)
|
||||
(segment_width 0.2)
|
||||
(pcb_text_width 0.3)
|
||||
(pcb_text_size 1.5 1.5)
|
||||
(mod_edge_width 0.15)
|
||||
(mod_text_size 1 1)
|
||||
(mod_text_width 0.15)
|
||||
(pad_size 1.524 1.524)
|
||||
(pad_drill 0.762)
|
||||
(pad_to_mask_clearance 0)
|
||||
(aux_axis_origin 139.89 89.63)
|
||||
(visible_elements FFFFFF7F)
|
||||
(pcbplotparams
|
||||
(layerselection 0x010fc_ffffffff)
|
||||
(usegerberextensions false)
|
||||
(usegerberattributes true)
|
||||
(usegerberadvancedattributes true)
|
||||
(creategerberjobfile true)
|
||||
(excludeedgelayer true)
|
||||
(linewidth 0.100000)
|
||||
(plotframeref false)
|
||||
(viasonmask false)
|
||||
(mode 1)
|
||||
(useauxorigin false)
|
||||
(hpglpennumber 1)
|
||||
(hpglpenspeed 20)
|
||||
(hpglpendiameter 15.000000)
|
||||
(psnegative false)
|
||||
(psa4output false)
|
||||
(plotreference true)
|
||||
(plotvalue true)
|
||||
(plotinvisibletext false)
|
||||
(padsonsilk false)
|
||||
(subtractmaskfromsilk false)
|
||||
(outputformat 1)
|
||||
(mirror false)
|
||||
(drillshape 1)
|
||||
(scaleselection 1)
|
||||
(outputdirectory ""))
|
||||
)
|
||||
|
||||
(net 0 "")
|
||||
(net 1 "Net-(C1-Pad2)")
|
||||
(net 2 "Net-(C1-Pad1)")
|
||||
(net 3 "Net-(C2-Pad2)")
|
||||
(net 4 "Net-(C2-Pad1)")
|
||||
(net 5 "Net-(R1-Pad2)")
|
||||
(net 6 "Net-(R1-Pad1)")
|
||||
(net 7 "Net-(R2-Pad2)")
|
||||
(net 8 "Net-(R2-Pad1)")
|
||||
|
||||
(net_class Default "Esta es la clase de red por defecto."
|
||||
(clearance 0.2)
|
||||
(trace_width 0.25)
|
||||
(via_dia 0.8)
|
||||
(via_drill 0.4)
|
||||
(uvia_dia 0.3)
|
||||
(uvia_drill 0.1)
|
||||
(add_net "Net-(C1-Pad1)")
|
||||
(add_net "Net-(C1-Pad2)")
|
||||
(add_net "Net-(C2-Pad1)")
|
||||
(add_net "Net-(C2-Pad2)")
|
||||
(add_net "Net-(R1-Pad1)")
|
||||
(add_net "Net-(R1-Pad2)")
|
||||
(add_net "Net-(R2-Pad1)")
|
||||
(add_net "Net-(R2-Pad2)")
|
||||
)
|
||||
|
||||
(module Resistor_SMD:R_0805_2012Metric (layer F.Cu) (tedit 5B36C52B) (tstamp 5F503C4A)
|
||||
(at 148.555 89.154)
|
||||
(descr "Resistor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
|
||||
(tags resistor)
|
||||
(path /5F43D144)
|
||||
(attr smd)
|
||||
(fp_text reference R3 (at 0 -1.65) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value 1k (at 0 1.65) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 0.95) (end -1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.258578 0.71) (end 0.258578 0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.258578 -0.71) (end 0.258578 -0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start 1 0.6) (end -1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 1 -0.6) (end 1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 -0.6) (end 1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 0.6) (end -1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
(pad 1 smd roundrect (at -0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(pad 2 smd roundrect (at 0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25))
|
||||
(model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
||||
|
||||
(module Resistor_SMD:R_0805_2012Metric (layer F.Cu) (tedit 5B36C52B) (tstamp 5F496A8B)
|
||||
(at 141.57 90.58)
|
||||
(descr "Resistor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
|
||||
(tags resistor)
|
||||
(path /5F43D4BB)
|
||||
(fp_text reference R2 (at 0 -1.65) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value 1000 (at 1.178 2.13) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 0.95) (end -1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.258578 0.71) (end 0.258578 0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.258578 -0.71) (end 0.258578 -0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start 1 0.6) (end -1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 1 -0.6) (end 1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 -0.6) (end 1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 0.6) (end -1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
(pad 2 smd roundrect (at 0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
|
||||
(net 7 "Net-(R2-Pad2)"))
|
||||
(pad 1 smd roundrect (at -0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
|
||||
(net 8 "Net-(R2-Pad1)"))
|
||||
(model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
||||
|
||||
(module Resistor_SMD:R_0805_2012Metric (layer F.Cu) (tedit 5B36C52B) (tstamp 5F503C2A)
|
||||
(at 141.57 87.63)
|
||||
(descr "Resistor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
|
||||
(tags resistor)
|
||||
(path /5F43D144)
|
||||
(attr smd)
|
||||
(fp_text reference R1 (at 0 -1.65) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value 1k (at 0 1.65) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 0.95) (end -1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.258578 0.71) (end 0.258578 0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.258578 -0.71) (end 0.258578 -0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start 1 0.6) (end -1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 1 -0.6) (end 1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 -0.6) (end 1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 0.6) (end -1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
(pad 2 smd roundrect (at 0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
|
||||
(net 5 "Net-(R1-Pad2)"))
|
||||
(pad 1 smd roundrect (at -0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
|
||||
(net 6 "Net-(R1-Pad1)"))
|
||||
(model ${KISYS3DMOD}/Resistor_SMD.3dshapes/R_0805_2012Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
||||
|
||||
(module Capacitor_SMD:C_0805_2012Metric (layer B.Cu) (tedit 5B36C52B) (tstamp 5F496A69)
|
||||
(at 137.16 90.58)
|
||||
(descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
|
||||
(tags capacitor)
|
||||
(path /5F43CE1C)
|
||||
(fp_text reference C2 (at 0 1.65) (layer B.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
|
||||
)
|
||||
(fp_text value "1000 pF" (at -0.508 -2.13) (layer B.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)) (justify mirror))
|
||||
)
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer B.Adhes) (width 0.1))
|
||||
(fp_line (start 1.68 -0.95) (end -1.68 -0.95) (layer B.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 0.95) (end 1.68 -0.95) (layer B.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 0.95) (end 1.68 0.95) (layer B.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 -0.95) (end -1.68 0.95) (layer B.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.258578 -0.71) (end 0.258578 -0.71) (layer B.SilkS) (width 0.12))
|
||||
(fp_line (start -0.258578 0.71) (end 0.258578 0.71) (layer B.SilkS) (width 0.12))
|
||||
(fp_line (start 1 -0.6) (end -1 -0.6) (layer B.Fab) (width 0.1))
|
||||
(fp_line (start 1 0.6) (end 1 -0.6) (layer B.Fab) (width 0.1))
|
||||
(fp_line (start -1 0.6) (end 1 0.6) (layer B.Fab) (width 0.1))
|
||||
(fp_line (start -1 -0.6) (end -1 0.6) (layer B.Fab) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer B.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)) (justify mirror))
|
||||
)
|
||||
(pad 2 smd roundrect (at 0.9375 0) (size 0.975 1.4) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)
|
||||
(net 3 "Net-(C2-Pad2)"))
|
||||
(pad 1 smd roundrect (at -0.9375 0) (size 0.975 1.4) (layers B.Cu B.Paste B.Mask) (roundrect_rratio 0.25)
|
||||
(net 4 "Net-(C2-Pad1)"))
|
||||
(model ${KISYS3DMOD}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
||||
|
||||
(module Capacitor_SMD:C_0805_2012Metric (layer F.Cu) (tedit 5B36C52B) (tstamp 5F496A58)
|
||||
(at 137.16 87.63)
|
||||
(descr "Capacitor SMD 0805 (2012 Metric), square (rectangular) end terminal, IPC_7351 nominal, (Body size source: https://docs.google.com/spreadsheets/d/1BsfQQcO9C6DZCsRaXUlFlo91Tg2WpOkGARC1WS5S8t0/edit?usp=sharing), generated with kicad-footprint-generator")
|
||||
(tags capacitor)
|
||||
(path /5F43BEC2)
|
||||
(attr virtual)
|
||||
(fp_text reference C1 (at 0 -1.65) (layer F.SilkS)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_text value 1nF (at 0 1.65) (layer F.Fab)
|
||||
(effects (font (size 1 1) (thickness 0.15)))
|
||||
)
|
||||
(fp_circle (center 0 0) (end 0.4 0) (layer F.Adhes) (width 0.1))
|
||||
(fp_line (start 1.68 0.95) (end -1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start 1.68 -0.95) (end 1.68 0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 -0.95) (end 1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -1.68 0.95) (end -1.68 -0.95) (layer F.CrtYd) (width 0.05))
|
||||
(fp_line (start -0.258578 0.71) (end 0.258578 0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start -0.258578 -0.71) (end 0.258578 -0.71) (layer F.SilkS) (width 0.12))
|
||||
(fp_line (start 1 0.6) (end -1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start 1 -0.6) (end 1 0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 -0.6) (end 1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_line (start -1 0.6) (end -1 -0.6) (layer F.Fab) (width 0.1))
|
||||
(fp_text user %R (at 0 0) (layer F.Fab)
|
||||
(effects (font (size 0.5 0.5) (thickness 0.08)))
|
||||
)
|
||||
(pad 2 smd roundrect (at 0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
|
||||
(net 1 "Net-(C1-Pad2)"))
|
||||
(pad 1 smd roundrect (at -0.9375 0) (size 0.975 1.4) (layers F.Cu F.Paste F.Mask) (roundrect_rratio 0.25)
|
||||
(net 2 "Net-(C1-Pad1)"))
|
||||
(model ${KISYS3DMOD}/Capacitor_SMD.3dshapes/C_0805_2012Metric.wrl
|
||||
(at (xyz 0 0 0))
|
||||
(scale (xyz 1 1 1))
|
||||
(rotate (xyz 0 0 0))
|
||||
)
|
||||
)
|
||||
|
||||
(gr_text "Bogus component.\nNot in schematic." (at 161.163 89.281) (layer Cmts.User)
|
||||
(effects (font (size 1.5 1.5) (thickness 0.3)))
|
||||
)
|
||||
(gr_line (start 133.35 83.82) (end 133.35 93.98) (layer Edge.Cuts) (width 0.1) (tstamp 5F496ACC))
|
||||
(gr_line (start 146.05 83.82) (end 133.35 83.82) (layer Edge.Cuts) (width 0.1))
|
||||
(gr_line (start 146.05 93.98) (end 146.05 83.82) (layer Edge.Cuts) (width 0.1))
|
||||
(gr_line (start 133.35 93.98) (end 146.05 93.98) (layer Edge.Cuts) (width 0.1))
|
||||
|
||||
)
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
EESchema Schematic File Version 4
|
||||
EELAYER 30 0
|
||||
EELAYER END
|
||||
$Descr A4 11693 8268
|
||||
encoding utf-8
|
||||
Sheet 1 1
|
||||
Title "KiBom Test Schematic"
|
||||
Date "2020-03-12"
|
||||
Rev "A"
|
||||
Comp "https://github.com/SchrodingersGat/KiBom"
|
||||
Comment1 ""
|
||||
Comment2 ""
|
||||
Comment3 ""
|
||||
Comment4 ""
|
||||
$EndDescr
|
||||
Text Notes 500 750 0 79 ~ 0
|
||||
This schematic serves as a test-file for the KiBot export script.\nHere we implement the IBoM variants style.
|
||||
$Comp
|
||||
L Device:C C1
|
||||
U 1 1 5F43BEC2
|
||||
P 1000 1700
|
||||
F 0 "C1" H 1115 1746 50 0000 L CNN
|
||||
F 1 "1nF" H 1115 1655 50 0000 L CNN
|
||||
F 2 "Capacitor_SMD:C_0805_2012Metric" H 1038 1550 50 0001 C CNN
|
||||
F 3 "~" H 1000 1700 50 0001 C CNN
|
||||
F 4 "T2" H 1000 1700 50 0001 C CNN "Config"
|
||||
1 1000 1700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:C C2
|
||||
U 1 1 5F43CE1C
|
||||
P 1450 1700
|
||||
F 0 "C2" H 1565 1746 50 0000 L CNN
|
||||
F 1 "1000 pF" H 1565 1655 50 0000 L CNN
|
||||
F 2 "Capacitor_SMD:C_0805_2012Metric" H 1488 1550 50 0001 C CNN
|
||||
F 3 "~" H 1450 1700 50 0001 C CNN
|
||||
F 4 "T3" H 1450 1700 50 0001 C CNN "Config"
|
||||
1 1450 1700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R1
|
||||
U 1 1 5F43D144
|
||||
P 2100 1700
|
||||
F 0 "R1" H 2170 1746 50 0000 L CNN
|
||||
F 1 "1k" H 2170 1655 50 0000 L CNN
|
||||
F 2 "Resistor_SMD:R_0805_2012Metric" V 2030 1700 50 0001 C CNN
|
||||
F 3 "~" H 2100 1700 50 0001 C CNN
|
||||
F 4 "default" H 2100 1700 50 0001 C CNN "Config"
|
||||
1 2100 1700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
$Comp
|
||||
L Device:R R2
|
||||
U 1 1 5F43D4BB
|
||||
P 2500 1700
|
||||
F 0 "R2" H 2570 1746 50 0000 L CNN
|
||||
F 1 "1000" H 2570 1655 50 0000 L CNN
|
||||
F 2 "Resistor_SMD:R_0805_2012Metric" V 2430 1700 50 0001 C CNN
|
||||
F 3 "~" H 2500 1700 50 0001 C CNN
|
||||
F 4 "T1" H 2500 1700 50 0001 C CNN "Config"
|
||||
1 2500 1700
|
||||
1 0 0 -1
|
||||
$EndComp
|
||||
Text Notes 5950 3200 0 118 ~ 0
|
||||
The test tests the following \nvariants matrix:\n production test default\nC1 X\nC2 X X\nR1 X X X\nR2 X X\n\nproduction: blacklist T2\ntest: blacklist T1\ndefault: whitelist T1,default \n blacklist T2,T3
|
||||
$EndSCHEMATC
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -19,6 +19,27 @@ from kibot.misc import (PLOT_ERROR)
|
|||
|
||||
|
||||
GERBER_DIR = 'gerberdir'
|
||||
ALL_LAYERS = ['B_Adhes',
|
||||
'B_CrtYd',
|
||||
'B_Cu',
|
||||
'B_Fab',
|
||||
'B_Mask',
|
||||
'B_Paste',
|
||||
'B_SilkS',
|
||||
'Cmts_User',
|
||||
'Dwgs_User',
|
||||
'Eco1_User',
|
||||
'Eco2_User',
|
||||
'Edge_Cuts',
|
||||
'F_Adhes',
|
||||
'F_CrtYd',
|
||||
'F_Cu',
|
||||
'F_Fab',
|
||||
'F_Mask',
|
||||
'F_Paste',
|
||||
'F_SilkS',
|
||||
'Margin',
|
||||
]
|
||||
|
||||
|
||||
def test_gerber_2layer():
|
||||
|
|
@ -58,3 +79,40 @@ def test_gerber_inner_wrong():
|
|||
ctx.run(PLOT_ERROR)
|
||||
assert ctx.search_err('is not valid for this board')
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def compose_fname(dir, prefix, layer, suffix, ext='gbr'):
|
||||
return os.path.join(dir, prefix+'-'+layer+suffix+'.'+ext)
|
||||
|
||||
|
||||
def check_layers_exist(ctx, dir, prefix, layers, suffix):
|
||||
for layer in layers:
|
||||
ctx.expect_out_file(compose_fname(dir, prefix, layer, suffix))
|
||||
ctx.expect_out_file(compose_fname(dir, prefix, 'job', suffix, 'gbrjob'))
|
||||
|
||||
|
||||
def check_components(ctx, dir, prefix, layers, suffix, exclude, include):
|
||||
for layer in layers:
|
||||
fname = compose_fname(dir, prefix, layer, suffix)
|
||||
inc = [r'%TO\.C,{}\*%'.format(v) for v in include]
|
||||
ctx.search_in_file(fname, inc)
|
||||
exc = [r'%TO\.C,{}\*%'.format(v) for v in exclude]
|
||||
ctx.search_not_in_file(fname, exc)
|
||||
|
||||
|
||||
def test_gerber_variant_1():
|
||||
prj = 'kibom-variant_3'
|
||||
ctx = context.TestContext('test_gerber_variant_1', prj, 'gerber_variant_1', GERBER_DIR)
|
||||
ctx.run()
|
||||
# C1 is virtual, not included for all cases
|
||||
# R3 is a component added to the PCB, included in all cases
|
||||
# variant: default directory: gerber components: R1, R2 and R3
|
||||
check_layers_exist(ctx, 'gerber', prj, ALL_LAYERS, '')
|
||||
check_components(ctx, 'gerber', prj, ['F_Paste', 'F_Adhes'], '', ['C1', 'C2'], ['R1', 'R2', 'R3'])
|
||||
# variant: production directory: production components: R1, R2, R3 and C2
|
||||
check_layers_exist(ctx, 'production', prj, ALL_LAYERS, '_(production)')
|
||||
check_components(ctx, 'production', prj, ['F_Paste', 'F_Adhes'], '_(production)', ['C1'], ['R1', 'R2', 'R3', 'C2'])
|
||||
# variant: test directory: test components: R1, R3 and C2
|
||||
check_layers_exist(ctx, 'test', prj, ALL_LAYERS, '_(test)')
|
||||
check_components(ctx, 'test', prj, ['F_Paste', 'F_Adhes'], '_(test)', ['C1', 'R2'], ['R1', 'R3', 'C2'])
|
||||
ctx.clean_up()
|
||||
|
|
|
|||
|
|
@ -22,13 +22,11 @@ def test_pdf():
|
|||
prj = 'simple_2layer'
|
||||
ctx = context.TestContext('Plot_PDF', prj, 'pdf', PS_DIR)
|
||||
ctx.run()
|
||||
|
||||
f_cu = ctx.get_gerber_filename('F_Cu', '.pdf')
|
||||
f_silk = ctx.get_gerber_filename('B_Silks', '.pdf')
|
||||
ctx.expect_out_file(f_cu)
|
||||
ctx.expect_out_file(f_silk)
|
||||
ctx.dont_expect_out_file(ctx.get_gerber_job_filename())
|
||||
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
|
|
@ -36,7 +34,20 @@ def test_pdf_refill():
|
|||
prj = 'zone-refill'
|
||||
ctx = context.TestContext('Plot_PDF_Refill', prj, 'pdf_zone-refill', '')
|
||||
ctx.run()
|
||||
|
||||
b_cu = ctx.get_gerber_filename('B_Cu', '.pdf')
|
||||
ctx.expect_out_file(b_cu)
|
||||
ctx.compare_image(b_cu)
|
||||
ctx.clean_up()
|
||||
|
||||
|
||||
def test_pdf_variant_1():
|
||||
prj = 'kibom-variant_4'
|
||||
ctx = context.TestContext('test_pdf_variant_1', prj, 'pdf_variant_1', '')
|
||||
ctx.run()
|
||||
fname = prj+'-F_Fab.pdf'
|
||||
ctx.expect_out_file(fname)
|
||||
ctx.compare_image(fname)
|
||||
fname = prj+'-B_Fab.pdf'
|
||||
ctx.expect_out_file(fname)
|
||||
ctx.compare_image(fname)
|
||||
ctx.clean_up()
|
||||
|
|
|
|||
|
|
@ -304,9 +304,11 @@ class TestContext(object):
|
|||
with open(self.get_out_path(file)) as f:
|
||||
txt = f.read()
|
||||
for t in texts:
|
||||
logging.debug('- r"'+t+'"')
|
||||
msg = '- r"'+t+'"'
|
||||
m = re.search(t, txt, re.MULTILINE)
|
||||
assert m is None
|
||||
assert m is None, msg
|
||||
logging.debug(msg+' OK')
|
||||
# logging.debug(' '+m.group(0))
|
||||
|
||||
def compare_image(self, image, reference=None, diff='diff.png', ref_out_dir=False):
|
||||
""" For images and single page PDFs """
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
variants:
|
||||
- name: 'production'
|
||||
comment: 'Production variant'
|
||||
type: ibom
|
||||
file_id: '_(production)'
|
||||
variants_blacklist: T2
|
||||
|
||||
- name: 'test'
|
||||
comment: 'Test variant'
|
||||
type: ibom
|
||||
file_id: '_(test)'
|
||||
variants_blacklist: T1
|
||||
|
||||
- name: 'default'
|
||||
comment: 'Default variant'
|
||||
type: ibom
|
||||
variants_blacklist: T2,T3
|
||||
|
||||
outputs:
|
||||
- name: 'gerber'
|
||||
comment: "Gerber"
|
||||
type: gerber
|
||||
dir: gerber
|
||||
layers: all
|
||||
options:
|
||||
variant: default
|
||||
|
||||
- name: 'gerber_production'
|
||||
comment: "Gerber for production"
|
||||
type: gerber
|
||||
dir: production
|
||||
layers: all
|
||||
options:
|
||||
variant: production
|
||||
|
||||
- name: 'gerber_test'
|
||||
comment: "Gerber for test"
|
||||
type: gerber
|
||||
dir: test
|
||||
layers: all
|
||||
options:
|
||||
variant: test
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# Example KiBot config file
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
variants:
|
||||
- name: 'default'
|
||||
comment: 'Default variant'
|
||||
type: ibom
|
||||
variants_blacklist: T2,T3
|
||||
|
||||
outputs:
|
||||
- name: 'pdf_default'
|
||||
comment: "PDF w/variant"
|
||||
type: pdf
|
||||
layers: [ F.Fab, B.Fab ]
|
||||
options:
|
||||
variant: default
|
||||
|
||||
Loading…
Reference in New Issue