From e0939d1ec23a0d6152859d62d34cdc9d7564c49c Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Fri, 27 Jul 2018 14:44:11 +0800 Subject: [PATCH] assembly: support for derived assembly Deriving assembly directly contains all parts from derived assembly. And all derived parts are added as fixed part. The intention is mostly for user to customize visibilities of the derived parts as a way of controling the level of details. --- assembly.py | 80 +++++++++++++++++++++++++++++++++++++++++++---------- mover.py | 4 +-- solver.py | 4 +-- 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/assembly.py b/assembly.py index 06c73cd..8eaef04 100644 --- a/assembly.py +++ b/assembly.py @@ -179,8 +179,53 @@ class ViewProviderAsmGroupOnTop(ViewProviderAsmGroup): class AsmPartGroup(AsmGroup): def __init__(self,parent): self.parent = getProxy(parent,Assembly) + self.derivedParts = set() super(AsmPartGroup,self).__init__() + def getLinkedObject(self,obj,recursive,mat,transform,depth): + if not isTypeOf(getattr(obj,'DerivedFrom',None),Assembly,True): + return + if not recursive: + return (obj.DerivedFrom,mat) + return obj.DerivedFrom.getLinkedObject(True,mat,transform,depth+1) + + def canLinkProperties(self,_obj): + return False + + def linkSetup(self,obj): + super(AsmPartGroup,self).linkSetup(obj) + if not hasattr(obj,'DerivedFrom'): + obj.addProperty('App::PropertyLink','DerivedFrom','Base','') + self.derivedParts = set() + + def checkDerivedParts(self): + if self.getAssembly().Object.Freeze: + return + + obj = self.Object + if not isTypeOf(obj.DerivedFrom,Assembly,True): + self.derivedParts = set() + return + + parts = set(obj.Group) + derived = obj.DerivedFrom.getLinkedObject(True).Proxy.getPartGroup() + derivedParts = derived.Group + self.derivedParts = set(derivedParts) + newParts = obj.Group + vis = list(obj.VisibilityList) + touched = False + for o in derivedParts: + if o in parts: + continue + touched = True + newParts.append(o) + vis.append(True if derived.isElementVisible(o.Name) else False) + if touched: + obj.Group = newParts + obj.setPropertyStatus('VisibilityList','-Immutable') + obj.VisibilityList = vis + obj.setPropertyStatus('VisibilityList','Immutable') + def getAssembly(self): return self.parent @@ -193,7 +238,9 @@ class AsmPartGroup(AsmGroup): def onChanged(self,obj,prop): if obj.Removing or FreeCAD.isRestoring(): return - if prop == 'Group': + if prop == 'DerivedFrom': + self.checkDerivedParts() + elif prop == 'Group': parent = getattr(self,'parent',None) if parent and not self.parent.Object.Freeze: relationGroup = parent.getRelationGroup() @@ -2205,24 +2252,26 @@ class Assembly(AsmGroup): del partMap[part] def execute(self,obj): + if self.frozen: + return True + parts = set() partArrays = set() self.constraints = None - if not self.frozen: - self.buildShape() - System.touch(obj) - obj.ViewObject.Proxy.onExecute() + self.buildShape() + System.touch(obj) + obj.ViewObject.Proxy.onExecute() - # collect the part objects of this assembly - for cstr in self.getConstraints(): - for element in cstr.Proxy.getElements(): - info = element.Proxy.getInfo() - if isinstance(info.Part,tuple): - partArrays.add(info.Part[0]) - parts.add(info.Part[0]) - else: - parts.add(info.Part) + # collect the part objects of this assembly + for cstr in self.getConstraints(): + for element in cstr.Proxy.getElements(): + info = element.Proxy.getInfo() + if isinstance(info.Part,tuple): + partArrays.add(info.Part[0]) + parts.add(info.Part[0]) + else: + parts.add(info.Part) # Update the global part object list for auto solving # @@ -2441,9 +2490,9 @@ class Assembly(AsmGroup): obj.addProperty("App::PropertyLinkSubHidden", "ColoredElements","Base",'') obj.setPropertyStatus('ColoredElements',('Hidden','Immutable')) + obj.configLinkProperty('ColoredElements') if not hasattr(obj,'Freeze'): obj.addProperty('App::PropertyBool','Freeze','Base','') - obj.configLinkProperty('ColoredElements') super(Assembly,self).linkSetup(obj) obj.setPropertyStatus('Group','Output') System.attach(obj) @@ -2571,6 +2620,7 @@ class Assembly(AsmGroup): parent = getattr(ret.Proxy,'parent',None) if not parent: ret.Proxy.parent = self + ret.Proxy.checkDerivedParts() elif parent!=self: raise RuntimeError( 'invalid parent of part group {}'.format(objName(ret))) diff --git a/mover.py b/mover.py index a4bfe4d..e66ce3a 100644 --- a/mover.py +++ b/mover.py @@ -215,8 +215,8 @@ def checkFixedPart(info): return assembly = resolveAssembly(info.Parent) cstrs = assembly.getConstraints() - parts = assembly.getPartGroup().Group - if info.Part in Constraint.getFixedParts(None,cstrs,parts): + partGroup = assembly.getPartGroup() + if info.Part in Constraint.getFixedParts(None,cstrs,partGroup): raise RuntimeError('cannot move fixed part') def getMovingElementInfo(): diff --git a/solver.py b/solver.py index f4ee62d..24c4ada 100644 --- a/solver.py +++ b/solver.py @@ -56,8 +56,8 @@ class Solver(object): roty = FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90) self.ny = self.system.addNormal3dV(*utils.getNormal(roty)) - parts = assembly.Proxy.getPartGroup().Group - self._fixedParts = Constraint.getFixedParts(self,cstrs,parts) + partGroup = assembly.Proxy.getPartGroup() + self._fixedParts = Constraint.getFixedParts(self,cstrs,partGroup) for part in self._fixedParts: self._fixedElements.add((part,None))