diff --git a/README.md b/README.md index 942aaa0..3392bf2 100644 --- a/README.md +++ b/README.md @@ -29,19 +29,36 @@ git clone https://github.com/RockyHong/ComfyUI-FilePathsFromFolder.git ## Choose how you want to iterate -- **Option A — Use another loop pack (index-based): get a file path list + pick one path per iteration** +- **Option A — External loop (index-based): get a file path list + pick one path per iteration** ([jump](#option-a-external-loop)) - Use `LoadFilePathsFromFolder` → `GetPathByIndex` - Best when you already have a loop/for/while node from another pack, and you just need a clean “files-by-extension” input. -- **Option B — Use this repo’s simple loop: run downstream nodes once per file (list batching)** +- **Option B — This repo’s loop node: run downstream nodes once per file (list batching)** ([jump](#option-b-internal-loop)) - Use `FilePathsForLoop` → your processing nodes → (optional) `FilePathsEnsureExecution` → `FilePathsLoopClose` - Best when you want a simple, no-extra-deps “loop”: ComfyUI runs downstream nodes once per file via list batching. -## Node reference + +## Option A — External loop (index-based) -### `LoadFilePathsFromFolder` +Use this when you already have an external loop/for/while node pack and you want to drive it with “files in a folder” (by extension). -- **What it does**: scan a folder for matching files. +### Nodes used + +- `LoadFilePathsFromFolder`: scan folder → get `filepaths` / `filenames` / `count` +- `GetPathByIndex`: choose one item → get `filepath` / `filename` + +### Example workflow (external loop pack) + +1. `LoadFilePathsFromFolder` (set folder path + extension) +2. `count` → your loop node “iterations” / “max” (names vary by pack) +3. Loop `index` → `GetPathByIndex.index` +4. `LoadFilePathsFromFolder.filepaths` + `.filenames` → `GetPathByIndex` +5. `GetPathByIndex.filepath` → your loader node (Load Image / Load Video / etc.) +6. Do your processing + save/export inside your external loop pack + +### Node reference + +#### `LoadFilePathsFromFolder` - **Parameters** - `folder_path`: folder to scan - `extension`: pattern like `"*.png"`, `"*.jpg"`, `"*.txt"` @@ -50,9 +67,8 @@ git clone https://github.com/RockyHong/ComfyUI-FilePathsFromFolder.git - `filenames`: newline-separated base names (no extension) - `count`: number of matched files -### `GetPathByIndex` +#### `GetPathByIndex` -- **What it does**: pick one file by index (0-based). - **Inputs** - `filepaths`: from `LoadFilePathsFromFolder` - `filenames`: from `LoadFilePathsFromFolder` @@ -62,25 +78,40 @@ git clone https://github.com/RockyHong/ComfyUI-FilePathsFromFolder.git - `filepath`: selected full path - `filename`: selected base name -## Loop nodes (ComfyUI list batching) -### Memory note (about this repo’s loop nodes) + +## Option B — Internal loop (this repo’s loop node, list batching) -`FilePathsForLoop` uses **ComfyUI list batching** (it sets `OUTPUT_IS_LIST`). This is not a “while/for loop” that runs one full iteration end-to-end. +Use this when you want the simplest setup: `FilePathsForLoop` returns lists, and ComfyUI runs downstream nodes **once per file** via list batching. -- **What this means in practice**: if you connect `Load X From Path` → `Process` → `Save`, ComfyUI may do all the `Load` work for the batch first, then all the `Process` work, then all the `Save` work (instead of Load→Process→Save per item). +### Nodes used -- **Why memory can grow**: batching can keep more intermediate results “alive” until later nodes run, and heavy nodes (generation/model processing/large video frames) can push VRAM/RAM peak usage. -- **Why batching can be great**: big models can stay loaded while the batch runs, so you avoid repeated load/unload overhead between items. +- `FilePathsForLoop`: generates the per-file list outputs (`current_filepath`, `current_index`, etc.) +- (Optional) `FilePathsEnsureExecution`: “anchors” a route so it definitely runs (useful for save/write/export routes) +- `FilePathsLoopClose`: loop terminator / completion signal -- **Practical tip**: if you notice memory climbing, insert “Clean VRAM” / “Clean RAM” (or equivalent) at safe points after heavy steps. -- **If you need strict sequential iteration** (finish item 0 completely before item 1): use a dedicated for/while-loop node pack (a “real loop”), and drive it with: - - `LoadFilePathsFromFolder` → `count` (loop count) - - `GetPathByIndex` → `filepath`/`filename` (per-iteration selection) +### Memory note -### `FilePathsForLoop` +`FilePathsForLoop` uses **ComfyUI list batching** (it sets `OUTPUT_IS_LIST`). This is not a “while/for loop” that runs one full item end-to-end. + +- **What you may observe**: ComfyUI often runs **node-by-node for the batch**. So a route like `Load X From Path` → `Process` → `Save` can look like “all loads”, then “all processing”, then “all saves” (not Load→Process→Save per file). +- **Why memory can grow**: batching can keep more intermediate results “alive” until later nodes run; heavy nodes (models / large frames / big tensors) can push VRAM/RAM peak usage. +- **Practical tip**: if you notice memory climbing, add “Clean VRAM” / “Clean RAM” (or equivalent) at safe points after heavy steps. +- **If you need strict sequential iteration** (finish item 0 completely before item 1): use an external loop/for/while node pack and Option A. + +### Example workflow (internal loop: once per file) + +1. `FilePathsForLoop` (set folder path + extension) +2. `current_filepath` → your loader node (e.g. Load Image) +3. Your processing nodes +4. (Optional) outputs you want to **guarantee run** (e.g. save/write/export nodes) → `FilePathsEnsureExecution.passthrough_1` … `passthrough_5` +5. `current_index` → `FilePathsLoopClose.current_index` +6. (Optional) `FilePathsEnsureExecution.passthrough` → `FilePathsLoopClose.passthrough` (this “anchors” the route so it executes) + +### Node reference (internal loop nodes) + +#### `FilePathsForLoop` -- **What it does**: returns a **list** of files so ComfyUI can run downstream nodes **once per item**. - **Parameters** - `folder_path` - `extension` @@ -92,16 +123,7 @@ git clone https://github.com/RockyHong/ComfyUI-FilePathsFromFolder.git **Key detail:** this node sets `OUTPUT_IS_LIST`. Downstream nodes receive **one item per execution** (not the whole list). -### `FilePathsLoopClose` - -- **What it does**: loop “terminator” / completion signal. -- **Inputs** - - `current_index`: from `FilePathsForLoop` (required) - - `passthrough`: optional (often from `FilePathsEnsureExecution.passthrough`) -- **Outputs** - - `processed_count` - -### `FilePathsEnsureExecution` +#### `FilePathsEnsureExecution` - **What it does**: “collects” outputs so a route becomes **required** (and actually runs). @@ -119,20 +141,10 @@ Example route: `Load Image From Path` → processing → `Save Image` → connec Tip: if you need more than 5 inputs, chain multiple `FilePathsEnsureExecution` nodes. -## How ComfyUI list batching works (tiny mental model) +#### `FilePathsLoopClose` -When a node outputs a list (via `OUTPUT_IS_LIST`): - -1. The node returns something like `["file1.png", "file2.png", "file3.png"]` -2. ComfyUI schedules execution across the graph in **batch mode** -3. Many nodes will be invoked repeatedly so each call receives a **single** item (e.g. `"file2.png"`) -4. But execution tends to happen **node-by-node for the batch** (so you may observe “all loads”, then “all processing”, then “all saves”) - -## Example workflow (loop every file) - -1. `FilePathsForLoop` (set folder path + extension) -2. `current_filepath` → your loader node (e.g. Load Image) -3. Your processing nodes -4. (Optional) outputs you want to **guarantee run** (e.g. save/write/export nodes) → `FilePathsEnsureExecution.passthrough_1` … `passthrough_5` -5. `current_index` → `FilePathsLoopClose.current_index` -6. (Optional) `FilePathsEnsureExecution.passthrough` → `FilePathsLoopClose.passthrough` (this “anchors” the route so it executes) \ No newline at end of file +- **Inputs** + - `current_index`: from `FilePathsForLoop` (required) + - `passthrough`: optional (often from `FilePathsEnsureExecution.passthrough`) +- **Outputs** + - `processed_count` \ No newline at end of file