Compare commits

..

No commits in common. "6a639f2c7f69942fd40d3beb98f1ccc781d7259a" and "c76b49e7b9d2ab645dc349a9e2c29594462f7fe3" have entirely different histories.

4 changed files with 29 additions and 82 deletions

View file

@ -37,10 +37,10 @@ Hope to support this one of several ways, depending on the future of KiCAD/API
* KiCAD supports multi-document, API include `get_boards()` * KiCAD supports multi-document, API include `get_boards()`
* `kicad-cli` supports full API, spin up instances as needed * `kicad-cli` supports full API, spin up instances as needed
* Manually switch between KiCAD projects and import new boards * Manually switch between KiCAD projects and import new boards
* socket-per-project but this seems messy * socker-per-project but this seems messy
### Panelization ### Panelization
In it's most basic form, this will probably utilize `kikit` to assist in basic panelization but in multiboard projects it will assist in panelizing different boards into one panel. In it's most basic form, this will probably utilize `kikit` to assist in basic panelization but in multiboard projects it will assist in panelizing differnt boards into one panel.
### Synchronize all the things! ### Syncronize all the things!
Syncing selections is fairly straight forward, but long term it would be awesome to have everything sync as their changed. Syncing selections is fairly straight forward, but long term it would be awesome to have everything sync as their changed.

View file

@ -61,11 +61,12 @@ class APIObject(BaseObject):
if self.is_connected: if self.is_connected:
self.kicad_board = self.kicad.get_board() self.kicad_board = self.kicad.get_board()
polygons = Board.extract_polygons(self.kicad_board) polygons = Board.extract_polygons(self.kicad_board)
print('>', polygons)
for poly in polygons: for poly in polygons:
self.polygons[poly.id.value] = poly self.polygons[poly.id.value] = poly
else: else:
raise Exception('KiCAD API not connected.') print('*****NOT CONNECTED')
@property @property
def is_connected(self): def is_connected(self):
@ -76,6 +77,7 @@ class APIObject(BaseObject):
return self.feature.Connected return self.feature.Connected
def get_polygon(self, polygon_id): def get_polygon(self, polygon_id):
print(polygon_id, self.polygons)
self.refresh_polygons() self.refresh_polygons()
return self.polygons.get(polygon_id) return self.polygons.get(polygon_id)

View file

@ -4,7 +4,7 @@ import FreeCAD as App
from . import settings from . import settings
import Part import Part
from kipy.board_types import Footprint3DModel, BoardArc, 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
from kipy.util.board_layer import BoardLayer from kipy.util.board_layer import BoardLayer
@ -25,7 +25,7 @@ class BoardObject(BaseObject):
self.kicad_board = kicad_board self.kicad_board = kicad_board
# TODO needs to be restored in onDocumentRestored # TODO needs to be resotred in onDocumentRestored
#self.board_polygon = board_polygon #self.board_polygon = board_polygon
self.polygon_id = board_polygon.id.value self.polygon_id = board_polygon.id.value
@ -197,7 +197,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) ]
# XXX only single board supported at the moment
return polygons return polygons

View file

@ -3,7 +3,6 @@ import os
import FreeCAD as App import FreeCAD as App
from . import settings from . import settings
import Part import Part
import Sketcher
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
@ -40,104 +39,49 @@ class BoardSketchObject(BaseObject):
def setup_properties(self, feature): def setup_properties(self, feature):
super(BoardSketchObject, self).setup_properties(feature) super(BoardSketchObject, self).setup_properties(feature)
# TODO remove in favor of getting BoardOffset from parent Board object
feature.addProperty('App::PropertyPlacement', 'BoardOffset', 'KiConnect', 'Internal offset for zeroing out Footprint offset', hidden=True, read_only=True) feature.addProperty('App::PropertyPlacement', 'BoardOffset', 'KiConnect', 'Internal offset for zeroing out Footprint offset', hidden=True, read_only=True)
feature.addProperty('App::PropertyVectorList', 'Vectors', 'KiConnect', 'Board Outline as Vectors', hidden=True) feature.addProperty('App::PropertyVectorList', 'Vectors', 'KiConnect', 'Internal offset for zeroing out Footprint offset', hidden=True)
def sync_from(self): def sync_from(self):
feature = self.feature feature = self.feature
vectors = [] vectors = []
# board.get_shapes needs to be called to ensure polygons are actually up to date # board.get_shapes needs to be called to ensure polygons are actually up to date
# XXX get_polygon should be moved to the Sketches parent Board object
# then the board should be making the api refresh board call and process
# the polygon, instead of that functionality being in the API
board_polygon = self.get_api().get_polygon(self.polygon_id) board_polygon = self.get_api().get_polygon(self.polygon_id)
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)
arc_count = 0 for node in board_polygon.polygons[0].outline:
vectors.append(self.point_to_vector(node.point))
self.feature.Vectors = vectors
begin = None
start = None start = None
outline = board_polygon.polygons[0].outline # this probably needs a bit more control..
line = [] feature.Constraints = []
feature.Geometry = []
for node in outline: for vector in self.feature.Vectors:
if node.has_arc: if not start:
arc_count = arc_count + 1 start = vector
begin = vector
if arc_count % 2 == 0: continue
continue
arc = node.arc feature.addGeometry(Part.LineSegment(start, vector))
start = vector
feature.addGeometry(Part.LineSegment(start, begin))
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 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].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]))
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 == line[1].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)
feature.recompute() feature.recompute()
class BoardSketchViewProvider(BaseViewProvider): class BoardSketchViewProvider(BaseViewProvider):
TYPE = 'KiConnect::BoardSketch' TYPE = 'KiConnect::BoardSketch'
#ICON = 'kicad/board.svg' #ICON = 'kicad/board.svg'
def makeBoardSketch(parent, kicad_board, polygon): def makeBoardSketch(parent, kicad_board, polygon):
feature = App.ActiveDocument.addObject('Sketcher::SketchObjectPython', 'BoardSketch') feature = App.ActiveDocument.addObject('Sketcher::SketchObjectPython', 'BoardSketch')
parent.addObject(feature) parent.addObject(feature)