node leaf sorting
This commit is contained in:
@@ -86,14 +86,13 @@ for category, class_names in MENU_LAYOUT.items():
|
||||
}
|
||||
|
||||
|
||||
def get_menu_metadata(class_name: str, fallback_category: str = "uncategorized") -> dict[str, Any]:
|
||||
def get_menu_metadata(class_name: str) -> dict[str, Any]:
|
||||
metadata = _NODE_METADATA.get(class_name)
|
||||
if metadata is not None:
|
||||
return dict(metadata)
|
||||
|
||||
fallback_order = _CATEGORY_ORDER.get(fallback_category, len(_CATEGORY_ORDER))
|
||||
return {
|
||||
"category": fallback_category,
|
||||
"category_order": fallback_order,
|
||||
"category": "Unsorted",
|
||||
"category_order": len(_CATEGORY_ORDER),
|
||||
"menu_order": 10_000,
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ def get_node_info(class_name: str) -> dict[str, Any]:
|
||||
"""
|
||||
cls = NODE_CLASS_MAPPINGS[class_name]
|
||||
input_types: dict = cls.INPUT_TYPES()
|
||||
menu_metadata = get_menu_metadata(class_name, getattr(cls, "CATEGORY", "uncategorized"))
|
||||
menu_metadata = get_menu_metadata(class_name)
|
||||
|
||||
return {
|
||||
"name": class_name,
|
||||
|
||||
@@ -33,7 +33,7 @@ class Statistics:
|
||||
RETURN_TYPES = ("MEASURE_TABLE",)
|
||||
RETURN_NAMES = ("stats",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Compute basic surface statistics: min, max, mean, RMS roughness, median, "
|
||||
"and skewness. Equivalent to gwy_data_field_get_min/max/avg/rms."
|
||||
@@ -82,7 +82,7 @@ class Histogram:
|
||||
RETURN_TYPES = ("MEASURE_TABLE", "COORDPAIR",)
|
||||
RETURN_NAMES = ("measurements", "marker pair",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Compute the height distribution histogram (DH). "
|
||||
"Use log scale to reveal small peaks next to a dominant background. "
|
||||
@@ -185,7 +185,7 @@ class Cursors:
|
||||
RETURN_TYPES = ("MEASURE_TABLE","COORDPAIR",)
|
||||
RETURN_NAMES = ("measurement","coord pair",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Place two cursors on a line plot or 2D field. "
|
||||
"On lines it reports x/y positions and dx/dy. "
|
||||
@@ -353,7 +353,7 @@ class FFT2D:
|
||||
RETURN_TYPES = ("DATA_FIELD", "DATA_FIELD", "DATA_FIELD", "DATA_FIELD")
|
||||
RETURN_NAMES = ("log_magnitude", "magnitude", "phase", "psdf")
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Compute the 2D FFT with optional windowing and mean/plane subtraction. "
|
||||
"Outputs log magnitude, magnitude, phase, and PSDF as separate channels. "
|
||||
@@ -511,7 +511,7 @@ class InverseFFT2D:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("image",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Reconstruct a spatial-domain image from a 2D frequency spectrum. "
|
||||
"For exact reconstruction, connect magnitude/phase (or log magnitude/phase, "
|
||||
@@ -658,7 +658,7 @@ class CrossSection:
|
||||
RETURN_TYPES = ("LINE", "COORDPAIR",)
|
||||
RETURN_NAMES = ("profile", "marker pair",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Extract a cross-section profile along a line between two points. "
|
||||
"Drag the markers on the image to set the line endpoints. "
|
||||
@@ -1010,7 +1010,7 @@ class Stats:
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("value",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "analysis"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Compute a contextual scalar statistic from a LINE, record table, DATA_FIELD, or IMAGE. "
|
||||
"The available operations adapt to the connected input type."
|
||||
|
||||
@@ -348,7 +348,7 @@ class ColorMap:
|
||||
RETURN_TYPES = ("COLORMAP",)
|
||||
RETURN_NAMES = ("colormap",)
|
||||
FUNCTION = "build"
|
||||
CATEGORY = "display"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Build a reusable colormap. Choose a preset, or create a custom gradient with min/max colours "
|
||||
"and any number of intermediate stops."
|
||||
@@ -389,7 +389,7 @@ class Font:
|
||||
RETURN_TYPES = ("FONT",)
|
||||
RETURN_NAMES = ("font",)
|
||||
FUNCTION = "build"
|
||||
CATEGORY = "display"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Build a reusable font spec for annotation overlays. Choose a discovered system font, "
|
||||
"use the default fallback stack, or point to a custom font file."
|
||||
@@ -429,7 +429,7 @@ class Annotations:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("annotated",)
|
||||
FUNCTION = "render"
|
||||
CATEGORY = "display"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Attach optional publication-style annotations to a DATA_FIELD without flattening the raw data. "
|
||||
"The preview shows a scale bar and/or side colour legend, while downstream field operations keep the underlying AFM values."
|
||||
@@ -488,7 +488,7 @@ class Markup:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("annotated",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "display"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Draw simple vector markup over a DATA_FIELD without flattening the underlying data. "
|
||||
"Choose a shape mode, colour, and stroke width, then drag directly on the preview to place lines, rectangles, circles, or arrows."
|
||||
@@ -549,7 +549,7 @@ class PreviewImage:
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "preview"
|
||||
CATEGORY = "display"
|
||||
|
||||
OUTPUT_NODE = True
|
||||
DESCRIPTION = "Display an IMAGE or DATA_FIELD as a coloured thumbnail. Connect either input."
|
||||
|
||||
@@ -614,7 +614,7 @@ class View3D:
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "render"
|
||||
CATEGORY = "display"
|
||||
|
||||
OUTPUT_NODE = True
|
||||
DESCRIPTION = (
|
||||
"Interactive 3D surface view of a DATA_FIELD. "
|
||||
@@ -691,7 +691,7 @@ class PrintTable:
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "print_table"
|
||||
CATEGORY = "display"
|
||||
|
||||
OUTPUT_NODE = True
|
||||
DESCRIPTION = "Send a measurement or record table to the browser as a WebSocket message for display."
|
||||
|
||||
@@ -724,7 +724,7 @@ class ValueDisplay:
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("value",)
|
||||
FUNCTION = "display_value"
|
||||
CATEGORY = "display"
|
||||
|
||||
DESCRIPTION = "Display a FLOAT, or a selected numeric row from a measurement table, and pass the value through unchanged."
|
||||
|
||||
_broadcast_value_fn = None
|
||||
|
||||
@@ -34,7 +34,7 @@ class GaussianFilter:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("filtered",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "filters"
|
||||
|
||||
DESCRIPTION = "Apply a Gaussian blur. Equivalent to gwy_data_field_filter_gaussian."
|
||||
|
||||
def process(self, field: DataField, sigma: float) -> tuple:
|
||||
@@ -61,7 +61,7 @@ class MedianFilter:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("filtered",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "filters"
|
||||
|
||||
DESCRIPTION = "Apply a median filter. Equivalent to gwy_data_field_filter_median."
|
||||
|
||||
def process(self, field: DataField, size: int) -> tuple:
|
||||
@@ -90,7 +90,7 @@ class EdgeDetect:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("edges",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "filters"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Detect edges using Sobel, Prewitt, Laplacian, or LoG operators. "
|
||||
"Equivalent to gwy_data_field_filter_sobel / gwy_data_field_filter_laplacian."
|
||||
@@ -229,7 +229,7 @@ class FFTFilter1D:
|
||||
RETURN_TYPES = ("LINE",)
|
||||
RETURN_NAMES = ("filtered",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "filters"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Frequency-domain filtering of a 1-D line profile. "
|
||||
"Supports lowpass, highpass, bandpass, and notch (band-reject) modes "
|
||||
@@ -295,7 +295,7 @@ class FFTFilter2D:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("filtered",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "filters"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Frequency-domain filtering of a 2-D data field. "
|
||||
"Supports lowpass, highpass, bandpass, and notch (band-reject) modes "
|
||||
|
||||
@@ -147,7 +147,7 @@ class Image:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("field",)
|
||||
FUNCTION = "load"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Load any supported file. "
|
||||
"SPM formats (.gwy, .sxm, .ibw) provide calibrated dimensions; "
|
||||
@@ -384,7 +384,7 @@ class ImageDemo:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("field",)
|
||||
FUNCTION = "load"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = "Load a bundled demo file so you can try the app without providing your own data."
|
||||
|
||||
def load(self, name: str = "", colormap: str = "viridis", colormap_map=None):
|
||||
@@ -408,7 +408,7 @@ class Folder:
|
||||
RETURN_TYPES = ("DIRECTORY",)
|
||||
RETURN_NAMES = ("directory",)
|
||||
FUNCTION = "list_files"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Pick a folder and output its directory path plus one file socket per compatible image, array, or SPM file inside it. "
|
||||
"Supported files include common images, .npy/.npz arrays, and .gwy/.sxm/.ibw scans."
|
||||
@@ -441,7 +441,7 @@ class Coordinate:
|
||||
RETURN_TYPES = ("COORD",)
|
||||
RETURN_NAMES = ("point",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = "Output a fractional (x, y) coordinate pair in [0, 1]."
|
||||
|
||||
def process(self, x: float, y: float) -> tuple:
|
||||
@@ -464,7 +464,7 @@ class CoordinatePair:
|
||||
RETURN_TYPES = ("COORDPAIR",)
|
||||
RETURN_NAMES = ("coord pair",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = "Output a pair of coordinates."
|
||||
|
||||
def process(self, a: tuple, b: tuple) -> tuple:
|
||||
@@ -490,7 +490,7 @@ class Number:
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("value",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Output a fixed numeric value. "
|
||||
"When connected to FLOAT inputs the exact value is used; "
|
||||
@@ -528,7 +528,7 @@ class RangeSlider:
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("value",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "io"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Interactive float slider. Set min and max bounds, then drag the slider to output a FLOAT value."
|
||||
)
|
||||
@@ -584,7 +584,7 @@ class SaveImage:
|
||||
|
||||
RETURN_TYPES = ()
|
||||
FUNCTION = "save"
|
||||
CATEGORY = "io"
|
||||
|
||||
OUTPUT_NODE = True
|
||||
MANUAL_TRIGGER = True
|
||||
DESCRIPTION = (
|
||||
|
||||
@@ -33,7 +33,7 @@ class PlaneLevelField:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("leveled",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "level"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Fit and subtract a least-squares plane from the data. "
|
||||
"Equivalent to gwy_data_field_fit_plane + gwy_data_field_plane_level."
|
||||
@@ -83,7 +83,7 @@ class PolyLevelField:
|
||||
RETURN_TYPES = ("DATA_FIELD", "DATA_FIELD")
|
||||
RETURN_NAMES = ("leveled", "background")
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "level"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Fit and subtract a polynomial background of given degree in x and y. "
|
||||
"Equivalent to gwy_data_field_fit_polynom."
|
||||
@@ -131,7 +131,7 @@ class FixZero:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("zeroed",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "level"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Shift data so that the minimum (or mean/median) is zero. "
|
||||
"Equivalent to fix_zero in Gwyddion's level.c."
|
||||
|
||||
@@ -173,7 +173,7 @@ class DrawMask:
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("mask",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "mask"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Paint a binary mask directly over an image preview. "
|
||||
"Pen size controls newly drawn strokes, the overlay lets you clear the mask, "
|
||||
@@ -227,7 +227,7 @@ class ThresholdMask:
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("mask",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "mask"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Create a binary mask by thresholding data. "
|
||||
"Otsu automatically finds the optimal threshold. "
|
||||
@@ -295,7 +295,7 @@ class MaskMorphology:
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("mask",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "mask"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Apply morphological operations to a binary mask. "
|
||||
"Dilate expands regions, erode shrinks them, "
|
||||
@@ -358,7 +358,7 @@ class MaskInvert:
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("mask",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "mask"
|
||||
|
||||
DESCRIPTION = "Invert a binary mask — swap masked and unmasked regions."
|
||||
|
||||
_broadcast_fn = None
|
||||
@@ -400,7 +400,7 @@ class MaskCombine:
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
RETURN_NAMES = ("mask",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "mask"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Combine two binary masks with a boolean operation. "
|
||||
"AND keeps overlap, OR merges, XOR keeps non-overlapping regions, "
|
||||
|
||||
@@ -30,7 +30,7 @@ class ColormapAdjust:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("field",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "modify"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Adjust how a DATA_FIELD maps into its colormap without changing the underlying data. "
|
||||
"offset and scale operate in normalized display coordinates; Auto resets to the full data range."
|
||||
@@ -71,7 +71,7 @@ class CropResizeField:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("field",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "modify"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Crop a DATA_FIELD with a draggable rectangle defined by two corners, then optionally resize it. "
|
||||
"Incoming COORD inputs can lock either corner. Cropping updates physical extents and offsets; "
|
||||
@@ -212,7 +212,7 @@ class RotateField:
|
||||
RETURN_TYPES = ("DATA_FIELD",)
|
||||
RETURN_NAMES = ("field",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "modify"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Rotate a DATA_FIELD counterclockwise by an angle in degrees. "
|
||||
"Optionally expand the canvas to keep the full rotated field while preserving the field center."
|
||||
|
||||
@@ -30,7 +30,7 @@ class ParticleAnalysis:
|
||||
RETURN_TYPES = ("RECORD_TABLE",)
|
||||
RETURN_NAMES = ("particle_stats",)
|
||||
FUNCTION = "process"
|
||||
CATEGORY = "particles"
|
||||
|
||||
DESCRIPTION = (
|
||||
"Label connected particle regions in a binary mask and compute per-particle "
|
||||
"statistics: area, equivalent diameter, mean/max height, bounding box. "
|
||||
|
||||
Reference in New Issue
Block a user