Compare commits

..

No commits in common. "c1194ecee097781f2bdca1efdd4a2925e43fa521" and "915d4981bda66d438c8ae620774f0fad027dfa03" have entirely different histories.

9 changed files with 48 additions and 175 deletions

View file

@ -2,7 +2,6 @@ import FreeCAD as App
import FreeCADGui as Gui
from kipy import KiCad
from kipy.proto.common.types import DocumentType
from . import settings
from .bases import BaseObject, BaseViewProvider
@ -15,7 +14,6 @@ class APIObject(BaseObject):
feature.addProperty('App::PropertyFile', 'Socket', 'KiConnect', 'Path to the KiCAD Socket File').Socket = '/tmp/kicad/api.lock'
feature.addProperty('App::PropertyBool', 'Connected', 'KiConnect', 'Is socket connected')
feature.addProperty('App::PropertyInteger', 'DocumentCount', 'KiConnect', 'Count of open Documnets')
self.onDocumentRestored(feature)
@ -28,49 +26,23 @@ class APIObject(BaseObject):
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' ]
@property
def is_connected(self):
'''
Returns connection status
'''
return self.feature.Connected
def ping_connection(self, feature):
'''
Ping the KiCAD API to determine if it's connected
'''
connection_status = 'Disconnected'
document_status = 'No Documents'
try:
self.kicad.ping()
feature.Connected = True
connection_status = 'Connected'
feature.Label2 = 'Connected'
except Exception as e:
print(e)
feature.Connected = False
connection_status = 'Disconnected'
if feature.Connected:
try:
docs = self.kicad.get_open_documents(DocumentType.DOCTYPE_PCB)
document_status = f'{len(docs)} Documents'
feature.DocumentCount = len(docs)
except Exception as e:
print(e)
feature.DocumentCount = 0
feature.Label2 = f'{connection_status} ({document_status})'
return feature.Connected
feature.Label2 = 'Disconnected'
pass
class APIViewProvider(BaseViewProvider):

View file

@ -1,5 +1,4 @@
class BaseObject:
EXTENSIONS = []
TYPE = None
def __init__(self, feature):
@ -14,8 +13,7 @@ class BaseObject:
def execute(self, feature):
# TODO this might not be the right move
print(self, 'BaseObject.execute')
#self.onDocumentRestored(feature)
self.onDocumentRestored(feature)
def get_api(self):
p = self.feature
@ -27,16 +25,6 @@ class BaseObject:
return None
def isChildOf(self, parent):
p = self.feature
while p:
if p == parent:
return True
p = p.getParent()
return False
def onBeforeChange(self, feature, prop):
pass
@ -54,11 +42,5 @@ class BaseObject:
def setup_properties(self, feature):
feature.addProperty('App::PropertyString', 'Type', 'KiConnect', 'Internatl KiConnect Type', read_only=True, hidden=True)
def sync_from(self):
pass
def sync_to(self):
pass
def __getstate__(self):
return None

View file

@ -7,11 +7,10 @@ from .. import settings
class BaseViewProvider:
ICON = None
TYPE = None
EXTENSIONS = []
VIEWPROVIDER_EXTENSIONS = []
def __init__(self, viewprovider):
self.viewprovider = viewprovider
self.feature = viewprovider.Object.Proxy.feature
self.icon = ''
@ -23,8 +22,8 @@ class BaseViewProvider:
self.setup_extensions()
def setup_extensions(self):
if hasattr(self, 'EXTENSIONS'):
for ext in self.EXTENSIONS:
if hasattr(self, 'VIEWPROVIDER_EXTENSIONS'):
for ext in self.VIEWPROVIDER_EXTENSIONS:
self.feature.addExtension(ext)
def attach(self, vobj):

View file

@ -19,57 +19,23 @@ class BoardObject(BaseObject):
super(BoardObject, self).__init__(feature)
self.kicad_board = None
self.substrate_body = None
self.substrate_sketch = None
self.via_sketch = None
feature.addProperty('App::PropertyPlacement', 'BoardOffset', 'KiConnect', 'Internal offset for zeroing out Footprint offset', hidden=True, read_only=True)
def execute(self, feature):
super(BoardObject, self).execute(feature)
def onDocumentRestored(self, feature):
if self.kicad_board is None:
self.kicad_board = self.get_api().kicad.get_board()
if not self.substrate_body:
self.create_substrate_body()
if not self.substrate_sketch:
self.create_substrate_sketch()
self.sketch_outline()
def onDocumentRestored(self, feature):
super(BoardObject, self).onDocumentRestored(feature)
self.kicad_board = self.get_api().kicad.get_board()
@property
def substrate_body(self):
return self.feature.getObject('Substrate')
@property
def substrate_sketch(self):
return self.substrate_body.getObject('Sketch')
def create_substrate_body(self):
substrate_body = App.ActiveDocument.addObject('PartDesign::Body', 'Substrate')
substrate_body.addProperty('App::PropertyString', 'Type', 'KiConnect', 'KiConnect specific Type', read_only=True, hidden=True)
substrate_body.Type = 'KiConnect::BoardBody'
self.feature.addObject(substrate_body)
def create_substrate_sketch(self):
substrate_sketch = App.ActiveDocument.addObject('Sketcher::SketchObject', 'Sketch')
substrate_sketch.Visibility = False
self.substrate_body.addObject(substrate_sketch)
pad = self.substrate_body.newObject('PartDesign::Pad', 'Outline')
pad.Profile = substrate_sketch
pad.Length = 1.6
pad.Midplane = True
if self.substrate_body is None:
self.extrude_substrate(feature)
self.sketch_outline(feature)
if len(self.kicad_board.get_vias()) > 0 and self.via_sketch is None:
self.setup_vias()
self.pocket_vias()
def extrude_substrate(self, feature):
self.substrate_sketch = App.ActiveDocument.addObject('Sketcher::SketchObject', 'Sketch')
@ -129,14 +95,7 @@ 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
Parameters:
do_offset (bool): If offset should be recalcualted, typically this is undesired after calculated the first time. (Default: True)
'''
def sketch_outline(self, feature):
boardpoly = self.get_boardpoly()
poly = boardpoly.polygons[0]
@ -145,15 +104,13 @@ class BoardObject(BaseObject):
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
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 = []
# reset Sketch Geometry
self.substrate_sketch.Geometry = []
# sketch outline
@ -179,11 +136,7 @@ class BoardObject(BaseObject):
Part.LineSegment(start, begin)
)
def sync_from(self):
self.sketch_outline()
self.substrate_body.recompute(True)
def sync_to(self):
def sync(self):
board = self.kicad_board
commit = board.begin_commit()

View file

@ -1,43 +0,0 @@
import FreeCADGui as Gui
class Syncable:
SYNCABLES = [ 'KiConnect::Project', 'KiConnect::Board', 'KiConnect::Parts', 'KiConnect::BoardBody', ]
def IsActive(self):
sel = Gui.Selection.getSelection()
if len(sel) == 0: return False
for obj in sel:
if obj.Type not in self.SYNCABLES:
return False
return True
def Activated(self):
selection = [ sel for sel in Gui.Selection.getSelection() if sel.Type in self.SYNCABLES ]
syncables = []
if len(selection) == 1:
syncables = selection
else:
syncables = []
for i in selection:
for j in selection:
print(selection)
if i == j: continue
if i in j.OutList:
break
else:
syncables.append(i)
for s in syncables:
if not hasattr(s, 'Proxy'): continue
feature = s.Proxy
if hasattr(feature, self.method):
getattr(feature, self.method)()
s.recompute()

View file

@ -8,7 +8,7 @@ from ..project import Project
class Reload:
def GetResources(self):
tooltip = '<p>Reload KiConnect Workbench for development.\nNOTE: Does not reload toolbars.</p>'
tooltip = '<p>Reload KiConnect Workbench for development.</p>'
iconFile = os.path.join(settings.ICONPATH, 'kiconnect.svg')
return {
@ -19,14 +19,15 @@ class Reload:
def Activated(self):
try:
Gui.activateWorkbench('PartWorkbench')
except:
Gui.activateWorkbench('Part')
print('failed to switch to Part WB')
except: pass
try:
Gui.removeWorkbench('KiConnect')
except:
print('failed to remove KiConnect')
pass
for mod in [mod for mod in sys.modules if 'kicon' in mod]:
print(f'Reloading {mod}')

View file

@ -7,11 +7,7 @@ import sys
from .. import settings
from ..project import Project
from .Syncable import Syncable
class SyncFrom(Syncable):
method = 'sync_from'
class Sync:
def GetResources(self):
tooltip = '<p>Reload Board from KiCAD.</p>'
iconFile = os.path.join(settings.ICONPATH, 'import_brd_file.svg')
@ -22,4 +18,12 @@ class SyncFrom(Syncable):
'Pixmap' : iconFile
}
Gui.addCommand('kiconn_sync_from', SyncFrom())
def Activated(self):
boards = [ sel for sel in Gui.Selection.getSelection() if sel.Type == 'KiConnect::Board' ]
for board in boards:
board.KiConnBoard.sketch_outline()
App.ActiveDocument.recompute()
Gui.addCommand('kiconn_sync_from', Sync())

View file

@ -6,11 +6,7 @@ import sys
from .. import settings
from ..project import Project
from .Syncable import Syncable
class SyncTo(Syncable):
method = 'sync_to'
class Sync:
def GetResources(self):
tooltip = '<p>Update Board in KiCAD.</p>'
iconFile = os.path.join(settings.ICONPATH, 'export_to_pcbnew.svg')
@ -21,4 +17,13 @@ class SyncTo(Syncable):
'Pixmap' : iconFile
}
Gui.addCommand('kiconn_sync_to', SyncTo())
def Activated(self):
boards = [ sel for sel in Gui.Selection.getSelection() if sel.Type == 'KiConnect::Board' ]
for board in boards:
board.KiConnBoard.sync()
Gui.addCommand('kiconn_sync_to', Sync())

View file

@ -28,7 +28,7 @@ class Project:
self.API = api.makeAPI(self.feature)
if self.API.Proxy.is_connected and self.API.DocumentCount > 0:
if self.API.Proxy.is_connected:
kicad_board = self.API.Proxy.kicad.get_board()
self.board = Board(kicad_board, self.feature)