#python #maya
#python #maya
Вопрос:
Я немного новичок в Python и пытаюсь получить список, содержащий всех корневых родительских элементов, существующих в сцене типа joint
. например, мой компоновщик сцены выглядит примерно так:
group1>> group2>> joint1>> joint2>> joint3
группа3>> объединение4>> объединение5
joint16>> joint17>> joint18
Мне нужен скрипт, который перемещается по контуру и возвращает список, как в моем примере:
[joint1, joint4, joint16]
Любые советы были бы действительно оценены. большое вам спасибо.
Ответ №1:
Я не уверен, что это можно использовать, решение Haggi Krey работает нормально, но вы также можете использовать флаг: -long from cmds.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) amp; 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. Это точно то же самое, просто способ поиска родительских узлов отличается!
Комментарии:
1. большое вам спасибо за ваше время и помощь. я тоже попробую и дам вам знать ^^
2. Здравствуйте, Диан Лан Луу, обратите внимание, что пометка вопроса как принятого отличается от получения наилучшего ответа. Теоретически вы должны были предоставить ему ключ Haggi и проголосовать за новые ответы, которые вы считаете более актуальными
3. обратите внимание, что вы, возможно, не сможете проголосовать за повышение, потому что вы новичок, но это своего рода правило stackoverflow ;]
Ответ №2:
Я уже использовал идею DrWeeny, когда вы перемещаетесь по иерархии по длинному имени объекта. Разница в этом ответе заключается в том, что скрипт не завершит работу, если в сцене есть объекты с повторяющимися именами. Под этим я подразумеваю, допустим, у вас ситуация, когда у вас есть 2 иерархии:
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']
Комментарии:
1. предполагать, что у них будут двойные имена, немного грустно, но всегда есть сумасшедший ученый, пытающийся это сделать…. Мне нравится, когда вы выполняете цикл while, я всегда избегаю их, потому что в конечном итоге я зацикливаю maya: S
2. Я полностью согласен, но это случается чаще, чем мне хотелось бы! Особенно при работе с младшими.
3. Я очень благодарен за ваше время и ценную помощь и прошу прощения за мой поздний ответ, поскольку я не смог протестировать ваши решения в maya. работает как по маслу. миллион раз благодарю вас, Хагги, DrWeeny и Green Cell 🙂
Ответ №3:
Я бы предложил перечислить все соединения, и для каждого соединения вы можете проверить, не является ли это родительское соединение соединением. По вашему определению, эти соединения должны быть вашими корневыми соединениями.
Комментарии:
1. Я попробую и дам вам знать, большое спасибо за ваш совет!!!
2. большое вам спасибо, работает как шарм. импортируйте maya.cmds как cmds allParentsList = [] myItems= cmds.ls (тип=’joint’) для элемента в myItems: theParent = cmds.listRelatives(элемент, родительский элемент= True), если cmds.nodeType(родительский элемент) != «joint»: allParentsList.append(элемент) напечатать allParentsList
3. @DienLanLuu Это не работает. Представьте ситуацию, когда у вас есть другой тип объекта, нарушающий цепочку соединений, например:
joint1>>joint2>>group1>>joint3
. Он вернет обаjoint1
иjoint3
вместо onlyjoint1
4. @GreenCell да, это был быстрый скрипт для тестирования того, что посоветовал мне сделать хагги, но теперь с вашей помощью и всеми остальными я заставил его работать. спасибо миллион раз 🙂
Ответ №4:
Я использую этот метод для получения совместной иерархии. Я отказался от попыток найти более сексуальный способ сделать это.
myItems = cmds.ls(selection = True, type='joint')
theParentJnt = cmds.listRelatives(myItems, parent = True)
jntRel = cmds.listRelatives(myItems, allDescendents = True)
allJnt = jntRel myItems
@Green Cell
Ваш метод сработал один раз и больше никогда не работал. Перезапускал maya 2020 более 5 раз и отображает только соединение верхнего узла, больше никогда не возвращает все соединения в одном списке.