Mesh Symmetrize
Mirroring a lopsided Avatar Graph mesh in one pass
- BPY_OBJ
- BPY_OBJ
A mesh built automatically from a 2D character image doesn't know your character is supposed to be symmetric. If the source art leans slightly, or the segmentation pass wasn't perfectly centered, you end up with a face mesh where the left side and right side genuinely don't match. Mesh_Symmetrize is the blunt, effective fix.
What it is and why you'd reach for it
Avatar Graph embeds Blender itself (via the bpy package) inside ComfyUI, and this node is a direct wrap of Blender's bpy.ops.mesh.symmetrize(). It's not a gentle nudge - it replaces the geometry on one side of your chosen axis with a mirrored copy of the other side. One half wins, the other half is thrown away and rebuilt from the mirror. That's the tradeoff: perfect symmetry, at the cost of anything asymmetric you wanted to keep (an off-center scar, an asymmetric hairstyle detail baked into the mesh) being erased.
In the Avatar Graph pipeline this typically runs right after the mesh comes out of Create Mesh Layer and before you start adding shape keys - you want a clean, symmetric base before you rig blink/lipsync shapes on top of it, otherwise your left and right eye blinks will visibly differ in shape.
Inputs and outputs that matter
BPY_OBJ(optional) - the mesh from upstream.direction(enum: NEGATIVE_X, POSITIVE_X, NEGATIVE_Y, POSITIVE_Y, NEGATIVE_Z, POSITIVE_Z) - which side is the source and which side gets overwritten. For a front-facing 2D character built along X, you'll typically be choosing between the negative-X and positive-X half as the one that survives.threshold(float, default ~0.0001, 0–10) - how close to the center-line a vertex has to be before it's merged onto the seam rather than duplicated as two separate points. Too tight and you get a visible split down the middle; loosen it if the seam doesn't weld cleanly.
Output: a single BPY_OBJ, now mirrored, ready for more cleanup or straight into shape keys.
Like every mesh-editing node in this pack, it acts on the current selection - select the whole mesh upstream if you want the whole thing mirrored, not just a region.
Installing Avatar Graph
The pack is built on bpy, which only has wheels for Python 3.10.x - pin your environment to that before anything else.
ComfyUI Manager: search avatar-graph-comfyui, install, restart. Or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/avatechai/avatar-graph-comfyui.git
cd avatar-graph-comfyui
python -m pip install -r requirements.txt
Restart with python main.py --enable-cors-header (add --force-fp16 on Mac). Windows users get a prebuilt Python 3.10 bundle from the README to sidestep version conflicts; on macOS/Linux the recommended path is a dedicated conda create --name comfyui python=3.10 environment.
Common issues
Half your character vanishes or duplicates weirdly. That's direction picking the wrong side as the mirror source - flip it to the other option and re-run. Worth doing a quick undo/redo test with both directions the first time, since it's not always obvious from the enum name alone which half is being kept versus overwritten.
A visible seam down the center after symmetrizing. Loosen threshold slightly so near-center vertices actually weld together instead of sitting as unmerged duplicates.
Nodes not loading at all. Almost always the Python version mismatch - bpy needs exactly 3.10.x, and outside that range the import fails and the whole pack won't register.
No live preview panel. That needs --enable-cors-header; without it you still get a working graph, you just export via right-click → Save File on Avatar Main Output instead of watching it update live in the embedded editor.avatech.ai panel.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| BPY_OBJopt | BPY_OBJ | — | |
| directionopt | COMBO | 6 options: NEGATIVE_X, POSITIVE_X, NEGATIVE_Y, POSITIVE_Y, NEGATIVE_Z, POSITIVE_Z | |
| thresholdopt | FLOAT | 0.000–10 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| BPY_OBJ | BPY_OBJ | — |