Nodes/ComfyUI_Antonioilev_Lightpack/⚓ Hard Bottom Cap (Strict)
ComfyUI Node

⚓ Hard Bottom Cap (Strict)

It closes the flat cut and leaves your hair alone

By Antonioilev·Created 2 days ago·Updated a day ago· 0
⚓ Hard Bottom Cap (Strict)
  • mesh
  • info
  • mesh
cap_offset0.001
z_ratio0.05

Generated busts and statues have two kinds of openings: the honest one (a clean horizontal cut where the model was chopped at the base) and the dishonest ones (hair strands with gaps between them, a neck hole, alpha-card outlines). A generic hole filler closes all of them and turns your character's hair into a plastic helmet.

Hard Bottom Cap does one thing. It finds horizontal boundary edges near the bottom of the mesh and plugs them with a flat floor. Nothing else.

The mechanism

It merges vertices, then finds boundary edges the reliable way - edges that appear exactly once when sorted and de-duplicated. Then the "strict" filter, which is the entire point of the node:

  1. Both endpoints of the edge must be below z_min + z_ratio × Z-extent of the mesh. Default z_ratio 0.05 means 5% up from the lowest point.
  2. The edge must be nearly horizontal - difference in Z between its endpoints under 0.01 world units, hard-coded.

Edges passing both tests are the rim of the cut. It then adds one new vertex at the mean of those rim points, dropped by cap_offset below the mesh's lowest point (default 0.001 - one millimetre-ish in a metre-scale model), fans triangles from the rim to that point, and repairs winding and normals so the floor faces outward.

Result: the flat bottom is sealed, the neck hole and every hair gap is untouched, and the info string tells you exactly what happened - Sealed N faces at Z=..., or No horizontal boundary found below ..., or Mesh already watertight.

The two inputs

  • cap_offset (-0.05 to 0.05, default 0.001) - how far below the lowest vertex the plug sits. The default gives you a hair of separation rather than a coplanar floor, which is usually the safer geometry. A negative value pushes the plug up into the model instead, which occasionally reads better in a slicer.
  • z_ratio (0.01–0.2, default 0.05) - how far up from the bottom the search band goes. Raise it for a model whose cut isn't quite flat or which lost the bottom few percent in generation; lower it if the model's actual feet are near the bottom and you don't want to touch them.

Outputs: info (STRING, slot one) then mesh (slot two). Yes, the string is first. It's the same convention as CapGPU, Clean Mesh, and Hole Surgeon in this pack - check the socket index before you drag.

The scale trap

Both thresholds - z_ratio's extent multiplier is fine, but the 0.01 horizontality tolerance is absolute world units - are scale-sensitive. On a mesh normalised to ~1 unit tall, a 0.01 slope is a genuine horizontal edge and everything works. On a mesh exported in centimetres or in a 100-unit Blender scene, your "flat" rim has slopes larger than 0.01 and the strict filter finds nothing. You'll get No horizontal boundary found on a model that visibly has a flat bottom.

Fix: scale the mesh to roughly 1–2 units of height before capping (normalise on load), or accept that this node wants unit-scale input. This isn't a bug so much as a design assumption the author never surfaced.

When to pick it over CapGPU

CapGPU takes the largest boundary loop, so on a mesh whose neck hole is bigger than the base it caps the neck. Hard Bottom Cap is location-based, not size-based, so it's the right tool for a bust with a broad open neck. Meanwhile CapGPU in advanced_cap mode is what you reach for if you want the base to look like something - a plinth, a socket - rather than just be closed.

For a print: Hard Bottom Cap → MeshFixer Fast (which handles the small punctures it deliberately ignored) → Composite Mesh Saver to .stl.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/Antonioilev/ComfyUI_Antonioilev_Lightpack.git
python -m pip install trimesh

Restart ComfyUI. ComfyUI Manager will clone the pack for you (search Antonioilev Light Pack), but there is no requirements.txt in the repo, so trimesh - the only dependency this node has - has to be installed by hand into ComfyUI's environment. If the node is missing from the menu after a restart, look for the pack's startup banner: [Antonioilev_Light_pack] Loaded N nodes (M failed) followed by the import error is the whole diagnosis.

CategoryAntonioilev/Mesh

Inputs (3)

NameTypeDefaultDescription
meshTRIMESH
cap_offsetFLOAT0.001-0.05–0.05
z_ratioFLOAT0.050.01–0.2

Outputs (2)

NameTypeDescription
infoSTRING
meshTRIMESH