import html
import json
import os.path
import pathlib
import typing
import urllib.parse
import gradio as gr
try:
root_path = pathlib.Path(__file__).resolve().parents[1]
except NameError:
import inspect
root_path = pathlib.Path(inspect.getfile(lambda: None)).resolve().parents[1]
def get_asset_url(
file_path: pathlib.Path, append: typing.Optional[dict[str, str]] = None
) -> str:
if append is None:
append = {"v": str(os.path.getmtime(file_path))}
else:
append = append.copy()
append["v"] = str(os.path.getmtime(file_path))
return f"/file={file_path.absolute()}?{urllib.parse.urlencode(append)}"
def write_config_file() -> pathlib.Path:
assets = {
"models/hand.fbx": get_asset_url(root_path / "models" / "hand.fbx"),
"models/foot.fbx": get_asset_url(root_path / "models" / "foot.fbx"),
"src/poses/data.bin": get_asset_url(root_path / "src" / "poses" / "data.bin"),
}
MEDIAPIPE_POSE_VERSION = "0.5.1675469404"
mediapipe_dir = root_path / "downloads" / "pose" / MEDIAPIPE_POSE_VERSION
for file_name in [
"pose_landmark_full.tflite",
"pose_web.binarypb",
"pose_solution_packed_assets.data",
"pose_solution_simd_wasm_bin.wasm",
"pose_solution_packed_assets_loader.js",
"pose_solution_simd_wasm_bin.js",
]:
file_path = mediapipe_dir / file_name
if not file_path.exists():
continue
assets[file_name] = get_asset_url(file_path.absolute())
consts = {"assets": assets}
config_dir = root_path / "downloads"
config_dir.mkdir(mode=0o755, parents=True, exist_ok=True)
config_path = config_dir / "config.json"
config_path.write_text(json.dumps(consts))
return config_path
def on_ui_tabs():
with gr.Blocks(analytics_enabled=False) as blocks:
create_ui()
return [(blocks, "3D Openpose", "threedopenpose")]
def create_ui():
try:
from modules.shared import opts
cn_max: int = opts.control_net_max_models_num
use_online: bool = opts.openpose3d_use_online_version
except (ImportError, AttributeError):
cn_max = 0
use_online = False
if use_online:
html_url = "https://zhuyu1997.github.io/open-pose-editor/"
else:
config = {"config": get_asset_url(write_config_file()) or ""}
html_url = get_asset_url(root_path / "pages" / "index.html", config)
with gr.Tabs(elem_id="openpose3d_main"):
with gr.Tab(label="Edit Openpose"):
gr.HTML(
f"""
"""
)
gr.Markdown(
"Original: [Online 3D Openpose Editor](https://zhuyu1997.github.io/open-pose-editor/)"
)
with gr.Tab(label="Send to ControlNet"):
with gr.Row():
send_t2i = gr.Button(value="Send to txt2img", variant="primary")
send_i2i = gr.Button(value="Send to img2img", variant="primary")
with gr.Row():
cn_dropdown_list = [str(i) for i in range(cn_max)]
cn_dropdown_list.insert(0, "-")
with gr.Column(variant="panel"):
pose_image = gr.Image(
label="Pose",
elem_id="openpose3d_pose_image",
)
with gr.Row():
pose_target = gr.Dropdown(
label="Control Model number",
choices=cn_dropdown_list,
value="0" if cn_max >= 1 else "-",
)
pose_download = gr.Button(value="Download")
with gr.Column(variant="panel"):
depth_image = gr.Image(
label="Depth",
elem_id="openpose3d_depth_image",
)
with gr.Row():
depth_target = gr.Dropdown(
label="Control Model number",
choices=cn_dropdown_list,
value="1" if cn_max >= 2 else "-",
)
depth_download = gr.Button(value="Download")
with gr.Column(variant="panel"):
normal_image = gr.Image(
label="Normal",
elem_id="openpose3d_normal_image",
)
with gr.Row():
normal_target = gr.Dropdown(
label="Control Model number",
choices=cn_dropdown_list,
value="2" if cn_max >= 3 else "-",
)
normal_download = gr.Button(value="Download")
with gr.Column(variant="panel"):
canny_image = gr.Image(
label="Canny",
elem_id="openpose3d_canny_image",
)
with gr.Row():
canny_target = gr.Dropdown(
label="Control Model number",
choices=cn_dropdown_list,
value="3" if cn_max >= 4 else "-",
)
canny_download = gr.Button(value="Download")
send_cn_inputs = [
pose_image,
pose_target,
depth_image,
depth_target,
normal_image,
normal_target,
canny_image,
canny_target,
]
send_t2i.click(
None,
send_cn_inputs,
None,
_js="window.openpose3d.sendTxt2img",
)
send_i2i.click(
None,
send_cn_inputs,
None,
_js="window.openpose3d.sendImg2img",
)
pose_download.click(
None,
pose_image,
None,
_js="(v) => window.openpose3d.downloadImage(v, 'pose')",
)
depth_download.click(
None,
depth_image,
None,
_js="(v) => window.openpose3d.downloadImage(v, 'depth')",
)
normal_download.click(
None,
normal_image,
None,
_js="(v) => window.openpose3d.downloadImage(v, 'normal')",
)
canny_download.click(
None,
canny_image,
None,
_js="(v) => window.openpose3d.downloadImage(v, 'canny')",
)
def on_ui_settings():
from modules.shared import OptionInfo, opts
section = ("openpose3d", "3D Openpose Editor")
opts.add_option(
"openpose3d_use_online_version",
OptionInfo(False, "Use online version", section=section),
)
def main():
js_path = root_path / "javascript" / "index.js"
css_path = root_path / "style.css"
original_template_response = gr.routes.templates.TemplateResponse
head = """
"""
head += f"""
"""
def template_response(*args, **kwargs):
res = original_template_response(*args, **kwargs)
res.body = res.body.replace(b"", f"{head}".encode("utf8"))
res.init_headers()
return res
gr.routes.templates.TemplateResponse = template_response
with gr.Blocks(analytics_enabled=False, css=css_path.read_text()) as blocks:
with gr.Tab(label="3D Openpose", elem_id="tab_threedopenpose"):
create_ui()
blocks.launch()
try:
from modules import script_callbacks
script_callbacks.on_ui_tabs(on_ui_tabs)
script_callbacks.on_ui_settings(on_ui_settings)
except ImportError:
main()