[Stencil_3D] New output
- KiKit's "stencil createprinted"
This commit is contained in:
parent
5767a03868
commit
2a46ab1cff
|
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `populate` to create step-by-step assembly instructions
|
||||
With support for `pcbdraw` and `render_3d`.
|
||||
- `panelize` to create a PCB panel containing N copies of the PCB.
|
||||
- `stencil_3d` to create 3D self-registering printable stencils.
|
||||
- generic filters: options to filter by PCB side
|
||||
- BoM:
|
||||
- Option to link to Mouser site.
|
||||
|
|
|
|||
60
README.md
60
README.md
|
|
@ -97,6 +97,8 @@ For example, it's common that you might want for each board rev:
|
|||
* PCB 3D model in STEP format
|
||||
* PCB 3D render in PNG format
|
||||
* Compare PCB/SCHs
|
||||
* Panelization
|
||||
* Stencil creation
|
||||
|
||||
You want to do this in a one-touch way, and make sure everything you need to
|
||||
do so is securely saved in version control, not on the back of an old
|
||||
|
|
@ -142,6 +144,9 @@ Notes:
|
|||
- Show KiAuto installation information for `info` (v2.0.0)
|
||||
- Print the page frame in GUI mode for `pcb_print` (v1.6.7)
|
||||
|
||||
[**KiKit**](https://github.com/yaqwsx/KiKit) [](https://github.com/yaqwsx/KiKit) 
|
||||
- Mandatory for: `panelize`, `stencil_3d`
|
||||
|
||||
[**LXML**](https://pypi.org/project/LXML/) [](https://pypi.org/project/LXML/) [](https://packages.debian.org/bullseye/python3-lxml) 
|
||||
- Mandatory for: `pcb_print`, `pcbdraw`
|
||||
|
||||
|
|
@ -158,12 +163,12 @@ Notes:
|
|||
[**KiCad PCB/SCH Diff**](https://github.com/INTI-CMNB/KiDiff) v2.4.3 [](https://github.com/INTI-CMNB/KiDiff) 
|
||||
- Mandatory for `diff`
|
||||
|
||||
[**KiKit**](https://github.com/yaqwsx/KiKit) [](https://github.com/yaqwsx/KiKit) 
|
||||
- Mandatory for `panelize`
|
||||
|
||||
[**mistune**](https://pypi.org/project/mistune/) [](https://pypi.org/project/mistune/) [](https://packages.debian.org/bullseye/python3-mistune)
|
||||
- Mandatory for `populate`
|
||||
|
||||
[**OpenSCAD**](https://openscad.org/) [](https://openscad.org/) [](https://packages.debian.org/bullseye/openscad)
|
||||
- Mandatory for `stencil_3d`
|
||||
|
||||
[**QRCodeGen**](https://pypi.org/project/QRCodeGen/) [](https://pypi.org/project/QRCodeGen/) [](https://pypi.org/project/QRCodeGen/) [](https://packages.debian.org/bullseye/python3-qrcodegen) 
|
||||
- Mandatory for `qr_lib`
|
||||
|
||||
|
|
@ -3555,6 +3560,55 @@ 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.
|
||||
|
||||
* 3D Printed Stencils
|
||||
* Type: `stencil_3d`
|
||||
* Description: Creates a 3D self-registering model of a stencil you can easily print on
|
||||
SLA printer, you can use it to apply solder paste to your PCB.
|
||||
These stencils are quick solution when you urgently need a stencil but probably
|
||||
they don't last long and might come with imperfections.
|
||||
It currently uses KiKit, so please read
|
||||
[KiKit docs](https://github.com/yaqwsx/KiKit/blob/master/doc/stencil.md).
|
||||
Note that we don't implement `--ignore` option, you should use a variant for this
|
||||
* 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 `Stencil_3D` output.
|
||||
* Valid keys:
|
||||
- **`output`**: [string='%f-%i%I%v.%x'] Filename for the output (%i='stencil_3d_top'|'stencil_3d_bottom'|'stencil_3d_edge',
|
||||
%x='stl'|'scad'|'dxf'). Affected by global options.
|
||||
- **`thickness`**: [number=0.15] Stencil thickness [mm]. Defines amount of paste dispensed.
|
||||
- `cutout`: [string|list(string)] List of components to add a cutout based on the component courtyard.
|
||||
This is useful when you have already pre-populated board and you want to populate more
|
||||
components.
|
||||
- `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.
|
||||
- *enlarge_holes*: Alias for enlarge_holes.
|
||||
- `enlargeholes`: [number=0] Enlarge pad holes by x mm.
|
||||
- *frame_clearance*: Alias for frameclearance.
|
||||
- *frame_width*: Alias for framewidth.
|
||||
- `frameclearance`: [number=0] Clearance for the stencil register [mm].
|
||||
- `framewidth`: [number=1] Register frame width.
|
||||
- `include_scad`: [boolean=true] Include the generated OpenSCAD files. Note that this also includes the DXF files.
|
||||
- *pcb_thickness*: Alias for pcbthickness.
|
||||
- `pcbthickness`: [number=0] PCB thickness [mm]. If 0 we will ask KiCad.
|
||||
- `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.
|
||||
- `side`: [string='auto'] [top,bottom,auto,both] Which side of the PCB we want. Using `auto` will detect which
|
||||
side contains solder paste.
|
||||
- `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.
|
||||
|
||||
* STEP (ISO 10303-21 Clear Text Encoding of the Exchange Structure)
|
||||
* Type: `step`
|
||||
* Description: Exports the PCB as a 3D model.
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ For example, it's common that you might want for each board rev:
|
|||
* PCB 3D model in STEP format
|
||||
* PCB 3D render in PNG format
|
||||
* Compare PCB/SCHs
|
||||
* Panelization
|
||||
* Stencil creation
|
||||
|
||||
You want to do this in a one-touch way, and make sure everything you need to
|
||||
do so is securely saved in version control, not on the back of an old
|
||||
|
|
|
|||
|
|
@ -2460,6 +2460,52 @@ outputs:
|
|||
title: ''
|
||||
# [string=''] Board variant to apply
|
||||
variant: ''
|
||||
# 3D Printed Stencils:
|
||||
# SLA printer, you can use it to apply solder paste to your PCB.
|
||||
# These stencils are quick solution when you urgently need a stencil but probably
|
||||
# they don't last long and might come with imperfections.
|
||||
# It currently uses KiKit, so please read
|
||||
# [KiKit docs](https://github.com/yaqwsx/KiKit/blob/master/doc/stencil.md).
|
||||
# Note that we don't implement `--ignore` option, you should use a variant for this
|
||||
- name: 'stencil_3d_example'
|
||||
comment: 'Creates a 3D self-registering model of a stencil you can easily print on'
|
||||
type: 'stencil_3d'
|
||||
dir: 'Example/stencil_3d_dir'
|
||||
options:
|
||||
# [string|list(string)] List of components to add a cutout based on the component courtyard.
|
||||
# This is useful when you have already pre-populated board and you want to populate more
|
||||
# components
|
||||
cutout: ''
|
||||
# [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'
|
||||
# `enlarge_holes` is an alias for `enlarge_holes`
|
||||
# [number=0] Enlarge pad holes by x mm
|
||||
enlargeholes: 0
|
||||
# `frame_clearance` is an alias for `frameclearance`
|
||||
# `frame_width` is an alias for `framewidth`
|
||||
# [number=0] Clearance for the stencil register [mm]
|
||||
frameclearance: 0
|
||||
# [number=1] Register frame width
|
||||
framewidth: 1
|
||||
# [boolean=true] Include the generated OpenSCAD files. Note that this also includes the DXF files
|
||||
include_scad: true
|
||||
# [string='%f-%i%I%v.%x'] Filename for the output (%i='stencil_3d_top'|'stencil_3d_bottom'|'stencil_3d_edge',
|
||||
# %x='stl'|'scad'|'dxf'). Affected by global options
|
||||
output: '%f-%i%I%v.%x'
|
||||
# `pcb_thickness` is an alias for `pcbthickness`
|
||||
# [number=0] PCB thickness [mm]. If 0 we will ask KiCad
|
||||
pcbthickness: 0
|
||||
# [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='auto'] [top,bottom,auto,both] Which side of the PCB we want. Using `auto` will detect which
|
||||
# side contains solder paste
|
||||
side: 'auto'
|
||||
# [number=0.15] Stencil thickness [mm]. Defines amount of paste dispensed
|
||||
thickness: 0.15
|
||||
# [string=''] Board variant to apply
|
||||
variant: ''
|
||||
# STEP (ISO 10303-21 Clear Text Encoding of the Exchange Structure):
|
||||
# This is the most common 3D format for exchange purposes.
|
||||
# This output is what you get from the 'File/Export/STEP' menu in pcbnew.
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@ Dependencies:
|
|||
debian: python3-lxml
|
||||
arch: python-lxml
|
||||
downloader: python
|
||||
- name: KiKit
|
||||
github: yaqwsx/KiKit
|
||||
pypi: KiKit
|
||||
downloader: pytool
|
||||
"""
|
||||
import importlib
|
||||
import os
|
||||
|
|
@ -559,6 +563,9 @@ def run_command(cmd, only_first_line=False, pre_ver_text=None, no_err_2=False):
|
|||
return None
|
||||
last_stderr = res_run.stderr.decode()
|
||||
res = res_run.stdout.decode().strip()
|
||||
if len(res) == 0 and len(last_stderr) != 0:
|
||||
# Ok, yes, OpenSCAD prints its version to stderr!!!
|
||||
res = last_stderr
|
||||
if only_first_line:
|
||||
res = res.split('\n')[0]
|
||||
pre_vers = (cmd[0]+' version ', cmd[0]+' ', pre_ver_text)
|
||||
|
|
|
|||
13
kibot/gs.py
13
kibot/gs.py
|
|
@ -377,6 +377,19 @@ class GS(object):
|
|||
copy2(pro_name, pro_copy)
|
||||
return pro_copy
|
||||
|
||||
@staticmethod
|
||||
def get_pcb_and_pro_names(name):
|
||||
if GS.ki5:
|
||||
return [name, name.replace('kicad_pcb', 'pro')]
|
||||
return [name, name.replace('kicad_pcb', 'kicad_pro'), name.replace('kicad_pcb', 'kicad_prl')]
|
||||
|
||||
@staticmethod
|
||||
def remove_pcb_and_pro(name):
|
||||
""" Used to remove temporal PCB and project files """
|
||||
for fn in GS.get_pcb_and_pro_names(name):
|
||||
if os.path.isfile(fn):
|
||||
os.remove(fn)
|
||||
|
||||
@staticmethod
|
||||
def load_board():
|
||||
""" Will be repplaced by kiplot.py """
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ W_PCBDRAW = '(W103) '
|
|||
W_NOCRTYD = '(W104) '
|
||||
W_PANELEMPTY = '(W105) '
|
||||
W_ONWIN = '(W106) '
|
||||
W_AUTONONE = '(W106) '
|
||||
# Somehow arbitrary, the colors are real, but can be different
|
||||
PCB_MAT_COLORS = {'fr1': "937042", 'fr2': "949d70", 'fr3': "adacb4", 'fr4': "332B16", 'fr5': "6cc290"}
|
||||
PCB_FINISH_COLORS = {'hal': "8b898c", 'hasl': "8b898c", 'imag': "8b898c", 'enig': "cfb96e", 'enepig': "cfb96e",
|
||||
|
|
|
|||
|
|
@ -252,6 +252,11 @@ class VariantOptions(BaseOptions):
|
|||
return []
|
||||
return [c.ref for c in self._comps if not c.fitted or not c.included]
|
||||
|
||||
# Here just to avoid pulling pcbnew for this
|
||||
@staticmethod
|
||||
def to_mm(val):
|
||||
return ToMM(val)
|
||||
|
||||
@staticmethod
|
||||
def create_module_element(m):
|
||||
if GS.ki6:
|
||||
|
|
@ -334,6 +339,22 @@ class VariantOptions(BaseOptions):
|
|||
for line in restore:
|
||||
m.Remove(line)
|
||||
|
||||
def detect_solder_paste(self, board):
|
||||
""" Detects if the top and/or bottom layer has solder paste """
|
||||
fpaste = board.GetLayerID('F.Paste')
|
||||
bpaste = board.GetLayerID('B.Paste')
|
||||
top = bottom = False
|
||||
for m in GS.get_modules_board(board):
|
||||
for p in m.Pads():
|
||||
pad_layers = p.GetLayerSet()
|
||||
if not top and fpaste in pad_layers.Seq():
|
||||
top = True
|
||||
if not bottom and bpaste in pad_layers.Seq():
|
||||
bottom = True
|
||||
if top and bottom:
|
||||
return top, bottom
|
||||
return top, bottom
|
||||
|
||||
def remove_paste_and_glue(self, board, comps_hash):
|
||||
""" Remove from solder paste layers the filtered components. """
|
||||
if comps_hash is None or not (GS.global_remove_solder_paste_for_dnp or GS.global_remove_adhesive_for_dnp):
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@
|
|||
# Project: KiBot (formerly KiPlot)
|
||||
"""
|
||||
Dependencies:
|
||||
- name: KiKit
|
||||
github: yaqwsx/KiKit
|
||||
pypi: KiKit
|
||||
downloader: pytool
|
||||
- from: KiKit
|
||||
role: mandatory
|
||||
"""
|
||||
import collections
|
||||
|
|
@ -708,10 +705,7 @@ class PanelizeOptions(VariantOptions):
|
|||
fname = self.save_tmp_board()
|
||||
self.unfilter_pcb_components(GS.board, do_3D=True)
|
||||
self.restore_title()
|
||||
to_remove.append(fname)
|
||||
to_remove.append(fname.replace('kicad_pcb', 'kicad_pro'))
|
||||
to_remove.append(fname.replace('kicad_pcb', 'kicad_prl'))
|
||||
to_remove.append(fname.replace('kicad_pcb', 'pro'))
|
||||
to_remove.extend(GS.get_pcb_and_pro_names(fname))
|
||||
logger.debug('- Modified PCB: '+fname)
|
||||
else:
|
||||
fname = GS.pcb_file
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
# -*- 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: KiKit
|
||||
role: mandatory
|
||||
- name: OpenSCAD
|
||||
url: https://openscad.org/
|
||||
url_down: https://openscad.org/downloads.html
|
||||
command: openscad
|
||||
debian: openscad
|
||||
arch: openscad
|
||||
role: mandatory
|
||||
"""
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from .error import PlotError
|
||||
from .gs import GS
|
||||
from .kiplot import run_command
|
||||
from .out_base import VariantOptions
|
||||
from .misc import W_AUTONONE
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
logger = log.get_logger()
|
||||
|
||||
|
||||
class Stencil_3D_Options(VariantOptions):
|
||||
def __init__(self):
|
||||
with document:
|
||||
self.output = GS.def_global_output
|
||||
""" *Filename for the output (%i='stencil_3d_top'|'stencil_3d_bottom'|'stencil_3d_edge',
|
||||
%x='stl'|'scad'|'dxf') """
|
||||
self.side = 'auto'
|
||||
""" [top,bottom,auto,both] Which side of the PCB we want. Using `auto` will detect which
|
||||
side contains solder paste """
|
||||
self.include_scad = True
|
||||
""" Include the generated OpenSCAD files. Note that this also includes the DXF files """
|
||||
self.cutout = ''
|
||||
""" [string|list(string)] List of components to add a cutout based on the component courtyard.
|
||||
This is useful when you have already pre-populated board and you want to populate more
|
||||
components """
|
||||
self.pcbthickness = 0
|
||||
""" PCB thickness [mm]. If 0 we will ask KiCad """
|
||||
self.pcb_thickness = None
|
||||
""" {pcbthickness} """
|
||||
self.thickness = 0.15
|
||||
""" *Stencil thickness [mm]. Defines amount of paste dispensed """
|
||||
self.framewidth = 1
|
||||
""" Register frame width """
|
||||
self.frame_width = None
|
||||
""" {framewidth} """
|
||||
self.frameclearance = 0
|
||||
""" Clearance for the stencil register [mm] """
|
||||
self.frame_clearance = None
|
||||
""" {frameclearance} """
|
||||
self.enlargeholes = 0
|
||||
""" Enlarge pad holes by x mm """
|
||||
self.enlarge_holes = None
|
||||
""" {enlarge_holes} """
|
||||
super().__init__()
|
||||
|
||||
def config(self, parent):
|
||||
super().config(parent)
|
||||
self.cutout = ','.join(self.force_list(self.cutout))
|
||||
|
||||
def move_output(self, src_dir, src_file, id, ext, replacement=None, patch=False):
|
||||
self._expand_id = id
|
||||
self._expand_ext = ext
|
||||
dst_name = self._parent.expand_filename(self._parent.output_dir, self.output)
|
||||
src_name = os.path.join(src_dir, src_file)
|
||||
if not os.path.isfile(src_name):
|
||||
raise PlotError('Missing output file {}'.format(src_name))
|
||||
if patch:
|
||||
# Adjust the names of the DXF files
|
||||
with open(src_name, 'r') as f:
|
||||
content = f.read()
|
||||
for k, v in replacement.items():
|
||||
content = content.replace(k, v)
|
||||
with open(dst_name, 'w') as f:
|
||||
f.write(content)
|
||||
else:
|
||||
shutil.move(src_name, dst_name)
|
||||
if replacement is not None:
|
||||
replacement[src_name] = os.path.basename(dst_name)
|
||||
|
||||
def get_targets(self, out_dir):
|
||||
# TODO: auto side is tricky, needs variants applied
|
||||
return [self._parent.expand_filename(out_dir, self.output)]
|
||||
|
||||
def run(self, output):
|
||||
cmd_kikit = self.ensure_tool('KiKit')
|
||||
self.ensure_tool('OpenSCAD')
|
||||
super().run(output)
|
||||
# Apply variants and filters
|
||||
filtered = self.filter_pcb_components(GS.board)
|
||||
if self.side == 'auto':
|
||||
detected_top, detected_bottom = self.detect_solder_paste(GS.board)
|
||||
fname = self.save_tmp_board() if filtered else GS.pcb_file
|
||||
if filtered:
|
||||
self.unfilter_pcb_components(GS.board)
|
||||
# Avoid running the tool if we will generate useless models
|
||||
if self.side == 'auto' and not detected_top and not detected_bottom:
|
||||
logger.warning(W_AUTONONE+'No solder paste detected, skipping 3D stencil generation')
|
||||
return
|
||||
# If no PCB thickness indicated ask KiCad
|
||||
if not self.pcbthickness:
|
||||
ds = GS.board.GetDesignSettings()
|
||||
self.pcbthickness = self.to_mm(ds.GetBoardThickness())
|
||||
# Create the command line
|
||||
cmd = [cmd_kikit, 'stencil', 'createprinted',
|
||||
'--thickness', str(self.thickness),
|
||||
'--framewidth', str(self.framewidth),
|
||||
'--pcbthickness', str(self.pcbthickness)]
|
||||
if self.cutout:
|
||||
cmd.extend(['--coutout', self.cutout])
|
||||
if self.frameclearance:
|
||||
cmd.extend(['--frameclearance', str(self.frameclearance)])
|
||||
if self.enlargeholes:
|
||||
cmd.extend(['--enlargeholes', str(self.enlargeholes)])
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
cmd.append(fname)
|
||||
cmd.append(tmp)
|
||||
try:
|
||||
run_command(cmd)
|
||||
finally:
|
||||
# Remove temporal variant
|
||||
if filtered:
|
||||
GS.remove_pcb_and_pro(fname)
|
||||
# Now copy the files we want
|
||||
# - Which side?
|
||||
do_top = do_bottom = False
|
||||
if self.side == 'top':
|
||||
do_top = True
|
||||
elif self.side == 'bottom':
|
||||
do_bottom = True
|
||||
elif self.side == 'both':
|
||||
do_top = True
|
||||
do_bottom = True
|
||||
else: # auto
|
||||
do_top = detected_top
|
||||
do_bottom = detected_bottom
|
||||
prj_name = os.path.splitext(os.path.basename(fname))[0]
|
||||
replacements = {}
|
||||
# The edge is needed by any of the OpenSCAD files
|
||||
if (do_top or do_bottom) and self.include_scad:
|
||||
self.move_output(tmp, prj_name+'-EdgeCuts.dxf', 'stencil_3d_edge', 'dxf', replacements)
|
||||
# Top side
|
||||
if do_top:
|
||||
self.move_output(tmp, 'topStencil.stl', 'stencil_3d_top', 'stl')
|
||||
if self.include_scad:
|
||||
self.move_output(tmp, prj_name+'-PasteTop.dxf', 'stencil_3d_top', 'dxf', replacements)
|
||||
self.move_output(tmp, 'topStencil.scad', 'stencil_3d_top', 'scad', replacements, patch=True)
|
||||
# Bottom side
|
||||
if do_bottom:
|
||||
self.move_output(tmp, 'bottomStencil.stl', 'stencil_3d_bottom', 'stl')
|
||||
if self.include_scad:
|
||||
self.move_output(tmp, prj_name+'-PasteBottom.dxf', 'stencil_3d_bottom', 'dxf', replacements)
|
||||
self.move_output(tmp, 'bottomStencil.scad', 'stencil_3d_bottom', 'scad', replacements, patch=True)
|
||||
|
||||
|
||||
@output_class
|
||||
class Stencil_3D(BaseOutput): # noqa: F821
|
||||
""" 3D Printed Stencils
|
||||
Creates a 3D self-registering model of a stencil you can easily print on
|
||||
SLA printer, you can use it to apply solder paste to your PCB.
|
||||
These stencils are quick solution when you urgently need a stencil but probably
|
||||
they don't last long and might come with imperfections.
|
||||
It currently uses KiKit, so please read
|
||||
[KiKit docs](https://github.com/yaqwsx/KiKit/blob/master/doc/stencil.md).
|
||||
Note that we don't implement `--ignore` option, you should use a variant for this """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
with document:
|
||||
self.options = Stencil_3D_Options
|
||||
""" *[dict] Options for the `Stencil_3D` output """
|
||||
|
|
@ -558,7 +558,7 @@ deps = '{\
|
|||
"extra_arch": null,\
|
||||
"extra_deb": null,\
|
||||
"help_option": "--version",\
|
||||
"importance": 10000,\
|
||||
"importance": 20000,\
|
||||
"in_debian": false,\
|
||||
"is_kicad_plugin": false,\
|
||||
"is_python": false,\
|
||||
|
|
@ -575,6 +575,13 @@ deps = '{\
|
|||
"max_version": null,\
|
||||
"output": "panelize",\
|
||||
"version": null\
|
||||
},\
|
||||
{\
|
||||
"desc": null,\
|
||||
"mandatory": true,\
|
||||
"max_version": null,\
|
||||
"output": "stencil_3d",\
|
||||
"version": null\
|
||||
}\
|
||||
],\
|
||||
"tests": [],\
|
||||
|
|
@ -622,6 +629,39 @@ deps = '{\
|
|||
"url": null,\
|
||||
"url_down": null\
|
||||
},\
|
||||
"OpenSCAD": {\
|
||||
"arch": "openscad",\
|
||||
"command": "openscad",\
|
||||
"comments": [],\
|
||||
"deb_package": "openscad",\
|
||||
"downloader": null,\
|
||||
"downloader_str": null,\
|
||||
"extra_arch": null,\
|
||||
"extra_deb": null,\
|
||||
"help_option": "--version",\
|
||||
"importance": 10000,\
|
||||
"in_debian": true,\
|
||||
"is_kicad_plugin": false,\
|
||||
"is_python": false,\
|
||||
"name": "OpenSCAD",\
|
||||
"no_cmd_line_version": false,\
|
||||
"no_cmd_line_version_old": false,\
|
||||
"output": "stencil_3d",\
|
||||
"plugin_dirs": null,\
|
||||
"pypi_name": "OpenSCAD",\
|
||||
"roles": [\
|
||||
{\
|
||||
"desc": null,\
|
||||
"mandatory": true,\
|
||||
"max_version": null,\
|
||||
"output": "stencil_3d",\
|
||||
"version": null\
|
||||
}\
|
||||
],\
|
||||
"tests": [],\
|
||||
"url": "https://openscad.org/",\
|
||||
"url_down": "https://openscad.org/downloads.html"\
|
||||
},\
|
||||
"Pandoc": {\
|
||||
"arch": "pandoc",\
|
||||
"command": "pandoc",\
|
||||
|
|
@ -1027,7 +1067,7 @@ def run_command(cmd, only_first_line=False, pre_ver_text=None, no_err_2=False):
|
|||
cmd[0] = cmd_full
|
||||
last_cmd = None
|
||||
try:
|
||||
cmd_output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
|
||||
res_run = subprocess.run(cmd, check=True, capture_output=True)
|
||||
last_cmd = cmd[0]
|
||||
except FileNotFoundError as e:
|
||||
last_ok = False
|
||||
|
|
@ -1039,7 +1079,9 @@ def run_command(cmd, only_first_line=False, pre_ver_text=None, no_err_2=False):
|
|||
print('Output from command: '+e.output.decode())
|
||||
last_ok = False
|
||||
return UNKNOWN
|
||||
res = cmd_output.decode().strip()
|
||||
res = res_run.stdout.decode().strip()
|
||||
if len(res) == 0:
|
||||
res = res_run.stderr.decode().strip()
|
||||
if only_first_line:
|
||||
res = res.split('\n')[0]
|
||||
pre_vers = (cmd[0]+' version ', cmd[0]+' ', pre_ver_text)
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ def run_command(cmd, only_first_line=False, pre_ver_text=None, no_err_2=False):
|
|||
cmd[0] = cmd_full
|
||||
last_cmd = None
|
||||
try:
|
||||
cmd_output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
|
||||
res_run = subprocess.run(cmd, check=True, capture_output=True)
|
||||
last_cmd = cmd[0]
|
||||
except FileNotFoundError as e:
|
||||
last_ok = False
|
||||
|
|
@ -92,7 +92,9 @@ def run_command(cmd, only_first_line=False, pre_ver_text=None, no_err_2=False):
|
|||
print('Output from command: '+e.output.decode())
|
||||
last_ok = False
|
||||
return UNKNOWN
|
||||
res = cmd_output.decode().strip()
|
||||
res = res_run.stdout.decode().strip()
|
||||
if len(res) == 0:
|
||||
res = res_run.stderr.decode().strip()
|
||||
if only_first_line:
|
||||
res = res.split('\n')[0]
|
||||
pre_vers = (cmd[0]+' version ', cmd[0]+' ', pre_ver_text)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# Example KiBot config file for a basic 3D stencil
|
||||
kibot:
|
||||
version: 1
|
||||
|
||||
outputs:
|
||||
- name: 'stencil'
|
||||
comment: "Creates a 3D printable stencil"
|
||||
type: stencil_3d
|
||||
dir: stencil/3D
|
||||
Loading…
Reference in New Issue