Mesh Primitive Plane Add
The flattest possible starting point
- location
- rotation
- scale
- BPY_OBJ
The plane is the simplest mesh Blender has - four vertices, one face, no subdivisions - and this node is that operator, bpy.ops.mesh.primitive_plane_add, exposed directly as a ComfyUI node. It's part of Avatar Graph, the pack built for turning a 2D character portrait into a rigged, interactive avatar via real Blender running inside ComfyUI's own process through the bpy Python package. The pack auto-generates a node for every one of Blender's mesh operators, and a flat plane is one of them - plain and unglamorous, but it's also the actual mesh the pack's own README describes building character faces on top of, so it's more relevant here than it might look.
How it works
It spawns a single flat quad into the scene, centered at the origin by default. No subdivisions, no curvature - if you need the surface to actually bend or deform later, you'd reach for Mesh Primitive Grid Add instead, which is the same idea with subdivisions baked in. The plane's real use is as a base for texture-mapped geometry: this pack's own higher-level nodes (Plane Texture Unwrap, Create Mesh Layer) work by taking a segmented character image and projecting it onto a plane-shaped mesh, scaled to the segment's bounds. This raw node is the primitive underneath that idea, exposed for anyone building a custom variant of that pipeline by hand.
Inputs and outputs
Everything's optional, so it drops in with zero configuration and gives you a 2-unit plane at the world origin:
size(default 2) - the edge length of the square.location,rotation,scale- XYZ vectors if you need it placed somewhere other than the origin.
The rest is the same boilerplate every primitive-add node in this pack carries: calc_uvs (on by default - gives the plane a basic UV map, worth leaving alone if anything downstream is going to texture it), enter_editmode, an align enum (WORLD/VIEW/CURSOR), and a seed field that isn't actually part of Blender's plane operator - the real one has no randomness in it. It's almost certainly there to give ComfyUI a hook to force the node to re-run rather than to change the geometry, so don't spend time tuning it. Output is a single BPY_OBJ, a live handle to the plane inside the running Blender session, ready to wire into a texture-unwrap step or any other mesh node in the pack.
Installing it
ComfyUI Manager: search "avatar-graph-comfyui", install, restart. Manual: cd ComfyUI/custom_nodes && git clone https://github.com/avatechai/avatar-graph-comfyui, then cd avatar-graph-comfyui && python -m pip install -r requirements.txt, then restart ComfyUI.
The requirement to sort out before anything else is Python 3.10.x - the bpy package this pack depends on is built for that exact minor version, and the README steers macOS/Linux users toward a dedicated conda environment (conda create --name comfyui python=3.10) rather than trusting whatever Python is already on the system. Windows has it easier: a prebuilt ComfyUI + Python 3.10 zip linked right in the README, unzipped over your ComfyUI folder, then the pack itself installed through Manager. Restart with --enable-cors-header (macOS also wants --force-fp16) - that flag is what enables the live hand-off to Avatech's web-based 3D viewer. Skip it and the graph still runs fine; you just save the model manually via the pack's Avatar Main Output node instead of previewing it live in ComfyUI.
Common issues
Python version mismatch is the one to rule out first - anything other than 3.10.x and bpy won't have a compatible build, so the whole pack fails to load rather than misbehaving quietly. If the plane comes out with no visible texture in a downstream step, check that calc_uvs wasn't turned off - without UVs, texture projection has nothing to map onto. And since this pack embeds a real chunk of Blender rather than a lightweight Python library, expect it to be a heavier, more collision-prone dependency than the average custom node - a familiar shape of problem in an ecosystem where every pack ships its own requirements file. As always, the README's own warning that nodes and templates are still in flux is worth keeping in mind if a default shifts on you later.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| seedopt | INT | 00–18446744073709550000 | — |
| sizeopt | FLOAT | 2.000–999999995904 | — |
| calc_uvsopt | BOOLEAN | true | — |
| enter_editmodeopt | BOOLEAN | false | — |
| alignopt | COMBO | 3 options: WORLD, VIEW, CURSOR | |
| locationopt | B_VECTOR3 | — | |
| rotationopt | B_VECTOR3 | — | |
| scaleopt | B_VECTOR3 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| BPY_OBJ | BPY_OBJ | — |