You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
5.1 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Blockbench UV Packer
A Blockbench plugin that auto-packs per-face UV models with ML-assisted share-merge suggestions, mirror detection, multi-variant texture support, and pow2 canvas cropping. One button, end-to-end.
Originally built for the Decocraft project's bbmodel corpus (~600 models). The ML model in `ml/share_model.json` is trained on that corpus; you can retrain on your own corpus with the scripts in `ml/`.
## What it does
When you click **Tools → Pack UVs (Decocraft)**, the plugin:
1. Collects all per-face-UV cubes in the project (skips box-UV cubes; works in mixed-mode projects)
2. **Heuristic share-merge** — faces with the same UV rect (modulo flip) collapse to one packed slot. Median 80% rect dedupe across the training corpus.
3. **ML share-merge suggestions** (if `share_model.json` is loaded) — surfaces candidate merges the heuristic missed. A pixel-similarity gate filters out false positives. Each suggestion shows a thumbnail preview before you accept.
4. **Mirror-orientation detection** — for cross-rect merges, the planner samples each member's pixels in 4 orientations and picks the one that minimizes RGBA diff against the canonical, so mirror-painted symmetric regions stay mirror-correct after merging.
5. **Skyline pack** — biggest-first, top-to-bottom, left-to-right. Outliner-group ordering clusters same-group faces. Auto-expands the working canvas if rects don't fit.
6. **Variant texture rearrangement** — alternate skin textures (any texture in the project with no faces pointing to it) get the same pixel rearrangement as the driver texture, so swapping skins still lines up.
7. **Pow2 crop** — final texture canvas is shrunk to next-power-of-2 of the actual packed bbox.
8. Single Undo entry covers everything.
## Install
1. In Blockbench: **File → Plugins → Load Plugin from File**
2. Pick `decocraft_uv_packer.js`
3. (One-time) **Tools → Load Share Model JSON** → pick both `ml/share_model.json` and `ml/inference_test_cases.json` (multi-select). The model is cached to `localStorage` after first load. The plugin self-tests the JS LightGBM evaluator against the test cases on every load — if it doesn't match LightGBM exactly, it refuses to use the model.
## Workflow
- Open a project that uses per-face UVs
- **Tools → Pack UVs (Decocraft)**
- If the ML model finds candidates, a dialog opens with thumbnails. Uncheck any pair where the previews disagree visually. Click **Accept & Pack** (or **Pack without merging** to skip ML suggestions).
- The plugin packs, crops to pow2, and rearranges variants. Toast reports `Packed N faces into M slots · canvas A×B → C×D`.
## Retraining the ML model on your own corpus
If you have your own bbmodel collection and want a model trained on its conventions:
```sh
# 1. Inspect the corpus statistics (optional)
node analyze_uvs.mjs path/to/your/bbmodel/folder
# 2. Extract face-pair training data (~250k labeled pairs from ~600 models)
node ml/extract_pairs.mjs path/to/your/bbmodel/folder
# → produces ml/pairs.csv (~30 MB on a 600-model corpus)
# 3. Train (Python: pip install lightgbm pandas scikit-learn)
cd ml
python train_share_classifier.py
# → updates share_model.json, eval_report.txt, inference_test_cases.json
# 4. In Blockbench: Tools → Load Share Model JSON → pick the new files
```
The training script splits **by model** (not by pair) for held-out evaluation — so the precision/recall numbers in `eval_report.txt` reflect actual generalization to unseen models, not just unseen pairs from already-seen models. The bundled `share_model.json` was trained on the Decocraft corpus and reaches AUC 0.985 / precision 0.96 @ recall 0.88 on 123 held-out models.
## File layout
```
blockbench-uv-packer/
├── decocraft_uv_packer.js Blockbench plugin (single file)
├── analyze_uvs.mjs Corpus stats (per-model density, group overlap, share fraction…)
└── ml/
├── extract_pairs.mjs Build pairs.csv from a bbmodel directory
├── train_share_classifier.py LightGBM trainer + eval + JSON export
├── validate_js_eval.mjs Verifies the JS evaluator matches LightGBM bit-for-bit
├── share_model.json Trained model (350 trees, ~2.5 MB)
├── inference_test_cases.json 50 self-test cases for the plugin
└── eval_report.txt Precision/recall sweep + feature importance from last train
```
## Limitations / non-goals
- **Per-face UV only.** Cubes set to box-UV mode are skipped (counted in the success toast).
- **Same-dimension share-merges only.** The merger collapses faces whose source rects have the same dims (with optional 90°-mirror); it doesn't rotate-to-fit different aspect ratios.
- **Reorient-cubes feature was attempted and dropped.** Auto-rotating cubes for tighter packing fights against either Blockbench's `cube.roll()` (which rotates visually, breaking model assemblies) or requires deriving the full per-(perm × slot) D4-symmetry texture transform (which kept hitting subtle bugs across iterations). If you want a cube reoriented, use Blockbench's built-in Transform → Rotate tools manually before running Pack UVs.
## License
TBD — add the license your project uses.