BD CubePart Segment
BD CubePart Segment
- mesh
- parts
- combined
- part_names
The whole reason image-to-3D outputs are "unusable" for anything that has to move is that you get one fused triangle soup - no separate arms, no wheels, no way to rig it. BD CubePart Segment is the node that fixes that: give it a mesh and type "body, left wheel, right wheel" and it hands you back one clean mesh per part, canonically aligned. It's the Roblox CubePart model (open-vocabulary, up to 8 free-text part names) wrapped as a single ComfyUI node, and it's genuinely the difference between a 3D print and a game asset.
It lives in the BrainDead pack, which is worth knowing about if you're not already there: this is an internal production node pack from Biloxi Studios that got open-sourced, and it's built around the whole "image → mesh → parts → PBR bake" pipeline. CubePart is the part-decomposition step.
How it works
CubePart is a diffusion model, not a heuristic. The node samples a bunch of surface points from your input mesh (num_samples, default 128,000), encodes them, then runs a multi-part DiT conditioned on your text labels to generate a per-part occupancy field. Each part gets extracted with marching cubes - that's what resolution_base controls (higher = finer grid = crisper parts, slower). A small text encoder names things, which is why the whole thing is "open vocabulary" and you don't need a fixed class list.
The inputs that matter for a beginner:
- parts - up to 8 names, comma- or newline-separated. Extra names past 8 are silently dropped (it logs a warning). Open vocabulary: "body, left wheel, right wheel, driver" all work.
- seed - for reproducibility; change it if the split looks cursed.
- guidance_scale (7.5) and num_inference_steps (50) - the usual diffusion dials. Lower steps is faster but parts get less clean.
- resolution_base (8.5) - marching-cubes grid fineness. This is the first thing to nudge up if part boundaries are blobby.
- mesh (TRIMESH) or mesh_path (a
.glbon disk) - one or the other, mesh wins if both are wired.
Outputs: parts (a TRIMESH_LIST, one mesh per part in your name order), combined (a single color-coded TRIMESH you can preview immediately), and part_names (a STRING you can wire into labeling or a filename). From parts you typically go into BD CubePart Get Part to pull one mesh at a time, then BD CuMesh Simplify / export.
Weights, and the license you need to read
This is not a lightweight node. First run auto-downloads Roblox/cubepart (~8.6 GB DiT + ~1.3 GB VAE) plus the Qwen/Qwen3-VL-4B-Instruct text encoder. Paths auto-resolve through ComfyUI's extra_model_paths.yaml, and you can pre-download with:
huggingface-cli download Roblox/cubepart --local-dir /srv/AI_Stuff/models/cubepart
huggingface-cli download Qwen/Qwen3-VL-4B-Instruct --local-dir /srv/AI_Stuff/models/LLM/Qwen3-VL-4B-Instruct
The license is the thing people get burned on: the CubePart code is MIT, but the model weights sit under the CUBE3D RESEARCH-ONLY RAIL-MS license. Fine for internal/research work; actually review it before you ship outputs commercially.
Installing
ComfyUI Manager, search "BrainDead", install, restart - cube_part is vendored inside the pack so nothing extra to pip. Manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/BizaNator/ComfyUI-BrainDead
cd ComfyUI-BrainDead
pip install -r requirements.txt
Where people get burned
First run is slow - that's the ~10 GB download plus model load, not a hang. It's also a real diffusion model on top of your pipeline, so VRAM matters: if you're already holding a big base model, expect pressure. And remember the 8-part cap; if a part name is missing from the output, check you didn't sneak in a ninth.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| parts | STRING | body, left wheel, right wheel | Up to 8 part names, comma- or newline-separated. Open vocabulary. Extra names past 8 are dropped (logged). |
| seed | INT | 00–2147483647 | Random seed for reproducibility. |
| guidance_scale | FLOAT | 7.50–20 | Classifier-free guidance strength. |
| num_inference_steps | INT | 501–200 | Diffusion denoising steps. |
| resolution_base | FLOAT | 8.56–10 | Marching-cubes grid resolution base (higher = finer, slower). |
| scheduler | COMBO | dpm_solver | Sampling scheduler. |
| timeshift | FLOAT | 4.01–10 | Flow-matching timestep shift. |
| num_samples | INT | 12800016000–256000 | Surface points sampled from the input mesh for encoding. |
| meshopt | TRIMESH | Input mesh from a BD mesh source. If unset, mesh_path is used. | |
| mesh_pathopt | STRING | Path to a .glb on disk. Used only when no `mesh` is wired. | |
| auto_downloadopt | BOOLEAN | true | Download missing weights from HF on first run (Roblox/cubepart, Qwen/Qwen3-VL-4B-Instruct). Off = error if not pre-downloaded. |
| model_diropt | STRING | Override the cubepart weights dir. Empty = auto-resolve via ComfyUI folder_paths / extra_model_paths.yaml ('cubepart' key, else models/cubepart). | |
| text_encoder_pathopt | STRING | Override the Qwen3-VL-4B-Instruct dir (loaded offline). Empty = auto-resolve under the LLM models folder. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| parts | TRIMESH_LIST | — |
| combined | TRIMESH | — |
| part_names | STRING | — |