仅显示选定对象的层级

2 投票
1 回答
3203 浏览
提问于 2025-04-17 21:14

我正在创建一个用户界面,用户可以选择一个对象,界面会显示这个对象的层级结构。这有点像大纲工具,但我找不到任何文档或类似的结果来实现我想要的功能。顺便说一下,我是用Python编写代码的……

那么,这样做到底可不可以呢?

让我给你举个简单的例子:假设我选择了testCtrl,它只会显示testCtrl、loc和jnt,而不显示它的父级(Grp 01)。

比如说:Grp 01 --> testCtrl --> loc --> jnt

import maya.cmds as cmds

def customOutliner():
if cmds.ls( sl=True ):
    # Create the window/UI for the custom Oultiner 
    newOutliner = cmds.window(title="Outliner (Custom)", iconName="Outliner*", widthHeight=(250,100))
    frame = cmds.frameLayout(labelVisible = False)
    customOutliner = cmds.outlinerEditor()

    # Create the selection connection network; Selects the active selection
    inputList = cmds.selectionConnection( activeList=True )
    fromEditor = cmds.selectionConnection()

    cmds.outlinerEditor( customOutliner, edit=True, mainListConnection=inputList )
    cmds.outlinerEditor( customOutliner, edit=True, selectionConnection=fromEditor )

    cmds.showWindow( newOutliner )

else:
    cmds.warning('Nothing is selected. Custom Outliner will not be created.')

1 个回答

3

创建窗口:

你想使用 treeView 命令(可以查看文档)来实现这个功能。我把它放在一个表单布局里,这样更方便。

from maya import cmds
from collections import defaultdict

window = cmds.window()
layout = cmds.formLayout()

control = cmds.treeView(parent=layout)

cmds.formLayout(layout, e=True, attachForm=[(control,'top', 2),
                                            (control,'left', 2),
                                            (control,'bottom', 2),
                                            (control,'right', 2)])
cmds.showWindow(window)

填充树视图:

为此,我们将使用一个递归函数,这样你就可以通过嵌套的 listRelatives 调用来构建层级结构(详细信息可以查看文档)。首先用老牌的 ls -sl 命令开始:

def populateTreeView(control, parent, parentname, counter):
    # list all the children of the parent node
    children = cmds.listRelatives(parent, children=True, path=True) or []

    # loop over the children
    for child in children:
        # childname is the string after the last '|'
        childname = child.rsplit('|')[-1]

        # increment the number of spaces
        counter[childname] += 1
        # make a new string with counter spaces following the name
        childname = '{0} {1}'.format(childname, ' '*counter[childname])

        # create the leaf in the treeView, named childname, parent parentname
        cmds.treeView(control, e=True, addItem=(childname, parentname))

        # call this function again, with child as the parent. recursion!
        populateTreeView(control, child, childname, counter)


# find the selected object
selection = cmds.ls(sl=True)[0]

# create the root node in the treeView
cmds.treeView(control, e=True, addItem=(selection, ''), hideButtons=True)

# enter the recursive function
populateTreeView(control, selection, '', defaultdict(int))

窗口与大纲的对比。

我把空格替换成了 X,这样你可以更清楚地看到发生了什么。不过运行这段代码时会使用空格:

在这里输入图片描述


你可以查阅文档来进一步改进这个功能,但这应该是一个很好的起点。如果你想要与选择项保持实时连接,可以创建一个 scriptJob 来跟踪这个变化,并确保在重新填充之前清空树视图。

撰写回答