Maya中如何快速查找无UV Shell的网格对象?求高效实现方案
快速检测Maya场景中无UV Shell的Mesh对象
太懂这种慢到抓狂的感受了——findUvShells本质是面向交互的命令,每次调用都会附带UI层面的计算和反馈,再加上你原来脚本里频繁的选择切换,单个角色跑一分钟完全是这些额外开销堆出来的。下面给你两种优化方案,尤其是基于OpenMaya的实现,速度能提升一个量级。
一、先优化现有MEL命令脚本(快速见效)
原来的脚本慢的核心原因之一是每次遍历都切换选择,而且findUvShells其实可以直接指定目标对象,不用先选中它。另外我们还能提前过滤掉没有UV集的mesh,避免无效计算:
import maya.cmds as mc def FindObjectsWithNoUVShells_optimized(): ObjectsWithNoUVShells = [] old_sel = mc.ls(sl=True) # 遍历所有mesh,跳过无UV集的对象 geo_list = mc.ls(typ="mesh") for obj in geo_list: all_uv_sets = mc.polyUVSet(obj, q=True, allUVSets=True) if not all_uv_sets: ObjectsWithNoUVShells.append(obj) continue # 直接传入对象调用findUvShells,无需切换选择 uv_set = all_uv_sets[0] shell_count = mc.findUvShells(obj, uvSet=uv_set, q=True)[1] if shell_count == 0: ObjectsWithNoUVShells.append(obj) mc.select(old_sel) return len(ObjectsWithNoUVShells) > 0, ObjectsWithNoUVShells # 测试调用 has_empty, empty_list = FindObjectsWithNoUVShells_optimized() print(f"找到{len(empty_list)}个无UV Shell的对象: {empty_list}")
这个修改去掉了频繁的mc.select操作,能节省不少时间,但本质还是依赖MEL命令,复杂场景下还是有瓶颈。
二、基于OpenMaya的高性能实现(推荐)
OpenMaya API直接操作底层数据,完全绕开UI交互开销,速度会快很多。核心思路是:
- 遍历所有mesh节点
- 通过
MFnMesh直接获取UV数据,判断是否存在有效UV壳
import maya.OpenMaya as om def FindObjectsWithNoUVShells_openmaya(): ObjectsWithNoUVShells = [] # 创建迭代器遍历所有mesh节点 iter_mesh = om.MItDependencyNodes(om.MFn.kMesh) while not iter_mesh.isDone(): mesh_obj = iter_mesh.thisNode() fn_mesh = om.MFnMesh(mesh_obj) # 获取所有UV集名称 uv_set_names = om.MStringArray() fn_mesh.getUVSetNames(uv_set_names) if uv_set_names.length() == 0: # 无任何UV集,直接加入列表 full_name = fn_mesh.fullPathName() ObjectsWithNoUVShells.append(full_name) iter_mesh.next() continue # 检查第一个UV集的UV数据和面分配情况 uv_set = uv_set_names[0] u_array = om.MFloatArray() v_array = om.MFloatArray() uv_counts = om.MIntArray() uv_ids = om.MIntArray() fn_mesh.getUVs(u_array, v_array, uv_set) fn_mesh.getAssignedUVs(uv_counts, uv_ids, uv_set) # 判断无UV壳的情况:UV数组为空 或 没有面分配UV if u_array.length() == 0 or uv_ids.length() == 0: full_name = fn_mesh.fullPathName() ObjectsWithNoUVShells.append(full_name) iter_mesh.next() return len(ObjectsWithNoUVShells) > 0, ObjectsWithNoUVShells # 测试调用 has_empty, empty_list = FindObjectsWithNoUVShells_openmaya() print(f"找到{len(empty_list)}个无UV Shell的对象: {empty_list}")
为什么这个更快?
- 直接访问Maya底层数据结构,没有命令调用的额外开销
- 无需切换选择、无需等待UI刷新
- 批量获取UV数据,避免多次小操作的累积耗时
补充说明
如果你的场景需要检查所有UV集(而非仅第一个),可以修改代码遍历uv_set_names数组逐个验证即可。
内容的提问来源于stack exchange,提问作者mranim8or
相关产品推荐
相关产品推荐

