Mercurial > hg > svgui
changeset 812:6c52314b31b0
Dense colour 3d plot layers should be scrollable, I think; and some tidying, debug stuff, and minor optimisations
author | Chris Cannam |
---|---|
date | Tue, 01 Jul 2014 15:32:54 +0100 |
parents | c4ef666721bf |
children | db31266cf606 |
files | layer/Colour3DPlotLayer.cpp layer/Colour3DPlotLayer.h |
diffstat | 2 files changed, 114 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/layer/Colour3DPlotLayer.cpp Wed Jun 18 13:51:27 2014 +0100 +++ b/layer/Colour3DPlotLayer.cpp Tue Jul 01 15:32:54 2014 +0100 @@ -509,7 +509,7 @@ if (dormant) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::setLayerDormant(" << dormant << ")" + cerr << "Colour3DPlotLayer::setLayerDormant(" << dormant << ")" << endl; #endif @@ -530,7 +530,12 @@ bool Colour3DPlotLayer::isLayerScrollable(const View *v) const { - if (m_normalizeVisibleArea) return false; + if (m_normalizeVisibleArea) { + return false; + } + if (shouldPaintDenseIn(v)) { + return true; + } QPoint discard; return !v->shouldIlluminateLocalFeatures(this, discard); } @@ -686,8 +691,8 @@ float(v->getViewManager()->getMainModelSampleRate()) / float(m_model->getSampleRate()); - int sx0 = int((v->getFrameForX(x) / srRatio - long(modelStart)) / - long(modelResolution)); + int sx0 = int((v->getFrameForX(x) / srRatio - modelStart) / + modelResolution); int f0 = sx0 * modelResolution; int f1 = f0 + modelResolution; @@ -708,6 +713,10 @@ int sy = getBinForY(v, y); + if (sy < 0 || sy >= m_model->getHeight()) { + return ""; + } + if (m_invertVertical) sy = m_model->getHeight() - sy - 1; float value = m_model->getValueAt(sx0, sy); @@ -903,6 +912,8 @@ DenseThreeDimensionalModel::Column Colour3DPlotLayer::getColumn(int col) const { + Profiler profiler("Colour3DPlotLayer::getColumn"); + DenseThreeDimensionalModel::Column values = m_model->getColumn(col); while (values.size() < m_model->getHeight()) values.push_back(0.f); if (!m_normalizeColumns && !m_normalizeHybrid) return values; @@ -941,33 +952,39 @@ void Colour3DPlotLayer::fillCache(int firstBin, int lastBin) const { - Profiler profiler("Colour3DPlotLayer::fillCache"); + Profiler profiler("Colour3DPlotLayer::fillCache", true); int modelStart = m_model->getStartFrame(); int modelEnd = m_model->getEndFrame(); int modelResolution = m_model->getResolution(); -#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << endl; -#endif - int modelStartBin = modelStart / modelResolution; int modelEndBin = modelEnd / modelResolution; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: range " << firstBin << " -> " << lastBin << " of model range " << modelStartBin << " -> " << modelEndBin << " (model resolution " << modelResolution << ")" << endl; +#endif + int cacheWidth = modelEndBin - modelStartBin + 1; if (lastBin > modelEndBin) cacheWidth = lastBin - modelStartBin + 1; int cacheHeight = m_model->getHeight(); - if (m_cache && (m_cache->height() != int(cacheHeight))) { + if (m_cache && m_cache->height() != cacheHeight) { // height has changed: delete everything rather than resizing +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: Cache height has changed, recreating" << endl; +#endif delete m_cache; delete m_peaksCache; m_cache = 0; m_peaksCache = 0; } - if (m_cache && (m_cache->width() != int(cacheWidth))) { + if (m_cache && m_cache->width() != cacheWidth) { // width has changed and we have an existing cache: resize it +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: Cache width has changed, resizing existing cache" << endl; +#endif QImage *newCache = new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight)); delete m_cache; @@ -982,15 +999,18 @@ } if (!m_cache) { +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "Colour3DPlotLayer::fillCache: Have no cache, making one" << endl; +#endif m_cache = new QImage (cacheWidth, cacheHeight, QImage::Format_Indexed8); -// No longer exists in Qt5: m_cache->setNumColors(256); + m_cache->setColorCount(256); m_cache->fill(0); if (!m_normalizeVisibleArea) { m_peaksCache = new QImage (cacheWidth / m_peakResolution + 1, cacheHeight, QImage::Format_Indexed8); -// No longer exists in Qt5: m_peaksCache->setNumColors(256); + m_peaksCache->setColorCount(256); m_peaksCache->fill(0); } else if (m_peaksCache) { delete m_peaksCache; @@ -1000,8 +1020,10 @@ m_cacheValidEnd = 0; } -// cerr << "cache size = " << m_cache->width() << "x" << m_cache->height() -// << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "cache size = " << m_cache->width() << "x" << m_cache->height() + << " peaks cache size = " << m_peaksCache->width() << "x" << m_peaksCache->height() << endl; +#endif if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT @@ -1034,14 +1056,15 @@ } else { - // the only valid area, ever, is the currently visible one + // when normalising the visible area, the only valid area, + // ever, is the currently visible one m_cacheValidStart = fillStart; m_cacheValidEnd = fillEnd; } #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << endl; + cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " will be valid from " << m_cacheValidStart << " to " << m_cacheValidEnd << " (fillStart = " << fillStart << ", fillEnd = " << fillEnd << ")" << endl; #endif DenseThreeDimensionalModel::Column values; @@ -1125,6 +1148,8 @@ } } + Profiler profiler2("Colour3DPlotLayer::fillCache: filling", true); + for (int c = fillStart; c <= fillEnd; ++c) { values = getColumn(c); @@ -1204,6 +1229,24 @@ delete[] peaks; } +bool +Colour3DPlotLayer::shouldPaintDenseIn(const View *v) const +{ + if (!m_model || !v || !(v->getViewManager())) { + return false; + } + float srRatio = + float(v->getViewManager()->getMainModelSampleRate()) / + float(m_model->getSampleRate()); + if (m_opaque || + m_smooth || + m_model->getHeight() >= v->height() || + ((m_model->getResolution() * srRatio) / v->getZoomLevel()) < 2) { + return true; + } + return false; +} + void Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const { @@ -1214,7 +1257,7 @@ */ Profiler profiler("Colour3DPlotLayer::paint"); #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << endl; + cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << ", rect is (" << rect.x() << "," << rect.y() << ") " << rect.width() << "x" << rect.height() << endl; #endif int completion = 0; @@ -1250,10 +1293,10 @@ float(v->getViewManager()->getMainModelSampleRate()) / float(m_model->getSampleRate()); - int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) - / long(modelResolution)); - int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) - / long(modelResolution)); + int sx0 = int((v->getFrameForX(x0) / srRatio - modelStart) + / modelResolution); + int sx1 = int((v->getFrameForX(x1) / srRatio - modelStart) + / modelResolution); int sh = m_model->getHeight(); int symin = m_miny; @@ -1270,22 +1313,19 @@ sx1 < 0 ? 0 : sx1); #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << endl; + cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << endl; #endif - if (m_opaque || - m_smooth || - int(m_model->getHeight()) >= v->height() || - ((modelResolution * srRatio) / v->getZoomLevel()) < 2) { + if (shouldPaintDenseIn(v)) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "calling paintDense" << endl; + cerr << "calling paintDense" << endl; #endif paintDense(v, paint, rect); return; } #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT - SVDEBUG << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl; + cerr << "Colour3DPlotLayer::paint: w " << x1-x0 << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sx1-sx0 << ", sh " << sh << endl; cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << endl; #endif @@ -1295,13 +1335,12 @@ for (int sx = sx0; sx <= sx1; ++sx) { - int fx = sx * int(modelResolution); + int fx = sx * modelResolution; - if (fx + int(modelResolution) <= int(modelStart) || - fx > int(modelEnd)) continue; + if (fx + modelResolution <= modelStart || fx > modelEnd) continue; - int rx0 = v->getXForFrame(int((fx + int(modelStart)) * srRatio)); - int rx1 = v->getXForFrame(int((fx + int(modelStart) + int(modelResolution) + 1) * srRatio)); + int rx0 = v->getXForFrame(int((fx + modelStart) * srRatio)); + int rx1 = v->getXForFrame(int((fx + modelStart + modelResolution + 1) * srRatio)); int rw = rx1 - rx0; if (rw < 1) rw = 1; @@ -1371,7 +1410,7 @@ void Colour3DPlotLayer::paintDense(View *v, QPainter &paint, QRect rect) const { - Profiler profiler("Colour3DPlotLayer::paintDense"); + Profiler profiler("Colour3DPlotLayer::paintDense", true); if (!m_cache) return; float modelStart = m_model->getStartFrame(); @@ -1406,30 +1445,37 @@ int zoomLevel = v->getZoomLevel(); QImage *source = m_cache; - - SVDEBUG << "modelResolution " << modelResolution << ", srRatio " - << srRatio << ", m_peakResolution " << m_peakResolution - << ", zoomLevel " << zoomLevel << ", result " - << ((modelResolution * srRatio * m_peakResolution) / zoomLevel) - << endl; + +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "modelResolution " << modelResolution << ", srRatio " + << srRatio << ", m_peakResolution " << m_peakResolution + << ", zoomLevel " << zoomLevel << ", result " + << ((modelResolution * srRatio * m_peakResolution) / zoomLevel) + << endl; +#endif if (m_peaksCache) { if (((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) { - SVDEBUG << "using peaks cache" << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "using peaks cache" << endl; +#endif source = m_peaksCache; modelResolution *= m_peakResolution; } else { - SVDEBUG << "not using peaks cache" << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "not using peaks cache" << endl; +#endif } } else { - SVDEBUG << "have no peaks cache" << endl; +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "have no peaks cache" << endl; +#endif } - int psy1i = -1; int sw = source->width(); - long xf = -1; - long nxf = v->getFrameForX(x0); + int xf = -1; + int nxf = v->getFrameForX(x0); float epsilon = 0.000001; @@ -1453,6 +1499,10 @@ float logmin = symin+1, logmax = symax+1; LogRange::mapRange(logmin, logmax); +#ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT + cerr << "m_smooth = " << m_smooth << ", w = " << w << ", h = " << h << endl; +#endif + if (m_smooth) { for (int y = 0; y < h; ++y) { @@ -1525,22 +1575,28 @@ } } else { + float sy0 = getBinForY(v, 0); + + int psy0i = -1, psy1i = -1; + for (int y = 0; y < h; ++y) { - float sy0, sy1; - + float sy1 = sy0; sy0 = getBinForY(v, y + 1); - sy1 = getBinForY(v, y); int sy0i = int(sy0 + epsilon); int sy1i = int(sy1); uchar *targetLine = img.scanLine(y); - if (sy0i == sy1i && sy0i == psy1i) { // same source scan line as just computed + if (sy0i == psy0i && sy1i == psy1i) { + // same source scan line as just computed goto copy; } + psy0i = sy0i; + psy1i = sy1i; + for (int x = 0; x < w; ++x) { peaks[x] = 0; }
--- a/layer/Colour3DPlotLayer.h Wed Jun 18 13:51:27 2014 +0100 +++ b/layer/Colour3DPlotLayer.h Tue Jul 01 15:32:54 2014 +0100 @@ -214,6 +214,13 @@ DenseThreeDimensionalModel::Column getColumn(int col) const; + /** + * True if we have the opaque or smooth flag set, or if the cells + * are so small you can't see their borders. False for big, + * translucent cells. + */ + bool shouldPaintDenseIn(const View *) const; + int getColourScaleWidth(QPainter &) const; void fillCache(int firstBin, int lastBin) const; void paintDense(View *v, QPainter &paint, QRect rect) const;