💨

オブジェクトを等間隔に並べるのとかめんどいよね。そんなときはチャンネルボックスを alt + 右クリックだ。

4 min read

「Dashスクリプト」 っていうらしいです。


課題

オブジェクトを等間隔に並べて見てみたいときがたまにあります。複数メッシュが1アセット扱いになってるシーンを開いたときとか。

重なったオブジェクトの例
▲重なったオブジェクトの例

手作業でちまちま並べてももちろん問題ありません。重なってるオブジェクトが5とか10ならそれでいい気がします。
でも100とかなら困りますし、気持ち的に10でもイヤだっていうときもあるでしょう。

そんなときに、この機能を使います。

Dash

DashはMashの機能の一部だそうです。
なので、使うときにはプラグインエディタでMashが有効になっていることを確認します。

今回の課題「重なったオブジェクトをパパッと並べる」を達成するためには、下記の手順を行います。

  1. 複数オブジェクトを選択
  2. チャンネルボックスのTX辺りを「alt」+右クリック
  3. 小さな入力欄が現れるので、「l(20)」 などと入力
  4. すると、オブジェクトがTX=20までの距離で等間隔に配置される

20は等間隔配置される最大値で、TX=20までの間で均等に値が入力されます。
20ではなく100にしても10000にしても、いい具合に等間隔にしてくれます。

20など 整数 で入力すると、アトリビュートに入力される値も整数に丸められます。(上の例も、l(20)と入力しているのに最大値が18とかになっているのはそういうわけです)
20.0とすれば、小数で割られます

階段

TY方向とか、RY回転とかにも値を入れられます。
ので、階段も作れます。

y回転の例

これは螺旋階段です(強弁)
Duplicate Specialだと同じ形状で作られちゃいますが、こちらは同一形状じゃなくても作れます。

適当に配置したい

「ばらばらに配置したいですー」
という要望は、テクニカルな相談で定期的に上がる定番の話題です。
でも、ツールを追加で作らなくても元からできるんですよ。 そう、Dashを使えばね!

r(-20.0,20.0)

TYは0のままにしておけば、平らにばらばらに配置

Autodeskさんはもっとこれ喧伝してもいいと思うの。

スクリプト

DashはMayaインストールフォルダにソースが置いてあります。
「alt」+ 右クリック じゃなくても、スクリプト的に呼び出すこともできます。

import DashLegacy;DashLegacy.showDash('mainChannelBox')

これを実行すると、チャンネルボックスじゃなくてもカーソルのある位置にDash入力欄を召喚することができます。
だからなんだというとあれですけど。
'mainChannelBox' のあたりは、ほかの入力欄に対応させたりいじり甲斐がありそうです。

拡張してみる

インストールフォルダにはソースが置かれているので、それを加工することもできます。
たとえば、
先ほど試したランダム配置ですが、
まるで最大値、最小値の「-20~20」の範囲が見えるような、四角い範囲に配置されます。そこはそういうものなので仕方ない。
Pythonのrandomモジュールには それ以外の乱数生成 も用意されているので、
それを呼び出せるようにしてみましょう。

https://docs.python.org/ja/2.7/library/random.html

MASHが置かれている場所はこのへんだったはず

getenv "MASH_LOCATION"

具体的には、「DashCommand.py」に処理内容を書き、「Dash.json」に呼び出し方を登録します。

DashCommand.pyにdashGauss関数を追加
# dashRandom 関数をコピーして関数名かえたやつ
def dashGauss(*args):
    selectedObjs = cmds.ls(selection=True)
    selectedChannels = getAllSelectedChannels()

    numArgs = len(args)
    result = 0
    for obj in selectedObjs:
        for chan in selectedChannels:
            if numArgs == 1:
                result =  random.uniform(0,args[0])
            elif numArgs == 2:
		# ポイントはここ
                mu = args[0]
                sigma = args[1]
                result =  random.gauss(mu,sigma)
            else:
                result =  random.random()

            cmds.setAttr(obj+"."+chan, result)
Dash.jsonに書き足した内容
{"MayaExec": "import DashCommand", "MayaEval": "DashCommand.dashGauss", "DashCommand": "gauss", "ShortDashCommand": "g", "Description": "Quick redirect to Python's random.gauss()"},

実行すると、こんな感じです。

いかにも乱雑な感じで配置されました!
(「え~もうちょい重ならないようにできないの~?」っていうフィードバックまでがワンセット)

なにかチャンネルボックスに入力する内容であれば、ほかにもDash拡張で便利にできるかもしれません。
いろいろ試してみてください!

注意点として、
中身はただforでsetAttr回してるだけというシンプルなものなので(シンプルだから拡張も気楽でいいんですけど)
内容によっては 簡単に重くなっちゃう かもしれないです。よしなに処理してください。

公式ドキュメント

ここでは「l()」「r()」と拡張した「g()」を紹介しましたが、
ほかにもあるのでご確認・ご活用ください。

https://help.autodesk.com/view/MAYAUL/2020/JPN/?guid=GUID-94DA2210-6FF1-4993-8EB9-9A6D87562D35

明日

明日12/05のアドカレは、 harker さんの「Maya上でクラスタ分析 (K-means 法)を使ってグループ分けする」です。
おたのしみに!

https://qiita.com/advent-calendar/2020/maya