aboutsummaryrefslogtreecommitdiff
path: root/gerbolyze/gerbolyze.py
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2021-02-06 14:59:44 +0100
committerjaseg <git@jaseg.de>2021-02-06 14:59:44 +0100
commit3e323c953c1916b6d342f01e1a28916b86b692c9 (patch)
tree33ac231f4987553f94a597c2b4f9361dba9d0a47 /gerbolyze/gerbolyze.py
parent13cb49b218df952a11316988c1a02e5c72851f9d (diff)
downloadgerbolyze-3e323c953c1916b6d342f01e1a28916b86b692c9.tar.gz
gerbolyze-3e323c953c1916b6d342f01e1a28916b86b692c9.tar.bz2
gerbolyze-3e323c953c1916b6d342f01e1a28916b86b692c9.zip
Add workaround to clipper zero-height path bug
Diffstat (limited to 'gerbolyze/gerbolyze.py')
-rwxr-xr-xgerbolyze/gerbolyze.py34
1 files changed, 26 insertions, 8 deletions
diff --git a/gerbolyze/gerbolyze.py b/gerbolyze/gerbolyze.py
index 297789c..396ca18 100755
--- a/gerbolyze/gerbolyze.py
+++ b/gerbolyze/gerbolyze.py
@@ -54,16 +54,15 @@ def vectorize(ctx, side, layer, exact, source, target, image, trace_space):
@click.argument('output_gerbers')
@click.option('-t', '--top', help='Top side SVG or PNG overlay')
@click.option('-b', '--bottom', help='Bottom side SVG or PNG overlay')
-@click.option('--layer-top', help='Top side SVG or PNG target layer. Default: Map SVG layers to Gerber layers, map PNG to Silk')
-@click.option('--layer-bottom', help='Bottom side SVG or PNG target layer. Default: Map SVG layers to Gerber layers, map PNG to Silk')
+@click.option('--layer-top', help='Top side SVG or PNG target layer. Default: Map SVG layers to Gerber layers, map PNG to Silk.')
+@click.option('--layer-bottom', help='Bottom side SVG or PNG target layer. See --layer-top.')
@click.option('--bbox', help='Output file bounding box. Format: "w,h" to force [w] mm by [h] mm output canvas OR '
'"x,y,w,h" to force [w] mm by [h] mm output canvas with its bottom left corner at the given input gerber '
'coördinates. MUST MATCH --bbox GIVEN TO PREVIEW')
@click.option('--dilate', default=0.1, help='Default dilation for subtraction operations 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('--mask-clips-silk/--silk-clips-mask', default=True, help='Set clipping order of mask and silk')
-#@click.option('--copper-clips-copper/--no-copper-clips-copper', default=True, help='Set whether output copper features clip input copper features')
+@click.option('--input-on-top/--overlay-on-top', default=True, help='Set paint order of input and overlay')
@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')
@@ -74,6 +73,7 @@ def paste(input_gerbers, output_gerbers,
bbox,
dilate, no_subtract, subtract,
preserve_aspect_ratio,
+ input_on_top,
trace_space, vectorizer, vectorizer_map, exclude_groups):
""" Render vector data and raster images from SVG file into gerbers. """
@@ -93,8 +93,14 @@ def paste(input_gerbers, output_gerbers,
matches = match_gerbers_in_dir(source)
if input_gerbers.is_dir():
+ # Create output dir if it does not exist yet
output_gerbers.mkdir(exist_ok=True)
+ # In case output dir already existed, remove files we will overwrite
+ for in_file in source.iterdir():
+ out_cand = output_gerbers / in_file.name
+ out_cand.unlink(missing_ok=True)
+
for side, in_svg_or_png, target_layer in [
('top', top, layer_top),
('bottom', bottom, layer_bottom)]:
@@ -128,7 +134,7 @@ def paste(input_gerbers, output_gerbers,
@functools.lru_cache()
def do_dilate(layer, amount):
print('dilating', layer, 'by', amount)
- outfile = tmpdir / 'dilated-{layer}-{amount}.gbr'
+ outfile = tmpdir / f'dilated-{layer}-{amount}.gbr'
dilate_gerber(layers, layer, amount, bbox, tmpdir, outfile, units)
gbr = gerberex.read(str(outfile))
gbr.offset(bounds[0][0], bounds[1][0])
@@ -163,15 +169,21 @@ def paste(input_gerbers, output_gerbers,
print('compositing')
comp = gerberex.GerberComposition()
- foo = gerberex.rs274x.GerberFile.from_gerber_file(in_grb.cam_source)
- comp.merge(foo)
+ if not input_on_top:
+ # input below everything
+ comp.merge(gerberex.rs274x.GerberFile.from_gerber_file(in_grb.cam_source))
+ # overlay on bottom
overlay_grb.offset(bounds[0][0], bounds[1][0])
comp.merge(overlay_grb)
+ # dilated subtract layers on top of overlay
dilations = subtract_map.get(layer, [])
for d_layer, amount in dilations:
print('processing dilation', d_layer, amount)
dilated = do_dilate(d_layer, amount)
comp.merge(dilated)
+ if input_on_top:
+ # input on top of everything
+ comp.merge(gerberex.rs274x.GerberFile.from_gerber_file(in_grb.cam_source))
if input_gerbers.is_dir():
this_out = output_gerbers / in_grb_path.name
@@ -270,6 +282,9 @@ def template(input, top, bottom, bbox, vector, raster_dpi):
DEFAULT_SUB_SCRIPT = '''
out.silk -= in.mask
+out.silk -= in.silk+0.5
+out.mask -= in.mask+0.5
+out.copper -= in.copper+0.5
'''
def parse_subtract_script(script, default_dilation=0.1):
@@ -578,11 +593,12 @@ def dilate_gerber(layers, layer_name, dilation, bbox, tmpdir, outfile, units):
f'--origin={origin_x:.6f}x{origin_y:.6f}', f'--window_inch={width:.6f}x{height:.6f}',
'--foreground=#ffffff',
'-o', str(tmpfile), str(path)]
+ print('dilation cmd:', ' '.join(cmd))
subprocess.run(cmd, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
# dilate & render back to gerber
# TODO: the scale parameter is a hack. ideally we would fix svg-flatten to handle input units correctly.
- svg_to_gerber(tmpfile, outfile, dilate=-dilation, dpi=72, scale=25.4/72.0)
+ svg_to_gerber(tmpfile, outfile, dilate=-dilation*72.0/25.4, dpi=72, scale=25.4/72.0)
def svg_to_gerber(infile, outfile,
layer=None, trace_space:'mm'=0.1,
@@ -641,9 +657,11 @@ def svg_to_gerber(infile, outfile,
args += [str(infile), str(outfile)]
+ print('svg-flatten args:', ' '.join(args))
for candidate in candidates:
try:
res = subprocess.run([candidate, *args], check=True)
+ print('used svg-flatten:', candidate)
break
except FileNotFoundError:
continue