Mercurial > hg > svgui
comparison layer/SliceLayer.cpp @ 1472:dbff4b290bf0 by-id
Further layer updates
author | Chris Cannam |
---|---|
date | Mon, 01 Jul 2019 14:25:53 +0100 |
parents | c8a6fd3f9dff |
children | 0e971e3d93e2 |
comparison
equal
deleted
inserted
replaced
1471:f2525e6cbdf1 | 1472:dbff4b290bf0 |
---|---|
30 #include <QPainterPath> | 30 #include <QPainterPath> |
31 #include <QTextStream> | 31 #include <QTextStream> |
32 | 32 |
33 | 33 |
34 SliceLayer::SliceLayer() : | 34 SliceLayer::SliceLayer() : |
35 m_sliceableModel(nullptr), | |
36 m_binAlignment(BinsSpanScalePoints), | 35 m_binAlignment(BinsSpanScalePoints), |
37 m_colourMap(int(ColourMapper::Ice)), | 36 m_colourMap(int(ColourMapper::Ice)), |
38 m_colourInverted(false), | 37 m_colourInverted(false), |
39 m_energyScale(dBScale), | 38 m_energyScale(dBScale), |
40 m_samplingMode(SampleMean), | 39 m_samplingMode(SampleMean), |
55 { | 54 { |
56 | 55 |
57 } | 56 } |
58 | 57 |
59 void | 58 void |
60 SliceLayer::setSliceableModel(const Model *model) | 59 SliceLayer::setSliceableModel(ModelId modelId) |
61 { | 60 { |
62 const DenseThreeDimensionalModel *sliceable = | 61 auto newModel = ModelById::getAs<DenseThreeDimensionalModel>(modelId); |
63 dynamic_cast<const DenseThreeDimensionalModel *>(model); | 62 |
64 | 63 if (!modelId.isNone() && !newModel) { |
65 if (model && !sliceable) { | 64 throw std::logic_error("Not a DenseThreeDimensionalModel"); |
66 cerr << "WARNING: SliceLayer::setSliceableModel(" << model | 65 } |
67 << "): model is not a DenseThreeDimensionalModel" << endl; | 66 |
68 } | 67 if (m_sliceableModel == modelId) return; |
69 | 68 m_sliceableModel = modelId; |
70 if (m_sliceableModel == sliceable) return; | 69 |
71 | 70 if (newModel) { |
72 m_sliceableModel = sliceable; | 71 connectSignals(m_sliceableModel); |
73 | 72 |
74 if (!m_sliceableModel) return; | 73 if (m_minbin == 0 && m_maxbin == 0) { |
75 | 74 m_minbin = 0; |
76 connectSignals(m_sliceableModel); | 75 m_maxbin = newModel->getHeight(); |
77 | 76 } |
78 if (m_minbin == 0 && m_maxbin == 0) { | |
79 m_minbin = 0; | |
80 m_maxbin = m_sliceableModel->getHeight(); | |
81 } | 77 } |
82 | 78 |
83 emit modelReplaced(); | 79 emit modelReplaced(); |
84 emit layerParametersChanged(); | 80 emit layerParametersChanged(); |
85 } | 81 } |
86 | 82 |
87 void | 83 void |
88 SliceLayer::sliceableModelReplaced(const Model *orig, const Model *replacement) | 84 SliceLayer::sliceableModelReplaced(ModelId orig, ModelId replacement) |
89 { | 85 { |
90 SVDEBUG << "SliceLayer::sliceableModelReplaced(" << orig << ", " << replacement << ")" << endl; | 86 SVDEBUG << "SliceLayer::sliceableModelReplaced(" << orig << ", " << replacement << ")" << endl; |
91 | 87 |
92 if (orig == m_sliceableModel) { | 88 if (orig == m_sliceableModel) { |
93 setSliceableModel | 89 setSliceableModel(replacement); |
94 (dynamic_cast<const DenseThreeDimensionalModel *>(replacement)); | 90 } |
95 } | 91 } |
96 } | 92 /*!!! |
97 | |
98 void | 93 void |
99 SliceLayer::modelAboutToBeDeleted(Model *m) | 94 SliceLayer::modelAboutToBeDeleted(Model *m) |
100 { | 95 { |
101 SVDEBUG << "SliceLayer::modelAboutToBeDeleted(" << m << ")" << endl; | 96 SVDEBUG << "SliceLayer::modelAboutToBeDeleted(" << m << ")" << endl; |
102 | 97 |
103 if (m == m_sliceableModel) { | 98 if (m == m_sliceableModel) { |
104 setSliceableModel(nullptr); | 99 setSliceableModel(nullptr); |
105 } | 100 } |
106 } | 101 } |
107 | 102 */ |
108 QString | 103 QString |
109 SliceLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &p) const | 104 SliceLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &p) const |
110 { | 105 { |
111 int minbin, maxbin, range; | 106 int minbin, maxbin, range; |
112 return getFeatureDescriptionAux(v, p, true, minbin, maxbin, range); | 107 return getFeatureDescriptionAux(v, p, true, minbin, maxbin, range); |
117 bool includeBinDescription, | 112 bool includeBinDescription, |
118 int &minbin, int &maxbin, int &range) const | 113 int &minbin, int &maxbin, int &range) const |
119 { | 114 { |
120 minbin = 0; | 115 minbin = 0; |
121 maxbin = 0; | 116 maxbin = 0; |
122 if (!m_sliceableModel) return ""; | 117 |
118 auto sliceableModel = | |
119 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); | |
120 if (!sliceableModel) return ""; | |
123 | 121 |
124 if (m_binAlignment == BinsSpanScalePoints) { | 122 if (m_binAlignment == BinsSpanScalePoints) { |
125 minbin = int(getBinForX(v, p.x())); | 123 minbin = int(getBinForX(v, p.x())); |
126 maxbin = int(getBinForX(v, p.x() + 1)); | 124 maxbin = int(getBinForX(v, p.x() + 1)); |
127 } else { | 125 } else { |
128 minbin = int(getBinForX(v, p.x()) + 0.5); | 126 minbin = int(getBinForX(v, p.x()) + 0.5); |
129 maxbin = int(getBinForX(v, p.x() + 1) + 0.5); | 127 maxbin = int(getBinForX(v, p.x() + 1) + 0.5); |
130 } | 128 } |
131 | 129 |
132 int mh = m_sliceableModel->getHeight(); | 130 int mh = sliceableModel->getHeight(); |
133 if (minbin >= mh) minbin = mh - 1; | 131 if (minbin >= mh) minbin = mh - 1; |
134 if (maxbin >= mh) maxbin = mh - 1; | 132 if (maxbin >= mh) maxbin = mh - 1; |
135 if (minbin < 0) minbin = 0; | 133 if (minbin < 0) minbin = 0; |
136 if (maxbin < 0) maxbin = 0; | 134 if (maxbin < 0) maxbin = 0; |
137 | 135 |
138 sv_samplerate_t sampleRate = m_sliceableModel->getSampleRate(); | 136 sv_samplerate_t sampleRate = sliceableModel->getSampleRate(); |
139 | 137 |
140 sv_frame_t f0 = m_currentf0; | 138 sv_frame_t f0 = m_currentf0; |
141 sv_frame_t f1 = m_currentf1; | 139 sv_frame_t f1 = m_currentf1; |
142 | 140 |
143 RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate); | 141 RealTime rt0 = RealTime::frame2RealTime(f0, sampleRate); |
418 } | 416 } |
419 | 417 |
420 void | 418 void |
421 SliceLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const | 419 SliceLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const |
422 { | 420 { |
423 if (!m_sliceableModel || | 421 auto sliceableModel = |
424 !m_sliceableModel->isOK() || | 422 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); |
425 !m_sliceableModel->isReady()) return; | 423 if (!sliceableModel || |
424 !sliceableModel->isOK() || | |
425 !sliceableModel->isReady()) return; | |
426 | 426 |
427 Profiler profiler("SliceLayer::paint()"); | 427 Profiler profiler("SliceLayer::paint()"); |
428 | 428 |
429 paint.save(); | 429 paint.save(); |
430 paint.setRenderHint(QPainter::Antialiasing, true); | 430 paint.setRenderHint(QPainter::Antialiasing, true); |
440 rect.width(), m_scalePoints[i] * ratio); | 440 rect.width(), m_scalePoints[i] * ratio); |
441 } | 441 } |
442 } | 442 } |
443 } | 443 } |
444 | 444 |
445 int mh = m_sliceableModel->getHeight(); | 445 int mh = sliceableModel->getHeight(); |
446 int bin0 = 0; | 446 int bin0 = 0; |
447 if (m_maxbin > m_minbin) { | 447 if (m_maxbin > m_minbin) { |
448 mh = m_maxbin - m_minbin; | 448 mh = m_maxbin - m_minbin; |
449 bin0 = m_minbin; | 449 bin0 = m_minbin; |
450 } | 450 } |
491 sv_frame_t f1 = v->getFrameForX(f0x + 1); | 491 sv_frame_t f1 = v->getFrameForX(f0x + 1); |
492 if (f1 > f0) --f1; | 492 if (f1 > f0) --f1; |
493 | 493 |
494 // cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << endl; | 494 // cerr << "centre frame " << v->getCentreFrame() << ", x " << f0x << ", f0 " << f0 << ", f1 " << f1 << endl; |
495 | 495 |
496 int res = m_sliceableModel->getResolution(); | 496 int res = sliceableModel->getResolution(); |
497 int col0 = int(f0 / res); | 497 int col0 = int(f0 / res); |
498 int col1 = col0; | 498 int col1 = col0; |
499 if (m_samplingMode != NearestSample) col1 = int(f1 / res); | 499 if (m_samplingMode != NearestSample) col1 = int(f1 / res); |
500 f0 = col0 * res; | 500 f0 = col0 * res; |
501 f1 = (col1 + 1) * res - 1; | 501 f1 = (col1 + 1) * res - 1; |
510 getBiasCurve(curve); | 510 getBiasCurve(curve); |
511 int cs = int(curve.size()); | 511 int cs = int(curve.size()); |
512 | 512 |
513 for (int col = col0; col <= col1; ++col) { | 513 for (int col = col0; col <= col1; ++col) { |
514 DenseThreeDimensionalModel::Column column = | 514 DenseThreeDimensionalModel::Column column = |
515 m_sliceableModel->getColumn(col); | 515 sliceableModel->getColumn(col); |
516 for (int bin = 0; bin < mh; ++bin) { | 516 for (int bin = 0; bin < mh; ++bin) { |
517 float value = column[bin0 + bin]; | 517 float value = column[bin0 + bin]; |
518 if (bin < cs) value *= curve[bin]; | 518 if (bin < cs) value *= curve[bin]; |
519 if (m_samplingMode == SamplePeak) { | 519 if (m_samplingMode == SamplePeak) { |
520 if (value > m_values[bin]) m_values[bin] = value; | 520 if (value > m_values[bin]) m_values[bin] = value; |
672 } | 672 } |
673 | 673 |
674 int | 674 int |
675 SliceLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const | 675 SliceLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const |
676 { | 676 { |
677 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested | |
678 // replacement (horizontalAdvance) was only added in Qt 5.11 | |
679 // which is too new for us | |
680 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
681 | |
677 int width; | 682 int width; |
678 if (m_energyScale == LinearScale || m_energyScale == AbsoluteScale) { | 683 if (m_energyScale == LinearScale || m_energyScale == AbsoluteScale) { |
679 width = std::max(paint.fontMetrics().width("0.0") + 13, | 684 width = std::max(paint.fontMetrics().width("0.0") + 13, |
680 paint.fontMetrics().width("x10-10")); | 685 paint.fontMetrics().width("x10-10")); |
681 } else { | 686 } else { |
1164 | 1169 |
1165 bool | 1170 bool |
1166 SliceLayer::getValueExtents(double &min, double &max, bool &logarithmic, | 1171 SliceLayer::getValueExtents(double &min, double &max, bool &logarithmic, |
1167 QString &unit) const | 1172 QString &unit) const |
1168 { | 1173 { |
1169 if (!m_sliceableModel) return false; | 1174 auto sliceableModel = |
1175 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); | |
1176 if (!sliceableModel) return false; | |
1170 | 1177 |
1171 min = 0; | 1178 min = 0; |
1172 max = double(m_sliceableModel->getHeight()); | 1179 max = double(sliceableModel->getHeight()); |
1173 | 1180 |
1174 logarithmic = (m_binScale == BinScale::LogBins); | 1181 logarithmic = (m_binScale == BinScale::LogBins); |
1175 unit = ""; | 1182 unit = ""; |
1176 | 1183 |
1177 return true; | 1184 return true; |
1178 } | 1185 } |
1179 | 1186 |
1180 bool | 1187 bool |
1181 SliceLayer::getDisplayExtents(double &min, double &max) const | 1188 SliceLayer::getDisplayExtents(double &min, double &max) const |
1182 { | 1189 { |
1183 if (!m_sliceableModel) return false; | 1190 auto sliceableModel = |
1184 | 1191 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); |
1185 double hmax = double(m_sliceableModel->getHeight()); | 1192 if (!sliceableModel) return false; |
1193 | |
1194 double hmax = double(sliceableModel->getHeight()); | |
1186 | 1195 |
1187 min = m_minbin; | 1196 min = m_minbin; |
1188 max = m_maxbin; | 1197 max = m_maxbin; |
1189 if (max <= min) { | 1198 if (max <= min) { |
1190 min = 0; | 1199 min = 0; |
1197 } | 1206 } |
1198 | 1207 |
1199 bool | 1208 bool |
1200 SliceLayer::setDisplayExtents(double min, double max) | 1209 SliceLayer::setDisplayExtents(double min, double max) |
1201 { | 1210 { |
1202 if (!m_sliceableModel) return false; | 1211 auto sliceableModel = |
1212 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); | |
1213 if (!sliceableModel) return false; | |
1203 | 1214 |
1204 m_minbin = int(lrint(min)); | 1215 m_minbin = int(lrint(min)); |
1205 m_maxbin = int(lrint(max)); | 1216 m_maxbin = int(lrint(max)); |
1206 | 1217 |
1207 if (m_minbin < 0) { | 1218 if (m_minbin < 0) { |
1208 m_minbin = 0; | 1219 m_minbin = 0; |
1209 } | 1220 } |
1210 if (m_maxbin < 0) { | 1221 if (m_maxbin < 0) { |
1211 m_maxbin = 0; | 1222 m_maxbin = 0; |
1212 } | 1223 } |
1213 if (m_minbin > m_sliceableModel->getHeight()) { | 1224 if (m_minbin > sliceableModel->getHeight()) { |
1214 m_minbin = m_sliceableModel->getHeight(); | 1225 m_minbin = sliceableModel->getHeight(); |
1215 } | 1226 } |
1216 if (m_maxbin > m_sliceableModel->getHeight()) { | 1227 if (m_maxbin > sliceableModel->getHeight()) { |
1217 m_maxbin = m_sliceableModel->getHeight(); | 1228 m_maxbin = sliceableModel->getHeight(); |
1218 } | 1229 } |
1219 if (m_maxbin < m_minbin) { | 1230 if (m_maxbin < m_minbin) { |
1220 m_maxbin = m_minbin; | 1231 m_maxbin = m_minbin; |
1221 } | 1232 } |
1222 | 1233 |
1225 } | 1236 } |
1226 | 1237 |
1227 int | 1238 int |
1228 SliceLayer::getVerticalZoomSteps(int &defaultStep) const | 1239 SliceLayer::getVerticalZoomSteps(int &defaultStep) const |
1229 { | 1240 { |
1230 if (!m_sliceableModel) return 0; | 1241 auto sliceableModel = |
1242 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); | |
1243 if (!sliceableModel) return 0; | |
1231 | 1244 |
1232 defaultStep = 0; | 1245 defaultStep = 0; |
1233 int h = m_sliceableModel->getHeight(); | 1246 int h = sliceableModel->getHeight(); |
1234 return h; | 1247 return h; |
1235 } | 1248 } |
1236 | 1249 |
1237 int | 1250 int |
1238 SliceLayer::getCurrentVerticalZoomStep() const | 1251 SliceLayer::getCurrentVerticalZoomStep() const |
1239 { | 1252 { |
1240 if (!m_sliceableModel) return 0; | 1253 auto sliceableModel = |
1254 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); | |
1255 if (!sliceableModel) return 0; | |
1241 | 1256 |
1242 double min, max; | 1257 double min, max; |
1243 getDisplayExtents(min, max); | 1258 getDisplayExtents(min, max); |
1244 return m_sliceableModel->getHeight() - int(lrint(max - min)); | 1259 return sliceableModel->getHeight() - int(lrint(max - min)); |
1245 } | 1260 } |
1246 | 1261 |
1247 void | 1262 void |
1248 SliceLayer::setVerticalZoomStep(int step) | 1263 SliceLayer::setVerticalZoomStep(int step) |
1249 { | 1264 { |
1250 if (!m_sliceableModel) return; | 1265 auto sliceableModel = |
1266 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); | |
1267 if (!sliceableModel) return; | |
1251 | 1268 |
1252 // SVDEBUG << "SliceLayer::setVerticalZoomStep(" <<step <<"): before: minbin = " << m_minbin << ", maxbin = " << m_maxbin << endl; | 1269 // SVDEBUG << "SliceLayer::setVerticalZoomStep(" <<step <<"): before: minbin = " << m_minbin << ", maxbin = " << m_maxbin << endl; |
1253 | 1270 |
1254 int dist = m_sliceableModel->getHeight() - step; | 1271 int dist = sliceableModel->getHeight() - step; |
1255 if (dist < 1) dist = 1; | 1272 if (dist < 1) dist = 1; |
1256 double centre = m_minbin + (m_maxbin - m_minbin) / 2.0; | 1273 double centre = m_minbin + (m_maxbin - m_minbin) / 2.0; |
1257 int minbin = int(lrint(centre - dist/2.0)); | 1274 int minbin = int(lrint(centre - dist/2.0)); |
1258 int maxbin = minbin + dist; | 1275 int maxbin = minbin + dist; |
1259 setDisplayExtents(minbin, maxbin); | 1276 setDisplayExtents(minbin, maxbin); |
1260 } | 1277 } |
1261 | 1278 |
1262 RangeMapper * | 1279 RangeMapper * |
1263 SliceLayer::getNewVerticalZoomRangeMapper() const | 1280 SliceLayer::getNewVerticalZoomRangeMapper() const |
1264 { | 1281 { |
1265 if (!m_sliceableModel) return nullptr; | 1282 auto sliceableModel = |
1266 | 1283 ModelById::getAs<DenseThreeDimensionalModel>(m_sliceableModel); |
1267 return new LinearRangeMapper(0, m_sliceableModel->getHeight(), | 1284 if (!sliceableModel) return nullptr; |
1268 0, m_sliceableModel->getHeight(), ""); | 1285 |
1286 return new LinearRangeMapper(0, sliceableModel->getHeight(), | |
1287 0, sliceableModel->getHeight(), ""); | |
1269 } | 1288 } |
1270 | 1289 |
1271 void | 1290 void |
1272 SliceLayer::zoomToRegion(const LayerGeometryProvider *v, QRect rect) | 1291 SliceLayer::zoomToRegion(const LayerGeometryProvider *v, QRect rect) |
1273 { | 1292 { |