add flip node

This commit is contained in:
2026-03-27 21:37:39 -07:00
parent 63bdc70456
commit fa9aeaa4a9
4 changed files with 171 additions and 0 deletions

View File

@@ -39,6 +39,7 @@ MENU_LAYOUT: dict[str, list[str]] = {
"ColormapAdjust",
"CropResizeField",
"RotateField",
"FlipField",
],
"Filter": [
"GaussianFilter",

View File

@@ -20,6 +20,7 @@ from backend.nodes import (
colormap_adjust,
crop_resize_field,
rotate_field,
flip_field,
# Level
plane_level_field,
poly_level_field,

View File

@@ -0,0 +1,93 @@
from __future__ import annotations
from copy import deepcopy
import numpy as np
from backend.data_types import DataField
from backend.node_registry import register_node
@register_node(display_name="Flip")
class FlipField:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"field": ("DATA_FIELD",),
"axis": (["x", "y"], {"default": "x"}),
}
}
RETURN_TYPES = ("DATA_FIELD",)
RETURN_NAMES = ("field",)
FUNCTION = "process"
DESCRIPTION = (
"Reflect a DATA_FIELD across the X axis (top/bottom) or Y axis (left/right). "
"Physical extents are preserved, and stored markup overlays are mirrored with the data."
)
def process(self, field: DataField, axis: str) -> tuple:
axis_name = str(axis).strip().lower()
if axis_name == "x":
flipped = np.flipud(field.data).copy()
elif axis_name == "y":
flipped = np.fliplr(field.data).copy()
else:
raise ValueError(f"Unknown flip axis: {axis}")
return (
field.replace(
data=np.asarray(flipped, dtype=np.float64),
overlays=self._flip_overlays(field.overlays, axis_name),
),
)
@classmethod
def _flip_overlays(cls, overlays: list[dict] | None, axis: str) -> list[dict]:
if not isinstance(overlays, list):
return []
flipped_overlays = []
for overlay in overlays:
if not isinstance(overlay, dict):
continue
next_overlay = deepcopy(overlay)
if str(next_overlay.get("kind", "")).strip().lower() == "markup":
next_overlay["shapes"] = [
cls._flip_markup_shape(shape, axis)
for shape in next_overlay.get("shapes", [])
if isinstance(shape, dict)
]
flipped_overlays.append(next_overlay)
return flipped_overlays
@staticmethod
def _flip_markup_shape(shape: dict, axis: str) -> dict:
flipped = deepcopy(shape)
kind = str(flipped.get("kind", "")).strip().lower()
try:
x1 = float(flipped.get("x1"))
y1 = float(flipped.get("y1"))
x2 = float(flipped.get("x2"))
y2 = float(flipped.get("y2"))
except (TypeError, ValueError):
return flipped
if axis == "x":
y1, y2 = 1.0 - y1, 1.0 - y2
else:
x1, x2 = 1.0 - x1, 1.0 - x2
if kind in {"rectangle", "circle"}:
x1, x2 = sorted((x1, x2))
y1, y2 = sorted((y1, y2))
flipped["x1"] = float(np.clip(x1, 0.0, 1.0))
flipped["y1"] = float(np.clip(y1, 0.0, 1.0))
flipped["x2"] = float(np.clip(x2, 0.0, 1.0))
flipped["y2"] = float(np.clip(y2, 0.0, 1.0))
return flipped