Получите флаги параметров и значения по умолчанию для команды Maya

Я пытаюсь получить флаги и значения по умолчанию для любой данной команды Maya. В python я бы обычно использовал модуль проверки, но поскольку pymel — это всего лишь оболочка, я не вижу здесь такой возможности. Я надеялся, что у API будет что-то, что могло бы это сделать, но ничего не наткнулся. Ниже приведен подход гетто, который работает в этом случае использования, но он хакерский и должен быть значительно изменен, чтобы действительно работать для всех команд (это не дорога, по которой я хочу путешествовать):

def getMayaCmdFlagDefaults(cmd):
    '''Get the flags and corresponding default values of a given MEL command.

    :Parameters:
        cmd (str) = A MEL command name.

    :Return:
        (dict) {'flag':<value>}
    '''
    obj_types = ['polyPlane', 'nurbsPlane'] #etc..

    for obj in obj_types:
        try:
            temp = getattr(pm, obj)(ch=0)
            node = getattr(pm, cmd)(temp)
            if node:
                result = Init.getAttributesMEL(node[0])
                pm.delete(temp)
                return result

        except Exception as error:
            print ('# Error: {}: {} #'.format(cmd, error))
            pm.delete(temp)


print (getMayaCmdFlagDefaults('polyReduce'))
# returns: {u'keepQuadsWeight': 0.0, u'symmetryPlaneW': 0.0, u'symmetryPlaneZ': 0.0, u'symmetryPlaneX': 0.0, u'symmetryPlaneY': 0.0, u'sharpness': 0.0, u'keepBorderWeight': 0.5, u'vertexMapName': None, u'vertexWeights': None, u'border': 0.5, u'keepBorder': True, u'triangleCount': 0, u'keepHardEdgeWeight': 0.5, u'keepCreaseEdge': True, u'percentageAchieved': 0.0, u'keepColorBorder': True, u'version': 0, u'triangleCountIn': 200, u'percentage': 0.0, u'keepMapBorderWeight': 0.5, u'useVirtualSymmetry': 0, u'keepColorBorderWeight': 0.5, u'symmetryTolerance': 0.0, u'geomWeights': 1.0, u'detail': 0.5, u'invertVertexWeights': True, u'keepHardEdge': True, u'keepCreaseEdgeWeight': 0.5, u'uvWeights': 0.0, u'vertexCount': 0, u'termination': 0, u'line': 0.5, u'weightCoefficient': 10000.0, u'vertexCountIn': 121, u'keepFaceGroupBorderWeight': 0.5, u'keepMapBorder': True, u'vertexCountAchieved': 0, u'keepFaceGroupBorder': True, u'triangulate': True, u'cachingReduce': False, u'weights': [], u'compactness': 0.0, u'vertexWeightCoefficient': 1.0, u'triangleCountAchieved': 0, u'keepOriginalVertices': False, u'symmetryPlane': (0.0, 0.0, 0.0, 0.0), u'colorWeights': 0.0, u'preserveTopology': True}

Используя Inspect (на сегодняшний день предпочтительный метод):

print (inspect.getargspec(pm.polyReduce))
# returns: ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)

print (inspect.getargspec(cmds.polyReduce))
# returns: TypeError: <built-in method polyReduce of module object at 0x000002B30DDE3078> is not a Python function

# Additional things of interest that I have tried:
# backport of inspect.signature for python 2.6+:
import funcsigs
bound_args = funcsigs.signature(pm.polyReduce)

# unwrap a decorated method:
def extract_wrapped(decorated):
    closure = (c.cell_contents for c in decorated.__closure__)
    return next((c for c in closure if isinstance(c, FunctionType)), None)

person m3trik    schedule 29.12.2020    source источник


Ответы (1)


Проблема в том, что команда не предоставляет эту информацию. Вы должны понимать, что модуль cmds именно так и называется; ряд команд для заполнения/управления сценой. Фактические значения по умолчанию встроены в фактический класс узла через его атрибуты.

На самом деле команда представляет собой функцию, которая вызывает специальный класс (MPxCommand), и ее задача состоит в том, чтобы анализировать аргументы, которые вы передаете в mel/python, и что-то делать с этими аргументами.

Например, cmds.polyPlane принимает ряд переданных ему параметров и либо создает/изменяет узел, либо, по сути, обертывает его, поэтому это невозможно. Без каких-либо параметров обычно создается экземпляр этого объекта в вашей сцене. Значения по умолчанию исходят из класса самого полиплана, а не из функции cmd.polyPlane, использованной для его создания. Когда вы передаете аргументы cmds.polyPlane для изменения его свойств, команда просто создает полиплан, а затем изменяет его атрибуты... явно!

Я думаю, что вам нужно cmds.attrInfo. Проверьте его документацию. Там они приводят пример, который может помочь вам начать работу. Вы были на правильном пути...

Хорошей новостью является то, что эти данные необходимо проанализировать один раз (значения атрибутов объекта по умолчанию не изменятся, пока приложение не перейдет на новую версию). Если у вас есть сценарий, который создает, а затем проверяет узел с помощью cmds.attrInfo, вы можете сбросить эту информацию в файл и впоследствии прочитать файл, когда вам понадобится эта информация.

Например, вы можете создать простой текстовый файл или файл json со списком узлов, которым вы хотите расставить приоритеты, и запустить сценарий, который считывает список узлов, создает каждый узел, анализирует информацию о его атрибутах и ​​выгружает эти данные в отдельный текстовый или json-файл, который вы сможете прочитать позже. Если вам нужна информация о дополнительных узлах, просто обновите прежний файл с новыми именами узлов, запустите свой скрипт, который обновит последний файл. Начните с малого и изменяйте по мере необходимости.

person Claudio Alvaro    schedule 03.02.2021
comment
Спасибо за ваше время. У меня было смутное понимание, но это действительно прояснило ситуацию. Когда я в последний раз работал над этим, я использовал json для принуждения различных типов данных к строковым значениям и из них в таблице sql, так что в основном та же идея. У Maya есть некоторые типы данных, с которыми json не знает, что делать, но я полагаю, что это не будет слишком большой проблемой для обхода. - person m3trik; 04.02.2021