UV Smart Project
The pack's default auto-unwrap, angle limit and all
- BPY_OBJ
- BPY_OBJ
UV Smart Project is where the Avatar Graph pack stops selecting and starts making. It's Blender's "Smart UV Project" operator (bpy.ops.uv.smart_project()) wrapped as a node: give it a mesh, and it auto-unwraps the whole thing - projecting faces at a chosen angle limit, splitting them into islands wherever the angle between faces is too sharp, and laying the islands out in the 0–1 UV square. It's the pack's default answer to "my avatar mesh has no usable UV layout."
That matters because every mesh the pack builds from a 2D character image starts with UVs generated by the mesh-from-texture path, and those are often fine for flat layers and wrong for anything curved. When your eye mesh or head mesh needs a real layout, Smart Project is the first stop - the README's own Plane Texture Unwrap node is basically this idea specialized for planes.
The settings that matter
- angle_limit (float, 0–π/2, default ~1.15 rad ≈ 66°) - the threshold that decides when two faces get split into separate islands. Lower = more islands, more seams, less distortion. Higher = fewer, bigger islands, more stretching. For a face mesh, ~60–70° is the sane starting band; expect to nudge it per mesh.
- island_margin (float, 0–1) and margin_method (
SCALED,ADD,FRACTION) - breathing room between islands. On an avatar that gets exported and animated, margins are what stop adjacent islands bleeding into each other during mipmapping.SCALEDis the modern default; crank the margin a little for export. - correct_aspect (bool, default on) - correct for the texture's aspect ratio so circles stay circles. Leave it on.
- area_weight (float, 0–1) - bias the projection by face area. Default 0 treats all faces equally; a small boost can help tiny detail islands (lashes, teeth) keep resolution.
- scale_to_bounds (bool, default off) - scale islands to fill the full 0–1 bounds. Handy for texture-paint-from-image workflows, often wrong for avatars where you want proportional scaling.
How it works
Standard pack wrapper: edit mode, operator, return the same BPY_OBJ. It discards the old UV layout and writes a new one on the mesh's UV layer (creating it if absent). Then the resulting selection/islands are ready for pinning, stitching, or vertex-group work downstream.
Installing it
Same pack-wide story - Avatar Graph pins bpy==3.6.0, so your ComfyUI environment must be Python 3.10. ComfyUI Manager search: "Avatar Graph." Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/avatechai/avatar-graph-comfyui
cd avatar-graph-comfyui
python -m pip install -r requirements.txt
Restart ComfyUI, then let the first launch pull the SAM ViT-H model (~2.5 GB) and mediapipe landmarkers. Add --enable-cors-header for the live editor preview, or export a .GLB via right-click on Avatar Main Output.
Troubleshooting
The classic mistake is cranking angle_limit down to near zero and wondering why the mesh came back as a confetti of hundreds of islands - that's exactly what you asked for. Start at the default and only tighten if faces are visibly stretched. The other trap: Smart Project remaps everything, including UVs you carefully pinned. If you have anchors, either run it before pinning or accept that pins don't survive the re-projection. And as always, if the node errors, check the mesh has a UV-capable data type and that you're feeding a BPY_OBJ, not an image.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| BPY_OBJopt | BPY_OBJ | — | |
| angle_limitopt | FLOAT | 1.150–1.570796370506287 | — |
| margin_methodopt | COMBO | 3 options: SCALED, ADD, FRACTION | |
| island_marginopt | FLOAT | 0.000–1 | — |
| area_weightopt | FLOAT | 0.000–1 | — |
| correct_aspectopt | BOOLEAN | true | — |
| scale_to_boundsopt | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| BPY_OBJ | BPY_OBJ | — |