Atlas Crop ROI ✂️
One fill region, generation-ready, with its camera
- solve
- source_image
- camera_path
- exclude_mask
- guide
- mask
- gen_width
- gen_height
- crop
- report
- native_width
- native_height
When a camera move opens a hole in your projection - a disocclusion gap where the source photo never looked - the fix is to generate the missing pixels with a video or image model. But you don't want to generate the whole frame; you want to aim the generator at exactly the hole. Atlas Crop ROI ✂️ is the node that turns one artist-drawn fill region into a generation-ready crop plus the camera that region was rendered with.
The mechanism
The key insight is that a camera-matrix crop is just a shifted principal point with a smaller raster - no separate render, no perspective warping, no misalignment. The ROI renders 1:1 with the plate through the same rasterizer the solve uses, so what comes out is geometrically exact. That's why the paste-back later (via AtlasCompositeCrop) is a pure rect blit instead of an alignment exercise.
The node handles the variable-ROI problem with an artist budget: three slots (roi_slot 1–3), three static branches, and an unused slot degrades to a no-op end to end - its guide passes through, the composite returns its input. That "no-op when empty" behavior is what lets you build one static graph that works whether you drew one, two, or three fills.
What comes out
The outputs are generation-ready on purpose:
guide- the crop's image, aspect-preserving and snapped to a/16grid, no longer thanmax_gen_long_edge(1280 default). A raster your generator will actually accept without resizing surprises.mask- the hole mask for that crop, at the same raster.gen_width/gen_height- the raster as plain INTs, made to wire intoWanVaceToVideo's width/height widgets (which would otherwise hard-code one raster for every crop).crop- theATLAS_CROPhandle carrying the native rect for the exact paste-back.
Artist or automatic?
roi_source defaults to artist: the viewport's drawn Fill ROIs win. But auto_largest is worth knowing - it surveys the end frame's disocclusion holes and takes the roi_slot-th LARGEST cluster, which is exactly the holes the viewport wand can't fix. It uses the same clustering recipe as the pack's CLI, so the two can't drift. min_area_px filters out clusters small enough for the wand or a band layer to handle, and exclude_mask subtracts regions already carried by something other than geometry (a sky dome, a matte) so the generator is never aimed at them. Auto mode also always drops holes whose ray at infinity lands on a hole in the plate (sky - nothing was ever occluding it) or outside the plate frame entirely (that's outpainting, not filling).
The camera_path input matters for the move case: give it the move and the crop renders its FINAL frame - whose holes are a superset of every earlier frame's - so one fill covers the whole path. No path means the solved pose.
Other knobs: pad_frac (context around the rect, 0.1 default), snap (grid snap, 64), hole_dilate_px (4). Install is the pack's clone-and-go; no heavy extras for the crop math itself. It's filed under Atlas/advanced because it's part of the repair loop, but it's honestly the friendliest way to aim a generator at a hole.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| solve | ATLAS_SOLVE | — | |
| source_image | IMAGE | — | |
| camera_pathopt | ATLAS_CAMERA_PATH | The move; the crop renders its FINAL frame (whose holes are a superset of every earlier frame's). No path = the solved pose. | |
| roi_slotopt | INT | 11–64 | Which ROI. ARTIST mode keeps its budget of 3 drawn ▦ Fill regions; AUTO mode ranks every move-revealed cluster, so the bound was raised to 64 for AtlasFillOccluded's expanded loop (2026-09-03) — survey_hole_rois never had a cap, only the three static branches a loopless graph could wire. An unused slot emits an empty crop that every downstream node treats as a no-op. |
| pad_fracopt | FLOAT | 0.100–0.5 | — |
| snapopt | INT | 648–128 | ROI grid snap (/64 covers every adapter). |
| hole_dilate_pxopt | INT | 40–64 | — |
| max_gen_long_edgeopt | INT | 1280256–4096 | Generation raster cap; the crop is scaled down (aspect kept, /16) when its native long edge exceeds this. |
| roi_sourceopt | COMBO | artist | artist: the viewport's drawn Fill ROIs (the default; artist selection wins). auto_largest: survey the end frame's disocclusion holes and take the roi_slot-th LARGEST cluster — the holes the viewport wand cannot fix. Same clustering recipe as the CLI (survey_hole_rois), so the two cannot drift. |
| min_area_pxopt | INT | 10241–1048576 | auto_largest only: clusters smaller than this (survey-resolution px) are ignored — the wand or a band layer handles those. |
| exclude_maskopt | MASK | auto_largest only: region already carried by something other than geometry (SkyDome, matte). Subtracted before clustering so a generator is never aimed at it. Auto mode ALSO always drops what the move did not reveal — holes whose ray at infinity lands on a hole in the plate (sky: nothing was ever occluding it) or outside the plate frame entirely (never looked at — that is outpainting). This input is for regions those geometric tests cannot know about. | |
| min_gen_long_edgeopt | INT | 00–4096 | Generation raster FLOOR (0 = off, the shipped behaviour). max_gen_long_edge only ever scales a crop DOWN, so a small hole cluster reaches the model at its native size -- and a diffusion model handed a 256px tile is far outside the band it was trained in and hallucinates rather than continues (measured 2026-09-04: FLUX Fill put a sand beach into both 256x256 sea-cliff ROIs). This scales the crop UP to the model's band before it is filled; the result comes back down to the native rect on the way to the plate, so no downstream node sees the working raster. The cap still WINS if the two conflict -- it is a VRAM bound, not a preference. |
Outputs (8)
| Name | Type | Description |
|---|---|---|
| guide | IMAGE | — |
| mask | MASK | — |
| gen_width | INT | — |
| gen_height | INT | — |
| crop | ATLAS_CROP | — |
| report | STRING | — |
| native_width | INT | — |
| native_height | INT | — |