diff --git a/README.md b/README.md index 891bf637..bda9f90e 100644 --- a/README.md +++ b/README.md @@ -1593,6 +1593,8 @@ Notes: - `output`: [string='%f-%i%I%v.%x'] Name for the generated PCB3D file (%i='blender_export' %x='pcb3d'). Affected by global options. - `pre_transform`: [string|list(string)='_none'] Name of the filter to transform fields before applying other filters. A short-cut to use for simple cases where a variant is an overkill. + - `solder_paste_for_populated`: [boolean=true] Add solder paste only for the populated components. + Populated components are the ones listed in `show_components`. - `variant`: [string=''] Board variant to apply. - `version`: [string='2.1'] [2.1,2.1_haschtl] Variant of the format used. - **`point_of_view`**: [dict|list(dict)] How the object is viewed by the camera. @@ -3344,6 +3346,8 @@ Notes: - **`options`**: [dict] Options for the `pcb2blender_tools` output. * Valid keys: - **`output`**: [string='%f-%i%I%v.%x'] Filename for the output (%i=pcb2blender, %x=pcb3d). Affected by global options. + - **`show_components`**: [list(string)|string=all] [none,all] List of components to include in the pads list, + can be also a string for `none` or `all`. The default is `all`. - `board_bounds_create`: [boolean=true] Create the file that informs the size of the used PCB area. This is the bounding box reported by KiCad for the PCB edge with 1 mm of margin. - `board_bounds_dir`: [string='layers'] Sub-directory where the bounds file is stored. diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 1f3d28f9..df4399fd 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -169,6 +169,9 @@ outputs: # [list(string)|string=all] [none,all] List of components to draw, can be also a string for `none` or `all`. # Unlike the `pcbdraw` output, the default is `all` show_components: all + # [boolean=true] Add solder paste only for the populated components. + # Populated components are the ones listed in `show_components` + solder_paste_for_populated: true # [string=''] Board variant to apply variant: '' # [string='2.1'] [2.1,2.1_haschtl] Variant of the format used @@ -2061,6 +2064,9 @@ outputs: # [string|list(string)='_none'] Name of the filter to transform fields before applying other filters. # A short-cut to use for simple cases where a variant is an overkill pre_transform: '_none' + # [list(string)|string=all] [none,all] List of components to include in the pads list, + # can be also a string for `none` or `all`. The default is `all` + show_components: all # [boolean=false] Create a JSON file containing the board stackup stackup_create: false # [string='.'] Directory for the stackup file diff --git a/kibot/out_base.py b/kibot/out_base.py index 9be07893..9063d12f 100644 --- a/kibot/out_base.py +++ b/kibot/out_base.py @@ -990,7 +990,7 @@ class VariantOptions(BaseOptions): self._sub_pcb = self.variant._sub_pcb self._comps = comps - # The following 3 members are used by 2D and 3D renderers + # The following 5 members are used by 2D and 3D renderers def setup_renderer(self, components, active_components): """ Setup the options to use it as a renderer """ self._show_all_components = False @@ -998,6 +998,7 @@ class VariantOptions(BaseOptions): self.highlight = self.solve_kf_filters([c for c in active_components if c]) self.show_components = [c for c in components if c] if self.show_components: + self._show_components_raw = self.show_components self.show_components = self.solve_kf_filters(self.show_components) def save_renderer_options(self): @@ -1016,6 +1017,35 @@ class VariantOptions(BaseOptions): self._parent.dir = self.old_dir self._parent._done = self.old_done + def apply_show_components(self): + if self._show_all_components: + # Don't change anything + return + logger.debug('Applying components list ...') + # The user specified a list of components, we must remove the rest + if not self._comps: + # No variant or filter applied + # Load the components + load_sch() + self._comps = GS.sch.get_components() + get_board_comps_data(self._comps) + # If the component isn't listed by the user make it DNF + show_components = set(self.expand_kf_components(self.show_components)) + self.undo_show = set() + for c in self._comps: + if c.ref not in show_components and c.fitted: + c.fitted = False + self.undo_show.add(c.ref) + logger.debugl(2, '- Removing '+c.ref) + + def undo_show_components(self): + if self._show_all_components: + # Don't change anything + return + for c in self._comps: + if c.ref in self.undo_show: + c.fitted = True + class PcbMargin(Optionable): """ To adjust each margin """ diff --git a/kibot/out_base_3d.py b/kibot/out_base_3d.py index d74e2fca..16e9c75b 100644 --- a/kibot/out_base_3d.py +++ b/kibot/out_base_3d.py @@ -12,7 +12,6 @@ from .gs import GS from .optionable import Optionable from .out_base import VariantOptions, BaseOutput from .kicad.config import KiConf -from .kiplot import load_sch, get_board_comps_data from .macros import macros, document # noqa: F401 from . import log @@ -259,6 +258,7 @@ class Base3DOptionsWithHL(Base3DOptions): self._filters_to_expand = False # List of components self._show_all_components = False + self._show_components_raw = self.show_components if isinstance(self.show_components, str): if self.show_components == 'all': self._show_all_components = True @@ -284,35 +284,6 @@ class Base3DOptionsWithHL(Base3DOptions): self._filters_to_expand = ref._filters_to_expand self._show_all_components = ref._show_all_components - def apply_show_components(self): - if self._show_all_components: - # Don't change anything - return - logger.debug('Applying components list ...') - # The user specified a list of components, we must remove the rest - if not self._comps: - # No variant or filter applied - # Load the components - load_sch() - self._comps = GS.sch.get_components() - get_board_comps_data(self._comps) - # If the component isn't listed by the user make it DNF - show_components = set(self.expand_kf_components(self.show_components)) - self.undo_show = set() - for c in self._comps: - if c.ref not in show_components and c.fitted: - c.fitted = False - self.undo_show.add(c.ref) - logger.debugl(2, '- Removing '+c.ref) - - def undo_show_components(self): - if self._show_all_components: - # Don't change anything - return - for c in self._comps: - if c.ref in self.undo_show: - c.fitted = True - class Base3D(BaseOutput): def __init__(self): diff --git a/kibot/out_blender_export.py b/kibot/out_blender_export.py index e32a5c75..688da48e 100644 --- a/kibot/out_blender_export.py +++ b/kibot/out_blender_export.py @@ -185,6 +185,9 @@ class PCB3DExportOptions(Base3DOptionsWithHL): """ Name for the generated PCB3D file (%i='blender_export' %x='pcb3d') """ self.version = '2.1' """ [2.1,2.1_haschtl] Variant of the format used """ + self.solder_paste_for_populated = True + """ Add solder paste only for the populated components. + Populated components are the ones listed in `show_components` """ self._expand_id = 'blender_export' self._expand_ext = 'pcb3d' self._unkown_is_error = True @@ -381,6 +384,15 @@ class Blender_ExportOptions(BaseOptions): 'comment': 'Internally created for the PCB3D', 'dir': dest_dir, 'options': {'stackup_create': self.pcb3d.version == '2.1_haschtl'}} + if self.pcb3d.solder_paste_for_populated: + sc = 'all' + if not self.pcb3d._show_all_components: + sc = 'none' if not self.pcb3d.show_components else self.pcb3d._show_components_raw + tree['options']['show_components'] = sc + logger.error(tree) + logger.error(f"_show_all_components: {self.pcb3d._show_all_components}") + logger.error(f"show_components: {self.pcb3d.show_components}") + logger.error(f"_show_components_raw: {self.pcb3d._show_components_raw}") configure_and_run(tree, dest_dir, ' - Creating Pads and boundary ...') def create_pcb3d(self, data_dir): diff --git a/kibot/out_pcb2blender_tools.py b/kibot/out_pcb2blender_tools.py index c283f095..966a31a2 100644 --- a/kibot/out_pcb2blender_tools.py +++ b/kibot/out_pcb2blender_tools.py @@ -14,6 +14,7 @@ from pcbnew import B_Paste, F_Paste, PCB_TEXT_T, ToMM from .gs import GS from .misc import (MOD_THROUGH_HOLE, MOD_SMD, UI_VIRTUAL, W_UNKPCB3DTXT, W_NOPCB3DBR, W_NOPCB3DTL, W_BADPCB3DTXT, W_UNKPCB3DNAME, W_BADPCB3DSTK) +from .optionable import Optionable from .out_base import VariantOptions from .macros import macros, document, output_class # noqa: F401 from . import log @@ -71,10 +72,27 @@ class PCB2Blender_ToolsOptions(VariantOptions): """ File name for the sub-PCBs bounds """ self.sub_boards_stacked_prefix = 'stacked_' """ Prefix used for the stack files """ + self.show_components = Optionable + """ *[list(string)|string=all] [none,all] List of components to include in the pads list, + can be also a string for `none` or `all`. The default is `all` """ super().__init__() self._expand_id = 'pcb2blender' self._expand_ext = 'pcb3d' + def config(self, parent): + super().config(parent) + # List of components + self._show_all_components = False + if isinstance(self.show_components, str): + if self.show_components == 'all': + self._show_all_components = True + self.show_components = [] + elif isinstance(self.show_components, type): + # Default is all + self._show_all_components = True + else: # a list + self.show_components = self.solve_kf_filters(self.show_components) + def do_board_bounds(self, dir_name): if not self.board_bounds_create: return @@ -243,12 +261,14 @@ class PCB2Blender_ToolsOptions(VariantOptions): def run(self, output): super().run(output) dir_name = os.path.dirname(output) + self.apply_show_components() self.filter_pcb_components(do_3D=True) self.do_board_bounds(dir_name) self.do_pads_info(dir_name) self.do_stackup(dir_name) self.do_sub_boards(dir_name) self.unfilter_pcb_components(do_3D=True) + self.undo_show_components() def get_targets(self, out_dir): files = []