-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The #GreatAccidentalsReform #21042
The #GreatAccidentalsReform #21042
Conversation
Wow, quite the project! I look forward to checking out the results. I wanted to find my old test file based on Daniel Spreadbury's blog article https://blog.dorico.com/2014/03/development-diary-part-six, but unfortunately I can't seem to find the MSCZ file itself. I did find the results of one of my other tests from back then, and I'll be curious to compare: |
Disclaimer: don't get overexcited over any particular details. This is just me not resisting the urge to use the new cutouts and trying out stuff. |
LOVING THIS |
Fabulous progress @mike-spa! |
fa1f8d3
to
525a11a
Compare
dd89567
to
63f35fc
Compare
642a240
to
5777d2e
Compare
5777d2e
to
7bfe8d1
Compare
7bfe8d1
to
1ceb6a0
Compare
d5c2f0e
to
ec94049
Compare
|
||
m_spatium = accidental->spatium(); | ||
|
||
m_verticalAccidentalToAccidentalClearance = 0.15 * m_spatium; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
magic numbers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still actual
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how else should I write this? I'm just initializing constants that I will need later. Some of these constants have a style, others are hardcoded. Problem is I can't hardcode these as const
or constexpr
because they need to be constructed from other information when constructing AccidentalsLayoutContext
data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should specify (in a comment) how you found / why exactly you are using these constants
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This 0.15 (and other magic numbers) is used in a lot of different places in this PR. Worth adding a named constexpr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've removed all the magic numbers I had used around the file and collected them all here with proper names and a comment that explains that they are just engraving parameters that don't have a style. The fact that some of them have the same value (like 0.15) is just a coincidence, they actually all mean different things.
ecee97a
to
e1b8bb6
Compare
@RomanPudashkin done! 👍 |
{ | ||
std::vector<Accidental*> accidentals; | ||
|
||
for (Chord* chord : chords) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use const with pointers unless you are going to change their value
if (!acc) { | ||
continue; | ||
} | ||
acc->setPos(0.0, 0.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not ideal... This function not only collects accidentals but also changes some properties. Ideally, it should have only one responsibility (find and return accidentals)
verticallyAlignAccidentals(ctx); | ||
} | ||
|
||
void AccidentalsLayout::findOctaves(AccidentalsLayoutContext& ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this code will be called quite often, it is probably better to combine this function with findSeconds. This way, we will reduce the complexity of the algorithm
firstGroup.push_back(ctx.allAccidentals.front()); | ||
ctx.accidentalSubChords.push_back(firstGroup); | ||
|
||
for (int i = 1; i < ctx.allAccidentals.size(); ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will generate a warning as size() returns size_t
TLayout::layoutAccidental(acc, acc->mutldata(), ctx.conf()); | ||
} | ||
|
||
AccidentalsLayoutContext accidentalsLayoutContext(allAccidentals, chords); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to use std::move with allAccidentals to avoid creating a copy (the AccidentalsLayoutContext constructor also needs to be adjusted)
void AccidentalsLayout::mergeSubGroupsWithOctavesAcross(AccidentalsLayoutContext& ctx) | ||
{ | ||
bool foundOctave = false; | ||
do { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what's going on in this function, but it's very complex (5 nested loops + lots of operations on std::vector). Is there any way to simplify/optimize it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved out some code to make it more readable, but unfortunately I can't think of any way to simplify this. These are very gnarly engraving requirements resulting in very gnarly code logic. Luckily this function (and the next one that you pointed out) is used rarely so it shouldn't impact performance
applyOrderingOffsets(accidentals); | ||
} | ||
|
||
std::vector<std::vector<Accidental*> > AccidentalsLayout::splitIntoPriorityGroups |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to add an alias for this type
void AccidentalsLayout::moveOctavesToSecondGroup(std::vector<std::vector<Accidental*> >& subGroups) | ||
{ | ||
std::vector<Accidental*>& firstGroup = subGroups[0]; | ||
std::vector<Accidental*>& secondGroup = subGroups[1]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like std::array might be a better type for subGroups
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one particular case (with conditions defined by the caller), but in general subGroups may have different sizes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worth adding this
IF_ASSERT_FAILED(subGroups.size() == 2) {
return;
}
return 0.0; | ||
} | ||
|
||
double AccidentalsLayout::computePadding(Accidental* acc, const EngravingItem* chordElement, AccidentalsLayoutContext& ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const AccidentalsLayoutContext&
AccidentalType accType = acc->accidentalType(); | ||
if (chordItem->isLedgerLine() && (accType == AccidentalType::NATURAL || accType == AccidentalType::SHARP)) { | ||
if (chordItem->y() > accShape.top() && chordItem->y() < accShape.bottom()) { | ||
return accShape.right() - chordElement.left() + 0.1 * ctx.spatium(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0.1?
for (int j = 0; j < thisGroup.size(); ++j) { | ||
Accidental* acc1 = thisGroup[j]; | ||
for (Accidental* secondAcc : acc1->ldata()->seconds.value()) { | ||
if (muse::remove(nextGroup, secondAcc)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same question. remove() isn't very efficient with std::vector
adc9a8a
to
6e0f341
Compare
@RomanPudashkin done! 👍 |
TLayout::layoutAccidental(acc, acc->mutldata(), ctx.conf()); | ||
} | ||
|
||
AccidentalsLayoutContext accidentalsLayoutContext(std::move(allAccidentals), std::move(chords)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::move(chords) - this has no effect as chords is const std::vector<Chord*>& :)
return subGroups; | ||
} | ||
|
||
AccidentalGroups AccidentalsLayout::groupAccidentalsByNoteXPos(std::vector<Accidental*>& accidentals) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This vector should be const
6e0f341
to
f27403f
Compare
f27403f
to
f074b44
Compare
Resolves: #9302
A complete rewrite of the accidental placement algorithms, making good use of the recently introduced accidental cutouts. Basically see the vtests.