diff --git a/assembly.py b/assembly.py index b8225cb..3700408 100644 --- a/assembly.py +++ b/assembly.py @@ -3658,6 +3658,68 @@ class Assembly(AsmGroup): return Assembly.find( obj,subname,AsmConstraintGroup,False,relativeToChild) + @staticmethod + def fromLinkGroup(obj): + block = gui.AsmCmdManager.AutoRecompute + if block: + gui.AsmCmdManager.AutoRecompute = False + try: + removes = set() + table = {} + asm = Assembly._fromLinkGroup(obj,table,removes) + for o in removes: + o.Document.removeObject(o.Name) + asm.recompute(True) + return asm + finally: + if block: + gui.AsmCmdManager.AutoRecompute = True + + @staticmethod + def _fromLinkGroup(obj,table,removes): + mapped = table.get(obj,None) + if mapped: + return mapped + + if hasattr(obj,'Shape'): + return obj + + linked = obj.getLinkedObject(False) + if linked==obj and getattr(obj,'ElementCount',0): + linked = obj.LinkedObject + + if linked != obj: + mapped = Assembly._fromLinkGroup(linked,table,removes) + if mapped != linked: + obj.setLink(mapped) + table[obj] = obj + return obj + + children = [] + hiddens = [] + subs = obj.getSubObjects() + for sub in subs: + child,parent,childName,_ = obj.resolve(sub) + if not child: + logger.warn('failed to find sub object {}.{}'.format( + obj.Name,sub)) + continue + asm = Assembly._fromLinkGroup(child,table,removes) + children.append(asm) + if not parent.isElementVisible(childName): + hiddens.append(asm.Name) + asm.Visibility = False + + asm = Assembly.make(obj.Document,undo=False) + asm.Label = obj.Label + asm.Placement = obj.Placement + partGroup = asm.Proxy.getPartGroup() + partGroup.setLink(children) + for sub in hiddens: + partGroup.setElementVisible(sub,False) + table[obj] = asm + removes.add(obj) + return asm class ViewProviderAssembly(ViewProviderAsmGroup): _iconName = 'Assembly_Assembly_Frozen_Tree.svg' diff --git a/gui.py b/gui.py index 63707ad..d45e34d 100644 --- a/gui.py +++ b/gui.py @@ -314,6 +314,95 @@ class AsmCmdNewElement(AsmCmdBase): cls._active = None if hasSelection else False +class AsmCmdImportSingle(AsmCmdBase): + _id = 25 + _menuText = 'Import from STEP' + _iconName = 'Assembly_Import.svg' + _toolbarName = None + _menuGroupName = None + + @classmethod + def IsActive(cls): + return True + + @classmethod + def Activated(cls,idx=0): + _ = idx + from .assembly import Assembly + + objs = [] + for obj in FreeCADGui.Selection.getSelection(): + if obj.isDerivedFrom('App::LinkGroup'): + objs.append(obj) + else: + objs = None + break + + filenames = None + if not objs: + filenames = QtGui.QFileDialog.getOpenFileNames( + QtGui.QApplication.activeWindow(), 'Please select file', + None, 'STEP (*.stp *.step);;All (*.*)')[0] + if not filenames: + return + + FreeCAD.setActiveTransaction('Assembly import') + + doc = FreeCAD.ActiveDocument + if not doc: + doc = FreeCAD.newDocument() + + if filenames: + import ImportGui + for name in filenames: + obj = ImportGui.insert(name,doc.Name,merge=False, + useLinkGroup=True,mode=cls.importMode()) + if obj: + objs.append(obj) + + for obj in objs: + Assembly.fromLinkGroup(obj) + FreeCAD.closeActiveTransaction() + return + + @classmethod + def importMode(cls): + return 0 + + +class AsmCmdImportMulti(AsmCmdImportSingle): + _id = 26 + _menuText = 'Import as multi-document' + _tooltip = 'Import assemblies from STEP file into separate document' + _iconName = 'Assembly_ImportMulti.svg' + + @classmethod + def importMode(cls): + params = FreeCAD.ParamGet( + 'User parameter:BaseApp/Preferences/Mod/Import') + mode = params.GetInt('ImportMode',0) + if not mode: + mode = 2 + return mode + +class AsmCmdImport(AsmCmdBase): + _id = 27 + _iconName = AsmCmdImportSingle._iconName + _menuText = AsmCmdImportSingle._menuText + _menuGroupName = '' + _toolbarName = AsmCmdBase._toolbarName + _cmds = (AsmCmdImportSingle.getName(), + AsmCmdImportMulti.getName()) + + @classmethod + def IsActive(cls): + return True + + @classmethod + def GetCommands(cls): + return cls._cmds + + class AsmCmdSolve(AsmCmdBase): _id = 1 _menuText = 'Solve constraints' @@ -666,6 +755,7 @@ class AsmCmdAddWorkplaneGroup(AsmCmdBase): def GetCommands(cls): return cls._cmds + class AsmCmdGotoRelation(AsmCmdBase): _id = 16 _menuText = 'Go to relation'