From c76b49e7b9d2ab645dc349a9e2c29594462f7fe3 Mon Sep 17 00:00:00 2001 From: "Morgan 'ARR\\!' Allen" Date: Thu, 10 Jul 2025 14:18:27 -0700 Subject: [PATCH] big refactor of polygon references in Boards and feature references in API --- freecad/kiconnect/api.py | 64 +++++++++++++++++++------------ freecad/kiconnect/board.py | 1 + freecad/kiconnect/board_sketch.py | 6 +++ 3 files changed, 47 insertions(+), 24 deletions(-) diff --git a/freecad/kiconnect/api.py b/freecad/kiconnect/api.py index d7dbbf4..747ade1 100644 --- a/freecad/kiconnect/api.py +++ b/freecad/kiconnect/api.py @@ -13,6 +13,7 @@ class APIObject(BaseObject): def __init__(self, feature): self.boards = {} + self.polygons = {} self.kicad = KiCad() super(APIObject, self).__init__(feature) @@ -23,34 +24,49 @@ class APIObject(BaseObject): self.onDocumentRestored(feature) - self.ping_connection(feature) + self.ping_connection() self.kicad_board = self.kicad.get_board() - self.polygons = Board.extract_polygons(self.kicad_board) + polygons = Board.extract_polygons(self.kicad_board) - for polygon in self.polygons: + for polygon in polygons: board, polygon_id = Board.makeBoard(self.feature.getParent(), self.kicad_board, polygon) + self.polygons[polygon_id] = polygon self.boards[polygon_id] = board def onDocumentRestored(self, feature): super(APIObject, self).onDocumentRestored(feature) + if not hasattr(self, 'polygons'): + setattr(self, 'polygons', {}) + + if not hasattr(self, 'boards'): + setattr(self, 'boards', {}) + self.kicad = KiCad() - self.ping_connection(feature) - - if self.is_connected: - self.kicad_board = self.kicad.get_board() - self.polygons = Board.extract_polygons(self.kicad_board) - + self.refresh_polygons() parent = feature.getParent() if not parent: return - ''' - # XXX This gets all of the KiConnect::Board features but then does nothing with them - # future multi-board support? boards = [ board for board in parent.Group if hasattr(board, 'Type') and board.Type == 'KiConnect::Board' ] - ''' + + for board in boards: + print(board) + self.boards[board.PolygonId] = board + + def refresh_polygons(self): + self.ping_connection() + + if self.is_connected: + self.kicad_board = self.kicad.get_board() + polygons = Board.extract_polygons(self.kicad_board) + print('>', polygons) + + for poly in polygons: + self.polygons[poly.id.value] = poly + else: + print('*****NOT CONNECTED') @property def is_connected(self): @@ -61,11 +77,11 @@ class APIObject(BaseObject): return self.feature.Connected def get_polygon(self, polygon_id): - for p in self.polygons: - if p.id.value == polygon_id: - return p + print(polygon_id, self.polygons) + self.refresh_polygons() + return self.polygons.get(polygon_id) - def ping_connection(self, feature): + def ping_connection(self): ''' Ping the KiCAD API to determine if it's connected ''' @@ -76,25 +92,25 @@ class APIObject(BaseObject): try: self.kicad.ping() - feature.Connected = True + self.feature.Connected = True connection_status = 'Connected' except Exception as e: - feature.Connected = False + self.feature.Connected = False connection_status = 'Disconnected' - if feature.Connected: + if self.feature.Connected: try: docs = self.kicad.get_open_documents(DocumentType.DOCTYPE_PCB) document_status = f'{len(docs)} Documents' - feature.DocumentCount = len(docs) + self.feature.DocumentCount = len(docs) except Exception as e: print(e) - feature.DocumentCount = 0 + self.feature.DocumentCount = 0 - feature.Label2 = f'{connection_status} ({document_status})' + self.feature.Label2 = f'{connection_status} ({document_status})' - return feature.Connected + return self.feature.Connected class APIViewProvider(BaseViewProvider): diff --git a/freecad/kiconnect/board.py b/freecad/kiconnect/board.py index 1a3e542..c69888e 100644 --- a/freecad/kiconnect/board.py +++ b/freecad/kiconnect/board.py @@ -171,6 +171,7 @@ class BoardObject(BaseObject): feature.addProperty('App::PropertyVectorList', 'Vectors', 'KiConnect', 'Internal offset for zeroing out Footprint offset', hidden=True) feature.Doc = kicad_board.name + feature.Label2 = kicad_board.name if not feature.Thickness: feature.Thickness = 1.6 diff --git a/freecad/kiconnect/board_sketch.py b/freecad/kiconnect/board_sketch.py index b4eb537..87178ea 100644 --- a/freecad/kiconnect/board_sketch.py +++ b/freecad/kiconnect/board_sketch.py @@ -11,6 +11,9 @@ from kipy.util.board_layer import BoardLayer from .bases import BaseObject, BaseViewProvider +class BoardPolyNotFoundException(Exception): + pass + class BoardSketchObject(BaseObject): TYPE = 'KiConnect::BoardSketch' @@ -46,6 +49,9 @@ class BoardSketchObject(BaseObject): # board.get_shapes needs to be called to ensure polygons are actually up to date board_polygon = self.get_api().get_polygon(self.polygon_id) + if not board_polygon: + raise BoardPolyNotFoundException('Board Polygon not found: ' + self.polygon_id) + for node in board_polygon.polygons[0].outline: vectors.append(self.point_to_vector(node.point))