mayaがエラー・ワーニングを吐く時の対処 10　~UVがなんか変~

エラーが発生してレンダリングが落ちてしまうと

エラーの内容を見てみると

```
// Warning: resetting parameter uvlist on hogeGeoShape (found: nans or infs) // 
// Error: [polymesh] hogeGeoShape: incorrectly defined UV coordinates, missing either uvlist or uvidxs //
```

状況を細かく詰めてくと
- arnoldレンダラーで落ちる
- 特定のオブジェクトにpolySmoothをかけてsmoothUV入れてると落ちる

一応フォーラムに該当のエラーを見つけたけども
https://forums.autodesk.com/t5/maya-forum/maya-error-incorrectly-defined-uv-coordinates-missing-uvlist-or/td-p/7361321

- エラー無視モードにすればいけるよ！
- UVを開き直せばいけるよ！
- UVからface選択して選択できないfaceがある！からUVを開き直せばいけるよ！

うーん　なんかこう・・・ねぇ・・・・

観察
-
問題あるっぽいオブジェクトのうちの1つを抜き出して観察
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/69cd03d7-9a14-20aa-3437-87e220dff4a8.png)

しかしこのオブジェクトも、エラーが出たり出なかったり・・・

とりあえず　開いたり閉じたりして何とかエラーを再現

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/74539b3a-3112-bab0-38bb-41a69c440cc7.png)

やはりこのオプションが何かを引き起こしてる様子。

フォーラムの方法を試してみる
-

**UVを開き直せばいけるよ**
との事なので、UVをオートマで開いてみる

確かにエラーは消失したので、UV違いだけという事で　maファイルを比較してみる。

```
#before
setAttr -s 235 ".uvst[0].uvsp[0:234]" -type "float2" 0.89956701 0.50210595

#after
setAttr -s 212 ".uvst[0].uvsp[0:211]" -type "float2" 0.23808144 0.70847791
```
まぁ順当にUVが編集されてますが・・・

フォーラムにあったように
UVからface選択して選択できないfaceがある！
というのも当てはまらなそう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/62a77aaa-f934-1c36-2ca5-de6cb76a330c.png)

あ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/deb007fe-71a8-48f2-b211-0420f664791b.png)

あー？　UV全部選択できてないなぁ？
face全選択 -> toUVにしてるのに？

全選択してみると
```
cmds.select("hogeGeo.map[*]",r =True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/83beb4d6-8271-7f2e-88c7-f34ccf966c0c.png)

なんかいるなー
UVエディタ上では直接選択できず、問題ないUVシェルと同時に範囲選択すると選択できるようですね。

詳しく観察
-
viewport上でUV全選択 
-> cmds.ls(sl =True) 
-> 歯抜けになってるindexを選択

```
cmds.select("hogeGeo.map[4]",r=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/50df7d47-6246-0455-d8d7-931dc5041a54.png)

viewport上では確認できないですね。

問題ないUVシェルからfaceを選択すると、faceは全て選択出来てるので

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/49d856bf-0607-5ef0-7a69-6b32c754e4d3.png)

仮定
- どのUVシェルに参加していないUV
が問題なのでは？

仮実装
-
UVシェルの何かを取得したい

https://help.autodesk.com/view/MAYAUL/2022/JPN/?guid=Maya_SDK_py_ref_class_open_maya_1_1_m_fn_mesh_html

>OpenMaya.MFnMesh.getUvShellsIds()
>getUvShellsIds(uvSet='') -> (int, MIntArray)
>Returns a tuple containing describing how the specified UV set's UVs
>are grouped into shells. The first element of the tuple is the number
>of distinct shells. The second element of the tuple is an array of
>shell indices, one per uv, indicating which shell that uv is part of.


```python
import maya.api.OpenMaya as om
target = "hogeGeo"
mesh_dagPath = om.MGlobal.getSelectionListByName(target).getDagPath(0)
shape_Fn = om.MFnMesh(mesh_dagPath)
print(shape_Fn.getUvShellsIds())

(50, maya.api.OpenMaya.MIntArray([0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, 0, -1, -1, 0, -1, -1, 0, -1, -1, -1, -1, 0, -1, -1, -1, 0, -1, -1, -1, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -1, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0]))

```
1つ目は shellの数で、2つ目は各UVが所属してるshellのIDですね。
先述のテストで選択したindex 4を見てみると　-1

UVの数は　235
-1の数は　37
235 - 37 = 198

お　数字が一致しましたね。


実装
-

ひとまず　チェックできるだけでもかなり捗るのでチェックスクリプトを作成

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

def checkIsolateUV(target):
    mesh_dagPath = om.MGlobal.getSelectionListByName(target).getDagPath(0)
    shape_Fn = om.MFnMesh(mesh_dagPath)
    shellNum,uvShellIds = shape_Fn.getUvShellsIds()

    if list(uvShellIds).count(-1) != 0:
        return False
    else:
        return True

target = "hogeGeo"
checkIsolateUV(target)
```


追記
-
肝心な対処法を忘れてました。

UV情報がアップデートされるとこの迷子のUV達は成仏するようで、今のところ

- exportSelectで保存する
- 削除できないvtxを選択してdeleteボタンを実行

で対応できることは見つけました。
他なにか方法ご存じの方は是非ご共有ください。