comparison layer/RegionLayer.cpp @ 946:36cddc3de023 alignment_view

Merge from default branch
author Chris Cannam
date Mon, 20 Apr 2015 09:19:52 +0100
parents 251dd0abc7b7
children 94e4952a6774 3871dffc31bd
comparison
equal deleted inserted replaced
897:499b637f2a26 946:36cddc3de023
273 // SVDEBUG << "RegionLayer::recalcSpacing: " << i->first << " -> " << m_spacingMap[i->first] << endl; 273 // SVDEBUG << "RegionLayer::recalcSpacing: " << i->first << " -> " << m_spacingMap[i->first] << endl;
274 } 274 }
275 } 275 }
276 276
277 bool 277 bool
278 RegionLayer::getValueExtents(float &min, float &max, 278 RegionLayer::getValueExtents(double &min, double &max,
279 bool &logarithmic, QString &unit) const 279 bool &logarithmic, QString &unit) const
280 { 280 {
281 if (!m_model) return false; 281 if (!m_model) return false;
282 min = m_model->getValueMinimum(); 282 min = m_model->getValueMinimum();
283 max = m_model->getValueMaximum(); 283 max = m_model->getValueMaximum();
287 287
288 return true; 288 return true;
289 } 289 }
290 290
291 bool 291 bool
292 RegionLayer::getDisplayExtents(float &min, float &max) const 292 RegionLayer::getDisplayExtents(double &min, double &max) const
293 { 293 {
294 if (!m_model || 294 if (!m_model ||
295 m_verticalScale == AutoAlignScale || 295 m_verticalScale == AutoAlignScale ||
296 m_verticalScale == EqualSpaced) return false; 296 m_verticalScale == EqualSpaced) return false;
297 297
369 369
370 return true; 370 return true;
371 } 371 }
372 372
373 QString 373 QString
374 RegionLayer::getLabelPreceding(int frame) const 374 RegionLayer::getLabelPreceding(sv_frame_t frame) const
375 { 375 {
376 if (!m_model) return ""; 376 if (!m_model) return "";
377 RegionModel::PointList points = m_model->getPreviousPoints(frame); 377 RegionModel::PointList points = m_model->getPreviousPoints(frame);
378 for (RegionModel::PointList::const_iterator i = points.begin(); 378 for (RegionModel::PointList::const_iterator i = points.begin();
379 i != points.end(); ++i) { 379 i != points.end(); ++i) {
451 getYForValue(v, region.value)); 451 getYForValue(v, region.value));
452 return text; 452 return text;
453 } 453 }
454 454
455 bool 455 bool
456 RegionLayer::snapToFeatureFrame(View *v, int &frame, 456 RegionLayer::snapToFeatureFrame(View *v, sv_frame_t &frame,
457 int &resolution, 457 int &resolution,
458 SnapType snap) const 458 SnapType snap) const
459 { 459 {
460 if (!m_model) { 460 if (!m_model) {
461 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 461 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
471 frame = points.begin()->frame; 471 frame = points.begin()->frame;
472 return true; 472 return true;
473 } 473 }
474 474
475 points = m_model->getPoints(frame, frame); 475 points = m_model->getPoints(frame, frame);
476 int snapped = frame; 476 sv_frame_t snapped = frame;
477 bool found = false; 477 bool found = false;
478 478
479 for (RegionModel::PointList::const_iterator i = points.begin(); 479 for (RegionModel::PointList::const_iterator i = points.begin();
480 i != points.end(); ++i) { 480 i != points.end(); ++i) {
481 481
534 frame = snapped; 534 frame = snapped;
535 return found; 535 return found;
536 } 536 }
537 537
538 bool 538 bool
539 RegionLayer::snapToSimilarFeature(View *v, int &frame, 539 RegionLayer::snapToSimilarFeature(View *v, sv_frame_t &frame,
540 int &resolution, 540 int &resolution,
541 SnapType snap) const 541 SnapType snap) const
542 { 542 {
543 if (!m_model) { 543 if (!m_model) {
544 return Layer::snapToSimilarFeature(v, frame, resolution, snap); 544 return Layer::snapToSimilarFeature(v, frame, resolution, snap);
549 const RegionModel::PointList &points = m_model->getPoints(); 549 const RegionModel::PointList &points = m_model->getPoints();
550 RegionModel::PointList close = m_model->getPoints(frame, frame); 550 RegionModel::PointList close = m_model->getPoints(frame, frame);
551 551
552 RegionModel::PointList::const_iterator i; 552 RegionModel::PointList::const_iterator i;
553 553
554 int matchframe = frame; 554 sv_frame_t matchframe = frame;
555 float matchvalue = 0.f; 555 double matchvalue = 0.f;
556 556
557 for (i = close.begin(); i != close.end(); ++i) { 557 for (i = close.begin(); i != close.end(); ++i) {
558 if (i->frame > frame) break; 558 if (i->frame > frame) break;
559 matchvalue = i->value; 559 matchvalue = i->value;
560 matchframe = i->frame; 560 matchframe = i->frame;
561 } 561 }
562 562
563 int snapped = frame; 563 sv_frame_t snapped = frame;
564 bool found = false; 564 bool found = false;
565 bool distant = false; 565 bool distant = false;
566 float epsilon = 0.0001; 566 double epsilon = 0.0001;
567 567
568 i = close.begin(); 568 i = close.begin();
569 569
570 // Scan through the close points first, then the more distant ones 570 // Scan through the close points first, then the more distant ones
571 // if no suitable close one is found. So the while-termination 571 // if no suitable close one is found. So the while-termination
586 } 586 }
587 587
588 if (snap == SnapRight) { 588 if (snap == SnapRight) {
589 589
590 if (i->frame > matchframe && 590 if (i->frame > matchframe &&
591 fabsf(i->value - matchvalue) < epsilon) { 591 fabs(i->value - matchvalue) < epsilon) {
592 snapped = i->frame; 592 snapped = i->frame;
593 found = true; 593 found = true;
594 break; 594 break;
595 } 595 }
596 596
597 } else if (snap == SnapLeft) { 597 } else if (snap == SnapLeft) {
598 598
599 if (i->frame < matchframe) { 599 if (i->frame < matchframe) {
600 if (fabsf(i->value - matchvalue) < epsilon) { 600 if (fabs(i->value - matchvalue) < epsilon) {
601 snapped = i->frame; 601 snapped = i->frame;
602 found = true; // don't break, as the next may be better 602 found = true; // don't break, as the next may be better
603 } 603 }
604 } else if (found || distant) { 604 } else if (found || distant) {
605 break; 605 break;
622 if (m_model) return m_model->getScaleUnits(); 622 if (m_model) return m_model->getScaleUnits();
623 else return ""; 623 else return "";
624 } 624 }
625 625
626 void 626 void
627 RegionLayer::getScaleExtents(View *v, float &min, float &max, bool &log) const 627 RegionLayer::getScaleExtents(View *v, double &min, double &max, bool &log) const
628 { 628 {
629 min = 0.0; 629 min = 0.0;
630 max = 0.0; 630 max = 0.0;
631 log = false; 631 log = false;
632 632
677 677
678 int 678 int
679 RegionLayer::spacingIndexToY(View *v, int i) const 679 RegionLayer::spacingIndexToY(View *v, int i) const
680 { 680 {
681 int h = v->height(); 681 int h = v->height();
682 int n = m_spacingMap.size(); 682 int n = int(m_spacingMap.size());
683 // this maps from i (spacing of the value from the spacing 683 // this maps from i (spacing of the value from the spacing
684 // map) and n (number of region types) to y 684 // map) and n (number of region types) to y
685 int y = h - (((h * i) / n) + (h / (2 * n))); 685 int y = h - (((h * i) / n) + (h / (2 * n)));
686 return y; 686 return y;
687 } 687 }
688 688
689 float 689 double
690 RegionLayer::yToSpacingIndex(View *v, int y) const 690 RegionLayer::yToSpacingIndex(View *v, int y) const
691 { 691 {
692 // we return an inexact result here (float rather than int) 692 // we return an inexact result here (double rather than int)
693 int h = v->height(); 693 int h = v->height();
694 int n = m_spacingMap.size(); 694 int n = int(m_spacingMap.size());
695 // from y = h - ((h * i) / n) + (h / (2 * n)) as above (vh taking place of i) 695 // from y = h - ((h * i) / n) + (h / (2 * n)) as above (vh taking place of i)
696 float vh = float(2*h*n - h - 2*n*y) / float(2*h); 696 double vh = double(2*h*n - h - 2*n*y) / double(2*h);
697 return vh; 697 return vh;
698 } 698 }
699 699
700 int 700 int
701 RegionLayer::getYForValue(View *v, float val) const 701 RegionLayer::getYForValue(View *v, double val) const
702 { 702 {
703 float min = 0.0, max = 0.0; 703 double min = 0.0, max = 0.0;
704 bool logarithmic = false; 704 bool logarithmic = false;
705 int h = v->height(); 705 int h = v->height();
706 706
707 if (m_verticalScale == EqualSpaced) { 707 if (m_verticalScale == EqualSpaced) {
708 708
730 730
731 return int(h - ((val - min) * h) / (max - min)); 731 return int(h - ((val - min) * h) / (max - min));
732 } 732 }
733 } 733 }
734 734
735 float 735 double
736 RegionLayer::getValueForY(View *v, int y) const 736 RegionLayer::getValueForY(View *v, int y) const
737 { 737 {
738 return getValueForY(v, y, -1); 738 return getValueForY(v, y, -1);
739 } 739 }
740 740
741 float 741 double
742 RegionLayer::getValueForY(View *v, int y, int avoid) const 742 RegionLayer::getValueForY(View *v, int y, int avoid) const
743 { 743 {
744 float min = 0.0, max = 0.0; 744 double min = 0.0, max = 0.0;
745 bool logarithmic = false; 745 bool logarithmic = false;
746 int h = v->height(); 746 int h = v->height();
747 747
748 if (m_verticalScale == EqualSpaced) { 748 if (m_verticalScale == EqualSpaced) {
749 749
755 755
756 // n is the number of distinct regions. if we are close to 756 // n is the number of distinct regions. if we are close to
757 // one of the m/n divisions in the y scale, we should snap to 757 // one of the m/n divisions in the y scale, we should snap to
758 // the value of the mth region. 758 // the value of the mth region.
759 759
760 float vh = yToSpacingIndex(v, y); 760 double vh = yToSpacingIndex(v, y);
761 761
762 // spacings in the map are integral, so find the closest one, 762 // spacings in the map are integral, so find the closest one,
763 // map it back to its y coordinate, and see how far we are 763 // map it back to its y coordinate, and see how far we are
764 // from it 764 // from it
765 765
766 int n = m_spacingMap.size(); 766 int n = int(m_spacingMap.size());
767 int ivh = lrintf(vh); 767 int ivh = int(lrint(vh));
768 if (ivh < 0) ivh = 0; 768 if (ivh < 0) ivh = 0;
769 if (ivh > n-1) ivh = n-1; 769 if (ivh > n-1) ivh = n-1;
770 int iy = spacingIndexToY(v, ivh); 770 int iy = spacingIndexToY(v, ivh);
771 771
772 int dist = iy - y; 772 int dist = iy - y;
781 } 781 }
782 if (i == m_spacingMap.end()) i = m_spacingMap.begin(); 782 if (i == m_spacingMap.end()) i = m_spacingMap.begin();
783 783
784 // cerr << "nearest existing value = " << i->first << " at " << iy << endl; 784 // cerr << "nearest existing value = " << i->first << " at " << iy << endl;
785 785
786 float val = 0; 786 double val = 0;
787 787
788 // cerr << "note: avoid = " << avoid << ", i->second = " << i->second << endl; 788 // cerr << "note: avoid = " << avoid << ", i->second = " << i->second << endl;
789 789
790 if (dist < -gap/3 && 790 if (dist < -gap/3 &&
791 ((avoid == -1) || 791 ((avoid == -1) ||
823 823
824 } else { 824 } else {
825 825
826 getScaleExtents(v, min, max, logarithmic); 826 getScaleExtents(v, min, max, logarithmic);
827 827
828 float val = min + (float(h - y) * float(max - min)) / h; 828 double val = min + (double(h - y) * double(max - min)) / h;
829 829
830 if (logarithmic) { 830 if (logarithmic) {
831 val = powf(10.f, val); 831 val = pow(10.0, val);
832 } 832 }
833 833
834 return val; 834 return val;
835 } 835 }
836 } 836 }
837 837
838 QColor 838 QColor
839 RegionLayer::getColourForValue(View *v, float val) const 839 RegionLayer::getColourForValue(View *v, double val) const
840 { 840 {
841 float min, max; 841 double min, max;
842 bool log; 842 bool log;
843 getScaleExtents(v, min, max, log); 843 getScaleExtents(v, min, max, log);
844 844
845 if (min > max) std::swap(min, max); 845 if (min > max) std::swap(min, max);
846 if (max == min) max = min + 1; 846 if (max == min) max = min + 1;
868 void 868 void
869 RegionLayer::paint(View *v, QPainter &paint, QRect rect) const 869 RegionLayer::paint(View *v, QPainter &paint, QRect rect) const
870 { 870 {
871 if (!m_model || !m_model->isOK()) return; 871 if (!m_model || !m_model->isOK()) return;
872 872
873 int sampleRate = m_model->getSampleRate(); 873 sv_samplerate_t sampleRate = m_model->getSampleRate();
874 if (!sampleRate) return; 874 if (!sampleRate) return;
875 875
876 // Profiler profiler("RegionLayer::paint", true); 876 // Profiler profiler("RegionLayer::paint", true);
877 877
878 int x0 = rect.left() - 40, x1 = rect.right(); 878 int x0 = rect.left() - 40, x1 = rect.right();
879 long frame0 = v->getFrameForX(x0); 879 sv_frame_t frame0 = v->getFrameForX(x0);
880 long frame1 = v->getFrameForX(x1); 880 sv_frame_t frame1 = v->getFrameForX(x1);
881 881
882 RegionModel::PointList points(m_model->getPoints(frame0, frame1)); 882 RegionModel::PointList points(m_model->getPoints(frame0, frame1));
883 if (points.empty()) return; 883 if (points.empty()) return;
884 884
885 paint.setPen(getBaseQColor()); 885 paint.setPen(getBaseQColor());
888 brushColour.setAlpha(80); 888 brushColour.setAlpha(80);
889 889
890 // SVDEBUG << "RegionLayer::paint: resolution is " 890 // SVDEBUG << "RegionLayer::paint: resolution is "
891 // << m_model->getResolution() << " frames" << endl; 891 // << m_model->getResolution() << " frames" << endl;
892 892
893 float min = m_model->getValueMinimum(); 893 double min = m_model->getValueMinimum();
894 float max = m_model->getValueMaximum(); 894 double max = m_model->getValueMaximum();
895 if (max == min) max = min + 1.0; 895 if (max == min) max = min + 1.0;
896 896
897 QPoint localPos; 897 QPoint localPos;
898 RegionModel::Point illuminatePoint(0); 898 RegionModel::Point illuminatePoint(0);
899 bool shouldIlluminate = false; 899 bool shouldIlluminate = false;
1081 RegionLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const 1081 RegionLayer::paintVerticalScale(View *v, bool, QPainter &paint, QRect) const
1082 { 1082 {
1083 if (!m_model || m_model->getPoints().empty()) return; 1083 if (!m_model || m_model->getPoints().empty()) return;
1084 1084
1085 QString unit; 1085 QString unit;
1086 float min, max; 1086 double min, max;
1087 bool logarithmic; 1087 bool logarithmic;
1088 1088
1089 int w = getVerticalScaleWidth(v, false, paint); 1089 int w = getVerticalScaleWidth(v, false, paint);
1090 1090
1091 if (m_plotStyle == PlotSegmentation) { 1091 if (m_plotStyle == PlotSegmentation) {
1127 1127
1128 long frame = v->getFrameForX(e->x()); 1128 long frame = v->getFrameForX(e->x());
1129 if (frame < 0) frame = 0; 1129 if (frame < 0) frame = 0;
1130 frame = frame / m_model->getResolution() * m_model->getResolution(); 1130 frame = frame / m_model->getResolution() * m_model->getResolution();
1131 1131
1132 float value = getValueForY(v, e->y()); 1132 double value = getValueForY(v, e->y());
1133 1133
1134 m_editingPoint = RegionModel::Point(frame, value, 0, ""); 1134 m_editingPoint = RegionModel::Point(frame, float(value), 0, "");
1135 m_originalPoint = m_editingPoint; 1135 m_originalPoint = m_editingPoint;
1136 1136
1137 if (m_editingCommand) finish(m_editingCommand); 1137 if (m_editingCommand) finish(m_editingCommand);
1138 m_editingCommand = new RegionModel::EditCommand(m_model, 1138 m_editingCommand = new RegionModel::EditCommand(m_model,
1139 tr("Draw Region")); 1139 tr("Draw Region"));
1147 void 1147 void
1148 RegionLayer::drawDrag(View *v, QMouseEvent *e) 1148 RegionLayer::drawDrag(View *v, QMouseEvent *e)
1149 { 1149 {
1150 if (!m_model || !m_editing) return; 1150 if (!m_model || !m_editing) return;
1151 1151
1152 long frame = v->getFrameForX(e->x()); 1152 sv_frame_t frame = v->getFrameForX(e->x());
1153 if (frame < 0) frame = 0; 1153 if (frame < 0) frame = 0;
1154 frame = frame / m_model->getResolution() * m_model->getResolution(); 1154 frame = frame / m_model->getResolution() * m_model->getResolution();
1155 1155
1156 float newValue = m_editingPoint.value; 1156 double newValue = m_editingPoint.value;
1157 if (m_verticalScale != EqualSpaced) newValue = getValueForY(v, e->y()); 1157 if (m_verticalScale != EqualSpaced) newValue = getValueForY(v, e->y());
1158 1158
1159 long newFrame = m_editingPoint.frame; 1159 sv_frame_t newFrame = m_editingPoint.frame;
1160 long newDuration = frame - newFrame; 1160 sv_frame_t newDuration = frame - newFrame;
1161 if (newDuration < 0) { 1161 if (newDuration < 0) {
1162 newFrame = frame; 1162 newFrame = frame;
1163 newDuration = -newDuration; 1163 newDuration = -newDuration;
1164 } else if (newDuration == 0) { 1164 } else if (newDuration == 0) {
1165 newDuration = 1; 1165 newDuration = 1;
1166 } 1166 }
1167 1167
1168 m_editingCommand->deletePoint(m_editingPoint); 1168 m_editingCommand->deletePoint(m_editingPoint);
1169 m_editingPoint.frame = newFrame; 1169 m_editingPoint.frame = newFrame;
1170 m_editingPoint.value = newValue; 1170 m_editingPoint.value = float(newValue);
1171 m_editingPoint.duration = newDuration; 1171 m_editingPoint.duration = newDuration;
1172 m_editingCommand->addPoint(m_editingPoint); 1172 m_editingCommand->addPoint(m_editingPoint);
1173 1173
1174 recalcSpacing(); 1174 recalcSpacing();
1175 } 1175 }
1272 int avoid = m_spacingMap[m_editingPoint.value]; 1272 int avoid = m_spacingMap[m_editingPoint.value];
1273 1273
1274 // ... unless there are other points with the same value 1274 // ... unless there are other points with the same value
1275 if (m_distributionMap[m_editingPoint.value] > 1) avoid = -1; 1275 if (m_distributionMap[m_editingPoint.value] > 1) avoid = -1;
1276 1276
1277 float value = getValueForY(v, newy, avoid); 1277 double value = getValueForY(v, newy, avoid);
1278 1278
1279 if (!m_editingCommand) { 1279 if (!m_editingCommand) {
1280 m_editingCommand = new RegionModel::EditCommand(m_model, 1280 m_editingCommand = new RegionModel::EditCommand(m_model,
1281 tr("Drag Region")); 1281 tr("Drag Region"));
1282 } 1282 }
1283 1283
1284 m_editingCommand->deletePoint(m_editingPoint); 1284 m_editingCommand->deletePoint(m_editingPoint);
1285 m_editingPoint.frame = frame; 1285 m_editingPoint.frame = frame;
1286 m_editingPoint.value = value; 1286 m_editingPoint.value = float(value);
1287 m_editingCommand->addPoint(m_editingPoint); 1287 m_editingCommand->addPoint(m_editingPoint);
1288 recalcSpacing(); 1288 recalcSpacing();
1289 } 1289 }
1290 1290
1291 void 1291 void
1356 recalcSpacing(); 1356 recalcSpacing();
1357 return true; 1357 return true;
1358 } 1358 }
1359 1359
1360 void 1360 void
1361 RegionLayer::moveSelection(Selection s, int newStartFrame) 1361 RegionLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
1362 { 1362 {
1363 if (!m_model) return; 1363 if (!m_model) return;
1364 1364
1365 RegionModel::EditCommand *command = 1365 RegionModel::EditCommand *command =
1366 new RegionModel::EditCommand(m_model, tr("Drag Selection")); 1366 new RegionModel::EditCommand(m_model, tr("Drag Selection"));
1401 for (RegionModel::PointList::iterator i = points.begin(); 1401 for (RegionModel::PointList::iterator i = points.begin();
1402 i != points.end(); ++i) { 1402 i != points.end(); ++i) {
1403 1403
1404 if (s.contains(i->frame)) { 1404 if (s.contains(i->frame)) {
1405 1405
1406 double targetStart = i->frame; 1406 double targetStart = double(i->frame);
1407 targetStart = newSize.getStartFrame() + 1407 targetStart = double(newSize.getStartFrame()) +
1408 double(targetStart - s.getStartFrame()) * ratio; 1408 targetStart - double(s.getStartFrame()) * ratio;
1409 1409
1410 double targetEnd = i->frame + i->duration; 1410 double targetEnd = double(i->frame + i->duration);
1411 targetEnd = newSize.getStartFrame() + 1411 targetEnd = double(newSize.getStartFrame()) +
1412 double(targetEnd - s.getStartFrame()) * ratio; 1412 targetEnd - double(s.getStartFrame()) * ratio;
1413 1413
1414 RegionModel::Point newPoint(*i); 1414 RegionModel::Point newPoint(*i);
1415 newPoint.frame = lrint(targetStart); 1415 newPoint.frame = lrint(targetStart);
1416 newPoint.duration = lrint(targetEnd - targetStart); 1416 newPoint.duration = lrint(targetEnd - targetStart);
1417 command->deletePoint(*i); 1417 command->deletePoint(*i);
1463 } 1463 }
1464 } 1464 }
1465 } 1465 }
1466 1466
1467 bool 1467 bool
1468 RegionLayer::paste(View *v, const Clipboard &from, int /* frameOffset */, bool /* interactive */) 1468 RegionLayer::paste(View *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */)
1469 { 1469 {
1470 if (!m_model) return false; 1470 if (!m_model) return false;
1471 1471
1472 const Clipboard::PointList &points = from.getPoints(); 1472 const Clipboard::PointList &points = from.getPoints();
1473 1473
1495 1495
1496 for (Clipboard::PointList::const_iterator i = points.begin(); 1496 for (Clipboard::PointList::const_iterator i = points.begin();
1497 i != points.end(); ++i) { 1497 i != points.end(); ++i) {
1498 1498
1499 if (!i->haveFrame()) continue; 1499 if (!i->haveFrame()) continue;
1500 int frame = 0; 1500 sv_frame_t frame = 0;
1501 1501
1502 if (!realign) { 1502 if (!realign) {
1503 1503
1504 frame = i->getFrame(); 1504 frame = i->getFrame();
1505 1505
1519 if (i->haveValue()) newPoint.value = i->getValue(); 1519 if (i->haveValue()) newPoint.value = i->getValue();
1520 else newPoint.value = (m_model->getValueMinimum() + 1520 else newPoint.value = (m_model->getValueMinimum() +
1521 m_model->getValueMaximum()) / 2; 1521 m_model->getValueMaximum()) / 2;
1522 if (i->haveDuration()) newPoint.duration = i->getDuration(); 1522 if (i->haveDuration()) newPoint.duration = i->getDuration();
1523 else { 1523 else {
1524 int nextFrame = frame; 1524 sv_frame_t nextFrame = frame;
1525 Clipboard::PointList::const_iterator j = i; 1525 Clipboard::PointList::const_iterator j = i;
1526 for (; j != points.end(); ++j) { 1526 for (; j != points.end(); ++j) {
1527 if (!j->haveFrame()) continue; 1527 if (!j->haveFrame()) continue;
1528 if (j != i) break; 1528 if (j != i) break;
1529 } 1529 }