Object Join
Merging your avatar's mesh layers
- BPY_OBJ
- BPY_OBJ
Blender's Ctrl+J joins selected objects into the active one - one mesh, one object, all the data merged. Object_Join is that operator, exposed as a node in the Avatar Graph pack, and it's one of the few nodes in this family you'll genuinely reach for. In the pack's character pipeline it's the "combine my segmented layers into a single model" step.
Here's the flow it slots into. You start from a 2D character image, run SAM to cut out segments, and Create Mesh Layer turns each segment into its own mesh object - body, hair, face, accessories all as separate objects. That's great while you're rigging each part, but a real-time avatar doesn't want a dozen draw calls and a mile-long object list. When you're done with the per-part work, you Ctrl+J them back together.
How it works
It calls bpy.ops.object.join(). Like all the Object_* nodes it sets the BPY_OBJ input as the active object in the embedded scene and passes it back out unchanged. The operator then merges every currently selected object into the active one. Selection comes from what your graph has been doing - the pack's nodes select objects as they work, and you drive selection with the pack's object-selection utilities.
The output is the active object, now carrying the geometry of everything that was selected. Data transfers along: materials, UV maps, vertex groups, and shape keys all merge in (Blender keeps them per-mesh, so you won't lose your blink shape key just because the body and face became one object).
When you'd use it in an avatar graph
The canonical use is post-rig assembly: rig each layer separately (that's easier - hooks and vertex groups are per-mesh), then join everything before the AvatarMainOutput export so the editor gets one clean model. A second, sneakier use: you can join to merge duplicate data. If the scene rebuild left you with stray objects, joining is a tidy-up step.
Inputs and outputs
BPY_OBJ- the target object everything merges into; returned as the merged result.BPY_OBJoutput - the joined object.
That's it - no other parameters. If your graph needs to join a specific set of objects regardless of current selection, make sure you've selected them upstream; this node has no "which objects" field.
Installing it
Ships in Avatar Graph (avatechai/avatar-graph-comfyui). 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
Pack constraints to keep in mind: bpy==3.6.0 needs Python 3.10.x, and first launch auto-downloads the SAM ViT-H checkpoint (~2.5 GB) and MediaPipe models.
Common issues
"Join did nothing" is the usual report, and it's almost always a selection problem - you connected BPY_OBJ but the other objects you want merged aren't selected. The operator only joins what's selected; the active object is just the destination. Also, joining objects that were rigged separately can leave their vertex groups merged but their bones unparented - check the rig after a join, or do the join before parenting. The README flags the pack as work-in-progress, so expect occasional rough edges.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| BPY_OBJopt | BPY_OBJ | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| BPY_OBJ | BPY_OBJ | — |