|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# Copyright (c) 2026 Salvador E. Tropea |
| 3 | +# Copyright (c) 2026 Instituto Nacional de Tecnología Industrial |
| 4 | +# License: AGPL-3.0 |
| 5 | +# Project: KiBot (formerly KiPlot) |
| 6 | +from .misc import UNITS_2_KICAD, MISSING_TOOL |
| 7 | +from .kiplot import run_command |
| 8 | +from .gs import GS |
| 9 | +from .out_base import VariantOptions |
| 10 | +from .macros import macros, document, output_class # noqa: F401 |
| 11 | +from . import log |
| 12 | + |
| 13 | +logger = log.get_logger() |
| 14 | +BOOLEAN_OPS = ('exclude_footprints_without_pads', 'subtract_holes_from_board', 'subtract_holes_from_copper') |
| 15 | + |
| 16 | + |
| 17 | +class PCB_StatsOptions(VariantOptions): |
| 18 | + def __init__(self): |
| 19 | + with document: |
| 20 | + self.output = GS.def_global_output |
| 21 | + """ *Name for the generated report file (%i='statistics' %x='txt/json') """ |
| 22 | + self.format = 'txt' |
| 23 | + """ *[txt,json] Output file format """ |
| 24 | + self.units = 'millimeters' |
| 25 | + """ [millimeters,inches] Units used for the values. Affected by global options """ |
| 26 | + self.exclude_footprints_without_pads = False |
| 27 | + """ Exclude footprints without pads """ |
| 28 | + self.subtract_holes_from_board = False |
| 29 | + """ Subtract holes from the board area """ |
| 30 | + self.subtract_holes_from_copper = False |
| 31 | + """ Subtract holes from copper areas """ |
| 32 | + super().__init__() |
| 33 | + self._expand_id = 'statistics' |
| 34 | + |
| 35 | + def config(self, parent): |
| 36 | + super().config(parent) |
| 37 | + # Adjust the units |
| 38 | + self._units = UNITS_2_KICAD[self.units] |
| 39 | + # The format indicates the extension |
| 40 | + self._expand_ext = self.format |
| 41 | + |
| 42 | + def run(self, output): |
| 43 | + if not GS.ki10: |
| 44 | + GS.exit_with_error("`pcb_stats` needs KiCad 10+", MISSING_TOOL) |
| 45 | + super().run(output) |
| 46 | + # Make units explicit |
| 47 | + # Base command |
| 48 | + cmd = [GS.kicad_cli, 'pcb', 'export', 'stats', '-o', output] |
| 49 | + if self.format != 'txt': |
| 50 | + cmd.extend(['--format', self.format]) |
| 51 | + for ops in BOOLEAN_OPS: |
| 52 | + if getattr(self, ops): |
| 53 | + cmd.append('--'+ops.replace('_', '-')) |
| 54 | + # The board |
| 55 | + board_name = self.save_tmp_board_if_variant() |
| 56 | + cmd.append(board_name) |
| 57 | + run_command(cmd) |
| 58 | + if self._files_to_remove: |
| 59 | + self.remove_temporals() |
| 60 | + |
| 61 | + |
| 62 | +@output_class |
| 63 | +class PCB_Stats(BaseOutput): # noqa: F821 |
| 64 | + """ PCB statistics |
| 65 | + Generates basic PCB statistics using KiCad 10 or newer. |
| 66 | + Corresponds to what you get in the Inspect -> Show Board Statistics menu """ |
| 67 | + def __init__(self): |
| 68 | + super().__init__() |
| 69 | + with document: |
| 70 | + self.options = PCB_StatsOptions |
| 71 | + """ *[dict={}] Options for the `pcb_stats` output """ |
| 72 | + self._category = 'PCB/docs' |
| 73 | + |
| 74 | + @staticmethod |
| 75 | + def get_conf_examples(name, layers): |
| 76 | + if not GS.ki10: |
| 77 | + return None |
| 78 | + return BaseOutput.simple_conf_examples(name, 'PCB Statistics', '') # noqa: F821 |
0 commit comments