[VRML] Added options to select and highlight components

- Uses the same code as render_3d
This commit is contained in:
Salvador E. Tropea 2023-01-23 18:44:17 -03:00
parent 525deaadff
commit 72eb6e9f90
8 changed files with 113 additions and 65 deletions

View File

@ -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.

View File

@ -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

View File

@ -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__()

View File

@ -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.

View File

@ -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:

View File

@ -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])

View File

@ -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

View File

@ -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