I have a task where I need to select a lot of pairs of nodes and swap their positions but when I tried to do this programmatically, only the nodes moved, is there a function that lets me swap them including the handles – i.e. the way the ‘flip horizontal’ and ‘flip vertical’ works?
Can you make a mock-up please? If you want to change node positions, why do you not want them to move?
I don’t know of a specific existing function, but I would approach it like this:
from Foundation import NSPoint
def swap_oncurve_node_positions_keep_offcurves():
# get the selected oncurve nodes
selected_nodes = [selected for selected in Layer.selection if type(selected) == GSNode and selected.type != "offcurve"]
# check that exactly two nodes are selected
if len(selected_nodes) != 2:
return
node_1 = selected_nodes[0]
node_2 = selected_nodes[1]
# collect node positions
node_1_old_position = node_1.position
node_2_old_position = node_2.position
# collect offcurve node positions
node_1_offcurves = [attached_node for attached_node in [node_1.prevNode, node_1.nextNode] if attached_node.type == "offcurve"]
node_2_offcurves = [attached_node for attached_node in [node_2.prevNode, node_2.nextNode] if attached_node.type == "offcurve"]
# calculate difference in position
x_diff = node_1.position.x - node_2.position.x
y_diff = node_1.position.y - node_2.position.y
# swap node positions
node_1.position = node_2_old_position
node_2.position = node_1_old_position
# move offcurves by change in position
for node_1_offcurve in node_1_offcurves:
node_1_offcurve.position = NSPoint(node_1_offcurve.position.x - x_diff, node_1_offcurve.position.y - y_diff)
for node_2_offcurve in node_2_offcurves:
node_2_offcurve.position = NSPoint(node_2_offcurve.position.x + x_diff, node_2_offcurve.position.y + y_diff)
swap_oncurve_node_positions_keep_offcurves()
No, I am not ashamed of loving generator expressions.
If you want a more confusing way of writing the above, here are even more beautiful generator expressions:
from Foundation import NSPoint
def swap_oncurve_node_positions_keep_offcurves():
# get selected oncurve nodes
selected_nodes = [selected for selected in Layer.selection if type(selected) == GSNode and selected.type != "offcurve"]
# check that exactly two nodes are selected
if len(selected_nodes) != 2:
return
# collect the offcurve nodes for each selected node
nodes_offcurves = [[attached_node for attached_node in [node.prevNode, node.nextNode] if attached_node.type == "offcurve"] for node in selected_nodes]
# swap the oncurve node positions
for index, position in enumerate([node.position for node in selected_nodes]):
selected_nodes[index - 1].position = position
# move the offcurve nodes by the change in oncurve node position
for index, node_offcurves in enumerate(nodes_offcurves):
x_diff = selected_nodes[index].x - selected_nodes[index - 1].x
y_diff = selected_nodes[index].y - selected_nodes[index - 1].y
for offcurve in node_offcurves:
offcurve.position = NSPoint(offcurve.position.x + x_diff, offcurve.position.y + y_diff)
swap_oncurve_node_positions_keep_offcurves()
Now part of my scripts:
1 Like
Amazing thank you! I thought there would’ve been a way to do it with an existing function instead of manually calculating the difference and applying it to the offcurve points.