【问题标题】:What's happening in my object renaming script?我的对象重命名脚本中发生了什么?
【发布时间】:2014-05-04 18:36:53
【问题描述】:

请多多包涵,尤其是我的问题…… 如果我的主题标题在某些方面误导了您,我提前道歉,但这是我能想到的最好的方法

我正在做一个基本的重命名应用程序,如下面的代码所示。 基本上,我是从我遇到的一个示例中获取的,将其添加到我的代码和中提琴中,它可以工作。遗憾的是,有几个部分我不明白,当我尝试在网上搜索答案时,我什么也没想到,这确实令人沮丧。

import pymel.core as pm
objects = pm.ls(selection=True)
# Result: [nt.Transform(u'my_pCube1')] # 
pfx = 'test'

for item in objects:
    item.rename(pfx + "_" + item.name().split('|')[-1])
    print 'Prefix added: %s_' %pfx
  1. 在这种情况下,[nt.Transform(u'my_pCube1')] 被视为长名称还是短名称?

  2. .name() 来自哪里?它是重命名隐藏函数的一部分还是我从文档中看不到的东西?

然后,由于我几乎在整个编码过程中都在使用cmds,我想我不妨将它标准化并将pm 更改为cmds...但是,它并没有像我想象的那样运行,而是给了我错误如下图。

objects = cmds.ls(selection=True)
# AttributeError: 'unicode' object has no attribute 'rename' # 
  1. 为什么会这样?
  2. 此外,当我试图打印出objects 的输出时,它会打印出对象而不是选择。有什么想法吗?

【问题讨论】:

  • 也许可以查看 Maya 的 API 文档。此外,从您的帖子中也不清楚您正在使用该 API。

标签: python rename maya


【解决方案1】:

您的示例使用 PyMel,因此列表中的对象是 PyNodes,正如 @vaibhaw 指出的那样。它们在这种情况下很有用,因为它们保留了与原始场景对象的连接。

maya 对象的长名称是 |path|to|object 形式的名称,其中包含层次结构中它上面的所有对象的名称。要从 pynode 获取此信息,请在节点上使用 fullPath() 函数

短名称通常是在对象的大纲或通道框中显示的名称。当您有多个具有相同短名称的对象时,maya 将为您提供足够的长名称来区分这些对象。对于像这样的层次结构:

group1
  box
group2 
  box

短名称将是 |group1|box|group2|box。使用 shortName() 从 pynode 获取此信息;这就是你使用普通的旧 Maya 或 mel 所得到的。

要从 pynode 获取您在通道框中看到的名称,请使用 nodeName()。这只会为您提供对象的“个人”名称。

如果你使用 pynodes,你应该能够在每个对象上调用 rename()。但是,您需要保留对象以检查它们的新名称——新名称可能不是您想要的,因为 Maya 不允许同级对象具有相同的名称;它将使用尾随数字重命名兄弟姐妹以保持它们的唯一性。

在第二段代码中,您使用的是 maya.cmds。它不对具有自己功能的对象进行操作,而是将所有对象视为字符串。所以

pynode = pm.PyNode("pCube1")
pynode.rename("fred")
print pynode
# Result: [nt.Transform(u'fred')] # 

在 pymel 中,但在 maya.cmds 中,对象只是字符串:

cube = "pCube1"
renamed_cube = cmds.rename(cube, "barney")
print renamed_cube:
#  Result: barney # 

【讨论】:

  • 我明白你所说的长名称和短名称的意思,但是,我仍然对我发布的代码感到困惑。我相信我的,它正在读取并打印出短名称,但仍然, split 首先来自哪里?它甚至没有|
  • 对象名中确实没有|。所以没有必要使用拆分。虽然它仍然有效,因为如果separator(此处为|)不存在于字符串中,split() 将返回一个仅包含 1 个元素的列表,该元素是原始字符串(对象名称)。 list[-1]list 中的最后一个元素。由于列表中只有 1 个元素,因此 list[-1] 为您提供对象名称。因此在这种情况下 item.name().split('|')[-1] 最终是 item.name()
  • @vaibhaw 谢谢你的解释。我做了一个快速的实验,理论奏效了。但是,当我使用[0] 而不是[-1] 对其进行测试时,代码可以正常工作并提供相同的输出。这是否意味着0(指第一个元素,我想)等于-1(最后一个元素)?
  • 确实如此。 some_list[0] 是列表 some_list 的第一个元素。当列表中只有一个元素时,它可以作为[0][-1] 访问,因为它既是第一个元素也是最后一个元素。在具有n 元素的列表中,您可以通过两种方式访问​​它:1. for item in objects: ... 或 2. 使用列表中项目的索引(即位置)。 list[x-1] 将为您提供从list[0](第一个元素)到list[n-1](最后一个元素)的列表的第 x 个元素。您还可以从list[-1](最后一个元素)到list[-n](第一个元素)向后访问列表的元素。
【解决方案2】:

我假设 pm 是 pymel.core 模块。请参阅此模块 here 的文档。 pymel.core 模块中的ls 方法返回一个 PyNode 对象列表。

阅读 PyNodes here。特别阅读PyNodes Are Not StringsMutability and You 部分,其中提到 rename 方法可用于 PyNode 对象。

查看 cmds 中 lsrename 方法的文档。 ls 返回一个字符串变量数组(对象名称),而不是对象本身。并且字符串没有称为rename 的方法,因此您得到的是AttributeError

要使用 cmds 重命名,这可能有效:

objects = cmds.ls(selection=True)
pfx = 'test'

for item in objects:
    cmds.rename(item, pfx + "_" + item)
    # cmds.rename(old_filename, new_filename)
    print 'Prefix added: %s_' %pfx

代码未测试,因为我没有安装 Maya。

.name()PyNode 对象的一个​​属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-15
    • 2017-09-27
    • 2013-09-14
    • 2021-02-16
    • 1970-01-01
    • 2022-01-22
    • 2021-01-22
    • 1970-01-01
    相关资源
    最近更新 更多