We no longer need to plot the files to know the KiCad's name.

Much faster.
This commit is contained in:
Salvador E. Tropea 2021-01-18 17:23:27 -03:00
parent 88cd5927dc
commit 50f38ea71b
2 changed files with 51 additions and 22 deletions

View File

@ -75,6 +75,20 @@ class Layer(Optionable):
'F.CrtYd': 'F.Courtyard',
'B.CrtYd': 'B.Courtyard',
}
# Protel extensions
PROTEL_EXTENSIONS = {
pcbnew.F_Cu: 'gtl',
pcbnew.B_Cu: 'gbl',
pcbnew.F_Adhes: 'gta',
pcbnew.B_Adhes: 'gba',
pcbnew.F_Paste: 'gtp',
pcbnew.B_Paste: 'gbp',
pcbnew.F_SilkS: 'gto',
pcbnew.B_SilkS: 'gbo',
pcbnew.F_Mask: 'gts',
pcbnew.B_Mask: 'gbs',
pcbnew.Edge_Cuts: 'gm1',
}
# Names from the board file
_pcb_layers = None
_plot_layers = None
@ -87,8 +101,9 @@ class Layer(Optionable):
self.suffix = ''
""" Suffix used in file names related to this layer. Derived from the name if not specified """
self.description = ''
""" A description for the layer, for documentation purposes """ # pragma: no cover
""" A description for the layer, for documentation purposes """
self._unkown_is_error = True
self._protel_extension = None
def config(self):
super().config()
@ -106,6 +121,20 @@ class Layer(Optionable):
def id(self):
return self._id
def fix_protel_ext(self):
""" Makes sure we have a defined Protel extension """
if self._protel_extension is not None:
# Already set, keep it
return
if self._is_inner:
self._protel_extension = 'g'+str(self.id-pcbnew.F_Cu+1)
return
if self.id in Layer.PROTEL_EXTENSIONS:
self._protel_extension = Layer.PROTEL_EXTENSIONS[self.id]
return
self._protel_extension = 'gbr'
return
@staticmethod
def solve(values):
board = GS.board
@ -135,6 +164,7 @@ class Layer(Optionable):
# Check if the layer is in use
if layer._is_inner and (layer._id < 1 or layer._id >= layer_cnt - 1):
raise PlotError("Inner layer `{}` is not valid for this board".format(layer))
layer.fix_protel_ext()
new_vals.append(layer)
else: # A string
ext = None
@ -184,6 +214,7 @@ class Layer(Optionable):
layer.suffix = name.replace('.', '_')
layer.description = Layer.DEFAULT_LAYER_DESC.get(name)
layer._get_layer_id_from_name()
layer.fix_protel_ext()
return layer
@staticmethod
@ -213,7 +244,7 @@ class Layer(Optionable):
if id is not None:
# 2) List from the PCB
self._id = id
self._is_inner = id < pcbnew.B_Cu
self._is_inner = id > pcbnew.F_Cu and id < pcbnew.B_Cu
elif self.layer.startswith("Inner"):
# 3) Inner.N names
m = match(r"^Inner\.([0-9]+)$", self.layer)

View File

@ -7,9 +7,8 @@
# Adapted from: https://github.com/johnbeard/kiplot
import os
import re
from shutil import rmtree
from tempfile import mkdtemp
from pcbnew import GERBER_JOBFILE_WRITER, PLOT_CONTROLLER, IsCopperLayer, F_Cu, B_Cu, Edge_Cuts
from pcbnew import (GERBER_JOBFILE_WRITER, PLOT_CONTROLLER, IsCopperLayer, F_Cu, B_Cu, Edge_Cuts, PLOT_FORMAT_HPGL,
PLOT_FORMAT_GERBER, PLOT_FORMAT_POST, PLOT_FORMAT_DXF, PLOT_FORMAT_PDF, PLOT_FORMAT_SVG)
from .optionable import Optionable
from .out_base import BaseOutput, VariantOptions
from .error import PlotError, KiPlotConfigurationError
@ -22,6 +21,14 @@ from . import log
logger = log.get_logger(__name__)
FORMAT_EXTENSIONS = {PLOT_FORMAT_HPGL: 'plt',
PLOT_FORMAT_GERBER: 'gbr',
PLOT_FORMAT_POST: 'ps',
PLOT_FORMAT_DXF: 'dxf',
PLOT_FORMAT_PDF: 'pdf',
PLOT_FORMAT_SVG: 'svg'}
class CustomReport(Optionable):
def __init__(self):
super().__init__()
@ -187,34 +194,25 @@ class AnyLayerOptions(VariantOptions):
if exclude:
self.unfilter_components(GS.board)
def solve_extension(self, layer):
if self._plot_format == PLOT_FORMAT_GERBER and self.use_protel_extensions:
return layer._protel_extension
return FORMAT_EXTENSIONS[self._plot_format]
def get_targets(self, output_dir, layers):
# This is tricky because we can use names generated by KiCad
targets = []
# Configure KiCad's plotter
plot_ctrl = PLOT_CONTROLLER(GS.board)
po = plot_ctrl.GetPlotOptions()
self._configure_plot_ctrl(po, output_dir)
# KiCad doesn't assign an extension until we actually call OpenPlotFile
# So we create temporal files just to get their name :-(
tmp_dir = mkdtemp()
po.SetOutputDirectory(tmp_dir)
layers = Layer.solve(layers)
for la in layers:
id = la.id
if not GS.board.IsLayerEnabled(id):
continue
plot_ctrl.SetLayer(id)
plot_ctrl.OpenPlotfile(la.suffix, self._plot_format, '')
# Here we convert the temporal name to the actual name using replace
k_filename = plot_ctrl.GetPlotFileName().replace(tmp_dir, output_dir)
k_filename = self.expand_filename(output_dir, '%f-%i.%x', la.suffix, self.solve_extension(la))
filename = self.compute_name(k_filename, output_dir, self.output, id, la.suffix)
plot_ctrl.ClosePlot()
if GS.debug_level > 2:
logger.debug('Layer id {} file name {} ({})'.format(id, filename, k_filename))
targets.append(filename)
rmtree(tmp_dir)
if po.GetCreateGerberJobFile():
targets.append(self.expand_filename(output_dir, po.gerber_job_file, 'job', 'gbrjob'))
if self._plot_format == PLOT_FORMAT_GERBER and self.create_gerber_job_file:
targets.append(self.expand_filename(output_dir, self.gerber_job_file, 'job', 'gbrjob'))
for report in self.custom_reports:
targets.append(os.path.join(output_dir, report.output))
return targets