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

View File

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