coll obj + fast ng access
This commit is contained in:
parent
d0c11a500c
commit
ed047337ba
4 changed files with 78 additions and 11 deletions
|
|
@ -32,6 +32,50 @@ class SLICENODE_InputObject(InputNode):
|
||||||
input_type = "Object"
|
input_type = "Object"
|
||||||
bl_icon = "OBJECT_DATA"
|
bl_icon = "OBJECT_DATA"
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICENODE_CollectionObjects(SliceNode):
|
||||||
|
bl_label = "Collection Objects"
|
||||||
|
|
||||||
|
collection: bpy.props.PointerProperty(
|
||||||
|
name="Collection",
|
||||||
|
type=bpy.types.Collection,
|
||||||
|
update=notify_tree_changed
|
||||||
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
|
def init(self, context):
|
||||||
|
self._update_outputs()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
super().update()
|
||||||
|
self._update_outputs()
|
||||||
|
|
||||||
|
def draw_buttons(self, context, layout):
|
||||||
|
assert layout
|
||||||
|
layout.prop(self, "collection", text="")
|
||||||
|
|
||||||
|
def _update_outputs(self):
|
||||||
|
if not self.collection:
|
||||||
|
self.outputs.clear()
|
||||||
|
return
|
||||||
|
|
||||||
|
objs = [obj for obj in self.collection.objects if obj.type == 'MESH']
|
||||||
|
expected_names = [obj.name for obj in objs]
|
||||||
|
|
||||||
|
# Remove outputs that are no longer in the collection
|
||||||
|
to_remove = [o for o in self.outputs if o.name not in expected_names]
|
||||||
|
for o in to_remove:
|
||||||
|
self.outputs.remove(o)
|
||||||
|
|
||||||
|
# Add new outputs
|
||||||
|
for name in expected_names:
|
||||||
|
if name not in self.outputs:
|
||||||
|
self.add_output("SLICESOCK_ObjectRo", name, identifier=name)
|
||||||
|
|
||||||
|
def evaluate_output(self, socket_name: str, **kwargs) -> Any:
|
||||||
|
if self.collection and socket_name in bpy.data.objects:
|
||||||
|
return bpy.data.objects[socket_name]
|
||||||
|
return None
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_InputSettings(InputNode):
|
class SLICENODE_InputSettings(InputNode):
|
||||||
input_type = "Settings"
|
input_type = "Settings"
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,7 @@ 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]
|
||||||
|
|
||||||
@register_class
|
class SLICESOCK_ObjectCommon(InputNodeSocket):
|
||||||
class SLICESOCK_Object(InputNodeSocket):
|
|
||||||
bl_label = "Object"
|
bl_label = "Object"
|
||||||
|
|
||||||
value: NfPointerProperty(
|
value: NfPointerProperty(
|
||||||
|
|
@ -55,6 +54,10 @@ class SLICESOCK_Object(InputNodeSocket):
|
||||||
) # pyright: ignore[reportInvalidTypeForm]
|
) # pyright: ignore[reportInvalidTypeForm]
|
||||||
bl_color = (0.9, 0.7, 0.2, 1.0)
|
bl_color = (0.9, 0.7, 0.2, 1.0)
|
||||||
|
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_ObjectRo(ReadonlySocket, SLICESOCK_ObjectCommon): ...
|
||||||
|
@register_class
|
||||||
|
class SLICESOCK_Object(SLICESOCK_ObjectCommon): ...
|
||||||
|
|
||||||
class SLICESOCK_Float_Common(InputNodeSocket):
|
class SLICESOCK_Float_Common(InputNodeSocket):
|
||||||
bl_label = "Float"
|
bl_label = "Float"
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,11 @@ def depsgraph_update_handler(scene, depsgraph):
|
||||||
node.sync_sockets()
|
node.sync_sockets()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
elif node.bl_idname == "SLICENODE_CollectionObjects" and hasattr(node, "_update_outputs"):
|
||||||
|
try:
|
||||||
|
node._update_outputs()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
|
|
@ -141,27 +146,33 @@ class SLICENODE_OT_GroupToggle(Operator):
|
||||||
bl_description = "Enter or exit the selected node group"
|
bl_description = "Enter or exit the selected node group"
|
||||||
bl_options = {'REGISTER', 'UNDO'}
|
bl_options = {'REGISTER', 'UNDO'}
|
||||||
|
|
||||||
|
node_name: bpy.props.StringProperty() # pyright: ignore[reportInvalidTypeForm]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
assert context.space_data
|
assert context.space_data
|
||||||
return (context.space_data.type == 'NODE_EDITOR' and
|
return (context.space_data.type == 'NODE_EDITOR' and
|
||||||
context.space_data.tree_type == "SLICETREE_NodeTree") # pyright: ignore[reportAttributeAccessIssue]
|
context.space_data.tree_type == "SLICETREE_NodeTree") # pyright: ignore[reportAttributeAccessIssue]
|
||||||
|
|
||||||
def execute(self, context) -> set[OperatorReturnItems]:
|
def execute(self, context) -> set['OperatorReturnItems']:
|
||||||
space = context.space_data
|
space = context.space_data
|
||||||
path = getattr(space, 'path', None)
|
path = getattr(space, 'path', None)
|
||||||
if not path:
|
if not path:
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
# If we are inside a group, popping returns us to the parent
|
tree = getattr(space, 'edit_tree', None)
|
||||||
# We want to exit if: 1. No node is selected, OR 2. We press Tab while editing inside a group
|
|
||||||
active_node = context.active_node
|
|
||||||
|
|
||||||
# If we have an active group node, we try to enter it
|
target_node = None
|
||||||
if active_node and active_node.bl_idname == "SLICENODE_Group":
|
if self.node_name and tree and self.node_name in tree.nodes:
|
||||||
group_tree = getattr(active_node, "slicer_tree", None)
|
target_node = tree.nodes[self.node_name]
|
||||||
|
else:
|
||||||
|
target_node = context.active_node
|
||||||
|
|
||||||
|
# If we have a target group node, we try to enter it
|
||||||
|
if target_node and target_node.bl_idname == "SLICENODE_Group":
|
||||||
|
group_tree = getattr(target_node, "slicer_tree", None)
|
||||||
if group_tree:
|
if group_tree:
|
||||||
path.append(group_tree, node=active_node)
|
path.append(group_tree, node=target_node)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
# Otherwise, if we are nested, we pop out
|
# Otherwise, if we are nested, we pop out
|
||||||
|
|
@ -171,6 +182,7 @@ class SLICENODE_OT_GroupToggle(Operator):
|
||||||
|
|
||||||
return {'CANCELLED'}
|
return {'CANCELLED'}
|
||||||
|
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_OT_GroupMake(Operator):
|
class SLICENODE_OT_GroupMake(Operator):
|
||||||
bl_idname = "slicenode.group_make"
|
bl_idname = "slicenode.group_make"
|
||||||
|
|
@ -451,6 +463,7 @@ class SLICENODE_MT_DataInput(Menu):
|
||||||
layout.operator("node.add_node", text="Vector").type = "SLICENODE_InputVector"
|
layout.operator("node.add_node", text="Vector").type = "SLICENODE_InputVector"
|
||||||
layout.separator()
|
layout.separator()
|
||||||
layout.operator("node.add_node", text="Object").type = "SLICENODE_InputObject"
|
layout.operator("node.add_node", text="Object").type = "SLICENODE_InputObject"
|
||||||
|
layout.operator("node.add_node", text="Collection Objects").type = "SLICENODE_CollectionObjects"
|
||||||
layout.operator("node.add_node", text="Settings").type = "SLICENODE_InputSettings"
|
layout.operator("node.add_node", text="Settings").type = "SLICENODE_InputSettings"
|
||||||
layout.operator("node.add_node", text="PrusaSlicer Config").type = "SLICENODE_PrusaslicerConf"
|
layout.operator("node.add_node", text="PrusaSlicer Config").type = "SLICENODE_PrusaslicerConf"
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
|
@ -542,6 +555,8 @@ class SLICENODE_MT_Group(Menu):
|
||||||
layout.operator("node.group_ungroup", text="Ungroup")
|
layout.operator("node.group_ungroup", text="Ungroup")
|
||||||
layout.operator("slicenode.group_toggle", text="Edit Group")
|
layout.operator("slicenode.group_toggle", text="Edit Group")
|
||||||
layout.separator()
|
layout.separator()
|
||||||
|
layout.operator("node.add_node", text="Add Group Node").type = "SLICENODE_Group"
|
||||||
|
layout.separator()
|
||||||
layout.operator("node.add_node", text="Group Input").type = "NodeGroupInput"
|
layout.operator("node.add_node", text="Group Input").type = "NodeGroupInput"
|
||||||
layout.operator("node.add_node", text="Group Output").type = "NodeGroupOutput"
|
layout.operator("node.add_node", text="Group Output").type = "NodeGroupOutput"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ def _get_current_group_node() -> bpy.types.Node | None:
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_Group(bpy.types.NodeCustomGroup, AutoBlIdName):
|
class SLICENODE_Group(bpy.types.NodeCustomGroup, AutoBlIdName):
|
||||||
bl_label = "Group"
|
bl_label = "Group"
|
||||||
|
bl_icon = 'NODETREE'
|
||||||
|
|
||||||
def _tree_updated(self, context):
|
def _tree_updated(self, context):
|
||||||
try:
|
try:
|
||||||
|
|
@ -260,7 +261,11 @@ class SLICENODE_Group(bpy.types.NodeCustomGroup, AutoBlIdName):
|
||||||
|
|
||||||
def draw_buttons(self, context, layout):
|
def draw_buttons(self, context, layout):
|
||||||
assert layout
|
assert layout
|
||||||
layout.prop(self, "slicer_tree", text="")
|
row = layout.row(align=True)
|
||||||
|
row.prop(self, "slicer_tree", text="")
|
||||||
|
if self.slicer_tree:
|
||||||
|
op = row.operator("slicenode.group_toggle", text="", icon='NODETREE')
|
||||||
|
op.node_name = self.name
|
||||||
|
|
||||||
def draw_label(self):
|
def draw_label(self):
|
||||||
if self.slicer_tree:
|
if self.slicer_tree:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue