assembly: change AsmElement linking behvaior

Instead of link to PartGroup, which causes over dependency, AsmElement
now links directly the part object. Note that this breaks forward
compatibility.
This commit is contained in:
Zheng, Lei 2018-10-09 16:05:57 +08:00
parent 5d9558b404
commit c66f782e65

View File

@ -318,6 +318,23 @@ class AsmElement(AsmBase):
obj.setPropertyStatus('LinkedObject','ReadOnly') obj.setPropertyStatus('LinkedObject','ReadOnly')
obj.configLinkProperty('LinkedObject','Placement','LinkTransform') obj.configLinkProperty('LinkedObject','Placement','LinkTransform')
def migrate(self):
# To avoid over dependency, we no longer link to PartGroup, but to the
# child part object directly
obj = self.Object
link = obj.LinkedObject
if not isinstance(link,tuple):
return
partGroup = self.getAssembly().getPartGroup()
if isinstance(link,tuple) and link[0]==partGroup:
sub = link[1]
dot = sub.find('.')
sobj = partGroup.getSubObject(sub[:dot+1],1)
touched = 'Touched' in obj.State
obj.setLink(sobj,sub[dot+1:])
if not touched:
obj.purgeTouched()
def attach(self,obj): def attach(self,obj):
obj.addProperty("App::PropertyXLink","LinkedObject"," Link",'') obj.addProperty("App::PropertyXLink","LinkedObject"," Link",'')
super(AsmElement,self).attach(obj) super(AsmElement,self).attach(obj)
@ -351,9 +368,9 @@ class AsmElement(AsmBase):
def execute(self,obj): def execute(self,obj):
info = None info = None
partGroup = self.getAssembly().getPartGroup()
if not obj.Detach and hasattr(obj,'Shape'): if not obj.Detach and hasattr(obj,'Shape'):
info = getElementInfo(self.getAssembly().getPartGroup(), info = getElementInfo(partGroup,self.getElementSubname())
self.getElementSubname())
mat = info.Placement.toMatrix() mat = info.Placement.toMatrix()
if not getattr(obj,'Radius',None): if not getattr(obj,'Radius',None):
shape = Part.Shape(info.Shape) shape = Part.Shape(info.Shape)
@ -419,7 +436,7 @@ class AsmElement(AsmBase):
if not isinstance(link,tuple): if not isinstance(link,tuple):
raise RuntimeError('Invalid element link "{}"'.format( raise RuntimeError('Invalid element link "{}"'.format(
objName(self.Object))) objName(self.Object)))
return link[1] return link[0].Name + '.' + link[1]
def getElementSubname(self,recursive=False): def getElementSubname(self,recursive=False):
''' '''
@ -431,10 +448,11 @@ class AsmElement(AsmBase):
if not recursive: if not recursive:
return subname return subname
obj = self.Object.LinkedObject link = self.Object.LinkedObject
if isinstance(obj,tuple): if not isinstance(link,tuple):
obj = obj[0] raise RuntimeError('Borken element link')
if not obj or obj == self.Object: obj = link[0].getSubObject(link[1],1)
if not obj:
raise RuntimeError('Borken element link') raise RuntimeError('Borken element link')
if not isTypeOf(obj,AsmElement): if not isTypeOf(obj,AsmElement):
# If not pointing to another element, then assume we are directly # If not pointing to another element, then assume we are directly
@ -452,8 +470,7 @@ class AsmElement(AsmBase):
# append the child assembly part group name, and recursively call into # append the child assembly part group name, and recursively call into
# child element # child element
return subname+childElement.getAssembly().getPartGroup().Name+'.'+\ return subname+'2.'+childElement.getElementSubname(True)
childElement.getElementSubname(True)
# Element: optional, if none, then a new element will be created if no # Element: optional, if none, then a new element will be created if no
# pre-existing. Or else, it shall be the element to be amended # pre-existing. Or else, it shall be the element to be amended
@ -511,8 +528,7 @@ class AsmElement(AsmBase):
if element: if element:
if len(hierarchies)>1: if len(hierarchies)>1:
raise RuntimeError('too many selections') raise RuntimeError('too many selections')
element = element[-1].Assembly.getSubObject( element = element[-1].Assembly.getSubObject(element[-1].Subname,1)
element[-1].Subname,retType=1)
if not isTypeOf(element,AsmElement): if not isTypeOf(element,AsmElement):
element = None element = None
@ -591,9 +607,10 @@ class AsmElement(AsmBase):
group.Name,subname)) group.Name,subname))
if not allowDuplicate: if not allowDuplicate:
return element return element
group,subname = element.LinkedObject group = element.getAssembly().getPartGroup()
subname = element.getSubName()
if isTypeOf(group,AsmConstraintGroup): elif isTypeOf(group,AsmConstraintGroup):
# if the selected object is an element link of a constraint of the # if the selected object is an element link of a constraint of the
# current assembly, then try to import its linked element if it is # current assembly, then try to import its linked element if it is
# not already imported # not already imported
@ -654,11 +671,11 @@ class AsmElement(AsmBase):
element = selection.Element element = selection.Element
sobj = group.getSubObject(subname,1) dot = subname.find('.')
sobj = group.getSubObject(subname[:dot+1],1)
if not sobj: if not sobj:
raise RuntimeError('invalid link {}.{}'.format( raise RuntimeError('invalid link {}.{}'.format(
objName(group),subname)) objName(group),subname))
try: try:
if undo: if undo:
FreeCAD.setActiveTransaction('Assembly change element' \ FreeCAD.setActiveTransaction('Assembly change element' \
@ -686,7 +703,7 @@ class AsmElement(AsmBase):
elements.setElementVisible(element.Name,False) elements.setElementVisible(element.Name,False)
element.Proxy._initializing = False element.Proxy._initializing = False
elements.cacheChildLabel() elements.cacheChildLabel()
element.setLink(group,subname) element.setLink(sobj,subname[dot+1:])
element.recompute() element.recompute()
if undo: if undo:
FreeCAD.closeActiveTransaction() FreeCAD.closeActiveTransaction()
@ -1075,7 +1092,7 @@ class AsmElementLink(AsmBase):
# subname reference relative to the parent assembly's part group # subname reference relative to the parent assembly's part group
link = self.Object.LinkedObject link = self.Object.LinkedObject
linked = link[0].getSubObject(link[1],retType=1) linked = link[0].getSubObject(link[1],1)
if not linked: if not linked:
raise RuntimeError('Element link broken') raise RuntimeError('Element link broken')
element = getProxy(linked,AsmElement) element = getProxy(linked,AsmElement)
@ -1092,8 +1109,7 @@ class AsmElementLink(AsmBase):
# two names. # two names.
ref = self.Object.LinkedObject[1] ref = self.Object.LinkedObject[1]
prefix = ref[0:ref.rfind('.',0,ref.rfind('.',0,-1))] prefix = ref[0:ref.rfind('.',0,ref.rfind('.',0,-1))]
return '{}.{}.{}'.format(prefix, assembly.getPartGroup().Name, return '{}.2.{}'.format(prefix,element.getElementSubname(recursive))
element.getElementSubname(recursive))
def setLink(self,owner,subname,checkOnly=False,multiply=False): def setLink(self,owner,subname,checkOnly=False,multiply=False):
obj = self.Object obj = self.Object
@ -1242,7 +1258,7 @@ class AsmElementLink(AsmBase):
pla = getLinkProperty(part[0],'PlacementList')[i] pla = getLinkProperty(part[0],'PlacementList')[i]
part = (part[0],i,part[2],part[3]) part = (part[0],i,part[2],part[3])
else: else:
sobj = part[0].getSubObject(str(i)+'.',retType=1) sobj = part[0].getSubObject(str(i)+'.',1)
pla = sobj.Placement pla = sobj.Placement
part = (part[0],i,sobj,part[3]) part = (part[0],i,sobj,part[3])
pla = part[0].Placement.multiply(pla) pla = part[0].Placement.multiply(pla)
@ -2230,7 +2246,7 @@ class AsmRelationGroup(AsmBase):
@staticmethod @staticmethod
def gotoRelationOfConstraint(obj,subname): def gotoRelationOfConstraint(obj,subname):
sub = Part.splitSubname(subname)[0].split('.') sub = Part.splitSubname(subname)[0].split('.')
sobj = obj.getSubObject(subname,retType=1) sobj = obj.getSubObject(subname,1)
if isTypeOf(sobj,AsmElementLink): if isTypeOf(sobj,AsmElementLink):
sobj = sobj.parent.Object sobj = sobj.parent.Object
sub = sub[:-2] sub = sub[:-2]
@ -2950,6 +2966,8 @@ 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
for o in ret.Group:
o.Proxy.migrate()
elif parent!=self: elif parent!=self:
raise RuntimeError('invalid parent of element group ' raise RuntimeError('invalid parent of element group '
'{}'.format(objName(ret))) '{}'.format(objName(ret)))