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 )