gui: add GotoRelation command
Can either go from part or constraint to their corresponding relation item.
This commit is contained in:
parent
8cf599ec15
commit
c359f07870
83
assembly.py
83
assembly.py
|
@ -1553,6 +1553,77 @@ class AsmRelationGroup(AsmBase):
|
|||
obj.purgeTouched()
|
||||
return obj
|
||||
|
||||
@staticmethod
|
||||
def gotoRelationOfConstraint(obj,subname):
|
||||
sub = Part.splitSubname(subname)[0].split('.')
|
||||
sobj = obj.getSubObject(subname,retType=1)
|
||||
if isTypeOf(sobj,AsmElementLink):
|
||||
sobj = sobj.parent.Object
|
||||
sub = sub[:-2]
|
||||
else:
|
||||
sub = sub[:-1]
|
||||
if not isTypeOf(sobj,AsmConstraint):
|
||||
return
|
||||
sub[-2] = '3'
|
||||
sub[-1] = ''
|
||||
sub = '.'.join(sub)
|
||||
subs = []
|
||||
relationGroup = sobj.Proxy.getAssembly().getRelationGroup(True)
|
||||
for relation in relationGroup.Proxy.getRelations().values():
|
||||
for o in relation.Group:
|
||||
if isTypeOf(o,AsmRelation):
|
||||
found = False
|
||||
for child in o.Group:
|
||||
if child == sobj:
|
||||
subs.append('{}{}.{}.{}.'.format(
|
||||
sub,relation.Name,o.Name,child.Name))
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
continue
|
||||
elif o == sobj:
|
||||
subs.append('{}{}.{}.'.format(sub,relation.Name,o.Name))
|
||||
|
||||
if subs:
|
||||
FreeCADGui.Selection.pushSelStack()
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(obj,subs)
|
||||
FreeCADGui.Selection.pushSelStack()
|
||||
FreeCADGui.runCommand('Std_TreeSelection')
|
||||
|
||||
@staticmethod
|
||||
def gotoRelation(moveInfo):
|
||||
if not moveInfo:
|
||||
return
|
||||
info = moveInfo.ElementInfo
|
||||
if info.Subname:
|
||||
subs = moveInfo.SelSubname[:-len(info.Subname)]
|
||||
else:
|
||||
subs = moveInfo.SelSubname
|
||||
subs = subs.split('.')
|
||||
relationGroup = resolveAssembly(info.Parent).getRelationGroup()
|
||||
if isinstance(info.Part,tuple):
|
||||
part = info.Part[0]
|
||||
else:
|
||||
part = info.Part
|
||||
relation = relationGroup.Proxy.findRelation(part)
|
||||
if not relation:
|
||||
return
|
||||
if isinstance(info.Part,tuple):
|
||||
if len(subs)<4:
|
||||
subs.append('')
|
||||
subs[-4] = '3'
|
||||
subs[-3] = relation.Name
|
||||
subs[-2] = relation.Group[info.Part[1]].Name
|
||||
else:
|
||||
subs[-3] = '3'
|
||||
subs[-2] = relation.Name
|
||||
FreeCADGui.Selection.pushSelStack()
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.Selection.addSelection(moveInfo.SelObj,'.'.join(subs))
|
||||
FreeCADGui.Selection.pushSelStack()
|
||||
FreeCADGui.runCommand('Std_TreeSelection')
|
||||
|
||||
|
||||
class ViewProviderAsmRelationGroup(ViewProviderAsmBase):
|
||||
_iconName = 'Assembly_Assembly_Relation_Tree.svg'
|
||||
|
@ -1587,6 +1658,18 @@ class AsmRelation(AsmBase):
|
|||
obj.setPropertyStatus('Group','Hidden')
|
||||
super(AsmRelation,self).attach(obj)
|
||||
|
||||
def getSubObject(self,obj,subname,retType,mat,transform,depth):
|
||||
if not subname or subname[0]==';':
|
||||
return False
|
||||
idx = subname.find('.')
|
||||
if idx<0:
|
||||
return False
|
||||
name = subname[:idx]
|
||||
for o in obj.Group:
|
||||
if o.Name == name:
|
||||
return o.getSubObject(subname[idx+1:],
|
||||
retType,mat,transform,depth+1)
|
||||
|
||||
def getAssembly(self):
|
||||
return self.parent.getAssembly()
|
||||
|
||||
|
|
77
gui.py
77
gui.py
|
@ -231,31 +231,48 @@ class AsmCmdMove(AsmCmdBase):
|
|||
_id = 2
|
||||
_menuText = 'Move part'
|
||||
_iconName = 'Assembly_Move.svg'
|
||||
_useCenterballDragger = True
|
||||
_accel = 'A, M'
|
||||
_moveInfo = None
|
||||
|
||||
@classmethod
|
||||
def Activated(cls):
|
||||
from . import mover
|
||||
mover.movePart(cls._useCenterballDragger)
|
||||
mover.movePart(True,cls._moveInfo)
|
||||
|
||||
@classmethod
|
||||
def canMove(cls):
|
||||
from . import mover
|
||||
cls._moveInfo = None
|
||||
cls._moveInfo = mover.getMovingElementInfo()
|
||||
mover.checkFixedPart(cls._moveInfo.ElementInfo)
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def checkActive(cls):
|
||||
from . import mover
|
||||
cls._active = mover.canMovePart()
|
||||
cls._active = logger.catchTrace('',cls.canMove)
|
||||
|
||||
@classmethod
|
||||
def onClearSelection(cls):
|
||||
cls._active = False
|
||||
cls._moveInfo = None
|
||||
|
||||
class AsmCmdAxialMove(AsmCmdMove):
|
||||
class AsmCmdAxialMove(AsmCmdBase):
|
||||
_id = 3
|
||||
_menuText = 'Axial move part'
|
||||
_iconName = 'Assembly_AxialMove.svg'
|
||||
_useCenterballDragger = False
|
||||
_accel = 'A, A'
|
||||
|
||||
class AsmCmdQuickMove(AsmCmdBase):
|
||||
@classmethod
|
||||
def IsActive(cls):
|
||||
return AsmCmdMove.IsActive()
|
||||
|
||||
@classmethod
|
||||
def Activated(cls):
|
||||
from . import mover
|
||||
mover.movePart(False,AsmCmdMove._moveInfo)
|
||||
|
||||
class AsmCmdQuickMove(AsmCmdAxialMove):
|
||||
_id = 13
|
||||
_menuText = 'Quick move'
|
||||
_tooltip = 'Bring an object contained in an assembly to where the mouse\n'\
|
||||
|
@ -269,15 +286,6 @@ class AsmCmdQuickMove(AsmCmdBase):
|
|||
from . import mover
|
||||
mover.quickMove()
|
||||
|
||||
@classmethod
|
||||
def checkActive(cls):
|
||||
from . import mover
|
||||
cls._active = mover.canMovePart()
|
||||
|
||||
@classmethod
|
||||
def onClearSelection(cls):
|
||||
cls._active = False
|
||||
|
||||
class AsmCmdCheckable(AsmCmdBase):
|
||||
_id = -2
|
||||
_saveParam = False
|
||||
|
@ -465,6 +473,45 @@ class AsmCmdAddWorkplaneGroup(AsmCmdAddWorkplane):
|
|||
def Activated(cls,idx=0):
|
||||
FreeCADGui.runCommand(cls._cmds[idx])
|
||||
|
||||
class AsmCmdGotoRelation(AsmCmdBase):
|
||||
_id = 16
|
||||
_menuText = 'Go to relation'
|
||||
_tooltip = 'Select the corresponding part object in the relation group'
|
||||
_iconName = 'Assembly_GotoRelation.svg'
|
||||
_accel = 'A, R'
|
||||
|
||||
@classmethod
|
||||
def Activated(cls):
|
||||
from .assembly import AsmRelationGroup
|
||||
if AsmCmdMove._moveInfo:
|
||||
AsmRelationGroup.gotoRelation(AsmCmdMove._moveInfo)
|
||||
return
|
||||
sels = FreeCADGui.Selection.getSelectionEx('',0,True)
|
||||
if sels and len(sels[0].SubElementNames)==1:
|
||||
AsmRelationGroup.gotoRelationOfConstraint(
|
||||
sels[0].Object,sels[0].SubElementNames[0])
|
||||
|
||||
@classmethod
|
||||
def IsActive(cls):
|
||||
if AsmCmdMove._moveInfo:
|
||||
return True
|
||||
if cls._active is None:
|
||||
cls.checkActive()
|
||||
return cls._active
|
||||
|
||||
@classmethod
|
||||
def checkActive(cls):
|
||||
from .assembly import isTypeOf, AsmConstraint, AsmElementLink
|
||||
sels = FreeCADGui.Selection.getSelection('',1,True)
|
||||
if sels and isTypeOf(sels[0],(AsmConstraint,AsmElementLink)):
|
||||
cls._active = True
|
||||
else:
|
||||
cls._active = False
|
||||
|
||||
@classmethod
|
||||
def onSelectionChange(cls,hasSelection):
|
||||
cls._active = None if hasSelection else False
|
||||
|
||||
|
||||
class AsmCmdUp(AsmCmdBase):
|
||||
_id = 6
|
||||
|
|
27
mover.py
27
mover.py
|
@ -210,13 +210,10 @@ class AsmMovingPart(object):
|
|||
# AsmMovingPart.update()
|
||||
return self.draggerPlacement
|
||||
|
||||
def _checkFixedPart(info):
|
||||
def checkFixedPart(info):
|
||||
if not gui.AsmCmdManager.LockMover:
|
||||
return
|
||||
if isTypeOf(info.Parent,Assembly,True):
|
||||
assembly = info.Parent.getLinkedObject(True).Proxy
|
||||
else:
|
||||
assembly = info.Parent.getAssembly()
|
||||
assembly = resolveAssembly(info.Parent)
|
||||
cstrs = assembly.getConstraints()
|
||||
parts = assembly.getPartGroup().Group
|
||||
if info.Part in Constraint.getFixedParts(None,cstrs,parts):
|
||||
|
@ -258,7 +255,6 @@ def getMovingElementInfo():
|
|||
if len(sels[0].SubElementNames)==1:
|
||||
info = getElementInfo(ret[0].Assembly,
|
||||
ret[0].Subname, checkPlacement=True)
|
||||
_checkFixedPart(info)
|
||||
return MovingPartInfo(SelObj=selObj,
|
||||
SelSubname=selSub,
|
||||
Hierarchy=ret,
|
||||
|
@ -283,22 +279,19 @@ def getMovingElementInfo():
|
|||
for r in ret2:
|
||||
if assembly == r.Assembly:
|
||||
info = getElementInfo(r.Assembly,r.Subname,checkPlacement=True)
|
||||
_checkFixedPart(info)
|
||||
return MovingPartInfo(SelObj=selObj,
|
||||
SelSubname=selSub,
|
||||
Hierarchy=ret2,
|
||||
ElementInfo=info)
|
||||
raise RuntimeError('not child parent selection')
|
||||
|
||||
def canMovePart():
|
||||
return logger.catchTrace('',getMovingElementInfo) is not None
|
||||
|
||||
def movePart(useCenterballDragger=None):
|
||||
ret = logger.catch('exception when moving part', getMovingElementInfo)
|
||||
if not ret:
|
||||
return False
|
||||
|
||||
info = ret.ElementInfo
|
||||
def movePart(useCenterballDragger=None,moveInfo=None):
|
||||
if not moveInfo:
|
||||
moveInfo = logger.catch(
|
||||
'exception when moving part', getMovingElementInfo)
|
||||
if not moveInfo:
|
||||
return False
|
||||
info = moveInfo.ElementInfo
|
||||
doc = FreeCADGui.editDocument()
|
||||
if doc:
|
||||
doc.resetEdit()
|
||||
|
@ -306,7 +299,7 @@ def movePart(useCenterballDragger=None):
|
|||
doc = info.Parent.ViewObject.Document
|
||||
if useCenterballDragger is not None:
|
||||
vobj.UseCenterballDragger = useCenterballDragger
|
||||
vobj.Proxy._movingPart = AsmMovingPart(ret.Hierarchy,info)
|
||||
vobj.Proxy._movingPart = AsmMovingPart(moveInfo.Hierarchy,info)
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
return doc.setEdit(vobj,1)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user