comparison layer/Colour3DPlotLayer.cpp @ 469:9863f9a36cc2

* some tweaks that make Colour3DPlotLayer a little bit faster for very dense models
author Chris Cannam
date Fri, 23 Jan 2009 15:11:40 +0000
parents 762e96217900
children 26d1ddc0ce96
comparison
equal deleted inserted replaced
468:762e96217900 469:9863f9a36cc2
34 34
35 35
36 Colour3DPlotLayer::Colour3DPlotLayer() : 36 Colour3DPlotLayer::Colour3DPlotLayer() :
37 m_model(0), 37 m_model(0),
38 m_cache(0), 38 m_cache(0),
39 m_peaksCache(0),
40 m_peakResolution(128),
39 m_cacheValidStart(0), 41 m_cacheValidStart(0),
40 m_cacheValidEnd(0), 42 m_cacheValidEnd(0),
41 m_colourScale(LinearScale), 43 m_colourScale(LinearScale),
42 m_colourScaleSet(false), 44 m_colourScaleSet(false),
43 m_colourMap(0), 45 m_colourMap(0),
52 } 54 }
53 55
54 Colour3DPlotLayer::~Colour3DPlotLayer() 56 Colour3DPlotLayer::~Colour3DPlotLayer()
55 { 57 {
56 delete m_cache; 58 delete m_cache;
59 delete m_peaksCache;
57 } 60 }
58 61
59 void 62 void
60 Colour3DPlotLayer::setModel(const DenseThreeDimensionalModel *model) 63 Colour3DPlotLayer::setModel(const DenseThreeDimensionalModel *model)
61 { 64 {
75 } 78 }
76 79
77 void 80 void
78 Colour3DPlotLayer::cacheInvalid() 81 Colour3DPlotLayer::cacheInvalid()
79 { 82 {
80 delete m_cache; 83 delete m_cache;
84 delete m_peaksCache;
81 m_cache = 0; 85 m_cache = 0;
86 m_peaksCache = 0;
82 m_cacheValidStart = 0; 87 m_cacheValidStart = 0;
83 m_cacheValidEnd = 0; 88 m_cacheValidEnd = 0;
84 } 89 }
85 90
86 void 91 void
719 size_t cacheWidth = modelEndBin - modelStartBin + 1; 724 size_t cacheWidth = modelEndBin - modelStartBin + 1;
720 size_t cacheHeight = m_model->getHeight(); 725 size_t cacheHeight = m_model->getHeight();
721 726
722 if (m_cache && (m_cache->height() != int(cacheHeight))) { 727 if (m_cache && (m_cache->height() != int(cacheHeight))) {
723 delete m_cache; 728 delete m_cache;
729 delete m_peaksCache;
724 m_cache = 0; 730 m_cache = 0;
731 m_peaksCache = 0;
725 } 732 }
726 733
727 if (m_cache && (m_cache->width() != int(cacheWidth))) { 734 if (m_cache && (m_cache->width() != int(cacheWidth))) {
728 QImage *newCache = new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight)); 735 QImage *newCache =
736 new QImage(m_cache->copy(0, 0, cacheWidth, cacheHeight));
729 delete m_cache; 737 delete m_cache;
730 m_cache = newCache; 738 m_cache = newCache;
739 if (m_peaksCache) {
740 QImage *newPeaksCache =
741 new QImage(m_peaksCache->copy
742 (0, 0, cacheWidth / m_peakResolution, cacheHeight));
743 delete m_peaksCache;
744 m_peaksCache = newPeaksCache;
745 }
731 } 746 }
732 747
733 if (!m_cache) { 748 if (!m_cache) {
734 m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8); 749 m_cache = new QImage
750 (cacheWidth, cacheHeight, QImage::Format_Indexed8);
735 m_cache->setNumColors(256); 751 m_cache->setNumColors(256);
752 if (modelResolution < m_peakResolution / 2 && !m_normalizeVisibleArea) {
753 m_peaksCache = new QImage
754 (cacheWidth / m_peakResolution + 1, cacheHeight,
755 QImage::Format_Indexed8);
756 m_peaksCache->setNumColors(256);
757 } else if (m_peaksCache) {
758 delete m_peaksCache;
759 m_peaksCache = 0;
760 }
736 m_cacheValidStart = 0; 761 m_cacheValidStart = 0;
737 m_cacheValidEnd = 0; 762 m_cacheValidEnd = 0;
738 } 763 }
739 764
740 if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) { 765 if (m_cacheValidStart <= firstBin && m_cacheValidEnd >= lastBin) {
789 814
790 ColourMapper mapper(m_colourMap, 0.f, 255.f); 815 ColourMapper mapper(m_colourMap, 0.f, 255.f);
791 816
792 for (int index = 0; index < 256; ++index) { 817 for (int index = 0; index < 256; ++index) {
793 QColor colour = mapper.map(index); 818 QColor colour = mapper.map(index);
794 m_cache->setColor(index, qRgb(colour.red(), colour.green(), colour.blue())); 819 m_cache->setColor
820 (index, qRgb(colour.red(), colour.green(), colour.blue()));
821 if (m_peaksCache) {
822 m_peaksCache->setColor
823 (index, qRgb(colour.red(), colour.green(), colour.blue()));
824 }
795 } 825 }
796 826
797 // m_cache->fill(0); 827 // m_cache->fill(0);
798 828
799 float visibleMax = 0.f, visibleMin = 0.f; 829 float visibleMax = 0.f, visibleMin = 0.f;
823 } 853 }
824 } 854 }
825 855
826 if (visibleMin == visibleMax) visibleMax = visibleMin + 1; 856 if (visibleMin == visibleMax) visibleMax = visibleMin + 1;
827 857
858 int *peaks = 0;
859 if (m_peaksCache) {
860 peaks = new int[cacheHeight];
861 for (int y = 0; y < cacheHeight; ++y) {
862 peaks[y] = 0;
863 }
864 }
865
828 for (size_t c = fillStart; c <= fillEnd; ++c) { 866 for (size_t c = fillStart; c <= fillEnd; ++c) {
829 867
830 values = getColumn(c); 868 values = getColumn(c);
831 869
832 for (size_t y = 0; y < cacheHeight; ++y) { 870 for (size_t y = 0; y < cacheHeight; ++y) {
833 871
834 float value = min; 872 float value = min;
835 if (y < values.size()) { 873 if (y < values.size()) {
836 value = values[y]; 874 value = values.at(y);
837 } 875 }
838 876
839 if (m_colourScale == LogScale) { 877 if (m_colourScale == LogScale) {
840 value = LogRange::map(value); 878 value = LogRange::map(value);
841 } 879 }
846 } 884 }
847 885
848 int pixel = int(((value - min) * 256) / (max - min)); 886 int pixel = int(((value - min) * 256) / (max - min));
849 if (pixel < 0) pixel = 0; 887 if (pixel < 0) pixel = 0;
850 if (pixel > 255) pixel = 255; 888 if (pixel > 255) pixel = 255;
889 if (peaks && (pixel > peaks[y])) peaks[y] = pixel;
851 890
852 if (m_invertVertical) { 891 if (m_invertVertical) {
853 m_cache->setPixel(c, cacheHeight - y - 1, pixel); 892 m_cache->setPixel(c, cacheHeight - y - 1, pixel);
854 } else { 893 } else {
855 m_cache->setPixel(c, y, pixel); 894 m_cache->setPixel(c, y, pixel);
856 } 895 }
857 } 896 }
858 } 897
898 if (peaks) {
899 size_t notch = (c % m_peakResolution);
900 if (notch == m_peakResolution-1 || c == fillEnd) {
901 size_t pc = c / m_peakResolution;
902 for (size_t y = 0; y < cacheHeight; ++y) {
903 if (m_invertVertical) {
904 m_peaksCache->setPixel(pc, cacheHeight - y - 1, peaks[y]);
905 } else {
906 m_peaksCache->setPixel(pc, y, peaks[y]);
907 }
908 }
909 for (int y = 0; y < cacheHeight; ++y) {
910 peaks[y] = 0;
911 }
912 }
913 }
914 }
915
916 delete[] peaks;
859 } 917 }
860 918
861 void 919 void
862 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const 920 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const
863 { 921 {
927 std::cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << std::endl; 985 std::cerr << "Colour3DPlotLayer::paint: height = "<< m_model->getHeight() << ", modelStart = " << modelStart << ", resolution = " << modelResolution << ", model rate = " << m_model->getSampleRate() << " (zoom level = " << v->getZoomLevel() << ", srRatio = " << srRatio << ")" << std::endl;
928 #endif 986 #endif
929 987
930 if (m_opaque || 988 if (m_opaque ||
931 int(m_model->getHeight()) >= v->height() || 989 int(m_model->getHeight()) >= v->height() ||
932 // int(modelResolution * m_model->getSampleRate()) < v->getZoomLevel() / 2) {
933 ((modelResolution * srRatio) / v->getZoomLevel()) < 2) { 990 ((modelResolution * srRatio) / v->getZoomLevel()) < 2) {
934 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 991 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
935 std::cerr << "calling paintDense" << std::endl; 992 std::cerr << "calling paintDense" << std::endl;
936 #endif 993 #endif
937 paintDense(v, paint, rect); 994 paintDense(v, paint, rect);
1029 if (!m_cache) return; 1086 if (!m_cache) return;
1030 1087
1031 float modelStart = m_model->getStartFrame(); 1088 float modelStart = m_model->getStartFrame();
1032 float modelResolution = m_model->getResolution(); 1089 float modelResolution = m_model->getResolution();
1033 1090
1034 float srRatio = 1091 int mmsr = v->getViewManager()->getMainModelSampleRate();
1035 float(v->getViewManager()->getMainModelSampleRate()) / 1092 int msr = m_model->getSampleRate();
1036 float(m_model->getSampleRate()); 1093 float srRatio = float(mmsr) / float(msr);
1037 1094
1038 int x0 = rect.left(); 1095 int x0 = rect.left();
1039 int x1 = rect.right() + 1; 1096 int x1 = rect.right() + 1;
1040 1097
1041 int w = x1 - x0; 1098 int w = x1 - x0;
1055 img.setColorTable(m_cache->colorTable()); 1112 img.setColorTable(m_cache->colorTable());
1056 1113
1057 uchar *peaks = new uchar[w]; 1114 uchar *peaks = new uchar[w];
1058 memset(peaks, 0, w); 1115 memset(peaks, 0, w);
1059 1116
1117 int zoomLevel = v->getZoomLevel();
1118
1119 QImage *source = m_cache;
1120 if (m_peaksCache &&
1121 ((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) {
1122 // std::cerr << "using peaks cache" << std::endl;
1123 source = m_peaksCache;
1124 modelResolution *= m_peakResolution;
1125 } else {
1126 // std::cerr << "not using peaks cache" << std::endl;
1127 }
1128
1060 int psy1i = -1; 1129 int psy1i = -1;
1130 int sw = source->width();
1061 1131
1062 for (int y = 0; y < h; ++y) { 1132 for (int y = 0; y < h; ++y) {
1063 1133
1064 float sy0 = symin + (float(h - y - 1) * (symax - symin)) / h; 1134 float sy0 = symin + (float(h - y - 1) * (symax - symin)) / h;
1065 float sy1 = symin + (float(h - y) * (symax - symin)) / h; 1135 float sy1 = symin + (float(h - y) * (symax - symin)) / h;
1075 1145
1076 memset(peaks, 0, w); 1146 memset(peaks, 0, w);
1077 1147
1078 for (int sy = sy0i; sy <= sy1i; ++sy) { 1148 for (int sy = sy0i; sy <= sy1i; ++sy) {
1079 1149
1080 if (sy < 0 || sy >= m_cache->height()) continue; 1150 if (sy < 0 || sy >= source->height()) continue;
1081 1151
1082 uchar *sourceLine = m_cache->scanLine(sy); 1152 uchar *sourceLine = source->scanLine(sy);
1083 1153
1084 long xf = -1, nxf = -1; 1154 long xf = -1;
1155 long nxf = v->getFrameForX(x0);
1156
1157 int nsxi = -1;
1085 1158
1086 for (int x = 0; x < w; ++x) { 1159 for (int x = 0; x < w; ++x) {
1087 1160
1088 xf = nxf; 1161 xf = nxf;
1089 nxf = v->getFrameForX(x + 1 + x0); 1162 nxf = xf + zoomLevel;
1090
1091 if (xf < 0) {
1092 xf = v->getFrameForX(x + x0);
1093 }
1094 1163
1095 if (xf < 0) { 1164 if (xf < 0) {
1096 peaks[x] = 0; 1165 peaks[x] = 0;
1097 continue; 1166 continue;
1098 } 1167 }
1103 int sx0i = int(sx0 + 0.001); 1172 int sx0i = int(sx0 + 0.001);
1104 int sx1i = int(sx1); 1173 int sx1i = int(sx1);
1105 1174
1106 uchar peak = 0; 1175 uchar peak = 0;
1107 for (int sx = sx0i; sx <= sx1i; ++sx) { 1176 for (int sx = sx0i; sx <= sx1i; ++sx) {
1108 if (sx < 0 || sx >= m_cache->width()) continue; 1177 if (sx < 0 || sx >= sw) continue;
1109 if (sourceLine[sx] > peak) peak = sourceLine[sx]; 1178 if (sourceLine[sx] > peak) peak = sourceLine[sx];
1110 } 1179 }
1111 peaks[x] = peak; 1180 peaks[x] = peak;
1112 } 1181 }
1113 } 1182 }
1115 copy: 1184 copy:
1116 for (int x = 0; x < w; ++x) { 1185 for (int x = 0; x < w; ++x) {
1117 targetLine[x] = peaks[x]; 1186 targetLine[x] = peaks[x];
1118 } 1187 }
1119 } 1188 }
1189
1190 delete[] peaks;
1120 1191
1121 paint.drawImage(x0, 0, img); 1192 paint.drawImage(x0, 0, img);
1122 } 1193 }
1123 1194
1124 bool 1195 bool