Nodes/Avatar Graph/Transform Shrink Fatten
ComfyUI Node

Transform Shrink Fatten

The One That Actually Shapes the Face

By avatechai·Created 3 years ago·Updated 2 years ago· 264
Transform Shrink Fatten
  • BPY_OBJ
  • BPY_OBJ
value0.00
use_even_offsetfalse
mirrorfalse
use_proportional_editfalse
proportional_edit_falloff
proportional_size1.00
use_proportional_connectedfalse
use_proportional_projectedfalse
snapfalse
release_confirmfalse
use_accuratefalse

If you remember one node from Avatar Graph's Transform_ shelf, make it this one. Transform Shrink Fatten is the Blender operator transform.shrink_fatten, and it's the fastest way to give a flat avatar mesh actual volume. Positive value pushes vertices outward along their normals - fattening, puffing, rounding. Negative pulls them in - shrinking, hollowing. For a character built from segmented image layers, this is how a paper-flat mouth becomes a lip you can deform.

How it works

The mechanism is simple and it's why the result looks good: each vertex moves along its own normal direction, not along a single world axis. That means a cheek mesh puffs out uniformly instead of just sliding sideways. Internally the node takes your BPY_OBJ, enters edit mode, and calls bpy.ops.transform.shrink_fatten(value=...). The mesh comes back on the output BPY_OBJ socket, ready to chain into the next op.

The inputs that matter:

  • value - the amount. 0 is unchanged; 0.2 is a subtle puff; 1+ is a balloon. Negative shrinks. There's no upper clamp, so ease into it.
  • use_even_offset - keeps edge lengths even as vertices move, so you don't get stretched, uneven geometry. Generally leave it on.
  • use_proportional_edit + proportional_size - the secret to a local, organic effect. Enable it and only the region within proportional_size of the pivot transforms, with a falloff you pick (SMOOTH, SPHERE, SHARP...). This is how you fatten just the lips without inflating the whole head.

Everything else (mirror, snap, release_confirm, use_accurate) is Blender operator plumbing you can ignore.

Where it fits in the avatar workflow

The classic Avatar Graph flow is: generate a character image with an open mouth → segment it with the SAM node → Create Mesh Layer for each part (mouth, eyes, head) → join or keep them separate → shape them → build shape keys → export to the Avatech editor. Shrink Fatten lives right after mesh creation. Fatten the mouth layer so there's actual geometry to deform, then let Mesh Modify Shape Key drive it into smile/blink expressions later.

Two gotchas. First, it acts on the whole mesh you feed it - there's no vertex-selection socket, so apply it per-part via separate mesh layers. Second, keep an eye on the mesh's texture: since these layers carry the character image as a texture, heavy shrinkage can warp how the image reads on the surface. Match Texture Aspect Ratio at the end fixes the re-scale.

Installing

This node ships in the Avatar Graph pack (avatechai/avatar-graph-comfyui). The pack's real dependency is bpy==3.6.0, which needs Python 3.10:

conda create --name comfyui python=3.10
conda activate comfyui

Install via ComfyUI Manager (search Avatar Graph) or:

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 with python main.py --enable-cors-header for the live preview. No model downloads for this node - the only heavyweight download in the pack is the SAM segmentation model, which you don't need to touch for shaping.

Categoryblender

Inputs (12)

NameTypeDefaultDescription
BPY_OBJoptBPY_OBJ
valueoptFLOAT0.00-3.402823466385289e+38–3.402823466385289e+38
use_even_offsetoptBOOLEANfalse
mirroroptBOOLEANfalse
use_proportional_editoptBOOLEANfalse
proportional_edit_falloffoptCOMBO8 options: SMOOTH, SPHERE, ROOT, INVERSE_SQUARE, SHARP, LINEAR, +2
proportional_sizeoptFLOAT1.009.999999974752427e-7–999999995904
use_proportional_connectedoptBOOLEANfalse
use_proportional_projectedoptBOOLEANfalse
snapoptBOOLEANfalse
release_confirmoptBOOLEANfalse
use_accurateoptBOOLEANfalse

Outputs (1)

NameTypeDescription
BPY_OBJBPY_OBJ