我正在使用Autodesk Maya程序。 我已经制作了一个命名约定脚本,它将相应地命名某个约定中的每个项目。但是我每次都在场景中列出它,然后检查所选名称是否与场景中的任何当前名称匹配,然后我重命名它并在场景中再次重新检查,如果有重复。
然而,当我运行代码时,可能需要长达30秒到一分钟或更长时间才能完成所有操作。起初我不知道是什么让我的代码运行缓慢,因为它在相对较低的场景量下工作正常。但是当我将打印语句放入检查场景代码时,我发现检查场景中的所有项目需要很长时间,并检查重复项。
ls()命令提供场景中所有项目的unicode列表。这些项目可能相对较大,如果场景甚至有适量的项目,则可达到一千或更多,正常场景将比我现在的测试场景大几倍(在此列表中有大约794个项目) )。
这应该花这么久吗?我用的方法是用来比较效率低下的东西吗?我不知道该怎么做,代码占用了太多时间,我也想知道它是否可能是代码中的任何其他内容,但这似乎可能就是它。
以下是一些代码。
class Name(object):
"""A naming convention class that runs passed arguments through user
dictionary, and returns formatted string of users input naming convention.
"""
def __init__(self, user_conv):
self.user_conv = user_conv
# an example of a user convention is '${prefix}_${name}_${side}_${objtype}'
@staticmethod
def abbrev_lib(word):
# a dictionary of abbreviated words is here, takes in a string
# and returns an abbreviated string, if not found return given string
@staticmethod
def check_scene(name):
"""Checks entire scene for same name. If duplicate exists,
Keyword Arguments:
name -- (string) name of object to be checked
"""
scene = ls()
match = [x for x in scene if isinstance(x, collections.Iterable)
and (name in x)]
if not match:
return name
else:
return ''
def convert(self, prefix, name, side, objtype):
"""Converts given information about object into user specified convention.
Keyword Arguments:
prefix -- what is prefixed before the name
name -- name of the object or node
side -- what side the object is on, example 'left' or 'right'
obj_type -- the type of the object, example 'joint' or 'multiplyDivide'
"""
prefix = self.abbrev_lib(prefix)
name = self.abbrev_lib(name)
side = ''.join([self.abbrev_lib(x) for x in side])
objtype = self.abbrev_lib(objtype)
i = 02
checked = ''
subs = {'prefix': prefix, 'name': name, 'side':
side, 'objtype': objtype}
while self.checked == '':
newname = Template (self.user_conv.lower())
newname = newname.safe_substitute(**subs)
newname = newname.strip('_')
newname = newname.replace('__', '_')
checked = self.check_scene(newname)
if checked == '' and i < 100:
subs['objtype'] = '%s%s' %(objtype, i)
i+=1
else:
break
return checked
答案 0 :(得分:1)
while self.checked ==''
内为每次迭代拖曳几百或几千个项目的列表,这可能是罪魁祸首。 Maya中的FWIW打印速度也很慢,特别是如果你要打印一个很长的列表 - 所以这样做很多次肯定会很慢。无论如何。
我会尝试一些方法来加快速度:
MultiplyDivide
,为什么要浏览数百个随机节点?这是一些用于查找唯一节点名称的廉价代码:
def get_unique_scene_names (*nodeTypes):
if not nodeTypes:
nodeTypes = ('transform',)
results = {}
for longname in cmds.ls(type = nodeTypes, l=True):
shortname = longname.rpartition("|")[-1]
if not shortname in results:
results[shortname] = set()
results[shortname].add(longname)
return results
def add_unique_name(item, node_dict):
shortname = item.rpartition("|")[-1]
if shortname in node_dict:
node_dict[shortname].add(item)
else:
node_dict[shortname] = set([item])
def remove_unique_name(item, node_dict):
shortname = item.rpartition("|")[-1]
existing = node_dict.get(shortname, [])
if item in existing:
existing.remove(item)
def apply_convention(node, new_name, node_dict):
if not new_name in node_dict:
renamed_item = cmds.ls(cmds.rename(node, new_name), l=True)[0]
remove_unique_name(node, node_dict)
add_unique_name ( renamed_item, node_dict)
return renamed_item
else:
for n in range(99999):
possible_name = new_name + str(n + 1)
if not possible_name in node_dict:
renamed_item = cmds.ls(cmds.rename(node, possible_name), l=True)[0]
add_unique_name(renamed_item, node_dict)
return renamed_item
raise RuntimeError, "Too many duplicate names"
要在特定节点类型上使用它,您只需在调用apply_convention()
时提供正确的名称。这会将场景中的所有关节(天真!)重命名为'jnt_X',同时保持后缀唯一。你会做比这更聪明的事情,就像你的原始代码那样 - 这只是确保叶子是唯一的:
joint_names= get_unique_scene_names('joint')
existing = cmds.ls( type='joint', l = True)
existing .sort()
existing .reverse()
# do this to make sure it works from leaves backwards!
for item in existing :
apply_convention(item, 'jnt_', joint_names)
# check the uniqueness constraint by looking for how many items share a short name in the dict:
for d in joint_names:
print d, len (joint_names[d])
但是,就像我说的那样,计划那些该死的数字后缀,maya一直让他们没有征得许可,所以你不能打击他们:(
答案 1 :(得分:0)
不是为每个ls
运行name
,而是应该运行一次并将结果存储到set
(无序列表 - 稍快一点)。然后在运行check_scene
def check_scene(self, name):
"""Checks entire scene for same name. If duplicate exists,
Keyword Arguments:
name -- (string) name of object to be checked
"""
if not hasattr(self, 'scene'):
self.scene = set(ls())
if name not in self.scene:
return name
else:
return ''