Cet article est un article du 20 décembre du Calendrier de l'Avent Maya-Python 2016.
Dans maya.cmds, vous pouvez écrire l'indicateur à passer à la commande de deux manières: ** notation de nom court ** et ** notation de nom long **. Par exemple, si vous utilisez la commande maya.cmds.optionMenu pour écrire des processus avec la même signification en notation de nom court et en notation de nom long, cela ressemblera à ceci.
#Notation de nom court
cmds.optionMenu(name, en=True, l="top_node:",
vis=True, ann=u"Sélectionnez le nœud supérieur", w=200,
cc=partial(self.change_topnode, name))
#Notation de nom long
cmds.optionMenu(name, enable=True, label="top_node:",
visible=True, annotation=u"Sélectionnez le nœud supérieur", width=200,
changeCommand=partial(self.change_topnode, name))
La notation de nom court rend le code plus compact, donc il peut être préférable pour ceux qui y sont habitués. Cependant, pour les débutants de maya.cmds comme moi, chaque fois qu'un indicateur de nom court apparaît lors de l'héritage ou de la révision du code écrit par quelqu'un d'autre, [Autodesk Maya Python Command Reference](http: // aide) .autodesk.com / cloudhelp / 2016 / JPN / Maya-Tech-Docs / CommandsPython / index.html) est inefficace.
Par conséquent, cette fois, nous allons créer un script qui remplace l'indicateur de notation de nom court par la notation de nom long à la fois.
Le fonctionnement du programme a été confirmé dans l'environnement suivant.
Seul un module externe appelé astor est requis, donc installez-le avec pip.
pip install astor
AST (Abstract Syntax Tree) est utilisé pour analyser et remplacer les noms de paramètres utilisés lors de l'appel de la fonction maya.cmds. Avec le module ast inclus dans le standard python, vous pouvez obtenir un AST simplement en analysant le code que vous souhaitez analyser.
import ast
if __name__ == '__main__':
example = """def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, q=True, v=True)
return 0
"""
tree = ast.parse(example)
print ast.dump(tree)
Lorsque le programme ci-dessus est exécuté, le résultat suivant sera affiché.
Module(body=[FunctionDef(name='fake', args=arguments(args=[Name(id='x', ctx=Param())],
vararg=None, kwarg=None, defaults=[]), body=[Import(names=[alias(name='maya.cmds',
asname='cmds')]), Expr(value=Call(func=Attribute(value=Name(id='cmds', ctx=Load()),
attr='optionMenu', ctx=Load()), args=[Name(id='name', ctx=Load())],
keywords=[keyword(arg='q', value=Name(id='True', ctx=Load())), keyword(arg='v',
value=Name(id='True', ctx=Load()))], starargs=None, kwargs=None)),
Return(value=Num(n=0))], decorator_list=[])])
C'est un peu long et difficile à lire, mais ici
Il est important que vous puissiez obtenir des informations sur la région. En d'autres termes, vous pouvez voir quelle commande dans maya.cmds est exécutée avec quel argument indicateur.
Maintenant que nous savons que nous pouvons utiliser AST pour savoir si la notation de nom court est utilisée dans le code, l'étape suivante consiste à obtenir la table de correspondance entre la notation de nom court et la notation de nom long dans chaque maya.cmds. Si vous passez le nom de la commande à maya.cmds.help (), elle renverra la notation du nom court et la notation du nom long comme indiqué ci-dessous.
import maya.cmds
print(maya.cmds.help("optionMenu"))
-----------------------------------------------------
emballer: optionMenu [flags] [String]
Flags:
-e -edit
-q -query
-acc -alwaysCallChangeCommand
-ann -annotation String
-bgc -backgroundColor Float Float Float
-cc -changeCommand Script
...(réduction)
Générez dynamiquement un dict avec la notation du nom court comme clé et la notation du nom long comme valeur à l'aide d'expressions régulières.
help_regex.py
method_name_dict = {}
help_messages = cmds.help(method_name)
method_name_dict[method_name] = {}
for line in help_messages.split(os.linesep):
arg_names = re.search(r"-([a-zA-Z0-9]+) -([a-zA-Z0-9]+)", line)
if arg_names:
method_name_dict[method_name][arg_names.group(1)] = arg_names.group(2)
Vous pouvez créer un objet dict comme celui-ci
[('optionMenu', {u'en': u'enable', u'cc': u'changeCommand', u'm': u'manage', u'ann': u'annotation', ...(réduction)
Cependant, la commande maya.cmds.help () doit être exécutée dans l'environnement d'exécution python de maya. (Normalement, fonctionner avec python aaa.py ne renvoie rien)
Pour Mac
/Applications/Autodesk/maya2015/Maya.app/Contents/bin/mayapy
Pour les fenêtres
C:\Program Files\Autodesk\Maya2015\bin\mayapy.exe
Il y a mayapy autour, donc si vous exécutez un programme python avec lui, vous obtiendrez le résultat de la commande help ().
/Applications/Autodesk/maya2015/Maya.app/Contents/bin/mayapy aaa.py
Vous êtes maintenant prêt à remplacer le nom court par le nom long.
Utilisez NodeTransformer pour vérifier, remplacer ou supprimer chaque élément de l'AST. Par exemple, si vous voulez faire quelque chose sur le nœud d'appel de fonction (Call) comme cette fois, définissez la fonction visit_Call (self, node) et écrivez le processus.
class MayaPythonShort2LongNameNodeTransformer(ast.NodeTransformer):
def visit_Call(self, node):
#J'écrirai le processus de remplacement ici
Après avoir remplacé le nom du drapeau par NodeTransformer, revenez enfin au code python avec astor.to_source ().
print(astor.to_source(tree).decode("unicode-escape"))
Le code suivant est un résumé approprié du traitement ci-dessus.
maya_cmds_name_converter.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
import os
import re
import ast
import astor
import maya.standalone
import maya.cmds as cmds
class MayaPythonShort2LongNameNodeTransformer(ast.NodeTransformer):
def __init__(self):
self.method_name_dict = {}
@staticmethod
def is_maya_cmds_func(node):
return hasattr(node, "func") and hasattr(node.func, "value") and hasattr(node.func.value, "id") and \
node.func.value.id == "cmds"
def visit_Call(self, node):
if self.is_maya_cmds_func(node):
method_name = node.func.attr
if not self.method_name_dict.get(method_name):
# short_nom et long_Créer un dict correspondant pour le nom
try:
help_messages = cmds.help(method_name)
except RuntimeError:
# print(u"help()Est une commande non prise en charge: " + method_name)
return node
self.method_name_dict[method_name] = {}
for line in help_messages.split(os.linesep):
arg_names = re.search(r"-([a-zA-Z0-9]+) -([a-zA-Z0-9]+)", line)
if arg_names:
self.method_name_dict[method_name][arg_names.group(1)] = arg_names.group(2)
for keyword in node.keywords:
if keyword.arg in {"q", "e", "c", "m"}:
#Ignorer si drapeau de base
continue
long_name = self.method_name_dict[method_name].get(keyword.arg)
if long_name:
if long_name == "import":
#Dans ce cas, ça devient étrange comme python
continue
# print(keyword.arg + u"À" + long_name + u"Convertir en")
keyword.arg = long_name
return node
if __name__ == '__main__':
maya.standalone.initialize(name='python')
#Exemple de code pour les tests
example = """def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, en=True, l="top_node:",
vis=True, ann=u"Sélectionnez le nœud supérieur", w=200,
cc=partial(self.change_topnode, name))
return top_node
"""
tree = ast.parse(example)
tree = MayaPythonShort2LongNameNodeTransformer().visit(tree)
# after convert python code
print(astor.to_source(tree).decode("unicode-escape"))
if float(cmds.about(v=True)) >= 2016:
maya.standalone.uninitialize()
Lorsque ce programme est exécuté, la commande de l'indicateur de notation de nom court introduit au début est remplacée par la notation de nom long et la sortie.
Avant le remplacement
def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, en=True, l="top_node:",
vis=True, ann=u"Sélectionnez le nœud supérieur", w=200,
cc=partial(self.change_topnode, name))
return top_node
Après remplacement
def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, enable=True, label='top_node:', visible=True, annotation=u'Sélectionnez le nœud supérieur', width=200, changeCommand=partial(self.change_topnode, name))
return top_node
Cela semblait fonctionner, mais après ast.parse le code python, lorsque je le reconvertis en code python avec astor.to_source (), je perds beaucoup d'informations de formatage.
--u "" "Ceci est une chaîne de documentation" "" est tout u \ Ceci est une chaîne de documentation \
Donc, après avoir effectué le remplacement du nom court -> nom long, je le nettoie séparément avec AutoFormatter / suppression / remplacement d'avertissement avec PyCharm. ..
Si vous vous y habituez, la notation du nom court peut être plus facile à écrire et à lire, mais je ne me souviens toujours pas du grand nombre d'indicateurs contenus dans maya.cmds.
Maintenant que nous savons que l est label et v est value, je pense que c'est une bonne idée de décider des règles pour les noms de drapeau en fonction de la compétence de l'équipe impliquée dans le code. Si c'est un drapeau qui semble rarement utilisé, vous pouvez comprendre la signification en regardant le nom long, mais s'il s'agit d'un nom court, il sera certainement envoyé comme référence de commande, alors soyez prudent.
bsp -> beforeShowPopup npm -> numberOfPopupMenus vcc -> visibleChangeCommand Et.
Recommended Posts