Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import asyncio | |
| import os | |
| import subprocess | |
| import shutil | |
| import threading | |
| from concurrent.futures import ThreadPoolExecutor | |
| import logging | |
| logging.basicConfig(level=logging.INFO) | |
| iframe_html = """ | |
| <iframe src="http://localhost:8080" width="100%" height="500" style="border:none;"></iframe> | |
| """ | |
| async def run_simulation(data_path, config_path): | |
| proc = await asyncio.create_subprocess_exec( | |
| "python3", "GarmentCode/pattern_data_sim.py", | |
| "--data", data_path, | |
| "--config", config_path | |
| ) | |
| await proc.wait() # дождаться завершения процесса | |
| return | |
| async def run_fitting(data_path, config_path): | |
| proc = await asyncio.create_subprocess_exec( | |
| "python3", "GarmentCode/pattern_fitter.py", | |
| "--data", data_path, | |
| "--config", config_path | |
| ) | |
| await proc.wait() # дождаться завершения процесса | |
| return | |
| def organize_images_into_structure(source_folder, new_folder): | |
| os.makedirs(new_folder, exist_ok=True) | |
| for file_name in os.listdir(source_folder): | |
| source_file = os.path.join(source_folder, file_name) | |
| if os.path.isfile(source_file) and file_name.lower().endswith(('.png', '.jpg', '.jpeg')): | |
| folder_name = os.path.splitext(file_name)[0] | |
| subfolder_path = os.path.join(new_folder, folder_name, "outputs") | |
| os.makedirs(subfolder_path, exist_ok=True) | |
| destination_file = os.path.join(subfolder_path, file_name) | |
| shutil.copy(source_file, destination_file) | |
| smpl_thread = None | |
| smpl_process = None | |
| def run_smpl(): | |
| global smpl_process | |
| # Запускаем процесс и храним ссылку на него | |
| smpl_process = subprocess.Popen([ | |
| "python3", "smpl_visualizer.py", | |
| "--model-path", "./SMPL_FEMALE.npz" | |
| ]) | |
| smpl_process.wait() # Ждём завершения процесса | |
| def stop_smpl(): | |
| global smpl_process | |
| if smpl_process and smpl_process.poll() is None: | |
| smpl_process.terminate() # Мягко завершить | |
| try: | |
| smpl_process.wait(timeout=1) | |
| except subprocess.TimeoutExpired: | |
| smpl_process.kill() # Форсированно убить, если не завершился | |
| smpl_process = None | |
| def clear_render(): | |
| global smpl_thread | |
| stop_smpl() | |
| if smpl_thread and smpl_thread.is_alive(): | |
| smpl_thread.join() | |
| smpl_thread = threading.Thread(target=run_smpl, daemon=True) | |
| smpl_thread.start() | |
| return gr.skip() | |
| def update_submenu(clothing_type): | |
| if clothing_type == "Top": | |
| return ( | |
| gr.Dropdown(visible=True, label="Front Collar", | |
| choices=["CircleNeckHalf", "CurvyNeckHalf", "VNeckHalf", "SquareNeckHalf", | |
| "TrapezoidNeckHalf", "CircleArcNeckHalf", "Bezier2NeckHalf"], | |
| interactive=True), | |
| gr.Dropdown(visible=True, label="Back Collar", | |
| choices=["CircleNeckHalf", "CurvyNeckHalf", "VNeckHalf", "SquareNeckHalf", | |
| "TrapezoidNeckHalf", "CircleArcNeckHalf", "Bezier2NeckHalf"], | |
| interactive=True) | |
| ) | |
| elif clothing_type == "Down": | |
| return ( | |
| gr.Dropdown(visible=True, label="Waist Style", | |
| choices=["High Waist", "Low Waist", "Medium Waist"], | |
| interactive=True), | |
| gr.Dropdown(visible=False, interactive=True) | |
| ) | |
| elif clothing_type == "Full body": | |
| return ( | |
| gr.Dropdown(visible=True, label="Overall Style", | |
| choices=["Slim Fit", "Loose Fit", "Regular Fit"], | |
| interactive=True), | |
| gr.Dropdown(visible=False, interactive=True) | |
| ) | |
| else: | |
| return ( | |
| gr.Dropdown(visible=False, interactive=True), | |
| gr.Dropdown(visible=False, interactive=True) | |
| ) | |
| with gr.Blocks(title="3D Garment Generator", theme=gr.themes.Default(text_size="sm")) as demo: | |
| front_collar = gr.State() | |
| back_collar = gr.State() | |
| with gr.Row(): | |
| # Левая колонка: рендер и кнопки | |
| with gr.Column(scale=3): | |
| viewer = gr.HTML(iframe_html, label="3D Рендер") | |
| sim_button = gr.Button("Запустить симуляцию",variant="primary", | |
| scale=2,inputs=[gr.State("GarmentCode/pattern_data_sim.py"), | |
| gr.State("GarmentCode/configs/pattern_data_sim.json")], | |
| ) | |
| fit_button = gr.Button("Запустить фитинг",variant="primary", | |
| scale=2,inputs=[gr.State("GarmentCode/pattern_fitter.py"), | |
| gr.State("GarmentCode/configs/pattern_fitter.json")], | |
| ) | |
| with gr.Row(): | |
| save_render_btn = gr.Button("Сохранить рендер") | |
| save_obj_btn = gr.Button("Сохранить OBJ") | |
| clear_button = gr.Button("Очистить") | |
| zip_file = gr.File(label="Download Zip File") | |
| # Правая колонка: загрузки и параметры | |
| with gr.Column(scale=1): | |
| gr.Markdown("### Параметры генерации") | |
| with gr.Row(): | |
| pattern_upload = gr.File( | |
| label="1. Лекала (JSON/SVG)", | |
| file_types=[".json", ".svg"], | |
| height=120 | |
| ) | |
| body_upload = gr.File( | |
| label="2. Тело (OBJ/GLB/GLTF/FBX)", | |
| file_types=[".obj", ".glb", ".gltf", ".fbx"], | |
| height=120 | |
| ) | |
| with gr.Row(): | |
| pattern_specs = gr.File( | |
| label="3.Спецификация (JSON/YAML)", | |
| file_types=[".json", ".yaml"], | |
| height=120 | |
| ) | |
| with gr.Accordion("4. Параметры генерации", open=True): | |
| clothing_type_dropdown = gr.Dropdown( | |
| label="Тип одежды", | |
| choices=["Top", "Down", "Full body"], | |
| value="Top", | |
| interactive=True | |
| ) | |
| front_dropdown = gr.Dropdown( | |
| visible=False, | |
| label="Front Collar", | |
| choices=[], | |
| interactive=True | |
| ) | |
| back_dropdown = gr.Dropdown( | |
| visible=False, | |
| label="Back Collar", | |
| choices=[], | |
| interactive=True | |
| ) | |
| overall_length = gr.Slider( | |
| 1, 50, value=25, label="Длина одежды", | |
| info="Выберите значение от 1 до 50", | |
| interactive=True | |
| ) | |
| clothing_type_dropdown.change( | |
| fn=update_submenu, | |
| inputs=clothing_type_dropdown, | |
| outputs=[front_dropdown, back_dropdown] | |
| ) | |
| ## Button callbacks ## | |
| sim_button.click( | |
| fn=run_simulation, | |
| inputs=[gr.State("GarmentCode/pattern_data_sim.py"), gr.State("GarmentCode/configs/pattern_data_sim.json")], | |
| outputs=viewer | |
| ) | |
| fit_button.click( | |
| fn=run_fitting, | |
| inputs=[gr.State("GarmentCode/pattern_fitter.py"), gr.State("GarmentCode/configs/pattern_fitter.json")], | |
| outputs=viewer | |
| ) | |
| clear_button.click( | |
| fn=clear_render, | |
| outputs=viewer | |
| ) | |
| # def run_smpl(): | |
| # subprocess.run([ | |
| # "python3", "smpl_visualizer.py", | |
| # "--model-path", "/Users/user/Downloads/SMPL/SMPL_julia/SMPL_FEMALE.npz" | |
| # ]) | |
| if __name__ == "__main__": | |
| smpl_thread = threading.Thread(target=run_smpl) | |
| smpl_thread.start() | |
| demo.launch(share=True) | |