visualization
This commit is contained in:
parent
716e619c28
commit
f532fada23
3 changed files with 56 additions and 32 deletions
|
|
@ -1315,26 +1315,24 @@ class SLICENODE_AirtableSubmit(ExecSliceNode_DatabaseSubmit):
|
||||||
return str(record_id)
|
return str(record_id)
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_PrusaslicerSlice(ExecSliceNode):
|
class SLICENODE_PrusaslicerSlice(SliceNode):
|
||||||
bl_label = "PrusaSlicer Slice"
|
bl_label = "PrusaSlicer Slice"
|
||||||
button_label = "Slice with PrusaSlicer"
|
|
||||||
|
|
||||||
prusaslicer_executable: NfStringProperty(name="PrusaSlicer Path", subtype='FILE_PATH', default='flatpak run com.prusa3d.PrusaSlicer') # pyright: ignore[reportInvalidTypeForm]
|
prusaslicer_executable: NfStringProperty(name="PrusaSlicer Path", subtype='FILE_PATH', default='flatpak run com.prusa3d.PrusaSlicer') # pyright: ignore[reportInvalidTypeForm]
|
||||||
gcode_result: NfStringProperty(name="Gcode Result", default="") # pyright: ignore[reportInvalidTypeForm]
|
gcode_result: NfStringProperty(name="Gcode Result", default="") # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self._init_exec()
|
|
||||||
self.add_input("SLICESOCK_Mesh", "Mesh")
|
self.add_input("SLICESOCK_Mesh", "Mesh")
|
||||||
self.add_input("SLICESOCK_PrusaslicerConf", "Config")
|
self.add_input("SLICESOCK_PrusaslicerConf", "Config")
|
||||||
self.add_input("SLICESOCK_Overrides", "Overrides")
|
self.add_input("SLICESOCK_Overrides", "Overrides")
|
||||||
self.add_output("SLICESOCK_GcodeRo")
|
self.add_output("SLICESOCK_GcodeRo")
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
super().draw_buttons(context, layout)
|
|
||||||
layout.prop(self, "prusaslicer_executable")
|
layout.prop(self, "prusaslicer_executable")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **kwargs) -> Any:
|
def evaluate_output(self, socket_name: str, **kwargs) -> Any:
|
||||||
if socket_name == "Gcode":
|
if socket_name == "Gcode":
|
||||||
|
self.evaluate()
|
||||||
return self.gcode_result
|
return self.gcode_result
|
||||||
return super().evaluate_output(socket_name, **kwargs)
|
return super().evaluate_output(socket_name, **kwargs)
|
||||||
|
|
||||||
|
|
@ -1603,6 +1601,7 @@ class SLICENODE_Executor(ExecSliceNode, SliceNodeJoiner):
|
||||||
layout.prop(self, "auto_refresh")
|
layout.prop(self, "auto_refresh")
|
||||||
|
|
||||||
def evaluate(self, operator=None):
|
def evaluate(self, operator=None):
|
||||||
|
from ...infra.blender.blender_slice_nodes_generic import node_execution_feedback
|
||||||
for i, job in enumerate(self.inputs):
|
for i, job in enumerate(self.inputs):
|
||||||
# Resolve the input to get the connected node(s)
|
# Resolve the input to get the connected node(s)
|
||||||
res = resolve_input(job)
|
res = resolve_input(job)
|
||||||
|
|
@ -1620,6 +1619,7 @@ class SLICENODE_Executor(ExecSliceNode, SliceNodeJoiner):
|
||||||
operator.report({'INFO'}, f"Executing: {upstream_node.bl_label}")
|
operator.report({'INFO'}, f"Executing: {upstream_node.bl_label}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
with node_execution_feedback(upstream_node):
|
||||||
exec_res = upstream_node.evaluate(operator=operator)
|
exec_res = upstream_node.evaluate(operator=operator)
|
||||||
if exec_res != 'ok' and exec_res is not None:
|
if exec_res != 'ok' and exec_res is not None:
|
||||||
if operator: operator.report({'WARNING'}, f"Node {upstream_node.bl_label} returned {exec_res}")
|
if operator: operator.report({'WARNING'}, f"Node {upstream_node.bl_label} returned {exec_res}")
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from bpy.types import NodeTree, Operator, Menu
|
||||||
from bpy.app.handlers import persistent
|
from bpy.app.handlers import persistent
|
||||||
|
|
||||||
from ...infra.blender.mixins import update_collection
|
from ...infra.blender.mixins import update_collection
|
||||||
|
from ...infra.blender.blender_slice_nodes_generic import node_execution_feedback, resolve_input
|
||||||
from ...registry import register_class
|
from ...registry import register_class
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
@ -84,6 +85,7 @@ def tree_update_handler(scene, depsgraph):
|
||||||
if should_refresh:
|
if should_refresh:
|
||||||
_is_updating = True
|
_is_updating = True
|
||||||
try:
|
try:
|
||||||
|
with node_execution_feedback(node):
|
||||||
node.evaluate()
|
node.evaluate()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Auto-refresh failed: {e}")
|
print(f"Auto-refresh failed: {e}")
|
||||||
|
|
@ -130,6 +132,7 @@ class SLICENODE_OT_Execute(Operator):
|
||||||
node = node_tree.nodes[self.node_name]
|
node = node_tree.nodes[self.node_name]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
with node_execution_feedback(node):
|
||||||
res = node.evaluate(operator=self)
|
res = node.evaluate(operator=self)
|
||||||
if res == 'ok':
|
if res == 'ok':
|
||||||
self.report({"INFO"}, f"Execution Successful")
|
self.report({"INFO"}, f"Execution Successful")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import typing
|
import typing
|
||||||
|
import bpy
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from bpy.types import NodeSocket, Node
|
from bpy.types import NodeSocket, Node
|
||||||
|
|
@ -41,6 +43,24 @@ class SliceNode(Node, AutoBlIdName):
|
||||||
|
|
||||||
## Evaluation helpers
|
## Evaluation helpers
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def node_execution_feedback(node: bpy.types.Node):
|
||||||
|
# Save original color
|
||||||
|
old_use_color = node.use_custom_color
|
||||||
|
old_color = node.color[:]
|
||||||
|
|
||||||
|
node.use_custom_color = True
|
||||||
|
node.color = (75/255, 73/255, 19/255) # Green
|
||||||
|
|
||||||
|
# Refresh UI
|
||||||
|
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||||
|
try:
|
||||||
|
yield
|
||||||
|
finally:
|
||||||
|
node.use_custom_color = old_use_color
|
||||||
|
node.color = old_color
|
||||||
|
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
|
||||||
|
|
||||||
def _follow_reroute(socket: NodeSocket) -> NodeSocket:
|
def _follow_reroute(socket: NodeSocket) -> NodeSocket:
|
||||||
current: NodeSocket = socket
|
current: NodeSocket = socket
|
||||||
seen: set[int] = set()
|
seen: set[int] = set()
|
||||||
|
|
@ -106,6 +126,7 @@ def _resolve_output(
|
||||||
|
|
||||||
visited.add(key)
|
visited.add(key)
|
||||||
try:
|
try:
|
||||||
|
with node_execution_feedback(socket.node):
|
||||||
if not isinstance(socket.node, SliceNode):
|
if not isinstance(socket.node, SliceNode):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue