diff --git a/README.md b/README.md index c3d4f9f5..83a57ed9 100644 --- a/README.md +++ b/README.md @@ -2451,6 +2451,9 @@ Notes: * Description: Creates a panel to fabricate various copies of the PCB at once. It currently uses the KiKit tool, which must be available. Consult KiKit docs for detailed information. + Current versions of KiKit only support KiCad 6 and my tests using + KiKit 1.0.5 (the last to support KiCad 5) shown some + incompatibilities. Note that you don't need to specify the units for all distances. If they are omitted they are assumed to be `default_units`. The same is valid for angles, using `default_angles` @@ -2605,6 +2608,9 @@ Notes: - `drawboxes`: [boolean=false] Draw boxes. - `drawtabfail`: [boolean=false] Draw tab fail. - `trace`: [boolean=false] Trace. + - `extends`: [string=''] A configuration to use as base for this one. Use the following format: `OUTPUT_NAME[CFG_NAME]`. + - `name`: [string=''] A name to identify this configuration. If empty will be the order in the list, starting with 1. + Don't use just a number or it will be confused as an index. - `post`: [dict] Finishing touches to the panel. * Valid keys: - `copperfill`: [boolean=false] Fill tabs and frame with copper (e.g., to save etchant or to increase rigidity of flex-PCB panels). @@ -2647,7 +2653,7 @@ Notes: *boardCompany* the company from the source board, *boardComment1*-*boardComment9* comments from the source board. - `thickness`: [number|string] Stroke thickness. - - `type`: [string='simple'] [simple] Currently fixed. + - `type`: [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works. - `vjustify`: [string='center'] [left,right,center] Vertical justification of the text. - `voffset`: [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system. - `width`: [number|string] Width of the characters (the same parameters as KiCAD uses). @@ -2669,7 +2675,7 @@ Notes: *boardCompany* the company from the source board, *boardComment1*-*boardComment9* comments from the source board. - `thickness`: [number|string] Stroke thickness. - - `type`: [string='simple'] [simple] Currently fixed. + - `type`: [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works. - `vjustify`: [string='center'] [left,right,center] Vertical justification of the text. - `voffset`: [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system. - `width`: [number|string] Width of the characters (the same parameters as KiCAD uses). @@ -2691,7 +2697,7 @@ Notes: *boardCompany* the company from the source board, *boardComment1*-*boardComment9* comments from the source board. - `thickness`: [number|string] Stroke thickness. - - `type`: [string='simple'] [simple] Currently fixed. + - `type`: [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works. - `vjustify`: [string='center'] [left,right,center] Vertical justification of the text. - `voffset`: [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system. - `width`: [number|string] Width of the characters (the same parameters as KiCAD uses). @@ -2713,7 +2719,7 @@ Notes: *boardCompany* the company from the source board, *boardComment1*-*boardComment9* comments from the source board. - `thickness`: [number|string] Stroke thickness. - - `type`: [string='simple'] [simple] Currently fixed. + - `type`: [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works. - `vjustify`: [string='center'] [left,right,center] Vertical justification of the text. - `voffset`: [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system. - `width`: [number|string] Width of the characters (the same parameters as KiCAD uses). diff --git a/docs/samples/generic_plot.kibot.yaml b/docs/samples/generic_plot.kibot.yaml index b2753047..05674ed9 100644 --- a/docs/samples/generic_plot.kibot.yaml +++ b/docs/samples/generic_plot.kibot.yaml @@ -1209,6 +1209,9 @@ outputs: # Panelize: # It currently uses the KiKit tool, which must be available. # Consult KiKit docs for detailed information. + # Current versions of KiKit only support KiCad 6 and my tests using + # KiKit 1.0.5 (the last to support KiCad 5) shown some + # incompatibilities. # Note that you don't need to specify the units for all distances. # If they are omitted they are assumed to be `default_units`. # The same is valid for angles, using `default_angles` @@ -1275,6 +1278,8 @@ outputs: drawtabfail: false # [boolean=false] Trace trace: false + # [string=''] A configuration to use as base for this one. Use the following format: `OUTPUT_NAME[CFG_NAME]` + extends: '' # [dict] Used to add fiducial marks to the (rail/frame of) the panel fiducials: # `copper_size` is an alias for `coppersize` @@ -1370,6 +1375,9 @@ outputs: vboneskip: 0 # [number|string] Specify the vertical gap between the boards vspace: 0 + # [string=''] A name to identify this configuration. If empty will be the order in the list, starting with 1. + # Don't use just a number or it will be confused as an index + name: '' # [dict] Sets page size on the resulting panel and position the panel in the page page: # [string='tl'] [tl,tr,bl,br,mt,mb,ml,mr,c] Point of the panel to be placed at given position. Can be one of tl, tr, bl, br @@ -1481,8 +1489,8 @@ outputs: text: '' # [number|string] Stroke thickness thickness: 0.3 - # [string='simple'] [simple] Currently fixed - type: 'simple' + # [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works + type: 'none' # [string='center'] [left,right,center] Vertical justification of the text vjustify: 'center' # [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system @@ -1515,8 +1523,8 @@ outputs: text: '' # [number|string] Stroke thickness thickness: 0.3 - # [string='simple'] [simple] Currently fixed - type: 'simple' + # [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works + type: 'none' # [string='center'] [left,right,center] Vertical justification of the text vjustify: 'center' # [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system @@ -1549,8 +1557,8 @@ outputs: text: '' # [number|string] Stroke thickness thickness: 0.3 - # [string='simple'] [simple] Currently fixed - type: 'simple' + # [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works + type: 'none' # [string='center'] [left,right,center] Vertical justification of the text vjustify: 'center' # [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system @@ -1583,8 +1591,8 @@ outputs: text: '' # [number|string] Stroke thickness thickness: 0.3 - # [string='simple'] [simple] Currently fixed - type: 'simple' + # [string='none'] [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works + type: 'none' # [string='center'] [left,right,center] Vertical justification of the text vjustify: 'center' # [number|string] Specify the vertical offset from anchor. Respects KiCAD coordinate system diff --git a/kibot/optionable.py b/kibot/optionable.py index 323c6e29..64cb91b6 100644 --- a/kibot/optionable.py +++ b/kibot/optionable.py @@ -195,7 +195,18 @@ class Optionable(object): new_val.append(element) v = new_val # Seems to be ok, map it - setattr(self, alias if is_alias else k, v) + dest_name = alias if is_alias else k + setattr(self, dest_name, v) + self.set_user_defined(dest_name) + + def set_user_defined(self, name): + setattr(self, '_{}_user_defined'.format(name), True) + + def get_user_defined(self, name): + name = '_{}_user_defined'.format(name) + if hasattr(self, name): + return getattr(self, name) + return False def set_tree(self, tree): self._tree = tree diff --git a/kibot/out_panelize.py b/kibot/out_panelize.py index 85a2432e..42b18666 100644 --- a/kibot/out_panelize.py +++ b/kibot/out_panelize.py @@ -11,6 +11,8 @@ Dependencies: downloader: pytool role: mandatory """ +import collections +from copy import deepcopy import os import re import json @@ -22,12 +24,24 @@ from .layer import Layer from .misc import W_PANELEMPTY from .optionable import BaseOptions from .out_base import VariantOptions +from .registrable import RegOutput from .macros import macros, document, output_class # noqa: F401 from . import log logger = log.get_logger() +def update_dict(d, u): + for k, v in u.items(): + if isinstance(v, collections.abc.Mapping): + d[k] = update_dict(d.get(k, {}), v) + elif isinstance(v, list) and k in d: + d[k] = v+d[k] + else: + d[k] = v + return d + + class PanelOptions(BaseOptions): _num_regex = re.compile(r'([\d\.]+)(mm|cm|dm|m|mil|inch|in)') _ang_regex = re.compile(r'([\d\.]+)(deg|°|rad)') @@ -336,8 +350,8 @@ class PanelizeFiducials(PanelOptions): class PanelizeText(PanelOptions): def __init__(self): with document: - self.type = 'simple' - """ [simple] Currently fixed """ + self.type = 'none' + """ [none,simple] Currently fixed. BTW: don't ask me about this ridiculous default, is how KiKit works """ self.text = '' """ The text to be displayed. Note that you can escape ; via \\. Available variables in text: *date* formats current date as --, @@ -474,6 +488,11 @@ class PanelizeDebug(PanelOptions): class PanelizeConfig(PanelOptions): def __init__(self): with document: + self.name = '' + """ A name to identify this configuration. If empty will be the order in the list, starting with 1. + Don't use just a number or it will be confused as an index """ + self.extends = '' + """ A configuration to use as base for this one. Use the following format: `OUTPUT_NAME[CFG_NAME]` """ self.page = PanelizePage """ *[dict] Sets page size on the resulting panel and position the panel in the page """ self.layout = PanelizeLayout @@ -506,6 +525,15 @@ class PanelizeConfig(PanelOptions): def config(self, parent): super().config(parent) + # Avoid confusing names + name_is_number = True + try: + _ = int(self.name) + except ValueError: + name_is_number = False + if name_is_number: + raise KiPlotConfigurationError("Don't use a number as name, this can be confused with an index ({})". + format(self.name)) # Make None all things not specified for k, v in self.get_attrs_gen(): if isinstance(v, type): @@ -513,6 +541,8 @@ class PanelizeConfig(PanelOptions): class PanelizeOptions(VariantOptions): + _extends_regex = re.compile(r'(.+)\[(.+)\]') + def __init__(self): with document: self.output = GS.def_global_output @@ -533,21 +563,103 @@ class PanelizeOptions(VariantOptions): self._expand_id = 'panel' self._expand_ext = 'kicad_pcb' + def solve_cfg_name(self, cfg): + """ Find the name of a configuration that isn't yet configured """ + name = cfg.get('name') + if name: + return name + return str(self._tree['configs'].index(cfg)+1) + + def solve_extends(self, tree, level=0, used=None, our_name=None): + base = tree.get('extends') + if our_name is None: + our_name = '{}[{}]'.format(self._parent.name, self.solve_cfg_name(tree)) + if used is None: + used = {our_name} + else: + if our_name in used: + raise KiPlotConfigurationError('Recursive extends detected in `extends: {}` ({})'.format(base, used)) + used.add(our_name) + logger.debugl(1, "Extending from "+base) + # Should be an string + if not isinstance(base, str): + raise KiPlotConfigurationError('`extends` must be a string, not {}'.format(type(base))) + # Extract the output and config names + m = PanelizeOptions._extends_regex.match(base) + if m is None: + raise KiPlotConfigurationError('Malformed `extends` reference: `{}` use OUTPUT_NAME[CFG_NAME]'.format(base)) + out_name, cfg_name = m.groups() + # Look for the output + out = RegOutput.get_output(out_name) + if out is None: + raise KiPlotConfigurationError('Unknown output `{}` in `extends: {}`'.format(out_name, base)) + # Look for the config + configs = None + out_options = out._tree.get('options') + if out_options: + configs = out_options.get('configs') + if configs is None or isinstance(configs, str): + raise KiPlotConfigurationError("Using `extends: {}` but `{}` hasn't configs to copy". format(base, out_name)) + cfg_name_is_number = True + try: + id = int(cfg_name)-1 + except ValueError: + cfg_name_is_number = False + if cfg_name_is_number: + # Using an index, is it valid? + if id >= len(configs): + raise KiPlotConfigurationError('Using `extends: {}` but `{}` has {} configs'. + format(base, out_name, len(configs))) + origin = configs[id] + else: + # Using a name + origin = next(filter(lambda x: 'name' in x and x['name'] == cfg_name, configs), None) + if origin is None: + raise KiPlotConfigurationError("Using `extends: {}` but `{}` doesn't define `{}`". + format(base, out_name, cfg_name)) + # Now we have the origin + # Does it also use extends? + origin_extends = origin.get('extends') + if origin_extends: + origin = self.solve_extends(origin, level=level+1, used=used, our_name=base) + # Copy the origin, update it and replace the current values + logger.debugl(1, "{} before applying {}: {}".format(our_name, base, tree)) + logger.debugl(1, "- Should add {}".format(origin)) + new_origin = deepcopy(origin) + update_dict(new_origin, tree) + if level: + tree = deepcopy(tree) + logger.error(tree) + update_dict(tree, new_origin) + if not level: + # Remove the extends, we solved it + del tree['extends'] + logger.debugl(1, "After apply: {}".format(tree)) + return tree + def config(self, parent): + self._parent = parent + # Look for configs that uses extends + configs = self._tree.get('configs') + if configs: + list(map(self.solve_extends, filter(lambda x: 'extends' in x, configs))) super().config(parent) if isinstance(self.configs, type): logger.warning(W_PANELEMPTY+'Generating a panel with default options, not very useful') self.configs = [] elif isinstance(self.configs, str): self.configs = [self.configs] + for c, cfg in enumerate(self.configs): + if not cfg.name: + cfg.name = str(c+1) def create_config(self, cfg): with NamedTemporaryFile(mode='w', delete=False, suffix='.json', prefix='kibot_panel_cfg') as f: logger.debug('Writing panel config to '+f.name) cfg_d = {} for k, v in cfg.get_attrs_gen(): - if v: - cfg_d[k] = {k: v for k, v in v.get_attrs_gen() if v is not None} + if isinstance(v, PanelOptions): + cfg_d[k] = {ky: va for ky, va in v.get_attrs_gen() if va is not None and v.get_user_defined(ky)} js = json.dumps(cfg_d, indent=4) logger.debugl(1, js) f.write(js) @@ -576,7 +688,7 @@ class PanelizeOptions(VariantOptions): fname = GS.pcb_file # Create the command - cmd = [cmd_kikit, 'panelize'] + cmd = [cmd_kikit, 'panelize'] # , '--dump', 'test.json' # Add all the configurations for cfg in self.configs: cmd.append('--preset') diff --git a/tests/yaml_samples/panelize_1.kibot.yaml b/tests/yaml_samples/panelize_1.kibot.yaml index 67e510e0..b10d16d1 100644 --- a/tests/yaml_samples/panelize_1.kibot.yaml +++ b/tests/yaml_samples/panelize_1.kibot.yaml @@ -52,6 +52,7 @@ outputs: coppersize: 2 opening: 1 text: + type: simple text: My panel anchor: mt voffset: 2.5 diff --git a/tests/yaml_samples/panelize_all_examples.kibot.yaml b/tests/yaml_samples/panelize_all_examples.kibot.yaml new file mode 100644 index 00000000..050efdcb --- /dev/null +++ b/tests/yaml_samples/panelize_all_examples.kibot.yaml @@ -0,0 +1,385 @@ +# Example KiBot config file for a basic panel +kibot: + version: 1 + +outputs: + - name: 'panel_examples' + comment: "The KiKit examples" + type: panelize + run_by_default: false + options: + configs: + - name: basic + layout: + rows: 2 + cols: 2 + tabs: + type: full + cuts: + type: vcuts + - name: mill_radius_1 + post: + mill_radius: 1 + - name: basic_with_tabs + extends: panel_examples[basic] + layout: + space: 2 + tabs: + type: fixed + hwidth: 10 + vwidth: 15 + - name: vcuts_railstb + extends: panel_examples[basic_with_tabs] + framing: + type: railstb + width: 5 + space: 3 + - name: basic_with_mouse_bites + extends: panel_examples[basic_with_tabs] + tabs: + width: 5 + cuts: + type: mousebites + drill: 0.5 + spacing: 1 + offset: 0.2 + - name: basic_with_mouse_bites_prolong + extends: panel_examples[basic_with_mouse_bites] + tabs: + width: 3 + cuts: + prolong: 0.5 + - name: basic_with_mouse_bites_2v + extends: panel_examples[basic_with_mouse_bites_prolong] + tabs: + vcount: 2 + - name: basic_with_mouse_bites_fm1 + extends: panel_examples[basic_with_mouse_bites_2v] + framing: + type: railstb + width: 5 + space: 3 + - name: basic_with_mouse_bites_fm2 + extends: panel_examples[basic_with_mouse_bites_fm1] + framing: + type: frame + cuts: both + - name: basic_with_mouse_bites_fm3 + extends: panel_examples[basic_with_mouse_bites_fm2] + framing: + type: frame + cuts: h + - name: tight + extends: panel_examples[basic] + layout: + space: 6 + tabs: + type: fixed + width: 3 + vcount: 2 + framing: + type: tightframe + width: 5 + space: 3 + - name: holes_fid_text + extends: panel_examples[basic_with_mouse_bites_fm1] + tooling: + type: 3hole + hoffset: 2.5 + voffset: 2.5 + size: 1.5 + fiducials: + type: 3fid + hoffset: 5 + voffset: 2.5 + coppersize: 2 + opening: 1 + text: + type: simple + text: Example panel + anchor: mt + voffset: 2.5 + hjustify: center + vjustify: center + - name: holes_fid_text2 + extends: panel_examples[holes_fid_text] + text2: + type: simple + text: "Created on {date}" + anchor: mb + voffset: -2.5 + hjustify: center + vjustify: center + - name: holes_fid_text_rounded + extends: panel_examples[holes_fid_text] + framing: + fillet: 1 + - name: holes_fid_text_chamfer + extends: panel_examples[holes_fid_text] + framing: + chamfer: 1 + - name: holes_fid_text_minimal + extends: panel_examples[holes_fid_text] + framing: + type: frame + mintotalheight: 100 + mintotalwidth: 100 + text: + text: Example panel with minimal dimensions + - name: 'panel_basic' + comment: "Basic example" + type: panelize + output_id: _basic + options: + configs: + - extends: panel_examples[basic] + + - name: 'panel_basic_with_mill_radius' + comment: "Basic example + mill radius simulation" + type: panelize + output_id: _basic_with_mill_radius + options: + configs: + - extends: panel_examples[basic] + post: + mill_radius: 1 + + - name: 'panel_basic_with_tabs' + comment: "Basic example + simple tabs" + type: panelize + output_id: _basic_with_tabs + options: + configs: + - extends: panel_examples[basic_with_tabs] + post: + mill_radius: 1 + + - name: 'basic_with_mouse_bites' + comment: "Basic example + mouse bites" + type: panelize + output_id: _basic_with_nouse_bites + options: + configs: + - extends: panel_examples[basic_with_mouse_bites] + + - name: 'basic_with_mouse_bites_mr' + comment: "Basic example + mouse bites + mill radius simulation" + type: panelize + output_id: _basic_with_nouse_bites_mr + options: + configs: + - extends: panel_examples[basic_with_mouse_bites] + - extends: panel_examples[mill_radius_1] + + - name: 'basic_with_mouse_bites_mrp' + comment: "Basic example + mouse bites + prolong + mill radius simulation" + type: panelize + output_id: _basic_with_nouse_bites_mrp + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_prolong] + - extends: panel_examples[mill_radius_1] + + - name: 'basic_with_mouse_bites_2v' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + mill radius simulation" + type: panelize + output_id: _basic_with_nouse_bites_2v + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_2v] + - extends: panel_examples[mill_radius_1] + + - name: 'basic_with_mouse_bites_fm1' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + mill radius simulation" + type: panelize + output_id: _basic_with_nouse_bites_fm1 + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm1] + - extends: panel_examples[mill_radius_1] + + - name: 'basic_with_mouse_bites_fm2' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame full + mill radius simulation" + type: panelize + output_id: _basic_with_nouse_bites_fm2 + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm2] + - extends: panel_examples[mill_radius_1] + + - name: 'basic_with_mouse_bites_fm3' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame full h cuts + mill radius simulation" + type: panelize + output_id: _basic_with_nouse_bites_fm3 + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm3] + - extends: panel_examples[mill_radius_1] + + - name: 'tight' + comment: "Tight frame example" + type: panelize + output_id: _tight + options: + configs: + - extends: panel_examples[tight] + - extends: panel_examples[mill_radius_1] + + - name: 'holes_fid_text' + comment: "With marks and text" + type: panelize + output_id: _holes_fid_text + options: + configs: + - extends: panel_examples[holes_fid_text] + - extends: panel_examples[mill_radius_1] + + - name: 'holes_fid_text2' + comment: "With marks and two texts" + type: panelize + output_id: _holes_fid_text2 + options: + configs: + - extends: panel_examples[holes_fid_text2] + - extends: panel_examples[mill_radius_1] + + - name: 'holes_fid_text_rounded' + comment: "With marks and text, rounded" + type: panelize + output_id: _holes_fid_text_rounded + options: + configs: + - extends: panel_examples[holes_fid_text_rounded] + - extends: panel_examples[mill_radius_1] + + - name: 'holes_fid_text_chamfer' + comment: "With marks and text, chamfer" + type: panelize + output_id: _holes_fid_text_chamfer + options: + configs: + - extends: panel_examples[holes_fid_text_chamfer] + - extends: panel_examples[mill_radius_1] + + - name: 'holes_fid_text_minimal' + comment: "With marks and text, minimal" + type: panelize + output_id: _holes_fid_text_minimal + options: + configs: + - extends: panel_examples[holes_fid_text_minimal] + - extends: panel_examples[mill_radius_1] + + - name: 'rotated_45' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame full + rotated + mill radius simulation" + type: panelize + output_id: _rotated_45 + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm2] + layout: + rotation: 45 + - extends: panel_examples[mill_radius_1] + + - name: 'alternated' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame full + alternated + mill radius simulation" + type: panelize + output_id: _alternated + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm2] + layout: + alternation: cols + - extends: panel_examples[mill_radius_1] + + - name: 'hbone' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + h bone + mill radius simulation" + type: panelize + output_id: _hbone + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm1] + layout: + hbonecut: true + hbackbone: 5 + - extends: panel_examples[mill_radius_1] + + - name: 'both_bones' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + both bones + mill radius simulation" + type: panelize + output_id: _both_bones + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm1] + layout: + rows: 4 + cols: 4 + hbackbone: 5 + vbackbone: 5 + hboneskip: 1 + vboneskip: 1 + - extends: panel_examples[mill_radius_1] + + - name: 'spec_tabs' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + indicated tabs + mill radius simulation" + type: panelize + output_id: _spec_tabs + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm1] + layout: + space: 5 + tabs: + type: annotation + - extends: panel_examples[mill_radius_1] + + - name: 'spec_tabs_bones' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + indicated tabs + bones + mill radius simulation" + type: panelize + output_id: _spec_tabs_bones + options: + configs: + - extends: spec_tabs[1] + layout: + space: 2 + hbackbone: 3 + vbackbone: 3 + - extends: panel_examples[mill_radius_1] + + - name: 'copperfill_solid_1' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + copperfill solid + mill radius simulation" + type: panelize + output_id: _copperfill_solid_1 + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm1] + copperfill: + type: solid + - extends: panel_examples[mill_radius_1] + + - name: 'copperfill_solid_2' + comment: "Copperfill and V-Cuts" + type: panelize + output_id: _copperfill_solid_2 + options: + configs: + - extends: panel_examples[vcuts_railstb] + copperfill: + type: solid + cuts: + clearance: 1.5 + - extends: panel_examples[mill_radius_1] + + - name: 'copperfill_hatched' + comment: "Basic example + mouse bites + prolong + 2 vert tabs + frame h + copperfill hatched + mill radius simulation" + type: panelize + output_id: _copperfill_hatched + options: + configs: + - extends: panel_examples[basic_with_mouse_bites_fm1] + copperfill: + type: hatched + clearance: 2 + spacing: 0.5 + width: 0.5 + - extends: panel_examples[mill_radius_1] diff --git a/tests/yaml_samples/panelize_check_defaults.kibot.yaml b/tests/yaml_samples/panelize_check_defaults.kibot.yaml new file mode 100644 index 00000000..5efd7e4d --- /dev/null +++ b/tests/yaml_samples/panelize_check_defaults.kibot.yaml @@ -0,0 +1,17 @@ +# Example KiBot config file for a basic panel +kibot: + version: 1 + +outputs: + - name: 'panel' + comment: "Create a 4x4 complex panel" + type: panelize + options: + title: '+ (Panel)' + default_units: mm + configs: + - layout: + rows: 2 + cols: 2 + page: + anchor: c