Skip to content

Instantly share code, notes, and snippets.

@BigRoy
Last active January 31, 2025 21:27
Show Gist options
  • Save BigRoy/1e935abfbaa2b2a7f3f71091d949cebd to your computer and use it in GitHub Desktop.
Save BigRoy/1e935abfbaa2b2a7f3f71091d949cebd to your computer and use it in GitHub Desktop.
Fusion script to swap two selected tools, which swaps their position and connections
from typing import List, Iterable
import itertools
import contextlib
@contextlib.contextmanager
def comp_lock_and_undo_chunk(
comp,
undo_queue_name="Script CMD",
keep_undo=True,
):
"""Lock comp and open an undo chunk during the context"""
try:
comp.Lock()
comp.StartUndo(undo_queue_name)
yield
finally:
comp.Unlock()
comp.EndUndo(keep_undo)
def iter_inputs(tool):
inputs = list(tool.GetInputList().values())
for input in inputs:
connected_output = input.GetConnectedOutput()
if connected_output:
yield connected_output, input
def iter_outputs(tool):
outputs = list(tool.GetOutputList().values())
for output in outputs:
connected_inputs = list(output.GetConnectedInputs().values())
for connected_input in connected_inputs:
yield output, connected_input
def get_position(tool) -> List[float]:
return list(
tool.Composition.CurrentFrame.FlowView.GetPosTable(tool).values()
)
def set_position(tool, pos: List[float]):
tool.Composition.CurrentFrame.FlowView.SetPos(tool, *pos)
def swap_connections(a, b):
a_inputs = list(iter_inputs(a))
b_inputs = list(iter_inputs(b))
a_outputs = list(iter_outputs(a))
b_outputs = list(iter_outputs(b))
# Disconnect all
for output, input in itertools.chain(
a_inputs, b_inputs, a_outputs, b_outputs):
input.ConnectTo(None)
# Reconnect from the other nodes
for output, input in a_inputs:
b_input = b[input.Name]
if b_input:
b_input.ConnectTo(output)
for output, input in b_inputs:
a_input = a[input.Name]
if a_input:
a_input.ConnectTo(output)
for output, input in a_outputs:
b_output = b[output.Name]
if b_output:
input.ConnectTo(b_output)
for output, input in b_outputs:
a_output = a[output.Name]
if a_output:
input.ConnectTo(a_output)
def swap_positions(a, b):
a_pos = get_position(a)
b_pos = get_position(b)
set_position(a, b_pos)
set_position(b, a_pos)
def swap_tools(a, b):
"""Swap tool a with tool b, swapping connections and positions."""
swap_connections(a, b)
swap_positions(a, b)
if __name__ == "__main__":
# Selected tools
tools = list(comp.GetToolList(True).values())
if len(tools) != 2:
raise ValueError("Please select two tools to swap")
names = [tool.Name for tool in tools]
print(f"Swapping tools: {tools[0].Name} <-> {tools[1].Name}")
with comp_lock_and_undo_chunk(comp):
swap_tools(tools[0], tools[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment