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.
This commit is contained in:
Zheng, Lei 2018-07-27 14:44:11 +08:00
parent b30e63594c
commit e0939d1ec2
3 changed files with 69 additions and 19 deletions

View File

@ -179,8 +179,53 @@ class ViewProviderAsmGroupOnTop(ViewProviderAsmGroup):
class AsmPartGroup(AsmGroup): class AsmPartGroup(AsmGroup):
def __init__(self,parent): def __init__(self,parent):
self.parent = getProxy(parent,Assembly) self.parent = getProxy(parent,Assembly)
self.derivedParts = set()
super(AsmPartGroup,self).__init__() 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): def getAssembly(self):
return self.parent return self.parent
@ -193,7 +238,9 @@ class AsmPartGroup(AsmGroup):
def onChanged(self,obj,prop): def onChanged(self,obj,prop):
if obj.Removing or FreeCAD.isRestoring(): if obj.Removing or FreeCAD.isRestoring():
return return
if prop == 'Group': if prop == 'DerivedFrom':
self.checkDerivedParts()
elif prop == 'Group':
parent = getattr(self,'parent',None) parent = getattr(self,'parent',None)
if parent and not self.parent.Object.Freeze: if parent and not self.parent.Object.Freeze:
relationGroup = parent.getRelationGroup() relationGroup = parent.getRelationGroup()
@ -2205,24 +2252,26 @@ class Assembly(AsmGroup):
del partMap[part] del partMap[part]
def execute(self,obj): def execute(self,obj):
if self.frozen:
return True
parts = set() parts = set()
partArrays = set() partArrays = set()
self.constraints = None self.constraints = None
if not self.frozen: self.buildShape()
self.buildShape() System.touch(obj)
System.touch(obj) obj.ViewObject.Proxy.onExecute()
obj.ViewObject.Proxy.onExecute()
# collect the part objects of this assembly # collect the part objects of this assembly
for cstr in self.getConstraints(): for cstr in self.getConstraints():
for element in cstr.Proxy.getElements(): for element in cstr.Proxy.getElements():
info = element.Proxy.getInfo() info = element.Proxy.getInfo()
if isinstance(info.Part,tuple): if isinstance(info.Part,tuple):
partArrays.add(info.Part[0]) partArrays.add(info.Part[0])
parts.add(info.Part[0]) parts.add(info.Part[0])
else: else:
parts.add(info.Part) parts.add(info.Part)
# Update the global part object list for auto solving # Update the global part object list for auto solving
# #
@ -2441,9 +2490,9 @@ class Assembly(AsmGroup):
obj.addProperty("App::PropertyLinkSubHidden", obj.addProperty("App::PropertyLinkSubHidden",
"ColoredElements","Base",'') "ColoredElements","Base",'')
obj.setPropertyStatus('ColoredElements',('Hidden','Immutable')) obj.setPropertyStatus('ColoredElements',('Hidden','Immutable'))
obj.configLinkProperty('ColoredElements')
if not hasattr(obj,'Freeze'): if not hasattr(obj,'Freeze'):
obj.addProperty('App::PropertyBool','Freeze','Base','') obj.addProperty('App::PropertyBool','Freeze','Base','')
obj.configLinkProperty('ColoredElements')
super(Assembly,self).linkSetup(obj) super(Assembly,self).linkSetup(obj)
obj.setPropertyStatus('Group','Output') obj.setPropertyStatus('Group','Output')
System.attach(obj) System.attach(obj)
@ -2571,6 +2620,7 @@ class Assembly(AsmGroup):
parent = getattr(ret.Proxy,'parent',None) parent = getattr(ret.Proxy,'parent',None)
if not parent: if not parent:
ret.Proxy.parent = self ret.Proxy.parent = self
ret.Proxy.checkDerivedParts()
elif parent!=self: elif parent!=self:
raise RuntimeError( raise RuntimeError(
'invalid parent of part group {}'.format(objName(ret))) 'invalid parent of part group {}'.format(objName(ret)))

View File

@ -215,8 +215,8 @@ def checkFixedPart(info):
return return
assembly = resolveAssembly(info.Parent) assembly = resolveAssembly(info.Parent)
cstrs = assembly.getConstraints() cstrs = assembly.getConstraints()
parts = assembly.getPartGroup().Group partGroup = assembly.getPartGroup()
if info.Part in Constraint.getFixedParts(None,cstrs,parts): if info.Part in Constraint.getFixedParts(None,cstrs,partGroup):
raise RuntimeError('cannot move fixed part') raise RuntimeError('cannot move fixed part')
def getMovingElementInfo(): def getMovingElementInfo():

View File

@ -56,8 +56,8 @@ class Solver(object):
roty = FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90) roty = FreeCAD.Rotation(FreeCAD.Vector(1,0,0),90)
self.ny = self.system.addNormal3dV(*utils.getNormal(roty)) self.ny = self.system.addNormal3dV(*utils.getNormal(roty))
parts = assembly.Proxy.getPartGroup().Group partGroup = assembly.Proxy.getPartGroup()
self._fixedParts = Constraint.getFixedParts(self,cstrs,parts) self._fixedParts = Constraint.getFixedParts(self,cstrs,partGroup)
for part in self._fixedParts: for part in self._fixedParts:
self._fixedElements.add((part,None)) self._fixedElements.add((part,None))