File size: 3,559 Bytes
346b70f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import numpy as np
from .palette import create_palette, PaletteMapper
from .atlas import create_atlas
from .mesh import apply_atlas

__all__ = ["convert_meshes", "ConversionConfig", "ConversionResult"]


class ConversionConfig:
    def __init__(
        self,
        atlas_size=16,
        face_sampling_ratio=0.1,
        simplify_details=True,
        detail_sensitivity=None,
    ):
        self.atlas_size = atlas_size
        self.face_sampling_ratio = face_sampling_ratio
        self.simplify_details = simplify_details
        self.detail_sensitivity = detail_sensitivity
        self.total_palette_colors = atlas_size * atlas_size


class ConversionResult:
    def __init__(self, meshes, atlas, palette, scene_metadata=None):
        self.meshes = meshes
        self.atlas = atlas
        self.palette = palette
        self.scene_metadata = scene_metadata


def convert_meshes(
    mesh_list,
    atlas_size=16,
    face_sampling_ratio=0.1,
    simplify_details=True,
    detail_sensitivity=None,
    scene_metadata=None,
):
    if not mesh_list:
        raise ValueError("No meshes provided")

    config = ConversionConfig(
        atlas_size, face_sampling_ratio, simplify_details, detail_sensitivity
    )

    print(
        f"Processing {len(mesh_list)} mesh(es) with {config.total_palette_colors}-color palette"
    )

    all_sampled_colors = []
    meshes_with_valid_geometry = []
    mesh_face_colors = {}

    for mesh_name, mesh_object in mesh_list:
        if mesh_object is None or len(mesh_object.faces) == 0:
            print(f"Skipping {mesh_name}: no valid geometry")
            continue

        print(
            f"Analyzing {mesh_name}: {len(mesh_object.faces)} faces, {len(mesh_object.vertices)} vertices"
        )
        meshes_with_valid_geometry.append((mesh_name, mesh_object))

        from .extraction.reader import get_face_colors
        face_colors = get_face_colors(
            mesh_object,
            simplify_details=config.simplify_details,
            detail_sensitivity=config.detail_sensitivity,
        )
        mesh_face_colors[mesh_name] = face_colors

        from .extraction import sample_colors
        face_areas = mesh_object.area_faces if hasattr(mesh_object, "area_faces") else None
        sampled_colors = sample_colors(face_colors, config.face_sampling_ratio, face_areas)
        all_sampled_colors.extend(sampled_colors)

    if not meshes_with_valid_geometry:
        raise ValueError("No valid meshes found")

    combined_color_array = np.array(all_sampled_colors, dtype=np.uint8)
    print(
        f"Total sampled colors: {len(combined_color_array)} from {len(meshes_with_valid_geometry)} mesh(es)"
    )

    quantized_palette = create_palette(combined_color_array, size=config.atlas_size)
    texture_atlas_image, color_to_uv_mapping = create_atlas(
        quantized_palette, size=config.atlas_size
    )
    nearest_color_mapper = PaletteMapper(quantized_palette)

    atlas_applied_meshes = []
    for mesh_name, mesh_object in meshes_with_valid_geometry:
        print(f"Applying atlas to {mesh_name}")
        mesh_with_atlas_texture = apply_atlas(
            mesh_object, texture_atlas_image, color_to_uv_mapping, nearest_color_mapper,
            face_colors=mesh_face_colors[mesh_name]
        )
        atlas_applied_meshes.append((mesh_name, mesh_with_atlas_texture))

    print(f"✓ Successfully processed {len(atlas_applied_meshes)} mesh(es)")

    return ConversionResult(
        atlas_applied_meshes, texture_atlas_image, quantized_palette, scene_metadata
    )