feat: add Type Conversion and Number Utility nodes (v1.4.0)
New Type Conversion nodes (DebugPadawan/Conversion): - Type Converter: Universal type conversion (string, int, float, boolean) - Int to Float: Convert integers to floats - Float to Int: Convert floats to ints with rounding modes - String to Int: Parse strings as integers - String to Float: Parse strings as floats - String to Boolean: Parse strings as booleans - Number to String: Format numbers as strings with precision control New Number Utility nodes (DebugPadawan/Number): - Number Clamp: Clamp values between min and max - Number Round: Round with decimal precision control - Number Range: Generate number sequences - Number Compare: Compare two numbers - Number Absolute: Get absolute value - Number Sign: Get sign (-1, 0, 1) of a number - Number Remap: Remap values between ranges - Number Lerp: Linear interpolation between values Updated version to 1.4.0 and added documentation for all new nodes.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
[](https://python.org)
|
||||
[](https://github.com/comfyanonymous/ComfyUI)
|
||||
[](LICENSE)
|
||||
[](https://github.com/DebugPadawan/DebugPadawans-ComfyUI-Essentials/releases)
|
||||
[](https://github.com/DebugPadawan/DebugPadawans-ComfyUI-Essentials/releases)
|
||||
[](https://github.com/DebugPadawan/DebugPadawans-ComfyUI-Essentials/stargazers)
|
||||
|
||||
</div>
|
||||
@@ -553,6 +553,375 @@ Get the first N images of a batch, skip the first item, or take a specific range
|
||||
|
||||
---
|
||||
|
||||
### 🔄 Type Conversion
|
||||
|
||||
<details>
|
||||
<summary><b>🔀 Type Converter</b> - Universal type conversion</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts between different data types: string, int, float, and boolean.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Any)*: The value to convert
|
||||
- `output_type` *(List)*: Target type - string, int, float, boolean
|
||||
|
||||
**📤 Outputs:**
|
||||
- `converted` *(Any)*: The converted value
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 42 (int)
|
||||
Type: "string"
|
||||
Output: "42"
|
||||
|
||||
Input: "3.14" (string)
|
||||
Type: "float"
|
||||
Output: 3.14
|
||||
```
|
||||
|
||||
Convert any value to any type, workflow data type compatibility, normalize inputs for nodes that require specific types.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔢 Int to Float</b> - Convert integer to float</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts an integer to a floating-point number.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Integer)*: The integer to convert
|
||||
|
||||
**📤 Outputs:**
|
||||
- `float_value` *(Float)*: The converted float
|
||||
|
||||
Useful for nodes that only accept float inputs.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>📐 Float to Int</b> - Convert float to integer</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts a float to an integer with rounding mode control.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The float to convert
|
||||
- `mode` *(List)*: Rounding mode - round, floor, ceil
|
||||
|
||||
**📤 Outputs:**
|
||||
- `int_value` *(Integer)*: The converted integer
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 3.7
|
||||
Mode: "floor"
|
||||
Output: 3
|
||||
|
||||
Input: 3.2
|
||||
Mode: "ceil"
|
||||
Output: 4
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔤 String to Int</b> - Parse string as integer</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts a string to an integer.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(String)*: The string to parse
|
||||
|
||||
**📤 Outputs:**
|
||||
- `int_value` *(Integer)*: The parsed integer
|
||||
|
||||
Handles strings like "42" or "3.14" (converts via float first).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔤 String to Float</b> - Parse string as float</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts a string to a floating-point number.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(String)*: The string to parse
|
||||
|
||||
**📤 Outputs:**
|
||||
- `float_value` *(Float)*: The parsed float
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: "3.14159"
|
||||
Output: 3.14159
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔤 String to Boolean</b> - Parse string as boolean</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts a string to a boolean value.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(String)*: The string to parse
|
||||
|
||||
**📤 Outputs:**
|
||||
- `bool_value` *(Boolean)*: The parsed boolean
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: "true" → Output: True
|
||||
Input: "yes" → Output: True
|
||||
Input: "false" → Output: False
|
||||
Input: "0" → Output: False
|
||||
```
|
||||
|
||||
Recognizes: true/false, yes/no, 1/0, on/off (case insensitive).
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔢 Number to String</b> - Format number as string</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Conversion`
|
||||
|
||||
Converts a number to a string with decimal precision control.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The number to convert
|
||||
- `decimal_places` *(Integer)*: Number of decimal places (0-10)
|
||||
|
||||
**📤 Outputs:**
|
||||
- `string_value` *(String)*: The formatted string
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 3.14159
|
||||
Decimal Places: 2
|
||||
Output: "3.14"
|
||||
|
||||
Input: 3.14159
|
||||
Decimal Places: 0
|
||||
Output: "3"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
### 🔢 Number Utilities
|
||||
|
||||
<details>
|
||||
<summary><b>📏 Number Clamp</b> - Clamp value between min and max</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Clamps a number to stay within a specified range.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The value to clamp
|
||||
- `min_val` *(Float)*: Minimum allowed value (default: 0.0)
|
||||
- `max_val` *(Float)*: Maximum allowed value (default: 1.0)
|
||||
|
||||
**📤 Outputs:**
|
||||
- `clamped` *(Float)*: The clamped value
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 1.5, min: 0.0, max: 1.0
|
||||
Output: 1.0
|
||||
|
||||
Input: -0.5, min: 0.0, max: 1.0
|
||||
Output: 0.0
|
||||
```
|
||||
|
||||
Useful for ensuring values stay within valid ranges, like RGB values or percentages.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔢 Number Round</b> - Round with precision control</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Rounds a number to a specified number of decimal places.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The value to round
|
||||
- `decimal_places` *(Integer)*: Number of decimal places (0-10)
|
||||
|
||||
**📤 Outputs:**
|
||||
- `rounded` *(Float)*: The rounded value
|
||||
- `rounded_string` *(String)*: The rounded value as a formatted string
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 3.14159
|
||||
Decimal Places: 2
|
||||
Output: 3.14, "3.14"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>📊 Number Range</b> - Generate number sequence</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Generates a list of numbers from start to end with a step.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `start` *(Integer)*: Starting value
|
||||
- `end` *(Integer)*: Ending value (exclusive)
|
||||
- `step` *(Integer)*: Step increment
|
||||
|
||||
**📤 Outputs:**
|
||||
- `range_list` *(List)*: List of integers
|
||||
- `count` *(Integer)*: Number of items
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Start: 0, End: 10, Step: 2
|
||||
Output: [0, 2, 4, 6, 8], 5
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>⚖️ Number Compare</b> - Compare two numbers</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Compares two numbers and returns a boolean result.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `a` *(Float)*: First value
|
||||
- `b` *(Float)*: Second value
|
||||
- `comparison` *(List)*: Comparison type - equal, not equal, greater, less, greater or equal, less or equal
|
||||
|
||||
**📤 Outputs:**
|
||||
- `result` *(Boolean)*: Comparison result
|
||||
- `result_text` *(String)*: Result as text ("True"/"False")
|
||||
|
||||
Useful for conditional workflow branching based on numeric values.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>📏 Number Absolute</b> - Get absolute value</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Returns the absolute (positive) value of a number.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The value
|
||||
|
||||
**📤 Outputs:**
|
||||
- `absolute` *(Float)*: The absolute value
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: -5.3
|
||||
Output: 5.3
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>➖ Number Sign</b> - Get sign of a number</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Returns the sign of a number (-1, 0, or 1).
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The value
|
||||
|
||||
**📤 Outputs:**
|
||||
- `sign` *(Integer)*: -1 (negative), 0 (zero), or 1 (positive)
|
||||
- `sign_text` *(String)*: "negative", "zero", or "positive"
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 42 → Output: 1, "positive"
|
||||
Input: -3.5 → Output: -1, "negative"
|
||||
Input: 0 → Output: 0, "zero"
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>🔄 Number Remap</b> - Remap value between ranges</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Remaps a value from one range to another (linear interpolation).
|
||||
|
||||
**📥 Inputs:**
|
||||
- `value` *(Float)*: The value to remap
|
||||
- `from_min` *(Float)*: Source range minimum
|
||||
- `from_max` *(Float)*: Source range maximum
|
||||
- `to_min` *(Float)*: Target range minimum
|
||||
- `to_max` *(Float)*: Target range maximum
|
||||
|
||||
**📤 Outputs:**
|
||||
- `remapped` *(Float)*: The remapped value
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
Input: 0.5, from: [0, 1], to: [0, 100]
|
||||
Output: 50.0
|
||||
|
||||
Input: 25, from: [0, 100], to: [0, 1]
|
||||
Output: 0.25
|
||||
```
|
||||
|
||||
Perfect for normalizing values or converting between different scales.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>📊 Number Lerp</b> - Linear interpolation</summary>
|
||||
|
||||
**Category:** `DebugPadawan/Number`
|
||||
|
||||
Performs linear interpolation between two values.
|
||||
|
||||
**📥 Inputs:**
|
||||
- `a` *(Float)*: Start value
|
||||
- `b` *(Float)*: End value
|
||||
- `t` *(Float)*: Interpolation factor (0.0 to 1.0)
|
||||
|
||||
**📤 Outputs:**
|
||||
- `lerped` *(Float)*: The interpolated value
|
||||
|
||||
**💡 Example:**
|
||||
```
|
||||
a: 0, b: 100, t: 0.5
|
||||
Output: 50.0
|
||||
|
||||
a: 10, b: 20, t: 0.25
|
||||
Output: 12.5
|
||||
```
|
||||
|
||||
Useful for smooth transitions and blending values.
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
### 🔧 Utility Nodes
|
||||
|
||||
<details>
|
||||
@@ -652,6 +1021,8 @@ Data → Wait (2.0s) → Processing → Wait (1.0s) → Output
|
||||
| **DebugPadawan/Image** | Image Info, Color Palette Extractor | Image tensor analysis and color extraction |
|
||||
| **DebugPadawan/Math** | Int/Float Math Operation, Random Generator | Basic arithmetic and random number generation |
|
||||
| **DebugPadawan/List** | Get List Item, List Slicer | List manipulation |
|
||||
| **DebugPadawan/Conversion** | Type Converter, Int to Float, Float to Int, String to Int, String to Float, String to Boolean, Number to String | Type conversion utilities |
|
||||
| **DebugPadawan/Number** | Number Clamp, Number Round, Number Range, Number Compare, Number Absolute, Number Sign, Number Remap, Number Lerp | Number formatting and utilities |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+9
-1
@@ -26,6 +26,10 @@ from .nodes.string_formatter import NODE_CLASS_MAPPINGS as STRING_FORMATTER_NODE
|
||||
from .nodes.string_formatter import NODE_DISPLAY_NAME_MAPPINGS as STRING_FORMATTER_DISPLAY_NAMES
|
||||
from .nodes.text_compare import NODE_CLASS_MAPPINGS as TEXT_COMPARE_NODES
|
||||
from .nodes.text_compare import NODE_DISPLAY_NAME_MAPPINGS as TEXT_COMPARE_DISPLAY_NAMES
|
||||
from .nodes.type_conversion import NODE_CLASS_MAPPINGS as TYPE_CONVERSION_NODES
|
||||
from .nodes.type_conversion import NODE_DISPLAY_NAME_MAPPINGS as TYPE_CONVERSION_DISPLAY_NAMES
|
||||
from .nodes.number_utils import NODE_CLASS_MAPPINGS as NUMBER_UTILS_NODES
|
||||
from .nodes.number_utils import NODE_DISPLAY_NAME_MAPPINGS as NUMBER_UTILS_DISPLAY_NAMES
|
||||
|
||||
# Combine all node mappings
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
@@ -40,6 +44,8 @@ NODE_CLASS_MAPPINGS = {
|
||||
**JSON_TO_TEXT_NODES,
|
||||
**STRING_FORMATTER_NODES,
|
||||
**TEXT_COMPARE_NODES,
|
||||
**TYPE_CONVERSION_NODES,
|
||||
**NUMBER_UTILS_NODES,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
@@ -54,10 +60,12 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
**JSON_TO_TEXT_DISPLAY_NAMES,
|
||||
**STRING_FORMATTER_DISPLAY_NAMES,
|
||||
**TEXT_COMPARE_DISPLAY_NAMES,
|
||||
**TYPE_CONVERSION_DISPLAY_NAMES,
|
||||
**NUMBER_UTILS_DISPLAY_NAMES,
|
||||
}
|
||||
|
||||
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
||||
|
||||
# Version info
|
||||
__version__ = "1.3.0"
|
||||
__version__ = "1.4.0"
|
||||
__author__ = "DebugPadawan"
|
||||
@@ -0,0 +1,266 @@
|
||||
"""
|
||||
Number Utility Nodes for ComfyUI
|
||||
Provides number formatting, clamping, and mathematical helpers
|
||||
"""
|
||||
import math
|
||||
|
||||
|
||||
class NumberClamp:
|
||||
"""
|
||||
Node for clamping a number between min and max values
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.0}),
|
||||
"min_val": ("FLOAT", {"default": 0.0}),
|
||||
"max_val": ("FLOAT", {"default": 1.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("clamped",)
|
||||
|
||||
FUNCTION = "clamp"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def clamp(self, value, min_val, max_val):
|
||||
result = max(min_val, min(value, max_val))
|
||||
return (result,)
|
||||
|
||||
|
||||
class NumberRound:
|
||||
"""
|
||||
Node for rounding numbers with precision control
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.0}),
|
||||
"decimal_places": ("INT", {"default": 2, "min": 0, "max": 10}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT", "STRING")
|
||||
RETURN_NAMES = ("rounded", "rounded_string")
|
||||
|
||||
FUNCTION = "round_num"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def round_num(self, value, decimal_places):
|
||||
rounded = round(value, decimal_places)
|
||||
formatted = f"{rounded:.{decimal_places}f}"
|
||||
return (rounded, formatted)
|
||||
|
||||
|
||||
class NumberRange:
|
||||
"""
|
||||
Node for generating a range of numbers (like Python's range)
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"start": ("INT", {"default": 0}),
|
||||
"end": ("INT", {"default": 10}),
|
||||
"step": ("INT", {"default": 1}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("LIST", "INT")
|
||||
RETURN_NAMES = ("range_list", "count")
|
||||
|
||||
FUNCTION = "generate_range"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def generate_range(self, start, end, step):
|
||||
if step == 0:
|
||||
raise ValueError("Step cannot be zero")
|
||||
|
||||
if step > 0:
|
||||
result = list(range(start, end, step))
|
||||
else:
|
||||
result = list(range(start, end, step))
|
||||
|
||||
return (result, len(result))
|
||||
|
||||
|
||||
class NumberCompare:
|
||||
"""
|
||||
Node for comparing two numbers
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"a": ("FLOAT", {"default": 0.0}),
|
||||
"b": ("FLOAT", {"default": 0.0}),
|
||||
"comparison": (["equal", "not equal", "greater", "less", "greater or equal", "less or equal"],),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN", "STRING")
|
||||
RETURN_NAMES = ("result", "result_text")
|
||||
|
||||
FUNCTION = "compare"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def compare(self, a, b, comparison):
|
||||
import math
|
||||
|
||||
if comparison == "equal":
|
||||
result = abs(a - b) < 1e-9 # Float comparison with tolerance
|
||||
elif comparison == "not equal":
|
||||
result = abs(a - b) >= 1e-9
|
||||
elif comparison == "greater":
|
||||
result = a > b
|
||||
elif comparison == "less":
|
||||
result = a < b
|
||||
elif comparison == "greater or equal":
|
||||
result = a >= b
|
||||
elif comparison == "less or equal":
|
||||
result = a <= b
|
||||
else:
|
||||
result = False
|
||||
|
||||
return (result, str(result))
|
||||
|
||||
|
||||
class NumberAbs:
|
||||
"""
|
||||
Node for getting the absolute value of a number
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("absolute",)
|
||||
|
||||
FUNCTION = "abs_value"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def abs_value(self, value):
|
||||
return (abs(value),)
|
||||
|
||||
|
||||
class NumberSign:
|
||||
"""
|
||||
Node for getting the sign of a number (-1, 0, or 1)
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT", "STRING")
|
||||
RETURN_NAMES = ("sign", "sign_text")
|
||||
|
||||
FUNCTION = "get_sign"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def get_sign(self, value):
|
||||
if value > 0:
|
||||
return (1, "positive")
|
||||
elif value < 0:
|
||||
return (-1, "negative")
|
||||
else:
|
||||
return (0, "zero")
|
||||
|
||||
|
||||
class NumberRemap:
|
||||
"""
|
||||
Node for remapping a value from one range to another
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.5}),
|
||||
"from_min": ("FLOAT", {"default": 0.0}),
|
||||
"from_max": ("FLOAT", {"default": 1.0}),
|
||||
"to_min": ("FLOAT", {"default": 0.0}),
|
||||
"to_max": ("FLOAT", {"default": 100.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("remapped",)
|
||||
|
||||
FUNCTION = "remap"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def remap(self, value, from_min, from_max, to_min, to_max):
|
||||
if from_max == from_min:
|
||||
raise ValueError("from_min and from_max cannot be equal")
|
||||
|
||||
# Normalize value to 0-1 range
|
||||
normalized = (value - from_min) / (from_max - from_min)
|
||||
# Remap to target range
|
||||
result = to_min + normalized * (to_max - to_min)
|
||||
return (result,)
|
||||
|
||||
|
||||
class NumberLerp:
|
||||
"""
|
||||
Node for linear interpolation between two values
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"a": ("FLOAT", {"default": 0.0}),
|
||||
"b": ("FLOAT", {"default": 1.0}),
|
||||
"t": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("lerped",)
|
||||
|
||||
FUNCTION = "lerp"
|
||||
CATEGORY = "DebugPadawan/Number"
|
||||
|
||||
def lerp(self, a, b, t):
|
||||
result = a + t * (b - a)
|
||||
return (result,)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"DebugPadawan_NumberClamp": NumberClamp,
|
||||
"DebugPadawan_NumberRound": NumberRound,
|
||||
"DebugPadawan_NumberRange": NumberRange,
|
||||
"DebugPadawan_NumberCompare": NumberCompare,
|
||||
"DebugPadawan_NumberAbs": NumberAbs,
|
||||
"DebugPadawan_NumberSign": NumberSign,
|
||||
"DebugPadawan_NumberRemap": NumberRemap,
|
||||
"DebugPadawan_NumberLerp": NumberLerp,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"DebugPadawan_NumberClamp": "Number Clamp",
|
||||
"DebugPadawan_NumberRound": "Number Round",
|
||||
"DebugPadawan_NumberRange": "Number Range",
|
||||
"DebugPadawan_NumberCompare": "Number Compare",
|
||||
"DebugPadawan_NumberAbs": "Number Absolute",
|
||||
"DebugPadawan_NumberSign": "Number Sign",
|
||||
"DebugPadawan_NumberRemap": "Number Remap",
|
||||
"DebugPadawan_NumberLerp": "Number Lerp",
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
"""
|
||||
Type Conversion Nodes for ComfyUI
|
||||
Converts between different data types: int, float, string, boolean
|
||||
"""
|
||||
|
||||
|
||||
class TypeConverter:
|
||||
"""
|
||||
Node for converting between different data types
|
||||
Supports: int, float, string, boolean conversions
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("*", {"forceInput": True}),
|
||||
"output_type": (["string", "int", "float", "boolean"],),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("*",)
|
||||
RETURN_NAMES = ("converted",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value, output_type):
|
||||
"""
|
||||
Convert value to the specified output type
|
||||
|
||||
Args:
|
||||
value: Input value of any type
|
||||
output_type: Target type (string, int, float, boolean)
|
||||
|
||||
Returns:
|
||||
Converted value
|
||||
"""
|
||||
try:
|
||||
if output_type == "string":
|
||||
return (str(value),)
|
||||
|
||||
elif output_type == "int":
|
||||
# Handle boolean conversion
|
||||
if isinstance(value, bool):
|
||||
return (int(value),)
|
||||
# Handle string conversion
|
||||
if isinstance(value, str):
|
||||
# Try to parse as float first (handles "3.14" -> 3)
|
||||
try:
|
||||
return (int(float(value)),)
|
||||
except ValueError:
|
||||
raise ValueError(f"Cannot convert '{value}' to int")
|
||||
# Handle float
|
||||
return (int(value),)
|
||||
|
||||
elif output_type == "float":
|
||||
# Handle boolean conversion
|
||||
if isinstance(value, bool):
|
||||
return (float(value),)
|
||||
# Handle string conversion
|
||||
if isinstance(value, str):
|
||||
try:
|
||||
return (float(value),)
|
||||
except ValueError:
|
||||
raise ValueError(f"Cannot convert '{value}' to float")
|
||||
# Handle int or float
|
||||
return (float(value),)
|
||||
|
||||
elif output_type == "boolean":
|
||||
# String to boolean
|
||||
if isinstance(value, str):
|
||||
lower_val = value.strip().lower()
|
||||
if lower_val in ("true", "yes", "1", "on"):
|
||||
return (True,)
|
||||
elif lower_val in ("false", "no", "0", "off", ""):
|
||||
return (False,)
|
||||
else:
|
||||
# Non-empty string that's not a known false value
|
||||
return (True,)
|
||||
# Numeric to boolean
|
||||
if isinstance(value, (int, float)):
|
||||
return (bool(value),)
|
||||
# Default bool conversion
|
||||
return (bool(value),)
|
||||
|
||||
else:
|
||||
return (value,)
|
||||
|
||||
except Exception as e:
|
||||
raise ValueError(f"Type conversion error: {str(e)}")
|
||||
|
||||
|
||||
class IntToFloat:
|
||||
"""
|
||||
Dedicated node for converting int to float
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("INT", {"default": 0}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("float_value",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value):
|
||||
return (float(value),)
|
||||
|
||||
|
||||
class FloatToInt:
|
||||
"""
|
||||
Dedicated node for converting float to int
|
||||
Supports different rounding modes
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.0}),
|
||||
"mode": (["round", "floor", "ceil"],),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("int_value",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value, mode):
|
||||
import math
|
||||
if mode == "round":
|
||||
return (round(value),)
|
||||
elif mode == "floor":
|
||||
return (math.floor(value),)
|
||||
elif mode == "ceil":
|
||||
return (math.ceil(value),)
|
||||
return (int(value),)
|
||||
|
||||
|
||||
class StringToInt:
|
||||
"""
|
||||
Dedicated node for converting string to int
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("STRING", {"multiline": False, "default": "0"}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("INT",)
|
||||
RETURN_NAMES = ("int_value",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value):
|
||||
try:
|
||||
# Handle float strings by converting to float first
|
||||
return (int(float(value)),)
|
||||
except ValueError:
|
||||
raise ValueError(f"Cannot convert '{value}' to int")
|
||||
|
||||
|
||||
class StringToFloat:
|
||||
"""
|
||||
Dedicated node for converting string to float
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("STRING", {"multiline": False, "default": "0.0"}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("FLOAT",)
|
||||
RETURN_NAMES = ("float_value",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value):
|
||||
try:
|
||||
return (float(value),)
|
||||
except ValueError:
|
||||
raise ValueError(f"Cannot convert '{value}' to float")
|
||||
|
||||
|
||||
class StringToBoolean:
|
||||
"""
|
||||
Dedicated node for converting string to boolean
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("STRING", {"multiline": False, "default": "false"}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("BOOLEAN",)
|
||||
RETURN_NAMES = ("bool_value",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value):
|
||||
lower_val = value.strip().lower()
|
||||
if lower_val in ("true", "yes", "1", "on"):
|
||||
return (True,)
|
||||
elif lower_val in ("false", "no", "0", "off", ""):
|
||||
return (False,)
|
||||
else:
|
||||
# Non-empty string that's not a recognized false value is True
|
||||
return (True,)
|
||||
|
||||
|
||||
class NumberToString:
|
||||
"""
|
||||
Dedicated node for converting numbers (int/float) to string
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"value": ("FLOAT", {"default": 0.0}),
|
||||
"decimal_places": ("INT", {"default": 2, "min": 0, "max": 10}),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("string_value",)
|
||||
|
||||
FUNCTION = "convert"
|
||||
CATEGORY = "DebugPadawan/Conversion"
|
||||
|
||||
def convert(self, value, decimal_places):
|
||||
if decimal_places == 0:
|
||||
return (str(int(round(value))),)
|
||||
else:
|
||||
return (f"{value:.{decimal_places}f}",)
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"DebugPadawan_TypeConverter": TypeConverter,
|
||||
"DebugPadawan_IntToFloat": IntToFloat,
|
||||
"DebugPadawan_FloatToInt": FloatToInt,
|
||||
"DebugPadawan_StringToInt": StringToInt,
|
||||
"DebugPadawan_StringToFloat": StringToFloat,
|
||||
"DebugPadawan_StringToBoolean": StringToBoolean,
|
||||
"DebugPadawan_NumberToString": NumberToString,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"DebugPadawan_TypeConverter": "Type Converter",
|
||||
"DebugPadawan_IntToFloat": "Int to Float",
|
||||
"DebugPadawan_FloatToInt": "Float to Int",
|
||||
"DebugPadawan_StringToInt": "String to Int",
|
||||
"DebugPadawan_StringToFloat": "String to Float",
|
||||
"DebugPadawan_StringToBoolean": "String to Boolean",
|
||||
"DebugPadawan_NumberToString": "Number to String",
|
||||
}
|
||||
Reference in New Issue
Block a user