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):
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)))

View File

@ -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():

View File

@ -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))