from __future__ import annotations import json from pathlib import Path from PIL import Image ROOT = Path(r"D:\Work_AI\Dansori") APP = ROOT / "DansoriEQ" / "src" / "DansoriEQ.App" HOST = APP / "Assets" / "Live2DHost" PUPPET = APP / "Assets" / "Characters" / "Puppets" / "LeeSoriV2" PLAN = ROOT / "DansoriEQ" / "docs" / "LIVE2D_CHARACTER_INTEGRATION_PLAN.md" def remove_legs_bone() -> None: rig_path = PUPPET / "rig.json" rig = json.loads(rig_path.read_text(encoding="utf-8-sig")) rig["bones"] = [bone for bone in rig["bones"] if bone.get("name") != "legs"] rig["status"] = "new_sheet_overlap_puppet_v4_static_torso_clean_waist" rig["note"] = ( "New LeeSori sheet-based overlap puppet. Torso, waist, lower body, and " "pocketed left hand stay in the base image to avoid doubled outlines, " "green waist ghosting, and awkward hand motion." ) rig_path.write_text(json.dumps(rig, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") def update_css() -> None: path = HOST / "style.css" css = path.read_text(encoding="utf-8") css = css.replace(" right: 17.5%;\n bottom: -20%;\n width: 65%;", " right: 6.5%;\n bottom: -65%;\n width: 87%;") path.write_text(css, encoding="utf-8") def make_qa() -> None: src = Image.open(PUPPET / "leesori_v2_source.png").convert("RGBA") width, height = 390, 600 stage = Image.new("RGBA", (width, height), (16, 16, 18, 255)) target_w = int(width * 0.87) target_h = int(target_w * src.height / src.width) resized = src.resize((target_w, target_h), Image.Resampling.LANCZOS) right = int(width * 0.065) bottom = int(height * -0.65) x = width - target_w - right y = height - target_h - bottom stage.alpha_composite(resized, (x, y)) stage.convert("RGB").save(PUPPET / "qa_view_390x600_knee_upper.png") def update_plan() -> None: entry = """ ### 2026-07-04 - LeeSoriV2 Knee-Up Framing and Lower-Body Outline Fix User request: - Frame LeeSori from around the midpoint between above-knee and left-hand tip up to the top of the head. - Fix the doubled green outline around both legs that appeared while the lower body moved. Changed: - Updated WebView puppet framing: - `right: 6.5%` - `bottom: -65%` - `width: 87%` - Removed the animated `legs` bone from `LeeSoriV2/rig.json`. - The lower body now remains only in the base image, so the green pants side line no longer alternates between one and two outlines. QA artifact: - `src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriV2/qa_view_390x600_knee_upper.png` """ text = PLAN.read_text(encoding="utf-8") if "LeeSoriV2 Knee-Up Framing" not in text: PLAN.write_text(text.rstrip() + entry + "\n", encoding="utf-8") def main() -> None: remove_legs_bone() update_css() make_qa() update_plan() if __name__ == "__main__": main()