Files
animation/characters/female/lena_nude
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
..

lena_nude — nude body variant (WIP, not released)

Lena's body with the underwear removed: no bra, no briefs, breasts with volume and no nipples, smooth featureless crotch. Staged here until it is approved for the game.

file role
lena_nude_quatskin_glb_v01.glb the body — 65-bone Quaternius game skeleton, texture embedded (self-contained)
lena_nude_basecolor.png the baked albedo, loose, for further iteration

Ship name at release is Ariki_Female_QuatSkin_Nude.glb in ariki-game/assets/quaternius/derived-bodies/. Per ../../REGISTRY.md rule 8 that rename happens exactly once, on import — never create Ariki_* files in this repo.

How it was made

Generators live in this repo (moved out of ariki-game 2026-08-06 — they author a character, so ../../REGISTRY.md governs them; see .agents/wiki/ARCHITECTURE.md "Tool provenance"). They still read the canonical rigged bodies from the game repo (Ariki_Female_QuatSkin.glb and the _ChestV1 breast-sculpt donor), resolved via $ARIKI_GAME or a sibling ariki-game/ checkout — if neither resolves they abort with the path they tried, rather than reading the wrong file. Run from C:\Users\Jeremy\tinqs\animation:

blender --background --python tools/_bake_nude_body_texture.py
    # defaults to writing lena_nude_basecolor.png into THIS folder

blender --background --python tools/make_lena_nude_body.py -- \
    --out     characters/female/lena_nude/lena_nude_quatskin_glb_v01.glb \
    --size    1.0 \
    --texture characters/female/lena_nude/lena_nude_basecolor.png

python tools/verify_body_variant.py \
    characters/female/lena_nude/lena_nude_quatskin_glb_v01.glb

--size is breast volume as a multiple of the _ChestV1 sculpt (0.75 / 1.0 / 1.25 were rendered for review; v01 ships 1.0). A new size is a version bump, not a new variant — same recipe, different parameter. (This README and ../../REGISTRY.md both called the flag --scale until 2026-08-06; the script has always parsed --size.)

Facts worth knowing before editing this

  • The underwear is the body surface. A ray-crossing census finds exactly two surface crossings at every height — thigh, belly, bra cup, briefs alike. There is no skin underneath, so the garment can only be flattened into the skin, never deleted. Deleting it opens a hole, which is precisely the defect in the game repo's Ariki_Female_QuatSkin_Bare.glb (black cavity across the chest, visible even untextured). Do not use _Bare geometry for anything.
  • The base mesh is not watertight (3,809 boundary edges). The painted underwear was hiding open slits; with it gone they read as a dotted line of black triangles, so the builder welds them shut in the torso band. That is where this file's lower vertex count comes from.
  • Use clay renders to judge geometry. tools/_render_body_closeup.py --clay drops the material; it is the only reliable way to tell a mesh defect from a painted one. Several dead ends here came from mistaking painted bra shadow for a dent, and vice versa.

Working files

This lane follows .agents/rules/working-files.md: a version is a milestone, not a step. Fixing the bra produces one saved file at the end, not one per cut.

hires_claude/.lanekeep pins the only .blend files that survive here — the masters named in the Derived-artifacts table of ../../REGISTRY.md, plus the live chain head. Everything else a step script wrote is scratch: the NN_*.py recipe plus masks.npz regenerates it from the master above it.

python tools/prune_lane.py characters/female/lena_nude --recursive   # dry run

Two things this lane learned the hard way:

  • Check for a running Blender before pruning. A heal step takes ~7 minutes and writes only at the end; the lane gained a new head (17_healed.blend) during the audit that produced this section.
  • hires_work/ is the abandoned GLM-agent attempt (see its glm_run_attempt*.log), superseded by hires_claude/. It has no .lanekeep, so every .blend in it classifies as scratch.

The root-level lena_sculpt_glb_v01-nude-Zephyr.blend is hand-authored — no step script rebuilds it — so the pruner reports it as UNKNOWN and never touches it. Decide its fate by hand.

Status

Verified against the canonical body: 1 primitive, identical attribute set (no tangents), material MI_Body_Lena, 65 joints in identical order, height 1.777 m, inverse-bind drift 4.6e-6, weights normalised, texture embedded. Posed sweep under a UAL clip is clean (no spikes or tearing).

Known cosmetic limits: a faint tonal seam where the fill meets untouched skin at extreme zoom, and no skin-pore detail inside the filled area — that smoothness is also what guarantees no nipple or crotch detail can appear.

Full history and the reasoning behind each choice: ~/.claude/plans/i-have-a-lena-velvet-ripple.md.

v04 — bust matched to the approved concept turnaround (2026-08-06)

lena_nude_sculpt_glb_v04.glb, master hires_claude/34_v04.blend. Recipes 32_ref_measure.py (measure) → 33_bust_variants.py (size study) → 34_apply_bust.py (k=0.5).

Guiding art: exchange/INBOX/lena-base-turnaround/ — front/side/back T-pose renders, GPT Image 2, approved by Can 2026-08-06.

The reference is the same character, not a new one. Measured against the front/side silhouettes:

landmark reference v03 mesh
heads tall 6.43 6.08
waist / hip 0.504 0.505
waist width 0.1260 H 0.1318 H
hip width 0.2500 H 0.2608 H
bust projection +0.0156 H +0.0210 H

Proportions already agree and the widths sit inside silhouette-threshold noise for generated art, so only the bust was changed: the breast forms are rescaled to 50% of their projection off a bi-harmonic chest wall, landing at +0.0155 H. Nothing outside the chest region moves (verified 0.0000 mm) and height is unchanged, so every v03 heal survives.

Two traps for whoever tunes this next:

  • The projection metric saturates below k≈0.5 — k=0.35 measures +0.0154, indistinguishable from k=0.5. Below that the "deepest slice" row migrates and stops tracking breast volume, so the number cannot be pushed lower meaningfully. Treat 0.5 as a floor, not a midpoint. The reference reading may also be inflated by the T-pose arm crossing the chest in a side view, which would mean the real reference bust is smaller still.
  • Front renders cannot tell the sizes apart. k=0.5, 0.65 and 0.8 look identical head-on because the frontal key light flattens the chest. Judge from the side view only. Variants are in hires_claude/review_33/k{100,080,065,050,035}/.

Re-running at another k takes seconds: _bust_wall_cache.npy holds the 8-minute chest-wall solve.

Not addressed, and the largest remaining gap to the concept art: the reference is a smooth mannequin with no scan noise, while this mesh still carries speckles and dents on the hips and thighs, plus the untouched original head.

Decimated for the retexture / re-atlas lane (2026-08-06)

lena_nude_decimated_glb_v01.glb — v03 collapsed to the game-body budget (31,964 v / 64,957 tris, ratio 0.037728) as input for hires_claude/24_seams.py. Recipe 30_decimate.py + 30b_fix_winding.py. Read HANDOFF_decimated_v01.md before working on it — in particular, its carried UVs are scrap (collapse shreds Tripo's 5,870-chart atlas) and it ships with 25 known backfacing triangles.

Re-atlased (2026-08-06)

lena_nude_decimated_glb_v02.glbv01's geometry with a new UV atlas and resampled maps. Same 31,964 v / 64,957 tris; Tripo's 5,870 charts replaced by 14 anatomical ones (coverage 62.0 → 68.6%, texel-density spread 1.8× → 1.00×). Recipe hires_claude/24_seams.pyhires_claude/31_reatlas.py. It deliberately looks identical to v01 (mean pixel |Δ| 0.0012 across five views) — the win is a paintable, uniform-density layout, not a new look. Read HANDOFF_reatlas_v02.md, especially the colorspace and unwrap-solver traps, and note that the grey tears on the face/underbust are v01's dangling-flap defect and are still there.

Hi-res sculpt v03 (2026-08-06) — Jeremy's three notes on v02

lena_nude_sculpt_glb_v03.glb, masters hires_claude/27_clean.blend (geometry) and 29b_final.blend (textured). Recipes: 17_line_heal.py26_finish.py25_speckle.py --apply29_tone3d.py08_export.py.

note measured outcome
cut lines shading kinks >12° 9704 → ~6900; flipped faces (the black dashes) 1511 → 10. Ribcage and thigh lines gone frontally; waistband + underbust still legible under raking light
discoloured bra/crotch on-body tone gap, patch interior vs surrounding skin: 0.0102 → 0.0068 luma. The pale panels in beauty_v02_healed/ are gone in beauty_v03b/
cleavage sternum fillet radius 9.5 mm → no sharp sample at any height; notch depth 44 → 31 mm

Four dead ends this version ruled out — do not repeat them

  1. The lines are not cracks; do not weld. Stage 15 assumed the panel seams were disconnected vertex runs. They are not: the mesh has only 830 boundary edges in 689 loops of 35 edges, and for kink verts the nearest vertex outside the 3-ring sits at 1.58× the local edge length (median) against 1.73× for control skin. Welding at eps 1.2 mm — about the 1.85 mm mean edge length — merged ordinary neighbours and tore the mesh, 830 → 24k boundary edges.
  2. They are not in the custom normals either. Corner-vs-vertex deviation is 0.008° mean, 15 loops above 5°; clearing custom split normals changes nothing.
  3. A membrane is the wrong operator, and widening it is worse. The relief is ONE VERTEX WIDE (0.23 mm median at the centre, back to the 0.074 mm background by ring 2), so a collar-fixed membrane pins itself to the defect's own shoulders. GROW 4 and 8 were no better than GROW 2 while moving material up to 38 mm. A ring median is correct: it deletes a 1-vertex outlier and returns anything broader unchanged, so the underbust fold, clavicles and navel survive by construction instead of by a tuned threshold.
  4. Never level tone from atlas-adjacent texels. A Poisson solve whose boundary condition was the mismatch against UV neighbours turned the patches into pale grey panels — UV adjacency is not body adjacency, so the border mismatch came from other body parts and gutter. This is the warning already in 05_texture.py's header. Sample on the body (KD over skin verts in 3D), smooth the correction over the mesh graph, then rasterise.

Two process traps worth keeping: restore the real material before saving18/20/25 originally rendered clay last and then saved, so the file on disk kept the clay material and lost its texture wiring, which is why the first tone attempt aborted with "could not find the wired basecolor". And the pristine textures are not inside working blends: Blender purges the orphan .002/.003 copies on save, so read them from 00_welded.blend.

Still open: 1649 non-manifold and 830 boundary edges — bmesh.ops.holes_fill, the edit-mode mesh.fill_holes operator, and a per-loop pass all refused every one, which is why normals_make_consistent could only reach 1198 of 1511 flipped faces before explicit per-face reversal finished the job. None of this is propagated to the game body (lena_nude_quatskin_glb_v01.glb), which is built independently on the 65-bone Quaternius rig.