初めてのコマンドプラグイン

#**概要**

Mayaコマンドプラグインについて初学者向けの内容を記載しています。

- コマンドプラグインとは何なのか？
- コマンドプラグインはどう使えそうなのか？
- どういった参考記事があるのか？

##モチベーション

コマンドプラグインってあまり情報を見かけませんよね。
そういえば自分も全く使ってないなぁと…
ということで自分自身も対象にした入門記事を書こうという狙いです。
とにかくMayaPythonに関する記事を増やそうかなということで内容は軽めです。

#**コマンドプラグインとは？**

[公式ヘルプ](http://help.autodesk.com/view/MAYAUL/2016/JPN/?guid=__files_GUID_A9FA6DEF_4E48_45A7_AC65_A69E8A55F62D_htm)にはこのように書いてあります。
>新しいカスタム MEL コマンドを定義して、それに応じて
>maya.cmds Python モジュールに関数を追加してスクリプトで使用できるようにします。

要するに自作したPythonモジュールがcmdsから直接呼び出せるということですね。

#**cmds.ls(sl=True)するコマンドプラグイン**

とにかく書いて使ってみるのが手っ取り早い。
ということで、cmds.ls(sl=True）の機能をコマンドプラグインで書いてみます。
[Maya ヘルプ](http://help.autodesk.com/view/MAYAUL/2016/JPN/?guid=__files_GUID_85B1116E_F0C1_42AD_9CD4_30E936B6C7B8_htm)を参考に（というかコピペして）したのが下記のコードです。


```python:command_select.py
# -*- coding: utf-8 -*-
import maya.api.OpenMaya as OpenMaya


def maya_useNewAPI():
    pass

class CommandSelection(OpenMaya.MPxCommand):
    kPluginCmdName = "selection"

    def __init__(self):
        OpenMaya.MPxCommand.__init__(self)

    @staticmethod
    def cmdCreator():
        return CommandSelection()

    def doIt(self, args):
        self.setResult(list(OpenMaya.MGlobal.getActiveSelectionList().getSelectionStrings()))
 
def initializePlugin(mobject):
    plugin = OpenMaya.MFnPlugin(mobject)
    plugin.registerCommand(CommandSelection.kPluginCmdName, CommandSelection.cmdCreator)

def uninitializePlugin(mobject):
    pluginFn = OpenMaya.MFnPlugin(mobject)
    pluginFn.deregisterCommand(CommandSelection.kPluginCmdName)
```

```python:command_select_doit.py
cmds.selection()
>>> # Result: [u'pPlane2', u'pPlane1'] # 
```
##コードの内容
### *戻り値について*
コマンドの戻り値は return文 じゃないんですね！（先入観が）
[ヘルプ](http://help.autodesk.com/view/MAYAUL/2017/JPN/?guid=__files_Command_plugins_Returning_results_to_MEL_htm)を調べると setResult()だと書いてありますので doIt()で呼び出しています。

ちょっと改良しようと思って独自クラスを setResult()しようとしたところ、
`# Command results must be string or numeric.` とエラーが発生。
他の親クラスの場合を調べていませんが、コマンドプラグインでは文字列か数値しか返せないんでしょうかね。

### *親クラスについて*
>**MPx** というプリフィックスが付けられたクラスはプロキシ クラスと呼ばれ、
>さまざまなプラグイン タイプを作成するために使用されます。

ということで他にどんなクラスがあるのか[リファレンス](http://help.autodesk.com/view/MAYAUL/2016/JPN/?guid=__py_ref_class_open_maya_1_1_m_px_command_html)を見てみました。
作りたいプラグインに合わせてどの親を継承するか？さらなるお勉強が必要ですね。

| Class                     |Description|
|:--------------------------|:-------------------------------------------------------------|
| MPxAttributePatternFactory|Base class for custom attribute pattern factories.|
| MPxCommand|Base class for custom commands.|
| MPxData|Base Class for User-defined Dependency Graph Data Types.|
| MPxGeometryData|Base Class for User-defined Dependency Graph Geometry Data Types.|
| MPxGeometryIterator|Base class for user defined geometry iterators.|
| MPxNode|Base class for user defined dependency nodes.|
| MPxSurfaceShape|Parent class of all user defined shapes.|


#**感想**
非常によく使いそうな処理はコマンドプラグインにしておくとコード量が減って楽になるかも。
MELコマンドとしても使えるのでMELerなアーティストにも便利なのかもしれないですね。
多方面からのツッコミやアドバイスも待ちつつ、追加のお勉強をしていきたいと思います。


#**参考サイト**

- [Digital Matrix 簡単なプラグイン](http://www.not-enough.org/abe/manual/maya-python-aa08/commandPlugin.html)
- [Digital Matrix 選択されたノードを調べるコマンド](http://www.not-enough.org/abe/manual/api-aa09/selectionList.html)
- [Autodesk Knowledge Network: コマンド プラグイン](https://knowledge.autodesk.com/ja/support/maya/learn-explore/caas/documentation/MAYAUL/2014/JPN/Maya-API-Documentation/files/Command-plugins-htm.html)