[sub-PCBs] Implemented the rectangle separation
- Notably faster
This commit is contained in:
parent
6b432f3de6
commit
b8dff52fa3
|
|
@ -89,6 +89,9 @@ class GS(object):
|
|||
stackup = None
|
||||
# Preprocessor definitions
|
||||
cli_defines = {}
|
||||
kikit_units_to_kicad = {'mm': pcbnew.IU_PER_MM, 'cm': 10*pcbnew.IU_PER_MM, 'dm': 100*pcbnew.IU_PER_MM,
|
||||
'm': 1000*pcbnew.IU_PER_MM, 'mil': pcbnew.IU_PER_MILS, 'inch': 1000*pcbnew.IU_PER_MILS,
|
||||
'in': 1000*pcbnew.IU_PER_MILS}
|
||||
#
|
||||
# Global defaults
|
||||
#
|
||||
|
|
@ -447,3 +450,7 @@ class GS(object):
|
|||
return dir_name
|
||||
logger.error('Missing resource directory `{}`'.format(name))
|
||||
exit(WRONG_INSTALL)
|
||||
|
||||
@staticmethod
|
||||
def create_eda_rect(tlx, tly, brx, bry):
|
||||
return pcbnew.EDA_RECT(pcbnew.wxPoint(tlx, tly), pcbnew.wxSize(brx-tlx, bry-tly))
|
||||
|
|
|
|||
|
|
@ -535,15 +535,20 @@ class PanelOptions(BaseOptions):
|
|||
_num_regex = re.compile(r'([\d\.]+)(mm|cm|dm|m|mil|inch|in)')
|
||||
_ang_regex = re.compile(r'([\d\.]+)(deg|°|rad)')
|
||||
|
||||
def add_units(self, ops, def_units=None):
|
||||
def add_units(self, ops, def_units=None, convert=False):
|
||||
if def_units is None:
|
||||
def_units = self._parent._parent.units
|
||||
for op in ops:
|
||||
val = getattr(self, op)
|
||||
_op = '_'+op
|
||||
if val is None:
|
||||
if convert:
|
||||
setattr(self, _op, 0)
|
||||
continue
|
||||
if isinstance(val, (int, float)):
|
||||
setattr(self, op, str(val)+def_units)
|
||||
if convert:
|
||||
setattr(self, _op, val*GS.kikit_units_to_kicad[def_units])
|
||||
else:
|
||||
m = PanelOptions._num_regex.match(val)
|
||||
if m is None:
|
||||
|
|
@ -555,6 +560,8 @@ class PanelOptions(BaseOptions):
|
|||
num_d = None
|
||||
if num_d is None:
|
||||
raise KiPlotConfigurationError('Malformed number in `{}` ({})'.format(op, num))
|
||||
if convert:
|
||||
setattr(self, _op, num_d*GS.kikit_units_to_kicad[m.group(2)])
|
||||
|
||||
def add_angle(self, ops, def_units=None):
|
||||
if def_units is None:
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ class SubPCBOptions(PanelOptions):
|
|||
if (not self.reference and self.is_zero(self.tlx) and self.is_zero(self.tly) and self.is_zero(self.brx) and
|
||||
self.is_zero(self.bry)):
|
||||
raise KiPlotConfigurationError('No reference or rectangle specified for {} sub-PCB'.format(self.name))
|
||||
self.add_units(('tlx', 'tly', 'brx', 'bry'), self.units)
|
||||
self.add_units(('tlx', 'tly', 'brx', 'bry'), self.units, convert=True)
|
||||
self.board_rect = GS.create_eda_rect(self._tlx, self._tly, self._brx, self._bry)
|
||||
|
||||
def get_separate_source(self):
|
||||
if self.reference:
|
||||
|
|
@ -86,7 +87,6 @@ class SubPCBOptions(PanelOptions):
|
|||
run_command(cmd)
|
||||
# Load this board
|
||||
GS.load_board(dest, forced=True)
|
||||
self._excl_by_sub_pcb = set()
|
||||
# Now reflect the changes in the list of components
|
||||
if comps_hash:
|
||||
logger.debug('Removing components outside the sub-PCB')
|
||||
|
|
@ -103,22 +103,65 @@ class SubPCBOptions(PanelOptions):
|
|||
self._excl_by_sub_pcb.add(c)
|
||||
logger.debugl(2, '- Removing '+c)
|
||||
|
||||
def _remove_items(self, iter):
|
||||
""" Remove items outside the rectangle.
|
||||
If the item has width (shapes and tracks) we discard it.
|
||||
This produces something closer to KiKit. """
|
||||
for m in iter:
|
||||
with_width = hasattr(m, 'GetWidth')
|
||||
if with_width:
|
||||
width = m.GetWidth()
|
||||
m.SetWidth(0)
|
||||
if not self.board_rect.Contains(m.GetBoundingBox()):
|
||||
GS.board.Remove(m)
|
||||
self._removed.append(m)
|
||||
if with_width:
|
||||
m.SetWidth(width)
|
||||
|
||||
def _remove_modules(self, iter):
|
||||
""" Remove modules outside the rectangle.
|
||||
Footprints are added to the list of references to exclude.
|
||||
We also check their position, not their BBox. """
|
||||
for m in iter:
|
||||
if not self.board_rect.Contains(m.GetPosition()):
|
||||
GS.board.Remove(m)
|
||||
self._removed.append(m)
|
||||
self._excl_by_sub_pcb.add(m.GetReference())
|
||||
|
||||
def remove_outside(self):
|
||||
self._removed = []
|
||||
self._remove_modules(GS.get_modules())
|
||||
self._remove_items(GS.board.GetDrawings())
|
||||
self._remove_items(GS.board.GetTracks())
|
||||
self._remove_items(list(GS.board.Zones()))
|
||||
|
||||
def apply(self, comps_hash):
|
||||
if True:
|
||||
self._excl_by_sub_pcb = set()
|
||||
if self.reference:
|
||||
self.separate_board(comps_hash)
|
||||
else:
|
||||
# Using a rectangle
|
||||
self.remove_outside()
|
||||
|
||||
def unload_board(self, comps_hash):
|
||||
# Undo the sub-PCB: just reload the PCB
|
||||
GS.load_board(forced=True)
|
||||
|
||||
def restore_removed(self):
|
||||
""" Restore the stuff we removed from the board """
|
||||
for o in self._removed:
|
||||
GS.board.Add(o)
|
||||
|
||||
def revert(self, comps_hash):
|
||||
if self.reference:
|
||||
self.unload_board(comps_hash)
|
||||
else:
|
||||
self.restore_removed()
|
||||
# Restore excluded components
|
||||
logger.debug('Restoring components outside the sub-PCB')
|
||||
for c in self._excl_by_sub_pcb:
|
||||
comps_hash[c].included = True
|
||||
|
||||
def revert(self, comps_hash):
|
||||
if True:
|
||||
self.unload_board(comps_hash)
|
||||
|
||||
|
||||
class BaseVariant(RegVariant):
|
||||
def __init__(self):
|
||||
|
|
|
|||
Loading…
Reference in New Issue