Atlas Path-Guided Hole Repair π₯
Pick the exact holes to fix from the camera move itself
- solve
- hole_mask
- camera_path
- path_frames
- paint_mask
- exclude_mask
- repair_mask
- angle_preview
- visible_islands
- report
The atlas-camera repair story has two chapters. The first - AtlasPlanarHolePatch - fills holes in the relief mesh by fitting planes from surrounding geometry, which is great for enclosed holes that have real neighbours to lean on. But open tears, silhouettes, and the messy leftovers at the frame edge don't have that support. Atlas Path-Guided Hole Repair is the chapter-two node: it uses the camera path itself to find and select exactly which source-space holes matter, from the viewpoint you'll actually see them at. It's the π₯ in Atlas/06 Β· Patch & Repair.
The trick is where the selection happens. Instead of trying to unproject brush strokes through geometry that doesn't exist, the node renders candidate planes with stable island IDs from a chosen frame of your camera path - the default being the last frame (frame_offset_from_end = 0). Because the IDs are stable, selecting them is deterministic: automatic modes pick visible fitted islands, or you paint on the render and the brush selects whole connected source islands.
How it works
It takes the remaining source-space holes from a first AtlasPlanarHolePatch pass, plus the authored camera path, and renders the scene from a chosen pose with each hole island carrying a stable ID. Then selection happens in rendered space:
- selection_mode = all_visible / smallest_visible / largest_visible - agent-style: automatically select every (or the smallest/largest) visible qualifying island at that angle.
- selection_mode = paint_overlap - you brush on the
angle_previewrender, and any island whose painted share clears paint_overlap_fraction gets its complete source-space component selected. No unprojecting through broken geometry.
The output repair_mask is exact source-space coverage of the selected islands - which the node tells you to wire into a second AtlasPlanarHolePatch with deliberately relaxed acceptance settings. First pass does the easy closed holes; this node finds the hard ones; the relaxed pass actually fills them.
Inputs and outputs
Required: solve, hole_mask (remaining holes from the first pass), camera_path. Key optional: path_frames (preview background only), paint_mask (for paint_overlap), exclude_mask (must match the mask you gave the mesh node, or it hunts for tears in geometry that was never built), layer, frame_offset_from_end, lens_scale_override (focal multiplier for the candidate render), resolution (long edge, default 768), selection_mode, max_selected_islands, min_visible_pixels, plus the plane-fit gates (ring_cells, normal_tolerance_deg, max_plane_error_m, max_hole_fraction, enclosed_only, min_normal_support_fraction).
Outputs: repair_mask, angle_preview, visible_islands, report.
Installing it
Core-tier node:
cd <ComfyUI>/custom_nodes
git clone https://github.com/mikejamesvfx/atlas-camera.git
Restart, find it in Atlas/06 Β· Patch & Repair (ComfyUI Manager: "atlas-camera").
Common issues
The exclude_mask contract is the trap. It's subtracted before connected components are found, separating open foreground tears from the exterior - and the tooltip says the report states its frame coverage so you can read the polarity back. Wire the same mask you gave the mesh node; if the two disagree, this node hunts for tears in geometry that was never built.
And remember the two-pass shape: this node selects, it doesn't fill. If you wire repair_mask into a AtlasPlanarHolePatch with the same strict settings as the first pass, the hard holes get rejected again and nothing happens. Relax the gates on the second pass - that's the design.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | β | |
| hole_mask | MASK | Remaining source-space holes from the first AtlasPlanarHolePatch pass. | |
| camera_path | ATLAS_CAMERA_PATH | Camera path authored/baked by Atlas Viewport. The selected pose is last frame minus offset. | |
| path_framesopt | IMAGE | Optional indexed viewport frame(s) used only as the preview background. Bake Repair Frame stores the final frame; candidate IDs remain exact without imagery. | |
| paint_maskopt | MASK | Optional mask painted over angle_preview. Used only when selection_mode=paint_overlap; touching a rendered candidate selects its complete source-space island. | |
| exclude_maskopt | MASK | Optional exclusion mask, subtracted before connected components are found, separating open foreground tears from the exterior. Wire the SAME mask you gave the mesh node - the two must agree or this one hunts for tears in geometry that was never built. The report states its frame coverage so you can read the polarity back. | |
| layeropt | STRING | Blank = primary relief; otherwise a ProjectionSource name. | |
| frame_offset_from_endopt | INT | 00β100000 | 0 = final frame, 1 = one frame before final, etc. |
| lens_scale_overrideopt | FLOAT | 0.000β4 | 0 = use the Camera Path playback lens. Otherwise a focal multiplier: below 1.0 is wider; above 1.0 tighter. |
| resolutionopt | INT | 768128β4096 | Long edge of the candidate ID render. |
| selection_modeopt | COMBO | Agent mode selects visible fitted islands automatically. paint_overlap converts a moved-view brush mask back into exact source-space connected islands. | |
| max_selected_islandsopt | INT | 00β1024 | 0 = all qualifying islands; otherwise cap selection in the chosen size order. |
| min_visible_pixelsopt | INT | 81β100000 | Ignore candidates with fewer rasterized pixels at the chosen repair angle. |
| paint_overlap_fractionopt | FLOAT | 0.020β1 | Minimum painted share of a visible island needed to select its full source-space component. |
| ring_cellsopt | INT | 21β12 | β |
| max_componentsopt | INT | 10241β4096 | β |
| normal_tolerance_degopt | FLOAT | 301β89 | β |
| max_plane_error_mopt | FLOAT | 0.450.001β10 | β |
| max_hole_fractionopt | FLOAT | 0.0400.0001β1 | β |
| enclosed_onlyopt | BOOLEAN | false | False allows silhouette/open-edge tears after the background/sky has already been excluded upstream. |
| min_normal_support_fractionopt | FLOAT | 0.200.1β1 | β |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| repair_mask | MASK | β |
| angle_preview | IMAGE | β |
| visible_islands | MASK | β |
| report | STRING | β |