Compare commits

..

4 commits

Author SHA1 Message Date
Morgan 'ARR\!' Allen
1f8457c136 improved geometry drawing and constraint handling 2026-01-15 10:54:30 -08:00
Morgan 'ARR\!' Allen
8beab90791 also attempt to reload kipy 2026-01-15 10:42:10 -08:00
Morgan 'ARR\!' Allen
a362c7d61d work towards removing API calls from document loading pathway 2026-01-15 10:40:47 -08:00
Morgan 'ARR\!' Allen
e5c2c90cb2 broaden edge type checking to include BoardCircle 2026-01-15 10:36:04 -08:00
4 changed files with 69 additions and 52 deletions

View file

@ -22,6 +22,7 @@ class APIObject(BaseObject):
feature.addProperty('App::PropertyBool', 'Connected', 'KiConnect', 'Is socket connected') feature.addProperty('App::PropertyBool', 'Connected', 'KiConnect', 'Is socket connected')
feature.addProperty('App::PropertyInteger', 'DocumentCount', 'KiConnect', 'Count of open Documnets') feature.addProperty('App::PropertyInteger', 'DocumentCount', 'KiConnect', 'Count of open Documnets')
# XXX onDocumentRestored should not be called on creation
self.onDocumentRestored(feature) self.onDocumentRestored(feature)
self.ping_connection() self.ping_connection()
@ -44,7 +45,6 @@ class APIObject(BaseObject):
setattr(self, 'boards', {}) setattr(self, 'boards', {})
self.kicad = KiCad() self.kicad = KiCad()
self.refresh_polygons()
parent = feature.getParent() parent = feature.getParent()
if not parent: return if not parent: return

View file

@ -4,6 +4,7 @@ import FreeCAD as App
from . import settings from . import settings
import Part import Part
from kipy import board_types as BoardTypes
from kipy.board_types import Footprint3DModel, BoardArc, BoardPolygon, BoardSegment, PadStackShape from kipy.board_types import Footprint3DModel, BoardArc, BoardPolygon, BoardSegment, PadStackShape
from kipy.geometry import PolygonWithHoles, PolyLine, PolyLineNode, Vector2 from kipy.geometry import PolygonWithHoles, PolyLine, PolyLineNode, Vector2
from kipy.proto.common.types import KiCadObjectType from kipy.proto.common.types import KiCadObjectType
@ -197,7 +198,8 @@ def makeBoard(parent, kicad_board, polygon):
def extract_polygons(board): def extract_polygons(board):
# find polygons of Edge Cuts # find polygons of Edge Cuts
edge_cuts = [ edge for edge in board.get_shapes() if edge.layer == BoardLayer.BL_Edge_Cuts ] edge_cuts = [ edge for edge in board.get_shapes() if edge.layer == BoardLayer.BL_Edge_Cuts ]
polygons = [ edge for edge in edge_cuts if (isinstance(edge, BoardPolygon) or isinstance(edge, BoardArc)) ]
polygons = [ edge for edge in edge_cuts if (isinstance(edge, BoardPolygon) or isinstance(edge, BoardArc) or isinstance(edge, BoardTypes.BoardCircle)) ]
return polygons return polygons

View file

@ -5,6 +5,7 @@ from . import settings
import Part import Part
import Sketcher import Sketcher
from kipy import board_types as BoardTypes
from kipy.board_types import Footprint3DModel, BoardPolygon, BoardSegment, PadStackShape from kipy.board_types import Footprint3DModel, BoardPolygon, BoardSegment, PadStackShape
from kipy.geometry import PolygonWithHoles, PolyLine, PolyLineNode, Vector2 from kipy.geometry import PolygonWithHoles, PolyLine, PolyLineNode, Vector2
from kipy.proto.common.types import KiCadObjectType from kipy.proto.common.types import KiCadObjectType
@ -57,78 +58,92 @@ class BoardSketchObject(BaseObject):
if not board_polygon: if not board_polygon:
raise BoardPolyNotFoundException('Board Polygon not found: ' + self.polygon_id) raise BoardPolyNotFoundException('Board Polygon not found: ' + self.polygon_id)
# XXX: arc_count is a hack to address
# https://codeberg.org/kiconnect/KiConnect/issues/2
# below every other arc is skipped.
arc_count = 0 arc_count = 0
start = None start = None
outline = board_polygon.polygons[0].outline
line = [] line = []
for node in outline: if isinstance(board_polygon, BoardTypes.BoardCircle):
if node.has_arc: print(board_polygon)
arc_count = arc_count + 1 else:
outline = board_polygon.polygons[0].outline
for node in outline:
if node.has_arc:
arc_count = arc_count + 1
if arc_count % 2 == 0: if arc_count % 2 == 0:
continue continue
arc = node.arc arc = node.arc
arc_start = self.point_to_vector(arc.start)
arc_mid = self.point_to_vector(arc.mid)
arc_end = self.point_to_vector(arc.end)
arc_start = self.point_to_vector(arc.start) if not start:
arc_mid = self.point_to_vector(arc.mid) start = arc_start
arc_end = self.point_to_vector(arc.end)
if not start: # if there is already part of a LineSegment, connect it to the start of this Arc
start = arc_start if len(line) == 1:
idx = feature.addGeometry(Part.LineSegment(line[0], arc_start))
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1))
# if there is already part of a LineSegment, connect it to the start of this Arc if line[0].x == arc_start.x:
if len(line) == 1: feature.addConstraint(Sketcher.Constraint("Vertical", idx))
idx = feature.addGeometry(Part.LineSegment(line[0], arc_start))
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1))
if line[0].x == arc_start.x: if line[0].y == arc_start.y:
feature.addConstraint(Sketcher.Constraint("Horizontal", idx))
line = []
idx = feature.addGeometry(Part.Arc(arc_start, arc_mid, arc_end))
if idx > 1:
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1))
line.append(arc_end)
elif node.has_point:
vector = self.point_to_vector(node.point)
if not start:
start = vector
line.append(vector)
else:
raise Exception('Hit unknown geometry type in board polygon')
if len(line) > 2: raise Exception('Too many points in line segment', line)
if len(line) == 2:
idx = feature.addGeometry(Part.LineSegment(line[0], line[1]))
if idx > 0:
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1))
if line[0].x == line[1].x:
feature.addConstraint(Sketcher.Constraint("Vertical", idx)) feature.addConstraint(Sketcher.Constraint("Vertical", idx))
if line[0].y == arc_start.y: if line[0].y == line[1].y:
feature.addConstraint(Sketcher.Constraint("Horizontal", idx)) feature.addConstraint(Sketcher.Constraint("Horizontal", idx))
line = [] line = [line[1]]
idx = feature.addGeometry(Part.Arc(arc_start, arc_mid, arc_end))
if idx > 1:
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1))
line.append(arc_end) if len(line) == 1:
elif node.has_point: # XXX what if the final piece of geo is an arc?
vector = self.point_to_vector(node.point) idx = feature.addGeometry(Part.LineSegment(start, line[0]))
if not start: feature.addConstraint(Sketcher.Constraint("Coincident", 0, 1, idx, 1))
start = vector feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 2))
line.append(vector) if line[0].x == start.x:
else:
raise Exception('Hit unknown geometry type in board polygon')
if len(line) > 2: raise Exception('Too many points in line segment', line)
if len(line) == 2:
idx = feature.addGeometry(Part.LineSegment(line[0], line[1]))
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1))
if line[0].x == line[1].x:
feature.addConstraint(Sketcher.Constraint("Vertical", idx)) feature.addConstraint(Sketcher.Constraint("Vertical", idx))
if line[0].y == line[1].y: if line[0].y == start.y:
feature.addConstraint(Sketcher.Constraint("Horizontal", idx)) feature.addConstraint(Sketcher.Constraint("Horizontal", idx))
else:
line = [ line[1] ] FreeCAD.Console.PrintError("Bad line segment:", line)
if len(line) == 1:
idx = feature.addGeometry(Part.LineSegment(start, line[0]))
feature.addConstraint(Sketcher.Constraint("Coincident", 0, 1, idx, 1))
feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 2))
else:
FreeCAD.Console.PrintError("Bad line segment:", line)
feature.recompute() feature.recompute()

View file

@ -28,7 +28,7 @@ class Reload:
except: except:
print('failed to remove KiConnect') print('failed to remove KiConnect')
for mod in [mod for mod in sys.modules if 'kicon' in mod]: for mod in [mod for mod in sys.modules if 'kicon' in mod or 'kipy' in mod]:
print(f'Reloading {mod}') print(f'Reloading {mod}')
importlib.reload(sys.modules[mod]) importlib.reload(sys.modules[mod])