Source code for scfile.content.models.mesh

"""Mesh structures."""

from dataclasses import dataclass, field

import numpy as np

from .enums import LinkSpace, UVOrigin, UVSign
from .types import BlendVertexMap, BonesMapping, Colors, LinksIds, LinksWeights, Polygons, Vector2D, Vector3D, Vector4D


[docs] @dataclass class MeshBounds: """Mesh bounding box.""" min: Vector3D = field(default_factory=lambda: np.zeros(3, dtype=np.float32)) max: Vector3D = field(default_factory=lambda: np.zeros(3, dtype=np.float32)) radius: float = 0.0
[docs] @dataclass class BlendShape: """Mesh deformation target.""" name: str = "name" deltas: Vector3D = field(default_factory=lambda: np.zeros((0, 3), dtype=np.float32)) channel: str | None = None
[docs] @dataclass class ModelMesh: """Mesh geometry container.""" name: str = "name" material: str = "material" bounds: MeshBounds = field(default_factory=MeshBounds) polygon_quads: bool = False has_blend_shapes: bool = False mip_factor: float = 0.1 bones: BonesMapping = field(default_factory=dict) skin: int | None = None vertices: Vector3D = field(default_factory=lambda: np.zeros((0, 3), dtype=np.float32)) uv1: Vector2D = field(default_factory=lambda: np.zeros((0, 2), dtype=np.float32)) uv2: Vector2D = field(default_factory=lambda: np.zeros((0, 2), dtype=np.float32)) normals: Vector3D = field(default_factory=lambda: np.zeros((0, 3), dtype=np.float32)) tangents: Vector4D = field(default_factory=lambda: np.zeros((0, 4), dtype=np.float32)) colors: Colors = field(default_factory=lambda: np.zeros((0, 4), dtype=np.uint8)) blend_vertex_map: BlendVertexMap = field(default_factory=lambda: np.zeros(0, dtype=np.uint16)) blend_shapes: list[BlendShape] = field(default_factory=list) links_ids: LinksIds = field(default_factory=lambda: np.zeros((0, 4), dtype=np.uint8)) links_weights: LinksWeights = field(default_factory=lambda: np.zeros((0, 4), dtype=np.float32)) polygons: Polygons = field(default_factory=lambda: np.zeros((0, 3), dtype=np.uint32)) link_space: LinkSpace = LinkSpace.GLOBAL uv_origin: UVOrigin = UVOrigin.TOP_LEFT uv_sign: UVSign = UVSign.POSITIVE @property def max_influences(self) -> int: if self.links_weights.size == 0: return 0 return int((self.links_weights > 0).sum(axis=1).max())