Cross-staff slurs/ties trying to avoid note on wrong staff
P0 - Critical
S3 - Major
1) load attached score
Result as shown:
Bar two has the last note moved to the bottom staff using cross staff notations; bar three has the last note actually entered onto the bottom staff directly. Either way, creating a slur that ends on this note is showing an obviously wrong endpoint, far too high.
For the record, my current PR https://github.com/musescore/MuseScore/pull/4374 does not deal with this. Cause seems to be unrelated to the other cases.
I realize now it's not just cross-staff notation in the sense of notes moved from one staff to another with Ctrl+Shift+Up/Down, internally) - it's also slurs that connect notes on different staves with no cross-staff movement involved. So, it's not about checking staffMove() somewhere, it's about checking the vStaffIdx() probably, and adding in an offset I guess. I thought spanners were generally calculated relative to the system but it seems they are actually relative to the staff - maybe that was changed as part of the "new" layout?
Ties between cross-staff notes have the same issue.
Thinking a little more, I think we have a chicken-and-egg problem. Right now I assume we layout slurs before finalizing staff distance, because in fact the existence of slurs can increase staff distance. So at the point of slur layout, we don't know the relative position of staves.
So my thinking we is, if we detect a cross-staff slur or tie, we should disable autoplace (results would probably be disastrous anyhow) and somehow mark it as needing attention. Then do a second pass to fix up the cross-staff slurs and ties after we've finalized staff positions.
I still feel this would be very important to get right before release, but am not sure it makes sense for me to tackle that right now.
As an experiment, I tried to postpone cross-staff slurs layout to the moment after finishing Y placement of staves and made slur positions calculations take note staff into account (though I could miss something there). Sometimes the results are more or less sane:
... and sometimes even worse than they were before:
It seems that cross-staff slurs layout would require not only taking into correct notes positions into account but also some tweaks to automatic slur direction choosing and making autoplacement not so aggressive in moving slurs out of staves.
Thanks for looking, and indeed, I don't expect this to be trivial. Might need to pass on this for initial release, but who knows. But do note my pending PR regarding relative layout of articulations & slurs (https://github.com/musescore/MuseScore/pull/4411) which probably touches some of the same code. To me, the articulation is higher priority as it's likely to affect many more scores, even if the current results aren't as dramatically bad.
So I just realize "note anchored lines" (a little-known feature, can only be added from the Add menu, directly connects two notes) actually does work across staves. Badly at first in that when you try to add one by Ctrl+clicking two notes then using the menu, it adds above the top staff of the system regardless of what staves you are actually connecting. But, if you turn off autoplace, the line jumps right back down to where it belongs, and it does track changes in staff distance, so it's basically doing the right thing.
The line gets added as a TextLine apparently but is "owned" by the note, using Spanner::Anchor::NOTE (same anchor type used for ties). Hmm. Probably there is a solution here.
Note anchored lines are handled toward the end of the loop in collectPage() right after ties, but then again a few later as part of Measure::layout2(). Probably we don't need both and could lose the calls within collectPage() itself. I'm thinking it's Measure::layout2() that would be the sensible place to handle cross-staff slurs, but only if we can get cross-staff ties working too (well, "regular" ties but between cross-staff notes), so I'm trying that first.
EDIT: both of those calls are no-ops - they called tie->layout() which doesn't actually do anything. Real layout happens in layoutFor() an layoutBack(), which are called in layoutSystemElements(), somewhat later than slurs but still too soon.
Probably you are discovering similar things, but maybe that's helpful information. I think that's as far as I'm getting tonight.
In reply to Note anchored lines are… by Marc Sabatella
Is the line between notes possibly related to #278490: Lines placed above the top staff when single note selected.? The results there sound like they are affected in a similar manner.
Surprisingly, while the symptom is very similar (line display above top of system), the causes was totally different. But my PR for that issue fixes both.
No, sorry that was confusing. That PR fixes regular lines above top staff and again more lines above top staff even though cause we're very different. Cross staff slurs are not part of the PR.
We definitely must fix this issue, but it is too complex and too rare in common use cases. Workaround is to manually adjust the slurs position.
For the record, cross-staff notation in general and cross-staff slurs are not uncommon at all in piano music, but given the complexity of the issue and the risk involved with the sort of structural change that would probably be needed to fix this, I agree it is better to live with it for now.
Yes, it's not uncommon. Just stumbled upon this bug. Can you at least fix the position of the slur, when it is not cross-staff, but when all notes moved as a whole to the next staff? Here is an example from Clementi's Sonatina in G Major, Op. 36, No. 2.
Well, it's the same issue, when it's fixed for one case, it should be fixed for them all. There is work done on this but not yet ready.
In reply to Well, it's the same issue,… by Marc Sabatella
Ok, got it. I thought if the slur is within one staff, it's easier to solve. Can I help? I am good at composing clever math algorithms.
Thanks for the offer! You are of course welcome to participate in development however you like - MuseScore is open sour e, after all. See the Contribute menu above, then click Development.
I can say that this particular problem isn't much about math. But one that is is handling cases like a slur between three notes - middle line B, B an octave higher, then back to middle line B. We draw the slur too flat, so the endpoints end up too far from the start and end notes:
We use a bezier curve algorithm to draw the slur with no consideration to how curved it will actually need to be to clear the high B in the middle. I have ideas on how to improve the algorithm to draw a more curved slur in these cases, so we'd get something more like this:
But I am not confident on how to get the math right (hard to admit for a math major, but my specialty was abstract math, not applied...)
In reply to Thanks for the offer! You… by Marc Sabatella
Marc, I am talking about another problem. Or at least I don't understand how they are connected. See my Clementi example. When I move the notes to the lower staff (Ctrl+Shift+DownArrow), the slur remains completely at the top staff. It has nothing to do with the curvature of the slur, it's just painted in the wrong place completely. Should I file another bug for that?
I can help with the curvature math as well, of course. :)
Sorry for being confusing. I get these are different. I just meant, if you're looking to help, and your specialty is math, it's the curvature issue that we could use help with. The cross-staff slur problem I think we have something of a handle on, and it's not a math problem at all but one of the data structures and algorithms, so perhaps harder for a newcomer to the code to deal with anyhow.
Using the 3.0 stable version.
I think I found the origin of the problem. When I used click the start note then ctrl+click the note in the other staff, the anchor is set to be in the original staff. This is difficult to see, because the anchor point is not drawn while in edit mode. If you grab the endpoint that should be in the other staff, you will see it is still in the original staff.
I see no way to anchor the slur in the other staff. Using shift+up arrow should change the anchor to the other staff, but this does not work. The best you can hope for it to make it look right, and this is a deal breaker for the Blind user I'm trying to make this score for.
There is indeed no way to get this right currently. There has been some work to try to address this but I think it's not ready. Absolutely a very high priority.
In reply to There is indeed no way to… by Marc Sabatella
I am still trying to get started and set up the developing environment. Thus there is no help from me so far with the slur math. I don't like git with every piece of my soul and heart.
In reply to I am still trying to get… by Slava Andrejev
@Slava Andrejev, You need to start a thread in the development forum so people can help you there without adding a bunch of unrelated stuff to the issue at hand.
In reply to @Slava Andrejev, You need to… by mike320
I know. I just informed why I didn't help, while promised. It's not that I am asking questions here.
Related to #281511: [EPIC] Braille friendly musicxml export
Came up again in https://musescore.org/en/node/281550 and https://musescore.org/en/node/281549
Als in #282695: ties on cross-staff notes are placed in the wrong staff
Came up in https://musescore.org/en/node/284497
Relates to #285233: [EPIC] Cross-staff notation issues
I'm on it, close to a solution.
The following PR should fix things for both slurs and ties, both for cases where the notes themselves are cross-staff and when they are simply on different staves "for real". Ties work whether one or both notes are moved. It's not a big change, and shouldn't affect layout in any cases except cross-staff, except for fixing a small glitch with the layout of ties between enharmonic notes along the way.
Fixed in branch master, commit f1ccc25997
fix #279182: layout of cross-staff slurs and ties
Fixed in branch master, commit 8920c762e9
_Merge pull request #4817 from MarcSabatella/cross-staff-2
fix #279182: layout of cross-staff slurs and ties_
Automatically closed -- issue fixed for 2 weeks with no activity.