MetaFusion/scripts/utils/PresetsSettings.py
2025-02-07 05:10:30 +08:00

255 lines
9.7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import maya.cmds as cmds
import math
from Core import GetMeshes, ReadJson, WriteJson, Descriptor
def presets_settings():
"""
创建预设设置窗口
"""
# 检查主窗口是否存在
if not cmds.window('SuperRiggingEditor', exists=True):
return
# 如果预设窗口已存在则删除
if cmds.window('presetsSettingsWin', exists=True):
cmds.deleteUI('presetsSettingsWin')
# 获取关节信息文件路径
json_file = Descriptor(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="select_vertexs(0, 'head')")
cmds.button(label="Save Head Vertexs", align="center",
command="save_vertexs(0, 'head')")
cmds.separator(height=10, style="in")
cmds.button(label="Select Teeth Vertexs", align="center",
command="select_vertexs(1, 'teeth')")
cmds.button(label="Save Teeth Vertexs", align="center",
command="save_vertexs(1, 'teeth')")
cmds.separator(height=10, style="in")
cmds.button(label="Select EyeLeft Vertexs", align="center",
command="select_vertexs(3, 'eyeLeft')")
cmds.button(label="Save EyeLeft Vertexs", align="center",
command="save_vertexs(3, 'eyeLeft')")
cmds.separator(height=10, style="in")
cmds.button(label="Select EyeRight Vertexs", align="center",
command="select_vertexs(4, 'eyeRight')")
cmds.button(label="Save EyeRight Vertexs", align="center",
command="save_vertexs(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="select_vertexs(50, 'body')")
cmds.button(label="Save Body Vertexs", align="center",
command="save_vertexs(50, 'body')")
cmds.separator(height=10, style="in")
cmds.button(label="Select Neck Vertexs", align="center",
command="select_vertexs(0, 'neck')")
cmds.button(label="Save Neck Vertexs", align="center",
command="save_vertexs(0, 'neck')")
cmds.separator(height=10, style="in")
cmds.button(label="Select HeadEye Vertexs", align="center",
command="select_vertexs(0, 'headEye')")
cmds.button(label="Save HeadEye Vertexs", align="center",
command="save_vertexs(0, 'headEye')")
cmds.separator(height=10, style="in")
cmds.button(label="Select HeadMouth Vertexs", align="center",
command="select_vertexs(0, 'headMouth')")
cmds.button(label="Save HeadMouth Vertexs", align="center",
command="save_vertexs(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="get_closest_point_on_mesh(0)")
cmds.button(label="The Closest Point Of The Body", align="center",
command="get_closest_point_on_mesh(50)")
cmds.button(label="The Closest Point Of The Teeth", align="center",
command="get_closest_point_on_mesh(1)")
cmds.separator(height=10, style="in")
cmds.button(label="Write Joints Default Position", align="center",
command="write_joints_default_position()")
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 select_vertexs(mesh_index, region):
"""
选择指定区域的顶点
Args:
mesh_index: 网格索引
region: 区域名称
"""
open_file = Descriptor(ti="vertexsInfo")
mesh = GetMeshes(m=mesh_index)
vertexs = ReadJson(f=open_file, k=region, t="int")
cmds.select(cl=True)
for vertex in vertexs:
cmds.select(f"{mesh}.vtx[{vertex}]", add=True)
def save_vertexs(mesh_index, region):
"""
保存选中顶点到指定区域
Args:
mesh_index: 网格索引
region: 区域名称
"""
json_file = Descriptor(ti="vertexsInfo")
mesh = GetMeshes(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[]')))
WriteJson(of=json_file, sf=json_file, k=region, t="int", value=indices)
def get_closest_point_on_mesh(mesh_index):
"""
获取最近点
Args:
mesh_index: 网格索引
"""
open_file = Descriptor(ti="jointsInfo")
mesh = GetMeshes(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 = ReadJson(f=open_file, k=key, t="object")
for obj in objects:
joint_name = ReadJson(d=obj, k="joint", t="string")[0]
if mesh_index in [0, 1]:
joint = f"DHIhead:{joint_name}"
index = ReadJson(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 = ReadJson(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 write_joints_default_position():
"""
写入关节默认位置
"""
json_file = Descriptor(ti="jointsInfo")
# 处理身体关节
object_body = ReadJson(f=json_file, k="body", t="object")
for i, obj in enumerate(object_body):
joint_name = ReadJson(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 = WriteJson(d=obj, sf="data", k="translate", t="double", value=pos)
object_body[i] = data
WriteJson(of=json_file, sf=json_file, k="body", t="object", value=object_body)
# 处理头部关节
object_head = ReadJson(f=json_file, k="head", t="object")
for i, obj in enumerate(object_head):
joint_name = ReadJson(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 = WriteJson(d=obj, sf="data", k="translate", t="double", value=pos)
object_head[i] = data
WriteJson(of=json_file, sf=json_file, k="head", t="object", value=object_head)
# 如果直接运行此脚本
if __name__ == '__main__':
presets_settings()