reorg(characters): ship-time folders — lena_base_v01 ships, lane moves to work/lena
REGISTRY rewritten around the central rule: a character folder is born only when a body ships to ariki-game (<character>_base_v<NN> = ship ordinal). lena_nude dissolves accordingly: - characters/female/lena_base_v01/ — SHIPPED 2026-08-10: AccuRig GLB carrier, T-pose/rig FBX + JSON, previews, frozen README - characters/work/lena/ — the live lane: recipes 01-47 (incl. new 36-47: refill/sheets/clay/despeckle/musculature/spin/AccuRig export/graft/pose QC), masters (athletic_v04 blend + textures, accurig blend), lane-history README - hires_claude/hires_work intermediates (blends, logs, probes) pruned Supporting docs: AGENTS.md, working-files rule, rig-graft plan addendum, originals README, prune_lane.py. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,403 @@
|
||||
# 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.
|
||||
|
||||
## RIGGED — `lena_nude_accurig_glb_v01.glb` (2026-08-07)
|
||||
|
||||
First rigged nude Lena. v10's mesh, byte-identical, plus a 101-bone AccuRig skeleton.
|
||||
`45_accurig_export.py` (carrier out) → AccuRig (manual) → `46_graft.py` (skeleton in) →
|
||||
`47_pose_qc.py`. Master `rig/lena_nude_accurig_glb_v01.blend`.
|
||||
|
||||
**No rig bait.** `tools/rigbait_decimate.py` exists because the source GLBs are 1.9M tris and
|
||||
AccuRig refuses them; v10 is 62,929 tris, under the lane's own 78k bait budget, so it went in
|
||||
whole. AccuRig returned the same 31,111 vertices **in the same order**, so weights copy
|
||||
index-to-index — which deletes the decimated→full-res nearest-surface transfer where the July lane
|
||||
mangled the fingers.
|
||||
|
||||
**Three traps, all of which produced a confidently wrong result before being caught:**
|
||||
|
||||
1. **AccuRig ships a `T-Pose` ACTION.** Blender's importer binds it as animation data, and an
|
||||
action re-applies its pose on every evaluation *and every file load*. Clearing pose values
|
||||
while it exists is futile: the in-session assertion passes, the saved file comes back posed,
|
||||
and the body deforms **1.25 units into the air with every edge length unchanged**. Rigid
|
||||
motion — which reads as "weights are fine, the model is gone". `animation_data_clear()` first,
|
||||
then clear the pose, then assert.
|
||||
2. **Verify the DEFORMED result, not the rest mesh.** The first graft asserted vertices hadn't
|
||||
moved and passed — while the armature modifier displaced the whole body. The rest mesh proves
|
||||
nothing; the modifier is what the engine runs.
|
||||
3. **Never pose bones by substring.** `"Upperarm"` also matches `UpperarmTwist01/02`; rotating a
|
||||
twist helper by its parent's angle compounds it and reports 14× edge stretch that looks like
|
||||
broken weights and is entirely self-inflicted.
|
||||
|
||||
Scale (0.576058) and the carrier's 11.77 mm offset are recovered by least-squares fit, not
|
||||
hardcoded, so a re-rig at a different height still lands.
|
||||
|
||||
**Still to come:** the AccuRig→Quaternius conversion. This carries 101 `CC_Base_*` bones; the game
|
||||
standard is the 65-bone Quaternius contract.
|
||||
|
||||
## Athletic build — v10 (2026-08-07), textures/geometry base
|
||||
|
||||
`lena_nude_decimated_glb_v10.glb`, master `hires_claude/athletic/athletic_v04.blend`.
|
||||
**v09's look, with a second geometry despeckle underneath it.** Recipe:
|
||||
`39_despeckle.py --apply` (`SHARP_DEG=55 CLUSTER_MAX=20`) on `refill_v04/final_v06.blend` →
|
||||
`42_musculature.py` (strength 1.0, `SPINE=0.34`).
|
||||
|
||||
Ready to look at without any scripting: **open `athletic/lena_v10_turntable.blend` and press
|
||||
spacebar** — the 50-second turntable is baked into the file.
|
||||
|
||||
Two things this pass settled:
|
||||
|
||||
- **Pick the threshold by sweep, not by feel.** At 55° the speckle caught rises 181 → 441 verts
|
||||
while the anatomy classification is *unchanged* (8 long folds, exactly as at 70°). At 45° it
|
||||
falls to 6 folds — real creases have started merging into the speckle set. 55° is the last
|
||||
threshold that is still free.
|
||||
- **Dissolve the stubborn clusters, do not pointmerge them.** Merging a cluster to a single point
|
||||
leaves a fan vertex in the middle of where the flap was, and on a ring that is not planar that
|
||||
vertex is a new spike: measured, it made folds >70° *worse* (361 → 444). Dissolving the
|
||||
vertices and letting the ring close over improved every band — >30° 2138→1763, >50° 741→524,
|
||||
>70° 361→304, >90° 268→196.
|
||||
|
||||
Converged: a third iteration is a wash (>70° 304 → 312). Mesh 31,504 → 31,111 v, height
|
||||
unchanged. What is left at >70° is mostly the real creases the isolation test is protecting.
|
||||
|
||||
## Athletic build — v09 (2026-08-07), superseded by v10
|
||||
|
||||
`lena_nude_decimated_glb_v09.glb`, master `hires_claude/athletic/athletic_v03.blend`.
|
||||
**v07's anatomy** (v08's additions rejected, left behind the `V08_EXTRAS` flag) with the back seam
|
||||
fixed and a subtle spinal furrow. `42_musculature.py` at strength 1.0, `SPINE=0.34`.
|
||||
|
||||
**The seam down her back was self-inflicted, and the cause is worth remembering.** The spinal
|
||||
groove sits at x = 0 — which is exactly where `24_seams.py` cuts the back midline. So the two
|
||||
sides of the spine live on *opposite edges of the torso chart*, and the atlas-space gradient was
|
||||
differentiating into padding rather than across her body. It drew a hard ragged line down her
|
||||
whole back.
|
||||
|
||||
Fixed by taking the height field's gradient in **3D** and projecting it into per-texel tangent
|
||||
frames. That never asks the atlas who a texel's neighbour is, so it is seam-correct by
|
||||
construction — for the spine and equally for the inner-leg and arm seams, which would have hit
|
||||
the same wall. Tangent maps are smoothed before use: rasterised per face they are
|
||||
piecewise-constant, and a faceted tangent basis facets the normal map.
|
||||
|
||||
Two checks worth repeating on any future field:
|
||||
|
||||
- **Prove which line is yours.** Rendering with `SPINE=0.0` gives a back identical to v06, which
|
||||
is what established the remaining soft line is the furrow and not a leftover artifact.
|
||||
- **A falling max tilt can be good news.** It went 53.8° → 10.9°. The 53.8° *was* the seam
|
||||
discontinuity, not anatomy; the real relief was never that steep.
|
||||
|
||||
Furrow trimmed to u 0.520–0.795 so it fades at the sacrum. Run it to 0.470 and it reaches the
|
||||
glute cleft, meets the crease already in the mesh, and reads ragged.
|
||||
|
||||
## Athletic build — v08 (2026-08-07), REJECTED — second definition pass
|
||||
|
||||
`lena_nude_decimated_glb_v08.glb`, master `hires_claude/athletic/athletic_v02.blend`,
|
||||
`42_musculature.py` at strength 1.25. Adds clavicles, lower rib arch, the inguinal furrow ("V"),
|
||||
glutes with cleft and fold, hamstrings, patella, tibialis, achilles and forearm mass.
|
||||
|
||||
**Two shape-function fixes mattered more than any of the new anatomy**, and both are worth
|
||||
remembering whenever a field is turned into a normal map — because a normal map *is* the
|
||||
derivative of the field, so anything that kinks the field draws a line:
|
||||
|
||||
- `band()` used a **linear clip ramp**, whose derivative jumps at both ends of the window. Every
|
||||
window boundary was drawing a crease. It is a **smoothstep** now, which reaches each end with
|
||||
zero slope.
|
||||
- The front/back selector was the boolean `y < 0`. That terminates every front- or back-only
|
||||
field abruptly at the silhouette — which is what drew the sickle lines down her shins. It is a
|
||||
smooth blend over ~4 cm now.
|
||||
- The per-leg `np.sign(sn) == sg` selector was dropped: it put a hard boundary at x=0 *and* was
|
||||
redundant, since every leg field is already a function of `|x| - legc`.
|
||||
|
||||
## Athletic build — v07 (2026-08-07), first pass, superseded by v08
|
||||
|
||||
`lena_nude_decimated_glb_v07.glb`, master `hires_claude/athletic/athletic_v01.blend`.
|
||||
Recipe `42_musculature.py <in> <out> [glb] [strength]`. **Maps only — geometry untouched, so this
|
||||
is fully reversible and v06 remains the smooth build.**
|
||||
|
||||
Relief goes into the **normal map**, not painted shading. Darkening the albedo to fake a muscle
|
||||
bakes one lighting direction into the skin: it reads as dirt the moment the key light moves and is
|
||||
wrong in every pose. The albedo takes only a 5.5% cavity term, which is what subsurface actually
|
||||
does and which survives relighting.
|
||||
|
||||
This is where the 14-chart atlas pays off a second time. A tangent-space normal *is* the surface
|
||||
gradient in (u,v), so taking the gradient of a height field in atlas space gives one directly —
|
||||
but only if texel density is uniform, or the same slope means different things in different
|
||||
charts. This atlas measures 1.00x spread; on Tripo's 1.8x soup it would have needed per-chart
|
||||
correction.
|
||||
|
||||
Two traps, both of which produced visible garbage before they were fixed:
|
||||
|
||||
- **Evaluate the anatomy per TEXEL, not per vertex.** Building it per vertex and interpolating
|
||||
gave crumpled-paper noise: with ~10 mm edges an ab block is 2-3 vertices across, so the field's
|
||||
gradient is piecewise-constant per triangle and the normal map follows the *triangulation*.
|
||||
Rasterise position, then evaluate the anatomy at texel resolution.
|
||||
- **Measure the landmarks.** The navel was assumed at u 0.523 and is actually at ~0.560 (the
|
||||
front-midline profile peaks at 0.56 and the waist pulls in from 0.57), which put the whole ab
|
||||
stack a band low. The quad centre line was assumed to drift inward going down; her stance has
|
||||
the feet apart so it drifts *outward* (x 0.037 at the hip → 0.106 at the ankle) — `24_seams.py`
|
||||
had already measured it, and using the guess laid the muscle bellies along the edges of the
|
||||
thigh and left contour lines down the leg.
|
||||
|
||||
Breast and crotch are excluded by mask, so the featureless brief survives. Strength 0.55 / 1.0 /
|
||||
1.45 rendered for review (`beauty_str_055`, `beauty_athletic_v01`, `beauty_str_145`); v07 ships
|
||||
1.0. **This departs from the approved turnaround**, which is a smooth mannequin.
|
||||
|
||||
## Smooth body — v06 (2026-08-07)
|
||||
|
||||
`lena_nude_decimated_glb_v06.glb`, master `hires_claude/refill_v04/final_v06.blend`.
|
||||
A second `40_texspeckle.py` pass on v05; geometry and UVs unchanged.
|
||||
|
||||
**Texture despeckling is done — do not run a third pass.** The passes converge fast and then stop
|
||||
mattering:
|
||||
|
||||
| pass | texels touched | effect on the render |
|
||||
|---|---|---|
|
||||
| 1 | 111,212 (0.663%) | flecks visibly gone from chest and belly |
|
||||
| 2 | 12,521 (0.075%) | 3,738 pixels over five views, max Δ 0.059 |
|
||||
| 3 (measured, not run) | 4,426 (0.026%) | would be invisible |
|
||||
|
||||
Every mark still visible is **geometric** — the 361 edges still folding over 70°, mostly in tight
|
||||
concave creases where collapsing them would cost real shape. More texture passes cannot reach
|
||||
those, and past this point each pass trades impurity for plasticity by eroding the grain
|
||||
`36_refill.py` deliberately transplanted.
|
||||
|
||||
## Body — v05 (2026-08-07), superseded by v06
|
||||
|
||||
`lena_nude_decimated_glb_v05.glb`, master `hires_claude/refill_v04/final_v05.blend`.
|
||||
Recipes `39_despeckle.py --apply` → `40_texspeckle.py`.
|
||||
|
||||
**The speckle was two different defects wearing the same face**, and a clay render
|
||||
(`38_clay.py`) is what separated them — as this README has said all along.
|
||||
|
||||
- **Geometry.** 892 edges folding over 70° in 220 isolated clusters. Detection needs *sharpness
|
||||
AND isolation together*: deviation-from-smooth alone flags 33% of the body at this density —
|
||||
her hips score like a defect — and sharpness alone would cut the real crease under the buttock.
|
||||
Smoothing cleared 891 → 335 verts, then stalled: the survivors are **folded** flaps, whose
|
||||
Laplacian target sits inside the fold, so relaxation cannot escape it. Those 126 clusters were
|
||||
collapsed by pointmerge instead. Result 892 → 361 edges >70°, mesh 31,964 → 31,504 v.
|
||||
- **Paint.** The rest was Tripo scan noise baked into the albedo and resampled faithfully by the
|
||||
re-atlas. 31,457 texels of small local-contrast outliers inpainted, with blobs over 400 px and
|
||||
the entire head excluded so lips, brows and eyes are never candidates.
|
||||
|
||||
## Body — v04 (2026-08-06), superseded by v05
|
||||
|
||||
`lena_nude_decimated_glb_v04.glb` — **v03 with the breast and underwear region re-authored.**
|
||||
Texture-only; geometry and UVs are v03's. Recipe `36_refill.py`.
|
||||
|
||||
The fill's low frequencies are a **harmonic solve on the mesh with Dirichlet boundaries**, not an
|
||||
average of nearby skin. That distinction is the whole point: an IDW average (what `05_texture.py`
|
||||
did) does not agree with the skin it abuts, so it lands as a decal with a tone step at the old
|
||||
bra/briefs outline — the ghost. A harmonic fill *equals* her real skin at the mask edge by
|
||||
construction, so a step is impossible rather than merely small. Solving on the mesh rather than in
|
||||
the atlas also keeps the fill continuous across chart seams; the crotch alone straddles the
|
||||
torso and leg charts.
|
||||
|
||||
Grain is transplanted back from clean skin tiles so it is not plastic, and the normal map is
|
||||
flattened with `rm` set to the surrounding-skin median over the same texels — that flatness is what
|
||||
guarantees no nipple or crotch detail can reappear.
|
||||
|
||||
Kills the rusty crotch patch. Against v03: mean pixel |Δ| 0.0028, **nothing over 0.15**, the change
|
||||
concentrated in hip and chest. Her original texture is untouched outside the region.
|
||||
|
||||
## Re-atlased body — v03 (2026-08-06), superseded by v04
|
||||
|
||||
`lena_nude_decimated_glb_v03.glb` — **the v04 bust-matched sculpt, decimated and re-atlased in one
|
||||
milestone.** Supersedes both files in the two sections below. 14 anatomical charts, material
|
||||
exported `doubleSided=true`. Recipe `30_decimate.py` → `24_seams.py` → `31_reatlas.py` (~4 min).
|
||||
|
||||
**The grey tears across her face and underbust are fixed, and they were never holes** — they were
|
||||
backface culling on inward-wound patches. Those patches are wound consistently *within themselves*,
|
||||
so `normals_make_consistent` cannot see them (which is why `30b_fix_winding.py` oscillated and
|
||||
settled at 25 stray triangles, far too few to explain a 15 cm band). Read
|
||||
`HANDOFF_reatlas_v03.md` before re-treading any of it.
|
||||
|
||||
## Re-atlased (2026-08-06) — superseded by v03
|
||||
|
||||
`lena_nude_decimated_glb_v02.glb` — **v01'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.py` →
|
||||
`hires_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.py` → `26_finish.py` →
|
||||
`25_speckle.py --apply` → `29_tone3d.py` → `08_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 3–5 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 saving** — `18/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.
|
||||
Reference in New Issue
Block a user