返回列表
mayaAPI

cmds.ls()函数详解(下)

ls()节点的获取,可以有很多方式,常见的方式有:
---基于 cmds.ls() 的高级节点筛选
---按名称规则筛选节点 (注意大小写 / 正则表达式)
---使用向量等数学运算
---结合openMaya

1.
基于 cmds.ls() 的高级节点筛选

assList = cmds.ls(assemblies=True)  # assemblies 装配Box(封装盒子)节点列表
print("场景中所有Box盒子节点列表:")
pp.pprint(assList ,width=120, compact=True)

功能:获取场景中所有最顶层父节点(包含自定义组 / 装配节点),用于场景层级结构梳理。

2.按名称规则筛选节点

1.1筛选名称含 t/T 摄像机节点

# 获取场景中,所有camera节点里,名字有字母 t 的节点
cameraNode = cmds.ls(type='camera')
list_t_T = [] # 创建空列表容器,用来接收处理好的节点

使用for if条件判单语句

for node in cameraNode:
if 't' in node.lower(): # 不区分大小写
list_t_T.append(node)
print("场景中名字包含 't/T' 的节点:")
pp.pprint(list_t_T,width=50,compact=True)

if 判断条件不同,获取不同节点,提升自由度

list_t = []
# 遍历判断
for node in cameraNode:
if 't' in node: # 严格小写
list_t.append(node)

print("\n只包含小写 't' 的节点:")
pprint(list_t,width=50,compact=True)

还可以使用,正则(re)表达式,进行更加复杂的字符串判断

import maya.cmds as cmds
import re

# 获取场景中,所有名字带数字后缀的mesh节点
all_nodes = cmds.ls(type="mesh")

list_nameNum= []

for node in all_nodes:
if re.search(r'\d+$', node):
list_nameNum.append(node)

print("场景中名字末尾有数字的节点:")
pp.pprint(list_nameNum,width=50,compact=True)

3.还可以使用向量等数学运算,进行更加复杂的节点获取

如:获取场景中,所有中心点不在世界中心的mesh节点

# 获取场景中,所有中心点不在世界中心的的mesh节点
notCenterList = []

meshList = cmds.ls(type="mesh", long=True)
for geo in meshList:
traNodeList = cmds.listRelatives(
geo,
parent=True,
fullPath=True
)
if not traNodeList:
continue

# 获取变换节点
traNode = traNodeList
print(f"获取到的变换节点: {traNode}")

# 获取几何体的世界空间边界框信息
bbox = cmds.xform(
traNode,
q=True,
bb=True,
ws=True
)
# bb列表: [最左, 最下, 最后, 最右, 最上, 最前]
# 记忆 : 左千户 徐向前
# bbox = [xmin, ymin, zmin, xmax, ymax, zmax]
# 索引 0 1 2 3 4 5
center_x = (bbox[0] + bbox[3]) / 2.0
center_y = (bbox[1] + bbox[4]) / 2.0
center_z = (bbox[2] + bbox[5]) / 2.0

# 向量距离 = 开根(xyz分量差 平方 的和)
# 这里不球实际距离,只做比较,不开根,减少运算量
vecDis = center_x**2 + center_y**2 + center_z**2
# 判断距离,1e-12=0.000000000001,1 乘以 10 的负 12 次方,用来检测双精度浮点数误差
if vecDis > 1e-12:
# 查新父子节点
parentList = cmds.listRelatives(
geo,
parent=True,
fullPath=True
)
parent = parentList
notCenterList.append(parent)

print("\n中心点不在世界中心的几何体节点:")
pp.pprint(notCenterList,width=50,compact=True)

"""
常用浮点数检测阈值
越大越精准,越大越占内存,运算卡顿
弧度检测 0.9999
距离判断 1e-7 1e-12
碰撞检测 1e-3 1e-5
"""

4.结合openMaya进行深入的获取

如:获取场景中,所有没有UV的mesh节点

# 获取场景中,所有没有UV的mesh节点
mesh_nodes = cmds.ls(type="mesh", long=True)
no_uv_meshes = []

for mesh in mesh_nodes:
# 获取MObject
sel = om.MSelectionList()
sel.add(mesh)
obj = sel.getDependNode(0)
fnMesh = om.MFnMesh(obj)

# 检查是否有UV数据
has_uv = False
uv_sets = fnMesh.getUVSetNames()
for uv_set in uv_sets:
# 获取UV数组
u_array, v_array = fnMesh.getUVs(uv_set)
if len(u_array) > 0:
has_uv = True
break

if not has_uv:
no_uv_meshes.append(mesh)

# 输出结果
if no_uv_meshes:
print(f"场景中没有UV的几何体有:{len(no_uv_meshes)}个:")
for mesh in no_uv_meshes:
trans_node = cmds.listRelatives(
mesh,
parent=True,
fullPath=True
)
if trans_node:
trans_name = trans_node[0].replace("|","")
else:
trans_name = mesh
print(f"\t{trans_name} 没有UV")
else:
print("场景中所有几何体都有UV数据")