From a8f11a4a50306ae57a2bc9a8a4a83d3ded70794f Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Sat, 27 Jan 2018 12:15:05 +0800 Subject: [PATCH] Add "Auto element visibility" command When enabled, it will hide all AsmElement, and AsmElementLink, and only shown then when they are selected, or a AsmConstraint object is selected in the tree view --- .../icons/Assembly_AutoElementVis.svg | 603 ++++++++++++++++++ assembly.py | 39 +- gui.py | 74 ++- init_gui.py | 8 +- 4 files changed, 706 insertions(+), 18 deletions(-) create mode 100644 Gui/Resources/icons/Assembly_AutoElementVis.svg diff --git a/Gui/Resources/icons/Assembly_AutoElementVis.svg b/Gui/Resources/icons/Assembly_AutoElementVis.svg new file mode 100644 index 0000000..74d5bf5 --- /dev/null +++ b/Gui/Resources/icons/Assembly_AutoElementVis.svg @@ -0,0 +1,603 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + [Sebastian Hoogen] + + + OpenSCAD_RemoveSubtree + 2012-05-03 + http://www.freecadweb.org/wiki/index.php?title=Artwork + + + FreeCAD + + + FreeCAD/src/Mod/OpenSCAD/Resources/icons/OpenSCAD_RemoveSubtree.svg + + + FreeCAD LGPL2+ + + + https://www.gnu.org/copyleft/lesser.html + + + [agryson] Alexander Gryson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assembly.py b/assembly.py index 2d7e460..35e9463 100644 --- a/assembly.py +++ b/assembly.py @@ -48,7 +48,8 @@ def resolveAssembly(obj): # For faking selection obtained from Gui.getSelectionEx() Selection = namedtuple('AsmSelection',('Object','SubElementNames')) -_IgnoredProperties = set(['Visibility', 'Label', '_LinkRecomputed']) +_IgnoredProperties = set(['VisibilityList','Visibility', + 'Label','_LinkRecomputed']) class AsmBase(object): def __init__(self): @@ -130,6 +131,7 @@ class AsmGroup(AsmBase): self.Object.setPropertyStatus('GroupMode','Transient') self.Object.setPropertyStatus('Group','Hidden') self.Object.setPropertyStatus('Group','Immutable') + self.Object.setPropertyStatus('VisibilityList','Output') def attach(self,obj): obj.addProperty("App::PropertyLinkList","Group","Base",'') @@ -150,10 +152,9 @@ class ViewProviderAsmGroup(ViewProviderAsmBase): class ViewProviderAsmGroupOnTop(ViewProviderAsmGroup): - def attach(self,vobj): - super(ViewProviderAsmGroupOnTop,self).attach(vobj) + def __init__(self,vobj): vobj.OnTopWhenSelected = 2 - + super(ViewProviderAsmGroupOnTop,self).__init__(vobj) class AsmPartGroup(AsmGroup): def __init__(self,parent): @@ -474,6 +475,11 @@ class ViewProviderAsmElement(ViewProviderAsmOnTop): vobj.PointSize = 8 super(ViewProviderAsmElement,self).__init__(vobj) + def attach(self,vobj): + super(ViewProviderAsmElement,self).attach(vobj) + if gui.AsmCmdManager.AutoElementVis: + vobj.OnTopWhenSelected = 2 + def getDefaultColor(self): return (60.0/255.0,1.0,1.0) @@ -782,8 +788,11 @@ class AsmElementLink(AsmBase): ViewProviderAsmElementLink(link.ViewObject) info.Constraint.setLink({-1:link}) link.Proxy.setLink(info.Owner,info.Subname) + if not gui.AsmCmdManager.AutoElementVis: + info.Constraint.setElementVisible(link.Name,False) return link + def setPlacement(part,pla): AsmElementLink.setPlacement(part,pla) @@ -795,6 +804,11 @@ class ViewProviderAsmElementLink(ViewProviderAsmOnTop): vobj.ShapeMaterial.EmissiveColor = self.getDefaultColor() super(ViewProviderAsmElementLink,self).__init__(vobj) + def attach(self,vobj): + super(ViewProviderAsmElementLink,self).attach(vobj) + if gui.AsmCmdManager.AutoElementVis: + vobj.OnTopWhenSelected = 2 + def getDefaultColor(self): return (1.0,60.0/255.0,60.0/255.0) @@ -855,9 +869,13 @@ class AsmConstraint(AsmGroup): def linkSetup(self,obj): self.elements = None super(AsmConstraint,self).linkSetup(obj) - obj.setPropertyStatus('VisibilityList','Output') - for o in obj.Group: + group = obj.Group + for o in group: getProxy(o,AsmElementLink).parent = self + if gui.AsmCmdManager.AutoElementVis: + obj.setPropertyStatus('VisibilityList','-Immutable') + obj.VisibilityList = [False]*len(group) + obj.setPropertyStatus('VisibilityList','Immutable') Constraint.attach(obj) obj.recompute() @@ -1040,6 +1058,11 @@ class AsmConstraint(AsmGroup): class ViewProviderAsmConstraint(ViewProviderAsmGroup): + def attach(self,vobj): + super(ViewProviderAsmConstraint,self).attach(vobj) + if gui.AsmCmdManager.AutoElementVis: + vobj.OnTopWhenSelected = 2 + def getIcon(self): return Constraint.getIcon(self.ViewObject.Object) @@ -1092,7 +1115,6 @@ class AsmConstraintGroup(AsmGroup): def linkSetup(self,obj): super(AsmConstraintGroup,self).linkSetup(obj) - obj.setPropertyStatus('VisibilityList','Output') for o in obj.Group: cstr = getProxy(o,AsmConstraint) if cstr: @@ -1122,7 +1144,6 @@ class AsmElementGroup(AsmGroup): def linkSetup(self,obj): super(AsmElementGroup,self).linkSetup(obj) - obj.setPropertyStatus('VisibilityList','Output') for o in obj.Group: getProxy(o,AsmElement).parent = self obj.cacheChildLabel() @@ -1330,7 +1351,6 @@ class Assembly(AsmGroup): self.partArrays = set() obj.configLinkProperty('Placement') super(Assembly,self).linkSetup(obj) - obj.setPropertyStatus('VisibilityList','Output') System.attach(obj) self.onChanged(obj,'BuildShape') @@ -1741,3 +1761,4 @@ class ViewProviderAsmWorkPlane(ViewProviderAsmBase): def setDisplayMode(self, mode): return mode + diff --git a/gui.py b/gui.py index ed15260..25409dc 100644 --- a/gui.py +++ b/gui.py @@ -5,31 +5,75 @@ from .proxy import ProxyType from .FCADLogger import FCADLogger class SelectionObserver: - def __init__(self, cmds): + def __init__(self): self._attached = False + self.cmds = [] + self.elements = set() + self.attach() + + def setCommands(self,cmds): self.cmds = cmds def onChanged(self): for cmd in self.cmds: cmd.checkActive() - def addSelection(self,*_args): - self.onChanged() + def setElementVisible(self,docname,objname,subname,vis): + if not AsmCmdManager.AutoElementVis: + self.elements.clear() + return + from .assembly import isTypeOf,AsmConstraint,AsmElement,AsmElementLink + obj = FreeCAD.getDocument(docname).getObject(objname) + if not obj: + return + sobj = obj.getSubObject(subname,1) + if isTypeOf(sobj,(AsmElement,AsmElementLink)): + sobj.Proxy.parent.Object.setElementVisible(sobj.Name,vis) + elif isTypeOf(sobj,AsmConstraint): + vis = [vis] * len(sobj.Group) + sobj.setPropertyStatus('VisibilityList','-Immutable') + sobj.VisibilityList = vis + sobj.setPropertyStatus('VisibilityList','Immutable') + else: + return + if vis: + self.elements.add((docname,objname,subname)) + FreeCADGui.Selection.updateSelection(obj,subname) + elif self.elements: + logger.catchTrace('',self.elements.remove,(docname,objname,subname)) - def removeSelection(self,*_args): + def resetElementVisible(self): + elements = list(self.elements) + self.elements.clear() + for docname,objname,subname in elements: + self.setElementVisible(docname,objname,subname,False) + + def addSelection(self,docname,objname,subname,_pos): self.onChanged() + self.setElementVisible(docname,objname,subname,True) + + def removeSelection(self,docname,objname,subname): + self.onChanged() + self.setElementVisible(docname,objname,subname,False) def setSelection(self,*_args): self.onChanged() + if AsmCmdManager.AutoElementVis: + self.resetElementVisible() + for sel in FreeCADGui.Selection.getSelectionEx('*',False): + for sub in sel.SubElementNames: + self.setElementVisible(sel.Object.Document.Name, + sel.Object.Name,sub,True) def clearSelection(self,*_args): for cmd in self.cmds: cmd.onClearSelection() + self.resetElementVisible() def attach(self): logger.trace('attach selection aboserver {}'.format(self._attached)) if not self._attached: - FreeCADGui.Selection.addObserver(self) + FreeCADGui.Selection.addObserver(self,False) self._attached = True self.onChanged() @@ -224,6 +268,26 @@ class AsmCmdAutoRecompute(AsmCmdCheckable): _iconName = 'Assembly_AutoRecompute.svg' _saveParam = True +class AsmCmdAutoElementVis(AsmCmdCheckable): + _id = 9 + _menuText = 'Auto element visibility' + _iconName = 'Assembly_AutoElementVis.svg' + _saveParam = True + + @classmethod + def Activated(cls,checked): + super(AsmCmdAutoElementVis,cls).Activated(checked) + from .assembly import isTypeOf,AsmConstraint,AsmElement,AsmElementLink + visible = not checked + for doc in FreeCAD.listDocuments().values(): + for obj in doc.Objects: + if isTypeOf(obj,AsmConstraint): + obj.ViewObject.OnTopWhenSelected = 2 if checked else 0 + elif isTypeOf(obj,(AsmElementLink,AsmElement)): + vis = visible and not isTypeOf(obj,AsmElement) + obj.Proxy.parent.Object.setElementVisible(obj.Name,vis) + obj.ViewObject.OnTopWhenSelected = 2 + class AsmCmdAddWorkplane(AsmCmdBase): _id = 8 _menuText = 'Add workplane' diff --git a/init_gui.py b/init_gui.py index 5b0820b..ca7ce03 100644 --- a/init_gui.py +++ b/init_gui.py @@ -15,19 +15,19 @@ class Assembly3Workbench(FreeCADGui.Workbench): MenuText = 'Assembly 3' Icon = utils.addIconToFCAD('AssemblyWorkbench.svg') + from .gui import SelectionObserver + _observer = SelectionObserver() + def __init__(self): - self.observer = None self.docObserver = None def Activated(self): - self.observer.attach() FreeCAD.addDocumentObserver(self.docObserver) from .gui import AsmCmdManager for cmd in AsmCmdManager.getInfo().Types: cmd.workbenchActivated() def Deactivated(self): - self.observer.detach() FreeCAD.removeDocumentObserver(self.docObserver) from .gui import AsmCmdManager for cmd in AsmCmdManager.getInfo().Types: @@ -43,7 +43,7 @@ class Assembly3Workbench(FreeCADGui.Workbench): for name,cmds in AsmCmdManager.Menus.items(): cmdSet.update(cmds) self.appendMenu(name,[cmd.getName() for cmd in cmds]) - self.observer = SelectionObserver(cmdSet) + self._observer.setCommands(cmdSet) self.docObserver = AsmDocumentObserver() # FreeCADGui.addPreferencePage( # ':/assembly3/ui/assembly3_prefs.ui','Assembly3')