Files
animation/characters/female/lena_nude/hires_claude/dbg_bow.py
T
jeremy 3ba86b2ea8 feat: clothing lane, character sources, and DCC bridges
Bulk import of the working lanes that were living untracked on the PC.

Content:
- characters/  Lena/male body lanes, bakes, texture work, run logs
- clothing/    garment pipeline, configs, gates, contract docs
- garments/    MD-authored garment sources (.zprj/.zpac)
- UAL-Lib/     Universal Animation Library 2 source (.blend/.fbx/.glb)
- tools/       blender_bridge, iclone_bridge, md_bridge, tailor, glm_agent
- docs/, plans/, dev/, .agents/plans/

Repo hygiene:
- .gitattributes: LFS now covers .blend, .zprj, .zpac, .obj, .npy and the
  Reallusion .iAvatar/.ccAvatar/.ccRestore containers. Without this the
  ~3.8 GB in this commit would land as raw blobs. .png/.jpg are left out
  on purpose — ~250 are already tracked raw and converting them would
  rewrite every one without shrinking history.
- .gitignore: exclude /accurig/ (~1 GB AccuRig program files, redistributable
  from Reallusion, nothing authored here) and /dev/null/ (git-lfs hook copies
  dropped by a `>/dev/null` redirect on Windows).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 15:55:43 -07:00

28 lines
1.5 KiB
Python

import bpy, sys
import numpy as np
W = r"C:\Users\Jeremy\tinqs\animation\characters\female\lena_nude\hires_claude"
bpy.ops.wm.open_mainfile(filepath=W + r"\00_welded.blend")
ob = max([o for o in bpy.data.objects if o.type=='MESH'], key=lambda o: len(o.data.vertices))
n = len(ob.data.vertices)
co0 = np.empty(n*3); ob.data.vertices.foreach_get("co", co0); co0 = co0.reshape(-1,3)
bpy.ops.wm.open_mainfile(filepath=W + r"\03_sculpted.blend")
ob = max([o for o in bpy.data.objects if o.type=='MESH'], key=lambda o: len(o.data.vertices))
co1 = np.empty(n*3); ob.data.vertices.foreach_get("co", co1); co1 = co1.reshape(-1,3)
disp = np.linalg.norm(co1-co0, axis=1)
M = np.load(W + r"\masks.npz")
A = np.load(W + r"\masks_active.npz")
act = A["active"]; garment = M["garment"]; cups = M["cups"]; shield = M["shield"]
# regions to interrogate (welded coords)
zones = {
"bow": (np.abs(co0[:,0])<0.03) & (co0[:,2]>0.715) & (co0[:,2]<0.760) & (co0[:,1]<-0.05),
"strap_tuft":(np.abs(co0[:,0])>0.035)&(np.abs(co0[:,0])<0.09)&(co0[:,2]>0.80)&(co0[:,2]<0.86),
"armpit": (np.abs(co0[:,0])>0.10)&(np.abs(co0[:,0])<0.15)&(co0[:,2]>0.66)&(co0[:,2]<0.75)&(co0[:,1]>-0.02),
"good_cup": (np.abs(co0[:,0])>0.03)&(np.abs(co0[:,0])<0.06)&(co0[:,2]>0.66)&(co0[:,2]<0.70)&(co0[:,1]<-0.06),
}
for nm, m in zones.items():
if not m.sum():
print(nm, "EMPTY"); continue
print(f"{nm}: n={m.sum():6d} garment={100*garment[m].mean():5.1f}% act={100*act[m].mean():5.1f}% "
f"disp mm p50={np.median(disp[m])*1000:.2f} p90={np.percentile(disp[m],90)*1000:.2f}")
print("DBG_BOW_DONE")