Skip to content

Add multi-criteria rescoring for merged UV shells - #7

Merged
SashaRX merged 2 commits into
masterfrom
claude/fix-source-shell-selection-fumsO
Mar 3, 2026
Merged

Add multi-criteria rescoring for merged UV shells#7
SashaRX merged 2 commits into
masterfrom
claude/fix-source-shell-selection-fumsO

Conversation

@SashaRX

@SashaRX SashaRX commented Mar 3, 2026

Copy link
Copy Markdown
Owner

Summary

This change improves the UV shell transfer process by adding a post-processing phase that attempts to "rescue" shells initially marked as merged by evaluating them against all source shells using a weighted multi-criteria scoring system.

Key Changes

  • New ComputeUv0CoverageFraction() method: Computes a continuous [0,1] coverage metric for UV0 vertices against source shell triangles, extending the logic from the existing DetectMergedShell() boolean check.

  • New RescoreMergedShells() method: Implements a four-factor scoring system for merged target shells:

    • UV0 area ratio (weight: 0.20) — compares footprint sizes
    • Surface normal agreement (weight: 0.30) — dot product similarity
    • 3D centroid distance (weight: 0.15) — normalized by mesh diagonal
    • UV0 coverage fraction (weight: 0.35) — primary quality metric

    Shells with coverage ≥ 0.70 are un-merged and reassigned to the best-scoring source shell.

  • Precomputed source shell metrics: Added per-shell average face normals and total UV0 areas for source shells to enable efficient multi-criteria evaluation.

  • Precomputed target shell metrics: Added per-shell average face normals and total UV0 areas for target shells, with proper bounds checking for vertex indices.

  • New Phase 2a+ processing: Integrated the rescoring pass between initial shell matching (Phase 2) and deduplication (Phase 2b), with informational logging of rescued shells.

Implementation Details

  • Coverage threshold of 0.70 ensures only high-confidence matches are accepted
  • Weighted scoring allows coverage to be the dominant factor (35%) while still considering geometry and topology
  • Mesh diagonal normalization makes distance scoring scale-invariant
  • Graceful handling of degenerate cases (zero-area shells, missing normals)
  • Detailed logging tracks which shells are rescued and their match quality scores

https://claude.ai/code/session_01CASV7NpbBhnt19BnuZemDq

claude added 2 commits March 3, 2026 12:18
Add RescoreMergedShells step between Phase 2a and Phase 2b in
GroupedShellTransfer. When DetectMergedShell marks a target shell as
merged (because 3D centroid-based matching picked a wrong source), the
new step evaluates all source shells using a 4-criteria weighted score:
- UV0 coverage fraction (35%) — direct UV0 compatibility measure
- Normal agreement (30%) — disambiguates front/back on thin walls
- UV0 area ratio (20%) — filters mismatched shell sizes
- 3D centroid distance (15%) — spatial proximity prior

If the best-scoring source has UV0 coverage >= 70%, the shell is
un-merged and reassigned, avoiding the lossy all-source fallback.

https://claude.ai/code/session_01CASV7NpbBhnt19BnuZemDq
@SashaRX
SashaRX merged commit 74fbe72 into master Mar 3, 2026
@SashaRX
SashaRX deleted the claude/fix-source-shell-selection-fumsO branch March 4, 2026 00:09
SashaRX pushed a commit that referenced this pull request Jul 18, 2026
ExportFbxIsolatedCore captured per-mesh snapshots from the tool's
working mesh (built from the current import) but then disabled
weldVertices / meshCompression / meshOptimizationFlags and reimported
the source FBX before cloning it. weldVertices is ON by default, so for
typical imports the reimported clone had a different vertex count than
the snapshot, and CopyIsolatedSnapshotsToClone silently skipped every
mesh on the mismatch — isolated UV1 / vertex-color exports reported "no
matching updates" and wrote nothing.

Remove the weld/compression/optimization pre-export reimport from the
isolated path:

- The snapshot source (e.g. the packed UV1 clone in UvPackHierarchyTool,
  or the AO-baked working copy) shares its vertex layout with the
  CURRENT import; the clone is also loaded from the current import, so
  they match when we don't reimport.
- The wide LOD-rebuild path (ExportFbx) never did this reimport and
  works, so it's the correct precedent.
- Those settings were restored right after export anyway, so the final
  re-imported FBX kept the user's original weld/optimization state
  regardless. The pre-export reimport therefore never affected the
  exported result — it only desynced the clone from the snapshot.

isReadable handling stays (layout-safe) and generateSecondaryUV stays
disabled for UV1 intents (so the authored UV1 isn't regenerated). The
remaining, rare case where an FBX still re-imports at a different vertex
count (Generate Lightmap UVs splitting vertices for a UV1 export) now
logs an actionable warning instead of a bare mismatch line.

https://claude.ai/code/session_01CkRooSFA5QW3Kox9AAFe3F
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants