forked from yaqwsx/PcbDraw
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpcbnew_common.py
71 lines (60 loc) · 2.42 KB
/
pcbnew_common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import sys
from pcbnewTransition import pcbnew, isV6 # type: ignore
from pcbnewTransition.pcbnew import BOX2I # type: ignore
from itertools import chain
from typing import Optional, List
import wx # type: ignore
import os
def getBBoxWithoutContours(edge: pcbnew.EDA_SHAPE) -> pcbnew.BOX2I:
width = edge.GetWidth()
edge.SetWidth(0)
bBox = edge.GetBoundingBox()
edge.SetWidth(width)
return bBox
def findBoundingBox(edges: List[pcbnew.EDA_SHAPE]) -> pcbnew.BOX2I:
"""
Return a bounding box of all drawings in edges
"""
if len(edges) == 0:
raise RuntimeError("No board edges found")
boundingBox = getBBoxWithoutContours(edges[0])
for edge in edges[1:]:
boundingBox = combineBoundingBoxes(boundingBox, getBBoxWithoutContours(edge))
return boundingBox
def findBoardBoundingBox(board: pcbnew.BOARD) -> BOX2I:
"""
Returns a bounding box (BOX2I) of all Edge.Cuts items either in
specified source area (BOX2I) or in the whole board
"""
edges = collectEdges(board, "Edge.Cuts")
return findBoundingBox(edges)
def collectEdges(board: pcbnew.BOARD, layerName: str) -> List[pcbnew.EDA_SHAPE]:
""" Collect edges on given layer including footprints """
edges = []
for edge in chain(board.GetDrawings(), *[m.GraphicalItems() for m in board.GetFootprints()]):
if edge.GetLayerName() != layerName:
continue
if isV6() and isinstance(edge, pcbnew.PCB_DIMENSION_BASE):
continue
edges.append(edge)
return edges
def combineBoundingBoxes(a: pcbnew.BOX2I, b: pcbnew.BOX2I) -> pcbnew.BOX2I:
""" Retrun BOX2I 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())
return BOX2I(pcbnew.VECTOR2I(x1, y1), pcbnew.VECTOR2I(x2 - x1, y2 - y1))
def fakeKiCADGui() -> Optional[wx.App]:
"""
KiCAD assumes wxApp and locale exists. If we invoke a command, fake the
existence of an app. You should store the application in a top-level
function of the command
"""
if os.name != "nt" and os.environ.get("DISPLAY", "").strip() == "":
return None
sys.stdout = os.fdopen(os.dup(1), "w")
sys.stderr = os.fdopen(os.dup(2), "w")
os.dup2(os.open(os.devnull,os.O_RDWR), 1)
os.dup2(os.open(os.devnull,os.O_RDWR), 2)
return None