Maya脚本:Shape Node转OBJ的顶点/三角面提取及四边面转三角面问题
Maya Shape Node 批量转 OBJ(自动三角化四边面)
一、正确获取三角面顶点索引的方法
你之前用OpenMaya.MFnMesh.getTriangles()没成功,大概率是没正确初始化MFnMesh对象。以下是靠谱的实现方式:
import maya.OpenMaya as om def get_triangle_indices(shape_name): # 获取shape node的MObject sel_list = om.MSelectionList() sel_list.add(shape_name) mesh_obj = om.MObject() sel_list.getDependNode(0, mesh_obj) # 初始化MFnMesh mesh_fn = om.MFnMesh(mesh_obj) # 获取三角面数据:tri_counts是每个面的三角数量,tri_verts是所有三角的顶点索引 tri_counts = om.MIntArray() tri_verts = om.MIntArray() mesh_fn.getTriangles(tri_counts, tri_verts) # 把tri_verts拆成三元组(每个三角的三个顶点索引) triangle_indices = [] idx = 0 for count in tri_counts: for _ in range(count): triangle = (tri_verts[idx], tri_verts[idx+1], tri_verts[idx+2]) triangle_indices.append(triangle) idx += 3 return triangle_indices
注意:如果原模型有四边面,getTriangles()会自动把四边面拆成两个三角面返回索引,不需要手动处理。
二、完整的Shape Node转OBJ脚本(含四边面三角化)
如果不想自己写OBJ文件的写入逻辑,可以结合Maya内置命令先三角化模型,再批量导出每个shape:
import maya.cmds as cmds import os def export_shapes_to_obj(export_dir): # 创建导出目录 if not os.path.exists(export_dir): os.makedirs(export_dir) # 获取所有可见的mesh shape node(排除中间节点) shape_nodes = cmds.ls(type='mesh', visible=True, long=True) # 过滤掉不是直接关联transform的shape(比如历史节点) shape_nodes = [s for s in shape_nodes if cmds.listRelatives(s, parent=True, type='transform')] for shape in shape_nodes: # 获取父transform的名称,作为导出文件名 transform = cmds.listRelatives(shape, parent=True)[0] obj_path = os.path.join(export_dir, f"{transform}.obj") # 临时三角化当前shape(创建新的三角化shape,保留原模型) tri_shape = cmds.polyTriangulate(shape, ch=False, keepOriginal=True)[0] # 单独导出这个三角化后的shape cmds.select(tri_shape) cmds.exportSelected(obj_path, type="OBJexport", options="groups=0;ptgroups=0;materials=0;smoothing=0;normals=1", force=True) # 删除临时三角化的shape cmds.delete(tri_shape) # 使用示例:替换成你的导出路径 export_shapes_to_obj("D:/Maya_Exports/OBJ_Files")
脚本说明:
polyTriangulate(shape, ch=False, keepOriginal=True):对原shape进行三角化,生成新的三角面shape,不修改原模型- 导出选项
options:关闭组、材质、平滑组,保留法线,符合标准OBJ格式 - 自动遍历所有可见的mesh shape,每个单独导出为OBJ,文件名用父transform的名称
三、手动写入OBJ文件的方式(适合自定义格式)
如果你需要完全手动控制OBJ内容,可以结合顶点坐标和三角索引来生成:
import maya.OpenMaya as om import os def write_shape_to_obj(shape_name, obj_path): # 获取shape的MObject sel_list = om.MSelectionList() sel_list.add(shape_name) mesh_obj = om.MObject() sel_list.getDependNode(0, mesh_obj) mesh_fn = om.MFnMesh(mesh_obj) # 获取顶点坐标 points = om.MPointArray() mesh_fn.getPoints(points, om.MSpace.kWorld) # 换成kObject可获取局部坐标 # 获取三角面索引 tri_counts = om.MIntArray() tri_verts = om.MIntArray() mesh_fn.getTriangles(tri_counts, tri_verts) # 写入OBJ文件 with open(obj_path, 'w') as f: # 写入顶点 for i in range(points.length()): p = points[i] f.write(f"v {p.x} {p.y} {p.z}\n") # 写入三角面(OBJ索引从1开始,所以要+1) idx = 0 for count in tri_counts: for _ in range(count): v1 = tri_verts[idx] + 1 v2 = tri_verts[idx+1] + 1 v3 = tri_verts[idx+2] + 1 f.write(f"f {v1} {v2} {v3}\n") idx += 3 # 使用示例 write_shape_to_obj("pSphereShape1", "D:/test.obj")
内容的提问来源于stack exchange,提问作者user8469759
相关产品推荐
相关产品推荐

