From 1f8457c136d48f73cfd09b75219080e9e4671984 Mon Sep 17 00:00:00 2001 From: "Morgan 'ARR\\!' Allen" Date: Thu, 15 Jan 2026 10:54:30 -0800 Subject: [PATCH] improved geometry drawing and constraint handling --- freecad/kiconnect/board_sketch.py | 113 +++++++++++++++++------------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/freecad/kiconnect/board_sketch.py b/freecad/kiconnect/board_sketch.py index 415efac..e51d5f5 100644 --- a/freecad/kiconnect/board_sketch.py +++ b/freecad/kiconnect/board_sketch.py @@ -5,6 +5,7 @@ from . import settings import Part import Sketcher +from kipy import board_types as BoardTypes from kipy.board_types import Footprint3DModel, BoardPolygon, BoardSegment, PadStackShape from kipy.geometry import PolygonWithHoles, PolyLine, PolyLineNode, Vector2 from kipy.proto.common.types import KiCadObjectType @@ -57,78 +58,92 @@ class BoardSketchObject(BaseObject): if not board_polygon: 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 start = None - outline = board_polygon.polygons[0].outline line = [] - for node in outline: - if node.has_arc: - arc_count = arc_count + 1 + if isinstance(board_polygon, BoardTypes.BoardCircle): + print(board_polygon) + 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: - continue + if arc_count % 2 == 0: + 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) - arc_mid = self.point_to_vector(arc.mid) - arc_end = self.point_to_vector(arc.end) + if not start: + start = arc_start - if not start: - start = arc_start + # if there is already part of a LineSegment, connect it to the start of this Arc + 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 len(line) == 1: - 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: + feature.addConstraint(Sketcher.Constraint("Vertical", idx)) - 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)) - if line[0].y == arc_start.y: + if line[0].y == line[1].y: 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) - elif node.has_point: - vector = self.point_to_vector(node.point) + if len(line) == 1: + # XXX what if the final piece of geo is an arc? + idx = feature.addGeometry(Part.LineSegment(start, line[0])) - if not start: - start = vector + feature.addConstraint(Sketcher.Constraint("Coincident", 0, 1, idx, 1)) + feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 2)) - 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])) - feature.addConstraint(Sketcher.Constraint("Coincident", idx - 1, 2, idx, 1)) - - if line[0].x == line[1].x: + if line[0].x == start.x: 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)) - - line = [ line[1] ] - - - 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) + else: + FreeCAD.Console.PrintError("Bad line segment:", line) feature.recompute()