Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import plotly.graph_objs as go | |
| import trimesh | |
| import numpy as np | |
| from PIL import Image | |
| import torch | |
| from diffusers import StableDiffusionPipeline | |
| import os | |
| import matplotlib.pyplot as plt | |
| # Load the Stable Diffusion model for text-to-image generation | |
| device = "cuda" if torch.cuda.is_available() else "cpu" | |
| pipeline = StableDiffusionPipeline.from_pretrained("CompVis/stable-diffusion-v1-4").to(device) | |
| # Get the current directory | |
| current_dir = os.getcwd() | |
| # Default object file path | |
| DEFAULT_OBJ_FILE = os.path.join(current_dir, "female.obj") | |
| # Temporary texture file path | |
| TEMP_TEXTURE_FILE = os.path.join(current_dir, "generated_texture.png") | |
| # File path to save the 2D image | |
| OUTPUT_IMAGE_FILE = os.path.join(current_dir, "output_image.png") | |
| DEFAULT_GLB_FILE= os.path.join(current_dir, "vroid_girl1.glb") | |
| def apply_texture(mesh, texture_file): | |
| texture_image = Image.open(texture_file) | |
| uv_coords = mesh.visual.uv | |
| uv_coords = np.clip(uv_coords, 0, 1) | |
| texture_colors = np.array([ | |
| texture_image.getpixel(( | |
| int(u * (texture_image.width - 1)), | |
| int(v * (texture_image.height - 1)) | |
| )) for u, v in uv_coords | |
| ]) | |
| texture_colors = texture_colors / 255.0 | |
| return texture_colors | |
| def display_3d_object(obj_file, texture_file, light_intensity, ambient_intensity, color): | |
| file_extension = obj_file.split('.')[-1].lower() | |
| if file_extension == 'obj': | |
| mesh = trimesh.load(obj_file) | |
| elif file_extension == 'glb': | |
| mesh = load_glb_file(obj_file) | |
| else: | |
| raise ValueError("Unsupported file format. Please upload a .obj or .glb file.") | |
| if texture_file: | |
| colors = apply_texture(mesh, texture_file) | |
| else: | |
| colors = color | |
| ambient_intensity = max(0, min(ambient_intensity, 1)) | |
| fig = go.Figure(data=[ | |
| go.Mesh3d( | |
| x=mesh.vertices[:, 0], | |
| y=mesh.vertices[:, 1], | |
| z=mesh.vertices[:, 2], | |
| i=mesh.faces[:, 0], | |
| j=mesh.faces[:, 1], | |
| k=mesh.faces[:, 2], | |
| facecolor=colors if texture_file else None, | |
| color=color if not texture_file else None, | |
| opacity=0.50, | |
| lighting=dict( | |
| ambient=ambient_intensity, | |
| diffuse=light_intensity, | |
| specular=0.5, | |
| roughness=0.1, | |
| fresnel=0.2 | |
| ), | |
| lightposition=dict( | |
| x=100, | |
| y=200, | |
| z=300 | |
| ) | |
| ) | |
| ]) | |
| fig.update_layout(scene=dict(aspectmode='data')) | |
| return fig | |
| def load_glb_file(filename): | |
| trimesh_scene = trimesh.load(filename) | |
| if isinstance(trimesh_scene, trimesh.Scene): | |
| mesh = trimesh_scene.dump(concatenate=True) | |
| else: | |
| mesh = trimesh_scene | |
| return mesh | |
| def extract_uv_texture(obj_file): | |
| mesh = trimesh.load(obj_file) | |
| if mesh.visual.uv is None or len(mesh.visual.uv) == 0: | |
| raise ValueError("The mesh does not have UV mapping information.") | |
| texture_image = None | |
| if mesh.visual.material.image is not None: | |
| texture_image = mesh.visual.material.image | |
| else: | |
| texture_size = 1024 | |
| texture_image = Image.new('RGB', (texture_size, texture_size), color=(255, 255, 255)) | |
| return texture_image | |
| def generate_clothing_image(prompt): | |
| image = pipeline(prompt).images[0] | |
| image.save(TEMP_TEXTURE_FILE) | |
| return TEMP_TEXTURE_FILE, image | |
| def update_texture_display(prompt, texture_file): | |
| if prompt: | |
| texture_path, image = generate_clothing_image(prompt) | |
| return image | |
| elif texture_file: | |
| return Image.open(texture_file) | |
| return None | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## 3D Object Viewer with Custom Texture, Color, and Adjustable Lighting") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| gr.Markdown("### Texture Options") | |
| prompt_input = gr.Textbox(label="Enter a Prompt to Generate Texture", placeholder="Type a prompt...") | |
| generate_button = gr.Button("Generate Texture") | |
| texture_file = gr.File(label="Upload Texture file (PNG or JPG, optional)", type="filepath") | |
| texture_preview = gr.Image(label="Texture Preview", visible=True) | |
| gr.Markdown("### Lighting & Color Settings") | |
| light_intensity_slider = gr.Slider(minimum=0, maximum=2, step=0.1, value=0.8, label="Light Intensity") | |
| ambient_intensity_slider = gr.Slider(minimum=0, maximum=1, step=0.1, value=0.5, label="Ambient Intensity") | |
| color_picker = gr.ColorPicker(value="#D3D3D3", label="Object Color") | |
| submit_button = gr.Button("Submit") | |
| obj_file = gr.File(label="Upload OBJ or GLB file", value=DEFAULT_OBJ_FILE, type='filepath') | |
| with gr.Column(scale=2): | |
| display = gr.Plot(label="3D Viewer") | |
| extract_button = gr.Button("Extract UV Texture") | |
| output_image = gr.Image(label="Extracted UV Texture", visible=True) | |
| def update_display(file, texture, light_intensity, ambient_intensity, color): | |
| texture_to_use = TEMP_TEXTURE_FILE if os.path.exists(TEMP_TEXTURE_FILE) else texture | |
| return display_3d_object(file, texture_to_use, light_intensity, ambient_intensity, color) | |
| def extract_and_display_uv_texture(file): | |
| uv_texture_image = extract_uv_texture(file) | |
| uv_texture_image.save(OUTPUT_IMAGE_FILE) | |
| return uv_texture_image | |
| submit_button.click(fn=update_display, inputs=[obj_file, texture_file, light_intensity_slider, ambient_intensity_slider, color_picker], outputs=display) | |
| generate_button.click(fn=update_texture_display, inputs=[prompt_input, texture_file], outputs=texture_preview) | |
| texture_file.change(fn=update_texture_display, inputs=[prompt_input, texture_file], outputs=texture_preview) | |
| extract_button.click(fn=extract_and_display_uv_texture, inputs=[obj_file], outputs=output_image) | |
| demo.load(fn=update_display, inputs=[obj_file, texture_file, light_intensity_slider, ambient_intensity_slider, color_picker], outputs=display) | |
| gr.Examples( | |
| examples=[[DEFAULT_OBJ_FILE, None],[DEFAULT_GLB_FILE, None]], | |
| inputs=[obj_file, texture_file], | |
| label="Example Files" | |
| ) | |
| demo.launch(debug=True) | |