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

200 lines
6.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import maya.cmds as cmds
from Core import GetMeshes
def create_lod(index):
"""
创建LOD模型
参数:
index (int): LOD级别索引0表示创建所有级别
"""
# 检查并加载Unfold3D插件
if not cmds.pluginInfo("Unfold3D", query=True, loaded=True):
cmds.loadPlugin("Unfold3D")
# 如果索引为0创建所有LOD级别
if index == 0:
for lod in range(1, 8):
create_lod(lod)
return
# 获取当前轴向设置
axis = cmds.upAxis(query=True, axis=True)
axis = "YAxisUp" if axis == "y" else "ZAxisUp"
# 定义网格体列表
meshes = [
"head", "teeth", "saliva", "eyeLeft", "eyeRight",
"eyeshell", "eyelashes", "eyeEdge", "cartilage", "body"
]
# 创建头部组和网格体
head_grp = f"head_lod{index}_grp"
head_mesh = f"head_lod{index}_mesh"
if not cmds.objExists(head_grp):
cmds.group(empty=True, name=head_grp)
if not cmds.objExists(head_mesh):
# 创建LOD网格体
GetMeshes(cml=index)
head_lod = GetMeshes(lod=0)
create_lod = GetMeshes(lod=index)
# 处理每个创建的LOD模型
for c in create_lod:
create = GetMeshes(i=c)
# 跳过索引大于等于50的模型
if c >= 50:
cmds.delete(create)
continue
exist = False
# 检查是否匹配头部LOD模型
for h in head_lod:
if h >= 50:
continue
if any(create.startswith(mesh) for mesh in meshes[:h+1]):
mesh = GetMeshes(m=h)
if cmds.objExists(mesh):
# 处理模型
cmds.parent(create, head_grp)
# 获取UV集
suv = cmds.polyUVSet(mesh, query=True, currentUVSet=True)
tuv = cmds.polyUVSet(create, query=True, currentUVSet=True)
# 检查UV集
if len(suv) != 1:
raise RuntimeError(f"{mesh}: There are multiple uvSet!!!")
if len(tuv) != 1:
raise RuntimeError(f"{create}: There are multiple uvSet!!!")
# 特殊处理eyeshell模型
if create.startswith("eyeshell"):
_process_eyeshell_model(mesh, create, suv[0], tuv[0])
else:
_process_normal_model(mesh, create, suv[0], tuv[0])
exist = True
# 如果模型不存在则删除
if not exist:
cmds.delete(create)
else:
cmds.warning(f"{head_mesh} Existed!!!")
# 处理身体LOD仅适用于LOD0-3
if index < 4:
body_grp = f"body_lod{index}_grp"
body_mesh = f"body_lod{index}_mesh"
if not cmds.objExists(body_grp):
cmds.group(empty=True, name=body_grp)
if not cmds.objExists(body_mesh):
mesh = GetMeshes(m=50)
if cmds.objExists(mesh):
body_index = 50 + index
GetMeshes(cm=body_index)
cmds.parent(body_mesh, body_grp)
# 获取UV集
suv = cmds.polyUVSet(mesh, query=True, currentUVSet=True)
tuv = cmds.polyUVSet(body_mesh, query=True, currentUVSet=True)
# 检查UV集
if len(suv) != 1:
raise RuntimeError(f"{mesh}: There are multiple uvSet!!!")
if len(tuv) != 1:
raise RuntimeError(f"{body_mesh}: There are multiple uvSet!!!")
# 处理身体模型
_process_normal_model(mesh, body_mesh, suv[0], tuv[0])
# 设置显示属性
body_mesh_shape = cmds.listRelatives(body_mesh, shapes=True)
cmds.setAttr(f"{body_mesh_shape[0]}.displayColors", 0)
else:
cmds.warning(f"{body_mesh} Existed!!!")
def _process_eyeshell_model(source, target, source_uv, target_uv):
"""
处理eyeshell模型的特殊UV和属性
"""
# 复制和设置UV
cmds.polyUVSet(source, copy=True, uvSet=source_uv)
cmds.polyUVSet(source, currentUVSet=True, uvSet="uvSet1")
cmds.u3dLayout(
source,
resolution=256,
scale=1,
spacing=0.0029296875,
margin=0.0029296875,
box=[0, 1, 0.5, 1]
)
cmds.polyUVSet(target, copy=True, uvSet=target_uv)
cmds.polyUVSet(target, currentUVSet=True, uvSet="uvSet1")
cmds.u3dLayout(
target,
resolution=256,
scale=1,
spacing=0.0029296875,
margin=0.0029296875,
box=[0, 1, 0.5, 1]
)
# 传输属性
_transfer_attributes(source, target, "uvSet1", "uvSet1")
# 清理UV集
cmds.polyUVSet(source, currentUVSet=True, uvSet=source_uv)
cmds.polyUVSet(source, delete=True, uvSet="uvSet1")
cmds.polyUVSet(target, currentUVSet=True, uvSet=target_uv)
cmds.polyUVSet(target, delete=True, uvSet="uvSet1")
def _process_normal_model(source, target, source_uv, target_uv):
"""
处理普通模型的属性传输
"""
_transfer_attributes(source, target, source_uv, target_uv)
def _transfer_attributes(source, target, source_uv, target_uv):
"""
传输模型属性
"""
# 传输位置、法线和UV
cmds.transferAttributes(
source,
target,
transferPositions=True,
transferNormals=True,
transferUVs=False,
transferColors=False,
sampleSpace=3,
sourceUvSpace=source_uv,
targetUvSpace=target_uv,
searchMethod=3,
flipUVs=False,
colorBorders=True
)
# 传输材质
cmds.transferShadingSets(
source,
target,
sampleSpace=0,
searchMethod=3
)
# 设置边缘和法线
cmds.polySoftEdge(target, angle=180, constructionHistory=True)
cmds.polyNormalPerVertex(target, unFreezeNormal=True)
cmds.delete(target, constructionHistory=True)