255 lines
9.7 KiB
Python
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() |