Files
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

5.9 KiB

GLM advice (glm-4.6 via api.z.ai)

1. Weld+Decimate Strategy

Do not use Collapse Decimate directly on 4.3M verts. It is computationally expensive (O(N \log N) or worse depending on implementation) and creates chaotic, sliver triangles that destroy the silhouette of pleats and deform poorly.

Better Approach:

  1. Clean: bpy.ops.mesh.merge_objects() or bpy.ops.mesh.remove_doubles(threshold=0.0001) to weld the MD "soup".
  2. Retopologize (Quadriflow): Use bpy.ops.object.quadriflow_remesh(target_face_count=1600).
    • Why: Quadriflow generates a consistent quad flow that preserves curvature and sharp features (pleat edges) far better than decimation. It handles the high-density input robustly and outputs a mesh that deforms cleanly for skinning.
    • Scripting Note: Quadriflow is deterministic in Blender 5.1 headless mode if you set seed and use_mesh_symmetry=False.
  3. Alternative (Faster): Decimate -> Unsubdivide.
    • MD meshes are grid-based. bpy.ops.object.decimate(ratio=0.5, mode='UNSUBDIVIDE') iteratively removes edge loops while maintaining the grid structure. This preserves the "flow" of the fabric better than Collapse, which eats holes in the mesh.

2. Skirt Weighting Recipe

Nearest-vertex transfer is incorrect for skirts; it creates a "hard" seam where the skirt splits to follow the legs.

Standard Recipe: "Pelvic Lock with Geometric Falloff"

  1. Initial Transfer: Perform your standard KDTree transfer to get base weights.
  2. Geometric Masking: Define a "Skirt Zone" via Python (e.g., all vertices with local Y < hip_joint_y).
  3. Nullify Leg Weights: Iterate vertices in the Skirt Zone. Force vertex_groups["Thigh_L"].weight = 0.0 and vertex_groups["Thigh_R"].weight = 0.0.
  4. Pelvic Dominance: Set vertex_groups["Hips"].weight = 1.0 (or Spine if Hips is unweighted in your source).
  5. Transition Blend: Select vertices in a band around the waist (e.g., hip_joint_y - 0.05m < y < hip_joint_y). Run bpy.ops.object.vertex_group_smooth(iterations=3) to blend the sharp cut between the Pelvis-locked skirt and the torso-weighted bodice.
  6. Normalize: bpy.ops.object.vertex_group_normalize_all().

3. Multi-Layer Shrinkwrap Pitfalls

Pitfall: "Snapping through." If you shrinkwrap the Bow to the Body, it will clip inside the Bodice. If you use "Nearest Surface" without care, the Bow might wrap around the back of the Bodice.

Solution: Sequential Shrinkwrapping & Projection

  1. Pass 1 (Bodice): Shrinkwrap Bodice to Body. Mode: Project (along normal). Offset: 2mm (fabric thickness).
  2. Pass 2 (Bow): Shrinkwrap Bow to Bodice (not Body). Mode: Project. Offset: 4mm (Bodice thickness + air gap).
  3. Vertex Group Masking: Crucial for the Bow. Assign a Vertex Group to only the "knot" area of the Bow. Restrict the Shrinkwrap modifier to this group so the loops float freely but the knot sits tight.

4. Re-posing Sleeves (Arms-Down to T-Pose)

Cleanest Scripted Approach: Bind & Apply Do not try to geometrically rotate the mesh; it will twist the UVs and volume.

  1. Transfer Weights: Copy weights from T-pose Lena to the Arms-Down Garment (using DATA_TRANSFER, 'Nearest Face Interpolated'). Even though the poses differ, this maps the arm volume to the arm bones.
  2. Apply Armature: Add an Armature modifier pointing to the T-pose skeleton. Run bpy.ops.object.modifier_apply(modifier="Armature").
  3. Result: This bakes the T-pose transformation into the mesh coordinates. The sleeve will physically stretch/rotate to align with the T-pose bones.
  4. Correction: If the mesh distorts slightly, run a Smooth or Laplacian deform pass, but usually, the high vertex count of the MD source handles the linear interpolation fine.

5. UVs and Baking

Is it worth it? Yes. At 1.5k tris, geometric pleats will look like jagged low-poly spikes. A normal map is mandatory for the "fabric" look.

Workflow Notes for MD Unwelded Sources:

  1. UV Unwrap: The MD UVs are likely per-panel and may be overlapping or messy. Run bpy.ops.uv.select_all(action='SELECT') -> bpy.ops.uv.pack_islands() on the Low-Poly target to ensure a clean layout for baking.
  2. Cage Object: Essential. Because the Low-Poly is a simplified shell of the High-Poly, ray-casting will miss or hit the back-faces of the thin MD mesh.
    • Create a Cage: Duplicate the Low-Poly mesh. bpy.ops.object.transform_apply(scale=True). Scale it up by ~5% (obj.scale = (1.05, 1.05, 1.05)).
    • In bpy.ops.object.bake(), assign this object to the cage parameter.
  3. Source Normals: Ensure the High-Poly MD mesh has Auto Smooth enabled or is set to Flat shading before baking. If you bake from a smooth-shaded high-poly to a low-poly, you will lose the sharp crease definitions of the pleats in the normal map.

6. Overall Plan Critique

  1. Missing: Hard Edges / Shading. You are exporting flat colors. At 1.5k tris, smooth shading will make the cloth look like inflated plastic. You must define seams.
    • Fix: Add an Edge Split modifier (bpy.ops.object.modifier_add(type='EDGE_SPLIT')) with split_angle=0.5 (approx 30 deg) before export. This preserves sharp cuffs, collars, and hems without increasing poly count.
  2. Missing: Clearance Verification. A static 6-8mm offset is risky for a "crowd-scale" game where animations might include deep squats or extreme twists.
    • Fix: In the script, generate a "Clearance Mesh" by scaling the Body mesh up by 1.05 (or offsetting along normals). Shrinkwrap the garment to this expanded mesh, not the body itself. This guarantees mathematical clearance regardless of animation pose.
  3. Export Rig: Ensure you export the full 65-bone skeleton with every garment, even if the garment only uses 10 bones. Godot's Skeleton3D expects a consistent bone hierarchy to stack skins correctly. Do not export "rest pose only" or a stripped skeleton.