?? Topology-Safe UV (Fixed Integrity)
A UV Node That Admits It's an Experiment (and Still Saves You Time)
- trimesh_obj
- TRIMESH
What it's actually for
Generated meshes come with machine-made UVs that are, in the words of the KB's 3D doc, "messed-up" - stretched, overlapping, or just nonsense. The proper fix is a real unwrap (the pack ships one, AntonioilevUVUnwrap). This node is the other fix: split the mesh into a controlled number of islands and lay them out flat with a projection that cannot tear topology, so faces never go missing.
The "??" in the display name and the research category aren't decoration. It's the author's own scratched-up experiment, and it's honest about being one. But for blobby, organic, or scan-ish assets where you're going to apply a tiling or triplanar-ish material anyway, an island count you control beats a perfectly-unwrapped UV atlas you can't predict.
How it works
It's a clustering-and-box-project pipeline, not a true unwrap:
- Every face becomes a feature vector - its centroid, plus its normal scaled down so shape dominates direction.
- KMeans clusters those features into groups (
island_countdrives the cluster count). - Each cluster is split into connected components on the face-adjacency graph, so no island ends up with disconnected pieces floating in it.
- Tiny islands get absorbed into their neighbours until you're under your target count.
- Each surviving island is projected to 2D along its dominant axis - a box projection - scaled by the square root of the mesh's total area so islands get size proportional to their surface, then squeezed to fit its slot.
- Islands are packed into a
ceil(sqrt(N))grid with a small padding inset, and everything is concatenated back into one mesh with a UV visual.
Because island count is bounded and packing is a grid, results are stable and predictable. Because projection is planar, anything curved gets some squeeze. That's the trade.
The inputs that matter
- trimesh_obj - the TRIMESH you want UVs on.
- island_count (default 50, 2-300) - how many UV islands you want. Low values mean big planar islands and heavier distortion on curved surfaces; high values mean more islands, more seams, less distortion. Start at 20-50 for a character-ish blob.
- min_island_size (default 10, 1-1000) - the floor for what counts as an island worth keeping. Raise it if you're getting dozens of two-face islands.
One output: TRIMESH, with UVs written onto the mesh's visual. Wire it to the pack's UV preview to eyeball the layout, or straight into a texture/bake step.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Antonioilev/ComfyUI_Antonioilev_Lightpack.git
# restart ComfyUI
No requirements file ships with the pack, and __init__.py catches import errors quietly - you'll see [Antonioilev_Light_pack] Loaded N nodes (M failed) in the console while the node itself simply never appears. This one needs scikit-learn (KMeans lives there) and networkx:
pip install scikit-learn networkx
Where people get burned
- It will not save a mesh you've already baked a texture onto. New UVs mean the existing texture map no longer lines up. Use it before texturing, or accept the rebake.
- Losing faces is the failure mode. The node prints
!!! [WARNING] Lost N faces!when the concatenation comes back smaller than the input. If you see that, your islands are too small or your mesh has degenerate/duplicate faces - clean it with the pack's weld or mesh-cleaner nodes first. - If any step throws, it hands your original mesh straight back with a printed error rather than failing the graph. Check the console; a silent "it did nothing" is usually an exception being swallowed.
- Don't compare it to xatlas. For a hero asset, a real unwrap wins on texture density every time. This is the fast, topology-safe option for a mesh you're not going to UV by hand.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| trimesh_obj | TRIMESH | — | |
| island_count | INT | 502–300 | — |
| min_island_size | INT | 101–1000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| TRIMESH | TRIMESH | — |