【Maya】複数の頂点を指定の座標に移動させるMEL

## はじめに
MELについてちょっと勉強したので、自分用メモですが、
自分的に案外使えたので、良ければ使ってみてください！
（MELあんまり詳しくないので、使用する際は自己責任でお願いします...）

## したいこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1393871/b24078e4-6e4e-2d62-7d92-bc31360bee0d.png)


## 完成形
![Mel.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1393871/90e98da5-a93c-5438-1e73-1e5a49b854e1.gif)
※gifにすると画面が粗くなってしまったのですが、拡大していただくと綺麗に見えるかと思います


### ■操作方法
1. 　基準としたい頂点を１つ選択
1. 　「基準座標取得」ボタンを押下し、選択した頂点の座標を取得
1. 　移動させたい頂点を選択（複数選択可）
1. 　「X座標」「Y座標」「Z座標」ボタンのいずれかを選択


### ■注意点
・ワールド座標で計算しているため、ローカル座標には対応してません
・あんまりテストしてないので、バグ出たらすみません...
　（今のところ、普通に使う分には特に問題なかったです）
 ・UI崩れてたら、手動で治してあげてください
 ・基準座標を元に移動しているので、**MELのウィンドウが表示されていないと使えません**


## コード
```php:CoordinateAdjustment.mel
global string $vertexCoordinateTxtFld = "coordinateAdjustmentUI_vertexCoordinate";

// 選択した頂点の座標を記録する（基準座標）
global proc getVertexCoordinate() {
    global string $vertexCoordinateTxtFld;

    string $singleVertexName[] = `ls -sl`;
    print($singleVertexName);
    if (`size $singleVertexName` > 1 ) {
        error "頂点を一つだけ選択してください";
    }
    // 選択している頂点の座標取得して、テキストフィールドに設定
    float $singleSelectVertexCorrdinate[] = `pointPosition -w $singleVertexName[0]`;

    $singleSelectVertexCorrdinate[0] = $singleSelectVertexCorrdinate[0] * 100.0;
    $singleSelectVertexCorrdinate[1] = $singleSelectVertexCorrdinate[1] * 100.0;
    $singleSelectVertexCorrdinate[2] = $singleSelectVertexCorrdinate[2] * 100.0;

    floatFieldGrp -e -v1 $singleSelectVertexCorrdinate[0] $vertexCoordinateTxtFld;
    floatFieldGrp -e -v2 $singleSelectVertexCorrdinate[1] $vertexCoordinateTxtFld;
    floatFieldGrp -e -v3 $singleSelectVertexCorrdinate[2] $vertexCoordinateTxtFld;
}

// X座標に頂点を移動
global proc coordinateAlignmentX() {
    moveVertexCoordinate("X");
}

// Y座標に頂点を移動
global proc coordinateAlignmentY() {
    moveVertexCoordinate("Y");
}

// Z座標に頂点を移動
global proc coordinateAlignmentZ() {
    moveVertexCoordinate("Z");
}


global proc moveVertexCoordinate(string $ShaftXYZ) {
    global string $vertexCoordinateTxtFld;

    // 選択している頂点の名前を取得
    string $multiVertexName[] = `ls -sl -fl`;

    // テキストフィールドにある基準座標を取得
    float $vertexCoordinateShaftXYZ;
    int $ShaftNum;

    if ($ShaftXYZ == "X") {
        $vertexCoordinateShaftXYZ = `floatFieldGrp -q -v1 $vertexCoordinateTxtFld`;
        $ShaftNum = 0;
    } else if ($ShaftXYZ == "Y") {
        $vertexCoordinateShaftXYZ = `floatFieldGrp -q -v2 $vertexCoordinateTxtFld`;
        $ShaftNum = 1;
    } else if ($ShaftXYZ == "Z") {
        $vertexCoordinateShaftXYZ = `floatFieldGrp -q -v3 $vertexCoordinateTxtFld`;
        $ShaftNum = 2;
    }

    // 頂点を移動　（コンポーネントエディタと数値を合わせるためにいろいろしてます）
    for ($i=0; $i<`size $multiVertexName`; $i++) {
        float $multiSelectVertexCorrdinate[] = `pointPosition $multiVertexName[$i]`;
        // 座標の数値を100倍
        $multiSelectVertexCorrdinate[$ShaftNum] = $multiSelectVertexCorrdinate[$ShaftNum] * 100.0;

        // 第四小数点で四捨五入
        // floorは整数部分だけ取得するから1000倍して、すべて整数にする
        // 1000で割って元の数値に変換
        float $differenceValue =$vertexCoordinateShaftXYZ - (`floor (($multiSelectVertexCorrdinate[$ShaftNum]+0.0005)*1000)`)/1000;
        $differenceValue = $differenceValue / 100.0;

        if ($ShaftNum == 0) {
            polyMoveVertex -tx $differenceValue $multiVertexName[$i];
        } else if ($ShaftNum == 1) {
            polyMoveVertex -ty $differenceValue $multiVertexName[$i];
        } else if ($ShaftNum == 2) {
            polyMoveVertex -tz $differenceValue $multiVertexName[$i];
        }
    }
}

// GUI
global proc CoordinateAdjustment() {

    global string $vertexCoordinateTxtFld;

    string $window = "coordinateAdjustment_window";
    if(`window -ex $window`) {
        deleteUI $window;
    }

    $window = `window -title "coordinateAdjustment" -ret -widthHeight 300 100 $window`;

        // 縦並びにする　columnLayout
        string $mainClm = `columnLayout -p $window "coordinateAdjustmentUI_mainColumn"`;

        text -p $mainClm -label "基準座標(X,Y,Z)" -align "left";;
        floatFieldGrp -p $mainClm -pre 3 -numberOfFields 3 $vertexCoordinateTxtFld;
        button -l "基準座標取得" -c "getVertexCoordinate()" -w 245 -h 40 "coordinateAdjustmentUI_getCorrdinateButton";

        separator -p $mainClm;

        // 横並びにする　rowLayout
        rowLayout -numberOfColumns 3 -columnWidth3 20 20 20;
            button -l "X座標" -c "coordinateAlignmentX()" -w 80 -bgc 0.8 0.4 0.4 "coordinateAdjustmentUI_moveVertexCoordinateX";
            button -l "Y座標" -c "coordinateAlignmentY()" -w 80 -bgc 0.4 0.8 0.4 "coordinateAdjustmentUI_moveVertexCoordinateY";
            button -l "Z座標" -c "coordinateAlignmentZ()" -w 80 -bgc 0.4 0.4 0.8 "coordinateAdjustmentUI_moveVertexCoordinateZ";

        setParent;

    showWindow $window;
}
```



## マーキングメニューに登録する方法
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1393871/90db7427-6635-ca08-300f-ee9fc7c5246c.png)
↑
自分はボタン押すのが面倒なので、マーキングメニューに登録してます

### ■登録方法
![Melの操作.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1393871/8efd2a7f-e8be-d09e-355a-2de840244fa7.gif)

関数名を中ボタンドラッグで移動できます。

### ■関数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1393871/155cf381-2cef-f3b3-67bd-a126c0dcc3aa.png)


・MELを開く
``` 
CoordinateAdjustment();
```

・基準座標取得
``` 
getVertexCoordinate();
```

・X座標に頂点を移動
``` 
coordinateAlignmentX();
```

・Y座標に頂点を移動
``` 
coordinateAlignmentY();
```


・Z座標に頂点を移動
``` 
coordinateAlignmentZ();
```


## 最後に
ここまで説明しておいてあれですが、実はMEL使わなくても割と簡単にできる方法があったり...

![Melの操作03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1393871/16ae545b-f655-7f10-192a-0e6a65cffe25.gif)



コードがおかしかったり、バグなどがあれば連絡していただけると助かります！
以上で終わりです！！