0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

mayaがエラー・ワーニングを吐く時の対処 9 ~non-Manifoldとの戦い~

Posted at

non-manifold ですって

発端はこれ

// Warning: The OpenSubdiv Catmull-Clark subdivision method cannot be applied to non-manifold geometry

smoothPreviewをonにするとこんなワーニングが出てくるデータに遭遇。
スクリプトエディタにはopen/import時にこのワーニング出てるんですけど、
思った以上にスクリプトエディタってのは見られてないらしい。

ワーニングの根源

今回ジオメトリはこんな感じになってました。
smoothPreviewをoffにすると一見問題ないのですが、
実は赤丸の部分にはエッジが2本重なっておりマージされてません。

image.png

目視でこれを見つけるのはかなーり大変な気がしますね。

そもそも non-manifold

ところで non-manifoldって?
のん まにふぉーるど?

なるほど?
雑に言えば、無茶なつながり方をしてるポリゴンか。
今回の場合は 2つ以上のフェースが1つの頂点を共有する場合(エッジは非共有) かなぁ

どうやって見つける?

  • とりあえずmaya標準の機能でやってみる。
    cleanupでできるらしい。

image.png

ビックリするぐらい引っかからない!
設定が悪い気もするけれども、一回忘れよう。

えーじゃぁどうしよう、力技でvtx数とかポリゴン数とかでなんとかするー?
ってtwitterでモゴモゴ言ってたら

polyInfo ってコマンドがあるそうですわ!

なるほど、non-manifoldの為のオプションが幾つかありますね。

※invalidVertices これ使えば前の記事の様に面倒なことしなくても孤立したvtx見つけられそうですね

polyInfoを試す

こんなメッシュの場合

image.png

これで

print(cmds.polyInfo("pPlane6",nonManifoldEdges =True))
print(cmds.polyInfo("pPlane6",nonManifoldVertices =True))

こう

['pPlane6.e[1]', 'pPlane6.e[12]', 'pPlane6.e[23]', 'pPlane6.e[34]', 'pPlane6.e[45]', 'pPlane6.e[56]', 'pPlane6.e[67]', 'pPlane6.e[78]', 'pPlane6.e[89]', 'pPlane6.e[100]']
['pPlane6.vtx[0]', 'pPlane6.vtx[6]', 'pPlane6.vtx[12]', 'pPlane6.vtx[18]', 'pPlane6.vtx[24]', 'pPlane6.vtx[30]', 'pPlane6.vtx[36]', 'pPlane6.vtx[42]', 'pPlane6.vtx[48]', 'pPlane6.vtx[54]', 'pPlane6.vtx[60]']

お、見つけられそうですね。

ではこいつの場合
※わかりづらいのでsmoothPreview = On

image.png

さぁ

print(cmds.polyInfo("pPlane3",nonManifoldEdges =True))
print(cmds.polyInfo("pPlane3",nonManifoldVertices =True))

えー・・・・・・・

None
None

力に頼ろう

要は、・・・・・どうすればいいんだ?

  • vtxを完全に共有しているedgeを探す

かな?
とりあえずAPI2のドキュメントを眺めてみて

OpenMaya.MItMeshPolygon.getConnectedEdges()
OpenMaya.MItMeshPolygon.getConnectedFaces()
OpenMaya.MItMeshPolygon.getConnectedVertices()

ポリゴンだけどもこの辺が使えそう。

getConnectedEdgesを試してみる

import maya.api.OpenMaya as om
target = "pPlane3"
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)
it.setIndex(130)
edges = it.getConnectedEdges()

for edge in edges:
    cmds.select(target + ".e["+str(edge)+"]",add =True)

image.png
お、重なってるうちの1つのエッジが取れましたね。

getConnectedVerticesを試してみる

import maya.api.OpenMaya as om

target = "pPlane3"
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)
it.setIndex(130)
vtxes = it.getConnectedVertices()

for vtx in vtxes:
    cmds.select(target + ".vtx["+str(vtx)+"]",add =True)

image.png

重なってるエッジが接続されてるvtxが取れましたね。

問題ない場合はこうなるはず
image.png

てことは
getConnectedVerticesで取得した接続されているvtx

faceを構成しているvtx
を比較して、被ってる場合は non-manifold ってことでいいのかしら?

実装

じゃぁまぁそういう事で一回まとめると

def listSlitVtx(target):
    vtxIds = []
    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)
    
    for index in face_ids:
        it.setIndex(index)

        #faceを構成するvtxIDを取得
        vtxs = it.getVertices()

        #faceに接続されているvtxIDを取得
        connectedVtx = it.getConnectedVertices()

        #2種類のvtxIDの積集合を取る
        product = list(set(vtxs) & set(connectedVtx))
        if len(product):
            vtxIds = list(set(vtxIds) | set(product))
              
    result = [target + '.vtx[' + str(vid) + ']'for vid in vtxIds]
    return result

cmds.select(listSlitVtx("pPlane3"),add=True)

なんか listSlitVtxは違う気がするけどもまぁ仮という事で。

image.png

お 取れました。

こっちのタイプだと無反応なので、こっちはpolyInfoでひっかけた方が良さそうですね
image.png

ひとまずこれで。
まぁ完全ではないけども、目視で探すよりは100倍くらい楽ですかね。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?