PCB PDF Print: mechanism to change the block title.

- Related to #102
- Also added %V to expand the variant name
- Documented %v and %V
This commit is contained in:
Salvador E. Tropea 2021-11-17 10:51:28 -03:00
parent cfcc9bea39
commit b4c1531e10
11 changed files with 73 additions and 15 deletions

View File

@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Generic filter: options to match if a field is/isn't defined.
- Excellon drill: added `route_mode_for_oval_holes` option.
- Default global `dir` option.
- Pattern to expand the variant name: %V
- PCB PDF Print: mechanism to change the block title. (#102)
### Changed
- Internal BoM: now components with different Tolerance, Voltage, Current

View File

@ -198,16 +198,18 @@ You can always choose the file name for a particular output.
The pattern uses the following expansions:
- **%f** original pcb/sch file name without extension.
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
- **%p** pcb/sch title from pcb metadata.
- **%c** company from pcb/sch metadata.
- **%r** revision from pcb/sch metadata.
- **%d** pcb/sch date from metadata if available, file modification date otherwise.
- **%D** date the script was started.
- **%T** time the script was started.
- **%f** original pcb/sch file name without extension.
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
- **%i** a contextual ID, depends on the output type.
- **%p** pcb/sch title from pcb metadata.
- **%r** revision from pcb/sch metadata.
- **%T** time the script was started.
- **%x** a suitable extension for the output type.
- **%v** the `file_id` of the current variant.
- **%V** the `name` of the current variant.
They are compatible with the ones used by IBoM.
The default value for `global.output` is `%f-%i.%x`.
@ -1299,6 +1301,8 @@ Next time you need this list just use an alias, like this:
- `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.
- `title`: [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
If it starts with `+` the text is concatenated.
- `variant`: [string=''] Board variant to apply.
* PDF Schematic Print (Portable Document Format)

View File

@ -177,16 +177,18 @@ You can always choose the file name for a particular output.
The pattern uses the following expansions:
- **%f** original pcb/sch file name without extension.
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
- **%p** pcb/sch title from pcb metadata.
- **%c** company from pcb/sch metadata.
- **%r** revision from pcb/sch metadata.
- **%d** pcb/sch date from metadata if available, file modification date otherwise.
- **%D** date the script was started.
- **%T** time the script was started.
- **%f** original pcb/sch file name without extension.
- **%F** original pcb/sch file name without extension. Including the directory part of the name.
- **%i** a contextual ID, depends on the output type.
- **%p** pcb/sch title from pcb metadata.
- **%r** revision from pcb/sch metadata.
- **%T** time the script was started.
- **%x** a suitable extension for the output type.
- **%v** the `file_id` of the current variant.
- **%V** the `name` of the current variant.
They are compatible with the ones used by IBoM.
The default value for `global.output` is `%f-%i.%x`.

View File

@ -898,6 +898,9 @@ outputs:
scaling: 1.0
# [boolean=false] Print layers in separated pages
separated: false
# [string=''] Text used to replace the sheet title. %VALUE expansions are allowed.
# If it starts with `+` the text is concatenated
title: ''
# [string=''] Board variant to apply
variant: ''
layers: all

View File

@ -194,6 +194,13 @@ class Optionable(object):
return self.variant.file_id
return ''
def _find_variant_name(self):
""" Returns the name for the current variant.
If no variant is defined an empty string is returned. """
if hasattr(self, 'variant') and self.variant and hasattr(self.variant, 'name'):
return self.variant.name
return ''
def expand_filename_pcb(self, name):
""" Expands %* values in filenames.
Uses data from the PCB. """
@ -210,6 +217,7 @@ class Optionable(object):
name = name.replace('%r', GS.pcb_rev)
name = name.replace('%T', GS.time)
name = name.replace('%v', self._find_variant() if self else '')
name = name.replace('%V', self._find_variant_name() if self else '')
name = name.replace('%x', self._expand_ext)
# sanitize the name to avoid characters illegal in file systems
name = name.replace('\\', '/')
@ -232,6 +240,7 @@ class Optionable(object):
name = name.replace('%r', GS.sch_rev)
name = name.replace('%T', GS.time)
name = name.replace('%v', self._find_variant() if self else '')
name = name.replace('%V', self._find_variant_name() if self else '')
name = name.replace('%x', self._expand_ext)
# sanitize the name to avoid characters illegal in file systems
name = name.replace('\\', '/')

View File

@ -179,6 +179,8 @@ class VariantOptions(BaseOptions):
def cross_modules(self, board, comps_hash):
""" Draw a cross in all 'not fitted' modules using *.Fab layer """
if comps_hash is None:
return
# Cross the affected components
ffab = board.GetLayerID('F.Fab')
bfab = board.GetLayerID('B.Fab')
@ -214,6 +216,8 @@ class VariantOptions(BaseOptions):
def uncross_modules(self, board, comps_hash):
""" Undo the crosses in *.Fab layer """
if comps_hash is None:
return
# Undo the drawings
for m in board.GetModules():
ref = m.GetReference()
@ -230,6 +234,8 @@ class VariantOptions(BaseOptions):
def remove_paste_and_glue(self, board, comps_hash):
""" Remove from solder paste layers the filtered components. """
if comps_hash is None:
return
exclude = LSET()
fpaste = board.GetLayerID('F.Paste')
bpaste = board.GetLayerID('B.Paste')
@ -279,6 +285,8 @@ class VariantOptions(BaseOptions):
return exclude
def restore_paste_and_glue(self, board, comps_hash):
if comps_hash is None:
return
for m in board.GetModules():
ref = m.GetReference()
c = comps_hash.get(ref, None)
@ -296,6 +304,8 @@ class VariantOptions(BaseOptions):
def remove_fab(self, board, comps_hash):
""" Remove from Fab the excluded components. """
if comps_hash is None:
return
ffab = board.GetLayerID('F.Fab')
bfab = board.GetLayerID('B.Fab')
old_ffab = []
@ -321,11 +331,28 @@ class VariantOptions(BaseOptions):
self.bfab = bfab
def restore_fab(self, board, comps_hash):
if comps_hash is None:
return
for gi in self.old_ffab:
gi.SetLayer(self.ffab)
for gi in self.old_bfab:
gi.SetLayer(self.bfab)
def set_title(self, title):
self.old_title = None
if title:
tb = GS.board.GetTitleBlock()
self.old_title = tb.GetTitle()
text = self.expand_filename_pcb(title)
if text[0] == '+':
text = self.old_title+text[1:]
tb.SetTitle(text)
def restore_title(self):
self.old_title = None
if self.old_title is not None:
GS.board.GetTitleBlock().SetTitle(self.old_title)
def run(self, output_dir):
""" Makes the list of components available """
if not self.dnf_filter and not self.variant:

View File

@ -43,6 +43,9 @@ class PDF_Pcb_PrintOptions(VariantOptions):
""" Print mirrored (X axis inverted). ONLY for KiCad 6 """
self.hide_excluded = False
""" Hide components in the Fab layer that are marked as excluded by a variant """
self.title = ''
""" Text used to replace the sheet title. %VALUE expansions are allowed.
If it starts with `+` the text is concatenated """
super().__init__()
self._expand_ext = 'pdf'
@ -71,8 +74,8 @@ class PDF_Pcb_PrintOptions(VariantOptions):
copy2(pro_name, pro_copy)
return pro_copy
def filter_components(self, board):
if not self._comps:
def filter_components(self, board, force_copy):
if not self._comps and not force_copy:
return GS.pcb_file, None
comps_hash = self.get_refs_hash()
self.cross_modules(board, comps_hash)
@ -85,7 +88,7 @@ class PDF_Pcb_PrintOptions(VariantOptions):
logger.debug('Storing filtered PCB to `{}`'.format(fname))
GS.board.Save(fname)
# Copy the project: avoids warnings, could carry some options
fproj = self._copy_project(fname)
self._copy_project(fname)
self.uncross_modules(board, comps_hash)
self.restore_paste_and_glue(board, comps_hash)
if self.hide_excluded:
@ -111,13 +114,15 @@ class PDF_Pcb_PrintOptions(VariantOptions):
cmd.append('--separate')
if self.mirror:
cmd.append('--mirror')
board_name, board_dir = self.filter_components(GS.board)
self.set_title(self.title)
board_name, board_dir = self.filter_components(GS.board, self.title != '')
cmd.extend([board_name, os.path.dirname(output)])
cmd, video_remove = add_extra_options(cmd)
# Add the layers
cmd.extend([la.layer for la in self._layers])
# Execute it
ret = exec_with_retry(cmd)
self.restore_title()
# Remove the temporal PCB
if board_dir:
logger.debug('Removing temporal variant dir `{}`'.format(board_dir))

View File

@ -107,3 +107,6 @@ class BasePreFlight(Registrable):
def _find_variant(self):
return ''
def _find_variant_name(self):
return ''

View File

@ -21,7 +21,7 @@ class BaseVariant(RegVariant):
self.comment = ''
""" A comment for documentation purposes """
self.file_id = ''
""" Text to use as the """
""" Text to use as the replacement for %v expansion """
# * Filters
self.pre_transform = Optionable
""" [string|list(string)=''] Name of the filter to transform fields before applying other filters.

View File

@ -7,6 +7,8 @@ outputs:
comment: "Print F.Cu+F.SilkS"
type: pdf_pcb_print
dir: Layers
options:
title: 'Fake title for front copper and silk'
layers:
- layer: F.Cu
- layer: F.SilkS

View File

@ -15,4 +15,5 @@ outputs:
options:
variant: default
scaling: 0
title: 'Hello %V'
layers: F.Fab