up
This commit is contained in:
parent
76ad7c2018
commit
68e61445a2
3 changed files with 81 additions and 4 deletions
|
|
@ -16,9 +16,11 @@ bl_info = {
|
||||||
def register():
|
def register():
|
||||||
registry.blender_register_classes()
|
registry.blender_register_classes()
|
||||||
bpy.types.NODE_MT_add.append(tree.draw_add_menu)
|
bpy.types.NODE_MT_add.append(tree.draw_add_menu)
|
||||||
|
bpy.app.handlers.depsgraph_update_post.append(tree.depsgraph_update_handler)
|
||||||
print('Nodeslicer Loaded')
|
print('Nodeslicer Loaded')
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
|
bpy.app.handlers.depsgraph_update_post.remove(tree.depsgraph_update_handler)
|
||||||
bpy.types.NODE_MT_add.remove(tree.draw_add_menu)
|
bpy.types.NODE_MT_add.remove(tree.draw_add_menu)
|
||||||
registry.blender_unregister_classes()
|
registry.blender_unregister_classes()
|
||||||
print('Nodeslicer Unloaded')
|
print('Nodeslicer Unloaded')
|
||||||
|
|
|
||||||
|
|
@ -835,18 +835,28 @@ class SLICENODE_GcodeToFile(ExecSliceNode):
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_GcodeToTextBlock(ExecSliceNode):
|
class SLICENODE_GcodeToTextBlock(ExecSliceNode):
|
||||||
bl_label = "Gcode to Text Block"
|
bl_label = "Gcode to Text Block"
|
||||||
button_label = "Create Text Block"
|
button_label = "Update Text Block"
|
||||||
|
|
||||||
|
text_block_name: bpy.props.StringProperty(name="Text Block Name", default="NodeSlicer_Gcode.gcode") # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self._init_exec()
|
self._init_exec()
|
||||||
self.add_input("SLICESOCK_Gcode")
|
self.add_input("SLICESOCK_Gcode")
|
||||||
|
|
||||||
|
def draw_buttons(self, context, layout):
|
||||||
|
super().draw_buttons(context, layout)
|
||||||
|
layout.prop(self, "text_block_name")
|
||||||
|
|
||||||
def evaluate(self, operator=None):
|
def evaluate(self, operator=None):
|
||||||
gcode: str = resolve_input(self.inputs.get("Gcode"))
|
gcode: str = resolve_input(self.inputs.get("Gcode"))
|
||||||
if not gcode:
|
if not gcode:
|
||||||
return 'ok'
|
return 'ok'
|
||||||
|
|
||||||
text_block = bpy.data.texts.new(name="NodeSlicer_Gcode.gcode")
|
name = self.text_block_name
|
||||||
|
text_block = bpy.data.texts.get(name)
|
||||||
|
if text_block is None:
|
||||||
|
text_block = bpy.data.texts.new(name=name)
|
||||||
|
|
||||||
text_block.from_string(gcode)
|
text_block.from_string(gcode)
|
||||||
|
|
||||||
# Attempt to show in an open text editor
|
# Attempt to show in an open text editor
|
||||||
|
|
@ -859,7 +869,6 @@ class SLICENODE_GcodeToTextBlock(ExecSliceNode):
|
||||||
space.text = text_block
|
space.text = text_block
|
||||||
|
|
||||||
return 'ok'
|
return 'ok'
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_StartPrint(ExecSliceNode):
|
class SLICENODE_StartPrint(ExecSliceNode):
|
||||||
bl_label = "Start Print"
|
bl_label = "Start Print"
|
||||||
|
|
@ -1033,9 +1042,15 @@ class SLICENODE_Executor(ExecSliceNode, SliceNodeJoiner):
|
||||||
button_label = "Execute All"
|
button_label = "Execute All"
|
||||||
socket_type = "SLICESOCK_ExecutionLink"
|
socket_type = "SLICESOCK_ExecutionLink"
|
||||||
|
|
||||||
|
auto_refresh: bpy.props.BoolProperty(name="Auto-refresh", default=False) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self._init_exec()
|
self._init_exec()
|
||||||
|
|
||||||
|
def draw_buttons(self, context, layout):
|
||||||
|
super().draw_buttons(context, layout)
|
||||||
|
layout.prop(self, "auto_refresh")
|
||||||
|
|
||||||
def evaluate(self, operator=None):
|
def evaluate(self, operator=None):
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,72 @@ from __future__ import annotations
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
import bpy
|
import bpy
|
||||||
from bpy.types import NodeTree, Operator, Menu
|
from bpy.types import NodeTree, Operator, Menu
|
||||||
|
from bpy.app.handlers import persistent
|
||||||
|
|
||||||
from ...registry import register_class
|
from ...registry import register_class
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from bpy.stub_internal.rna_enums import OperatorReturnItems
|
from bpy.stub_internal.rna_enums import OperatorReturnItems
|
||||||
|
|
||||||
|
def get_referenced_objects(node, visited=None):
|
||||||
|
if visited is None:
|
||||||
|
visited = set()
|
||||||
|
if node in visited:
|
||||||
|
return set()
|
||||||
|
visited.add(node)
|
||||||
|
|
||||||
|
objs = set()
|
||||||
|
# Check all input sockets for objects
|
||||||
|
for inp in node.inputs:
|
||||||
|
# If it's an object socket, it might have a value if not linked
|
||||||
|
if inp.bl_idname == "SLICESOCK_Object":
|
||||||
|
if not inp.is_linked and inp.value:
|
||||||
|
objs.add(inp.value)
|
||||||
|
|
||||||
|
# Always follow links to find more objects upstream
|
||||||
|
if inp.is_linked:
|
||||||
|
for link in inp.links:
|
||||||
|
objs.update(get_referenced_objects(link.from_node, visited))
|
||||||
|
|
||||||
|
# Also check output sockets of the node itself,
|
||||||
|
# as some nodes might "hold" an object (like InputObject)
|
||||||
|
for outp in node.outputs:
|
||||||
|
if outp.bl_idname == "SLICESOCK_Object":
|
||||||
|
if outp.value:
|
||||||
|
objs.add(outp.value)
|
||||||
|
|
||||||
|
return objs
|
||||||
|
|
||||||
|
_is_updating = False
|
||||||
|
|
||||||
|
@persistent
|
||||||
|
def depsgraph_update_handler(scene, depsgraph):
|
||||||
|
global _is_updating
|
||||||
|
if _is_updating:
|
||||||
|
return
|
||||||
|
|
||||||
|
updated_objects = {update.id.name for update in depsgraph.updates if isinstance(update.id, bpy.types.Object)}
|
||||||
|
if not updated_objects:
|
||||||
|
return
|
||||||
|
|
||||||
|
for tree in bpy.data.node_groups:
|
||||||
|
if tree.bl_idname != "SLICETREE_NodeTree":
|
||||||
|
continue
|
||||||
|
|
||||||
|
for node in tree.nodes:
|
||||||
|
if node.bl_idname == "SLICENODE_Executor" and getattr(node, "auto_refresh", False):
|
||||||
|
referenced = get_referenced_objects(node)
|
||||||
|
if any(obj.name in updated_objects for obj in referenced):
|
||||||
|
_is_updating = True
|
||||||
|
try:
|
||||||
|
node.evaluate()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Auto-refresh failed: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
finally:
|
||||||
|
_is_updating = False
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICETREE_NodeTree(NodeTree):
|
class SLICETREE_NodeTree(NodeTree):
|
||||||
bl_idname = "SLICETREE_NodeTree"
|
bl_idname = "SLICETREE_NodeTree"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue