如何获取在场景Autodesk Maya/Python中创建的根父级列表?

2024-09-23 06:38:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我对python有点陌生,我试图获得一个包含joint类型场景中存在的所有根父元素的列表。 例如,“场景大纲视图”(scene outliner)如下所示:

group1>>group2>>joint1>>joint2>>joint3

group3>>joint4>>joint5

joint16>>joint17>>joint18

我需要一个在大纲视图中遍历并返回列表的脚本,在我的示例中:

[joint1, joint4, joint16]

任何提示都将不胜感激。非常感谢你。在


Tags: 视图元素类型列表场景scene大纲group1
3条回答

我不确定是否有任何使用哈吉克雷解决方案工作良好,但 您也可以使用标志:-long from命令.ls在

# list all the joints from the scene
mjoints = cmds.ls(type='joint', l=True)
# list of the top joints from chain
output = []
# list to optimise the loop counter
exclusion = []
# lets iterate joints
for jnt in mjoints:
    # convert all hierarchy into a list
    pars = jnt.split('|')[1:]
    # lets see if our hierarchy is in the exclusion list
    # we put [1:] because maya root is represented by ''
    if not set(pars) & set(exclusion):
        # we parse the hierarchy until we reach the top joint
        # then we add it to the output
        # we add everything else to the exclusion list to avoid 
        for p in pars:
            if cmds.nodeType(p) == 'joint':
                output.append(p)
                exclusion+=pars
                break
print(output)

我之所以这么说是因为没有一条路可以走。我希望这段代码的构建可以帮助您掌握python的技能。完全一样,只是找到父节点的方法不同!在

我建议列出所有关节,对于每个关节,您可以检查它的父关节是否不是关节。按照你的定义,这些关节应该是你的根关节。在

我以前用过Weeny博士的想法,你可以通过对象的长名称遍历层次结构。这个答案的不同之处在于,如果场景中有重复名称的对象,脚本不会崩溃。我的意思是,假设你有两个等级:

group1>>joint1>>joint2>>group2>>joint3

以及

group3>>joint1>>joint2>>group2>>joint3

Maya很容易允许这样做,例如在复制顶部节点时,因此我们需要防止脚本在这种情况下崩溃。如果存在多个具有重复名称的对象,如果尝试访问对象的短名称,Maya将崩溃(它不知道您指的是哪个!),因此我们必须始终使用它的长名称:

import maya.cmds as cmds


jnts = cmds.ls(type="joint", l=True)  # Collect all joints in the scene by their long names.
output = set()  # Use a set to avoid adding the same joint.

for jnt in jnts:
    pars = jnt.split("|")  # Split long name so we can traverse its hierarchy.

    root_jnt = None

    while pars:
        obj = "|".join(pars)
        del pars[-1]  # Remove last word to "traverse" up hierarchy on next loop.

        # If this is a joint, mark it as the new root joint.
        if obj and cmds.nodeType(obj) == "joint":
            root_jnt = obj

    # If a root joint was found, append it to our final list.
    if root_jnt is not None:
        output.add(root_jnt)

print(list(output))

在上面的层次结构上使用此脚本将返回

[u'|group1|joint1', u'|group3|joint1']

相关问题 更多 >