assembly: fix GotoRelation on grouped objects

Fixes realthunder/FreeCAD_Assembly3#234
This commit is contained in:
Zheng, Lei 2019-04-30 21:25:22 +08:00
parent 279f5cd0bd
commit 381e970ac9
2 changed files with 41 additions and 22 deletions

View File

@ -58,7 +58,8 @@ def flattenLastSubname(obj,subname,last=None):
assembly along the subname path is considered
'''
if not last:
last = Assembly.find(obj,subname,recursive=True)[-1]
last = Assembly.find(obj,subname,
relativeToChild=True,recursive=True)[-1]
return subname[:-len(last.Subname)] \
+ flattenSubname(last.Object,last.Subname)
@ -2641,20 +2642,23 @@ class AsmRelationGroup(AsmBase):
moveInfo.SelObj, moveInfo.SelSubname)
return
last = moveInfo.Hierarchy[-1]
if len(moveInfo.Hierarchy)>1 and \
isTypeOf(sobj,(AsmConstraint,AsmElement,AsmElementLink)):
info = getElementInfo(last.Assembly, last.Subname)
if len(moveInfo.HierarchyList)>1 and \
isTypeOf(sobj,(AsmElement,AsmElementLink)):
hierarchy = moveInfo.HierarchyList[-1]
info = getElementInfo(hierarchy.Object, hierarchy.Subname)
else:
hierarchy = moveInfo.Hierarchy
if not info.Subname:
subname = flattenLastSubname(moveInfo.SelObj,subname,last)
subname = flattenLastSubname(moveInfo.SelObj,subname,hierarchy)
subs = subname.split('.')
elif moveInfo.SelSubname.endswith(info.Subname):
subname = flattenLastSubname(
moveInfo.SelObj, subname[:-len(info.Subname)],last)
moveInfo.SelObj,subname[:-len(info.Subname)])
subs = subname.split('.')
else:
subname = flattenLastSubname(moveInfo.SelObj, subname, last)
subname = flattenLastSubname(moveInfo.SelObj,subname,hierarchy)
logger.info('{} {}',subname,hierarchy)
subs = subname.split('.')
if isTypeOf(sobj,AsmElementLink):
subs = subs[:-3]
@ -4007,7 +4011,7 @@ class AsmPlainGroup(object):
if not sobj:
raise RuntimeError('Sub object not found: {}.{}'.format(
objName(group),sub))
if lastObj and isTypeOf(sobj,(AsmPlainGroup,AsmConstraint)):
if lastObj and isTypeOf(sobj,AsmPlainGroup):
group = sobj
selSub += sub[:index+1]
subs[0] = sub[index+1:]
@ -4025,7 +4029,7 @@ class AsmPlainGroup(object):
if not group:
raise RuntimeError('Sub object not found: {}.{}'.format(
objName(parent),common))
if not isTypeOf(group,(AsmPlainGroup,AsmConstraint)):
if not isTypeOf(group,AsmPlainGroup):
raise RuntimeError('Not from plain group')
selSub += common
subs = [ s[idx+1:] for s in subs ]

View File

@ -9,7 +9,7 @@ from .utils import logger, objName
from .constraint import Constraint
MovingPartInfo = namedtuple('MovingPartInfo',
('Hierarchy','ElementInfo','SelObj','SelSubname'))
('Hierarchy','HierarchyList','ElementInfo','SelObj','SelSubname'))
class AsmMovingPart(object):
def __init__(self,hierarchy,info):
@ -218,12 +218,15 @@ def checkFixedPart(info):
if info.Part in Constraint.getFixedParts(None,cstrs,partGroup):
raise RuntimeError('cannot move fixed part')
def findAssembly(obj,subname):
return Assembly.find(obj,subname,
recursive=True,relativeToChild=True,keepEmptyChild=True)
def getMovingElementInfo():
'''Extract information from current selection for part moving
It returns a tuple containing the selected assembly hierarchy (obtained from
Assembly.findChildren()), and AsmElementInfo of the selected child part
object.
It returns a tuple containing the selected assembly hierarchy, and
AsmElementInfo of the selected child part object.
If there is only one selection, then the moving part will be one belong to
the highest level assembly in selected hierarchy.
@ -246,20 +249,26 @@ def getMovingElementInfo():
selObj = sels[0].Object
selSub = sels[0].SubElementNames[0]
ret = Assembly.findChildren(selObj,selSub)
ret = findAssembly(selObj,selSub)
if not ret:
raise RuntimeError('invalid selection {}, subname {}'.format(
objName(selObj),selSub))
if len(sels[0].SubElementNames)==1:
info = getElementInfo(ret[0].Assembly,
ret[0].Subname, checkPlacement=True)
r = ret[0]
# Warning! Must not calling like below, because r.Assembly maybe a link,
# and we need that information
#
# info = getElementInfo(r.Object,r.Subname, ...)
info = getElementInfo(r.Assembly,
r.Object.Name+'.'+r.Subname, checkPlacement=True)
return MovingPartInfo(SelObj=selObj,
SelSubname=selSub,
Hierarchy=ret,
HierarchyList=ret,
Hierarchy=r,
ElementInfo=info)
ret2 = Assembly.findChildren(selObj,sels[0].SubElementNames[1])
ret2 = findAssembly(selObj,sels[0].SubElementNames[1])
if not ret2:
raise RuntimeError('invalid selection {}, subname {}'.format(
objName(selObj,sels[0].SubElementNames[1])))
@ -277,10 +286,16 @@ def getMovingElementInfo():
assembly = ret[-1].Assembly
for r in ret2:
if assembly == r.Assembly:
info = getElementInfo(r.Assembly,r.Subname,checkPlacement=True)
# Warning! Must not calling like below, because r.Assembly maybe a
# link, and we need that information
#
# info = getElementInfo(r.Object,r.Subname, ...)
info = getElementInfo(r.Assembly,
r.Object.Name+'.'+r.Subname,checkPlacement=True)
return MovingPartInfo(SelObj=selObj,
SelSubname=selSub,
Hierarchy=ret2,
HierarchyList=ret2,
Hierarchy=r,
ElementInfo=info)
raise RuntimeError('not child parent selection')
@ -295,7 +310,7 @@ def movePart(useCenterballDragger=None,moveInfo=None):
if doc:
doc.resetEdit()
vobj = resolveAssembly(info.Parent).Object.ViewObject
vobj.Proxy._movingPart = AsmMovingPart(moveInfo.Hierarchy,info)
vobj.Proxy._movingPart = AsmMovingPart(moveInfo.HierarchyList,info)
if useCenterballDragger is not None:
vobj.UseCenterballDragger = useCenterballDragger
FreeCADGui.Selection.clearSelection()