Skip to content

Instantly share code, notes, and snippets.

@redglasses67
Created December 24, 2024 19:33
Show Gist options
  • Save redglasses67/88bc0c7e730b9341f81afd5c2ff381b5 to your computer and use it in GitHub Desktop.
Save redglasses67/88bc0c7e730b9341f81afd5c2ff381b5 to your computer and use it in GitHub Desktop.
同一オブジェクト内のシェルごとの頂点リストと中心座標を取得
# -*- coding: utf-8 -*-
import maya.cmds as mc
import maya.api.OpenMaya as om2
from typing import List, Dict
def findConnectedVtxIndexes(targetVtxIndex: int, srcVtxIndexDict: dict, shellVtxIdList: list) -> list:
"""
srcVtxIndexDict 内で targetVtxIndex と繋がっている頂点のインデックスを探す.
繋がっているものは同じシェル内にある頂点となる.
"""
srcVtxIndexDictKeys = list(srcVtxIndexDict.keys())
if targetVtxIndex not in srcVtxIndexDictKeys:
return []
if targetVtxIndex not in shellVtxIdList:
shellVtxIdList.append(targetVtxIndex)
connectedVtxIndexList = srcVtxIndexDict[targetVtxIndex]
for connectedVtxIndex in connectedVtxIndexList:
if connectedVtxIndex in shellVtxIdList:
continue
shellVtxIdList.append(connectedVtxIndex)
# 再帰的に探す
subCVtxIndexList = findConnectedVtxIndexes(connectedVtxIndex, srcVtxIndexDict, shellVtxIdList)
for subCVtxIndex in subCVtxIndexList:
if subCVtxIndex not in shellVtxIdList:
shellVtxIdList.append(subCVtxIndex)
return list(set(shellVtxIdList))
def convertToVtxIndexListPerShell(meshDag: om2.MDagPath) -> List[om2.MIntArray]:
"""
渡された mesh の MDagPath の各頂点の接続を確認し,
シェルごとの頂点インデックスのリストを返す.
"""
meshVtxIter = om2.MItMeshVertex(meshDag)
connectedVtxDict: Dict[int, List[int]] = {}
while not meshVtxIter.isDone():
vtxIndex = meshVtxIter.index()
# getConnectedVertices() で, イテレーターで回している現在の頂点に繋がっている頂点たちを取得
connectedVertices = meshVtxIter.getConnectedVertices()
# MIntArray を List に変換して
# dict の key に現在の頂点インデックス, values に繋がっている頂点たちのインデックスを格納
connectedVtxDict[vtxIndex] = [c for c in connectedVertices]
meshVtxIter.next()
vtxShellList: List = []
for connectedVtxIndex in connectedVtxDict.keys():
hasIndex = False
for vtxShell in vtxShellList:
if connectedVtxIndex in vtxShell:
hasIndex = True
break
if hasIndex:
continue
connectedList = findConnectedVtxIndexes(connectedVtxIndex, connectedVtxDict, [])
vtxShellList.append(connectedList)
return vtxShellList
def main():
# 現在選択中のオブジェクトを取得して for を回します
selList = om2.MGlobal.getActiveSelectionList()
for i in range(selList.length()):
mDagPath = selList.getDagPath(i)
targetMesh = om2.MFnMesh(mDagPath)
# シェルごとの頂点リストを取得
vtxShellList = convertToVtxIndexListPerShell(mDagPath)
print(f"==================== mesh fullPath = {mDagPath.fullPathName()} ====================")
# 取得したシェルごとの頂点リストを for で回す
for vtxIndexList in vtxShellList:
# シェルごとの頂点のインデックスリストを print
print(f"vtxIndexList = {vtxIndexList}")
# 対象メッシュの WorldSpace での頂点情報のリストを取得
vtxPosWSList: om2.MPointArray = targetMesh.getPoints(om2.MSpace.kWorld)
boundingBox = om2.MBoundingBox()
# シェルごとの頂点のインデックスリストを for で回して
# それらの頂点座標を boundingBox に追加して広げていく
for vtxIndex in vtxIndexList:
vtxWorldPos = vtxPosWSList[vtxIndex]
boundingBox.expand(vtxWorldPos)
# シェルごとの boundingBox の中心座標を print
bboxCenter = boundingBox.center
print(f"bboxCenter = {bboxCenter}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment