style: apply black formatting to changed files

This commit is contained in:
Roman PASSLER
2026-03-01 19:15:32 +01:00
parent 61356d42cb
commit 2dd9de6a52
4 changed files with 356 additions and 192 deletions

View File

@@ -7,7 +7,8 @@ import logging
import math
from typing import Dict, Any, Optional
logger = logging.getLogger('kicad_interface')
logger = logging.getLogger("kicad_interface")
class BoardOutlineCommands:
"""Handles board outline operations"""
@@ -23,7 +24,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "No board is loaded",
"errorDetails": "Load or create a board first"
"errorDetails": "Load or create a board first",
}
shape = params.get("shape", "rectangle")
@@ -40,46 +41,54 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Invalid shape",
"errorDetails": f"Shape '{shape}' not supported"
"errorDetails": f"Shape '{shape}' not supported",
}
# Convert to internal units (nanometers)
scale = 1000000 if unit == "mm" else 25400000 # mm or inch to nm
# Create drawing for edge cuts
edge_layer = self.board.GetLayerID("Edge.Cuts")
if shape == "rectangle":
if width is None or height is None:
return {
"success": False,
"message": "Missing dimensions",
"errorDetails": "Both width and height are required for rectangle"
"errorDetails": "Both width and height are required for rectangle",
}
width_nm = int(width * scale)
height_nm = int(height * scale)
center_x_nm = int(center_x * scale)
center_y_nm = int(center_y * scale)
# Create rectangle
top_left = pcbnew.VECTOR2I(center_x_nm - width_nm // 2, center_y_nm - height_nm // 2)
top_right = pcbnew.VECTOR2I(center_x_nm + width_nm // 2, center_y_nm - height_nm // 2)
bottom_right = pcbnew.VECTOR2I(center_x_nm + width_nm // 2, center_y_nm + height_nm // 2)
bottom_left = pcbnew.VECTOR2I(center_x_nm - width_nm // 2, center_y_nm + height_nm // 2)
top_left = pcbnew.VECTOR2I(
center_x_nm - width_nm // 2, center_y_nm - height_nm // 2
)
top_right = pcbnew.VECTOR2I(
center_x_nm + width_nm // 2, center_y_nm - height_nm // 2
)
bottom_right = pcbnew.VECTOR2I(
center_x_nm + width_nm // 2, center_y_nm + height_nm // 2
)
bottom_left = pcbnew.VECTOR2I(
center_x_nm - width_nm // 2, center_y_nm + height_nm // 2
)
# Add lines for rectangle
self._add_edge_line(top_left, top_right, edge_layer)
self._add_edge_line(top_right, bottom_right, edge_layer)
self._add_edge_line(bottom_right, bottom_left, edge_layer)
self._add_edge_line(bottom_left, top_left, edge_layer)
elif shape == "rounded_rectangle":
if width is None or height is None:
return {
"success": False,
"message": "Missing dimensions",
"errorDetails": "Both width and height are required for rounded rectangle"
"errorDetails": "Both width and height are required for rounded rectangle",
}
width_nm = int(width * scale)
@@ -87,26 +96,29 @@ class BoardOutlineCommands:
center_x_nm = int(center_x * scale)
center_y_nm = int(center_y * scale)
corner_radius_nm = int(corner_radius * scale)
# Create rounded rectangle
self._add_rounded_rect(
center_x_nm, center_y_nm,
width_nm, height_nm,
corner_radius_nm, edge_layer
center_x_nm,
center_y_nm,
width_nm,
height_nm,
corner_radius_nm,
edge_layer,
)
elif shape == "circle":
if radius is None:
return {
"success": False,
"message": "Missing radius",
"errorDetails": "Radius is required for circle"
"errorDetails": "Radius is required for circle",
}
center_x_nm = int(center_x * scale)
center_y_nm = int(center_y * scale)
radius_nm = int(radius * scale)
# Create circle
circle = pcbnew.PCB_SHAPE(self.board)
circle.SetShape(pcbnew.SHAPE_T_CIRCLE)
@@ -121,7 +133,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Missing points",
"errorDetails": "At least 3 points are required for polygon"
"errorDetails": "At least 3 points are required for polygon",
}
# Convert points to nm
@@ -130,13 +142,13 @@ class BoardOutlineCommands:
x_nm = int(point["x"] * scale)
y_nm = int(point["y"] * scale)
polygon_points.append(pcbnew.VECTOR2I(x_nm, y_nm))
# Add lines for polygon
for i in range(len(polygon_points)):
self._add_edge_line(
polygon_points[i],
polygon_points[(i + 1) % len(polygon_points)],
edge_layer
polygon_points[i],
polygon_points[(i + 1) % len(polygon_points)],
edge_layer,
)
return {
@@ -149,8 +161,8 @@ class BoardOutlineCommands:
"center": {"x": center_x, "y": center_y, "unit": unit},
"radius": radius,
"cornerRadius": corner_radius,
"points": points
}
"points": points,
},
}
except Exception as e:
@@ -158,7 +170,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Failed to add board outline",
"errorDetails": str(e)
"errorDetails": str(e),
}
def add_mounting_hole(self, params: Dict[str, Any]) -> Dict[str, Any]:
@@ -168,7 +180,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "No board is loaded",
"errorDetails": "Load or create a board first"
"errorDetails": "Load or create a board first",
}
position = params.get("position")
@@ -180,19 +192,24 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Missing parameters",
"errorDetails": "position and diameter are required"
"errorDetails": "position and diameter are required",
}
# Convert to internal units (nanometers)
scale = 1000000 if position.get("unit", "mm") == "mm" else 25400000 # mm or inch to nm
scale = (
1000000 if position.get("unit", "mm") == "mm" else 25400000
) # mm or inch to nm
x_nm = int(position["x"] * scale)
y_nm = int(position["y"] * scale)
diameter_nm = int(diameter * scale)
pad_diameter_nm = int(pad_diameter * scale) if pad_diameter else diameter_nm + scale # 1mm larger by default
pad_diameter_nm = (
int(pad_diameter * scale) if pad_diameter else diameter_nm + scale
) # 1mm larger by default
# Create footprint for mounting hole with unique reference
existing_mh = [
fp.GetReference() for fp in self.board.GetFootprints()
fp.GetReference()
for fp in self.board.GetFootprints()
if fp.GetReference().startswith("MH")
]
next_num = 1
@@ -202,20 +219,22 @@ class BoardOutlineCommands:
module = pcbnew.FOOTPRINT(self.board)
module.SetReference(f"MH{next_num}")
module.SetValue(f"MountingHole_{diameter}mm")
# Create the pad for the hole
pad = pcbnew.PAD(module)
pad.SetNumber(1)
pad.SetShape(pcbnew.PAD_SHAPE_CIRCLE)
pad.SetAttribute(pcbnew.PAD_ATTRIB_PTH if plated else pcbnew.PAD_ATTRIB_NPTH)
pad.SetAttribute(
pcbnew.PAD_ATTRIB_PTH if plated else pcbnew.PAD_ATTRIB_NPTH
)
pad.SetSize(pcbnew.VECTOR2I(pad_diameter_nm, pad_diameter_nm))
pad.SetDrillSize(pcbnew.VECTOR2I(diameter_nm, diameter_nm))
pad.SetPosition(pcbnew.VECTOR2I(0, 0)) # Position relative to module
module.Add(pad)
# Position the mounting hole
module.SetPosition(pcbnew.VECTOR2I(x_nm, y_nm))
# Add to board
self.board.Add(module)
@@ -226,8 +245,8 @@ class BoardOutlineCommands:
"position": position,
"diameter": diameter,
"padDiameter": pad_diameter or diameter + 1,
"plated": plated
}
"plated": plated,
},
}
except Exception as e:
@@ -235,7 +254,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Failed to add mounting hole",
"errorDetails": str(e)
"errorDetails": str(e),
}
def add_text(self, params: Dict[str, Any]) -> Dict[str, Any]:
@@ -245,7 +264,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "No board is loaded",
"errorDetails": "Load or create a board first"
"errorDetails": "Load or create a board first",
}
text = params.get("text")
@@ -260,11 +279,13 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Missing parameters",
"errorDetails": "text and position are required"
"errorDetails": "text and position are required",
}
# Convert to internal units (nanometers)
scale = 1000000 if position.get("unit", "mm") == "mm" else 25400000 # mm or inch to nm
scale = (
1000000 if position.get("unit", "mm") == "mm" else 25400000
) # mm or inch to nm
x_nm = int(position["x"] * scale)
y_nm = int(position["y"] * scale)
size_nm = int(size * scale)
@@ -276,7 +297,7 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Invalid layer",
"errorDetails": f"Layer '{layer}' does not exist"
"errorDetails": f"Layer '{layer}' does not exist",
}
# Create text
@@ -297,7 +318,7 @@ class BoardOutlineCommands:
pcb_text.SetTextAngle(int(rotation * 10))
pcb_text.SetMirrored(mirror)
# Add to board
self.board.Add(pcb_text)
@@ -311,8 +332,8 @@ class BoardOutlineCommands:
"size": size,
"thickness": thickness,
"rotation": rotation,
"mirror": mirror
}
"mirror": mirror,
},
}
except Exception as e:
@@ -320,10 +341,12 @@ class BoardOutlineCommands:
return {
"success": False,
"message": "Failed to add text",
"errorDetails": str(e)
"errorDetails": str(e),
}
def _add_edge_line(self, start: pcbnew.VECTOR2I, end: pcbnew.VECTOR2I, layer: int) -> None:
def _add_edge_line(
self, start: pcbnew.VECTOR2I, end: pcbnew.VECTOR2I, layer: int
) -> None:
"""Add a line to the edge cuts layer"""
line = pcbnew.PCB_SHAPE(self.board)
line.SetShape(pcbnew.SHAPE_T_SEGMENT)
@@ -333,96 +356,112 @@ class BoardOutlineCommands:
line.SetWidth(0) # Zero width for edge cuts
self.board.Add(line)
def _add_rounded_rect(self, center_x_nm: int, center_y_nm: int,
width_nm: int, height_nm: int,
radius_nm: int, layer: int) -> None:
def _add_rounded_rect(
self,
center_x_nm: int,
center_y_nm: int,
width_nm: int,
height_nm: int,
radius_nm: int,
layer: int,
) -> None:
"""Add a rounded rectangle to the edge cuts layer"""
if radius_nm <= 0:
# If no radius, create regular rectangle
top_left = pcbnew.VECTOR2I(center_x_nm - width_nm // 2, center_y_nm - height_nm // 2)
top_right = pcbnew.VECTOR2I(center_x_nm + width_nm // 2, center_y_nm - height_nm // 2)
bottom_right = pcbnew.VECTOR2I(center_x_nm + width_nm // 2, center_y_nm + height_nm // 2)
bottom_left = pcbnew.VECTOR2I(center_x_nm - width_nm // 2, center_y_nm + height_nm // 2)
top_left = pcbnew.VECTOR2I(
center_x_nm - width_nm // 2, center_y_nm - height_nm // 2
)
top_right = pcbnew.VECTOR2I(
center_x_nm + width_nm // 2, center_y_nm - height_nm // 2
)
bottom_right = pcbnew.VECTOR2I(
center_x_nm + width_nm // 2, center_y_nm + height_nm // 2
)
bottom_left = pcbnew.VECTOR2I(
center_x_nm - width_nm // 2, center_y_nm + height_nm // 2
)
self._add_edge_line(top_left, top_right, layer)
self._add_edge_line(top_right, bottom_right, layer)
self._add_edge_line(bottom_right, bottom_left, layer)
self._add_edge_line(bottom_left, top_left, layer)
return
# Calculate corner centers
half_width = width_nm // 2
half_height = height_nm // 2
# Ensure radius is not larger than half the smallest dimension
max_radius = min(half_width, half_height)
if radius_nm > max_radius:
radius_nm = max_radius
# Calculate corner centers
top_left_center = pcbnew.VECTOR2I(
center_x_nm - half_width + radius_nm,
center_y_nm - half_height + radius_nm
center_x_nm - half_width + radius_nm, center_y_nm - half_height + radius_nm
)
top_right_center = pcbnew.VECTOR2I(
center_x_nm + half_width - radius_nm,
center_y_nm - half_height + radius_nm
center_x_nm + half_width - radius_nm, center_y_nm - half_height + radius_nm
)
bottom_right_center = pcbnew.VECTOR2I(
center_x_nm + half_width - radius_nm,
center_y_nm + half_height - radius_nm
center_x_nm + half_width - radius_nm, center_y_nm + half_height - radius_nm
)
bottom_left_center = pcbnew.VECTOR2I(
center_x_nm - half_width + radius_nm,
center_y_nm + half_height - radius_nm
center_x_nm - half_width + radius_nm, center_y_nm + half_height - radius_nm
)
# Add arcs for corners
self._add_corner_arc(top_left_center, radius_nm, 180, 270, layer)
self._add_corner_arc(top_right_center, radius_nm, 270, 0, layer)
self._add_corner_arc(bottom_right_center, radius_nm, 0, 90, layer)
self._add_corner_arc(bottom_left_center, radius_nm, 90, 180, layer)
# Add lines for straight edges
# Top edge
self._add_edge_line(
pcbnew.VECTOR2I(top_left_center.x, top_left_center.y - radius_nm),
pcbnew.VECTOR2I(top_right_center.x, top_right_center.y - radius_nm),
layer
layer,
)
# Right edge
self._add_edge_line(
pcbnew.VECTOR2I(top_right_center.x + radius_nm, top_right_center.y),
pcbnew.VECTOR2I(bottom_right_center.x + radius_nm, bottom_right_center.y),
layer
layer,
)
# Bottom edge
self._add_edge_line(
pcbnew.VECTOR2I(bottom_right_center.x, bottom_right_center.y + radius_nm),
pcbnew.VECTOR2I(bottom_left_center.x, bottom_left_center.y + radius_nm),
layer
layer,
)
# Left edge
self._add_edge_line(
pcbnew.VECTOR2I(bottom_left_center.x - radius_nm, bottom_left_center.y),
pcbnew.VECTOR2I(top_left_center.x - radius_nm, top_left_center.y),
layer
layer,
)
def _add_corner_arc(self, center: pcbnew.VECTOR2I, radius: int,
start_angle: float, end_angle: float, layer: int) -> None:
def _add_corner_arc(
self,
center: pcbnew.VECTOR2I,
radius: int,
start_angle: float,
end_angle: float,
layer: int,
) -> None:
"""Add an arc for a rounded corner"""
# Create arc for corner
arc = pcbnew.PCB_SHAPE(self.board)
arc.SetShape(pcbnew.SHAPE_T_ARC)
arc.SetCenter(center)
# Calculate start and end points
start_x = center.x + int(radius * math.cos(math.radians(start_angle)))
start_y = center.y + int(radius * math.sin(math.radians(start_angle)))
end_x = center.x + int(radius * math.cos(math.radians(end_angle)))
end_y = center.y + int(radius * math.sin(math.radians(end_angle)))
arc.SetStart(pcbnew.VECTOR2I(start_x, start_y))
arc.SetEnd(pcbnew.VECTOR2I(end_x, end_y))
arc.SetLayer(layer)