# SPDX-License-Identifier: MIT OR GPL-3.0-or-later from dataclasses import dataclass from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from bpy.types import Mesh, Object @dataclass class MaterialInfo: """材质信息数据类""" name: str index: int face_count: int is_skin: bool def find_body_mesh(armature: "Object") -> Optional["Object"]: """ 在Armature的子对象中查找名为"Body"的网格对象 Args: armature: Armature对象 Returns: Body网格对象,如果不存在则返回None """ if armature is None: return None for child in armature.children: if child.type == "MESH" and child.name == "Body": return child return None def is_skin_material(material_name: str) -> bool: """ 判断材质是否为皮肤材质 Args: material_name: 材质名称 Returns: 如果材质名包含"SKIN"则返回True(不区分大小写) """ return "SKIN" in material_name.upper() def get_material_face_count(mesh: "Mesh", material_index: int) -> int: """ 获取指定材质的面数量 Args: mesh: 网格数据 material_index: 材质索引 Returns: 使用该材质的面数量 """ count = 0 for polygon in mesh.polygons: if polygon.material_index == material_index: count += 1 return count def generate_unique_name(base_name: str, existing_names: set[str]) -> str: """ 生成唯一的对象名称 Args: base_name: 基础名称 existing_names: 已存在的名称集合 Returns: 唯一的名称 """ if base_name not in existing_names: return base_name suffix = 1 while True: candidate = f"{base_name}.{suffix:03d}" if candidate not in existing_names: return candidate suffix += 1