Converting B-Spline Cages to Bezier

I was interested in making a filter / reporter plugin to view and convert B-spline/NURBS cages (which would be drawn with line nodes then converted) to exportable bezier paths.

But I noticed the API has a mention of decomposeSuperBezierSegment() and a quadratic counterpart which seems like what I’m actually looking for, but I can’t seem to find decomposeSuperBezierSegment anywhere else. I take this to mean it’s not in the public API. Am I missing something in how this is supposed to be used?

Ultimately my question is whether I should continue working on a B-spline to bezier converter, or if decomposeSuperBezierSegment is / will be available.

Can you post a mockup/sample? Not quite sure I understand what you want to do with that method.

Sure, so for example you could have an o with this awful looking outline:

Figure 1: caged path

and convert it to quadratic curves with a script:

Figure 2: quadratic curves with offcurve-only nodes

So far this is all with native Glyphs rendering, but Glyphs seems to hang when I try to export curves like this to TTF (or crash when exported to OTF), and for the purposes of this, I’m looking at using cubic interpolation instead of quadratic. I think cubic interpolation would look something like this:

Figure 3: cubic representation of cage from Figure 1

So I was going to make a script that takes that original cage in Figure 1 and converts it to exportable cubic bezier curves similar to the form in Figure 3. (with Böhm’s algorithm I’m assuming (see section 6.3))

But I stumbled across the mention of decomposeSuperBezierSegment() and wondered if I could avoid the math of using Böhm’s algorithm and just convert a cage like Figure 1 into offcurve nodes as seen in Figure 2 and then decompose Figure 2’s curves into cubic bezier curves. But I don’t know what decomposeSuperBezierSegment actually does so I can’t even say i’m on the right track here :slight_smile:

Why Filter / Reporter?

The reason I thought to utilize a filter / reporter and have the cage built with line-type nodes as in Figure 1 is because the current toolset doesn’t seem to fully support offcurve-only path editing with paths (like in Figure 2), whereas the usual node drawing / editing tools in glyphs are great. Some oddities are:

  • insertNodeWithPathTime() seems to require one or two on-curve nodes, and disregards offcurve nodes in its calculations of path time
  • deleting offcurve nodes sometimes deletes the entire path
  • slice and measure tools don’t work with offcurve paths (though measure wouldn’t exactly work well with a caged path either, since the cage doesn’t REALLY represent the final path)

So with this filter and reporter, I could get the ability to edit paths as usual while the reporter will give a preview of what the result will look like after the filter is applied.

Let me know if this is still unclear or if I’m misunderstanding something.

That is not actually implemented. It is a leftover from some old code.
I fear you need to implement that yourself.

This is a very specific method that you shouldn’t use for this kind of thing. It is mostly useful in combination with the method nearestPointOnPath_pathTime_.

How did you delete the node? Manually or from a script?

The support for TrueType curves is very rudimentary. Thats why it is not documented and advertised. I see what I can do. For now, you can quite easily convert it to cubic beziers instead.

Shouldn’t be the inner cage made of 8 nodes, as the outer one is? You are creating 2 similar shapes (simple ovals in this case) with different cage node structure. Maybe this is one more thing to consider?!

I’ll try to keep that in mind. I’ve been using it in other places to insert/find midpoints along a path (especially curved paths). Is there another path or path segment method I should be using for things like this?

By selecting and backspace key. Test case:

Deleting more than one node in the selection will delete the whole path. Deleting just one node seems to work fine, though!

Probably! :slight_smile:

Can you send me that glyph?

You can use it for that. Please note that the integer part of the pathTime is the index of the node at the end of the segment, not the segment index.