# HG changeset patch # User Chris Cannam # Date 1480068532 0 # Node ID 3cde25cbe7f8d04de0b3668463b98f2b796247d1 # Parent fa574c909c3db7dc9ef6f2294e100315553b0498# Parent 114de081a42d894400dbdcf4945d578b4c7dc8a3 Merge from branch subdivide-instants diff -r fa574c909c3d -r 3cde25cbe7f8 data/model/Labeller.h --- a/data/model/Labeller.h Thu Nov 24 17:06:31 2016 +0000 +++ b/data/model/Labeller.h Fri Nov 25 10:08:52 2016 +0000 @@ -171,37 +171,35 @@ } } + /** + * Relabel all points in the given model that lie within the given + * multi-selection, according to the labelling properties of this + * labeller. Return a command that has been executed but not yet + * added to the history. + */ template - void labelAll(SparseModel &model, MultiSelection *ms) { + Command *labelAll(SparseModel &model, MultiSelection *ms) { - typename SparseModel::PointList::iterator i; - typename SparseModel::PointList pl(model.getPoints()); - - typename SparseModel::EditCommand *command = - new typename SparseModel::EditCommand + auto points(model.getPoints()); + auto command = new typename SparseModel::EditCommand (&model, tr("Label Points")); PointType prevPoint(0); + bool havePrevPoint(false); - for (i = pl.begin(); i != pl.end(); ++i) { + for (auto p: points) { - bool inRange = true; if (ms) { - Selection s(ms->getContainingSelection(i->frame, false)); - if (s.isEmpty() || !s.contains(i->frame)) { - inRange = false; + Selection s(ms->getContainingSelection(p.frame, false)); + if (!s.contains(p.frame)) { + prevPoint = p; + havePrevPoint = true; + continue; } } - PointType p(*i); - - if (!inRange) { - prevPoint = p; - continue; - } - if (actingOnPrevPoint()) { - if (i != pl.begin()) { + if (havePrevPoint) { command->deletePoint(prevPoint); label(p, &prevPoint); command->addPoint(prevPoint); @@ -213,9 +211,94 @@ } prevPoint = p; + havePrevPoint = true; } - command->finish(); + return command->finish(); + } + + /** + * For each point in the given model (except the last), if that + * point lies within the given multi-selection, add n-1 new points + * at equally spaced intervals between it and the following point. + * Return a command that has been executed but not yet added to + * the history. + */ + template + Command *subdivide(SparseModel &model, MultiSelection *ms, int n) { + + auto points(model.getPoints()); + auto command = new typename SparseModel::EditCommand + (&model, tr("Subdivide Points")); + + for (auto i = points.begin(); i != points.end(); ++i) { + + auto j = i; + // require a "next point" even if it's not in selection + if (++j == points.end()) { + break; + } + + if (ms) { + Selection s(ms->getContainingSelection(i->frame, false)); + if (!s.contains(i->frame)) { + continue; + } + } + + PointType p(*i); + PointType nextP(*j); + + // n is the number of subdivisions, so we add n-1 new + // points equally spaced between p and nextP + + for (int m = 1; m < n; ++m) { + sv_frame_t f = p.frame + (m * (nextP.frame - p.frame)) / n; + PointType newPoint(p); + newPoint.frame = f; + newPoint.label = tr("%1.%2").arg(p.label).arg(m+1); + command->addPoint(newPoint); + } + } + + return command->finish(); + } + + /** + * Return a command that has been executed but not yet added to + * the history. + */ + template + Command *winnow(SparseModel &model, MultiSelection *ms, int n) { + + auto points(model.getPoints()); + auto command = new typename SparseModel::EditCommand + (&model, tr("Winnow Points")); + + int counter = 0; + + for (auto p: points) { + + if (ms) { + Selection s(ms->getContainingSelection(p.frame, false)); + if (!s.contains(p.frame)) { + counter = 0; + continue; + } + } + + ++counter; + + if (counter == n+1) counter = 1; + if (counter == 1) { + // this is an Nth instant, don't remove it + continue; + } + + command->deletePoint(p); + } + + return command->finish(); } template