How to add off-curve nodes with a script? AKA a faster way to option+click for curves

I’m drawing a complex bit of lettering with lots of flourishes, which means that I’m placing a lot of nodes at extrema, then option+clicking all paths to add off curve nodes, then dragging them into curves. There are lots of path segments, and every one needs to be a curve. This gets a bit tedious.

Is there a faster way to do the conversion of straight to curved paths than the typical option+click? For example, is there a script I could run that would change all selected paths into curves? Even if this just placed the offcurve nodes, it would save a good bit of clicking around.

I found a partial post on this, but it lacked detail in how to make the final script work. Putting together what is there, I think this is close. However, it crashes Glyphs (v2) when I try to run it:

font = Glyphs.currentDocument.font
layer = font.selectedLayers[0]

for path in layer.paths:
    if path.selected == True:
        for node in path.nodes:
            
            if  node.type != GSCURVE:
                
            
                # aNode has to be set
                Index = node.index
                PreviousNode = path.nodes[Index-1]

                # add the off curve nodes
                newNode = GSNode()
                newNode.type = GSOFFCURVE
                newNode.position = NSMakePoint( PreviousNode.x + ((node.x-PreviousNode.x) / 3 * 2), PreviousNode.y + ((node.y-PreviousNode.y) / 3 * 2) )
                path.insertNode_atIndex_(newNode, Index)

                newNode = GSNode()
                newNode.type = GSOFFCURVE
                newNode.position = NSMakePoint( PreviousNode.x + ((node.x-PreviousNode.x) / 3), PreviousNode.y + ((node.y-PreviousNode.y) / 3) )
                path.insertNode_atIndex_(newNode, Index)

                # change the type of the selected node
                node.type = GSCURVE
                

If am trying to run the script on a path if it is selected. But, each time I do, Glyphs crashes.

What am I missing?

Thanks for any insights!

Simon Cozens has a script for it:

This is how I would implement it (based on @SimonC’s script)

#MenuTitle: Curve All Straights
# -*- coding: utf-8 -*-
__doc__="""
Turn corners into smooths (useful when tracing)
"""
import GlyphsApp
from Foundation import NSPoint

def lerp(t, a, b):
	return NSPoint(int((1-t)*a.x + t*b.x), int((1-t)*a.y + t*b.y))

Layer = Glyphs.font.selectedLayers[0]
testSelection = len(Layer.selection) > 0

for p in Layer.paths:
	if p.closed:
		start = -1
	else:
		start = 0
	for idx in range(len(p.nodes) - 1, start, -1):
		node = p.nodes[idx]
		if testSelection and not node.selected:
			continue
		if node.type == LINE:
			prevNode = p.nodes[idx - 1]
			off1 = GSNode(lerp(0.33, prevNode.position, node.position), OFFCURVE)
			off2 = GSNode(lerp(0.66, prevNode.position, node.position), OFFCURVE)
			p.nodes.insert(idx, off2)
			p.nodes.insert(idx, off1)
			node.type = CURVE
			node.connection = GSSMOOTH
1 Like

Awesome, thanks!