Nodes/ComfyUI-Tools/3d - Trimesh to Mesh
ComfyUI Node

3d - Trimesh to Mesh

The 10-second fix when your 3D node outputs something nothing will open

By visualbruno·Created 9 months ago·Updated 22 days ago· 5
3d - Trimesh to Mesh
  • trimesh
  • mesh

You generated a mesh. It looks great in whatever thumbnail the generating node paints, and then you try to plug it into SaveGLB or Preview3D and… nothing links. That's the problem this node exists to solve, and it's not a bug in either end. ComfyUI's 3D tooling is young enough that two socket families are in circulation: the native MESH container that core's 3D nodes speak, and TRIMESH, which a lot of the community wrappers use when they're just handing you a raw trimesh.Trimesh Python object. 3d - Trimesh to Mesh is the adapter between them.

Why anyone needs an adapter at all

The native MESH isn't a file path and isn't a trimesh object - it's a tensor bundle (vertices, faces, optional UVs, normals, texture maps, material factors) that core's SaveGLB, Preview3D, and the newer mesh post-process nodes understand. Feed it one of those and you get a .glb/.obj/.stl on disk, or an interactive viewport.

TRIMESH is the older, looser deal: packs that wrap image-to-3D models often leave the library object intact and pass that down the graph. Fine internal currency, dead end at the export nodes. It's the same corner of the ecosystem the 3D-generation doc calls install-fragile and format-balkanised - the socket type decides which downstream tool can accept your result, before topology even enters the conversation.

Worth knowing who's behind it: visualbruno wrote the ComfyUI-Trellis2 wrapper - a popular local TRELLIS.2 route, and the one that shipped prebuilt Windows wheels for the compiled pieces it needs. ComfyUI-Tools is the utility pack beside that work.

What actually happens on the wire

No options, no settings. One conversion, done thoroughly:

  • Geometry. Trimesh's vertices go to float32 and faces to int32, as single-item batches, with normals lifted from trimesh.vertex_normals so viewers don't fall back to flat per-face shading.
  • UVs. Copied over with the V axis flipped - trimesh stores UVs in OpenGL convention, MESH expects glTF's, so this is the kind of detail you'd otherwise discover as a mirrored texture three hours later.
  • Colour, if the source has any. Vertex colours scaled to 0–1, or a base colour map plus normal and emissive maps when the material has them.
  • Materials, if the source has them. Occlusion and metallic/roughness get packed into one ORM image (occlusion in red, flagged so downstream nodes unpack it correctly), and the scalar factors - metallic, roughness, double-sidedness, base colour, emissive - ride along in the material dict.

If the source has no material - an .stl, say - you get clean bare geometry. That's normal, not a failure.

It also prints vertex and face counts to the console every run, which is a decent sanity check: 12,000 vertices and a plausible face count means the conversion worked and your problem is downstream.

Inputs and output

trimesh in (type TRIMESH), mesh out (type MESH). That's the whole schema - the author didn't expose a single knob, which is the right call for an adapter.

Wire the output into SaveGLB, Preview3D, or a core post-process node (remesh, decimate) if your build has them. Nothing else in the graph changes.

Installing

ComfyUI Manager, search ComfyUI-Tools - or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/visualbruno/ComfyUI-Tools

Restart ComfyUI. The requirements.txt is short - trimesh and rembg - and the rembg half is for the pack's crop-image node, not this one; it drags in onnxruntime and downloads a model on first use, so don't be surprised by the size. No checkpoints to download for this node, and the meshoptimizer shared library ships inside the repo's libs/ folder.

One discrepancy to know about: pyproject.toml lists the heavy set (opencv-python, tqdm, nvdiffrast, cumesh) as dependencies, while requirements.txt comments most of those out as projection-only. If a registry install tries to build nvdiffrast or CuMesh and falls over, clone the repo and install requirements.txt yourself - nothing here needs them.

Where people get burned

The node isn't in the menu at all. libs/ only contains meshoptimizer.dll (Windows) and libmeshoptimizer.so (Linux), and the pack loads that library with ctypes at import time - before any node registers. On macOS, or on ARM Linux, that load fails and takes the entire pack down with it, this node included. A missing-node symptom that has nothing to do with the node you wanted.

ModuleNotFoundError: No module named 'trimesh'. The requirement didn't install, usually after a manual clone where you skipped that step.

An empty TRIMESH socket on both ends. People post screenshots of this regularly - a trimesh input with nothing willing to fill it, because TRIMESH isn't a core type and the socket renders whether or not a producing pack is installed. If your converter has nothing to convert, you're missing the generator side of the graph, not the adapter.

A texture that vanished. Check the source file. Trimesh only carries a visual if the file it read had one, and the node copies what it's given rather than inventing anything. GLB in, textured mesh out; STL in, plain geometry out.

CategoryVisualBrunoTools/3d

Inputs (1)

NameTypeDefaultDescription
trimeshTRIMESH—

Outputs (1)

NameTypeDescription
meshMESH—