refactor sockets
This commit is contained in:
parent
29f7b71be1
commit
2bfc1ef781
14 changed files with 213 additions and 191 deletions
|
|
@ -34,16 +34,29 @@ class SliceIntrinsics:
|
||||||
|
|
||||||
class InputNode(SliceNode):
|
class InputNode(SliceNode):
|
||||||
input_type: str = ""
|
input_type: str = ""
|
||||||
|
socket_type: str = ""
|
||||||
|
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
if "bl_label" not in cls.__dict__: cls.bl_label = cls.input_type
|
if "bl_label" not in cls.__dict__: cls.bl_label = cls.input_type
|
||||||
|
|
||||||
def init(self, context) -> None:
|
def init(self, context) -> None:
|
||||||
self.add_output(f"SLICESOCK_{self.bl_label}")
|
stype = self.socket_type or (f"NodeSocket{self.bl_label}" if not self.bl_label.startswith("NodeSocket") else self.bl_label)
|
||||||
|
self.add_output(stype)
|
||||||
|
|
||||||
|
def draw_buttons(self, context, layout):
|
||||||
|
assert layout
|
||||||
|
if self.outputs:
|
||||||
|
sock = self.outputs[0]
|
||||||
|
if hasattr(sock, "default_value"):
|
||||||
|
layout.prop(sock, "default_value", text="")
|
||||||
|
elif hasattr(sock, "value"):
|
||||||
|
layout.prop(sock, "value", text="")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs):
|
def evaluate_output(self, socket_name: str, **_kwargs):
|
||||||
return self.outputs.get(socket_name).value
|
out = self.outputs.get(socket_name) or (self.outputs[0] if self.outputs else None)
|
||||||
|
if out is None: return None
|
||||||
|
return getattr(out, "value", getattr(out, "default_value", None))
|
||||||
|
|
||||||
class MathNode(SliceNode):
|
class MathNode(SliceNode):
|
||||||
bl_label = "Float Math"
|
bl_label = "Float Math"
|
||||||
|
|
@ -72,12 +85,13 @@ class MathNode(SliceNode):
|
||||||
|
|
||||||
math_type: TypeAlias = float
|
math_type: TypeAlias = float
|
||||||
socket_label: str = "Float"
|
socket_label: str = "Float"
|
||||||
|
socket_type: str = "NodeSocketFloat"
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_output(f"SLICESOCK_{self.socket_label}Ro", "Value")
|
self.add_output(self.socket_type, "Value")
|
||||||
|
|
||||||
self.add_input(f"SLICESOCK_{self.socket_label}", "Value")
|
self.add_input(self.socket_type, "Value")
|
||||||
self.add_input(f"SLICESOCK_{self.socket_label}", "Value")
|
self.add_input(self.socket_type, "Value")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
assert layout
|
assert layout
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,9 @@ class SLICENODE_AssignMetadata(SliceNode):
|
||||||
bl_label = "Assign Metadata"
|
bl_label = "Assign Metadata"
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_String", "Name")
|
self.add_input("NodeSocketString", "Name")
|
||||||
self.add_input("SLICESOCK_String", "Filament Type")
|
self.add_input("NodeSocketString", "Filament Type")
|
||||||
self.add_input("SLICESOCK_String", "Printer Model")
|
self.add_input("NodeSocketString", "Printer Model")
|
||||||
self.add_output("SLICESOCK_GcodeRo", "Gcode")
|
self.add_output("SLICESOCK_GcodeRo", "Gcode")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> str:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> str:
|
||||||
|
|
@ -87,8 +87,8 @@ class SLICENODE_GcodeRegexReplace(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Gcode", "Gcode")
|
self.add_input("SLICESOCK_Gcode", "Gcode")
|
||||||
self.add_input("SLICESOCK_String", "Find")
|
self.add_input("NodeSocketString", "Find")
|
||||||
self.add_input("SLICESOCK_String", "Replace")
|
self.add_input("NodeSocketString", "Replace")
|
||||||
self.add_output("SLICESOCK_GcodeRo", "Gcode")
|
self.add_output("SLICESOCK_GcodeRo", "Gcode")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> str:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> str:
|
||||||
|
|
|
||||||
|
|
@ -10,27 +10,33 @@ from .base import InputNode, SliceNode, SliceIntrinsics
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputString(InputNode):
|
class SLICENODE_InputString(InputNode):
|
||||||
input_type = "String"
|
bl_label = "String"
|
||||||
|
socket_type = "NodeSocketString"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputFloat(InputNode):
|
class SLICENODE_InputFloat(InputNode):
|
||||||
input_type = "Float"
|
bl_label = "Float"
|
||||||
|
socket_type = "NodeSocketFloat"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputInt(InputNode):
|
class SLICENODE_InputInt(InputNode):
|
||||||
input_type = "Int"
|
bl_label = "Integer"
|
||||||
|
socket_type = "NodeSocketInt"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputVectorRotation(InputNode):
|
class SLICENODE_InputVectorRotation(InputNode):
|
||||||
input_type = "VectorRotation"
|
bl_label = "Vector Rotation"
|
||||||
|
socket_type = "NodeSocketRotation"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputVector(InputNode):
|
class SLICENODE_InputVector(InputNode):
|
||||||
input_type = "Vector"
|
bl_label = "Vector"
|
||||||
|
socket_type = "NodeSocketVector"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputObject(InputNode):
|
class SLICENODE_InputObject(InputNode):
|
||||||
input_type = "Object"
|
bl_label = "Object"
|
||||||
|
socket_type = "NodeSocketObject"
|
||||||
bl_icon = "OBJECT_DATA"
|
bl_icon = "OBJECT_DATA"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
|
|
@ -70,7 +76,7 @@ class SLICENODE_CollectionObjects(SliceNode):
|
||||||
# Add new outputs
|
# Add new outputs
|
||||||
for name in expected_names:
|
for name in expected_names:
|
||||||
if name not in self.outputs:
|
if name not in self.outputs:
|
||||||
self.add_output("SLICESOCK_ObjectRo", name, identifier=name)
|
self.add_output("NodeSocketObject", name, identifier=name)
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **kwargs) -> Any:
|
||||||
if self.collection and socket_name in bpy.data.objects:
|
if self.collection and socket_name in bpy.data.objects:
|
||||||
|
|
@ -82,8 +88,8 @@ class SLICENODE_WipeTower(SliceNode):
|
||||||
bl_label = "Wipe Tower"
|
bl_label = "Wipe Tower"
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Float", "X Position").value = 170.0
|
self.add_input("NodeSocketFloat", "X Position").value = 170.0
|
||||||
self.add_input("SLICESOCK_Float", "Y Position").value = 140.0
|
self.add_input("NodeSocketFloat", "Y Position").value = 140.0
|
||||||
self.add_output("SLICESOCK_SettingsRo", "Settings")
|
self.add_output("SLICESOCK_SettingsRo", "Settings")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
||||||
|
|
@ -108,9 +114,9 @@ class SLICENODE_OffsetObject(SliceNode):
|
||||||
bl_label = "Offset Object"
|
bl_label = "Offset Object"
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Float", "X Offset").value = 0.0
|
self.add_input("NodeSocketFloat", "X Offset").value = 0.0
|
||||||
self.add_input("SLICESOCK_Float", "Y Offset").value = 0.0
|
self.add_input("NodeSocketFloat", "Y Offset").value = 0.0
|
||||||
self.add_input("SLICESOCK_Float", "Z Offset").value = 0.0
|
self.add_input("NodeSocketFloat", "Z Offset").value = 0.0
|
||||||
self.add_output("SLICESOCK_SettingsRo", "Settings")
|
self.add_output("SLICESOCK_SettingsRo", "Settings")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
||||||
|
|
@ -250,11 +256,11 @@ class SLICENODE_InputPrinter(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_output("SLICESOCK_Printer")
|
self.add_output("SLICESOCK_Printer")
|
||||||
self.add_input("SLICESOCK_String", "Host").value = "localhost"
|
self.add_input("NodeSocketString", "Host").value = "localhost"
|
||||||
self.add_input("SLICESOCK_Int", "Port").value = 80
|
self.add_input("NodeSocketInt", "Port").value = 80
|
||||||
self.add_input("SLICESOCK_String", "Prefix")
|
self.add_input("NodeSocketString", "Prefix")
|
||||||
self.add_input("SLICESOCK_String", "Username")
|
self.add_input("NodeSocketString", "Username")
|
||||||
self.add_input("SLICESOCK_String", "Password")
|
self.add_input("NodeSocketString", "Password")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
layout.prop(self, "printer_label") # pyright: ignore[reportOptionalMemberAccess]
|
layout.prop(self, "printer_label") # pyright: ignore[reportOptionalMemberAccess]
|
||||||
|
|
@ -280,14 +286,14 @@ class SLICENODE_InputIntrinsics(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_output("SLICESOCK_Intrinsics")
|
self.add_output("SLICESOCK_Intrinsics")
|
||||||
self.add_input("SLICESOCK_Float", "Bed X").value = 250.0
|
self.add_input("NodeSocketFloat", "Bed X").value = 250.0
|
||||||
self.add_input("SLICESOCK_Float", "Bed Y").value = 210.0
|
self.add_input("NodeSocketFloat", "Bed Y").value = 210.0
|
||||||
self.add_input("SLICESOCK_Float", "Feedrate").value = 1200.0
|
self.add_input("NodeSocketFloat", "Feedrate").value = 1200.0
|
||||||
self.add_input("SLICESOCK_Float", "Travel Feedrate").value = 2400.0
|
self.add_input("NodeSocketFloat", "Travel Feedrate").value = 2400.0
|
||||||
self.add_input("SLICESOCK_Float", "Extrusion Rate").value = 0.035
|
self.add_input("NodeSocketFloat", "Extrusion Rate").value = 0.035
|
||||||
self.add_input("SLICESOCK_Float", "Retraction").value = 0.0
|
self.add_input("NodeSocketFloat", "Retraction").value = 0.0
|
||||||
self.add_input("SLICESOCK_Float", "Retraction Feedrate").value = 0.0
|
self.add_input("NodeSocketFloat", "Retraction Feedrate").value = 0.0
|
||||||
self.add_input("SLICESOCK_Float", "Lift").value = 0.0
|
self.add_input("NodeSocketFloat", "Lift").value = 0.0
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> SliceIntrinsics:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> SliceIntrinsics:
|
||||||
ret_fr = 0.0
|
ret_fr = 0.0
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ class SLICENODE_FloatMath(MathNode):
|
||||||
bl_label = "Math"
|
bl_label = "Math"
|
||||||
math_type = float
|
math_type = float
|
||||||
socket_label: str = "Float"
|
socket_label: str = "Float"
|
||||||
|
socket_type: str = "NodeSocketFloat"
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_IntMath(MathNode):
|
class SLICENODE_IntMath(MathNode):
|
||||||
bl_label = "Integer Math"
|
bl_label = "Integer Math"
|
||||||
math_type = int
|
math_type = int
|
||||||
socket_label: str = "Int"
|
socket_label: str = "Int"
|
||||||
|
socket_type: str = "NodeSocketInt"
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class SLICENODE_GetMesh(SliceNode):
|
||||||
include_children: NfBoolProperty(name="Include Children", default=True) # pyright: ignore[reportInvalidTypeForm]
|
include_children: NfBoolProperty(name="Include Children", default=True) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Object")
|
self.add_input("NodeSocketObject")
|
||||||
self.add_output("SLICESOCK_Mesh")
|
self.add_output("SLICESOCK_Mesh")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -89,8 +89,8 @@ class SLICENODE_SeparateMesh(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh")
|
self.add_input("SLICESOCK_Mesh")
|
||||||
self.add_input("SLICESOCK_String", "Attribute")
|
self.add_input("NodeSocketString", "Attribute")
|
||||||
self.add_input("SLICESOCK_Float", "Value")
|
self.add_input("NodeSocketFloat", "Value")
|
||||||
self.add_output("SLICESOCK_Mesh", "Selection")
|
self.add_output("SLICESOCK_Mesh", "Selection")
|
||||||
self.add_output("SLICESOCK_Mesh", "Inverted")
|
self.add_output("SLICESOCK_Mesh", "Inverted")
|
||||||
|
|
||||||
|
|
@ -172,7 +172,7 @@ class SLICENODE_SeparateMeshByRange(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh")
|
self.add_input("SLICESOCK_Mesh")
|
||||||
self.add_input("SLICESOCK_String", "Attribute")
|
self.add_input("NodeSocketString", "Attribute")
|
||||||
self._update_outputs()
|
self._update_outputs()
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
|
|
@ -277,9 +277,9 @@ class SLICENODE_ArrangeMesh(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh", "Slicing Group", display_shape='LIST')
|
self.add_input("SLICESOCK_Mesh", "Slicing Group", display_shape='LIST')
|
||||||
self.add_input("SLICESOCK_Float", "Bed X").value = 250.0
|
self.add_input("NodeSocketFloat", "Bed X").value = 250.0
|
||||||
self.add_input("SLICESOCK_Float", "Bed Y").value = 250.0
|
self.add_input("NodeSocketFloat", "Bed Y").value = 250.0
|
||||||
self.add_input("SLICESOCK_Float", "Spacing").value = 2.0
|
self.add_input("NodeSocketFloat", "Spacing").value = 2.0
|
||||||
self.add_output("SLICESOCK_Mesh", "Slicing Group", display_shape='LIST')
|
self.add_output("SLICESOCK_Mesh", "Slicing Group", display_shape='LIST')
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -584,18 +584,16 @@ class SLICENODE_TransformGeometry(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Geometry", "Geometry")
|
self.add_input("SLICESOCK_Geometry", "Geometry")
|
||||||
self.add_input("SLICESOCK_Vector", "Translation")
|
self.add_input("NodeSocketVector", "Translation")
|
||||||
self.add_input("SLICESOCK_VectorRotation", "Rotation")
|
self.add_input("NodeSocketRotation", "Rotation")
|
||||||
self.add_input("SLICESOCK_Vector", "Scale").value = (1.0, 1.0, 1.0)
|
self.add_input("NodeSocketVector", "Scale").value = (1.0, 1.0, 1.0)
|
||||||
self.add_output("SLICESOCK_Geometry", "Geometry")
|
self.add_output("SLICESOCK_Geometry", "Geometry")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
||||||
if socket_name not in ("Geometry", "Mesh"):
|
if socket_name not in ("Geometry"):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
geom_data: Any = self.resolve("Geometry")
|
geom_data: Any = self.resolve("Geometry")
|
||||||
if geom_data is None:
|
|
||||||
geom_data = self.resolve("Mesh")
|
|
||||||
if geom_data is None:
|
if geom_data is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -623,9 +621,9 @@ class SLICENODE_DropGeometry(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh", "Mesh")
|
self.add_input("SLICESOCK_Mesh", "Mesh")
|
||||||
self.add_input("SLICESOCK_Float", "Z")
|
self.add_input("NodeSocketFloat", "Z")
|
||||||
self.add_output("SLICESOCK_Mesh", "Mesh")
|
self.add_output("SLICESOCK_Mesh", "Mesh")
|
||||||
self.add_output("SLICESOCK_VectorRo", "Translation")
|
self.add_output("NodeSocketVector", "Translation")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> SlicingCollection | SlicingGroup | tuple[float, float, float] | None:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> SlicingCollection | SlicingGroup | tuple[float, float, float] | None:
|
||||||
if socket_name == "Translation":
|
if socket_name == "Translation":
|
||||||
|
|
@ -754,7 +752,7 @@ class SLICENODE_RenameMesh(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh", "Geometry")
|
self.add_input("SLICESOCK_Mesh", "Geometry")
|
||||||
self.add_input("SLICESOCK_String", "Name")
|
self.add_input("NodeSocketString", "Name")
|
||||||
self.add_output("SLICESOCK_Mesh", "Geometry")
|
self.add_output("SLICESOCK_Mesh", "Geometry")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -821,7 +819,7 @@ class SLICENODE_AssignPdfProperties(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh", "Geometry")
|
self.add_input("SLICESOCK_Mesh", "Geometry")
|
||||||
self.add_input("SLICESOCK_Float", "Line Width")
|
self.add_input("NodeSocketFloat", "Line Width")
|
||||||
self.add_output("SLICESOCK_Mesh", "Geometry")
|
self.add_output("SLICESOCK_Mesh", "Geometry")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ class SLICENODE_GetPaths(SliceNode):
|
||||||
bl_label = "Get Paths"
|
bl_label = "Get Paths"
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Object")
|
self.add_input("NodeSocketObject")
|
||||||
self.add_input("SLICESOCK_String", "Extrusion Multiplier Attribute").value = 'e_mult'
|
self.add_input("NodeSocketString", "Extrusion Multiplier Attribute").value = 'e_mult'
|
||||||
self.add_input("SLICESOCK_String", "Feedrate Attribute").value = 'f_rate'
|
self.add_input("NodeSocketString", "Feedrate Attribute").value = 'f_rate'
|
||||||
self.add_input("SLICESOCK_Settings", "Extra Attributes")
|
self.add_input("SLICESOCK_Settings", "Extra Attributes")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
|
|
@ -44,9 +44,9 @@ class SLICENODE_SliceShells(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh")
|
self.add_input("SLICESOCK_Mesh")
|
||||||
self.add_input("SLICESOCK_Float", "Layer Height").value = 0.2
|
self.add_input("NodeSocketFloat", "Layer Height").value = 0.2
|
||||||
self.add_input("SLICESOCK_Float", "First Layer Height").value = 0.2
|
self.add_input("NodeSocketFloat", "First Layer Height").value = 0.2
|
||||||
self.add_input("SLICESOCK_VectorRotation", "Rotation")
|
self.add_input("NodeSocketRotation", "Rotation")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> SlicePaths:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> SlicePaths:
|
||||||
|
|
@ -211,8 +211,8 @@ class SLICENODE_BufferCurve(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths")
|
self.add_input("SLICESOCK_Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Distance").value = 0.0
|
self.add_input("NodeSocketFloat", "Distance").value = 0.0
|
||||||
self.add_input("SLICESOCK_VectorRotation", "Rotation")
|
self.add_input("NodeSocketRotation", "Rotation")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -254,8 +254,8 @@ class SLICENODE_OffsetCurve(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths")
|
self.add_input("SLICESOCK_Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Distance").value = 0.0
|
self.add_input("NodeSocketFloat", "Distance").value = 0.0
|
||||||
self.add_input("SLICESOCK_VectorRotation", "Rotation")
|
self.add_input("NodeSocketRotation", "Rotation")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -283,7 +283,7 @@ class SLICENODE_PathOffset(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths", "Paths")
|
self.add_input("SLICESOCK_Paths", "Paths")
|
||||||
self.add_input("SLICESOCK_Vector", "Offset")
|
self.add_input("NodeSocketVector", "Offset")
|
||||||
self.add_output("SLICESOCK_Paths", "Paths")
|
self.add_output("SLICESOCK_Paths", "Paths")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
||||||
|
|
@ -300,8 +300,8 @@ class SLICENODE_RotatePath(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths", "Paths")
|
self.add_input("SLICESOCK_Paths", "Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Angle").value = 0.0
|
self.add_input("NodeSocketFloat", "Angle").value = 0.0
|
||||||
self.add_input("SLICESOCK_Vector", "Center")
|
self.add_input("NodeSocketVector", "Center")
|
||||||
self.add_output("SLICESOCK_Paths", "Paths")
|
self.add_output("SLICESOCK_Paths", "Paths")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> Any:
|
||||||
|
|
@ -330,10 +330,10 @@ class SLICENODE_BufferShellsMultiple(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths")
|
self.add_input("SLICESOCK_Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Distance").value = 0
|
self.add_input("NodeSocketFloat", "Distance").value = 0
|
||||||
self.add_input("SLICESOCK_Float", "Width Step").value = 0.4
|
self.add_input("NodeSocketFloat", "Width Step").value = 0.4
|
||||||
self.add_input("SLICESOCK_Int", "Count").value = 2
|
self.add_input("NodeSocketInt", "Count").value = 2
|
||||||
self.add_input("SLICESOCK_VectorRotation", "Rotation")
|
self.add_input("NodeSocketRotation", "Rotation")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -370,9 +370,9 @@ class SLICENODE_Infill(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths")
|
self.add_input("SLICESOCK_Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Density").value = 2.0
|
self.add_input("NodeSocketFloat", "Density").value = 2.0
|
||||||
self.add_input("SLICESOCK_Float", "Infill Rotation").value = 0.0
|
self.add_input("NodeSocketFloat", "Infill Rotation").value = 0.0
|
||||||
self.add_input("SLICESOCK_VectorRotation", "Layer Rotation")
|
self.add_input("NodeSocketRotation", "Layer Rotation")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -422,7 +422,7 @@ class SLICENODE_OverhangMask(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths")
|
self.add_input("SLICESOCK_Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Tolerance").value = 0.05
|
self.add_input("NodeSocketFloat", "Tolerance").value = 0.05
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -534,7 +534,7 @@ class SLICENODE_SimplifyPaths(SliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Paths")
|
self.add_input("SLICESOCK_Paths")
|
||||||
self.add_input("SLICESOCK_Float", "Tolerance").value = 0.1
|
self.add_input("NodeSocketFloat", "Tolerance").value = 0.1
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class SLICENODE_GcodeToMesh(ExecSliceNode):
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self._init_exec()
|
self._init_exec()
|
||||||
self.add_input("SLICESOCK_String", "Name")
|
self.add_input("NodeSocketString", "Name")
|
||||||
self.add_multi_socket_group("SLICESOCK_Gcode", name="Gcode")
|
self.add_multi_socket_group("SLICESOCK_Gcode", name="Gcode")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
|
|
@ -242,7 +242,7 @@ class SLICENODE_GcodeToMesh(ExecSliceNode):
|
||||||
|
|
||||||
for i, gcode in enumerate(gcodes):
|
for i, gcode in enumerate(gcodes):
|
||||||
if total_parts > 1:
|
if total_parts > 1:
|
||||||
mesh_name = f"{base_mesh_name}{i+1:0{num_digits}d}"
|
mesh_name = f"{base_mesh_name}{i:0{num_digits}d}"
|
||||||
else:
|
else:
|
||||||
mesh_name = base_mesh_name
|
mesh_name = base_mesh_name
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,101 +44,18 @@ class ReadonlySocket():
|
||||||
def draw(self, context: Any, layout: Any, node: Any, text: str | None):
|
def draw(self, context: Any, layout: Any, node: Any, text: str | None):
|
||||||
return self._draw_as_ro(context, layout, node, text) # pyright: ignore[reportAttributeAccessIssue]
|
return self._draw_as_ro(context, layout, node, text) # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
class SLICESOCK_ObjectCommon(InputNodeSocket):
|
# Native Blender socket type aliases
|
||||||
bl_label = "Object"
|
SLICESOCK_Object = "NodeSocketObject"
|
||||||
|
SLICESOCK_ObjectRo = "NodeSocketObject"
|
||||||
value: NfPointerProperty(
|
SLICESOCK_Float = "NodeSocketFloat"
|
||||||
name="Object",
|
SLICESOCK_FloatRo = "NodeSocketFloat"
|
||||||
type=bpy.types.Object,
|
SLICESOCK_Int = "NodeSocketInt"
|
||||||
update=notify_tree_changed
|
SLICESOCK_IntRo = "NodeSocketInt"
|
||||||
) # pyright: ignore[reportInvalidTypeForm]
|
SLICESOCK_String = "NodeSocketString"
|
||||||
bl_color = (0.9, 0.7, 0.2, 1.0)
|
SLICESOCK_VectorRotation = "NodeSocketRotation"
|
||||||
|
SLICESOCK_VectorRotationRo = "NodeSocketRotation"
|
||||||
@register_class
|
SLICESOCK_Vector = "NodeSocketVector"
|
||||||
class SLICESOCK_ObjectRo(ReadonlySocket, SLICESOCK_ObjectCommon): ...
|
SLICESOCK_VectorRo = "NodeSocketVector"
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Object(SLICESOCK_ObjectCommon): ...
|
|
||||||
|
|
||||||
class SLICESOCK_Float_Common(InputNodeSocket):
|
|
||||||
bl_label = "Float"
|
|
||||||
|
|
||||||
value: NfFloatProperty(name="Float", default=0) # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (161/255, 161/255, 161/255, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_FloatRo(ReadonlySocket, SLICESOCK_Float_Common): ...
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Float(SLICESOCK_Float_Common): ...
|
|
||||||
|
|
||||||
|
|
||||||
class SLICESOCK_Int_Common(InputNodeSocket):
|
|
||||||
bl_label = "Integer"
|
|
||||||
|
|
||||||
value: NfIntProperty(name="Int", default=0) # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (161/255, 161/255, 161/255, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Int(SLICESOCK_Int_Common): ...
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_IntRo(ReadonlySocket, SLICESOCK_Int_Common): ...
|
|
||||||
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_String(InputNodeSocket):
|
|
||||||
bl_label = "String"
|
|
||||||
|
|
||||||
value: NfStringProperty(name="String", default="") # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (0.4, 0.7, 1.0, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_FilePath(InputNodeSocket):
|
|
||||||
bl_label = "Filepath"
|
|
||||||
|
|
||||||
value: NfStringProperty(name="Filepath", default="", subtype='FILE_PATH') # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (0.4, 0.7, 1.0, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_DirPath(InputNodeSocket):
|
|
||||||
bl_label = "Filepath"
|
|
||||||
|
|
||||||
value: NfStringProperty(name="Folder", default="", subtype='DIR_PATH') # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (0.4, 0.7, 1.0, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_VectorRotation_Common(InputNodeSocket):
|
|
||||||
bl_label = "VectorRotation"
|
|
||||||
|
|
||||||
value: NfFloatVectorProperty(name="Vector", size=3, default=(0.0, 0.0, 0.0), subtype='EULER') # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (166/255, 99/255, 199/255, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_VectorRotation(SLICESOCK_VectorRotation_Common): ...
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_VectorRotationRo(ReadonlySocket, SLICESOCK_VectorRotation_Common): ...
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Vector_Common(InputNodeSocket):
|
|
||||||
bl_label = "Vector"
|
|
||||||
|
|
||||||
value: NfFloatVectorProperty(name="Vector", size=3, default=(0.0, 0.0, 0.0)) # pyright: ignore[reportInvalidTypeForm]
|
|
||||||
bl_color = (0.39, 0.39, 0.78, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Vector(SLICESOCK_Vector_Common): ...
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_VectorRo(ReadonlySocket, SLICESOCK_Vector_Common): ...
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Mesh(LabelNodeSocket):
|
|
||||||
bl_label = "Mesh"
|
|
||||||
default = None
|
|
||||||
bl_color = (0, 214/255, 163/255, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
|
||||||
class SLICESOCK_Paths(LabelNodeSocket):
|
|
||||||
bl_label = "Paths"
|
|
||||||
default = SlicePaths()
|
|
||||||
bl_color = (214/255, 0, 120/255, 1.0)
|
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICESOCK_Geometry(LabelNodeSocket):
|
class SLICESOCK_Geometry(LabelNodeSocket):
|
||||||
|
|
@ -159,7 +76,7 @@ class SLICESOCK_Geometry(LabelNodeSocket):
|
||||||
pass
|
pass
|
||||||
return getattr(from_sock, "bl_color", self.bl_color)
|
return getattr(from_sock, "bl_color", self.bl_color)
|
||||||
|
|
||||||
if self.is_output:
|
if getattr(self, "is_output", False):
|
||||||
if node and hasattr(node, "inputs"):
|
if node and hasattr(node, "inputs"):
|
||||||
sock_name = getattr(self, "name", "")
|
sock_name = getattr(self, "name", "")
|
||||||
matching_in = (node.inputs.get(sock_name) if sock_name else None) or node.inputs.get("Geometry")
|
matching_in = (node.inputs.get(sock_name) if sock_name else None) or node.inputs.get("Geometry")
|
||||||
|
|
@ -169,6 +86,32 @@ class SLICESOCK_Geometry(LabelNodeSocket):
|
||||||
else:
|
else:
|
||||||
return _get_upstream_color(self)
|
return _get_upstream_color(self)
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_FilePath(InputNodeSocket):
|
||||||
|
bl_label = "Filepath"
|
||||||
|
|
||||||
|
value: NfStringProperty(name="Filepath", default="", subtype='FILE_PATH') # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
bl_color = (0.4, 0.7, 1.0, 1.0)
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_DirPath(InputNodeSocket):
|
||||||
|
bl_label = "Filepath"
|
||||||
|
|
||||||
|
value: NfStringProperty(name="Folder", default="", subtype='DIR_PATH') # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
bl_color = (0.4, 0.7, 1.0, 1.0)
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_Mesh(LabelNodeSocket):
|
||||||
|
bl_label = "Mesh"
|
||||||
|
default = None
|
||||||
|
bl_color = (0, 214/255, 163/255, 1.0)
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_Paths(LabelNodeSocket):
|
||||||
|
bl_label = "Paths"
|
||||||
|
default = SlicePaths()
|
||||||
|
bl_color = (214/255, 0, 120/255, 1.0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class SLICESOCK_Gcode_Common(InputNodeSocket):
|
class SLICESOCK_Gcode_Common(InputNodeSocket):
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,11 @@ def get_referenced_objects(node, visited=None):
|
||||||
# Check all input sockets for objects
|
# Check all input sockets for objects
|
||||||
for inp in node.inputs:
|
for inp in node.inputs:
|
||||||
# If it's an object socket, it might have a value if not linked
|
# If it's an object socket, it might have a value if not linked
|
||||||
if inp.bl_idname in {"SLICESOCK_Object", "SLICESOCK_ObjectRo"}:
|
if inp.bl_idname == "NodeSocketObject":
|
||||||
if not inp.is_linked and getattr(inp, "value", None):
|
if not inp.is_linked and getattr(inp, "value", getattr(inp, "default_value", None)):
|
||||||
objs.add(inp.value)
|
val = getattr(inp, "value", getattr(inp, "default_value", None))
|
||||||
|
if isinstance(val, bpy.types.Object):
|
||||||
|
objs.add(val)
|
||||||
|
|
||||||
# Always follow links to find more objects upstream
|
# Always follow links to find more objects upstream
|
||||||
if inp.is_linked:
|
if inp.is_linked:
|
||||||
|
|
@ -48,9 +50,10 @@ def get_referenced_objects(node, visited=None):
|
||||||
# Also check output sockets of the node itself,
|
# Also check output sockets of the node itself,
|
||||||
# as some nodes might "hold" an object (like InputObject)
|
# as some nodes might "hold" an object (like InputObject)
|
||||||
for outp in node.outputs:
|
for outp in node.outputs:
|
||||||
if outp.bl_idname in {"SLICESOCK_Object", "SLICESOCK_ObjectRo"}:
|
if outp.bl_idname == "NodeSocketObject":
|
||||||
if getattr(outp, "value", None):
|
val = getattr(outp, "value", getattr(outp, "default_value", None))
|
||||||
objs.add(outp.value)
|
if isinstance(val, bpy.types.Object):
|
||||||
|
objs.add(val)
|
||||||
elif node.bl_idname == "SLICENODE_CollectionObjects" and outp.is_linked:
|
elif node.bl_idname == "SLICENODE_CollectionObjects" and outp.is_linked:
|
||||||
obj = bpy.data.objects.get(outp.identifier)
|
obj = bpy.data.objects.get(outp.identifier)
|
||||||
if obj:
|
if obj:
|
||||||
|
|
|
||||||
|
|
@ -752,7 +752,7 @@ def segments_to_slice(segments: np.ndarray) -> list[np.ndarray]:
|
||||||
open_paths = []
|
open_paths = []
|
||||||
for p in linked:
|
for p in linked:
|
||||||
path_pts = p[:, :2]
|
path_pts = p[:, :2]
|
||||||
if len(path_pts) > 2 and np.allclose(path_pts[0], path_pts[-1]):
|
if len(path_pts) > 3 and np.allclose(path_pts[0], path_pts[-1]):
|
||||||
closed_paths.append(p)
|
closed_paths.append(p)
|
||||||
else:
|
else:
|
||||||
open_paths.append(p)
|
open_paths.append(p)
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,5 @@ This file provides a mapping of modules to their primary responsibilities and ke
|
||||||
|
|
||||||
- `blender_slice_nodes_generic.py`:
|
- `blender_slice_nodes_generic.py`:
|
||||||
- Base classes for NodeSlicer nodes (`SliceNode`) and sockets (`SliceNodeSocket`).
|
- Base classes for NodeSlicer nodes (`SliceNode`) and sockets (`SliceNodeSocket`).
|
||||||
|
- Native Blender socket type mappings (`NodeSocketFloat`, `NodeSocketInt`, `NodeSocketVector`, `NodeSocketRotation`, `NodeSocketString`, `NodeSocketObject`, `NodeSocketGeometry`).
|
||||||
- Core evaluation logic (`resolve_input`).
|
- Core evaluation logic (`resolve_input`).
|
||||||
|
|
|
||||||
12
doc/NODES.md
12
doc/NODES.md
|
|
@ -4,11 +4,13 @@
|
||||||
|
|
||||||
| Socket ID | Type | Underlying Data Structure | Purpose |
|
| Socket ID | Type | Underlying Data Structure | Purpose |
|
||||||
|-----------|------|---------------------------|---------|
|
|-----------|------|---------------------------|---------|
|
||||||
| `SLICESOCK_Object` | `bpy.types.Object` | Blender RNA Object | Reference to a Blender Object |
|
| `NodeSocketObject` | `bpy.types.Object` | Blender RNA Object | Reference to a Blender Object |
|
||||||
| `SLICESOCK_Float` | `float` | Python float | Numeric value |
|
| `NodeSocketFloat` | `float` | Python float | Numeric value |
|
||||||
| `SLICESOCK_Int` | `int` | Python int | Integer value |
|
| `NodeSocketInt` | `int` | Python int | Integer value |
|
||||||
| `SLICESOCK_String` | `str` | Python string | Text/Path value |
|
| `NodeSocketString` | `str` | Python string | Text value |
|
||||||
| `SLICESOCK_Vector` | `tuple` | Python tuple (3) | XYZ or Euler rotation value |
|
| `NodeSocketVector` | `tuple` | Python tuple (3) | XYZ vector value |
|
||||||
|
| `NodeSocketRotation` | `tuple` | Python tuple (3) | Euler rotation value |
|
||||||
|
| `NodeSocketGeometry` | `Geometry` | Geometry Data | Generic geometry reference |
|
||||||
| `SLICESOCK_Mesh` | `SlicingObject` | NumPy NDArray (Triangles) | Internal mesh data (Transformed/Scaled) |
|
| `SLICESOCK_Mesh` | `SlicingObject` | NumPy NDArray (Triangles) | Internal mesh data (Transformed/Scaled) |
|
||||||
| `SLICESOCK_Paths` | `SlicePaths` (list) | List of paths (N, 3) + groups | Generic toolpaths or slice boundaries |
|
| `SLICESOCK_Paths` | `SlicePaths` (list) | List of paths (N, 3) + groups | Generic toolpaths or slice boundaries |
|
||||||
| `SLICESOCK_Gcode` | `str` | Multi-line string | Generated G-code text |
|
| `SLICESOCK_Gcode` | `str` | Multi-line string | Generated G-code text |
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,47 @@ class NodeException(Exception): ...
|
||||||
|
|
||||||
_EvalCache = dict[tuple[int, str, str], Any]
|
_EvalCache = dict[tuple[int, str, str], Any]
|
||||||
|
|
||||||
|
NATIVE_SOCKET_MAP: dict[str, str] = {}
|
||||||
|
|
||||||
|
NATIVE_SOCKET_LABELS: dict[str, str] = {
|
||||||
|
"NodeSocketFloat": "Float",
|
||||||
|
"NodeSocketInt": "Integer",
|
||||||
|
"NodeSocketVector": "Vector",
|
||||||
|
"NodeSocketRotation": "Rotation",
|
||||||
|
"NodeSocketString": "String",
|
||||||
|
"NodeSocketObject": "Object",
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasattr(bpy.types, "NodeSocket") and not hasattr(bpy.types.NodeSocket, "value"):
|
||||||
|
def _get_socket_value(self):
|
||||||
|
try:
|
||||||
|
return self.default_value
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
pass
|
||||||
|
return getattr(self, "_value", getattr(self, "default", None))
|
||||||
|
|
||||||
|
def _set_socket_value(self, val):
|
||||||
|
try:
|
||||||
|
self.default_value = val
|
||||||
|
return
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
pass
|
||||||
|
self._value = val
|
||||||
|
|
||||||
|
try:
|
||||||
|
bpy.types.NodeSocket.value = property(_get_socket_value, _set_socket_value)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
class AutoBlIdName:
|
class AutoBlIdName:
|
||||||
def __init_subclass__(cls, **kwargs):
|
def __init_subclass__(cls, **kwargs):
|
||||||
|
if kwargs:
|
||||||
|
try:
|
||||||
super().__init_subclass__(**kwargs)
|
super().__init_subclass__(**kwargs)
|
||||||
|
except TypeError:
|
||||||
|
super().__init_subclass__()
|
||||||
|
else:
|
||||||
|
super().__init_subclass__()
|
||||||
if "bl_idname" not in cls.__dict__:
|
if "bl_idname" not in cls.__dict__:
|
||||||
cls.bl_idname = cls.__name__
|
cls.bl_idname = cls.__name__
|
||||||
|
|
||||||
|
|
@ -40,7 +78,8 @@ class SliceNode(Node, AutoBlIdName):
|
||||||
return resolve_input(inputs.get(fieldname), cache=cache, visited=visited)
|
return resolve_input(inputs.get(fieldname), cache=cache, visited=visited)
|
||||||
|
|
||||||
def add_output(self, bl_idname: str, name: str = "", identifier: str = "", hide: bool = False, display_shape: str = ""):
|
def add_output(self, bl_idname: str, name: str = "", identifier: str = "", hide: bool = False, display_shape: str = ""):
|
||||||
eval_name = name or get_label_by_name(bl_idname)
|
bl_idname = NATIVE_SOCKET_MAP.get(bl_idname, bl_idname)
|
||||||
|
eval_name = name or NATIVE_SOCKET_LABELS.get(bl_idname) or get_label_by_name(bl_idname) or bl_idname
|
||||||
sock = self.outputs.new(bl_idname, eval_name, identifier=identifier or eval_name)
|
sock = self.outputs.new(bl_idname, eval_name, identifier=identifier or eval_name)
|
||||||
sock.hide = hide
|
sock.hide = hide
|
||||||
if display_shape:
|
if display_shape:
|
||||||
|
|
@ -48,7 +87,8 @@ class SliceNode(Node, AutoBlIdName):
|
||||||
return sock
|
return sock
|
||||||
|
|
||||||
def add_input(self, bl_idname: str, name: str = "", identifier: str = "", hide: bool = False, display_shape: str = ""):
|
def add_input(self, bl_idname: str, name: str = "", identifier: str = "", hide: bool = False, display_shape: str = ""):
|
||||||
eval_name = name or get_label_by_name(bl_idname)
|
bl_idname = NATIVE_SOCKET_MAP.get(bl_idname, bl_idname)
|
||||||
|
eval_name = name or NATIVE_SOCKET_LABELS.get(bl_idname) or get_label_by_name(bl_idname) or bl_idname
|
||||||
sock = self.inputs.new(bl_idname, eval_name, identifier=identifier or eval_name)
|
sock = self.inputs.new(bl_idname, eval_name, identifier=identifier or eval_name)
|
||||||
sock.hide = hide
|
sock.hide = hide
|
||||||
if display_shape:
|
if display_shape:
|
||||||
|
|
@ -268,6 +308,7 @@ class SLICENODE_Group(bpy.types.NodeCustomGroup, AutoBlIdName):
|
||||||
# Add or update sockets
|
# Add or update sockets
|
||||||
sock_indexes = {s.identifier: i for i, s in enumerate(collection)}
|
sock_indexes = {s.identifier: i for i, s in enumerate(collection)}
|
||||||
for ident, name, stype in expected:
|
for ident, name, stype in expected:
|
||||||
|
stype = NATIVE_SOCKET_MAP.get(stype, stype)
|
||||||
if ident not in sock_indexes:
|
if ident not in sock_indexes:
|
||||||
try:
|
try:
|
||||||
# Explicitly pass identifier to keep it perfectly synced
|
# Explicitly pass identifier to keep it perfectly synced
|
||||||
|
|
@ -384,10 +425,19 @@ def resolve_input(
|
||||||
visited = getattr(socket.node, "_current_visited", None)
|
visited = getattr(socket.node, "_current_visited", None)
|
||||||
|
|
||||||
if not socket.is_linked:
|
if not socket.is_linked:
|
||||||
|
try:
|
||||||
|
val = getattr(socket, "default_value", None)
|
||||||
|
if val is not None: return val
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
val = getattr(socket, "value", None)
|
val = getattr(socket, "value", None)
|
||||||
if val is not None:
|
if val is not None: return val
|
||||||
return val
|
except Exception:
|
||||||
return socket.default
|
pass
|
||||||
|
|
||||||
|
return getattr(socket, "default", None)
|
||||||
|
|
||||||
assert socket.is_linked
|
assert socket.is_linked
|
||||||
assert socket.links
|
assert socket.links
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,9 @@ sys.modules['bpy'] = mock_bpy
|
||||||
sys.modules['bpy.types'] = mock_types
|
sys.modules['bpy.types'] = mock_types
|
||||||
sys.modules['bpy.props'] = MagicMock()
|
sys.modules['bpy.props'] = MagicMock()
|
||||||
sys.modules['bpy.utils'] = MagicMock()
|
sys.modules['bpy.utils'] = MagicMock()
|
||||||
|
sys.modules['bpy.utils.previews'] = MagicMock()
|
||||||
|
sys.modules['bpy.app'] = MagicMock()
|
||||||
|
sys.modules['bpy.app.handlers'] = MagicMock()
|
||||||
|
|
||||||
from NodeSlicer.infra.blender.blender_slice_nodes_generic import (
|
from NodeSlicer.infra.blender.blender_slice_nodes_generic import (
|
||||||
_resolve_group_output,
|
_resolve_group_output,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue