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 = """ """ 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)