You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过OpenMaya实现顶点pnt属性的锁定状态读写?

使用OpenMaya实现顶点pnt属性的锁定状态获取与设置

问题背景

当前使用Maya cmds操作顶点pntx/pnty/pntz属性的锁定状态时速度过慢,希望改用OpenMaya API实现对应的获取器(getter)和设置器(setter)。

现有cmds实现:

获取顶点pntx锁定状态

mesh = cmds.ls(sl=1)[0]
vertices = cmds.ls(cmds.polyListComponentConversion(mesh, toVertex=True), flatten=True)  

cmds.getAttr("{}.pntx".format(vertices[0]), lock=True)

设置顶点pntx锁定状态

mesh = cmds.ls(sl=1)[0]
vertices = cmds.ls(cmds.polyListComponentConversion(mesh, toVertex=True), flatten=True)

cmds.setAttr("{}.pntx".format(vertices[0]), lock=False)

已完成的OpenMaya基础代码:

import maya.api.OpenMaya as om

sel = om.MSelectionList()
sel.add(meshes[0])
dag = sel.getDagPath(0)
fn_mesh = om.MFnMesh(dag)

困惑点:不知道如何获取顶点对应的pntx/pnty/pntz属性的MPlug,从而调用isLocked()和setLocked()方法——因为MFnMesh获取的顶点是整数索引,不是可传入MPlug的对象。


解决方案

核心思路是通过网格的DAG路径,结合顶点索引构建对应pnt属性的MPlug,再调用MPlug的锁定相关方法。

1. 获取顶点pnt属性的锁定状态(Getter)

import maya.api.OpenMaya as om

def get_vertex_pnt_lock_status(mesh_dag_path, vertex_index, axis="x"):
    # 获取网格的依赖节点对象,用于访问属性
    fn_dep_node = om.MFnDependencyNode(mesh_dag_path.node())
    # 获取对应轴的pnt属性MObject(pnt是多属性,对应所有顶点的位置)
    pnt_attr = fn_dep_node.attribute(f"pnt{axis}")
    # 构建基础MPlug并定位到目标顶点的属性实例
    pnt_plug = om.MPlug(mesh_dag_path.node(), pnt_attr)
    pnt_plug.selectAncestorLogicalIndex(vertex_index, pnt_attr)
    
    # 返回锁定状态
    return pnt_plug.isLocked()

# 使用示例
if __name__ == "__main__":
    # 获取选中的第一个网格
    sel = om.MSelectionList()
    sel.add(om.MGlobal.getActiveSelectionList()[0])
    mesh_dag = sel.getDagPath(0)
    # 获取第0个顶点pntx的锁定状态
    lock_status = get_vertex_pnt_lock_status(mesh_dag, 0, "x")
    print(f"顶点0的pntx锁定状态:{lock_status}")

2. 设置顶点pnt属性的锁定状态(Setter)

import maya.api.OpenMaya as om

def set_vertex_pnt_lock_status(mesh_dag_path, vertex_index, lock, axis="x"):
    fn_dep_node = om.MFnDependencyNode(mesh_dag_path.node())
    pnt_attr = fn_dep_node.attribute(f"pnt{axis}")
    pnt_plug = om.MPlug(mesh_dag_path.node(), pnt_attr)
    pnt_plug.selectAncestorLogicalIndex(vertex_index, pnt_attr)
    
    # 设置锁定状态
    pnt_plug.setLocked(lock)
    # 可选:同步设置关键帧可编辑状态(锁定时关闭关键帧)
    # pnt_plug.setKeyable(not lock)

# 使用示例
if __name__ == "__main__":
    sel = om.MSelectionList()
    sel.add(om.MGlobal.getActiveSelectionList()[0])
    mesh_dag = sel.getDagPath(0)
    # 将第0个顶点的pntx设置为锁定
    set_vertex_pnt_lock_status(mesh_dag, 0, True, "x")

关键步骤解释

  • pntx/pnty/pntz是网格节点的多属性(multi-attribute),每个顶点对应一个独立的逻辑索引
  • 通过MFnDependencyNode.attribute()获取目标属性的MObject
  • 使用MPlug.selectAncestorLogicalIndex()定位到对应顶点索引的属性实例
  • 最终通过MPlug.isLocked()和MPlug.setLocked()完成状态的读取与修改

内容的提问来源于stack exchange,提问作者Adam Sirrelle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 00:50:44