Skip to content

Commit

Permalink
Implement panel sizing constraints
Browse files Browse the repository at this point in the history
  • Loading branch information
yaqwsx committed Dec 28, 2022
1 parent 029b516 commit 95e897d
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 12 deletions.
45 changes: 37 additions & 8 deletions kikit/panelize.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
class PanelError(RuntimeError):
pass

class TooLargeError(PanelError):
pass

def identity(x):
return x

Expand Down Expand Up @@ -1127,7 +1130,8 @@ def makeGrid(self, boardfile: str, sourceArea: wxRect, rows: int, cols: int,
return self.substrates[substrateCount:]

def makeFrame(self, width: KiLength, hspace: KiLength, vspace: KiLength,
minWidth: KiLength=0, minHeight: KiLength=0) \
minWidth: KiLength = 0, minHeight: KiLength = 0,
maxWidth: Optional[KiLength] = None, maxHeight: Optional[KiLength] = None) \
-> Tuple[Iterable[LineString], Iterable[LineString]]:
"""
Build a frame around the boards. Specify width and spacing between the
Expand All @@ -1148,9 +1152,21 @@ def makeFrame(self, width: KiLength, hspace: KiLength, vspace: KiLength,
minHeight - if the panel doesn't meet this height, it is extended
maxWidth - if the panel doesn't meet this width, TooLargeError is raised
maxHeight - if the panel doesn't meet this height, TooLargeHeight is raised
"""
frameInnerRect = expandRect(shpBoxToRect(self.boardsBBox()), hspace, vspace)
frameOuterRect = expandRect(frameInnerRect, width)

sizeErrors = []
if maxWidth is not None and frameOuterRect.GetWidth() > maxWidth:
sizeErrors.append(f"Panel width {frameOuterRect.GetWidth() / units.mm} mm exceeds the limit {maxWidth / units.mm} mm")
if maxHeight is not None and frameOuterRect.GetHeight() > maxHeight:
sizeErrors.append(f"Panel height {frameOuterRect.GetHeight() / units.mm} mm exceeds the limit {maxHeight / units.mm} mm")
if len(sizeErrors) > 0:
raise TooLargeError(f"Panel doesn't meet size constraints:\n" + "\n".join(f"- {x}" for x in sizeErrors))

if frameOuterRect.GetWidth() < minWidth:
diff = minWidth - frameOuterRect.GetWidth()
frameOuterRect.SetX(frameOuterRect.GetX() - diff // 2)
Expand All @@ -1173,7 +1189,8 @@ def makeFrame(self, width: KiLength, hspace: KiLength, vspace: KiLength,

def makeTightFrame(self, width: KiLength, slotwidth: KiLength,
hspace: KiLength, vspace: KiLength, minWidth: KiLength=0,
minHeight: KiLength=0) -> None:
minHeight: KiLength=0, maxWidth: Optional[KiLength] = None,
maxHeight: Optional[KiLength] = None) -> None:
"""
Build a full frame with board perimeter milled out.
Add your boards to the panel first using appendBoard or makeGrid.
Expand All @@ -1192,35 +1209,47 @@ def makeTightFrame(self, width: KiLength, slotwidth: KiLength,
minHeight - if the panel doesn't meet this height, it is extended
maxWidth - if the panel doesn't meet this width, TooLargeError is raised
maxHeight - if the panel doesn't meet this height, TooLargeHeight is raised
"""
self.makeFrame(width, hspace, vspace, minWidth, minHeight)
self.makeFrame(width, hspace, vspace, minWidth, minHeight, maxWidth, maxHeight)
boardSlot = GeometryCollection()
for s in self.substrates:
boardSlot = boardSlot.union(s.exterior())
boardSlot = boardSlot.buffer(slotwidth)
frameBody = box(*self.boardSubstrate.bounds()).difference(boardSlot)
self.appendSubstrate(frameBody)

def makeRailsTb(self, thickness: KiLength, minHeight: KiLength=0):
def makeRailsTb(self, thickness: KiLength, minHeight: KiLength = 0,
maxHeight: Optional[KiLength] = None) -> None:
"""
Adds a rail to top and bottom. You can specify minimal height the panel
has to feature.
has to feature. You can also specify maximal height of the panel. If the
height would be exceeded, TooLargeError is raised.
"""
minx, miny, maxx, maxy = self.panelBBox()
if maxy - miny + 2 * thickness < minHeight:
height = maxy - miny + 2 * thickness
if maxHeight is not None and height > maxHeight:
raise TooLargeError(f"Panel height {height / units.mm} mm exceeds the limit {maxHeight / units.mm} mm")
if height < minHeight:
thickness = (minHeight - maxy + miny) // 2
topRail = box(minx, maxy, maxx, maxy + thickness)
bottomRail = box(minx, miny, maxx, miny - thickness)
self.appendSubstrate(topRail)
self.appendSubstrate(bottomRail)

def makeRailsLr(self, thickness: KiLength, minWidth: KiLength=0):
def makeRailsLr(self, thickness: KiLength, minWidth: KiLength = 0,
maxWidth: Optional[KiLength] = None) -> None:
"""
Adds a rail to left and right. You can specify minimal width the panel
has to feature.
"""
minx, miny, maxx, maxy = self.panelBBox()
if maxx - minx + 2 * thickness < minWidth:
width = maxx - minx + 2 * thickness
if maxWidth is not None and width > maxWidth:
raise TooLargeError(f"Panel width {width / units.mm} mm exceeds the limit {maxWidth / units.mm} mm")
if width < minWidth:
thickness = (minWidth - maxx + minx) // 2
leftRail = box(minx - thickness, miny, minx, maxy)
rightRail = box(maxx, miny, maxx + thickness, maxy)
Expand Down
12 changes: 8 additions & 4 deletions kikit/panelize_ui_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,17 +443,20 @@ def buildFraming(preset, panel):
if type == "none":
return []
if type == "railstb":
panel.makeRailsTb(framingPreset["width"], framingPreset["mintotalheight"])
panel.makeRailsTb(framingPreset["width"],
framingPreset["mintotalheight"], framingPreset["maxtotalheight"])
addFilletAndChamfer(framingPreset, panel)
return []
if type == "railslr":
panel.makeRailsLr(framingPreset["width"], framingPreset["mintotalwidth"])
panel.makeRailsLr(framingPreset["width"],
framingPreset["mintotalwidth"], framingPreset["maxtotalwidth"])
addFilletAndChamfer(framingPreset, panel)
return []
if type == "frame":
cuts = panel.makeFrame(framingPreset["width"],
framingPreset["hspace"], framingPreset["vspace"],
framingPreset["mintotalwidth"], framingPreset["mintotalheight"])
framingPreset["mintotalwidth"], framingPreset["mintotalheight"],
framingPreset["maxtotalwidth"], framingPreset["maxtotalheight"])
addFilletAndChamfer(framingPreset, panel)
if framingPreset["cuts"] == "both":
return chain(*cuts)
Expand All @@ -465,7 +468,8 @@ def buildFraming(preset, panel):
if type == "tightframe":
panel.makeTightFrame(framingPreset["width"], framingPreset["slotwidth"],
framingPreset["hspace"], framingPreset["vspace"],
framingPreset["mintotalwidth"], framingPreset["mintotalheight"])
framingPreset["mintotalwidth"], framingPreset["mintotalheight"],
framingPreset["maxtotalwidth"], framingPreset["maxtotalheight"])
panel.boardSubstrate.removeIslands()
addFilletAndChamfer(framingPreset, panel)
return []
Expand Down
8 changes: 8 additions & 0 deletions kikit/panelize_ui_sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,14 @@ def ppCuts(section):
typeIn(["frame", "raillr", "tightframe"]),
"Minimal width of the panel"
),
"maxtotalheight": SLength(
typeIn(["frame", "railstb", "tightframe"]),
"Maximal height of the panel"
),
"maxtotalwidth": SLength(
typeIn(["frame", "raillr", "tightframe"]),
"Maximal width of the panel"
),
"slotwidth": SLength(
typeIn(["tightframe"]),
"Width of the milled slot"),
Expand Down
2 changes: 2 additions & 0 deletions kikit/resources/panelizePresets/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
"vspace": "2mm",
"mintotalheight": "0mm",
"mintotalwidth": "0mm",
"maxtotalheight": "10m",
"maxtotalwidth": "10m",
"chamfer": "0mm",
"fillet": "0mm",
"code": "none",
Expand Down

0 comments on commit 95e897d

Please sign in to comment.