SideFX Houdini customization package
git clone https://git.lucas.co/hou-control.git
hc: let Set Node Shapes honour the selection, as one undo
It took pwd().children() unconditionally, so there was no way to reshape
a few nodes -- invoking it always rewrote every node in the network,
including the ones you had deliberately left alone. Its sibling Set Node
Colors has always honoured the selection.
It now shapes the selection when there is one and falls back to the whole
network when there is not, so nothing that relied on the old behaviour
changes, and the status message says which of the two happened. The loop
is a single undo, like the color operations.
Co-Authored-By: Claude Opus 5 <[email protected]>
otls/sop_lsgalante.developer_lead.1.0.hdalc | Bin 6964 -> 7083 bytes
python3.13libs/hc/hcnetworkeditor.py | 28 ++++++++++++++++++++++++----
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/otls/sop_lsgalante.developer_lead.1.0.hdalc b/otls/sop_lsgalante.developer_lead.1.0.hdalc
index d929150..425f8e9 100755
Binary files a/otls/sop_lsgalante.developer_lead.1.0.hdalc and b/otls/sop_lsgalante.developer_lead.1.0.hdalc differ
diff --git a/python3.13libs/hc/hcnetworkeditor.py b/python3.13libs/hc/hcnetworkeditor.py
index 0be4917..5239660 100644
--- a/python3.13libs/hc/hcnetworkeditor.py
+++ b/python3.13libs/hc/hcnetworkeditor.py
@@ -1275,8 +1275,28 @@ class HCNetworkEditor(HCPathTab):
@command("Set Node Shapes")
def setNodeShapes(self):
+ """Apply the configured node shape to the selection, or to the whole
+ network when nothing is selected.
+
+ This used to take children() unconditionally, so there was no way to
+ reshape a few nodes: invoking it always rewrote every node in the
+ network, including the ones you had deliberately left alone. Its
+ sibling Set Node Colors has always honoured the selection.
+ """
+ network = self.hou_tab.pwd()
+ nodes = list(network.selectedChildren())
+ selected = bool(nodes)
+ if not selected:
+ nodes = list(network.children())
+ if not nodes:
+ hou.ui.setStatusMessage("No nodes to shape",
+ hou.severityType.Warning)
+ return
shape = HCSettings().nodeShape()
- nodes = list(self.hou_tab.pwd().children())
- for node in nodes:
- node.setUserData("nodeshape", shape)
- hou.ui.setStatusMessage(f"Set {len(nodes)} node shape(s) to {shape}")
+ # One undo for the whole batch, not one per node.
+ with hou.undos.group("Set Node Shapes"):
+ for node in nodes:
+ node.setUserData("nodeshape", shape)
+ target = (f"{len(nodes)} selected node(s)" if selected
+ else f"all {len(nodes)} node(s) in this network")
+ hou.ui.setStatusMessage(f"Set {target} to shape {shape}")