200 lines
6.4 KiB
Python
200 lines
6.4 KiB
Python
|
||
#!/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) |