Maya Python API:OpenMaya.MItMeshPolygon.center()调用及多组件定位问题
问题:OpenMaya API获取选中组件中心的问题
初始问题描述
刚接触Python版OpenMaya API,已完成基础教程任务,现在想实现用Maya命令做过的「获取多边形组件中心」功能。确认可以用OpenMaya.MItMeshPolygon.center()方法,但调用时出错:
尝试直接调用类方法:
import maya.api.OpenMaya as om coordValue = om.MItMeshPolygon.center(om.MSpace.kWorld) print(coordValue) # 期望获取选中面的中心 # Error: TypeError: descriptor 'center' for 'OpenMaya.MItMeshPolygon' objects doesn't apply to a 'int' object
因为kWorld实际是整数(输出为4),尝试直接传整数仍报错:
import maya.api.OpenMaya as om print(om.MSpace.kWorld) # 输出4 coordValue = om.MItMeshPolygon.center(4) # 期望获取选中面的中心 print(coordValue)
使用Maya 2026,查阅Devkit示例未找到解决方法。
已尝试的进展(编辑1)
经摸索写出部分可行代码,但仅在选中面时符合预期;选中边或顶点时,仍会创建面中心的定位器:
import maya.api.OpenMaya as om import maya.cmds as cmds def get_selected_center(): selection = om.MGlobal.getActiveSelectionList() if selection.length() == 0: raise RuntimeError("Nothing selected") dag_path, component = selection.getComponent(0) if not dag_path.node().apiType() == om.MFn.kMesh: raise RuntimeError("Selected object is not a mesh") poly_iter = om.MItMeshPolygon(dag_path, component) center = poly_iter.center(om.MSpace.kWorld) return center center = get_selected_center() # 返回一个三维坐标值 cmds.spaceLocator(p=(center.x, center.y, center.z))
需求:选中多边形面、边或顶点时,分别在对应中心(顶点则为自身位置)创建定位器。
解决方案
1. 初始错误原因
MItMeshPolygon.center()是实例方法,不是类方法——必须先创建MItMeshPolygon的实例(绑定到具体的网格和组件),才能调用该方法。直接用om.MItMeshPolygon.center()调用类的方法,会因为缺少实例上下文而报错。
2. 支持多组件类型的完整实现
需要根据选中的组件类型(顶点/边/面),使用对应的迭代器,并计算对应中心:
- 顶点:用
MItMeshVertex获取顶点位置 - 边:用
MItMeshEdge.center()获取边中心 - 面:用
MItMeshPolygon.center()获取面中心
同时支持单个或多个选中组件(每个组件都创建对应定位器):
import maya.api.OpenMaya as om import maya.cmds as cmds def create_center_locators(): selection = om.MGlobal.getActiveSelectionList() if selection.length() == 0: raise RuntimeError("Nothing selected") # 遍历选中的每个对象-组件对 for i in range(selection.length()): dag_path, component = selection.getComponent(i) # 检查是否为网格对象 if dag_path.node().apiType() != om.MFn.kMesh: print(f"Skipping non-mesh object: {dag_path.partialPathName()}") continue # 判断组件类型,选择对应的迭代器 comp_fn = om.MFnSingleIndexedComponent(component) comp_type = comp_fn.componentType if comp_type == om.MFn.kMeshVertComponent: iter = om.MItMeshVertex(dag_path, component) while not iter.isDone(): pos = iter.position(om.MSpace.kWorld) cmds.spaceLocator(p=(pos.x, pos.y, pos.z)) iter.next() elif comp_type == om.MFn.kMeshEdgeComponent: iter = om.MItMeshEdge(dag_path, component) while not iter.isDone(): center = iter.center(om.MSpace.kWorld) cmds.spaceLocator(p=(center.x, center.y, center.z)) iter.next() elif comp_type == om.MFn.kMeshPolygonComponent: iter = om.MItMeshPolygon(dag_path, component) while not iter.isDone(): center = iter.center(om.MSpace.kWorld) cmds.spaceLocator(p=(center.x, center.y, center.z)) iter.next() else: print(f"Unsupported component type: {comp_type}") # 执行函数 create_center_locators()
代码说明
- 使用
MFnSingleIndexedComponent获取组件类型,判断是顶点、边还是面 - 针对不同组件类型初始化对应的迭代器,遍历每个选中的组件
- 每个组件都创建对应的定位器:顶点直接取位置,边和面取中心
- 加入了非网格对象的跳过逻辑,以及不支持组件类型的提示
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

