Cabbage Logo
Back to Cabbage Site

Bézier Curves for Gentables

Sure. There’s no hurry for this. I’m very grateful that you are willing to actually spend any time on this idea at all!

I had to multiply p4 by -1 as Victor suggested. I also fixed a serious bug. It still doesn’t do error-checking and also I need to comment it. But -unless you find a bug- the syntax and the functionality should stay the same. I’m still not sure if control points should be allowed to overlap the regular points in Cabbage. Later on we should decide about that.

quadbezier_1.zip (1.5 KB)

I tried using a quadbezier table with gentable and the good news is that drawVerticalLine() seems to work fine.

One potential issue I see is the fact that control points can be outside the the Y-bounds of the envelope. If scaling is turned off then this should be fine. I guess as Csound will normalise the contents of the table for us.

Yes, rescaling is always off. That’s why Victor asked me to multiply p4 by -1. The only way you could get a normalized quadbezier is if you call the routine by the corresponding number assigned to plugins by Csound (gen 65 in my machine). Even then, you’d have to call it as -65 to reverse the multiplication. Weird thing is that negative gen number means rescaling for quadbezier!

I think that in order to get the maximum height you should check for the greatest number in the arguments, i.e. y1,cy1,y2… That should work, shouldn’t it?

Yeah. That should work.

I started implementing this earlier, but had to return to life duties after an hour or so! You’ll see that once I detect a quadbezier table I set the gen routine to 999. I did this so I can continue to query gen numbers rather than strings further down the line. I’ve also put in some place holders in table.cpp for places that need bezier attention. When I had to leave it I was at the point of generating the handles for the table here:

https://github.com/rorywalsh/cabbage/blob/develop/Source/Table.cpp#L867-L880

But the handles are not appearing in the correct place. I’m sure it’s something simple. Just remember to use the active(1) identifier with the table to display the handles. I’m just letting you know in case you want to follow developments, or have a go at it yourself :wink: Although every time I go over old code I’m shocked at how I’ve over complicated things!

[edit] I’m not finding te correct range of values in the table…just spotted that now…

I created a new branch to work on this. There are a lot of things to do! But it kind of works (https://github.com/gsenna/cabbage/tree/feature-quadbezier).

Some issues and other things to do:

  1. SetWaveform() takes an Array of floats to determine MinMax. This won’t work because a CtrlPoint could have a higher y-value. This is the case of my test file inside Build/Linux. Should we overload that function specially for Quadbezier?
  2. You were not getting the correct values mainly because normalised was > 0. I just removed the conditional. Do we need that? quadbezier tables are not supposed to be rescaled anyway.
  3. We may need a way to set the Colour for Control Handles (I set them to blue in my fork). It would be nice to have dotted lines that connect these handles with the regular ones. Every graphic editor that implements bezier curves seems to do this.
  4. It would be nice to be able to change the colour of the CtrlPoint handle to some other colour when you create a straight line between two regular Handles. This way quadbezier=gen05+gen07.
  5. Adding and deleting handles with the mouse doesn’t work.

There was another thing but I can’t remember what it was. Anyway, it is very rewarding to see this (almost) working. I can’t believe that trick with the quadratic equation works. lol.

Great work. I’ll check it in the morning. I just added you up as a collaborator to Cabbage. If you accept the email link I have a new bezier branch set up. Maybe you can pull that, add your changes and push future ones directly to that rather than a fork. I’m happy to have people help out :wink:

1 Like

I’ve made a commit with the changes and also found a bug. Sometimes the new Csound functions return 0 instead of the gen routine number. I don’t know why yet. We may need to store that number instead of making a call on each mouse drag.

I just had a chance to try it now and it works great. I did hit an assertion but hey, that’s bound to happen until everything is ironed out. Whee about are you getting the problems? In which function? I’m amazed at how efficiently the table redraws using the hfgens() method. While I was implementing this the first time I thought it would be nice to expose all those gen routines as an API. As it stands they are kind of buried pretty deep into the Csound source.

Pushed some new changes. The problem was on updatefTableData(). Apparently you can’t call CsoundGetTableArgs so often (mouse drag). I solved it by creating a new isQuadbezier function that is called only once at InsertGenTable(). It shouldn’t crash anymore and I hope I didn’t screw anything else.

If someone creates a new named gen routine we should think of another strategy.

The next thing to fix should be the setWaveform() issue. MinMax in quadbezier tables can be in one of the control points, but the whole thing is prepared to look for inside the table values.

Great. I really am sorry that I can’t offer more assistance on this at the moment but you seem to be flying through it!

Yeah, but that’s because I’m taking some shortcuts. We’ll probably have to redo it some day.

What do you think of something like this? I had to override the virtual paint function inside HandleViewer. Do you think that’s fine? I’ll probably need to add a bool too to check whether it’s a quadbezier gentable or not.

EDIT: Fixed some things with the latest commit.

Looks great. I don’t think it’s a problem to override that method. You’re not doing any filling so it shouldn’t have an effect on other tables. You may check how it looks when using tables which are stacked on top of each other.

This is the second incarnation of a table editor for Cabbage. Please feel free to push it to the limits. No doubt we will need to rewrite it at some point in the future!

It may be a while before the next release of Csound which means users will not be able to try this out. Or we could add your opcode source to Cabbage and use one of the API load opcode functions to load the opcode on start up. That should work fine and give users access to the new feature straight away.

We could try this when the code is ready.

I’ve coded a new opcode called getfargs. It works at init-time, but I think I’ll change it to work with k-variables instead. My idea is to have invisible texteditors in Cabbage and replace their text() with the table arguments. That way .snaps will save the data.

getfargs.zip (620 Bytes)

Sounds good. Most table opcodes in Csound use ft(function table) rather than just an f, so perhaps getftargs might be a better fit? Do we also need an opcode that will automatically create a table based on an arg string?

I’ll change it. I think we can use scoreline to create the table. Or are you thinking about something else?

True, I’d forgotten about that. That should do the trick nicely.

I did some work today on the develop branch, but it should be pretty simple to merge your changes. I can prepare a Windows versions that can make use of Victor’s latest API methods, but not for OSX. On Linux it’s not really a problem as building there is not that tricky. OSX is not too hard but I’m happy to keep using Victor’s packages. He does some linking when he’s building that I’ve no interest in emulating. But, he has offered to run off an OSX build from the latest Csound source for another project I’m involved in, so that will give us up to date builds for both Windows and OSX. Once you’re happy that everything is working Ok I’m glad to merge the changes.

I think you can merge right now because the basic functionality is already there. I’m somewhat busy at the moment so I’ll be wrapping it up in small chunks whenever I have some free time. I hope I didn’t break anything!

The things that are missing or not working are:

  • Maybe, a way to set the color of CtrlPoints and straight line CtrlPoints from inside the .csd. Right now I’m picking it automatically like this:
    handles[i]->setColour(colour.withRotatedHue(0.3f)); // Straight lines CtrlPoints.
  • The method for figuring out if a straight line has been formed is accurate but not perfect.
  • The popup that shows the coordinates when you position the mouse over a point is not displaying the right data.
  • The “quadbezier” gen routine needs an error-handling function.
  • The getftargs opcode would be better as a k-rate opcode and I mostly guessed how to write it. I’ll probably have to ask in the developer’s list if I’m not breaking anything.

The only thing to note if you merge is that people in Linux will have to build Csound-develop in order to build Cabbage-develop because -at least in Ubuntu- the official packages for Csound are old. (what happened to @Codesound).

I’ll try merging and see how it goes. I might wrap the new API calls in an #ifdef for now so that people don’t have to upgrade to build from the dev branch. We can continue to work on it in the meantime, but can remove the bezier branch.