π§± GPU Strong Remesh (Watertight)
Hunyuan3D Gave You Triangle Soup β This Makes It Watertight
- trimesh
- mesh
- info
What it's actually for
Everything image-to-3D hands you is triangle soup. Hunyuan3D and TRELLIS give you a genuinely nice-looking surface wrapped around geometry nobody wants - the KB's 3D generation doc puts the community verdict at "terrible topology and messed-up UV unwrapping" from the model's own author, and that hasn't been overturned. For a 3D print or a static prop, that's fine. For anything that needs a solid, uniform, closed shell, it isn't.
π§± GPU Strong Remesh (Watertight) is the second pass. You generate the shape, then run it through this node to get an even-density, closed mesh you can slice, boolean, or hand to a retopo step.
How it works
It's a GPU dual-contouring remesh, not a Blender-style quad remesher. The input mesh gets voxelised onto a grid (grid_resolution), the surface is re-extracted as a new triangle mesh at that grid's density, and the result is projected back toward the original surface so you don't lose the silhouette you just spent five minutes generating.
Under the hood the node imports cumesh - the CUDA mesh library the heavier 3D pipelines use - and runs the remesh on your GPU with torch tensors. Two flags sit on top of the remesh itself: repair_holes closes boundary loops, and force_watertight keeps pushing until the shell is closed rather than returning a repaired-but-still-open mesh. Large inputs are guarded by pre_simplify_limit, and max_hole_edges caps how big a hole the repair pass will even attempt.
The inputs that matter
- grid_resolution (default 512) - the whole ballgame. 256 is a fast, blobby preview; 1024+ is where thin features survive. Cost scales roughly with the cube of this, in both time and VRAM.
- band_width (default 3) - how much volume around the surface the remesher keeps active. Wider catches thin geometry, costs more.
- project_back (default 0.15) - how hard the new surface is snapped back onto the original. Low values smooth and round; crank it up to keep detail, but too high reintroduces the lumpy original.
- repair_holes / force_watertight - leave both on unless you actually want the holes. They're the reason "watertight" is in the name.
- pre_simplify_limit (default 2,000,000) - drops the input down before remeshing if you feed it a scan with tens of millions of faces.
Outputs are mesh (a TRIMESH, so it chains straight into the pack's UV nodes) and info, a plain string. Read the info string. It's where a failed remesh reports Remesh Error: ... instead of crashing the graph, and where you confirm the run did what you think it did.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Antonioilev/ComfyUI_Antonioilev_Lightpack.git
# restart ComfyUI
Or search "Antonioilev Light Pack" in ComfyUI Manager. The pack ships no requirements.txt and no install.py - every module import is wrapped in try/except inside __init__.py, which prints [Antonioilev_Light_pack] Loaded N nodes (M failed) and moves on. So a missing dependency doesn't throw an error at you; the node just isn't in the menu. For this node the missing piece is cumesh (plus a working CUDA torch), which you install by hand:
pip install cumesh
If you're squeamish about a pip install pulling a CUDA build, test it in a venv first - this pack is the author's own working environment, not a packaged release.
Where people get burned
- It's CUDA-only. No
cumesh, no node. CPU-only ComfyUI installs should skip straight to the pack's non-GPU mesh tools. - VRAM is the limit, not patience. 1024 on a detailed asset can eat gigabytes; if you're on 8-12GB, remesh big sources at 256-512 and let
pre_simplify_limitdo its job. - Remeshing before texturing, always. A remesh throws away UVs by construction. If you already baked textures, you're rebaking.
- Zero-area and duplicate faces in the source mesh are the usual cause of a weird result; run the pack's weld/hole tools (or
trimesh.repair) first and the remesh has a much easier time.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| trimesh | TRIMESH | β | |
| grid_resolution | INT | 51264β2048 | β |
| band_width | FLOAT | 3.01β16 | β |
| project_back | FLOAT | 0.150β1 | β |
| repair_holes | BOOLEAN | true | β |
| force_watertight | BOOLEAN | true | β |
| pre_simplify_limitopt | INT | 20000000β20000000 | β |
| max_hole_edgesopt | INT | 5000β20000 | β |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| mesh | TRIMESH | β |
| info | STRING | β |