diff --git a/freecad/kiconnect/board.py b/freecad/kiconnect/board.py index 1c03282..e810f97 100644 --- a/freecad/kiconnect/board.py +++ b/freecad/kiconnect/board.py @@ -10,32 +10,54 @@ from kipy.proto.common.types import KiCadObjectType from kipy.util.board_layer import BoardLayer from .bases import BaseObject, BaseViewProvider -from . import parts +from . import parts as Parts class BoardObject(BaseObject): TYPE = 'KiConnect::Board' - def __init__(self, feature): - super(BoardObject, self).__init__(feature) + def __init__(self, feature, kicad_board, board_polygon): + self.feature = feature + self.kicad_board = kicad_board + # TODO add this to FreeCAD Preferences and Property? + self.do_offset = True + # TODO needs to be resotred in onDocumentRestored + #self.board_polygon = board_polygon + self.polygon_id = board_polygon.id.value - self.kicad_board = None self.via_sketch = None - feature.addProperty('App::PropertyPlacement', 'BoardOffset', 'KiConnect', 'Internal offset for zeroing out Footprint offset', hidden=True, read_only=True) + super(BoardObject, self).__init__(feature) + self.feature.PolygonId = board_polygon.id.value + + @property + def board_polygon(self): + print(self.polygon_id) + print([ poly for poly in extract_polygons(self.kicad_board) if poly.id.value == self.polygon_id ][0]) + return [ poly for poly in extract_polygons(self.kicad_board) if poly.id.value == self.polygon_id ][0] def execute(self, feature): - super(BoardObject, self).execute(feature) + begin = None + start = None - if self.kicad_board is None: - self.kicad_board = self.get_api().kicad.get_board() + sketch = self.substrate_sketch - if not self.substrate_body: - self.create_substrate_body() + # this probably needs a bit more control.. + sketch.Constraints = [] + sketch.Geometry = [] - if not self.substrate_sketch: - self.create_substrate_sketch() - self.sketch_outline() + for vector in self.feature.Vectors: + if not start: + start = vector + begin = vector + + continue + + sketch.addGeometry(Part.LineSegment(start, vector)) + + start = vector + + sketch.addGeometry(Part.LineSegment(start, begin)) def onDocumentRestored(self, feature): super(BoardObject, self).onDocumentRestored(feature) @@ -44,11 +66,21 @@ class BoardObject(BaseObject): @property def substrate_body(self): - return self.feature.getObject('Substrate') + body = self.feature.getObject('Substrate') + + if not body: + body = self.create_substrate_body() + + return body @property def substrate_sketch(self): - return self.substrate_body.getObject('Sketch') + sketch = self.substrate_body.getObject('Sketch') + + if not sketch: + sketch = self.create_substrate_sketch() + + return sketch def create_substrate_body(self): substrate_body = App.ActiveDocument.addObject('PartDesign::Body', 'Substrate') @@ -58,6 +90,8 @@ class BoardObject(BaseObject): self.feature.addObject(substrate_body) + return substrate_body + def create_substrate_sketch(self): substrate_sketch = App.ActiveDocument.addObject('Sketcher::SketchObject', 'Sketch') substrate_sketch.Visibility = False @@ -70,6 +104,7 @@ class BoardObject(BaseObject): pad.Length = 1.6 pad.Midplane = True + return substrate_sketch def extrude_substrate(self, feature): self.substrate_sketch = App.ActiveDocument.addObject('Sketcher::SketchObject', 'Sketch') @@ -87,6 +122,7 @@ class BoardObject(BaseObject): self.substrate_body.addObject(self.substrate_sketch) def get_boardpoly(self): + # TODO remove in favor of extract_polygons class method board = self.kicad_board # find polygons of Edge Cuts @@ -129,59 +165,32 @@ class BoardObject(BaseObject): via_pocket.Midplane = True via_pocket.Type = 1 - def sketch_outline(self, do_offset=True): - ''' - Draws the Board outline fetched from the API + def point_to_vector(self, point, offset=True): + return ( + App.Vector(point.x, + -point.y + )) / 1000000.0 - (self.feature.BoardOffset.Base if offset else 0) - Parameters: - do_offset (bool): If offset should be recalcualted, typically this is undesired after calculated the first time. (Default: True) - ''' - - boardpoly = self.get_boardpoly() - poly = boardpoly.polygons[0] - - # track KIID - # TODO FeaturePython objects interacting with kipy objects should inherit common parent class - self.feature.PolygonId = boardpoly.id.value - - # this offset centers the board to 0,0 - if do_offset: - bb = boardpoly.bounding_box() - self.feature.BoardOffset.Base = (App.Vector(bb.pos.x, -bb.pos.y) + App.Vector(bb.size.x, -bb.size.y) / 2) / 1000000.0 - - begin = None - start = None - - # reset Sketch Constraints and Geometry - self.substrate_sketch.Constraints = [] - self.substrate_sketch.Geometry = [] - - # sketch outline - for segment in poly.outline: - if not start: - start = (App.Vector(segment.point.x, -segment.point.y)) / 1000000.0 - self.feature.BoardOffset.Base - - # needs to remain to connect the last segment - begin = start - - continue - - end = (App.Vector(segment.point.x, -segment.point.y)) / 1000000.0 - self.feature.BoardOffset.Base - - self.substrate_sketch.addGeometry( - Part.LineSegment(start, end) - ) - - start = end - - # make final connection - self.substrate_sketch.addGeometry( - Part.LineSegment(start, begin) - ) def sync_from(self): - self.sketch_outline() - self.substrate_body.recompute(True) + ''' + Pulls outline from KiCAD PolygonBoard and saves points as Vectors + ''' + + if self.do_offset: + bb = self.board_polygon.bounding_box() + self.feature.BoardOffset.Base = (App.Vector(bb.pos.x, -bb.pos.y) + App.Vector(bb.size.x, -bb.size.y) / 2) / 1000000.0 + + vectors = [] + + for node in self.board_polygon.polygons[0].outline: + vectors.append(self.point_to_vector(node.point)) + + print(self.feature.Vectors == vectors) + self.feature.Vectors = vectors + print(self.feature.Vectors == vectors) + + App.ActiveDocument.recompute() def sync_to(self): board = self.kicad_board @@ -231,18 +240,22 @@ class BoardViewProvider(BaseViewProvider): TYPE = 'KiConnect::Board' ICON = 'board.svg' -class Board: - def __init__(self, kicad_board, parent): - feature = App.ActiveDocument.addObject('App::DocumentObjectGroupPython', 'Board') - parent.addObject(feature) - self.feature = feature +def makeBoard(parent, kicad_board, polygon): + feature = App.ActiveDocument.addObject('App::DocumentObjectGroupPython', 'Board') + parent.addObject(feature) - BoardObject(feature) - BoardViewProvider(feature.ViewObject) + BoardObject(feature, kicad_board, polygon) + BoardViewProvider(feature.ViewObject) - # TODO move into BoardObject - feature.addProperty('App::PropertyString', 'Doc', 'KiConnect', 'Doc in project to sync with', read_only=True).Doc = kicad_board.name - feature.addProperty('App::PropertyString', 'PolygonId', 'KiConnect', 'Polygon ID for the original outline', hidden=True, read_only=True) + Parts.makeParts(feature) - parts.makeParts(feature) + return feature + +def extract_polygons(board): + # find polygons of 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) ] + + # XXX only single board supported at the moment + return polygons