File size: 2,731 Bytes
6f62f26
 
 
 
 
 
bf70016
6f62f26
 
 
 
516de62
6f62f26
 
 
 
 
 
9b2ee46
6f62f26
 
 
 
 
 
 
 
 
 
9b2ee46
6f62f26
 
bf70016
f72b58c
bf70016
516de62
bf70016
9b2ee46
bf70016
f72b58c
bf70016
6f62f26
bf70016
f72b58c
 
6f62f26
f72b58c
 
6f62f26
9b2ee46
6f62f26
 
 
 
 
 
 
 
 
 
 
2d1ede7
bf70016
6f62f26
2d1ede7
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
import gradio as gr
import trimesh
import numpy as np
from PIL import Image
import tempfile

def apply_texture_to_selected(section):
    # Load the original mesh
    mesh = trimesh.load('train.glb', force='mesh')
    im = Image.open('rust_steel.png').convert('RGB')

    # Calculate bounding box coordinates
    bounds = mesh.bounds
    min_bounds, max_bounds = bounds[0], bounds[1]
    mid_x = (max_bounds[0] + min_bounds[0]) / 2
    mid_y = (max_bounds[1] + min_bounds[1]) / 2
    mid_z = (max_bounds[2] + min_bounds[2]) / 2

    # Define sections with indices
    sections = {
        'upper': np.where(mesh.vertices[:, 2] > mid_z)[0],
        'lower': np.where(mesh.vertices[:, 2] <= mid_z)[0],
        'middle': np.where((mesh.vertices[:, 0] >= min_bounds[0]) & (mesh.vertices[:, 0] <= max_bounds[0]) &
                           (mesh.vertices[:, 1] >= min_bounds[1]) & (mesh.vertices[:, 1] <= max_bounds[1]) &
                           (mesh.vertices[:, 2] >= min_bounds[2]) & (mesh.vertices[:, 2] <= max_bounds[2]))[0],
        'top': np.where(mesh.vertices[:, 1] > mid_y)[0],
        'right': np.where(mesh.vertices[:, 0] > mid_x)[0]
    }

    # Select the indices for the specified section
    selected_indices = sections[section]

    # Initialize the UV mapping with default or existing values
    if mesh.visual.kind == 'texture':
        original_uv = mesh.visual.uv
    else:
        original_uv = np.random.rand(len(mesh.vertices), 2)

    # Generate new UV coordinates for the selected region only
    new_uv = np.copy(original_uv)
    new_uv[selected_indices, :] = np.random.rand(len(selected_indices), 2)

    # Create a new material using the texture image
    material = trimesh.visual.texture.SimpleMaterial(image=im)
    new_visuals = trimesh.visual.TextureVisuals(uv=new_uv, material=material)

    # Create a new mesh with the updated visual data
    textured_mesh = trimesh.Trimesh(vertices=mesh.vertices, faces=mesh.faces, visual=new_visuals, validate=True, process=False)

    # Save the modified mesh to a temporary file for Gradio visualization
    temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.glb')
    textured_mesh.export(temp_file.name, file_type='glb')
    temp_file.close()
    return temp_file.name

with gr.Blocks() as app:
    gr.Markdown("### 3D Model Texture Application")
    original_model = gr.Model3D('train.glb', label="Original Model")
    modified_model = gr.Model3D(label="Textured Model")

    section_dropdown = gr.Dropdown(choices=['upper', 'lower', 'middle', 'top', 'right'], label="Select Section")
    button = gr.Button("Apply Texture to Section")
    button.click(apply_texture_to_selected, inputs=section_dropdown, outputs=modified_model)

app.launch()