From d2bb1b5cb0b7b185d0bd8e8ce7d3622b97a0f934 Mon Sep 17 00:00:00 2001 From: Nicolas Predella Date: Sat, 16 May 2026 18:26:01 +0300 Subject: [PATCH] overrides --- core/nodeslicer/bpy_ns_types.py | 36 ++++++++++++++++++++- core/nodeslicer/nodes.py | 16 ++++++++-- core/nodeslicer/sockets.py | 55 +++++++++++++++++++++++++++++++++ core/nodeslicer/tree.py | 1 + 4 files changed, 105 insertions(+), 3 deletions(-) diff --git a/core/nodeslicer/bpy_ns_types.py b/core/nodeslicer/bpy_ns_types.py index 10e3231..3c60785 100644 --- a/core/nodeslicer/bpy_ns_types.py +++ b/core/nodeslicer/bpy_ns_types.py @@ -1,16 +1,50 @@ import bpy -from bpy.props import PointerProperty, StringProperty, FloatProperty, IntProperty, EnumProperty, BoolProperty +from bpy.props import PointerProperty, StringProperty, FloatProperty, IntProperty, EnumProperty, BoolProperty, CollectionProperty from . import tree def notify_tree_changed(self, context): + from . import tree tree._tree_changed = True node = None + socket = None + if isinstance(self, bpy.types.Node): node = self elif isinstance(self, bpy.types.NodeSocket): + socket = self node = self.node + elif isinstance(self, bpy.types.PropertyGroup): + try: + id_data = self.id_data + if isinstance(id_data, bpy.types.NodeTree): + path = self.path_from_id() + if ".inputs[" in path or ".outputs[" in path: + socket_path = path.split(".items[")[0] if ".items[" in path else path.rsplit(".", 1)[0] + resolved = id_data.path_resolve(socket_path) + if isinstance(resolved, bpy.types.NodeSocket): + socket = resolved + node = socket.node + else: + node_path = path.rsplit(".", 1)[0] + resolved = id_data.path_resolve(node_path) + if isinstance(resolved, bpy.types.Node): + node = resolved + except Exception: + pass + + # Fallback to context + if node is None: + node = getattr(context, "node", None) + if socket is None: + socket = getattr(context, "socket", None) + + if socket and hasattr(socket, "update"): + try: + socket.update() # pyright: ignore[reportAttributeAccessIssue] + except Exception as e: + print(f"Error updating socket: {e}") if node and hasattr(node, "update"): try: diff --git a/core/nodeslicer/nodes.py b/core/nodeslicer/nodes.py index 0ab1642..3a01a73 100644 --- a/core/nodeslicer/nodes.py +++ b/core/nodeslicer/nodes.py @@ -68,6 +68,11 @@ class SLICENODE_InputObject(InputNode): input_type = "Object" bl_icon = "OBJECT_DATA" +@register_class +class SLICENODE_InputOverrides(InputNode): + input_type = "Overrides" + bl_icon = "OBJECT_DATA" + @register_class class SLICENODE_PrusaslicerConf(SliceNode): bl_label = "PrusaSlicer Config" @@ -1103,6 +1108,7 @@ class SLICENODE_PrusaslicerSlice(ExecSliceNode): self._init_exec() self.add_input("SLICESOCK_Object", "Object") self.add_input("SLICESOCK_PrusaslicerConf", "Config") + self.add_input("SLICESOCK_Overrides", "Overrides") self.add_output("SLICESOCK_GcodeRo") def draw_buttons(self, context, layout): @@ -1117,6 +1123,7 @@ class SLICENODE_PrusaslicerSlice(ExecSliceNode): def evaluate(self, operator=None): obj = resolve_input(self.inputs.get("Object")) conf_data = resolve_input(self.inputs.get("Config")) + overrides = resolve_input(self.inputs.get("Overrides")) if not obj: if operator: operator.report({'ERROR'}, "No Object connected") @@ -1153,12 +1160,17 @@ class SLICENODE_PrusaslicerSlice(ExecSliceNode): offset = np.array([bed_center[0], bed_center[1], a_z]) - np.array([slicing_group.center_xy[0], slicing_group.center_xy[1], 0]) slicing_group.offset(offset) - # Generate the ConfigWriter, forcing binary_gcode to 0 to ensure readable ASCII output + # Prepare overrides for generate_conf_writer + # The format expected by generate_conf_writer is overrides={'key': {'value': 'val'}} + writer_overrides = {k: {'value': v} for k, v in overrides.items()} + writer_overrides['binary_gcode'] = {'value': '0'} + + # Generate the ConfigWriter conf_writer = cache.generate_conf_writer( printer_id, filament_ids, print_id, - overrides={'binary_gcode': {'value': '0'}} + overrides=writer_overrides ) # Prepare 3mf path diff --git a/core/nodeslicer/sockets.py b/core/nodeslicer/sockets.py index ebe2cd7..e841f5e 100644 --- a/core/nodeslicer/sockets.py +++ b/core/nodeslicer/sockets.py @@ -1,6 +1,8 @@ from __future__ import annotations from typing import Any import bpy +from bpy.props import CollectionProperty +from bpy.types import Property, PropertyGroup, bpy_struct from .bpy_ns_types import NfStringProperty, NfFloatProperty, NfIntProperty, NfEnumProperty, NfPointerProperty from ...registry import register_class @@ -129,6 +131,59 @@ class SLICESOCK_PrusaslicerConf(LabelNodeSocket): default = None bl_color = (0.95, 0., 0., 1.0) # #F26C21 +@register_class +class SLICENODE_OverrideItem(bpy.types.PropertyGroup): + field: NfStringProperty(name="Field", default="") # pyright: ignore[reportInvalidTypeForm] + value_str: NfStringProperty(name="Value", default="") # pyright: ignore[reportInvalidTypeForm] + + @property + def is_active(self): + return bool(self.field) or bool(self.value_str) + +@register_class +class SLICESOCK_Overrides(InputNodeSocket): + bl_label = "Overrides" + + items: CollectionProperty(type=SLICENODE_OverrideItem) # pyright: ignore[reportInvalidTypeForm] + + bl_color = (1.0, 1.0, 0.0, 1.0) # Yellow + + def draw(self, context, layout, node, text): + if self.is_output or self.is_linked: + layout.label(text=text or self.name) + return + + col = layout.column(align=True) + for item in self.items: + row = col.row(align=True) + row.prop(item, "field", text="") + row.prop(item, "value_str", text="") + + def __init__(self, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + if len(self.items) == 0: + self.items.add() + + def update(self): + + + if self.items[-1].is_active: + self.items.add() + + while len(self.items) >= 2: + if not self.items[-1].is_active and not self.items[-2].is_active: + self.items.remove(len(self.items) - 1) + else: + break + + @property + def value(self) -> dict[str, str]: + overrides = {} + for item in self.items: + if item.field: + overrides[item.field] = item.value_str + return overrides + @register_class class SLICESOCK_ExecutionLink(LabelNodeSocket): bl_label = "Execution Link" diff --git a/core/nodeslicer/tree.py b/core/nodeslicer/tree.py index 7afe305..c9c5893 100644 --- a/core/nodeslicer/tree.py +++ b/core/nodeslicer/tree.py @@ -141,6 +141,7 @@ class SLICENODE_MT_Menu(Menu): layout.operator("node.add_node", text="Math").type = "SLICENODE_FloatMath" layout.operator("node.add_node", text="Integer Math").type = "SLICENODE_IntMath" layout.operator("node.add_node", text="Object").type = "SLICENODE_InputObject" + layout.operator("node.add_node", text="Overrides").type = "SLICENODE_InputOverrides" layout.operator("node.add_node", text="Printer").type = "SLICENODE_InputPrinter" layout.operator("node.add_node", text="PrusaSlicer Config").type = "SLICENODE_PrusaslicerConf" layout.operator("node.add_node", text="Printer List").type = "SLICENODE_PrinterList"