GarmentCode / app.py
qbhf2's picture
Update app.py
26976a8 verified
raw
history blame
9.6 kB
import gradio as gr
import asyncio
import os
import subprocess
import shutil
import threading
from concurrent.futures import ThreadPoolExecutor
import logging
import json
logging.basicConfig(level=logging.INFO)
iframe_html = """
<iframe src="http://0.0.0.0:8080" width="100%" height="500" style="border:none;"></iframe>
"""
DEFAULT_PATTERN_SPEC = "GarmentCode/assets/Patterns/shirt_mean_specification.json"
DEFAULT_SIM_CONFIG = "GarmentCode/assets/Sim_props/default_sim_props.yaml"
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_garment_sim(pattern_spec_file, sim_config_file):
pattern_path = getattr(pattern_spec_file, 'name', pattern_spec_file) if pattern_spec_file else DEFAULT_PATTERN_SPEC
config_path = getattr(sim_config_file, 'name', sim_config_file) if sim_config_file else DEFAULT_SIM_CONFIG
if not pattern_path or not config_path:
logging.critical(ValueError, "Не выбран файл спецификации паттерна или конфигурации симуляции.")
proc = await asyncio.create_subprocess_exec(
"python3", "GarmentCode/test_garment_sim.py",
"-p", pattern_path,
"-s", config_path,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
stdout, stderr = await proc.communicate()
if proc.returncode != 0:
print(stderr.decode())
raise RuntimeError("Simulation failed")
# Найти последнюю строку с JSON
lines = stdout.decode().splitlines()
for line in reversed(lines):
try:
result = json.loads(line)
return gr.Files(result["result_dir"])
except Exception:
continue
raise RuntimeError("Result path not found in output")
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", "custom_utils/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",size="sm",
inputs=[gr.State("GarmentCode/pattern_data_sim.py"),
gr.State("GarmentCode/configs/pattern_data_sim.json")],
)
fit_button = gr.Button("Запустить фитинг",variant="primary",size="sm",
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.Row():
sim_config = gr.File(
label="4. Конфигурация симуляции (JSON/YAML)",
file_types=[".json", ".yaml"],
height=120
)
with gr.Accordion("5. Параметры генерации", 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_garment_sim,
inputs=[pattern_specs, sim_config],
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
)
if __name__ == "__main__":
smpl_thread = threading.Thread(target=run_smpl)
smpl_thread.start()
demo.launch(share=True)