assembly: reduce dependency in AsmElementLink

This commit is contained in:
Zheng, Lei 2019-01-01 07:34:38 +08:00
parent 4aa3261e96
commit b72cc2c86d
2 changed files with 30 additions and 35 deletions

View File

@ -343,23 +343,25 @@ class AsmElement(AsmBase):
obj.setPropertyStatus('LinkedObject','ReadOnly') obj.setPropertyStatus('LinkedObject','ReadOnly')
obj.configLinkProperty('LinkedObject','Placement','LinkTransform') obj.configLinkProperty('LinkedObject','Placement','LinkTransform')
AsmElement.migrate(obj)
self.version = AsmVersion() self.version = AsmVersion()
def canLoadPartial(self,_obj): def canLoadPartial(self,_obj):
return 1 if self.getAssembly().frozen else 0 return 1 if self.getAssembly().frozen else 0
def migrate(self): @staticmethod
def migrate(obj):
# To avoid over dependency, we no longer link to PartGroup, but to the # To avoid over dependency, we no longer link to PartGroup, but to the
# child part object directly # child part object directly
obj = self.Object
link = obj.LinkedObject link = obj.LinkedObject
if not isinstance(link,tuple): if not isinstance(link,tuple):
return return
partGroup = self.getAssembly().getPartGroup() if isTypeOf(link[0],AsmPartGroup):
if isinstance(link,tuple) and link[0]==partGroup: logger.debug('migrate {}'.format(objName(obj)))
sub = link[1] sub = link[1]
dot = sub.find('.') dot = sub.find('.')
sobj = partGroup.getSubObject(sub[:dot+1],1) sobj = link[0].getSubObject(sub[:dot+1],1)
touched = 'Touched' in obj.State touched = 'Touched' in obj.State
obj.setLink(sobj,sub[dot+1:]) obj.setLink(sobj,sub[dot+1:])
if not touched: if not touched:
@ -1053,6 +1055,8 @@ class AsmElementLink(AsmBase):
self.part = None self.part = None
self.multiply = False self.multiply = False
AsmElement.migrate(obj)
self.version = AsmVersion() self.version = AsmVersion()
def childVersion(self,linked,mat): def childVersion(self,linked,mat):
@ -1107,7 +1111,7 @@ class AsmElementLink(AsmBase):
return False return False
_MyIgnoredProperties = _IgnoredProperties | \ _MyIgnoredProperties = _IgnoredProperties | \
set(('AcountCount','PlacementList')) set(('Count','PlacementList'))
def onChanged(self,obj,prop): def onChanged(self,obj,prop):
if obj.Removing or \ if obj.Removing or \
@ -1151,8 +1155,8 @@ class AsmElementLink(AsmBase):
# AsmElementLink is used by constraint to link to a geometry link. It # AsmElementLink is used by constraint to link to a geometry link. It
# does so by indirectly linking to an AsmElement object belonging to # does so by indirectly linking to an AsmElement object belonging to
# the same parent assembly. AsmElement is also a link, which again # the same parent or child assembly. AsmElement is also a link, which
# links to another AsmElement of a child assembly or the actual # again links to another AsmElement of a child assembly or the actual
# geometry element of a child feature. This function is for resolving # geometry element of a child feature. This function is for resolving
# the AsmElementLink's subname reference to the actual part object # the AsmElementLink's subname reference to the actual part object
# subname reference relative to the parent assembly's part group # subname reference relative to the parent assembly's part group
@ -1168,16 +1172,16 @@ class AsmElementLink(AsmBase):
if assembly == self.getAssembly(): if assembly == self.getAssembly():
return element.getElementSubname(recursive) return element.getElementSubname(recursive)
# The reference stored inside this ElementLink. We need the sub-assembly # The reference is stored inside this ElementLink. We need the
# name, which is the name before the first dot. This name may be # sub-assembly name, which is the name before the first dot. This name
# different from the actual assembly object's name, in case where the # may be different from the actual assembly object's name, in case where
# assembly is accessed through a link. And the sub-assembly may be # the assembly is accessed through a link. And the sub-assembly may be
# inside a link array, which we don't know for sure. But we do know that # inside a link array, which we don't know for sure. But we do know that
# the last two names are element group and element label. So just pop # the last two names are element group and element label. So just pop
# two names. # two names. The -3 below is to account for the last ending '.'
ref = self.Object.LinkedObject[1] ref = [link[0].Name] + link[1].split('.')[:-3]
prefix = ref[0:ref.rfind('.',0,ref.rfind('.',0,-1))] return '{}.2.{}'.format('.'.join(ref),
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
@ -1237,18 +1241,9 @@ class AsmElementLink(AsmBase):
sel = AsmElement.Selection(SelObj=None, SelSubname=None, sel = AsmElement.Selection(SelObj=None, SelSubname=None,
Element=None, Group=ret.Object, Subname=ret.Subname) Element=None, Group=ret.Object, Subname=ret.Subname)
element = AsmElement.make(sel,radius=radius) element = AsmElement.make(sel,radius=radius)
owner = owner.Proxy.getAssembly().getPartGroup()
# This give us reference to child assembly's immediate child owner = ret.Assembly
# without trailing dot. subname = '1.${}.'.format(element.Label)
prefix = subname[:len(subname)-len(ret.Subname)-1]
# Pop the immediate child name, and replace it with child
# assembly's element group name
prefix = prefix[:prefix.rfind('.')+1] + \
resolveAssembly(ret.Assembly).getElementGroup().Name
subname = '{}.${}.'.format(prefix, element.Label)
for sibling in elements: for sibling in elements:
if sibling == obj: if sibling == obj:
@ -3169,8 +3164,6 @@ 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)))

14
gui.py
View File

@ -669,7 +669,8 @@ class AsmCmdGotoLinked(AsmCmdBase):
@classmethod @classmethod
def Activated(cls): def Activated(cls):
from .assembly import isTypeOf, AsmElement, AsmElementLink from .assembly import isTypeOf, \
AsmElement, AsmElementLink, AsmElementGroup
sels = FreeCADGui.Selection.getSelectionEx('',0,True) sels = FreeCADGui.Selection.getSelectionEx('',0,True)
if not sels: if not sels:
return return
@ -683,12 +684,14 @@ class AsmCmdGotoLinked(AsmCmdBase):
return return
import Part import Part
subname = Part.splitSubname(subname)[0].split('.') subname = Part.splitSubname(subname)[0].split('.')
link,linkSub = obj.LinkedObject
if isTypeOf(obj,AsmElementLink): if isTypeOf(obj,AsmElementLink):
subname = subname[:-4] subname = subname[:-4]
if not isTypeOf(link,AsmElementGroup):
subname.append('3')
else: else:
subname = subname[:-2] subname = subname[:-2]
subname[-1] = '2' subname[-1] = '2'
link,linkSub = obj.LinkedObject
subname.append(link.Name) subname.append(link.Name)
subname = '.'.join(subname+linkSub.split('.')) subname = '.'.join(subname+linkSub.split('.'))
sobj = sels[0].Object.getSubObject(subname,retType=1) sobj = sels[0].Object.getSubObject(subname,retType=1)
@ -732,12 +735,11 @@ class AsmCmdGotoLinkedFinal(AsmCmdBase):
FreeCADGui.runCommand('Std_LinkSelectLinkedFinal') FreeCADGui.runCommand('Std_LinkSelectLinkedFinal')
return return
if isTypeOf(obj, AsmElementLink): while True:
obj = obj.getSubObject(subname,retType=1)
while isTypeOf(obj,AsmElement):
linked,subname = obj.LinkedObject linked,subname = obj.LinkedObject
obj = linked.getSubObject(subname,retType=1) obj = linked.getSubObject(subname,retType=1)
if not isTypeOf(obj,AsmElement):
break
obj = obj.getLinkedObject(True) obj = obj.getLinkedObject(True)