LoginSignup
2
0

mayaでUVエリア毎のfaceを選択したい

Last updated at Posted at 2023-12-03

UVエリア毎のfaceを選択したい
そんな気分になりました。

さてどうしよう

1つのfaceに対して、そのfaceが持ってるUV情報を取得して
そのUV座標をみて範囲内に収まってるか否かを判別して・・・・
うーん
image.png

しばしAPIのリファレンスを眺める

おーなんかあった
https://help.autodesk.com/view/MAYAUL/2022/JPN/?guid=Maya_SDK_py_ref_class_open_maya_1_1_m_it_mesh_polygon_html

def OpenMaya.MItMeshPolygon.getUVArea()
getUVArea(uvSet=None) -> float
This method gets the UV area of the face

  • uvSet (string) - UV set to work with

ん~ とりあえずgetUVAreaを試してみますか

getUVArea 一旦君に決めた

import maya.api.OpenMaya as om
target = "pPlane1"
faceIds = []
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)
    print(it.getUVArea())

0.08533608913421631
0.1096273809671402
0.08724434673786163
0.08724430203437805

(´A)?
あー・・・・・これは?
UVの?面積?かな?
うん 今回は使えない

別の方法を探す

def OpenMaya.MItMeshPolygon.getUVs()
getUVs(uvSet=None) -> [MFloatArray, MFloatArray]
Return the all the texture coordinates for the vertices of this face (in local vertex order).

  • uvSet (string) - UV set to work with

こいつで、faceが持ってるUV情報を全部引き出せるのかな?

import maya.api.OpenMaya as om
target = "pPlane1"
faceIds = []
faceIds = []
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)
    uvs = it.getUVs()
    print(uvs)

[maya.api.OpenMaya.MFloatArray([0.1039382815361023, 0.3960617184638977, 0.3960617184638977, 0.1039382815361023]), maya.api.OpenMaya.MFloatArray([0.1039382815361023, 0.1039382815361023, 0.3960617184638977, 0.3960617184638977])]
[maya.api.OpenMaya.MFloatArray([0.5844498872756958, 0.9155501127243042, 0.9155501127243042, 0.5844498872756958]), maya.api.OpenMaya.MFloatArray([0.08444985747337341, 0.08444985747337341, 0.4155501425266266, 0.4155501425266266])]
[maya.api.OpenMaya.MFloatArray([0.10231424868106842, 0.3976857662200928, 0.3976857662200928, 0.10231424868106842]), maya.api.OpenMaya.MFloatArray([0.6023142337799072, 0.6023142337799072, 0.8976857662200928, 0.8976857662200928])]
[maya.api.OpenMaya.MFloatArray([0.6023142337799072, 0.8976857662200928, 0.8976857662200928, 0.6023142337799072]), maya.api.OpenMaya.MFloatArray([0.6023142337799072, 0.6023142337799072, 0.8976857662200928, 0.8976857662200928])]

うん っぽいな

雑に実装

import maya.api.OpenMaya as om

def findFaceUVRange(target,UVRange):
    faceIds = []
    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:
        #faceID をセット
        it.setIndex(index)
        
        #facenのUV情報を取得
        uvs = it.getUVs()

        #指定したエリア内に有るか否かステータス
        insideRange = True        

        #U 座標評価
        for uPoint in uvs[0]:
            if uPoint < UVRange[0] or  uPoint > UVRange[1]:
                insideRange = False
        #V 座標評価         
        for vPoint in uvs[1]:            
            if vPoint < UVRange[2] or  vPoint > UVRange[3]:
                insideRange = False
        
        #範囲内にあるならIDを追加
        if insideRange:
            faceIds.append(index)

    result = []
    for faceId in faceIds:
        result.append(target+".f["+str(faceId)+"]")
        
    return result
    
cmds.select(findFaceUVRange("pPlane1",[0.0,0.5,0.5,1.0]),r=True)

実行結果
image.png

ヤッター

何に使えるか?

経緯としてはUDIMを使用しているオブジェクトで、
faceアサインでも良いのでUDIMを使わない構成に変えたくなって、
その際にUDIM使ったオブジェクトとマテリアルが複数あって、
あぁもう面倒だなぁ
というのが発端でした。

2
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
2
0