シーケンス (Sequences)
Griptape Nodes は、連番が付けられたファイル群を シーケンス (sequences) として読み込むことができます — 例えば、render.0001.exr、render.0002.exr、… render.0100.exr のようなレンダリング出力だけでなく、ダイアログのテイク(take_##.wav)、テキストチャンク(chapter_###.md)、またはファイル名内の数値キーによってアイテムが順序付きセットにグループ化されるあらゆるものが対象となります。シーケンス対応ノードに パスまたはパターン(番号部分にプレースホルダーを持つファイル名、またはリテラルなファイルパス)を指定すると、エンジンはディスク上の一致するアイテムを検索し、欠番(ギャップ)を処理して、整数値の番号とゼロ埋めされた文字列形式を含むエントリのリストを返します。
このページでは、パス/パターンの構文、欠落アイテムを処理するためのポリシー、および作成前に知っておくべき慣例について解説します。
パターン構文 (Pattern syntax)
シーケンスパターンは、アイテム番号の代わりにトークンを配置したファイル名の形式をとります。4 種類のトークン形式がサポートされています:
| トークン | 桁数 | 備考 |
|---|---|---|
#### |
4 | 各 # が 1 桁を表します。## = 2 桁、#### = 4 桁など。 |
%04d |
4 | C 言語スタイルの printf 形式。%04d = 4 桁ゼロ埋め。 |
@@@@ |
4 | Houdini/RV スタイル。#### と同じ意味。 |
$F4 |
4 | Houdini 変数。#### と同じ意味。 |
4 種類すべてが同等です;パイプラインの慣例に合致するものを選択してください。新規テンプレートには #### または %04d を推奨します — これらは各種 DCC ツール間で最も広く理解されています。
いくつか例を挙げます:
render.####.exr アイテム 5 → render.0005.exr
render.%04d.png アイテム 12 → render.0012.png
take_##.wav アイテム 7 → take_07.wav
トークンは常に ファイル名 内に配置されます。ディレクトリコンポーネント内のトークン(例: render/####/beauty.exr)はサポートされていません — 番号はファイル名部分にのみ配置してください。
パスにシーケンストークンがない場合 (When the path has no sequence token)
シーケンストークンを持たないパス(/work/photo.png、{inputs}/poster.png、render.0002.png など)は 曖昧 です。クリエイターの意図として以下のいずれかが考えられます:
- 特定の実体ファイル 1 つのリテラル名 —
render.0002.pngというファイルそのものを意図している; - 暗黙的なシーケンスの 1 フレーム — fileseq が数値を認識し、見つかったすべての
render.NNNN.pngを 1 つのシーケンスにまとめる; - 記述漏れ — クリエイターが
####を入力し忘れたため、修正できるように明確にエラーを通知すべきである。
エンジンは呼び出し元に対し、NoTokenBehavior(griptape_nodes.common.sequences 内)を通じてどの解釈を採用するかを問い合わせます:
| 値 | 動作 |
|---|---|
SINGLE_FILE (デフォルト) |
ファイル名全体をリテラルとして扱います。ファイルが存在する場合は 1 アイテムのシーケンス(first=last=1, padding=0)となり、存在しない場合は空の結果となります。同ディレクトリ内の兄弟ファイルは無視されます — render.0002.png の隣に 0001..0005 が存在していても、render.0002.png のみを返します。 |
EXPLORE_SEQUENCE |
fileseq がファイル名内の数値を暗黙のシーケンストークンとして解釈できるようにします。render.0002.png は推論された render.####.png シーケンスの 1 フレームとなり、スキャンは一致するすべての兄弟ファイルを走査します。下流のツールから 1 つのファイル名だけが渡されたものの、テイク全体を取得したい場合に有用です。 |
REJECT |
INVALID_TEMPLATE で即座に失敗し、クリエイターにトークンの追加を促すメッセージを表示します。クリエイターの意図を勝手に拡張してはならないパイプライン向けの厳格モードです。 |
デフォルトを SINGLE_FILE に設定しておくことで、「1 つのファイルを選択した」という直感的な期待に合わせた パス → 1 アイテムのシーケンス というマッピングが維持されます。暗黙的なグループ化の挙動を望むワークフローは、明示的にオプトインします。
マクロとの組み合わせ (Combining with macros)
シーケンスパスは、プロジェクトの マクロ言語 と連動します。エンジンがディスクから正しいディレクトリを読み込めるようにマクロの先頭部分は内部で解決されますが、出力されるパスはユーザーが指定した形状を維持します:
入力 : {inputs}/shot_a/render.####.exr
出力 : Sequence(directory="{inputs}/shot_a",
entries=[{path: "{inputs}/shot_a/render.0001.exr"},
{path: "{inputs}/shot_a/render.0002.exr"}, ...])
これによってスキャン結果の移植性が担保されます。{inputs} が /Volumes/Renders に解決されるマシンで構築されたワークフローは、パスに {inputs} を含んだままのシーケンスを生成します — {inputs} が C:\renders に解決されるマシンでそのワークフローを再度開いても問題なく動作します。下流の各コンシューマが自身のプロジェクトに対してマクロを新しく解決するためです。
プレーンな絶対パス({...} セグメントを含まないパス)も同様にラウンドトリップします — /work/render.####.png を入力すれば、/work/render.0001.png が返されます。
相対パス: 先頭に / がなくマクロの先頭部も持たないパス(例: shot_a/render.####.png)は、プロジェクトのワークスペースディレクトリを起点として解釈されます。エンジンはリストを取得する前にワークスペースパスを先頭に付与するため、shot_a/render.####.png と {workspace_dir}/shot_a/render.####.png は全く同じように解決されます。ワークフローにとってより自然に読める形式を使用してください。
{...} 内のマクロ変数はシーケンストークンとは完全に独立しています — 構文を共有することはなく、異なるステージで解決されます。
桁数マッチングは厳格 (Width matching is strict)
# 文字の個数(または %0Nd の桁数)は、一致させる 厳密な 桁数を宣言します。パターンが #### と記述されている場合、エンジンはそのスロットが厳密に 4 桁であるファイルのみに一致させます — render.0001.exr には一致しますが、render.001.exr(3 桁)や render.12345.exr(5 桁)には一致しません。
これは Nuke の挙動と同じです。シーケンス内の番号が宣言されたパディング桁数をオーバーフローする場合(例: 4 桁パターンだが実際の番号が 9999 を超える場合)、それらをキャプチャするにはより広いパターン(#####)を使用してください。
ディレクトリ内にパディング桁数が混在するファイルが含まれている場合(例えば render.0001.png と render.001.png の両方)、それらは 別々のシーケンス として扱われます。エンジンは宣言されたテンプレートのパディングと一致するもののみを照合し、その他は無視されます。
欠落アイテムのポリシー (Missing-item policies)
実際のシーケンスにはギャップ(欠番)が頻繁に発生します — フレーム 47 でクラッシュしたレンダリング、偶数テイクしか保存されていないまばらなエクスポート、まだ書き上げられていない章など。シーケンスをスキャンする際、それらのギャップをどのように処理するかについての ポリシー (policy) を選択します:
| ポリシー | 動作 |
|---|---|
ABORT |
即座に失敗します。[first, last] 内で最初のギャップに遭遇した時点で、問題のアイテム番号を含むエラーを表面化させます。Sequence は返されません。 |
SPLIT (デフォルト) |
存在するアイテムの 連続した塊(ラン) ごとに 1 つのシーケンスを生成します。アイテム 1–5、8–12、15 を持つシーケンスは、3 つの独立したシーケンスを生成します。 |
SKIP |
存在するアイテムのみを含む 1 つのシーケンスを生成します。ギャップは出力から除外されます(ただしシーケンスの missing_numbers セット経由で確認可能です)。 |
FILL_NEAREST |
[first, last] の全範囲をカバーする 1 つのシーケンスを生成します。欠落した各アイテムは、最も近い 手前 の存在するアイテムのパスで埋められます(手前に存在しない場合は直後のアイテム)。 |
ギャップによってワークフローを明確に失敗させるべき場合(例: クラッシュしたレンダリングを勝手に進めてはならない場合)は ABORT を選択します。ギャップ構造を 維持 したい場合(各連続区間がそれぞれ意味を持つ場合)は SPLIT を選択します。ディスク上の実態に関係なく、単一のまばらなシーケンスが必要な場合は SKIP、単一の密なシーケンスが必要な場合は FILL_NEAREST を選択します。
ドメイン固有のギャップ描画はエンジンではなくノードの責務です。 欠落アイテムの代わりに黒フレームのプレースホルダー、マゼンタ/イエローの市松模様、無音のオーディオチャンク、空のテキストチャンクなどを合成したい場合は、SKIP でスキャンし、ノード内で missing_numbers を走査してドメインが要求するものを独自に描画してください。エンジンは「この番号はディスク上に存在しない」と通知する役割に徹し、それ以降はノードが担当します。
サブセットのクリッピング (Subset clipping)
シーケンス対応ノードは、任意の start および end 境界を受け付けます。指定された場合、スキャンはその範囲にクリッピングされます:
startより前およびendより後ろのアイテムは出力から除外されます。- 元のディスク上の範囲は
discovered_first/discovered_last経由で報告されるため、クリッピング前に何が存在していたかを確認できます。 - 発見された範囲の外側にサブセット境界を指定した場合は、空の結果(Failure)となります。
返却されるデータ (What you get back)
Sequence は Pydantic モデルです — 属性経由でフィールドを読み取ります(seq.first、seq.entries[0].number など)。シーケンスを操作するノードは、その入力を type="Sequence" として宣言すべきです;エンジンは名前によって接続を検証します。
各 Sequence は以下を保持します:
first/last— 有効範囲(サブセットクリッピング後)。discovered_first/discovered_last— サブセットに関係なく、ディスク上に実際に存在していた範囲。padding— 宣言されたゼロ埋め桁数(例:####の場合は 4)。pattern— 標準パターン(例:render.####.exr)。directory— 指定されたパスのディレクトリ部分(マクロ指定時はマクロ形式、それ以外は絶対パス)。policy— 適用されたポリシー。entries— 有効範囲内の各アイテムに対する 1 つのSequenceEntry。それぞれ以下を持ちます:number— 整数キー(例: 5)。padded_number— ゼロ埋めされた文字列(例:0005)。path— 指定された形状を維持したファイルパス文字列。マクロ形式の入力はマクロ先頭部を維持してラウンドトリップし({inputs}/render.0005.exr)、プレーンな絶対パス入力はそのまま返ります(/work/render.0005.exr)。FILL_NEARESTのもとでは、ギャップエントリは最も近い実在アイテムのパスを保持します;実在するものと埋められたものを区別するにはentry.number in seq.present_numbersを照合してください。
present_numbers—[first, last]内でディスク上に実際に存在する番号のセット。missing_numbers—present_numbersから派生した、有効範囲内でディスク上に存在しない番号のセット(任意のポリシーでの診断に有用)。
意図的にサポートされていないケース
以下のケースは意図的に除外されています:
- 負の数:
render.-0005.exrのようなファイルはスキャン時に除外されます。除外された件数は結果のシーケンス上で報告されます。 - ディレクトリコンポーネント内のシーケンストークン:
render/####/beauty.exrのようなパターンはマッチしません。番号はファイル名に配置してください。 - マルチトークンパターン: 2 つ以上のシーケンストークンを含むテンプレート(例:
v##_f####.exr、render.##.##.exr)は、明確なエラーとともにスキャン時に拒否されます。1 つのパターンにつき 1 つのトークンを使用してください。 - タイムコード: 現在は未サポートです。
技術的背景 (Where this comes from)
シーケンス処理は、VFX スタイルのフレーム範囲解析におけるデファクトスタンダードな Python ライブラリである fileseq をベースに構築されています。パーサーおよび数値演算ライブラリとして採用されています;すべてのファイルシステムリスト取得はエンジンのリクエストバスを経由するため、他のファイル操作を管理するのと同じワークスペース権限、パスの正規化、および Windows のロングパス処理がここでも適用されます。fileseq 自体は全体を通じて「フレーム (frame)」という用語を使用していますが、これは内部実装の詳細です;公開 API では「アイテム (items)」および「番号 (numbers)」という用語を使用し、画像だけでなく任意の連番ファイルシーケンスに対応できるようにしています。
公開エントリポイント: ScanSequencesRequest
スキャンは関数をインポートするのではなく、エンジンのイベントバス上でディスパッチされます。ScanSequencesRequest(griptape_nodes.retained_mode.events.os_events に定義)を送信し、await GriptapeNodes.ahandle_request(...) を実行します;ハンドラはプロジェクトマクロを解決し、ディレクトリ一覧を取得し、ワーカースレッド内で fileseq の解析を実行するため、深いディレクトリに対する長時間のスキャンでもイベントループをブロックしません。
リクエストは単一の path フィールドを受け取ります。例:
# マクロ形式のパターン。出力されるすべてのパスで {inputs} 先頭部が維持されます。
ScanSequencesRequest(path="{inputs}/shot_a/render.####.exr")
# プレーンな絶対パスパターン。そのままラウンドトリップします。
ScanSequencesRequest(path="/work/render.####.png", policy=MissingItemPolicy.SKIP)
# トークンのないパス。デフォルトの `no_token_behavior=SINGLE_FILE` は、
# そのファイルのみを含む 1 アイテムのシーケンスを返します(存在しない場合は空)。
ScanSequencesRequest(path="/work/photo.png")
# トークンのないパスだが、暗黙のシーケンスの 1 フレームとして扱い、
# 一致するすべての兄弟ファイルを走査します。
ScanSequencesRequest(
path="/work/render.0002.png",
no_token_behavior=NoTokenBehavior.EXPLORE_SEQUENCE,
)
# 厳格モード: パスにトークンがない場合 INVALID_TEMPLATE で失敗します。
ScanSequencesRequest(
path="/work/render.0002.png",
no_token_behavior=NoTokenBehavior.REJECT,
)
# 有効範囲のサブセット指定。
ScanSequencesRequest(path="{inputs}/render.####.exr", start_number=10, end_number=50)
成功時は ScanSequencesResultSuccess が返され、以下を保持します:
sequences: list[Sequence]— ポリシー適用後の推論されたシーケンス群。各Sequence.directoryおよびentry.pathは指定されたパス形状を維持します(マクロ入力ならマクロ出力)。has_entries: bool— 少なくとも 1 つの Sequence が 1 つ以上のエントリを持つ場合に true。正常に実行されたが何も見つからなかった場合は失敗ではなくhas_entries=Falseの成功 となります — 結果が空の場合にフェイルファストする必要がある呼び出し元は、自身でhas_entriesをチェックします。directory_had_matching_files: bool— ディレクトリ一覧取得によって、ベース名 + 拡張子がターゲット形状に一致するファイルが少なくとも 1 つ生成された場合(事前フィルタが何らかを受け入れた場合)に true。has_entriesと組み合わせることで、スキャン結果が空になった 理由 が判明します:false の場合はパスが間違っているかベース名/拡張子が何にも一致しないことを意味し、true かつhas_entries=Falseの場合はファイルは存在するもののパディング桁数が一致しないか、有効サブセットによってすべて除外されたことを意味します。discovered_first: int | None/discovered_last: int | None— サブセットクリッピングが適用される 前 の、推論された番号のディスク上の範囲。ディレクトリから fileseq が少なくとも 1 つの数値を推論した場合は常に入力されます;リストにパディングの一致する番号がなかった場合はNoneになります。呼び出し元が推測に頼ることなくサブセットクリップのケースを診断できます — 例えば「90..100 を要求したがディスクには 1..7 しか存在しない」といった情報がこれらのフィールドから直接得られます。
これら 3 つの診断フィールドにより、コンシューマは result_details 文字列を解析することなく、パス誤り / パディング誤り / 範囲誤りのケースを判別できます。少なくとも 1 つのシーケンスがある場合は、各 Sequence オブジェクト上の discovered_first/discovered_last を読み取るのが適切です;トップレベルのフィールドは特に空結果の診断用です。
失敗時は ScanSequencesResultFailure が返され、その failure_reason は SequenceScanFailureReason(INVALID_TEMPLATE、INVALID_BOUNDS、ABORTED_AT_GAP)または OS レイヤーの FileIOFailureReason のいずれかになります。失敗はスキャンが続行できなかったケースのために予約されています:
INVALID_TEMPLATE— パス文字列を解析できなかった場合(不正なマクロ構文、複数トークンパターン、ファイル名コンポーネントの欠落、解決不能なマクロ変数など)。パスにシーケンストークンがなく、no_token_behaviorがREJECTの場合にも発生します。INVALID_BOUNDS—start_number < 0またはend_number < start_numberの場合。ABORTED_AT_GAP—ABORTポリシーが有効範囲内で少なくとも 1 つのギャップに遭遇した場合。この失敗では、問題のあるすべての整数キーが昇順でソートされてmissing_item_numbers: list[int]に入力されます — UI コンシューマは、再実行のたびに 1 つずつ修正させるのではなく、すべての 欠落スロットをクリエイターに一度に提示できます。FileIOFailureReason値 — 内部ディレクトリのリスト取得自体が失敗した場合(ディレクトリが見つからない、アクセス権限がないなど)。これらは空の成功結果にまとめられることなく、FileIOFailureReason経由で表面化します。
ノードレベル: fail_on_empty_result
標準ライブラリの ScanSequenceNode と ScanSplitSequenceNode は、どちらもトップレベルの fail_on_empty_result: bool = True パラメータを公開しています。true(デフォルト)の場合、空のスキャン結果になるとノードは上記のフィールドから構築された診断メッセージとともに Failure 制御フローエッジを通ります。false の場合、ノードは空の出力とオプトアウトを示すステータスとともに成功します — 空のスキャンを許容するワークフロー向けです。
ノードレベル: When there's no sequence marker(シーケンスマーカーがない場合)
両方の Scan ノードは、折りたたまれた Advanced Sequence Control グループ内に、When there's no sequence marker (e.g., ###) というわかりやすいラベルのドロップダウンとして NoTokenBehavior の選択肢を公開しています。3 つのオプションがエンジン列挙型に対応します:
| ドロップダウンラベル | エンジンの値 |
|---|---|
| Treat as a single file (デフォルト) | SINGLE_FILE |
| Treat as part of a sequence | EXPLORE_SEQUENCE |
| Fail unless a token is present | REJECT |
このドロップダウンは、ノード内の相対境界検出プローブ(Start at / End at が Relative … に設定されている場合)も制御するため、ノードがオフセットを調べている最中にリテラルファイルパスが勝手に探索されるのを防ぎます。
ライブラリやノードのコードは、下位のスキャナーを直接インポートしてはなりません — リクエストバスが唯一の公開パスです。