mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-03-23 01:53:32 +08:00
linear curve
This commit is contained in:
parent
62d9a99b8c
commit
57fc06ad6b
@ -7,6 +7,7 @@ from comfy_api.latest._input import (
|
|||||||
VideoInput,
|
VideoInput,
|
||||||
CurveInput,
|
CurveInput,
|
||||||
MonotoneCubicCurve,
|
MonotoneCubicCurve,
|
||||||
|
LinearCurve,
|
||||||
)
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -17,4 +18,5 @@ __all__ = [
|
|||||||
"VideoInput",
|
"VideoInput",
|
||||||
"CurveInput",
|
"CurveInput",
|
||||||
"MonotoneCubicCurve",
|
"MonotoneCubicCurve",
|
||||||
|
"LinearCurve",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
from .basic_types import ImageInput, AudioInput, MaskInput, LatentInput, CurveInput, MonotoneCubicCurve
|
from .basic_types import ImageInput, AudioInput, MaskInput, LatentInput, CurveInput, MonotoneCubicCurve, LinearCurve
|
||||||
from .video_types import VideoInput
|
from .video_types import VideoInput
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
@ -9,4 +9,5 @@ __all__ = [
|
|||||||
"LatentInput",
|
"LatentInput",
|
||||||
"CurveInput",
|
"CurveInput",
|
||||||
"MonotoneCubicCurve",
|
"MonotoneCubicCurve",
|
||||||
|
"LinearCurve",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -170,9 +170,9 @@ class MonotoneCubicCurve(CurveInput):
|
|||||||
xs, ys, slopes = self._xs, self._ys, self._slopes
|
xs, ys, slopes = self._xs, self._ys, self._slopes
|
||||||
n = len(xs)
|
n = len(xs)
|
||||||
if n == 0:
|
if n == 0:
|
||||||
return np.zeros_like(xs_in)
|
return np.zeros_like(xs_in, dtype=np.float64)
|
||||||
if n == 1:
|
if n == 1:
|
||||||
return np.full_like(xs_in, ys[0])
|
return np.full_like(xs_in, ys[0], dtype=np.float64)
|
||||||
|
|
||||||
hi = np.searchsorted(xs, xs_in, side='right').clip(1, n - 1)
|
hi = np.searchsorted(xs, xs_in, side='right').clip(1, n - 1)
|
||||||
lo = hi - 1
|
lo = hi - 1
|
||||||
@ -195,3 +195,40 @@ class MonotoneCubicCurve(CurveInput):
|
|||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"MonotoneCubicCurve(points={self._points})"
|
return f"MonotoneCubicCurve(points={self._points})"
|
||||||
|
|
||||||
|
|
||||||
|
class LinearCurve(CurveInput):
|
||||||
|
"""Piecewise linear interpolation over control points.
|
||||||
|
|
||||||
|
Mirrors the frontend ``createLinearInterpolator`` in
|
||||||
|
``ComfyUI_frontend/src/components/curve/curveUtils.ts``.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, control_points: list[CurvePoint]):
|
||||||
|
sorted_pts = sorted(control_points, key=lambda p: p[0])
|
||||||
|
self._points = [(float(x), float(y)) for x, y in sorted_pts]
|
||||||
|
self._xs = np.array([p[0] for p in self._points], dtype=np.float64)
|
||||||
|
self._ys = np.array([p[1] for p in self._points], dtype=np.float64)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def points(self) -> list[CurvePoint]:
|
||||||
|
return list(self._points)
|
||||||
|
|
||||||
|
def interp(self, x: float) -> float:
|
||||||
|
xs, ys = self._xs, self._ys
|
||||||
|
n = len(xs)
|
||||||
|
if n == 0:
|
||||||
|
return 0.0
|
||||||
|
if n == 1:
|
||||||
|
return float(ys[0])
|
||||||
|
return float(np.interp(x, xs, ys))
|
||||||
|
|
||||||
|
def interp_array(self, xs_in: np.ndarray) -> np.ndarray:
|
||||||
|
if len(self._xs) == 0:
|
||||||
|
return np.zeros_like(xs_in, dtype=np.float64)
|
||||||
|
if len(self._xs) == 1:
|
||||||
|
return np.full_like(xs_in, self._ys[0], dtype=np.float64)
|
||||||
|
return np.interp(xs_in, self._xs, self._ys)
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return f"LinearCurve(points={self._points})"
|
||||||
|
|||||||
11
nodes.py
11
nodes.py
@ -2039,7 +2039,7 @@ class CurveEditor:
|
|||||||
def INPUT_TYPES(s):
|
def INPUT_TYPES(s):
|
||||||
return {
|
return {
|
||||||
"required": {
|
"required": {
|
||||||
"curve": ("CURVE", {"default": [[0, 0], [1, 1]]}),
|
"curve": ("CURVE", {"default": {"points": [[0, 0], [1, 1]], "interpolation": "monotone_cubic"}}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2049,10 +2049,15 @@ class CurveEditor:
|
|||||||
CATEGORY = "utils"
|
CATEGORY = "utils"
|
||||||
|
|
||||||
def execute(self, curve):
|
def execute(self, curve):
|
||||||
from comfy_api.input import CurveInput, MonotoneCubicCurve
|
from comfy_api.input import CurveInput, MonotoneCubicCurve, LinearCurve
|
||||||
if isinstance(curve, CurveInput):
|
if isinstance(curve, CurveInput):
|
||||||
return (curve,)
|
return (curve,)
|
||||||
return (MonotoneCubicCurve([(float(x), float(y)) for x, y in curve]),)
|
raw_points = curve["points"] if isinstance(curve, dict) else curve
|
||||||
|
points = [(float(x), float(y)) for x, y in raw_points]
|
||||||
|
interpolation = curve.get("interpolation", "monotone_cubic") if isinstance(curve, dict) else "monotone_cubic"
|
||||||
|
if interpolation == "linear":
|
||||||
|
return (LinearCurve(points),)
|
||||||
|
return (MonotoneCubicCurve(points),)
|
||||||
|
|
||||||
|
|
||||||
NODE_CLASS_MAPPINGS = {
|
NODE_CLASS_MAPPINGS = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user