Improve layer stack handling

merge-requests/2/head
jaseg 2023-03-31 16:31:44 +02:00
rodzic 800827b2c5
commit 0295440770
4 zmienionych plików z 45 dodań i 11 usunięć

Wyświetl plik

@ -444,5 +444,8 @@ class LazyCamFile:
def save(self, filename, *args, **kwargs):
""" Copy this Gerber file to the new path. """
shutil.copy(self.original_path, filename)
if 'instance' in self.__dict__: # instance has been loaded, and might have been modified
self.instance.save(filename, *args, **kwargs)
else:
shutil.copy(self.original_path, filename)

Wyświetl plik

@ -245,6 +245,16 @@ class ExcellonFile(CamFile):
""" Test if there are multiple plating values used in this file. """
return len({obj.plated for obj in self.objects}) > 1
@property
def is_plated_tristate(self):
if self.is_plated:
return True
if self.is_nonplated:
return False
return None
def append(self, obj_or_comment):
""" Add a :py:class:`.GraphicObject` or a comment (str) to this file. """
if isinstance(obj_or_comment, str):
@ -252,11 +262,11 @@ class ExcellonFile(CamFile):
else:
self.objects.append(obj_or_comment)
def to_excellon(self):
def to_excellon(self, plated=None, errors='raise'):
""" Counterpart to :py:meth:`~.rs274x.GerberFile.to_excellon`. Does nothing and returns :py:obj:`self`. """
return self
def to_gerber(self):
def to_gerber(self, errros='raise'):
""" Convert this excellon file into a :py:class:`~.rs274x.GerberFile`. """
apertures = {}
out = GerberFile()
@ -274,14 +284,18 @@ class ExcellonFile(CamFile):
def generator(self):
return self.generator_hints[0] if self.generator_hints else None
def merge(self, other):
def merge(self, other, mode='ignored', keep_settings=False):
if other is None:
return
if not isinstance(other, ExcellonFile):
other = other.to_excellon(plated=self.is_plated_tristate)
self.objects += other.objects
self.comments += other.comments
self.generator_hints = None
self.import_settings = None
if not keep_settings:
self.import_settings = None
@classmethod
def open(kls, filename, plated=None, settings=None, external_tools=None):

Wyświetl plik

@ -113,16 +113,22 @@ class NamingScheme:
def _match_files(filenames):
matches = {}
for generator, rules in MATCH_RULES.items():
already_matched = set()
gen = {}
matches[generator] = gen
for layer, regex in rules.items():
for fn in filenames:
if fn in already_matched:
continue
if (m := re.fullmatch(regex, fn.name, re.IGNORECASE)):
if layer == 'inner copper':
target = 'inner_' + ''.join(e or '' for e in m.groups()) + ' copper'
else:
target = layer
gen[target] = gen.get(target, []) + [fn]
already_matched.add(fn)
return matches
@ -615,8 +621,10 @@ class LayerStack:
if self.drill_pth is not None:
yield get_name('plated drill', self.drill_pth), self.drill_pth
if self.drill_npth is not None:
yield get_name('nonplated drill', self.drill_npth), self.drill_npth
for layer in self._drill_layers:
yield get_name('unknown drill', layer), layer
@ -872,8 +880,7 @@ class LayerStack:
npth_out.append(obj)
self.drill_pth, self.drill_npth = pth_out, npth_out
self._drill_layers = unknown_out if unknown_out else None
self._drill_layers = []
self._drill_layers = [unknown_out] if unknown_out else []
@property
def drill_layers(self):

Wyświetl plik

@ -73,7 +73,7 @@ class GerberFile(CamFile):
self.apertures = [] # FIXME get rid of this? apertures are already in the objects.
self.file_attrs = file_attrs or {}
def to_excellon(self, plated=None):
def to_excellon(self, plated=None, errors='raise'):
""" Convert this excellon file into a :py:class:`~.excellon.ExcellonFile`. This will convert interpolated lines
into slots, and circular aperture flashes into holes. Other features such as ``G36`` polygons or flashes with
non-circular apertures will result in a :py:obj:`ValueError`. You can, of course, programmatically remove such
@ -83,7 +83,15 @@ class GerberFile(CamFile):
for obj in self.objects:
if not (isinstance(obj, go.Line) or isinstance(obj, go.Arc) or isinstance(obj, go.Flash)) or \
not isinstance(obj.aperture, apertures.CircleAperture):
raise ValueError(f'Cannot convert {obj} to excellon!')
if errors == 'raise':
raise ValueError(f'Cannot convert {obj} to excellon.')
elif errors == 'warn':
warnings.warn(f'Gerber to Excellon conversion: Cannot convert {obj} to excellon.')
continue
elif errors == 'ignore':
continue
else:
raise ValueError('Invalid "errors" parameter. Allowed values: "raise", "warn" or "ignore".')
if not (new_tool := new_tools.get(id(obj.aperture))):
# TODO plating?
@ -92,9 +100,9 @@ class GerberFile(CamFile):
return ExcellonFile(objects=new_objs, comments=self.comments)
def to_gerber(self):
def to_gerber(self, errors='raise'):
""" Counterpart to :py:meth:`~.excellon.ExcellonFile.to_gerber`. Does nothing and returns :py:obj:`self`. """
return
return self
def merge(self, other, mode='above', keep_settings=False):
""" Merge ``other`` into ``self``, i.e. add all objects that are in ``other`` to ``self``. This resets
@ -110,6 +118,8 @@ class GerberFile(CamFile):
if other is None:
return
other = other.to_gerber()
if not keep_settings:
self.import_settings = None
self.comments += other.comments