Mercurial > hg > svgui
comparison view/AlignmentView.cpp @ 1617:cbbb411da977
Merge
author | Chris Cannam |
---|---|
date | Tue, 21 Jul 2020 14:02:12 +0100 |
parents | 911330a28a7c |
children | 36634b427d61 |
comparison
equal
deleted
inserted
replaced
1616:199dbb3547d4 | 1617:cbbb411da977 |
---|---|
27 using std::set; | 27 using std::set; |
28 | 28 |
29 AlignmentView::AlignmentView(QWidget *w) : | 29 AlignmentView::AlignmentView(QWidget *w) : |
30 View(w, false), | 30 View(w, false), |
31 m_above(nullptr), | 31 m_above(nullptr), |
32 m_below(nullptr) | 32 m_below(nullptr), |
33 m_reference(nullptr), | |
34 m_leftmostAbove(-1), | |
35 m_rightmostAbove(-1) | |
33 { | 36 { |
34 setObjectName(tr("AlignmentView")); | 37 setObjectName(tr("AlignmentView")); |
35 } | 38 } |
36 | 39 |
37 void | 40 void |
39 { | 42 { |
40 #ifdef DEBUG_ALIGNMENT_VIEW | 43 #ifdef DEBUG_ALIGNMENT_VIEW |
41 SVCERR << "AlignmentView " << getId() << "::keyFramesChanged" << endl; | 44 SVCERR << "AlignmentView " << getId() << "::keyFramesChanged" << endl; |
42 #endif | 45 #endif |
43 | 46 |
44 // This is just a notification that we need to rebuild it - so all | 47 // This is just a notification that we need to rebuild - so all we |
45 // we do here is clear it, and it'll be rebuilt on demand later | 48 // do here is clear, and rebuild on demand later |
46 QMutexLocker locker(&m_keyFrameMutex); | 49 QMutexLocker locker(&m_mapsMutex); |
47 m_keyFrameMap.clear(); | 50 m_fromAboveMap.clear(); |
51 m_fromReferenceMap.clear(); | |
48 } | 52 } |
49 | 53 |
50 void | 54 void |
51 AlignmentView::globalCentreFrameChanged(sv_frame_t f) | 55 AlignmentView::globalCentreFrameChanged(sv_frame_t f) |
52 { | 56 { |
84 { | 88 { |
85 update(); | 89 update(); |
86 } | 90 } |
87 | 91 |
88 void | 92 void |
89 AlignmentView::setViewAbove(View *v) | 93 AlignmentView::setAboveView(View *v) |
90 { | 94 { |
91 if (m_above) { | 95 if (m_above) { |
92 disconnect(m_above, nullptr, this, nullptr); | 96 disconnect(m_above, nullptr, this, nullptr); |
93 } | 97 } |
94 | 98 |
111 | 115 |
112 keyFramesChanged(); | 116 keyFramesChanged(); |
113 } | 117 } |
114 | 118 |
115 void | 119 void |
116 AlignmentView::setViewBelow(View *v) | 120 AlignmentView::setBelowView(View *v) |
117 { | 121 { |
118 if (m_below) { | 122 if (m_below) { |
119 disconnect(m_below, nullptr, this, nullptr); | 123 disconnect(m_below, nullptr, this, nullptr); |
120 } | 124 } |
121 | 125 |
138 | 142 |
139 keyFramesChanged(); | 143 keyFramesChanged(); |
140 } | 144 } |
141 | 145 |
142 void | 146 void |
147 AlignmentView::setReferenceView(View *view) | |
148 { | |
149 m_reference = view; | |
150 } | |
151 | |
152 void | |
143 AlignmentView::paintEvent(QPaintEvent *) | 153 AlignmentView::paintEvent(QPaintEvent *) |
144 { | 154 { |
145 if (m_above == nullptr || m_below == nullptr || !m_manager) return; | 155 if (m_above == nullptr || m_below == nullptr || !m_manager) return; |
146 | 156 |
147 #ifdef DEBUG_ALIGNMENT_VIEW | 157 #ifdef DEBUG_ALIGNMENT_VIEW |
165 paint.setBrush(Qt::NoBrush); | 175 paint.setBrush(Qt::NoBrush); |
166 paint.setRenderHint(QPainter::Antialiasing, true); | 176 paint.setRenderHint(QPainter::Antialiasing, true); |
167 | 177 |
168 paint.fillRect(rect(), bg); | 178 paint.fillRect(rect(), bg); |
169 | 179 |
170 QMutexLocker locker(&m_keyFrameMutex); | 180 QMutexLocker locker(&m_mapsMutex); |
171 | 181 |
172 if (m_keyFrameMap.empty()) { | 182 if (m_fromAboveMap.empty()) { |
173 reconnectModels(); | 183 reconnectModels(); |
174 buildKeyFrameMap(); | 184 buildMaps(); |
175 } | 185 } |
176 | 186 |
177 #ifdef DEBUG_ALIGNMENT_VIEW | 187 #ifdef DEBUG_ALIGNMENT_VIEW |
178 SVCERR << "AlignmentView " << getId() << "::paintEvent: painting " | 188 SVCERR << "AlignmentView " << getId() << "::paintEvent: painting " |
179 << m_keyFrameMap.size() << " mappings" << endl; | 189 << m_fromAboveMap.size() << " mappings" << endl; |
180 #endif | 190 #endif |
181 | 191 |
182 for (const auto &km: m_keyFrameMap) { | 192 int w = width(); |
183 | 193 int h = height(); |
184 sv_frame_t af = km.first; | 194 |
185 sv_frame_t bf = km.second; | 195 if (m_leftmostAbove > 0) { |
186 | 196 |
187 int ax = m_above->getXForFrame(af); | 197 for (const auto &km: m_fromAboveMap) { |
188 int bx = m_below->getXForFrame(bf); | 198 |
189 | 199 sv_frame_t af = km.first; |
190 if (ax >= 0 || ax < width() || bx >= 0 || bx < width()) { | 200 sv_frame_t bf = km.second; |
191 paint.drawLine(ax, 0, bx, height()); | 201 |
202 if (af < m_leftmostAbove || af > m_rightmostAbove) { | |
203 continue; | |
204 } | |
205 | |
206 int ax = m_above->getXForFrame(af); | |
207 int bx = m_below->getXForFrame(bf); | |
208 | |
209 if (ax >= 0 || ax < w || bx >= 0 || bx < w) { | |
210 paint.drawLine(ax, 0, bx, h); | |
211 } | |
212 } | |
213 } else if (m_reference != nullptr) { | |
214 // the below has nothing in common with the above: show things | |
215 // in common with the reference instead | |
216 | |
217 for (const auto &km: m_fromReferenceMap) { | |
218 | |
219 sv_frame_t af = km.first; | |
220 sv_frame_t bf = km.second; | |
221 | |
222 int ax = m_reference->getXForFrame(af); | |
223 int bx = m_below->getXForFrame(bf); | |
224 | |
225 if (ax >= 0 || ax < w || bx >= 0 || bx < w) { | |
226 paint.drawLine(ax, 0, bx, h); | |
227 } | |
192 } | 228 } |
193 } | 229 } |
194 | 230 |
195 paint.end(); | 231 paint.end(); |
196 } | 232 } |
225 } | 261 } |
226 } | 262 } |
227 } | 263 } |
228 | 264 |
229 void | 265 void |
230 AlignmentView::buildKeyFrameMap() | 266 AlignmentView::buildMaps() |
231 { | 267 { |
232 #ifdef DEBUG_ALIGNMENT_VIEW | 268 #ifdef DEBUG_ALIGNMENT_VIEW |
233 SVCERR << "AlignmentView " << getId() << "::buildKeyFrameMap" << endl; | 269 SVCERR << "AlignmentView " << getId() << "::buildMaps" << endl; |
234 #endif | 270 #endif |
235 | 271 |
236 sv_frame_t resolution = 1; | 272 sv_frame_t resolution = 1; |
237 | 273 |
238 set<sv_frame_t> keyFramesBelow; | 274 set<sv_frame_t> keyFramesBelow; |
239 for (auto f: getKeyFrames(m_below, resolution)) { | 275 for (auto f: getKeyFrames(m_below, resolution)) { |
240 keyFramesBelow.insert(f); | 276 keyFramesBelow.insert(f); |
241 } | 277 } |
242 | 278 |
279 foreach(sv_frame_t f, keyFramesBelow) { | |
280 sv_frame_t rf = m_below->alignToReference(f); | |
281 m_fromReferenceMap.insert({ rf, f }); | |
282 } | |
283 | |
243 vector<sv_frame_t> keyFrames = getKeyFrames(m_above, resolution); | 284 vector<sv_frame_t> keyFrames = getKeyFrames(m_above, resolution); |
244 | 285 |
286 // These are the most extreme leftward and rightward frames in | |
287 // "above" that have distinct corresponding frames in | |
288 // "below". Anything left of m_leftmostAbove or right of | |
289 // m_rightmostAbove maps effectively off one end or the other of | |
290 // the below view. (They don't actually map off the ends, they | |
291 // just all map to the same first/last destination frame. But we | |
292 // don't want to display their mappings, as they're just noise.) | |
293 m_leftmostAbove = -1; | |
294 m_rightmostAbove = -1; | |
295 | |
296 sv_frame_t prevRf = -1; | |
297 sv_frame_t prevBf = -1; | |
298 | |
245 foreach (sv_frame_t f, keyFrames) { | 299 foreach (sv_frame_t f, keyFrames) { |
246 | 300 |
247 sv_frame_t rf = m_above->alignToReference(f); | 301 sv_frame_t rf = m_above->alignToReference(f); |
248 sv_frame_t bf = m_below->alignFromReference(rf); | 302 sv_frame_t bf = m_below->alignFromReference(rf); |
249 | 303 |
304 if (prevBf > 0 && bf > prevBf) { | |
305 if (m_leftmostAbove < 0 && prevBf > 0 && bf > prevBf) { | |
306 m_leftmostAbove = prevRf; | |
307 } | |
308 m_rightmostAbove = rf; | |
309 } | |
310 prevRf = rf; | |
311 prevBf = bf; | |
312 | |
250 bool mappedSomething = false; | 313 bool mappedSomething = false; |
251 | 314 |
252 if (resolution > 1) { | 315 if (resolution > 1) { |
253 if (keyFramesBelow.find(bf) == keyFramesBelow.end()) { | 316 if (keyFramesBelow.find(bf) == keyFramesBelow.end()) { |
254 | 317 |
256 sv_frame_t rf1 = m_above->alignToReference(f1); | 319 sv_frame_t rf1 = m_above->alignToReference(f1); |
257 sv_frame_t bf1 = m_below->alignFromReference(rf1); | 320 sv_frame_t bf1 = m_below->alignFromReference(rf1); |
258 | 321 |
259 for (sv_frame_t probe = bf + 1; probe <= bf1; ++probe) { | 322 for (sv_frame_t probe = bf + 1; probe <= bf1; ++probe) { |
260 if (keyFramesBelow.find(probe) != keyFramesBelow.end()) { | 323 if (keyFramesBelow.find(probe) != keyFramesBelow.end()) { |
261 m_keyFrameMap.insert({ f, probe }); | 324 m_fromAboveMap.insert({ f, probe }); |
262 mappedSomething = true; | 325 mappedSomething = true; |
263 } | 326 } |
264 } | 327 } |
265 } | 328 } |
266 } | 329 } |
267 | 330 |
268 if (!mappedSomething) { | 331 if (!mappedSomething) { |
269 m_keyFrameMap.insert({ f, bf }); | 332 m_fromAboveMap.insert({ f, bf }); |
270 } | 333 } |
271 } | 334 } |
272 | 335 |
273 #ifdef DEBUG_ALIGNMENT_VIEW | 336 #ifdef DEBUG_ALIGNMENT_VIEW |
274 SVCERR << "AlignmentView " << getId() << "::buildKeyFrameMap: have " | 337 SVCERR << "AlignmentView " << getId() << "::buildMaps: have " |
275 << m_keyFrameMap.size() << " mappings" << endl; | 338 << m_fromAboveMap.size() << " mappings" << endl; |
276 #endif | 339 #endif |
277 } | 340 } |
278 | 341 |
279 vector<sv_frame_t> | 342 vector<sv_frame_t> |
280 AlignmentView::getKeyFrames(View *view, sv_frame_t &resolution) | 343 AlignmentView::getKeyFrames(View *view, sv_frame_t &resolution) |