From fafd5d2f6d960475ebf150830f521e22047b79f8 Mon Sep 17 00:00:00 2001 From: "Salvador E. Tropea" Date: Sat, 17 Dec 2022 20:55:09 -0300 Subject: [PATCH] New VRML output --- CHANGELOG.md | 2 + README.md | 48 +++++- docs/README.in | 3 +- docs/images/icon_sources/file_wrl.svg | 213 ++++++++++++++++++++++++++ docs/samples/generic_plot.kibot.yaml | 39 +++++ kibot/out_navigate_results.py | 1 + kibot/out_vrml.py | 108 +++++++++++++ kibot/resources/images/file_wrl.svg | 179 ++++++++++++++++++++++ src/kibot-check | 13 +- tests/yaml_samples/vrml_1.kibot.yaml | 8 + 10 files changed, 609 insertions(+), 5 deletions(-) create mode 100644 docs/images/icon_sources/file_wrl.svg create mode 100644 kibot/out_vrml.py create mode 100644 kibot/resources/images/file_wrl.svg create mode 100644 tests/yaml_samples/vrml_1.kibot.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e6a0cfe..dace7ee4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.5.2] - Unreleased ### Fixed +- New output: + - `vrml` export the 3D model in Virtual Reality Modeling Language (#349) - PCB_Print: - Images not showing in custom frames. (#352) diff --git a/README.md b/README.md index fad538aa..b5ac1a40 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ For example, it's common that you might want for each board rev: * Gerbers, drills and drill maps for a fab in their favourite format * Fab docs for the assembler, including the BoM (Bill of Materials), costs spreadsheet and board view * Pick and place files -* PCB 3D model in STEP format +* PCB 3D model in STEP and VRML format * PCB 3D render in PNG format * Compare PCB/SCHs * Panelization @@ -137,8 +137,8 @@ Notes: [**Requests**](https://pypi.org/project/Requests/) [![Python module](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/Python-logo-notext-22x22.png)](https://pypi.org/project/Requests/) [![PyPi dependency](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/PyPI_logo_simplified-22x22.png)](https://pypi.org/project/Requests/) [![Debian](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/debian-openlogo-22x22.png)](https://packages.debian.org/bullseye/python3-requests) - Mandatory -[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v2.0.4 [![Tool](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/llave-inglesa-22x22.png)](https://github.com/INTI-CMNB/KiAuto)![PyPi dependency](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/PyPI_logo_simplified-22x22.png) ![Auto-download](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/auto_download-22x22.png) -- Mandatory for: `gencad`, `netlist`, `pdf_pcb_print`, `pdf_sch_print`, `render_3d`, `run_drc`, `run_erc`, `step`, `svg_pcb_print`, `svg_sch_print`, `update_xml` +[**KiCad Automation tools**](https://github.com/INTI-CMNB/KiAuto) v2.1.0 [![Tool](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/llave-inglesa-22x22.png)](https://github.com/INTI-CMNB/KiAuto)![PyPi dependency](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/PyPI_logo_simplified-22x22.png) ![Auto-download](https://raw.githubusercontent.com/INTI-CMNB/KiBot/master/docs/images/auto_download-22x22.png) +- Mandatory for: `gencad`, `netlist`, `pdf_pcb_print`, `pdf_sch_print`, `render_3d`, `run_drc`, `run_erc`, `step`, `svg_pcb_print`, `svg_sch_print`, `update_xml`, `vrml` - Optional to: - Compare schematics for `diff` (v2.0.0) - Show KiAuto installation information for `info` (v2.0.0) @@ -1260,6 +1260,7 @@ The available values for *type* are: - `kicost` BoM in XLSX format with costs generated by [KiCost](https://github.com/INTI-CMNB/KiCost) - 3D model: - `step` *Standard for the Exchange of Product Data* for the PCB + - `vrml` *Virtual Reality Modeling Language* for the PCB - `render_3d` PCB render, from the KiCad's 3D Viewer (broken in KiCad 6.0.0) - Web pages: - `populate` To create step-by-step assembly instructions. @@ -3977,6 +3978,47 @@ Notes: Internally we use 10 for low priority, 90 for high priority and 50 for most outputs. - `run_by_default`: [boolean=true] When enabled this output will be created when no specific outputs are requested. +* VRML (Virtual Reality Modeling Language) + * Type: `vrml` + * Description: Exports the PCB as a 3D model (WRL file). + This is intended for rendering, unlike STEP which is intended to be + an exact mechanic model + * Valid keys: + - **`comment`**: [string=''] A comment for documentation purposes. + - **`dir`**: [string='./'] Output directory for the generated files. + If it starts with `+` the rest is concatenated to the default dir. + - **`name`**: [string=''] Used to identify this particular output definition. + - **`options`**: [dict] Options for the `vrml` output. + * 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. + - **`output`**: [string='%f-%i%I%v.%x'] Filename for the output (%i=vrml, %x=wrl). Affected by global options. + - `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. + - `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. + A short-cut to use for simple cases where a variant is an overkill. + - `ref_units`: [string='millimeters'] [millimeters,inches'] Units for `ref_x` and `ref_y`. + - `ref_x`: [number=0] X coordinate to use as reference when `use_pcb_center_as_ref` is disabled. + - `ref_y`: [number=0] Y coordinate to use as reference when `use_pcb_center_as_ref` is disabled. + - `use_pcb_center_as_ref`: [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. + - `variant`: [string=''] Board variant to apply. + - `category`: [string|list(string)=''] The category for this output. If not specified an internally defined category is used. + Categories looks like file system paths, i.e. PCB/fabrication/gerber. + - `disable_run_by_default`: [string|boolean] Use it to disable the `run_by_default` status of other output. + Useful when this output extends another and you don't want to generate the original. + Use the boolean true value to disable the output you are extending. + - `extends`: [string=''] Copy the `options` section from the indicated output. + - `output_id`: [string=''] Text to use for the %I expansion content. To differentiate variations of this output. + - `priority`: [number=50] [0,100] Priority for this output. High priority outputs are created first. + Internally we use 10 for low priority, 90 for high priority and 50 for most outputs. + - `run_by_default`: [boolean=true] When enabled this output will be created when no specific outputs are requested. + #### Consolidating BoMs diff --git a/docs/README.in b/docs/README.in index 9f5323d7..521a7236 100644 --- a/docs/README.in +++ b/docs/README.in @@ -93,7 +93,7 @@ For example, it's common that you might want for each board rev: * Gerbers, drills and drill maps for a fab in their favourite format * Fab docs for the assembler, including the BoM (Bill of Materials), costs spreadsheet and board view * Pick and place files -* PCB 3D model in STEP format +* PCB 3D model in STEP and VRML format * PCB 3D render in PNG format * Compare PCB/SCHs * Panelization @@ -737,6 +737,7 @@ The available values for *type* are: - `kicost` BoM in XLSX format with costs generated by [KiCost](https://github.com/INTI-CMNB/KiCost) - 3D model: - `step` *Standard for the Exchange of Product Data* for the PCB + - `vrml` *Virtual Reality Modeling Language* for the PCB - `render_3d` PCB render, from the KiCad's 3D Viewer (broken in KiCad 6.0.0) - Web pages: - `populate` To create step-by-step assembly instructions. diff --git a/docs/images/icon_sources/file_wrl.svg b/docs/images/icon_sources/file_wrl.svg new file mode 100644 index 00000000..301af5bf --- /dev/null +++ b/docs/images/icon_sources/file_wrl.svg @@ -0,0 +1,213 @@ + + + + + + + + + + image/svg+xml + + svg_file + + + + + + + + + + + + + + + svg_file + + + + + + + + + + + + + + + + + + + wrl + + diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index 1dd61100..6a5d748f 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -2850,3 +2850,42 @@ outputs: # [string=''] Board variant to apply. # Not fitted components are crossed variant: '' + # VRML (Virtual Reality Modeling Language): + # This is intended for rendering, unlike STEP which is intended to be + # an exact mechanic model + - name: 'vrml_example' + comment: 'Exports the PCB as a 3D model (WRL file).' + type: 'vrml' + dir: 'Example/vrml_dir' + options: + # [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 + dir_models: 'shapes3D' + # [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 + dnf_filter: '_none' + # [boolean=true] Downloads missing 3D models from KiCad git. Only applies to models in KISYS3DMOD + download: true + # [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) + model_units: 'millimeters' + # [boolean=false] Used to exclude 3D models for components with 'virtual' attribute + no_virtual: false + # [string='%f-%i%I%v.%x'] Filename for the output (%i=vrml, %x=wrl). Affected by global options + output: '%f-%i%I%v.%x' + # [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' + # [string='millimeters'] [millimeters,inches'] Units for `ref_x` and `ref_y` + ref_units: 'millimeters' + # [number=0] X coordinate to use as reference when `use_pcb_center_as_ref` is disabled + ref_x: 0 + # [number=0] Y coordinate to use as reference when `use_pcb_center_as_ref` is disabled + ref_y: 0 + # [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 + # [string=''] Board variant to apply + variant: '' diff --git a/kibot/out_navigate_results.py b/kibot/out_navigate_results.py index 6bb113cf..e0e02806 100644 --- a/kibot/out_navigate_results.py +++ b/kibot/out_navigate_results.py @@ -78,6 +78,7 @@ EXT_IMAGE = {'gbr': 'file_gbr', 'stl': 'file_stl', 'step': 'file_stp', 'stp': 'file_stp', + 'wrl': 'file_wrl', 'html': 'file_html', 'css': 'file_css', 'xml': 'file_xml', diff --git a/kibot/out_vrml.py b/kibot/out_vrml.py new file mode 100644 index 00000000..4fddfa72 --- /dev/null +++ b/kibot/out_vrml.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2022 Salvador E. Tropea +# Copyright (c) 2022 Instituto Nacional de Tecnología Industrial +# License: GPL-3.0 +# Project: KiBot (formerly KiPlot) +""" +Dependencies: + - from: KiAuto + role: mandatory + version: 2.1.0 +""" +import os +from .gs import GS +from .out_base_3d import Base3DOptions, Base3D +from .misc import FAILED_EXECUTE +from .kiplot import exec_with_retry, add_extra_options +from .macros import macros, document, output_class # noqa: F401 +from . import log + +logger = log.get_logger() + + +class VRMLOptions(Base3DOptions): + def __init__(self): + with document: + self.output = GS.def_global_output + """ *Filename for the output (%i=vrml, %x=wrl) """ + self.dir_models = '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 """ + self.use_pcb_center_as_ref = 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 """ + self.ref_x = 0 + """ X coordinate to use as reference when `use_pcb_center_as_ref` is disabled """ + self.ref_y = 0 + """ Y coordinate to use as reference when `use_pcb_center_as_ref` is disabled """ + self.ref_units = 'millimeters' + """ [millimeters,inches'] Units for `ref_x` and `ref_y` """ + self.model_units = 'millimeters' + """ [millimeters,meters,deciinches,inches] Units used for the VRML (1 deciinch = 0.1 inches) """ + super().__init__() + self._expand_id = 'vrml' + self._expand_ext = 'wrl' + + def get_targets(self, out_dir): + targets = [self._parent.expand_filename(out_dir, self.output)] + if self.dir_models: + # We will also generate the models + dir = os.path.join(out_dir, self.dir_models) + filtered = {os.path.join(dir, os.path.basename(m)) for m in self.list_models() if m.endswith('.wrl')} + targets.extend(list(filtered)) + return targets + + def get_pcb_center(self): + center = GS.board.ComputeBoundingBox(True).Centre() + return self.to_mm(center.x), self.to_mm(center.y) + + def run(self, name): + command = self.ensure_tool('KiAuto') + super().run(name) + board_name = self.filter_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]) + if not self.use_pcb_center_as_ref or GS.ki5: + # KiCad 5 doesn't support using the center, we emulate it + if self.use_pcb_center_as_ref and GS.ki5: + x, y = self.get_pcb_center() + units = 'millimeters' + else: + x = self.ref_x + self.ref_y + units = self.ref_units + cmd.extend(['-x', str(x), '-y', str(x), '-u', units]) + cmd.extend([board_name, os.path.dirname(name)]) + cmd, video_remove = add_extra_options(cmd) + # Execute it + try: + ret = exec_with_retry(cmd) + finally: + self.remove_tmp_board(board_name) + if ret: + logger.error(command+' returned %d', ret) + exit(FAILED_EXECUTE) + if video_remove: + video_name = os.path.join(self.expand_filename_pcb(GS.out_dir), 'pcbnew_export_vrml_screencast.ogv') + if os.path.isfile(video_name): + os.remove(video_name) + + +@output_class +class VRML(BaseOutput): # noqa: F821 + """ VRML (Virtual Reality Modeling Language) + Exports the PCB as a 3D model (WRL file). + This is intended for rendering, unlike STEP which is intended to be + an exact mechanic model """ + def __init__(self): + super().__init__() + self._category = 'PCB/3D' + with document: + self.options = VRMLOptions + """ *[dict] Options for the `vrml` output """ + + @staticmethod + def get_conf_examples(name, layers, templates): + return Base3D.simple_conf_examples(name, 'PCB in VRML format', '3D') diff --git a/kibot/resources/images/file_wrl.svg b/kibot/resources/images/file_wrl.svg new file mode 100644 index 00000000..b1d1786d --- /dev/null +++ b/kibot/resources/images/file_wrl.svg @@ -0,0 +1,179 @@ + + + + + + + image/svg+xml + + svg_file + + + + + + + + + + + + + + + svg_file + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/kibot-check b/src/kibot-check index 2ec288e9..6a01f8f5 100755 --- a/src/kibot-check +++ b/src/kibot-check @@ -300,7 +300,7 @@ deps = '{\ "extra_arch": null,\ "extra_deb": null,\ "help_option": "--version",\ - "importance": 110003,\ + "importance": 120003,\ "in_debian": false,\ "is_kicad_plugin": false,\ "is_python": false,\ @@ -432,6 +432,17 @@ deps = '{\ 0\ ]\ },\ + {\ + "desc": null,\ + "mandatory": true,\ + "max_version": null,\ + "output": "vrml",\ + "version": [\ + 2,\ + 1,\ + 0\ + ]\ + },\ {\ "desc": null,\ "mandatory": true,\ diff --git a/tests/yaml_samples/vrml_1.kibot.yaml b/tests/yaml_samples/vrml_1.kibot.yaml new file mode 100644 index 00000000..ba1cec8d --- /dev/null +++ b/tests/yaml_samples/vrml_1.kibot.yaml @@ -0,0 +1,8 @@ +# Example KiBot config file +kibot: + version: 1 + +outputs: + - name: 'VRML export Test' + comment: "Example of VRML export" + type: vrml