Created
December 24, 2024 19:33
-
-
Save redglasses67/88bc0c7e730b9341f81afd5c2ff381b5 to your computer and use it in GitHub Desktop.
同一オブジェクト内のシェルごとの頂点リストと中心座標を取得
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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