From 381e970ac93e4389303a10e4e41a2a1f879fda6d Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Tue, 30 Apr 2019 21:25:22 +0800 Subject: [PATCH] assembly: fix GotoRelation on grouped objects Fixes realthunder/FreeCAD_Assembly3#234 --- assembly.py | 24 ++++++++++++++---------- mover.py | 39 +++++++++++++++++++++++++++------------ 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/assembly.py b/assembly.py index 0371f07..13f1ec1 100644 --- a/assembly.py +++ b/assembly.py @@ -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 ] diff --git a/mover.py b/mover.py index d5fcd8e..6fada26 100644 --- a/mover.py +++ b/mover.py @@ -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()