mayaがエラー・ワーニングを吐く時の対処 8　~孤立したvtx~

mayaがwarningを吐いて鬱陶しい時

メッシュデータをimportしただけでこんなワーニングを吐く時

    Warning: The mesh object|objectShape contains invalid or unused components.  These can be cleaned up using the Mesh Cleanup dialog. #

場合にもよるけれども、指示通りにcleanup実行してもwarnigが出続ける場合がある。
そのケースの1つとして、**孤立している頂点**があげられます。

孤立しているvertex
-
本来edgeやfaceを構成しているはずが、どのfaceにも所属せず1点のみで存在している頂点で、
逆に言えば全vertxIDと全faceに所属しているvertxIDを比較してその差分を取れば、
孤立している頂点が割り出せ・・・・はず。

mayaだと大体面に対してエッジ・頂点の数が少なくなると勝手に削除してくれるので滅多に遭遇しないのですが、
その分遭遇すると厄介ですね。

その為サンプルのデータを用意するのも厄介・・・

とりあえずcubeを作ってmaで保存して、無理やり vtxを１つ情報足してみます。

ここを
```
	setAttr -s 8 ".vt[0:7]"  -0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5
		 -0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5;
```

こんな感じに
```
	setAttr -s 8 ".vt[0:8]"  -0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5
		 -0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0 0 0;
```

エラーも無事？でたので、多分できてるはず
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/77c22bd5-93a4-7641-6f9b-0f57760eb7da.png)

Q:9個めのvtxはどーこだ？

設計
-

ざっくりやると

- meshの全てのvtxIdを取得
- meshの全てのfaceを取得し、そこに接続されているvtxIdを取得
- 両者の差分を出す

という感じですね。
vtxIdはまぁ何とかなるとして、faceに所属しているvtxの方がちょっと面倒そうかなと

これを使って

**OpenMaya.MItMeshPolygon**
https://help.autodesk.com/view/MAYAUL/2022/JPN/?guid=Maya_SDK_py_ref_class_open_maya_1_1_m_it_mesh_polygon_html

getVertices()とか使えそうですね。

zeroArea()　これはこれで別の時に使えそう

スクリプト
-

まずはfaceとそのvtxから・・・

```python
import maya.cmds as cmds
import maya.api.OpenMaya as om

def listIsolateVtx(target):
    mesh_dagPath = om.MGlobal.getSelectionListByName(target).getDagPath(0)
    shape_Fn = om.MFnMesh(mesh_dagPath)

    face_ids = range(0,shape_Fn.numPolygons)
    it = om.MItMeshPolygon(mesh_dagPath)

    all_faceVtx_ids = []
    for index in face_ids:
        it.setIndex(index)
        connected_vtx = it.getVertices()
        print(connected_vtx)

```

```
listIsolateVtx("pCube1")

##結果---------------------
[0, 1, 3, 2]
[2, 3, 5, 4]
[4, 5, 7, 6]
[6, 7, 1, 0]
[1, 7, 5, 3]
[6, 0, 2, 4]
```
6面分取れてますね。
ただ、もちろん重複があるのでこれも処理しておきたいですね。
この時点でvtx[8]が見えてないので、行けそうな気がしてきました。


```python
import maya.cmds as cmds
import maya.api.OpenMaya as om

def listIsolateVtx(target):
    mesh_dagPath = om.MGlobal.getSelectionListByName(target).getDagPath(0)
    shape_Fn = om.MFnMesh(mesh_dagPath)

    face_ids = range(0,shape_Fn.numPolygons)
    it = om.MItMeshPolygon(mesh_dagPath)

    all_faceVtx_ids = []
    for index in face_ids:
        it.setIndex(index)
        connected_vtx = it.getVertices()
        all_faceVtx_ids.extend(list(connected_vtx)) 

    all_faceVtx_ids = list(set(all_faceVtx_ids))
    print(all_faceVtx_ids)

```

次に vtxを直接確認しに行ってリストを作成

```python
import maya.cmds as cmds
import maya.api.OpenMaya as om

def listIsolateVtx(target):
    mesh_dagPath = om.MGlobal.getSelectionListByName(target).getDagPath(0)
    shape_Fn = om.MFnMesh(mesh_dagPath)

    face_ids = range(0,shape_Fn.numPolygons)
    it = om.MItMeshPolygon(mesh_dagPath)

    all_faceVtx_ids = []
    for index in face_ids:
        it.setIndex(index)
        connected_vtx = it.getVertices()
        all_faceVtx_ids.extend(list(connected_vtx)) 

    all_faceVtx_ids = list(set(all_faceVtx_ids))

    all_vtx_ids = []    
    for i in range(0,shape_Fn.numVertices):
        all_vtx_ids.append(i)

    print(all_vtx_ids)
```

```
listIsolateVtx("pCube1")

#結果-------------------
[0, 1, 2, 3, 4, 5, 6, 7, 8]
```

お、8いますね
じゃぁ最後に比較してみて・・・

```python
import maya.cmds as cmds
import maya.api.OpenMaya as om

def listIsolateVtx(target):
    mesh_dagPath = om.MGlobal.getSelectionListByName(target).getDagPath(0)
    shape_Fn = om.MFnMesh(mesh_dagPath)

    face_ids = range(0,shape_Fn.numPolygons)
    it = om.MItMeshPolygon(mesh_dagPath)

    all_faceVtx_ids = []
    for index in face_ids:
        it.setIndex(index)
        connected_vtx = it.getVertices()
        all_faceVtx_ids.extend(list(connected_vtx)) 

    all_faceVtx_ids = list(set(all_faceVtx_ids))

    all_vtx_ids = []    
    for i in range(0,shape_Fn.numVertices):
        all_vtx_ids.append(i)

    isolate_vtx_ids = list(set(all_vtx_ids) - set(all_faceVtx_ids))

    return isolate_vtx_ids
```

```
listIsolateVtx("pCube1")
# Result: [8] # 
```

取れたかな
id取れたのであとは適当に

```
cmds.select("pCubeShape1.vtx[8]",r = True)

```

よし、掴めましたね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/252e0d98-3c13-0a1d-293e-31797eee11de.png)

これを削除して、保存して、開き直すと
エラーが消えました！

まとめ
-

- DCCツール行き来したりとか何かの拍子に生まれてしまう様子
- 孤立してる上に、他のvtxと同じ位置にあったら目視は不可能なのでは？
- スキニングの時にこれが存在してると、厄介そう
- ワーニングだけど黄色メッセージで出てこないので気づきにくい


なぜかたまに対処してくれないけどcleanupでも対処できることもあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/60f21335-330a-854c-b175-cb9f3a675ce3.png)