summaryrefslogtreecommitdiff
path: root/gerbonara/layers.py
diff options
context:
space:
mode:
authorjaseg <git@jaseg.de>2023-02-19 23:42:17 +0100
committerjaseg <git@jaseg.de>2023-02-19 23:42:17 +0100
commita374483998baff2fab4c43027c83f8bf97e5fdf5 (patch)
tree090289b0aa8ea1fe7e425a9d39281cc24e44eae9 /gerbonara/layers.py
parentf64b03efc752b682b1cbe8cfb114f19e3362ef76 (diff)
downloadgerbonara-a374483998baff2fab4c43027c83f8bf97e5fdf5.tar.gz
gerbonara-a374483998baff2fab4c43027c83f8bf97e5fdf5.tar.bz2
gerbonara-a374483998baff2fab4c43027c83f8bf97e5fdf5.zip
cli: First draft of most of the CLI
Diffstat (limited to 'gerbonara/layers.py')
-rw-r--r--gerbonara/layers.py65
1 files changed, 49 insertions, 16 deletions
diff --git a/gerbonara/layers.py b/gerbonara/layers.py
index 19d0195..820454c 100644
--- a/gerbonara/layers.py
+++ b/gerbonara/layers.py
@@ -144,8 +144,8 @@ def common_prefix(l):
baseline = score(1)
if len(l) - baseline > 5:
continue
- for n in range(2, len(cand)):
- if len(l) - score(n) > 5:
+ for n in range(len(cand) if '.' not in cand else cand.index('.')+1, 2, -1):
+ if len(l) - score(n) < 5:
break
out.append(cand[:n-1])
@@ -237,31 +237,31 @@ def layername_autoguesser(fn):
class LayerStack:
-
- def __init__(self, graphic_layers, drill_layers, netlist=None, board_name=None, original_path=None, was_zipped=False):
+ def __init__(self, graphic_layers, drill_layers, netlist=None, board_name=None, original_path=None, was_zipped=False, generator=None):
self.graphic_layers = graphic_layers
self.drill_layers = drill_layers
self.board_name = board_name
self.netlist = netlist
self.original_path = original_path
self.was_zipped = was_zipped
+ self.generator = generator
@classmethod
- def open(kls, path, board_name=None, lazy=False):
+ def open(kls, path, board_name=None, lazy=False, overrides=None, autoguess=True):
if str(path) == '-':
data_io = io.BytesIO(sys.stdin.buffer.read())
return kls.from_zip_data(data_io, original_path='<stdin>', board_name=board_name, lazy=lazy)
path = Path(path)
if path.is_dir():
- return kls.open_dir(path, board_name=board_name, lazy=lazy)
+ return kls.open_dir(path, board_name=board_name, lazy=lazy, overrides=overrides, autoguess=autoguess)
elif path.suffix.lower() == '.zip' or is_zipfile(path):
- return kls.open_zip(path, board_name=board_name, lazy=lazy)
+ return kls.open_zip(path, board_name=board_name, lazy=lazy, overrides=overrides, autoguess=autoguess)
else:
- return kls.from_files([path], board_name=board_name, lazy=lazy)
+ return kls.from_files([path], board_name=board_name, lazy=lazy, overrides=overrides, autoguess=autoguess)
@classmethod
- def open_zip(kls, file, original_path=None, board_name=None, lazy=False):
+ def open_zip(kls, file, original_path=None, board_name=None, lazy=False, overrides=None, autoguess=True):
tmpdir = tempfile.TemporaryDirectory()
tmp_indir = Path(tmpdir.name) / 'input'
tmp_indir.mkdir()
@@ -276,20 +276,39 @@ class LayerStack:
return inst
@classmethod
- def open_dir(kls, directory, board_name=None, lazy=False):
+ def open_dir(kls, directory, board_name=None, lazy=False, overrides=None, autoguess=True):
directory = Path(directory)
if not directory.is_dir():
raise FileNotFoundError(f'{directory} is not a directory')
files = [ path for path in directory.glob('**/*') if path.is_file() ]
- return kls.from_files(files, board_name=board_name, lazy=lazy, original_path=directory)
+ return kls.from_files(files, board_name=board_name, lazy=lazy, original_path=directory, overrides=overrides,
+ autoguess=autoguess)
inst.original_path = directory
return inst
@classmethod
- def from_files(kls, files, board_name=None, lazy=False, original_path=None, was_zipped=False):
- generator, filemap = best_match(files)
+ def from_files(kls, files, board_name=None, lazy=False, original_path=None, was_zipped=False, overrides=None,
+ autoguess=True):
+ if autoguess:
+ generator, filemap = best_match(files)
+ else:
+ generator, filemap = 'custom', {}
+ all_generator_hints = set()
+
+ if overrides:
+ for fn in files:
+ for expr, layer in overrides.items():
+ if re.fullmatch(expr, fn.name):
+ if layer == 'ignore':
+ for entries in filemap.values():
+ if fn in entries:
+ entries.remove(fn)
+ else:
+ if layer in filemap and fn in filemap[layer]:
+ filemap[layer].remove(fn)
+ filemap[layer] = filemap.get(layer, []) + [fn]
if sum(len(files) for files in filemap.values()) < 6:
warnings.warn('Ambiguous gerber filenames. Trying last-resort autoguesser.')
@@ -404,6 +423,7 @@ class LayerStack:
if not lazy:
hints = set(layer.generator_hints) | { generator }
+ all_generator_hints |= hints
if len(hints) > 1:
warnings.warn('File identification returned ambiguous results. Please raise an issue on the '
'gerbonara tracker and if possible please provide these input files for reference.')
@@ -414,7 +434,7 @@ class LayerStack:
board_name = re.sub(r'\W+$', '', board_name)
return kls(layers, drill_layers, netlist, board_name=board_name,
- original_path=original_path, was_zipped=was_zipped)
+ original_path=original_path, was_zipped=was_zipped, generator=[*all_generator_hints, None][0])
def save_to_zipfile(self, path, naming_scheme={}, overwrite_existing=True, prefix=''):
if path.is_file():
@@ -428,7 +448,8 @@ class LayerStack:
with le_zip.open(prefix + str(path), 'w') as out:
out.write(layer.instance.write_to_bytes())
- def save_to_directory(self, path, naming_scheme={}, overwrite_existing=True):
+ def save_to_directory(self, path, naming_scheme={}, overwrite_existing=True,
+ gerber_settings=None, excellon_settings=None):
outdir = Path(path)
outdir.mkdir(parents=True, exist_ok=overwrite_existing)
@@ -442,7 +463,7 @@ class LayerStack:
def get_name(layer_type, layer):
nonlocal naming_scheme
- if (m := re.match('inner_([0-9]*) copper', layer_type)):
+ if (m := re.match('inner_([0-9]+) copper', layer_type)):
layer_type = 'inner copper'
num = int(m[1])
else:
@@ -569,6 +590,18 @@ class LayerStack:
else:
return self.bounding_box(unit=unit, default=default)
+ def offset(self, x=0, y=0, unit=MM):
+ for layer in itertools.chain(self.graphic_layers.values(), self.drill_layers):
+ layer.offset(x, y, unit=unit)
+
+ def rotate(self, angle, cx=0, cy=0, unit=MM):
+ for layer in itertools.chain(self.graphic_layers.values(), self.drill_layers):
+ layer.rotate(angle, cx, cy, unit=unit)
+
+ def scale(self, factor, unit=MM):
+ for layer in itertools.chain(self.graphic_layers.values(), self.drill_layers):
+ layer.scale(factor)
+
def merge_drill_layers(self):
target = ExcellonFile(comments=['Drill files merged by gerbonara'])