Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gerbolyze convert fails silently when an SVG contains a polygon with a large number of points. #46

Open
Wulfsta opened this issue Mar 20, 2024 · 0 comments

Comments

@Wulfsta
Copy link

Wulfsta commented Mar 20, 2024

Description

Gerbolyze fails to produce all layers contained in a template SVG generated by the empty-template sub-command when one of the layers contains a polygon with many points. The following can be used to generate a test SVG as well as demonstrate that the directory is lacking the expected set of files:

import numpy as np
import subprocess

from bs4 import BeautifulSoup
from pathlib import Path

def generate_polygon_and_append(soup, layer, radius, point_count=5e5, **kwargs):
    theta_array = np.linspace(0, 2*np.pi, num=int(point_count))
    # don't remember how numpy concat works rn so do it ugly
    point_array = np.array([radius * np.cos(theta_array), radius * np.sin(theta_array)]).transpose() + radius
    points = ' '.join([f'{x}, {y}' for (x, y) in point_array])
    layer.append(soup.new_tag('polygon', points=points, **kwargs))

def recursive_rmdir(directory):
    directory = Path(directory)
    for item in directory.iterdir():
        if item.is_dir():
            rmdir(item)
        else:
            item.unlink()
    directory.rmdir()

def main(output_dir='./gerbolyze_polygon_size_test', svg_template_name='gerbolyze_polygon_size_test.svg', point_count=512):
    output_dir_path = Path(output_dir).resolve()
    print(output_dir_path.as_posix())
    output_dir_path.mkdir(parents=True, exist_ok=True)
    svg_template_name_path = output_dir_path.joinpath(svg_template_name)
    if svg_template_name_path.exists():
        svg_template_name_path.unlink()

    maximum_radius = 50

    # Call Gerbolyze to generate an empty template SVG.
    command = ['gerbolyze', 'empty-template', f'--size {2*(maximum_radius)}x{2*(maximum_radius)}mm', svg_template_name_path.as_posix()]
    subprocess.run(' '.join(command), shell=True)

    # Open file we just generated.
    with svg_template_name_path.open() as svg_template:
        svg_template_soup = BeautifulSoup(svg_template, 'xml')

    # Construct SVG.
    for layer in svg_template_soup.find_all('g'):
        if layer['id'] == 'g-top-copper':
            generate_polygon_and_append(svg_template_soup, layer, maximum_radius)
        if layer['id'] == 'g-bottom-copper':
            generate_polygon_and_append(svg_template_soup, layer, maximum_radius)

    with svg_template_name_path.open('w') as svg_template:
        svg_template.write(svg_template_soup.prettify())

    # Call Gerbolyze program to convert SVG to Gerber.
    gerber_dir_path = output_dir_path.joinpath('gerber')
    if gerber_dir_path.exists():
        recursive_rmdir(gerber_dir_path)
    command = ['gerbolyze', 'convert', svg_template_name_path.as_posix(), gerber_dir_path.as_posix()]
    subprocess.run(' '.join(command), shell=True)

if __name__=='__main__':
    main()

This python script will create a directory called gerbolyze_polygon_size_test, populate it with a template SVG generated by Gerbolyze with two large polygons (with 5e5 points) added to the top and bottom copper layers, then call Gerbolyze to convert this SVG to Gerber files in a new subdirectory called gerber. The result of this on my machine appears as follows:

$ ls -hall ./gerbolyze_polygon_size_test/gerber_validation 
total 13M
drwxr-xr-x 2 luke users   6 Mar 19 21:52 .
drwxr-xr-x 4 luke users   5 Mar 19 21:52 ..
-rw-r--r-- 1 luke users 13M Mar 19 21:52 gerbolyze_polygon_size_test-F.Cu.gbr
-rw-r--r-- 1 luke users  86 Mar 19 21:52 gerbolyze_polygon_size_test-F.Mask.gbr
-rw-r--r-- 1 luke users  86 Mar 19 21:52 gerbolyze_polygon_size_test-F.Paste.gbr
-rw-r--r-- 1 luke users  86 Mar 19 21:52 gerbolyze_polygon_size_test-F.SilkS.gbr

Notably, this is missing the bottom copper layer, which we know in this case has elements in the SVG.

Expected Behavior

First, Gerbolyze should not fail silently in these cases - there should be some sort of warning or failure reported, which is not the case when I run this (from my shell, the python script is not hiding any stdout). Second, this probably shouldn't fail at all - the layers that are written appear to be correct when zipped and viewed with the Gerber viewer tool in KiCad. This level of resolution is useful for me, as I am using geometry from the boundary edges of a face of a high-resolution, manifold mesh to construct polygons in the template SVGs.

@Wulfsta Wulfsta changed the title Gerbolyze fails silently when an SVG contains a polygon with a large number of points. Gerbolyze convert fails silently when an SVG contains a polygon with a large number of points. Mar 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant