CheckTools/uvChecker/python/removeUnassginedUVs.py

110 lines
2.9 KiB
Python
Raw Permalink Normal View History

2024-10-01 19:48:12 +08:00
"""
Remove unassigned UVs
"""
from maya import OpenMaya
from maya import cmds
def checkUnassignedUVs():
bads = []
sel = cmds.ls(sl=True, fl=True, long=True)
if len(sel) == 0:
cmds.error("Nothing is selected")
return
root = sel[0]
children = cmds.listRelatives(root, ad=True, type="mesh", fullPath=True)
sel = OpenMaya.MSelectionList()
for i in children:
sel.add(i)
# OpenMaya.MGlobal.getActiveSelectionList(sel)
dagPath = OpenMaya.MDagPath()
for i in range(sel.length()):
sel.getDagPath(i, dagPath)
fnMesh = OpenMaya.MFnMesh(dagPath)
numAllUVs = fnMesh.numUVs()
uvCounts = OpenMaya.MIntArray()
uvIds = OpenMaya.MIntArray()
fnMesh.getAssignedUVs(uvCounts, uvIds)
numAssignedUVs = len(set(uvIds))
if numAllUVs != numAssignedUVs:
bads.append(dagPath.fullPathName())
return bads
def removeUnassignedUVs():
sel = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList(sel)
if sel.length() == 0:
cmds.error('Nothing is selected')
return
dagPath = OpenMaya.MDagPath()
sel.getDagPath(0, dagPath)
fnMesh = OpenMaya.MFnMesh(dagPath)
uArray = OpenMaya.MFloatArray()
vArray = OpenMaya.MFloatArray()
fnMesh.getUVs(uArray, vArray)
uvCounts = OpenMaya.MIntArray()
uvIds = OpenMaya.MIntArray()
fnMesh.getAssignedUVs(uvCounts, uvIds)
# This is UVs that are actually assgined to the geometry
# So you have to keep UVs of those indices.
# Then you have to remove all non-assgined UVs(what we call ghost UVs)
oldUVIndicesSorted = sorted(list(set(uvIds)))
# Remap old indices to new clean indices
# eg. [x, x, x, 3, x, x, 6, x, x, 9, x, ....] (x means unassigned UVs to be removed)
# |
# [3, 6, 9, ...] <- Remove Unassgined UVs and pack left UVs
# |
# [0, 1, 2, ...] <- Remap to clean order
# Create new dict which key is old uv indices and value is new uv indices
# In the above example, { 3:0, 6:1, 9:2, .... }
uvMap = {}
for num, oldUVIndex in enumerate(oldUVIndicesSorted):
uvMap[oldUVIndex] = num
# Replace old UV indices of each face to new UV indices
newUvIds = OpenMaya.MIntArray()
for i in uvIds:
newUvIds.append(uvMap[i])
# Construct u and v arrays using only assigned UVs
newUs = [uArray[i] for i in oldUVIndicesSorted]
newVs = [vArray[i] for i in oldUVIndicesSorted]
# Convert python new uvArrays from python list to MFloatArray
newUArray = OpenMaya.MFloatArray()
newVArray = OpenMaya.MFloatArray()
for i in newUs:
newUArray.append(i)
for i in newVs:
newVArray.append(i)
# Clear current uvSet and re-assgin new UV information
fnMesh.clearUVs()
fnMesh.setUVs(newUArray, newVArray)
fnMesh.assignUVs(uvCounts, newUvIds)
fnMesh.updateSurface()
if __name__ == "__main__":
removeUnassignedUVs()