π UV Shell Scaler
Shrink or Grow Every UV Island in Place, Without Repacking
- trimesh_mesh
- trimesh_mesh
What it's actually for
You've got a UV layout you're broadly happy with, and one problem: the islands are too big and touching each other. Or too small, leaving half your texture wasted. You don't want to re-unwrap - that would reshuffle everything and invalidate the texture you just made. You want to scale each island about its own centre and leave the layout alone.
That's exactly what this does, and it's a two-input node. It's the kind of thing that takes four lines of trimesh and twenty minutes of fiddling, which is the honest pitch for half of this pack.
How it works
The node groups faces into islands via trimesh's connected components over face adjacency, collects the unique vertices each island uses, computes that island's 2D bounding box in UV space, and moves every UV coordinate out from the box centre by the scale factor:
uvs[vert_idx] = center + (island_uvs - center) * scale_factor
That's it. Each island shrinks or grows in place, its centre stays put, and islands therefore drift apart as they shrink - which is the whole point if your problem was seams touching.
Two consequences follow directly from the maths:
- It doesn't know about the other islands. Shrinking to 0.9 gives you gaps, but nothing re-centres the layout or re-spreads the islands to use the freed space. Shrink too far and you've got a sparse atlas with wasted texels.
- It doesn't clamp to 0-1. An island sitting near the tile border that you scale up will happily wander past it. Scaling up is riskier than scaling down for this reason.
If the mesh has no UVs, it prints a warning and returns your original mesh unchanged rather than throwing - check the console if nothing seems to happen.
The inputs that matter
- trimesh_mesh - the TRIMESH to operate on.
- scale_factor (default 0.9, 0.01-2.0) - the multiplier. Below 1 shrinks every island toward its own centre (more gap, lower texel density), above 1 grows it (higher density, and a real chance of overlap). 0.9 is a "give me a little breathing room" default, and it's a good one.
One output: trimesh_mesh, a TRIMESH with adjusted UVs. Wire it into the pack's UV preview to see the layout, or straight on to your bake.
The console prints the island count it found, which is a quietly useful diagnostic - if that number is 300 on a mesh you expect to have 6 islands, your mesh is split to pieces and you should weld it (AntonioilevUVWatertight) before touching UV scale.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Antonioilev/ComfyUI_Antonioilev_Lightpack.git
# restart ComfyUI
Or via ComfyUI Manager, searching the pack title. No requirements file: the pack's __init__.py catches import errors and prints a node count, so a missing dependency shows up as an absent node, not an error. This one is numpy + trimesh only.
Where people get burned
- Scaling after baking invalidates the bake. Same rule as every UV node in this pack: adjust UVs, then bake.
- Growing past the border is silent. Nothing here clamps UVs into the unit square; a magnified island can go out of range and sample texture-less space. Scale down when you're unsure.
- Overlap from scaling up is invisible in the graph. Two islands expanded past each other read as a doubled texture pattern.
preview_mesh_uvwill show you the layout before you commit. - It's not a packer. Uniform scaling won't fix a bad layout - it preserves the relative proportions you started with, good or bad.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| trimesh_mesh | TRIMESH | β | |
| scale_factor | FLOAT | 0.900.01β2 | β |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| trimesh_mesh | TRIMESH | β |