LoginSignup
0
0

More than 1 year has passed since last update.

【ArtistでもMELが書きたい】Maya MEL入門(8)【ls】

Last updated at Posted at 2023-02-04

はじめに

この記事は、3DCG業界で働くArtist向けのMEL入門記事です。
普段の業務を効率化したいけど、MELの書き方が分からない、調べたけどイマイチ分からなかった、そんな方向けに書きました。
本記事は「lsコマンドを使う」をゴールとします。

環境

Autodesk Maya 2022.2

前回のあらすじと今回へのつなぎ

前回は変数を使いました。変数を使えるようになった今では、MELで実行できる幅が格段に広がったのではないでしょうか?
さて、今回はlsコマンドを学んでいきます。変数をふんだんに活用するlsコマンドはMELのなかでもかなり重要なコマンドになります。一つずつしっかりと確認していきましょう。

lsコマンドの概要

lsというのはListの略です。
リストアップとよく言いますよね。
lsコマンドの主な挙動としては、「フラグで指定したものを配列型で返す」です。

配列型とはなんぞや?

int, float, stringに続く新しい型になります。
しかし今までの型とは少し毛色が違います。
まずは初期化する場合の文法を見ていきましょう。

型名 $変数名[要素数] = {要素0, 要素1, 要素2、...}

実際のMELだと下記です。

string $cubeNames[3] = {"CubeA", "CubeB", "CubeC"};

配列型は、実直に言ってしまえば、ある型の値を複数個保持できる型です。
上記の変数cubeNamesはstring型の値を三つ保持しています。
保持できる値のことを要素といい、その数を要素数といいます。

配列型を使ってみる

実際に使ってみるのが一番理解がはかどります。
配列型を活用して、CubeA、CubeB、CubeCを生成するMELを書いてみます。

string $cubeNames[3] = {"CubeA", "CubeB", "CubeC"};
polyCube -name $cubeNames[0];
polyCube -name $cubeNames[1];
polyCube -name $cubeNames[2];

まずは実行して確認しましょう。
MEL_learning01.png
MEL_learning02.png
うまくいきました。
より詳細な文法を見ていきましょう。

配列型の文法

まず、初期化時の文法ですが、

string $cubeNames[3] = {"CubeA", "CubeB", "CubeC"};

上記は当然OKですが、実は、

string $cubeNames[] = {"CubeA", "CubeB", "CubeC"};

こちらの記法でもOKです。変数宣言の要素数を省略できるんですね。

初期化が終わったら、次は使用法です。

配列は一つの変数の中に複数個の値を保持しています。なので実際に-nameフラグ用の値を適用する際には、変数cubeNamesどの値を使うのかを指定する必要があります。

polyCube -name $cubeNames[0];

指定自体はシンプルで、変数名の後ろに[]をつけ、[]内に使いたい要素の順番を書きます。
この要素の順番のことを添字といいます。
上記だと変数names中の添字が0の要素を使う、ということになります。

一つ注意なのはこの順番は、1からのスタートではなく、0からのスタートだということです。
要素数が3の配列は、添字は、0, 1, 2となります。
1, 2, 3ではないので、十分に気をつけてください。

間話 printコマンド

突然ですが、「変数の中身は今はこれがこうで...」と考えるのって少し大変じゃありませんか?
変数の中身を確認することができれば多少は楽ができそうです。
そして、便利なことにそんなコマンドが存在します。

print()

printコマンドといいます。
使い方としては、printコマンドの後ろの()に変数を入れるだけです。

float $pi = 3.14;
print($pi);

早速実行してみましょう。
MEL_learning03.png
printの結果はログで確認ができます。
MEL_learning04.png
3.14と表示されています。
このように変数の中身を見たりして、プログラムが正常かを確認することをデバッグといいます。
とりわけ、printでデバッグすることをprintデバッグと呼んだりします。

「この書き方で合ってるはずだけど、何故か上手く動かない」というときは、変数の中身をprintで確認してみましょう。
出力されたログをもとに、ミスが見つかるかも知れません。

lsコマンドを使ってみる

便利なprintを学んだところで、本題のlsコマンドを実際に使ってみましょう。
今回は選択したオブジェクトたちを取得するMELを書いてみます。

string $selectionObjs[] = `ls -selection`;
print($selectionObjs);

lsコマンドは「フラグで指定したものを配列型で返す」コマンドでしたね。
MELコマンドリファレンスlsコマンドのフラグから、-selectionフラグの効果を見てみましょう。
MEL_learning05.png
選択したオブジェクトがリストアップできそうですね。

実行前に、適当なオブジェクトをシーンに並べましょう。
あとは、それらを選択した状態にしておきます
MEL_learning06.png
MEL_learning07.png
それでは実行していきましょう。
MEL_learning08.png
MEL_learning09.png
無事に四つのオブジェクト名がログに表示されています。

MEL実践

せっかくlsコマンドを使用できるようになったので、前回作った、

float $cubeATranslateX = `getAttr "CubeA.translateX"`;
float $cubeATranslateY = `getAttr "CubeA.translateY"`;
float $cubeATranslateZ = `getAttr "CubeA.translateZ"`;

setAttr "CubeB.translateX" $cubeATranslateX;
setAttr "CubeB.translateY" $cubeATranslateY;
setAttr "CubeB.translateZ" $cubeATranslateZ;

このMELをパワーアップしてみましょう。

「パワーアップもなにも、このままでもいいじゃん」を思う方がいるかもしれません。ですがよく考えてみてください。このMELはオブジェクト名が「CubeA」と「CubeB」でしか正常に動作しないのです。
このままでは汎用性がありませんよね。

しかしlsを使えば現在選択しているオブジェクトを取得できるので、少なくとも「CubeA」と「CubeB」でしか動かないなんてことは回避できそうです。

それではまず、MEL作りの計画から始めましょう。
動作要件としては、「一番目に選択したオブジェクトの位置を二番目に選択したオブジェクトの位置に合わせる」でやってみます。
今回はわかりやすさ重視のため、シーン上にはCubeとConeを用意します。
MEL_learning10.png
一番目にCube、二番目にConeを選択し、MELを実行すると、Cubeの位置がConeの位置と同じになればOKということにします。

まずは、移動するオブジェクト(一番目に選択したオブジェクト)と、移動先のオブジェクト(二番目に選択したオブジェクト)を取得してみます。
lsコマンドにおいて、選択した順番と配列に格納される順番の関係性はわかりませんが、一旦選択した順番でオブジェクトが格納されている想定でMELを書いてみましょう。
printも活用して、配列の中身を見てみます。

string $selectionObjs[] = `ls -selection`;
string $firstSelectionObj = $selectionObjs[0];
string $secondSelectionObj = $selectionObjs[1];
print($firstSelectionObj);
print($secondSelectionObj);

MEL_learning11.png
MEL_learning12.png

pCube1pCone1

ログを見ると、CubeとConeの名前は取れているようですが、改行されていません。
実は、printでは意図的に改行しない限り改行はされません。
改行を表す\nを間に挟んで、再度実行してみましょう。
MEL_learning13.png
MEL_learning14.png
うまくいきましたね。

改行に気を取られていましたが、選択した順番で配列に格納されている予想は当たっていましたね。このまま作業を続けていきましょう。

オブジェクトが取得できているので、後は位置を取得・設定する処理と合体するだけで完成になりますね。
しかしここで一つ問題があります。getAttrコマンドに「"オブジェクト名.アトリビュート名"」という形式の文字列を渡す必要がありますが、オブジェクト名は現在変数で用意しています。どうすればいいのでしょうか?

float $cubeATranslateX = `getAttr $secondSelectionObj".translateX"`;

無理あり当て込んでみてもエラーが出るようです。
MEL_learning15.png

間話 文字列の結合

実は文字列は+を使うことで結合することができます。

string $firstName = "my";
string $secondName = "Cube";
string $combinedName = $firstName + $secondName;
polyCube -name $combinedName;

MEL_learning16.png
MEL_learning17.png
ちなみに()で囲いさえすれば、コマンド内でも結合することができます。

string $firstName = "my";
string $secondName = "Cube";
polyCube -name ($firstName + $secondName);

MEL実践(2)

文字列の結合法がわかれば後は書くのみです。

string $selectionObjs[] = `ls -selection`;
string $firstSelectionObj = $selectionObjs[0];
string $secondSelectionObj = $selectionObjs[1];

float $secondTranslateX = `getAttr ($secondSelectionObj + ".translateX")`;
float $secondTranslateY = `getAttr ($secondSelectionObj + ".translateY")`;
float $secondTranslateZ = `getAttr ($secondSelectionObj + ".translateZ")`;

setAttr ($firstSelectionObj + ".translateX") $secondTranslateX;
setAttr ($firstSelectionObj + ".translateY") $secondTranslateY;
setAttr ($firstSelectionObj + ".translateZ") $secondTranslateZ;

一番目にCubeを、二番目にConeを選択して、
MEL_learning10.png
実行してみましょう。
MEL_learning19.png
MEL_learning18.png
やりました!大成功です!
これはかなり実践的なMELが書けたのではないでしょうか?

おわりに

いかがでしたか?配列型にlsコマンドにと大ボリュームでしたね。
新しい要素は読むだけ理解するだけ、ではなく、実際にスクリプトを書いて、体験して覚えるのが上達の近道です。
実際にスクリプトを書くと、本記事では説明していない文法やエラーに当たってしまうこともあるかと思います。そんなときでも一つずつ落ち着いて原因を探し出し、時にはインターネットの情報も駆使して、解決を目指してみてください。
そしてうまくMELが動いたときには存分に達成感に浸ってください!

次回はこちら→【ArtistでもMELが書きたい】Maya MEL入門(9)

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0