Don't apply dilation scripts in convert, add paste test
This commit is contained in:
parent
e1c40e8c80
commit
be24d0368f
16 changed files with 33884 additions and 68 deletions
|
|
@ -16,7 +16,6 @@ from zipfile import ZipFile, is_zipfile
|
|||
from pathlib import Path
|
||||
|
||||
from bs4 import BeautifulSoup
|
||||
from lxml import etree
|
||||
import numpy as np
|
||||
import click
|
||||
|
||||
|
|
@ -71,7 +70,7 @@ def paste(input_gerbers, input_svg, output_gerbers, is_zip,
|
|||
run_cargo_command('usvg', *shlex.split(os.environ.get('USVG_OPTIONS', '')), input_svg, processed_svg.name)
|
||||
|
||||
with open(processed_svg.name) as f:
|
||||
soup = BeautifulSoup(f.read(), features='lxml')
|
||||
soup = BeautifulSoup(f.read(), features='xml')
|
||||
|
||||
for (side, use), layer in [
|
||||
*stack.graphic_layers.items(),
|
||||
|
|
@ -245,8 +244,7 @@ def empty_template(output_svg, size, force, copper_layers, no_default_layers, la
|
|||
@click.option('--composite-drill-file/--separate-drill-file', 'composite_drill', help='Use Altium composite Excellon drill file format (default)')
|
||||
@click.option('--dilate', default=0.1, type=float, help='Default dilation for subtraction operations in mm')
|
||||
@click.option('--curve-tolerance', type=float, help='Tolerance for curve flattening in mm')
|
||||
@click.option('--no-subtract', 'no_subtract', flag_value=True, help='Disable subtraction')
|
||||
@click.option('--subtract', help='Use user subtraction script from argument (see description above)')
|
||||
@click.option('--subtract', help='Use user subtraction script from argument (default for "convert": none)')
|
||||
@click.option('--trace-space', type=float, default=0.1, help='passed through to svg-flatten')
|
||||
@click.option('--vectorizer', help='passed through to svg-flatten')
|
||||
@click.option('--vectorizer-map', help='passed through to svg-flatten')
|
||||
|
|
@ -254,76 +252,89 @@ def empty_template(output_svg, size, force, copper_layers, no_default_layers, la
|
|||
@click.option('--circle-test-tolerance', help='passed through to svg-flatten')
|
||||
@click.option('--pattern-complete-tiles-only', is_flag=True, help='passed through to svg-flatten')
|
||||
@click.option('--use-apertures-for-patterns', is_flag=True, help='passed through to svg-flatten')
|
||||
def convert(input_svg, output_gerbers, is_zip, dilate, curve_tolerance, no_subtract, subtract, trace_space, vectorizer,
|
||||
@click.option('--log-level', default='info', type=click.Choice(['debug', 'info', 'warning', 'error', 'critical']), help='log level')
|
||||
def convert(input_svg, output_gerbers, is_zip, dilate, curve_tolerance, subtract, trace_space, vectorizer,
|
||||
vectorizer_map, exclude_groups, composite_drill, naming_scheme, circle_test_tolerance,
|
||||
pattern_complete_tiles_only, use_apertures_for_patterns):
|
||||
pattern_complete_tiles_only, use_apertures_for_patterns, log_level):
|
||||
''' Convert SVG file directly to gerbers.
|
||||
|
||||
Unlike `gerbolyze paste`, this does not add the SVG's contents to existing gerbers. It allows you to directly create
|
||||
PCBs using Inkscape similar to PCBModE.
|
||||
'''
|
||||
logging.basicConfig(level=getattr(logging, log_level.upper()))
|
||||
|
||||
subtract_map = parse_subtract_script('' if no_subtract else subtract, dilate, default_script=DEFAULT_CONVERT_SUB_SCRIPT)
|
||||
subtract_map = parse_subtract_script(subtract, dilate, default_script='')
|
||||
output_is_zip = output_gerbers.name.lower().endswith('.zip') if is_zip is None else is_zip
|
||||
|
||||
stack = gn.LayerStack({}, None, None, [], board_name=input_svg.stem, original_path=input_svg)
|
||||
with tempfile.NamedTemporaryFile(suffix='.svg') as processed_svg:
|
||||
run_cargo_command('usvg', *shlex.split(os.environ.get('USVG_OPTIONS', '')), input_svg, processed_svg.name)
|
||||
|
||||
for group_id, label in get_layers_from_svg(input_svg.read_text()):
|
||||
if not group_id or not label or 'no export' in label:
|
||||
continue
|
||||
soup = BeautifulSoup(input_svg.read_text(), features='xml')
|
||||
layers = {e.get('id'): e.get('inkscape:label') for e in soup.find_all('g', recursive=True)}
|
||||
|
||||
if label == 'outline':
|
||||
side, use = 'mechanical', 'outline'
|
||||
elif label == 'comments':
|
||||
side, use = 'other', 'comments'
|
||||
elif len(label.split()) != 2:
|
||||
warnings.warn('Unknown layer {label}')
|
||||
continue
|
||||
else:
|
||||
side, use = label.split()
|
||||
stack = gn.LayerStack({}, None, None, [], board_name=input_svg.stem, original_path=input_svg)
|
||||
|
||||
grb = svg_to_gerber(input_svg,
|
||||
trace_space=trace_space, vectorizer=vectorizer, vectorizer_map=vectorizer_map,
|
||||
exclude_groups=exclude_groups, curve_tolerance=curve_tolerance, only_groups=group_id,
|
||||
circle_test_tolerance=circle_test_tolerance, pattern_complete_tiles_only=pattern_complete_tiles_only,
|
||||
use_apertures_for_patterns=(use_apertures_for_patterns and use not in ('outline', 'drill')),
|
||||
outline_mode=(use == 'outline' or side == 'drill'))
|
||||
grb.original_path = Path()
|
||||
for group_id, label in layers.items():
|
||||
label = label or ''
|
||||
if not group_id or 'no export' in label:
|
||||
continue
|
||||
|
||||
if side == 'drill':
|
||||
if use == 'plated':
|
||||
stack.drill_pth = grb.to_excellon(plated=True)
|
||||
elif use == 'nonplated':
|
||||
stack.drill_npth = grb.to_excellon(plated=False)
|
||||
if not group_id.startswith('g-'):
|
||||
continue
|
||||
group_id = group_id[2:]
|
||||
|
||||
if group_id == 'outline':
|
||||
side, use = 'mechanical', 'outline'
|
||||
elif group_id == 'comments':
|
||||
side, use = 'other', 'comments'
|
||||
elif len(group_id.split('-')) != 2:
|
||||
warnings.warn(f'Unknown layer {group_id}')
|
||||
continue
|
||||
else:
|
||||
warnings.warn(f'Invalid drill layer type "{side}". Must be one of "plated" or "nonplated"')
|
||||
side, use = group_id.split('-')
|
||||
|
||||
grb = svg_to_gerber(processed_svg.name, no_usvg=True,
|
||||
trace_space=trace_space, vectorizer=vectorizer, vectorizer_map=vectorizer_map,
|
||||
exclude_groups=exclude_groups, curve_tolerance=curve_tolerance, only_groups=f'g-{group_id}',
|
||||
circle_test_tolerance=circle_test_tolerance, pattern_complete_tiles_only=pattern_complete_tiles_only,
|
||||
use_apertures_for_patterns=(use_apertures_for_patterns and use not in ('outline', 'drill')),
|
||||
outline_mode=(use == 'outline' or side == 'drill'))
|
||||
grb.original_path = Path()
|
||||
|
||||
if side == 'drill':
|
||||
if use == 'plated':
|
||||
stack.drill_pth = grb.to_excellon(plated=True)
|
||||
elif use == 'nonplated':
|
||||
stack.drill_npth = grb.to_excellon(plated=False)
|
||||
else:
|
||||
warnings.warn(f'Invalid drill layer type "{side}". Must be one of "plated" or "nonplated"')
|
||||
|
||||
else:
|
||||
stack.graphic_layers[(side, use)] = grb
|
||||
|
||||
bounds = stack.board_bounds()
|
||||
@functools.lru_cache()
|
||||
def do_dilate(layer, amount):
|
||||
return dilate_gerber(layer, bounds, amount, curve_tolerance)
|
||||
|
||||
for (side, use), layer in stack.graphic_layers.items():
|
||||
# dilated subtract layers on top of overlay
|
||||
if side in ('top', 'bottom'): # do not process subtraction scripts for inner layers
|
||||
dilations = subtract_map.get(use, [])
|
||||
for d_layer, amount in dilations:
|
||||
d_layer = stack.graphic_layers[(side, d_layer)]
|
||||
dilated = do_dilate(d_layer, amount)
|
||||
layer.merge(dilated, mode='above', keep_settings=True)
|
||||
|
||||
if composite_drill:
|
||||
logging.info('Merging drill layers...')
|
||||
stack.merge_drill_layers()
|
||||
|
||||
naming_scheme = getattr(gn.layers.NamingScheme, naming_scheme)
|
||||
if output_is_zip:
|
||||
stack.save_to_zipfile(output_gerbers, naming_scheme=naming_scheme)
|
||||
else:
|
||||
stack.graphic_layers[(side, use)] = grb
|
||||
|
||||
bounds = stack.board_bounds()
|
||||
@functools.lru_cache()
|
||||
def do_dilate(layer, amount):
|
||||
return dilate_gerber(layer, bounds, amount, curve_tolerance)
|
||||
|
||||
for (side, use), layer in stack.graphic_layers.items():
|
||||
# dilated subtract layers on top of overlay
|
||||
if side in ('top', 'bottom'): # do not process subtraction scripts for inner layers
|
||||
dilations = subtract_map.get(use, [])
|
||||
for d_layer, amount in dilations:
|
||||
d_layer = stack.graphic_layers[(side, d_layer)]
|
||||
dilated = do_dilate(d_layer, amount)
|
||||
layer.merge(dilated, mode='above', keep_settings=True)
|
||||
|
||||
if composite_drill:
|
||||
logging.info('Merging drill layers...')
|
||||
stack.merge_drill_layers()
|
||||
|
||||
naming_scheme = getattr(gn.layers.NamingScheme, naming_scheme)
|
||||
if output_is_zip:
|
||||
stack.save_to_zipfile(output_gerbers, naming_scheme=naming_scheme)
|
||||
else:
|
||||
stack.save_to_directory(output_gerbers, naming_scheme=naming_scheme)
|
||||
stack.save_to_directory(output_gerbers, naming_scheme=naming_scheme)
|
||||
|
||||
|
||||
# Subtraction script handling
|
||||
|
|
@ -579,15 +590,5 @@ def svg_to_gerber(infile, outline_mode=False, **kwargs):
|
|||
|
||||
return gn.rs274x.GerberFile.open(temp_gbr.name)
|
||||
|
||||
def get_layers_from_svg(svg_data):
|
||||
svg = etree.fromstring(svg_data.encode('utf-8'))
|
||||
SVG_NS = '{http://www.w3.org/2000/svg}'
|
||||
INKSCAPE_NS = '{http://www.inkscape.org/namespaces/inkscape}'
|
||||
|
||||
# find groups
|
||||
for group in svg.findall(SVG_NS+'g'):
|
||||
yield group.get('id'), group.get(INKSCAPE_NS+'label')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
|
|
|
|||
4940
gerbolyze/tests/resources/layers-gerber/layers-B.Cu.gbr
Normal file
4940
gerbolyze/tests/resources/layers-gerber/layers-B.Cu.gbr
Normal file
File diff suppressed because it is too large
Load diff
4242
gerbolyze/tests/resources/layers-gerber/layers-B.Mask.gbr
Normal file
4242
gerbolyze/tests/resources/layers-gerber/layers-B.Mask.gbr
Normal file
File diff suppressed because it is too large
Load diff
4470
gerbolyze/tests/resources/layers-gerber/layers-B.Paste.gbr
Normal file
4470
gerbolyze/tests/resources/layers-gerber/layers-B.Paste.gbr
Normal file
File diff suppressed because it is too large
Load diff
4043
gerbolyze/tests/resources/layers-gerber/layers-B.SilkS.gbr
Normal file
4043
gerbolyze/tests/resources/layers-gerber/layers-B.SilkS.gbr
Normal file
File diff suppressed because it is too large
Load diff
29
gerbolyze/tests/resources/layers-gerber/layers-Cmts.User.gbr
Normal file
29
gerbolyze/tests/resources/layers-gerber/layers-Cmts.User.gbr
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
G04 Gerber file generated by Gerbonara*
|
||||
%MOMM*%
|
||||
%FSLAX46Y46*%
|
||||
%IPPOS*%
|
||||
G75
|
||||
%LPD*%
|
||||
%AMGNC*
|
||||
1,1,$1,0,0,-57.29578X$4*
|
||||
1,0,$2,0,0,0*
|
||||
21,0,$2,$3,0,0,-57.29578X$4*
|
||||
%
|
||||
%AMGNR*
|
||||
21,1,$1,$2,0,0,$5X-57.29578*
|
||||
1,0,$3,0,0,0*
|
||||
21,0,$3,$4,0,0,$5X-57.29578*
|
||||
%
|
||||
%AMGNO*
|
||||
21,1,$1,$2,0,0,$5X-57.29578*
|
||||
1,1,$2,$1/2,0,$5X-57.29578*
|
||||
1,1,$2,(0-$1)/2,0,$5X-57.29578*
|
||||
1,0,$3,0,0,0*
|
||||
21,0,$3,$4,0,0,$5X-57.29578*
|
||||
%
|
||||
%AMGNP*
|
||||
5,1,$2,0,0,$1,$3X-57.29578*
|
||||
1,0,$4,0,0,0*
|
||||
%
|
||||
%ADD10C,0.05*%
|
||||
M02*
|
||||
2710
gerbolyze/tests/resources/layers-gerber/layers-Edge.Cuts.gbr
Normal file
2710
gerbolyze/tests/resources/layers-gerber/layers-Edge.Cuts.gbr
Normal file
File diff suppressed because it is too large
Load diff
3683
gerbolyze/tests/resources/layers-gerber/layers-F.Cu.gbr
Normal file
3683
gerbolyze/tests/resources/layers-gerber/layers-F.Cu.gbr
Normal file
File diff suppressed because it is too large
Load diff
2983
gerbolyze/tests/resources/layers-gerber/layers-F.Mask.gbr
Normal file
2983
gerbolyze/tests/resources/layers-gerber/layers-F.Mask.gbr
Normal file
File diff suppressed because it is too large
Load diff
3211
gerbolyze/tests/resources/layers-gerber/layers-F.Paste.gbr
Normal file
3211
gerbolyze/tests/resources/layers-gerber/layers-F.Paste.gbr
Normal file
File diff suppressed because it is too large
Load diff
2788
gerbolyze/tests/resources/layers-gerber/layers-F.SilkS.gbr
Normal file
2788
gerbolyze/tests/resources/layers-gerber/layers-F.SilkS.gbr
Normal file
File diff suppressed because it is too large
Load diff
154
gerbolyze/tests/resources/layers-gerber/layers-NPTH.drl
Normal file
154
gerbolyze/tests/resources/layers-gerber/layers-NPTH.drl
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
; XNC file generated by gerbonara
|
||||
M48
|
||||
METRIC
|
||||
T01C0000.50000
|
||||
%
|
||||
T01
|
||||
G05
|
||||
X0006.40777Y0046.75991
|
||||
X0006.40777Y0046.00921
|
||||
X0006.40777Y0045.25852
|
||||
X0006.40777Y0044.50783
|
||||
X0006.40777Y0043.75713
|
||||
X0006.40777Y0043.00644
|
||||
X0006.40777Y0042.25575
|
||||
X0007.15847Y0046.00921
|
||||
X0007.90916Y0045.25852
|
||||
X0007.90916Y0044.50783
|
||||
X0007.90916Y0043.75713
|
||||
X0008.65985Y0043.00644
|
||||
X0009.41055Y0046.75991
|
||||
X0009.41055Y0046.00921
|
||||
X0009.41055Y0045.25852
|
||||
X0009.41055Y0044.50783
|
||||
X0009.41055Y0043.75713
|
||||
X0009.41055Y0043.00644
|
||||
X0009.41055Y0042.25575
|
||||
X0011.65588Y0046.00921
|
||||
X0011.65588Y0045.25852
|
||||
X0011.65588Y0044.50783
|
||||
X0011.65588Y0043.75713
|
||||
X0011.65588Y0043.00644
|
||||
X0012.40657Y0046.75991
|
||||
X0012.40657Y0042.25575
|
||||
X0013.15726Y0046.75991
|
||||
X0013.15726Y0042.25575
|
||||
X0013.90796Y0046.75991
|
||||
X0013.90796Y0042.25575
|
||||
X0014.65865Y0046.00921
|
||||
X0014.65865Y0045.25852
|
||||
X0014.65865Y0044.50783
|
||||
X0014.65865Y0043.75713
|
||||
X0014.65865Y0043.00644
|
||||
X0016.91003Y0046.75991
|
||||
X0016.91003Y0046.00921
|
||||
X0016.91003Y0045.25852
|
||||
X0016.91003Y0044.50783
|
||||
X0016.91003Y0043.75713
|
||||
X0016.91003Y0043.00644
|
||||
X0016.91003Y0042.25575
|
||||
X0017.66073Y0046.00921
|
||||
X0018.41142Y0045.25852
|
||||
X0018.41142Y0044.50783
|
||||
X0018.41142Y0043.75713
|
||||
X0019.16211Y0043.00644
|
||||
X0019.91281Y0046.75991
|
||||
X0019.91281Y0046.00921
|
||||
X0019.91281Y0045.25852
|
||||
X0019.91281Y0044.50783
|
||||
X0019.91281Y0043.75713
|
||||
X0019.91281Y0043.00644
|
||||
X0019.91281Y0042.25575
|
||||
X0022.37703Y0046.75991
|
||||
X0022.37703Y0046.00921
|
||||
X0022.37703Y0045.25852
|
||||
X0022.37703Y0044.50783
|
||||
X0022.37703Y0043.75713
|
||||
X0022.37703Y0043.00644
|
||||
X0022.37703Y0042.25575
|
||||
X0023.12773Y0046.75991
|
||||
X0023.12772Y0044.50783
|
||||
X0023.87842Y0046.75991
|
||||
X0023.87842Y0044.50783
|
||||
X0024.62911Y0046.75991
|
||||
X0024.62911Y0044.50783
|
||||
X0025.37981Y0046.00921
|
||||
X0025.37981Y0045.25852
|
||||
X0027.62514Y0046.75991
|
||||
X0027.62514Y0046.00921
|
||||
X0027.62514Y0045.25852
|
||||
X0027.62514Y0044.50783
|
||||
X0027.62514Y0043.75713
|
||||
X0027.62514Y0043.00644
|
||||
X0027.62514Y0042.25575
|
||||
X0028.37583Y0042.25575
|
||||
X0029.12652Y0042.25575
|
||||
X0029.87721Y0042.25575
|
||||
X0030.62791Y0042.25575
|
||||
X0032.87324Y0046.00921
|
||||
X0032.87324Y0045.25852
|
||||
X0032.87324Y0044.50783
|
||||
X0032.87324Y0043.75713
|
||||
X0032.87324Y0043.00644
|
||||
X0032.87324Y0042.25575
|
||||
X0033.62393Y0046.75991
|
||||
X0033.62393Y0043.75713
|
||||
X0034.37463Y0046.75991
|
||||
X0034.37463Y0043.75713
|
||||
X0035.12532Y0046.75991
|
||||
X0035.12532Y0043.75713
|
||||
X0035.87601Y0046.00921
|
||||
X0035.87601Y0045.25852
|
||||
X0035.87601Y0044.50783
|
||||
X0035.87601Y0043.75713
|
||||
X0035.87601Y0043.00644
|
||||
X0035.87601Y0042.25575
|
||||
X0038.12134Y0046.75991
|
||||
X0038.87204Y0046.75991
|
||||
X0039.62273Y0046.75991
|
||||
X0039.62273Y0046.00921
|
||||
X0039.62273Y0045.25852
|
||||
X0039.62273Y0044.50783
|
||||
X0039.62273Y0043.75713
|
||||
X0039.62273Y0043.00644
|
||||
X0039.62273Y0042.25575
|
||||
X0040.37342Y0046.75991
|
||||
X0041.12412Y0046.75991
|
||||
X0043.36945Y0046.75991
|
||||
X0043.36945Y0046.00921
|
||||
X0043.36945Y0045.25852
|
||||
X0043.36945Y0044.50783
|
||||
X0043.36945Y0043.75713
|
||||
X0043.36945Y0043.00644
|
||||
X0043.36945Y0042.25575
|
||||
X0044.12014Y0046.75991
|
||||
X0044.12014Y0044.50783
|
||||
X0044.12014Y0042.25575
|
||||
X0044.87083Y0046.75991
|
||||
X0044.87083Y0044.50783
|
||||
X0044.87083Y0042.25575
|
||||
X0045.62153Y0046.75991
|
||||
X0045.62153Y0044.50783
|
||||
X0045.62153Y0042.25575
|
||||
X0046.37222Y0046.75991
|
||||
X0046.37222Y0044.50783
|
||||
X0046.37222Y0042.25575
|
||||
X0048.61755Y0046.75991
|
||||
X0048.61755Y0046.00921
|
||||
X0048.61755Y0045.25852
|
||||
X0048.61755Y0044.50783
|
||||
X0048.61755Y0043.75713
|
||||
X0048.61755Y0043.00644
|
||||
X0048.61755Y0042.25575
|
||||
X0049.36825Y0046.75991
|
||||
X0049.36825Y0042.25575
|
||||
X0050.11894Y0046.75991
|
||||
X0050.11894Y0042.25575
|
||||
X0050.86963Y0046.75991
|
||||
X0050.86963Y0042.25575
|
||||
X0051.62033Y0046.00921
|
||||
X0051.62033Y0045.25852
|
||||
X0051.62033Y0044.50783
|
||||
X0051.62033Y0043.75713
|
||||
X0051.62033Y0043.00644
|
||||
M30
|
||||
136
gerbolyze/tests/resources/layers-gerber/layers-PTH.drl
Normal file
136
gerbolyze/tests/resources/layers-gerber/layers-PTH.drl
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
; XNC file generated by gerbonara
|
||||
M48
|
||||
METRIC
|
||||
T01C0000.70000
|
||||
%
|
||||
T01
|
||||
G05
|
||||
X0006.50749Y0058.18246
|
||||
X0007.85409Y0058.18246
|
||||
X0007.85409Y0057.13262
|
||||
X0007.85409Y0056.08279
|
||||
X0007.85409Y0055.03295
|
||||
X0007.85409Y0053.98311
|
||||
X0007.85409Y0052.93327
|
||||
X0007.85409Y0051.88343
|
||||
X0008.90393Y0058.18246
|
||||
X0008.90393Y0057.13262
|
||||
X0008.90393Y0056.08279
|
||||
X0008.90393Y0055.03295
|
||||
X0008.90393Y0053.98311
|
||||
X0008.90393Y0052.93327
|
||||
X0008.90393Y0051.88343
|
||||
X0009.95377Y0058.18246
|
||||
X0009.95377Y0057.13262
|
||||
X0009.95377Y0056.08279
|
||||
X0009.95377Y0055.03295
|
||||
X0009.95377Y0053.98311
|
||||
X0009.95377Y0052.93327
|
||||
X0009.95377Y0051.88343
|
||||
X0011.00360Y0058.18246
|
||||
X0011.00360Y0057.13262
|
||||
X0011.00360Y0056.08279
|
||||
X0011.00360Y0055.03295
|
||||
X0011.00360Y0053.98311
|
||||
X0011.00360Y0052.93327
|
||||
X0011.00360Y0051.88343
|
||||
X0012.05344Y0058.18246
|
||||
X0012.05344Y0057.13262
|
||||
X0012.05344Y0056.08279
|
||||
X0012.05344Y0055.03295
|
||||
X0012.05344Y0053.98311
|
||||
X0012.05344Y0052.93327
|
||||
X0012.05344Y0051.88343
|
||||
X0014.85905Y0058.18246
|
||||
X0014.85905Y0057.13262
|
||||
X0014.85905Y0056.08279
|
||||
X0014.85905Y0055.03295
|
||||
X0014.85905Y0053.98311
|
||||
X0014.85905Y0052.93327
|
||||
X0014.85905Y0051.88343
|
||||
X0015.90889Y0058.18246
|
||||
X0015.90889Y0055.03295
|
||||
X0016.95873Y0058.18246
|
||||
X0016.95873Y0055.03295
|
||||
X0018.00857Y0058.18246
|
||||
X0018.00857Y0055.03295
|
||||
X0019.05841Y0057.13262
|
||||
X0019.05841Y0056.08279
|
||||
X0022.19849Y0058.18246
|
||||
X0022.19849Y0057.13262
|
||||
X0022.19849Y0056.08279
|
||||
X0022.19849Y0055.03295
|
||||
X0022.19849Y0053.98311
|
||||
X0022.19849Y0052.93327
|
||||
X0022.19849Y0051.88343
|
||||
X0023.24833Y0051.88343
|
||||
X0024.29816Y0051.88343
|
||||
X0025.34800Y0051.88343
|
||||
X0026.39784Y0051.88343
|
||||
X0029.53792Y0057.13262
|
||||
X0029.53792Y0056.08279
|
||||
X0029.53792Y0055.03295
|
||||
X0029.53792Y0053.98311
|
||||
X0029.53792Y0052.93327
|
||||
X0029.53792Y0051.88343
|
||||
X0030.58776Y0058.18246
|
||||
X0030.58776Y0053.98311
|
||||
X0031.63760Y0058.18246
|
||||
X0031.63760Y0053.98311
|
||||
X0032.68744Y0058.18246
|
||||
X0032.68744Y0053.98311
|
||||
X0033.73728Y0057.13262
|
||||
X0033.73728Y0056.08279
|
||||
X0033.73728Y0055.03295
|
||||
X0033.73728Y0053.98311
|
||||
X0033.73728Y0052.93327
|
||||
X0033.73728Y0051.88343
|
||||
X0036.87735Y0058.18246
|
||||
X0037.92719Y0058.18246
|
||||
X0038.97703Y0058.18246
|
||||
X0038.97703Y0057.13262
|
||||
X0038.97703Y0056.08279
|
||||
X0038.97703Y0055.03295
|
||||
X0038.97703Y0053.98311
|
||||
X0038.97703Y0052.93327
|
||||
X0038.97703Y0051.88343
|
||||
X0040.02687Y0058.18246
|
||||
X0041.07671Y0058.18246
|
||||
X0044.21679Y0058.18246
|
||||
X0044.21679Y0057.13262
|
||||
X0044.21679Y0056.08279
|
||||
X0044.21679Y0055.03295
|
||||
X0044.21679Y0053.98311
|
||||
X0044.21679Y0052.93327
|
||||
X0044.21679Y0051.88343
|
||||
X0045.26663Y0058.18246
|
||||
X0045.26663Y0055.03295
|
||||
X0045.26663Y0051.88343
|
||||
X0046.31647Y0058.18246
|
||||
X0046.31647Y0055.03295
|
||||
X0046.31647Y0051.88343
|
||||
X0047.36631Y0058.18246
|
||||
X0047.36631Y0055.03295
|
||||
X0047.36631Y0051.88343
|
||||
X0048.41615Y0058.18246
|
||||
X0048.41615Y0055.03295
|
||||
X0048.41615Y0051.88343
|
||||
X0051.55622Y0058.18246
|
||||
X0051.55622Y0057.13262
|
||||
X0051.55622Y0056.08279
|
||||
X0051.55622Y0055.03295
|
||||
X0051.55622Y0053.98311
|
||||
X0051.55622Y0052.93327
|
||||
X0051.55622Y0051.88343
|
||||
X0052.60606Y0058.18246
|
||||
X0052.60606Y0051.88343
|
||||
X0053.65590Y0058.18246
|
||||
X0053.65590Y0051.88343
|
||||
X0054.70574Y0058.18246
|
||||
X0054.70574Y0051.88343
|
||||
X0055.75558Y0057.13262
|
||||
X0055.75558Y0056.08279
|
||||
X0055.75558Y0055.03295
|
||||
X0055.75558Y0053.98311
|
||||
X0055.75558Y0052.93327
|
||||
M30
|
||||
255
gerbolyze/tests/resources/tpl-bottom.svg
Normal file
255
gerbolyze/tests/resources/tpl-bottom.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 521 KiB |
135
gerbolyze/tests/resources/tpl-top.svg
Normal file
135
gerbolyze/tests/resources/tpl-top.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 192 KiB |
|
|
@ -16,6 +16,7 @@
|
|||
#
|
||||
|
||||
import sys
|
||||
import math
|
||||
import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
|
@ -66,6 +67,41 @@ def test_template(reference):
|
|||
run_command('python3', '-m', 'gerbolyze', 'template', '--top', '--force', infile, out_svg.name)
|
||||
run_command('python3', '-m', 'gerbolyze', 'template', '--bottom', '--force', '--vector', infile, out_svg.name)
|
||||
|
||||
def test_paste():
|
||||
in_gerbers = reference_path('layers-gerber')
|
||||
top_overlay = reference_path('tpl-top.svg')
|
||||
bottom_overlay = reference_path('tpl-bottom.svg')
|
||||
with tempfile.TemporaryDirectory() as intermediate_gerbers,\
|
||||
tempfile.TemporaryDirectory() as output_gerbers:
|
||||
run_command('python3', '-m', 'gerbolyze', 'paste', '--no-subtract', in_gerbers, top_overlay, intermediate_gerbers)
|
||||
run_command('python3', '-m', 'gerbolyze', 'paste', '--no-subtract', intermediate_gerbers, bottom_overlay, output_gerbers)
|
||||
|
||||
stack_old = gerbonara.layers.LayerStack.open(in_gerbers)
|
||||
stack_new = gerbonara.layers.LayerStack.open(output_gerbers)
|
||||
|
||||
for (side, use), layer_old in stack_old.graphic_layers.items():
|
||||
if use == 'outline':
|
||||
continue
|
||||
layer_new = stack_new[side, use]
|
||||
|
||||
bbox_old = layer_old.bounding_box(gerbonara.utils.MM)
|
||||
bbox_new = layer_new.bounding_box(gerbonara.utils.MM)
|
||||
print(side, use, bbox_old, bbox_new)
|
||||
print(' -> ',
|
||||
bbox_new[0][0]-bbox_old[0][0], bbox_new[0][1]-bbox_old[0][1],
|
||||
bbox_new[1][0]-bbox_old[1][0], bbox_new[1][1]-bbox_old[1][1])
|
||||
print(' -> ',
|
||||
bbox_new[0][0], bbox_new[0][1],
|
||||
bbox_new[1][0], bbox_new[1][1])
|
||||
print(' old ->', layer_old)
|
||||
print(' new ->', layer_new)
|
||||
|
||||
e = 0.8
|
||||
assert math.isclose(bbox_new[0][0], bbox_old[0][0]-e, abs_tol=0.1)
|
||||
assert math.isclose(bbox_new[0][1], bbox_old[0][1]-e, abs_tol=0.1)
|
||||
assert math.isclose(bbox_new[1][0], bbox_old[1][0]+e, abs_tol=0.1)
|
||||
assert math.isclose(bbox_new[1][1], bbox_old[1][1]+e, abs_tol=0.1)
|
||||
|
||||
def test_convert_layers():
|
||||
infile = reference_path('layers.svg')
|
||||
with tempfile.TemporaryDirectory() as out_dir:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue