πΎπ§± Composite Mesh Saver (Assimp FBX)
Export glb/obj/stl for free, fbx costs you one CLI install
- mesh_or_scene
This is the node that ends the 3D half of a workflow. Everything upstream in the pack - cleanup, capping, hole filling, colouring - is table stakes until something lands on disk in a format a game engine, Blender, or a slicer will open. That's this.
It's also the node with the sharpest hidden dependency in the pack, so read the fbx part before you wire anything.
What it does
One input socket, mesh_or_scene. If what arrives is a trimesh.Scene - which is what you get from the pack's own LoadMesh, or from a generated asset that still knows about its skeleton - it exports that scene as-is. If it's a single mesh, it builds a scene on the fly and names the parts part_00, part_01, and so on. Multi-part objects therefore survive as separate nodes in the exported file rather than being welded into one blob, which is what you want if anything downstream cares about parts.
Then:
glb,obj,stlgo straight through trimesh's exporter. GLB keeps the node hierarchy and, if the scene has it, the skeleton.fbxtakes a detour. It writes a temporary.glb, then shells out to the Assimp command line to convert it -assimp export temp.glb your_file.fbx- which is the trick that preserves bones and animation keys, since trimesh has no native FBX writer.
Outputs: none. This is an output node; it returns a UI text field with the final path so the node shows you where the file went.
The three parameters
mesh_or_scene(TRIMESH) - one mesh, or a scene.path(defaultoutput/my_project) - resolved withos.path.abspath, so a relative path lands relative to ComfyUI's working directory, not to itsoutput/folder. Absolute paths work; use them and stop guessing.filename(defaultfinal_character) - no extension; the format adds it.file_format-glb,obj,stl,fbx. Note the default isfbx, which is exactly the one that needs a binary you probably don't have.
The Assimp thing
fbx is a subprocess call. There is no pip package that puts an assimp executable on your PATH - that's a separate system install:
# Debian/Ubuntu
sudo apt install assimp-utils
# macOS
brew install assimp
# Windows: grab the Assimp release binaries, put assimp.exe on PATH
Now the nasty part: the export is wrapped in a broad try/except that prints the error and moves on. If assimp is missing, or the write fails, the node does not raise - the queue goes green and you get no file. This is the pack's single most confusing failure mode, and it's worth internalising across all of these nodes: when an Antonioilev node does nothing, read the ComfyUI console, not the UI.
Same applies to a bad path. The directory gets created with makedirs(exist_ok=True), so a typo gives you a new empty folder tree rather than an error.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Antonioilev/ComfyUI_Antonioilev_Lightpack.git
python -m pip install trimesh
Restart, and check the console for [Antonioilev_Light_pack] Loaded N nodes (M failed).
A community note that applies directly here: the most common way people lose an evening with 3D nodes in ComfyUI is a ModuleNotFoundError: No module named 'trimesh' in a node pack that ships no dependency installer. This pack is exactly that shape - no requirements.txt, no install.py, so Manager installs the code and nothing else. Install into the environment ComfyUI actually runs in (portable build: python_embeded\python.exe -m pip install trimesh). And note that once a trimesh import fails at module level, the affected nodes vanish from the Add Node menu entirely, which reads as "the node doesn't exist" rather than "the dependency is missing".
What you get on the other end
stl for printing - pair it with Mesh One Surface or MeshFixer Fast first, because a slicer only cares about watertight and will otherwise happily autofix your model into something worse. glb for anything modern and for re-import into ComfyUI. obj for the widest compatibility and for handing to a texturing app. fbx when the destination is Unreal, where the alternative is exporting a glb you can't import and round-tripping through Blender.
Keep the saver as the last node in the graph and let it write a fixed path - that gives you a stable file for Blender to re-import on watch, which is a much nicer loop than downloading zips out of output/.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| mesh_or_scene | TRIMESH | β | |
| path | STRING | output/my_project | β |
| filename | STRING | final_character | β |
| file_format | COMBO | fbx | 4 options: glb, obj, stl, fbx |
Outputs (0)
No outputs