2024-04-09(更新)

【ComfyUI ノードを作ろう #2】クラスの中身を作る。実際の処理を書くところ!

ComfyUIのノードを自作するシリーズ2回目。クラスの中身を書いてノードになにか処理をさせよう!

Article Image

2024-04-09:FUNCTIONの項の解説が少なかったため詳細を追記

前回のおさらい

前回はコピペでとりあえずComfyUIにオリジナルノードを認識させるところと、ノード名の付け方について解説した。

第一回を読んでいない方は次のリンクから

【ComfyUI ノードを作ろう #1】とりあえず動くノードを作る!ノード名の付け方 | 謎の技術研究部

前回のプログラムのクラス

今回は前回と同じプログラムを使って実際の処理の部分に迫っていきたい。

まずは前回のプログラムからクラスの中身を理解する。

class aaaaa:

    @classmethod
    def INPUT_TYPES(s):
        return {"required": {"myINT": ("INT", {"forceInput": True})}}

    RETURN_TYPES = ("INT",)
    FUNCTION = "go"
    CATEGORY = "test"

    def go(self, myINT):
        return (myINT,)


NODE_CLASS_MAPPINGS = {
    "bbbbb": aaaaa,
}

NODE_DISPLAY_NAME_MAPPINGS = {
    "bbbbb": "My Node",
}

※前回解説している__init__.pyは省略する。同一階層に置いてあればOK

@classmethod

ここはPython基礎なのでさらっと。

これをつけているとクラスをインスタンス化しなくてもメソッドが使えるようになるおまじない。

INPUT_TYPES

    def INPUT_TYPES(s):
        return {"required": {"myINT": ("INT", {"forceInput": True})}}

こちらの部分。

その名の通り入力ピンに相当するデータ形式を記述する。

辞書型をreturnすることで実現する。

requiredの箇所

頭のrequiredの箇所は

  • required:入力必須
  • hidden:非表示
  • optional:何も入力しなくてもOK

の3種類。

myINTの箇所

ここはソケットの表示名。

このキーの値には"()"で表される「タプル」が入ることを注意する。

わからない人はPython基礎で学習すべし。

INTの箇所

その中に各ピンの型を入れている。

公式の解説には

"MODEL", "VAE", "CLIP", "CONDITIONING", "LATENT", "IMAGE", "INT", "STRING", "FLOAT"

が例として上げられているが、これ以外なんでもよさそう。

適当に"MONEY"にして実行してみたがエラーにならず、恐らく自分で定義した型も使えそう。

ちょっと難しいが、実際にはbboxやsegmなんていう特殊な型はよく見かける。

現時点で型の定義などをする必要はないと思うが(要調査)同じ型のソケット同士しか繋げないはず

forceInputの箇所

ここは

  • forceInput:入力必須(true/false)
  • default:デフォルト値(好きな値)
  • multiline:複数行を許可(true/false)
  • min(max):最小値(最大値)を設定
  • step: 上下のボタンをクリックすることでこのstepずつ値が増減する(キー入力もこのstepに準じた値しか入力できない)
  • slider: "number" or "slider" で数値入力の見た目が変わるだけ。

がある。

forceInputfalseにするとノードに入力欄が現れ、trueにするとピンになる。

入力欄

sliderのサンプルは次。ドラッグで前後にスライダを動かせる

sliderサンプル

クラス変数

    RETURN_TYPES = ("INT", )
    FUNCTION = "go"
    CATEGORY = "test"

RETURN_TYPES

これだけ省略不可能な変数。必ず入れる。

RETURN_TYPESは出力される型を入れる。

タプルの最後の値は省略する書き方が一般的のようなので従っておく。

アウトプットピンを増やす

このタプルを("INT", "STRING", )のようにしてやればアウトプットのピンは2個になる

2個になった例

終端ノードにする場合(アウトプットなし)

アウトプット無しの終端ノードにしたい場合はRETUREN_TYPES = ()にする。

FUNCTION

    def go(self, myINT):
        return (myINT,)

ここは上で書いてあるFUNCTION = "go"に従ってgoという関数にする。名称は自由に変更する。

この関数がこのノードのメイン処理となる。

この関数の引数の最初はself,それ以降の引数はINPUT_TYPESで設定したものと同じ名称を入れることでここで入力ピンを受け取れる。

ここではmyINT

returnに注意

最後のreturn (myINT,)だが、必ず最後にカンマを打って終わることを注意する。

これがないと例えば文字列をreturnした時に最初の1文字しかリターンされないという不具合が起きる。

このリターンに入った変数がアウトプットのピンから出力される。

CATEGORY

右クリックでノードを出すときのカテゴリ分け。

ここをスラッシュで区切ると階層になる。

例えばCATEGORY = "test/a1/b2/b1"とすると

カテゴリ

このようになる。

末尾であるb1の後にスラッシュを入れてはいけない。

空のカテゴリがこの後に追加されるので表示がおかしくなる。

以降は上に記述していないその他のクラス変数を紹介する。

RETURN_NAMES

RETURN_TYPESで指定したピンの型に表示名をつけるだけ。このクラス変数は省略可能

    RETURN_TYPES = ("INT","STRING" , "MONAY")
    RETURN_NAMES = ("お金","を", "ください")

例えば上のようにすると

表示名を変更

かなりお金を欲するノードになる。

OUTPUT_NODE

OUTPUT_NODE = Trueのように記述する。

これがTrueの場合はこのノードが出力ノードとして扱われ、これに接続されている入力側のノードが全部実行されてからこれが実行されるようになる。

といったような記述(実は私もよく分かっていない)

すなわちノードの終端として扱われるようだが、この後に出力ピンをつけている実装例も複数ある。

SaveImageノードのような書き出し系のノードに使うらしい。

またわざわざこれをFalseにしなくても、そもそもOUTPUT_NODEのクラス変数はなくても良い。

以上

今回は長くなったが以上だ。

極端な話あとは関数の中に処理を記述してやればなんでもできる。



この記事をシェア


謎の技術研究部 (謎技研)