From 72eb6e9f9003ffd7330bc745bd0aa464e82e116b Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Mon, 23 Jan 2023 18:44:17 -0300 Subject: [PATCH] [VRML] Added options to select and highlight components - Uses the same code as render_3d --- README.md | 7 +- docs/samples/generic_plot.kibot.yaml | 11 +++- kibot/out_base_3d.py | 67 ++++++++++++++++++++ kibot/out_blender_export.py | 2 +- kibot/out_render_3d.py | 63 ++---------------- kibot/out_vrml.py | 8 ++- tests/yaml_samples/render_3d_list.kibot.yaml | 2 + tests/yaml_samples/vrml_list.kibot.yaml | 18 ++++++ 8 files changed, 113 insertions(+), 65 deletions(-) create mode 100644 tests/yaml_samples/vrml_list.kibot.yaml diff --git a/README.md b/README.md index f4061b3b..e1c62d3b 100644 --- a/README.md +++ b/README.md @@ -1571,7 +1571,7 @@ Notes: * Valid keys: - **`download`**: [boolean=true] Downloads missing 3D models from KiCad git. Only applies to models in KISYS3DMOD. - **`no_virtual`**: [boolean=false] Used to exclude 3D models for components with 'virtual' attribute. - - **`pcb3d`**: [string=''] Name of the output that generated the PCB3D file to import in Belnder. + - **`pcb3d`**: [string=''] Name of the output that generated the PCB3D file to import in Blender. See the `PCB2Blender_2_1` and `PCB2Blender_2_1_haschtl` templates. - **`render_options`**: [dict] How the render is done for the `render` output type. * Valid keys: @@ -4614,11 +4614,16 @@ Notes: - **`download`**: [boolean=true] Downloads missing 3D models from KiCad git. Only applies to models in KISYS3DMOD. - **`no_virtual`**: [boolean=false] Used to exclude 3D models for components with 'virtual' attribute. - **`output`**: [string='%f-%i%I%v.%x'] Filename for the output (%i=vrml, %x=wrl). Affected by global options. + - **`show_components`**: [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`. - `dir_models`: [string='shapes3D'] Subdirectory used to store the 3D models for the components. If you want to create a monolithic file just use '' here. Note that the WRL file will contain relative paths to the models. - `dnf_filter`: [string|list(string)='_none'] Name of the filter to mark components as not fitted. A short-cut to use for simple cases where a variant is an overkill. + - `highlight`: [list(string)=[]] List of components to highlight. + - `highlight_on_top`: [boolean=false] Highlight over the component (not under). + - `highlight_padding`: [number=1.5] [0,1000] How much the highlight extends around the component [mm]. - `kicad_3d_url`: [string='https://gitlab.com/kicad/libraries/kicad-packages3D/-/raw/master/'] Base URL for the KiCad 3D models. - `model_units`: [string='millimeters'] [millimeters,meters,deciinches,inches] Units used for the VRML (1 deciinch = 0.1 inches). - `pre_transform`: [string|list(string)='_none'] Name of the filter to transform fields before applying other filters. diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index c8aab170..3119dd36 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -149,7 +149,7 @@ outputs: # Note that some formats includes the light and camera and others are just the 3D model # (i.e. STL and PLY) type: 'render' - # [string=''] Name of the output that generated the PCB3D file to import in Belnder. + # [string=''] Name of the output that generated the PCB3D file to import in Blender. # See the `PCB2Blender_2_1` and `PCB2Blender_2_1_haschtl` templates pcb3d: '' # Options to configure how Blender imports the PCB. @@ -3266,6 +3266,12 @@ outputs: dnf_filter: '_none' # [boolean=true] Downloads missing 3D models from KiCad git. Only applies to models in KISYS3DMOD download: true + # [list(string)=[]] List of components to highlight + highlight: [] + # [boolean=false] Highlight over the component (not under) + highlight_on_top: false + # [number=1.5] [0,1000] How much the highlight extends around the component [mm] + highlight_padding: 1.5 # [string='https://gitlab.com/kicad/libraries/kicad-packages3D/-/raw/master/'] Base URL for the KiCad 3D models kicad_3d_url: 'https://gitlab.com/kicad/libraries/kicad-packages3D/-/raw/master/' # [string='millimeters'] [millimeters,meters,deciinches,inches] Units used for the VRML (1 deciinch = 0.1 inches) @@ -3283,6 +3289,9 @@ outputs: ref_x: 0 # [number=0] Y coordinate to use as reference when `use_pcb_center_as_ref` is disabled ref_y: 0 + # [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] The center of the PCB will be used as reference point. # When disabled the `ref_x`, `ref_y` and `ref_units` will be used use_pcb_center_as_ref: true diff --git a/kibot/out_base_3d.py b/kibot/out_base_3d.py index bba6b387..32fe20a9 100644 --- a/kibot/out_base_3d.py +++ b/kibot/out_base_3d.py @@ -9,8 +9,10 @@ import requests import tempfile from .misc import W_MISS3D, W_FAILDL, W_DOWN3D, DISABLE_3D_MODEL_TEXT 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 @@ -231,6 +233,71 @@ class Base3DOptions(VariantOptions): self._tmp_dir = None +class Base3DOptionsWithHL(Base3DOptions): + """ 3D options including which components will be displayed and highlighted """ + def __init__(self): + with document: + self.show_components = Optionable + """ *[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` """ + self.highlight = Optionable + """ [list(string)=[]] List of components to highlight """ + self.highlight_padding = 1.5 + """ [0,1000] How much the highlight extends around the component [mm] """ + self.highlight_on_top = False + """ Highlight over the component (not under) """ + super().__init__() + + def config(self, parent): + super().config(parent) + self._filters_to_expand = False + # 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) + # Highlight + if isinstance(self.highlight, type): + self.highlight = None + else: + self.highlight = self.solve_kf_filters(self.highlight) + + 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): super().__init__() diff --git a/kibot/out_blender_export.py b/kibot/out_blender_export.py index d7f912fe..2a17a293 100644 --- a/kibot/out_blender_export.py +++ b/kibot/out_blender_export.py @@ -140,7 +140,7 @@ class Blender_ExportOptions(Base3DOptions): def __init__(self): with document: self.pcb3d = "" - """ *Name of the output that generated the PCB3D file to import in Belnder. + """ *Name of the output that generated the PCB3D file to import in Blender. See the `PCB2Blender_2_1` and `PCB2Blender_2_1_haschtl` templates """ self.pcb_import = PCB2BlenderOptions """ Options to configure how Blender imports the PCB. diff --git a/kibot/out_render_3d.py b/kibot/out_render_3d.py index 2c40bc5c..d639d782 100644 --- a/kibot/out_render_3d.py +++ b/kibot/out_render_3d.py @@ -18,9 +18,7 @@ import subprocess from .misc import (RENDER_3D_ERR, PCB_MAT_COLORS, PCB_FINISH_COLORS, SOLDER_COLORS, SILK_COLORS, KICAD_VERSION_6_0_2, MISSING_TOOL) from .gs import GS -from .kiplot import load_sch, get_board_comps_data -from .optionable import Optionable -from .out_base_3d import Base3DOptions, Base3D +from .out_base_3d import Base3DOptionsWithHL, Base3D from .macros import macros, document, output_class # noqa: F401 from . import log @@ -40,7 +38,7 @@ def _run_command(cmd): logger.debug('- Output from command:\n'+cmd_output.decode()) -class Render3DOptions(Base3DOptions): +class Render3DOptions(Base3DOptionsWithHL): _colors = {'background1': 'bg_color_1', 'background2': 'bg_color_2', 'copper': 'copper_color', @@ -120,15 +118,6 @@ class Render3DOptions(Base3DOptions): """ Clip silkscreen at via annuli (KiCad 6) """ self.subtract_mask_from_silk = True """ Clip silkscreen at solder mask edges (KiCad 6) """ - self.show_components = Optionable - """ *[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` """ - self.highlight = Optionable - """ [list(string)=[]] List of components to highlight """ - self.highlight_padding = 1.5 - """ [0,1000] How much the highlight extends around the component [mm] """ - self.highlight_on_top = False - """ Highlight over the component (not under) """ self.auto_crop = False """ When enabled the image will be post-processed to remove the empty space around the image. In this mode the `background2` is changed to be the same as `background1` """ @@ -143,7 +132,6 @@ class Render3DOptions(Base3DOptions): self._expand_ext = 'png' def config(self, parent): - self._filters_to_expand = False # Apply global defaults if GS.global_pcb_material is not None: material = GS.global_pcb_material.lower() @@ -179,28 +167,14 @@ class Render3DOptions(Base3DOptions): if nm in name: self.copper = "#"+color break + # Now we can configure (defaults applied) super().config(parent) self.validate_colors(list(self._colors.keys())+['transparent_background_color']) + # View and also add it to the ID view = self._views.get(self.view, None) if view is not None: self.view = view - # 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) self._expand_id += '_'+self._rviews.get(self.view) - # highlight - if isinstance(self.highlight, type): - self.highlight = None - else: - self.highlight = self.solve_kf_filters(self.highlight) def add_step(self, cmd, steps, ops): if steps: @@ -247,35 +221,6 @@ class Render3DOptions(Base3DOptions): if not self.subtract_mask_from_silk: cmd.append('--dont_substrack_mask_from_silk') - 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 - def run(self, output): super().run(output) if GS.ki6 and GS.kicad_version_n < KICAD_VERSION_6_0_2: diff --git a/kibot/out_vrml.py b/kibot/out_vrml.py index e7da9e19..88bad9a2 100644 --- a/kibot/out_vrml.py +++ b/kibot/out_vrml.py @@ -11,7 +11,7 @@ Dependencies: """ import os from .gs import GS -from .out_base_3d import Base3DOptions, Base3D +from .out_base_3d import Base3DOptionsWithHL, Base3D from .misc import FAILED_EXECUTE from .macros import macros, document, output_class # noqa: F401 from . import log @@ -24,7 +24,7 @@ def replace_ext(file, ext): return file+'.wrl' -class VRMLOptions(Base3DOptions): +class VRMLOptions(Base3DOptionsWithHL): def __init__(self): with document: self.output = GS.def_global_output @@ -69,7 +69,9 @@ class VRMLOptions(Base3DOptions): def run(self, name): command = self.ensure_tool('KiAuto') super().run(name) - board_name = self.filter_components(force_wrl=True) + self.apply_show_components() + board_name = self.filter_components(highlight=set(self.expand_kf_components(self.highlight)), force_wrl=True) + self.undo_show_components() cmd = [command, 'export_vrml', '--output_name', os.path.basename(name), '-U', self.model_units] if self.dir_models: cmd.extend(['--dir_models', self.dir_models]) diff --git a/tests/yaml_samples/render_3d_list.kibot.yaml b/tests/yaml_samples/render_3d_list.kibot.yaml index ae0e467c..71d2fa86 100644 --- a/tests/yaml_samples/render_3d_list.kibot.yaml +++ b/tests/yaml_samples/render_3d_list.kibot.yaml @@ -1,4 +1,6 @@ # Example KiBot config file +# kibot -b tests/data/ArduinoLearningKitStarter.kicad_pcb -c tests/yaml_samples/render_3d_list.kibot.yaml -d r3d_lst +# r3d_lst/ArduinoLearningKitStarter-3D_top.png kibot: version: 1 diff --git a/tests/yaml_samples/vrml_list.kibot.yaml b/tests/yaml_samples/vrml_list.kibot.yaml new file mode 100644 index 00000000..115a9fbf --- /dev/null +++ b/tests/yaml_samples/vrml_list.kibot.yaml @@ -0,0 +1,18 @@ +# Example KiBot config file +# kibot -b tests/data/ArduinoLearningKitStarter.kicad_pcb -c tests/yaml_samples/vrml_3d_list.kibot.yaml -d r3d_lst +# r3d_lst/ArduinoLearningKitStarter-vrml.wrl +kibot: + version: 1 + +global: + solder_mask_color: blue + pcb_finish: ENIG + +outputs: + - name: vrml_list + comment: "VRML with only some components" + type: vrml + options: + show_components: ["RV1", "RV2", "U1", "U2", "U3"] + highlight: ["RV1"] + # highlight_on_top: true