#!/usr/bin/env python # -*- coding: utf-8 -*- """ 版权所有: 深圳时光科技有限公司 联系方式: q.100@qq.com 创建日期: 2024/04/08 """ import maya.cmds as cmds import math def sg_presets_settings(): """ 创建预设设置窗口 """ # 检查主窗口是否存在 if not cmds.window('SuperRiggingEditor', exists=True): return # 如果预设窗口已存在则删除 if cmds.window('presetsSettingsWin', exists=True): cmds.deleteUI('presetsSettingsWin') # 获取关节信息文件路径 json_file = cmds.SGDescriptor(ti="jointsInfo") # 创建窗口 window = cmds.window('presetsSettingsWin', title="Presets Settings", width=310, height=100, sizeable=True, toolbox=True, parent='SuperRiggingEditor') # 主布局 main_form = cmds.formLayout('sgPresetsFormLayout') # 创建控件 topology_field = cmds.textField('sgTopologyInfo', text=json_file) separator_a = cmds.separator('sgPresetsSeparatorA', height=10, style="in") # 左侧列布局 col_a = cmds.columnLayout('sgPresetsColumnLayoutA', adjustableColumn=True, columnAttach=('both', 5), rowSpacing=2, columnWidth=150) # 左侧按钮 cmds.button(label="Select Head Vertexs", align="center", command="cmds.SGSelectVertexs(0, 'head')") cmds.button(label="Save Head Vertexs", align="center", command="cmds.SGSaveVertexs(0, 'head')") cmds.separator(height=10, style="in") cmds.button(label="Select Teeth Vertexs", align="center", command="cmds.SGSelectVertexs(1, 'teeth')") cmds.button(label="Save Teeth Vertexs", align="center", command="cmds.SGSaveVertexs(1, 'teeth')") cmds.separator(height=10, style="in") cmds.button(label="Select EyeLeft Vertexs", align="center", command="cmds.SGSelectVertexs(3, 'eyeLeft')") cmds.button(label="Save EyeLeft Vertexs", align="center", command="cmds.SGSaveVertexs(3, 'eyeLeft')") cmds.separator(height=10, style="in") cmds.button(label="Select EyeRight Vertexs", align="center", command="cmds.SGSelectVertexs(4, 'eyeRight')") cmds.button(label="Save EyeRight Vertexs", align="center", command="cmds.SGSaveVertexs(4, 'eyeRight')") cmds.setParent('..') # 右侧列布局 col_b = cmds.columnLayout('sgPresetsColumnLayoutB', adjustableColumn=True, columnAttach=('both', 5), rowSpacing=2, columnWidth=150) # 右侧按钮 cmds.button(label="Select Body Vertexs", align="center", command="cmds.SGSelectVertexs(50, 'body')") cmds.button(label="Save Body Vertexs", align="center", command="cmds.SGSaveVertexs(50, 'body')") cmds.separator(height=10, style="in") cmds.button(label="Select Neck Vertexs", align="center", command="cmds.SGSelectVertexs(0, 'neck')") cmds.button(label="Save Neck Vertexs", align="center", command="cmds.SGSaveVertexs(0, 'neck')") cmds.separator(height=10, style="in") cmds.button(label="Select HeadEye Vertexs", align="center", command="cmds.SGSelectVertexs(0, 'headEye')") cmds.button(label="Save HeadEye Vertexs", align="center", command="cmds.SGSaveVertexs(0, 'headEye')") cmds.separator(height=10, style="in") cmds.button(label="Select HeadMouth Vertexs", align="center", command="cmds.SGSelectVertexs(0, 'headMouth')") cmds.button(label="Save HeadMouth Vertexs", align="center", command="cmds.SGSaveVertexs(0, 'headMouth')") cmds.setParent('..') # 底部列布局 col_c = cmds.columnLayout('sgPresetsColumnLayoutC', adjustableColumn=True, columnAttach=('both', 5), rowSpacing=2, columnWidth=150) cmds.separator(height=10, style="in") cmds.button(label="The Closest Point Of The Head", align="center", command="cmds.SGGetClosestPointOnMesh(0)") cmds.button(label="The Closest Point Of The Body", align="center", command="cmds.SGGetClosestPointOnMesh(50)") cmds.button(label="The Closest Point Of The Teeth", align="center", command="cmds.SGGetClosestPointOnMesh(1)") cmds.separator(height=10, style="in") cmds.button(label="Write Joints Default Position", align="center", command="cmds.SGWriteJointsDefaultPosition()") cmds.separator(height=10, style="in") cmds.setParent('..') # 设置表单布局 cmds.formLayout(main_form, edit=True, attachForm=[(topology_field, 'top', 3), (topology_field, 'left', 0), (topology_field, 'right', 0), (separator_a, 'left', 0), (separator_a, 'right', 0), (col_a, 'left', 0), (col_b, 'right', 0), (col_c, 'left', 0), (col_c, 'right', 0)], attachControl=[(separator_a, 'top', 1, topology_field), (col_a, 'top', 1, separator_a), (col_b, 'top', 1, separator_a), (col_c, 'top', 1, col_a)], attachPosition=[(col_a, 'right', 0, 51), (col_b, 'left', 0, 49)]) cmds.showWindow(window) def sg_select_vertexs(mesh_index, region): """ 选择指定区域的顶点 Args: mesh_index: 网格索引 region: 区域名称 """ open_file = cmds.SGDescriptor(ti="vertexsInfo") mesh = cmds.SGGetMeshes(m=mesh_index) vertexs = cmds.SGReadJson(f=open_file, k=region, t="int") cmds.select(cl=True) for vertex in vertexs: cmds.select(f"{mesh}.vtx[{vertex}]", add=True) def sg_save_vertexs(mesh_index, region): """ 保存选中顶点到指定区域 Args: mesh_index: 网格索引 region: 区域名称 """ json_file = cmds.SGDescriptor(ti="vertexsInfo") mesh = cmds.SGGetMeshes(m=mesh_index) selection = cmds.ls(sl=True, fl=True) indices = [] for sel in selection: mesh_name, vertex_id = sel.split('.') if not mesh_name.startswith(mesh): cmds.error("Model Selection Error...") return indices.append(int(vertex_id.strip('vtx[]'))) cmds.SGWriteJson(of=json_file, sf=json_file, k=region, t="int", value=indices) def sg_get_closest_point_on_mesh(mesh_index): """ 获取最近点 Args: mesh_index: 网格索引 """ open_file = cmds.SGDescriptor(ti="jointsInfo") mesh = cmds.SGGetMeshes(m=mesh_index) closest_point_node = cmds.createNode('closestPointOnMesh') cmds.connectAttr(f"{mesh}.worldMesh[0]", f"{closest_point_node}.inMesh", f=True) key = "head" if mesh_index != 50 else "body" cmds.select(cl=True) objects = cmds.SGReadJson(f=open_file, k=key, t="object") for obj in objects: joint_name = cmds.SGReadJson(d=obj, k="joint", t="string")[0] if mesh_index in [0, 1]: joint = f"DHIhead:{joint_name}" index = cmds.SGReadJson(d=obj, k="mesh", t="int")[0] if index == mesh_index: point_position = cmds.xform(joint, q=True, ws=True, t=True) cmds.setAttr(f"{closest_point_node}.inPosition", *point_position) closest_vertex_index = cmds.getAttr(f"{closest_point_node}.closestVertexIndex") cmds.select(f"{mesh}.vtx[{closest_vertex_index}]", add=True) else: joint = f"{joint_name}_drv" enable = cmds.SGReadJson(d=obj, k="enable", t="bool")[0] if enable: point_position = cmds.xform(joint, q=True, ws=True, t=True) cmds.setAttr(f"{closest_point_node}.inPosition", *point_position) closest_vertex_index = cmds.getAttr(f"{closest_point_node}.closestVertexIndex") cmds.select(f"{mesh}.vtx[{closest_vertex_index}]", add=True) cmds.delete(closest_point_node) def sg_write_joints_default_position(): """ 写入关节默认位置 """ json_file = cmds.SGDescriptor(ti="jointsInfo") # 处理身体关节 object_body = cmds.SGReadJson(f=json_file, k="body", t="object") for i, obj in enumerate(object_body): joint_name = cmds.SGReadJson(d=obj, k="joint", t="string")[0] joint = f"{joint_name}_drv" pos = cmds.xform(joint, q=True, ws=True, t=True) # 四舍五入到小数点后4位 pos = [round(x * 10000) / 10000 for x in pos] data = cmds.SGWriteJson(d=obj, sf="data", k="translate", t="double", value=pos) object_body[i] = data cmds.SGWriteJson(of=json_file, sf=json_file, k="body", t="object", value=object_body) # 处理头部关节 object_head = cmds.SGReadJson(f=json_file, k="head", t="object") for i, obj in enumerate(object_head): joint_name = cmds.SGReadJson(d=obj, k="joint", t="string")[0] joint = f"DHIhead:{joint_name}" pos = cmds.xform(joint, q=True, ws=True, t=True) # 四舍五入到小数点后4位 pos = [round(x * 10000) / 10000 for x in pos] data = cmds.SGWriteJson(d=obj, sf="data", k="translate", t="double", value=pos) object_head[i] = data cmds.SGWriteJson(of=json_file, sf=json_file, k="head", t="object", value=object_head) # 如果直接运行此脚本 if __name__ == '__main__': sg_presets_settings()