#!/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)