def translateRect(rect, translation): """ Given a wxRect return a new rect translated by transaltion (tuple-like object) """ return wxRect(rect.GetX() + translation[0], rect.GetY() + translation[1], rect.GetWidth(), rect.GetHeight())
def _placeBoardsInGrid(self, boardfile, rows, cols, destination, sourceArea, tolerance, verSpace, horSpace, rotation, netRenamer, refRenamer, placementClass): """ Create a grid of boards, return source board size aligned at the top left corner """ boardSize = wxRect(0, 0, 0, 0) topLeftSize = None placement = placementClass(destination, boardSize, horSpace, verSpace) for i, j in product(range(rows), range(cols)): placement.boardSize = boardSize dest = placement.position(i, j) boardRotation = rotation + placement.rotation(i, j) boardSize = self.appendBoard(boardfile, dest, sourceArea=sourceArea, tolerance=tolerance, origin=Origin.Center, rotationAngle=boardRotation, netRenamer=netRenamer, refRenamer=refRenamer) if not topLeftSize: topLeftSize = boardSize return topLeftSize
def makeGrid(self, boardfile, rows, cols, destination, sourceArea=None, tolerance=0, verSpace=0, horSpace=0, verTabCount=1, horTabCount=1, verTabWidth=0, horTabWidth=0, outerVerTabThickness=0, outerHorTabThickness=0, rotation=0, forceOuterCutsH=False, forceOuterCutsV=False, netRenamePattern="Board_{n}-{orig}", refRenamePattern="Board_{n}-{orig}"): """ Creates a grid of boards (row x col) as a panel at given destination separated by V-CUTS. The source can be either extracted automatically or from given sourceArea. There can be a spacing between the individual board (verSpacing, horSpacing) and the tab width can be adjusted (verTabWidth, horTabWidth). Also, the user can control whether to append the outer tabs (e.g. to connect it to a frame) by setting outerVerTabsWidth and outerHorTabsWidth. Returns a tuple - wxRect with the panel bounding box (excluding outerTabs) and a list of cuts (list of lines) to make. You can use the list to either create a V-CUTS via makeVCuts or mouse bites via makeMouseBites. """ netRenamer = lambda x, y: netRenamePattern.format(n=x, orig=y) refRenamer = lambda x, y: refRenamePattern.format(n=x, orig=y) boardSize = self._placeBoardsInGrid(boardfile, rows, cols, destination, sourceArea, tolerance, verSpace, horSpace, rotation, netRenamer, refRenamer) gridDest = wxPoint(boardSize.GetX(), boardSize.GetY()) tabs, cuts = [], [] if verTabCount != 0: if verTabWidth == 0: t, c = self._makeFullVerticalTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, outerVerTabThickness,outerHorTabThickness, forceOuterCutsV) else: t, c = self._makeVerGridTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, verTabCount, horTabCount, outerVerTabThickness, outerHorTabThickness) tabs += t cuts += c if horTabCount != 0: if horTabWidth == 0: t, c = self._makeFullHorizontalTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, outerVerTabThickness, outerHorTabThickness, forceOuterCutsH) else: t, c = self._makeHorGridTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, verTabCount, horTabCount, outerVerTabThickness, outerHorTabThickness) tabs += t cuts += c tabs = list([t.buffer(fromMm(0.001), join_style=2) for t in tabs]) self.appendSubstrate(tabs) return (wxRect(gridDest[0], gridDest[1], cols * boardSize.GetWidth() + (cols - 1) * horSpace, rows * boardSize.GetHeight() + (rows - 1) * verSpace), cuts)
def combineBoundingBoxes(a, b): """ Retrun wxRect as a combination of source bounding boxes """ x = min(a.GetX(), b.GetX()) y = min(a.GetY(), b.GetY()) topLeft = wxPoint(x, y) x = max(a.GetX() + a.GetWidth(), b.GetX() + b.GetWidth()) y = max(a.GetY() + a.GetHeight(), b.GetY() + b.GetHeight()) bottomRight = wxPoint(x, y) return wxRect(topLeft, bottomRight)
def expandRect(rect, offsetX, offsetY=None): """ Given a wxRect returns a new rectangle, which is larger in all directions by offset. If only offsetX is passed, it used for both X and Y offset """ if offsetY is None: offsetY = offsetX return wxRect(rect.GetX() - offsetX, rect.GetY() - offsetY, rect.GetWidth() + 2 * offsetX, rect.GetHeight() + 2 * offsetY)
def _makeSingleInnerTabs(self, destination, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius): """ Create inner tabs in board grid by placing exactly one in the middle """ lastRow = lambda x: x == rows - 1 lastCol = lambda x: x == cols - 1 cuts = [] for i, j in product(range(rows), range(cols)): dest = self._boardGridPos(destination, i, j, boardSize, horSpace, verSpace) if not lastRow(i): # Add bottom tab xOffset, width = self._singleTabSize(boardSize.GetWidth(), verTabWidth, horSpace, lastCol(j)) tab = wxRect(dest[0] + xOffset, dest[1] + boardSize.GetHeight(), width, verSpace) cuts.append( ((tab.GetX(), tab.GetY()), (tab.GetX() + tab.GetWidth(), tab.GetY()))) if tab.GetHeight() != 0: cuts.append(((tab.GetX(), tab.GetY() + tab.GetHeight()), (tab.GetX() + tab.GetWidth(), tab.GetY() + tab.GetHeight()))) tab = expandRect(tab, FromMM(0.001)) self.appendSubstrate(tab, radius) if not lastCol(j): # Add right tab yOffset, height = self._singleTabSize(boardSize.GetHeight(), horTabWidth, verSpace, lastRow(i)) tab = wxRect(dest[0] + boardSize.GetWidth(), dest[1] + yOffset, horSpace, height) cuts.append(((tab.GetX(), tab.GetY()), (tab.GetX(), tab.GetY() + tab.GetHeight()))) if tab.GetHeight() != 0: cuts.append(((tab.GetX() + tab.GetWidth(), tab.GetY()), (tab.GetX() + tab.GetWidth(), tab.GetY() + tab.GetHeight()))) tab = expandRect(tab, FromMM(0.001)) self.appendSubstrate(tab, radius) return cuts
def combineBoundingBoxes(a, b): """ Retrun wxRect as a combination of source bounding boxes """ x1 = min(a.GetX(), b.GetX()) y1 = min(a.GetY(), b.GetY()) x2 = max(a.GetX() + a.GetWidth(), b.GetX() + b.GetWidth()) y2 = max(a.GetY() + a.GetHeight(), b.GetY() + b.GetHeight()) # Beware that we cannot use the following code! It will add 1 to width and # height. See https://github.com/wxWidgets/wxWidgets/blob/e43895e5317a1e82e295788264553d9839190337/src/common/gdicmn.cpp#L94-L114 # return wxRect(topLeft, bottomRight) return wxRect(x1, y1, x2 - x1, y2 - y1)
def makeGrid(self, boardfile, rows, cols, destination, sourceArea=None, tolerance=0, radius=0, verSpace=0, horSpace=0, verTabWidth=0, horTabWidth=0, outerVerTabThickness=0, outerHorTabThickness=0): """ Creates a grid of boards (row x col) as a panel at given destination separated by V-CUTS. The source can be either extract automatically of from given sourceArea. There can be a spacing between the individual board (verSpacing, horSpacing) and the tab width can be adjusted (verTabWidth, horTabWidth). Also the user can control whether append the outer tabs (e.g. to connect it to a frame) by setting outerVerTabsWidth and outerHorTabsWidth. Returns a tuple - wxRect with the panel bounding box (excluding outerTabs) and a list of cuts (list of lines) to make. You can use the list to either create a V-CUTS via makeVCuts or mouse bites via makeMouseBites. """ boardSize = self._placeBoardsInGrid(boardfile, rows, cols, destination, sourceArea, tolerance, verSpace, horSpace) gridDest = wxPoint(boardSize.GetX(), boardSize.GetY()) cuts = self._makeSingleInnerTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius) if outerVerTabThickness > 0: cuts += self._makeSingleOuterVerTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius, outerVerTabThickness, outerHorTabThickness) if outerHorTabThickness > 0: cuts += self._makeSingleOuterHorTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius, outerVerTabThickness, outerHorTabThickness) return (wxRect(gridDest[0], gridDest[1], cols * boardSize.GetWidth() + (cols - 1) * horSpace, rows * boardSize.GetHeight() + (rows - 1) * verSpace), cuts)
def makeTightGrid(self, boardfile, rows, cols, destination, verSpace, horSpace, slotWidth, width, height, sourceArea=None, tolerance=0, verTabWidth=0, horTabWidth=0, verTabCount=1, horTabCount=1, rotation=0, netRenamePattern="Board_{n}-{orig}", refRenamePattern="Board_{n}-{orig}"): """ Creates a grid of boards just like `makeGrid`, however, it creates a milled slot around perimeter of each board and 4 tabs. """ netRenamer = lambda x, y: netRenamePattern.format(n=x, orig=y) refRenamer = lambda x, y: refRenamePattern.format(n=x, orig=y) boardSize = self._placeBoardsInGrid(boardfile, rows, cols, destination, sourceArea, tolerance, verSpace, horSpace, rotation, netRenamer, refRenamer) gridDest = wxPoint(boardSize.GetX(), boardSize.GetY()) panelSize = wxRect(destination[0], destination[1], cols * boardSize.GetWidth() + (cols - 1) * horSpace, rows * boardSize.GetHeight() + (rows - 1) * verSpace) tabs, cuts = [], [] if verTabCount != 0: t, c = self._makeVerGridTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, verTabCount, horTabCount, slotWidth, slotWidth) tabs += t cuts += c if horTabCount != 0: t, c = self._makeHorGridTabs(gridDest, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, verTabCount, horTabCount, slotWidth, slotWidth) tabs += t cuts += c xDiff = (width - panelSize.GetWidth()) // 2 if xDiff < 0: raise RuntimeError("The frame is to small") yDiff = (height - panelSize.GetHeight()) // 2 if yDiff < 0: raise RuntimeError("The frame is to small") outerRect = expandRect(panelSize, xDiff, yDiff) outerRing = rectToRing(outerRect) frame = Polygon(outerRing) frame = frame.difference(self.boardSubstrate.exterior().buffer(slotWidth)) self.appendSubstrate(frame) tabs = list([t.buffer(fromMm(0.001), join_style=2) for t in tabs]) self.appendSubstrate(tabs) if verTabCount != 0 or horTabCount != 0: self.boardSubstrate.removeIslands() return (outerRect, cuts)
def makeTightGrid(self, boardfile, rows, cols, destination, verSpace, horSpace, slotWidth, width, height, sourceArea=None, tolerance=0, radius=0, verTabWidth=0, horTabWidth=0): """ Creates a grid of boards just like `makeGrid`, however, it creates a milled slot around perimeter of each board and 4 tabs. """ boardSize = self._placeBoardsInGrid(boardfile, rows, cols, destination, sourceArea, tolerance, verSpace, horSpace) panelSize = wxRect( destination[0], destination[1], cols * boardSize.GetWidth() + (cols - 1) * horSpace, rows * boardSize.GetHeight() + (rows - 1) * verSpace) xDiff = (width - panelSize.GetWidth()) // 2 if xDiff < 0: raise RuntimeError("The frame is to small") yDiff = (height - panelSize.GetHeight()) // 2 if yDiff < 0: raise RuntimeError("The frame is to small") outerRect = expandRect(panelSize, xDiff, yDiff) outerRing = rectToRing(outerRect) frame = Polygon(outerRing) frame = frame.difference( self.boardSubstrate.exterior().buffer(slotWidth)) self.appendSubstrate(frame) cuts = self._makeSingleInnerTabs(destination, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius) cuts += self._makeSingleOuterVerTabs(destination, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius, slotWidth, slotWidth) cuts += self._makeSingleOuterHorTabs(destination, rows, cols, boardSize, verSpace, horSpace, verTabWidth, horTabWidth, radius, slotWidth, slotWidth) return (outerRect, cuts)
def _placeBoardsInGrid(self, boardfile, rows, cols, destination, sourceArea, tolerance, verSpace, horSpace, rotation): """ Create a grid of boards, return source board size aligned at the top left corner """ boardSize = wxRect(0, 0, 0, 0) topLeftSize = None for i, j in product(range(rows), range(cols)): dest = self._boardGridPos(destination, i, j, boardSize, horSpace, verSpace) boardSize = self.appendBoard(boardfile, dest, sourceArea=sourceArea, tolerance=tolerance, origin=Origin.TopLeft, rotationAngle=rotation) if not topLeftSize: topLeftSize = boardSize return topLeftSize
def appendVerticalTab(destination, i, outerVerTabThickness): dest = self._boardGridPos(destination, 0, i, boardSize, horSpace, verSpace) spaceSize = outerHorTabThickness if lastCol(i) else horSpace xOffset, width = self._singleTabSize(boardSize.GetWidth(), verTabWidth, spaceSize, False) tab = wxRect(dest[0] + xOffset, dest[1] - outerVerTabThickness, width, outerVerTabThickness) if i == 0 and verTabWidth == 0: tab.SetX(tab.GetX() - outerHorTabThickness) tab.SetWidth(tab.GetWidth() + outerHorTabThickness) cuts.append( ((tab.GetX(), tab.GetY() + tab.GetHeight()), (tab.GetX() + tab.GetWidth(), tab.GetY() + tab.GetHeight()))) tab = normalizeRect(tab) tab = expandRect(tab, FromMM(0.001)) self.appendSubstrate(tab, radius)
def appendHorizontalTab(destination, i, outerHorTabThickness): dest = self._boardGridPos(destination, i, 0, boardSize, horSpace, verSpace) spaceSize = outerVerTabThickness if lastRow(i) else verSpace yOffset, height = self._singleTabSize(boardSize.GetHeight(), horTabWidth, spaceSize, False) tab = wxRect(dest[0] - outerHorTabThickness, dest[1] + yOffset, outerHorTabThickness, height) if i == 0 and horTabWidth == 0: tab.SetY(tab.GetY() - outerVerTabThickness) tab.SetHeight(tab.GetHeight() + outerVerTabThickness) cuts.append( ((tab.GetX() + tab.GetWidth(), tab.GetY()), (tab.GetX() + tab.GetWidth(), tab.GetY() + tab.GetHeight()))) tab = normalizeRect(tab) tab = expandRect(tab, FromMM(0.001)) self.appendSubstrate(tab, radius)
def mirrorRectY(rect, axis): return wxRect(rect.GetX(), 2 * axis - rect.GetY() - rect.GetHeight(), rect.GetWidth(), rect.GetHeight())
def flipRect(rect): return wxRect(rect.GetY(), rect.GetX(), rect.GetHeight(), rect.GetWidth())
def shpBoxToRect(box): box = list([int(x) for x in box]) return wxRect(box[0], box[1], box[2] - box[0], box[3] - box[1])
def rectByCenter(center, width, height): """ Given a center point and size, return wxRect """ return wxRect(center[0] - width // 2, center[1] - height // 2, width, height)
def boundingBox(self): minx, miny, maxx, maxy = self.substrates.bounds return pcbnew.wxRect(int(minx), int(miny), int(maxx - minx), int(maxy - miny))