Compare commits
6 commits
c76b49e7b9
...
6a639f2c7f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a639f2c7f | ||
|
|
35363fac75 | ||
|
|
a2d800849a | ||
|
|
22ccb608dc | ||
|
|
3984abc2f3 | ||
|
|
261b3e91e7 |
4 changed files with 82 additions and 29 deletions
|
|
@ -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
|
||||||
* socker-per-project but this seems messy
|
* socket-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 differnt 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 different boards into one panel.
|
||||||
|
|
||||||
### Syncronize all the things!
|
### Synchronize 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.
|
||||||
|
|
|
||||||
|
|
@ -61,12 +61,11 @@ 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:
|
||||||
print('*****NOT CONNECTED')
|
raise Exception('KiCAD API not connected.')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_connected(self):
|
def is_connected(self):
|
||||||
|
|
@ -77,7 +76,6 @@ 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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import FreeCAD as App
|
||||||
from . import settings
|
from . import settings
|
||||||
import Part
|
import Part
|
||||||
|
|
||||||
from kipy.board_types import Footprint3DModel, 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
|
||||||
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 resotred in onDocumentRestored
|
# TODO needs to be restored 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,8 +197,7 @@ 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) ]
|
polygons = [ edge for edge in edge_cuts if (isinstance(edge, BoardPolygon) or isinstance(edge, BoardArc)) ]
|
||||||
|
|
||||||
# XXX only single board supported at the moment
|
|
||||||
return polygons
|
return polygons
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ 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
|
||||||
|
|
@ -39,49 +40,104 @@ 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', 'Internal offset for zeroing out Footprint offset', hidden=True)
|
feature.addProperty('App::PropertyVectorList', 'Vectors', 'KiConnect', 'Board Outline as Vectors', 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)
|
||||||
|
|
||||||
for node in board_polygon.polygons[0].outline:
|
arc_count = 0
|
||||||
vectors.append(self.point_to_vector(node.point))
|
|
||||||
|
|
||||||
self.feature.Vectors = vectors
|
|
||||||
|
|
||||||
begin = None
|
|
||||||
start = None
|
start = None
|
||||||
|
|
||||||
# this probably needs a bit more control..
|
outline = board_polygon.polygons[0].outline
|
||||||
feature.Constraints = []
|
line = []
|
||||||
feature.Geometry = []
|
|
||||||
|
|
||||||
for vector in self.feature.Vectors:
|
for node in outline:
|
||||||
if not start:
|
if node.has_arc:
|
||||||
start = vector
|
arc_count = arc_count + 1
|
||||||
begin = vector
|
|
||||||
|
|
||||||
|
if arc_count % 2 == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
feature.addGeometry(Part.LineSegment(start, vector))
|
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)
|
||||||
|
|
||||||
|
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
|
start = vector
|
||||||
|
|
||||||
feature.addGeometry(Part.LineSegment(start, begin))
|
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)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue