CG・コンテンツ制作
SUITE USERS NOTES
Maya2022 Python3対応とツールの更新
Maya2022 Python3 and UpdateTools
プロローグ;Prologue
python3_logo

Maya2022以降のPythonのバージョンが標準になりました。
つまり、今まで動いていた Python(つまりPython2)のツールがMaya2022以降ではそのままでは動かなくなります。

そこで今回はMaya2022をインストールすると備わっているPythonを使ってPython2 から Python3 への移行について、を取り上げてみたいと思います。

ツールを作成している方は、ぜひチャレンジしてみてください!
<多少の前知識は必要かもですが...>

もちろん、Pythonの機能紹介を基本としたページですが、Python3に対応したツールだけをダウンロードして利用することも可能です。

なお、このサイトに掲載している事例の決まり事ですが、使用に関しては自己責任でよろしくお願い申し上げます。

Please use this information as your own risk.

Windows 10 Pro 64bit、Intel Core i7-3930K (3.20GHz,6コア/12スレッド)
メモリ16GB、NVIDIA GeForce RTX 2060 SUPER 8GB


maya_13_ritaro_ml



Maya2022はデフォルトでPython3

AutodeskのドキュメントからもMaya2022 では規定でPython3であることが明記されています。

■ドキュメントMayaのPython新しいウィンドウで開きます(2021年9月21日)

Maya2022.2 のスクリプトエディタを使ってインストールされているPythonのバージョンを調べるには、

import sys
print (sys.version)
#結果 3.7.7 (tags/v3.7.7:d7c567b08f, Mar 10 2020, 10:41:24) [MSC v.1900 64 bit (AMD64)]

と表示され、V3.7.7であることがわかります。

ドキュメントにはPython2モードに切り替えて使用することも可能 と書いてはありますが、
将来のことを考えると、ここはやはりPython3に切り替えていく必要がありそうです。

Python2とPython3の違いについては、既にネット上に詳しく掲載されているページが見つかると思います。
[ python2 python3 違い ] などと検索すると良いでしょう。

このページでは、これまでの実際にMayaで動いていたPython2のスクリプトを、
Maya2022に備わるPythonライブラリーを使ってPython3に移行した作業を具体的に提示していきます。
また、既に公開しているツールについてもPython3版を公開し、引き続き使いたい方が利用出来るようにしておきたいと考えます。

では、はじまりはじまり~。

■ドキュメントPython チュートリアル(日本語 V3.7.10)新しいウィンドウで開きます




2to3ライブラリー

この記事を書いている時点では、Maya V2022.2を使用しています。
再びAutodeskのドキュメントを見ると、

■ドキュメントPython 3に移行する(Maya 2022.2 の新機能)新しいウィンドウで開きますというページが見受けられます。 

ですが、もう少し詳しい情報が知りたい、というところからスタート します。

今度はPythonのドキュメントの方を探りますと、2to3という変換プログラムがあることがわかります。

■ドキュメント2to3 - Python 2 から 3 への自動コード変換(V3.7.10)新しいウィンドウで開きます

Python2 のソースコードを読み込んで、Python3 のコードに変換してくれるらしいことがわかります。
これをMayaのインストールで用意されているPythonで動かせたら自分でPythonを別途インストールしなくても良いのでは、 と考えてみたとします。

ここまで来ても、まだ情報が足りませんね。
MayaのPythonで 2to3 を動かす方法、と、実は変換する種類も複数あることがわかります。

この時点で、大変役に立った英語のページがありました。
HOW TO CONVERT MAYA PYTHON 2 CODE TO PYTHON 3(March 27, 2021)新しいウィンドウで開きますです。

この記事の内容から、Python3に変換する種類と、その起動方法が書かれています。

Python3に変換する種類ですが、ここでは3種類を解説し、でも実はどれも2to3変換プログラム を使っていることがわかります。

その種類とは、2to3、futurize、modernizeです。
違いは、最初の2to3はPython3に変換するだけで下位互換は含まないということで(バックアップファイルは用意出来る)、つまり残りの2つは、下位互換を含んだ変換をする、ということです。

ここのページはこの最初の2to3を取り上げます。
なぜなら、既にPython2で動いているものはそのままで良く、新たに作成するスクリプトはPython3対応のみで良い、としました。
<本音は、下位互換のツールを新たにサポートしたくない、という思いからです。>

さて、先を急ぐ前に、
この2to3はライブラリーはインストールしたMayaのどこにあるのか?を探ると共に、
Python2 の何を Python3 に変換するのかも知ることが出来ます。

まずは2to3はライブラリーですが、以下のディレクトリーにあります。
C:\Program Files\Autodesk\Maya2022\Python37\Lib\lib2to3 そして実際に変換するPythonの構文については、その下の/fixesというディレクトリーの中に各項目毎に別れたファイルとして見ることが出来ます。

python3_003

例えば、大きな変更点の1つに辞書型のdictionaryがありますが、結構使われている構文なのでこれを手動て変換するとなった場合は厄介です。
この/fixes内のfix_dict.pyの中身を見ると、 

d.keys() -> list(d.keys())
d.items() -> list(d.items())
d.values() -> list(d.values())

d.iterkeys() -> iter(d.keys())
d.iteritems() -> iter(d.items())
d.itervalues() -> iter(d.values())

d.viewkeys() -> d.keys()
d.viewitems() -> d.items()
d.viewvalues() -> d.values()

というパターンで、キー/アイテム/バリューをリスト型にキャスト してくれて、従来的な使用方法を実現してくれています。
(Python3では keys/values/items の 「辞書ビューオブジェクト」の ビュー(view*) を返します。
例; dict_keys(['AAA', 'BBB', 'CCC'] )

気になる構文名が この 52個のファイルの中にありましたら、中を覗いてみると、どう変換されるのか見ることが出来ます。




Python3への変換作業

実はPython3に変わることで一番多く引っかかるのはprint文がprint()関数に変わったことです。

print 'AAA'   # Python2
print ('AAA') # Python3

printかっこ()でくくらないといけない、というのは分かっているとして、
このエラーが# エラー: invalid syntax #と出るので、何か大変なミスをしたのではないか!とびっくりする訳です。
しかも御覧の通り、print 関数が原因だと表示してくれません。
この print も2to3が自動で直してくれますので、それを参考にPython3への変換作業をしてみましょう。

まずは、Python2 形式で以下のように書き、example.pyという名前で任意のディレクトリー(例;D:\script)に保存します。
この記述をそのまま Maya2022.2のスクリプトエディタで動かすと、上記エラーが表示されます。

example.py
def greet(name):
print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)

では、先に紹介したWebページに書いてある通り、
コマンドプロンプトからインストールされているmayapy.exeを通して、2to3を起動して変換してみます。

[Windowsボタン]+Rを押して「ファイル名を指定して実行」画面を表示し、cmdと記述して [OK] 押してコマンドプロンプトを表示します。

python3_004

カレントパスを先にファイルを入れたディレクトリーにします。

python3_005

そうしたら、以下のように記述して、実行キーを押します。

"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m lib2to3 --nofix=long -w example.py

すると、数行の実行結果と共に Files that were modified: example.py という表示で終わっていたら完了です。
うまく行かなかった場合は、何かしら異なる表示になっています。

python3_006

上図表示行の先頭に
- が付いている行が元の記述で
+ が付いている行が変換作業によって書き換えられた記述です。

変換後に保存したディレクトリーを見ると、2つのファイルが出来上がります。
example.py   がPython3に変換されたファイル
example.py.bak が元のファイルです。

lib2to3の後にはオプションを設定することが出来、上記例では--nofix=long-wを使いました。
10個以上のオプションがあるのですが、主に使うのは数個です。

-w  --write     付けなければ何も書き出されず、Python3に変換すると何を変換するのかだけを見ることが出来る。
-n  --nobackups バックアップファイル無し。xxx.py.bak というバックアップファイルを作らない。
--nofix=long    変換途中に更なる詳細情報を表示しない、簡素化する。

ちなみに、--helpまたは-hをつけて実行するとオプションの種類と説明を表示してくれます。

python3_008

変換後の内容をMaya2022.2のスクリプトエディタで実行すると、以下のように動きました。

python3_007

この2to3の動かす .py ファイルは、内部の構文だけを見るので、長い行のスクリプトでどこかでうまく行かなかった場合にその前半なのか後半なのかなど、限られた行数で実行してみて不具合箇所を見つけ出すようにも使用出来ます。

Pythonにはもう1つチェック機能を備えたPylintというものがあり、次はこちらを紹介します。
出来あがった .py ファイルを検証したり、うまく行かなかった時に探りを入れたりすることが出来ます。




Pylint によるコードチェック

pylintもMayaをインストールしたライブラリーに存在します。

C:\Program Files\Autodesk\Maya2022\Python37\Lib\site-packages\pylint 内です。

■Pylinthttps://pylint.org/新しいウィンドウで開きます

pylintは、Pythonプログラミング言語のソースコード、バグ、および品質チェッカーであると通常紹介されているのですが、今回のようにPython3に移行する場合にも そのチェック機能が使えます。

Python3に変換する前の example.py を以下のようにpylintに実行させます。

"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m pylint example.py

すると、簡単なE:というエラーとその行数が表示されます。最初に引っかかった行数を表示して止まってしまっています。

python3_010

つまり、2行目の print 文を かっこでくくって修正してから、

def greet(name):
print "Hello, {0}!".format(name)

def greet(name):
print("Hello, {0}!".format(name))

pylintを実行すると、今度は3行目でE:表示します。

python3_011

先に示した通り、print文 は2to3が関数に修正してくれるので、2to3を通した example.pyをpylintにかけると、今度はたくさんの表示と共に、最後の行で Your code has been rated at -2.00/10 のような表記になります。

python3_012

2to3pylintをうまく組み合わせてPython3への変換作業を進めていけると思います。




2to3 実践;CustomOutliner

では、既に配布している CustomOutliner で実際にPython3に変換作業をしてみましょう。

■SUITE UsersNotesMaya 2016~ Python;カスタムアウトライナ

順序立てて手順を書いていきます。

1)スクリプトの用意とMaya2020.3で動作確認

D:\scriptにCustomOutliner.pyを置きます。
一旦、Maya2020.3 のスクリプトエディタに内容をコピーペーストして、最後の行にcustom_outliner()を追記して、 Maya2020.3 で動作するかを確認します。この時点でエラーが出ていたら、先に行っても解決しません。

python3_013

2)2to3を使ってPython3に変換

コマンドプロンプトでD:\scriptをカレントディレクトリにして、以下のように実行しています。 

"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m lib2to3 --nofix=long -w CustomOutliner.py

すると、一カ所のprint文を修正しただけで最後まで通りました。これは非常に簡単な例でした。

python3_014

3)pylint を使ってPython3に変換ファイルを検証

コマンドプロンプトで以下のように実行して出来上がった.pyファイルが本当に動きそうなのかチェックをしてみましょう。
ただし、今回はPython3に対応したかどうかだけをみたいと思うので--py3kというオプションを追加して使用してみます。

--helpで見ると、Python3の出力モードがあり、Python3対応のみを出力する、と書かれています。

python3_015
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m pylint --py3k CustomOutliner.py
python3_016

最後まで表示されていますので、これで Maya2022.2で動くはずです。

4)Maya2022.2 で動作確認

D:\script を見ると、CustomOutliner.py と CustomOutliner.py.bak というバックアップファイルが出来ています。
CustomOutliner.py の中身をMaya2022.2のスクリプトエディタにコピペして、最後の行にcustom_outliner()を追記して起動してみます。

python3_017

はい、起動に成功しました。

次は、2to3を使って対応出来ている いくつかの例を紹介します。




2to3;うまく行く事例

事例話の最初は、2to3 を実行すれば自動でPython3対応の記述に直してくれるものをいくつか取り上げます。
うまく変換されてはいるですが、何を直せるのかは知っておくと、万が一取りこぼしている場合にも対応出来るでしょう。

・print

example.py でも示した通り、プリントするものが代入される関数になっていても、print はとにかくカッコを付けてくれます。

・辞書型(dict)

こちらも/fixesというディレクトリー内に直してくれるファイル群がある、という項目で示した通り、辞書型は直してくれます。
辞書型は複雑に組んでしまっていると、後から見直すのがややこしくなるので、直してくれてありがたいです。
valuesの時、itemsの時、keysの時、valuesの中のitemsの時、などなど。

- all_joints = dict.values()
+ all_joints = list(dict.values())
- for key,value in dict.items():
+ for key,value in list(dict.items()):
- vert = reduce(lambda x,y: x if list[x]<=list[y] else y, iter(dict.keys()))
+ vert = reduce(lambda x,y: x if list[x]<=list[y] else y, iter(list(dict.keys())))
- if tex1 in dict.values():
-     mat1 = [k for k, v in dict.items() if v == tex1]
+ if tex1 in list(dict.values()):
+     mat1 = [k for k, v in list(dict.items()) if v == tex1]
・range

for 文で使う xrange も range に変換されます。

- for i in xrange(len(m_obj)):
+ for i in range(len(m_obj)):
・lambdaのmap

より簡単な for に変換されます。

- sel = map(lambda x: x.encode('ascii'), sel)
+ sel = [x.encode('ascii') for x in sel]
・reload

reload がPython3にありません。で、importlib モジュールの reload を使うのですが、直してくれます。以下例です。

  import base.aaa
- reload(base.aaa)
base.aaa.main()
  import base.aaa
+ import importlib
+ importlib.reload(base.aaa)
base.aaa.main()
・subprocess

import commandsはimport subprocessに変換されます。
この記事を書いている段階で変換しているツールにcommandsモジュールを使ったものが無かったのですが、たまたま置き換わることに気が付きました。

- import commands
+ import subprocess 

こんな感じで、直してくれるものがたくさんあって助かります。(特に初歩のptint文や辞書(dict)だけでも相当助かります。)まだたくさん うまく行く例があると思います。

次は、2to3を使っても対応出来なかったいくつかの例を紹介します。




2to3;うまく行かない事例

pythonの文字列はやっかい事になりました。
特に文字コードの扱いがPython2とPython3では違うのです。
Windowsの実行結果や、ASCII文字以外(全角文字,半角文字でもカタカナ等)などを扱うと以前との違いが出て、エラーになります。
この文字コード扱い部分は2to3で直してくれないと思った方が良いようです。

以下に、簡単な違いを書きましたが、より詳しくは調べてください。

python2
str型はバイト文字列で、Unicode型はユニコード文字列
先頭に u b 無しはバイト文字列

python3
str型はユニコード文字列,
バイト文字列に相当のものは バイト列 bytes型

これによる違いを、たまたま自分のミスから発覚したものも含めて紹介します。

・ASCII文字以外(全角文字)が紛れ込んだ場合

単なる print文なら直してくれるはずなのに、いきなり以下のようなエラーが表示されます。

RefactoringTool: There was 1 error:
RefactoringTool: Can't parse AAA.py: ParseError: bad input: type=5, value='        ', context=('', (84, 0))

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x81 in position 6585: invalid start byte 

ユニコードのデコードエラーが出ているので、どこかの文字列に不具合があります。
で、なかなか気が付かなかった自分のミス、なんと空白が全角文字だったのです。

print 'No object selected'


なんて単純なミスに時間をかけてしまうことに....。

・エンコード指定が逆に災いになる場合

コマンドの結果をエンコード指定して使っていた部分が、以下のようなエラーを出します。

TypeError: file <maya console> line 20: can't concat str to bytes # 

str(ユニコード文字列)にbytes型は結合出来ないと表示しています。
このような表示が出るパターンは幾つもあります。

今回はこのような所に使用していた部分でした。

python3_018

選択したNurbsカーブの色を左右に動かしたスライダー値で変化させる、という部分です。

cmds.colorIndexSliderGrp('icon_color', edit=True,value=set_color_index)
if cmds.ls( sl=True ):
o_selected = cmds.ls(selection = True,objectsOnly=True )[0].encode('utf-8')
cmds.setAttr(o_selected + ".overrideEnabled", 1)
cmds.setAttr(o_selected + ".overrideColor", value) 

これ、直すのはなんてことはありません、エンコード指定をやめれば良いだけです。

o_selected = (cmds.ls(selection = True,objectsOnly=True )[0])

文字列に関する不具合はたくさんありそうなので、気を付けて対処しましょう。

最後は、今まで公開して来たツールを Python3版に対応したものを再公開致します。
ツールだけ使いたい、という方は、最後の部分だけを見ても良いです。




既存ツールのPython3対応版公開

最後に、今まで公開していたPythonツールを更新ついでにPython3に対応したバージョンとして改めてここに公開します。

ツールの設定
Pyファイルはシェルフにボタン登録するか、プルダウンメニューに登録して実行します。

既知の制限・注釈;Maya2022以降のPython3環境でのみ動作確認

ツィッターウェア(twitter ware)@SI_UsersNotes新しいウィンドウで開きます
あくまでも自己責任でお使いください。 Use as your own risk.

ツール名 情報公開URL ダウンロード(Zip)
起動コマンド
CustomGraphEditor カスタム・グラフエディタ
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_02/
CustomGraphEditor_V30.zip
custom_graph_editor()
CustomSideGraphEditor カスタム・グラフエディタ
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_02/
CustomSideGraphEditor_V40.zip
custom_side_graph_editor()
CustomHyperGraph カスタム・ハイパーグラフ
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_06/
CustomHyperGraph_V5.0.zip
custom_hypergraph()
CustomOutliner カスタムアウトライナ
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_11/
CustomOutliner_V4.0.zip
custom_outliner()
Custom_UV_Editor カスタムUVエディタ
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_12/
Custom_UV_Editor_3.0.zip
custom_uv_editor()
ri_rig_icons Rig用 ICON
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_07/
ri_rig_icons_V2.0.zip
ri_rig_icons_menu()
ri_set_joint_size Jointサイズ変更ツール
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_05/
ri_set_joint_size_V2.0.zip
set_joint_size_menu()
constraint_table Pythonで表の作成と書き込み/読み込みツール
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_09/
constraint_table_V2.0.zip
constraint_table_menu()
ri_custom_objectviewer カスタムオブジェクトビューア for Maya
https://www.comtec.daikin.co.jp/DC/UsersNotes/Ritaro/tutorial/maya_13/
ri_custom_objectviewer_V2.0.zip
object_view_menu()

次回もMayaかも?・・・
乞う、ご期待!! Stay tuned ..

戻る

Twitter

ページの先頭へ