comparison layer/Colour3DPlotLayer.cpp @ 197:6b023411087b

* Work on harmonising colour and scale ranges between types of layer * Add normalize options to colour 3d plot layer
author Chris Cannam
date Thu, 01 Feb 2007 14:31:28 +0000
parents 57c2350a8c40
children c2ed5014d4ff
comparison
equal deleted inserted replaced
196:22c99c8aa1e0 197:6b023411087b
15 15
16 #include "Colour3DPlotLayer.h" 16 #include "Colour3DPlotLayer.h"
17 17
18 #include "view/View.h" 18 #include "view/View.h"
19 #include "base/Profiler.h" 19 #include "base/Profiler.h"
20 #include "base/LogRange.h"
21 #include "ColourMapper.h"
20 22
21 #include <QPainter> 23 #include <QPainter>
22 #include <QImage> 24 #include <QImage>
23 #include <QRect> 25 #include <QRect>
24 26
30 32
31 33
32 Colour3DPlotLayer::Colour3DPlotLayer() : 34 Colour3DPlotLayer::Colour3DPlotLayer() :
33 m_model(0), 35 m_model(0),
34 m_cache(0), 36 m_cache(0),
35 m_colourScale(LinearScale) 37 m_cacheStart(0),
38 m_colourScale(LinearScale),
39 m_colourMap(0),
40 m_normalizeColumns(false),
41 m_normalizeVisibleArea(false)
36 { 42 {
37 43
38 } 44 }
39 45
40 Colour3DPlotLayer::~Colour3DPlotLayer() 46 Colour3DPlotLayer::~Colour3DPlotLayer()
79 85
80 Layer::PropertyList 86 Layer::PropertyList
81 Colour3DPlotLayer::getProperties() const 87 Colour3DPlotLayer::getProperties() const
82 { 88 {
83 PropertyList list; 89 PropertyList list;
90 list.push_back("Colour");
84 list.push_back("Colour Scale"); 91 list.push_back("Colour Scale");
92 list.push_back("Normalize Columns");
93 list.push_back("Normalize Visible Area");
85 return list; 94 return list;
86 } 95 }
87 96
88 QString 97 QString
89 Colour3DPlotLayer::getPropertyLabel(const PropertyName &name) const 98 Colour3DPlotLayer::getPropertyLabel(const PropertyName &name) const
90 { 99 {
91 if (name == "Colour Scale") return tr("Colour Scale"); 100 if (name == "Colour") return tr("Colour");
101 if (name == "Colour Scale") return tr("Scale");
102 if (name == "Normalize Columns") return tr("Normalize Columns");
103 if (name == "Normalize Visible Area") return tr("Normalize Visible Area");
92 return ""; 104 return "";
93 } 105 }
94 106
95 Layer::PropertyType 107 Layer::PropertyType
96 Colour3DPlotLayer::getPropertyType(const PropertyName &name) const 108 Colour3DPlotLayer::getPropertyType(const PropertyName &name) const
97 { 109 {
110 if (name == "Normalize Columns") return ToggleProperty;
111 if (name == "Normalize Visible Area") return ToggleProperty;
98 return ValueProperty; 112 return ValueProperty;
99 } 113 }
100 114
101 QString 115 QString
102 Colour3DPlotLayer::getPropertyGroupName(const PropertyName &name) const 116 Colour3DPlotLayer::getPropertyGroupName(const PropertyName &name) const
103 { 117 {
118 if (name == "Normalize Columns" ||
119 name == "Normalize Visible Area" ||
120 name == "Colour Scale") return tr("Scale");
104 return QString(); 121 return QString();
105 } 122 }
106 123
107 int 124 int
108 Colour3DPlotLayer::getPropertyRangeAndValue(const PropertyName &name, 125 Colour3DPlotLayer::getPropertyRangeAndValue(const PropertyName &name,
115 if (!max) max = &garbage1; 132 if (!max) max = &garbage1;
116 133
117 if (name == "Colour Scale") { 134 if (name == "Colour Scale") {
118 135
119 *min = 0; 136 *min = 0;
120 *max = 3; 137 *max = 2;
121 138
122 deft = (int)m_colourScale; 139 deft = (int)m_colourScale;
140
141 } else if (name == "Colour") {
142
143 *min = 0;
144 *max = ColourMapper::getColourMapCount() - 1;
145
146 deft = m_colourMap;
147
148 } else if (name == "Normalize Columns") {
149
150 deft = (m_normalizeColumns ? 1 : 0);
151
152 } else if (name == "Normalize Visible Area") {
153
154 deft = (m_normalizeVisibleArea ? 1 : 0);
123 155
124 } else { 156 } else {
125 deft = Layer::getPropertyRangeAndValue(name, min, max); 157 deft = Layer::getPropertyRangeAndValue(name, min, max);
126 } 158 }
127 159
130 162
131 QString 163 QString
132 Colour3DPlotLayer::getPropertyValueLabel(const PropertyName &name, 164 Colour3DPlotLayer::getPropertyValueLabel(const PropertyName &name,
133 int value) const 165 int value) const
134 { 166 {
167 if (name == "Colour") {
168 return ColourMapper::getColourMapName(value);
169 }
135 if (name == "Colour Scale") { 170 if (name == "Colour Scale") {
136 switch (value) { 171 switch (value) {
137 default: 172 default:
138 case 0: return tr("Linear"); 173 case 0: return tr("Linear Scale");
139 case 1: return tr("Absolute"); 174 case 1: return tr("Log Scale");
140 case 2: return tr("Meter"); 175 case 2: return tr("+/-1 Scale");
141 case 3: return tr("dB");
142 } 176 }
143 } 177 }
144 return tr("<unknown>"); 178 return tr("<unknown>");
145 } 179 }
146 180
149 { 183 {
150 if (name == "Colour Scale") { 184 if (name == "Colour Scale") {
151 switch (value) { 185 switch (value) {
152 default: 186 default:
153 case 0: setColourScale(LinearScale); break; 187 case 0: setColourScale(LinearScale); break;
154 case 1: setColourScale(AbsoluteScale); break; 188 case 1: setColourScale(LogScale); break;
155 case 2: setColourScale(MeterScale); break; 189 case 2: setColourScale(PlusMinusOneScale); break;
156 case 3: setColourScale(dBScale); break;
157 } 190 }
191 } else if (name == "Colour") {
192 setColourMap(value);
193 } else if (name == "Normalize Columns") {
194 setNormalizeColumns(value ? true : false);
195 } else if (name == "Normalize Visible Area") {
196 setNormalizeVisibleArea(value ? true : false);
158 } 197 }
159 } 198 }
160 199
161 void 200 void
162 Colour3DPlotLayer::setColourScale(ColourScale scale) 201 Colour3DPlotLayer::setColourScale(ColourScale scale)
165 m_colourScale = scale; 204 m_colourScale = scale;
166 cacheInvalid(); 205 cacheInvalid();
167 emit layerParametersChanged(); 206 emit layerParametersChanged();
168 } 207 }
169 208
209 void
210 Colour3DPlotLayer::setColourMap(int map)
211 {
212 if (m_colourMap == map) return;
213 m_colourMap = map;
214 cacheInvalid();
215 emit layerParametersChanged();
216 }
217
218 void
219 Colour3DPlotLayer::setNormalizeColumns(bool n)
220 {
221 if (m_normalizeColumns == n) return;
222 m_normalizeColumns = n;
223 cacheInvalid();
224 emit layerParametersChanged();
225 }
226
227 bool
228 Colour3DPlotLayer::getNormalizeColumns() const
229 {
230 return m_normalizeColumns;
231 }
232
233 void
234 Colour3DPlotLayer::setNormalizeVisibleArea(bool n)
235 {
236 if (m_normalizeVisibleArea == n) return;
237 m_normalizeVisibleArea = n;
238 cacheInvalid();
239 emit layerParametersChanged();
240 }
241
242 bool
243 Colour3DPlotLayer::getNormalizeVisibleArea() const
244 {
245 return m_normalizeVisibleArea;
246 }
247
170 bool 248 bool
171 Colour3DPlotLayer::isLayerScrollable(const View *v) const 249 Colour3DPlotLayer::isLayerScrollable(const View *v) const
172 { 250 {
251 if (m_normalizeVisibleArea) return false;
173 QPoint discard; 252 QPoint discard;
174 return !v->shouldIlluminateLocalFeatures(this, discard); 253 return !v->shouldIlluminateLocalFeatures(this, discard);
175 } 254 }
176 255
177 QString 256 QString
293 paint.drawText(cw + 5, ty, text); 372 paint.drawText(cw + 5, ty, text);
294 } 373 }
295 } 374 }
296 375
297 void 376 void
377 Colour3DPlotLayer::getColumn(size_t col,
378 DenseThreeDimensionalModel::Column &values) const
379 {
380 m_model->getColumn(col, values);
381
382 float colMax = 0.f;
383
384 float min = 0.f, max = 0.f;
385 if (m_normalizeColumns) {
386 min = m_model->getMinimumLevel();
387 max = m_model->getMaximumLevel();
388 }
389
390 if (m_normalizeColumns) {
391 for (size_t y = 0; y < values.size(); ++y) {
392 if (values[y] > colMax || y == 0) colMax = values[y];
393 }
394 if (m_colourScale == LogScale) {
395 colMax = LogRange::map(colMax);
396 }
397 }
398
399 for (size_t y = 0; y < values.size(); ++y) {
400
401 float value = min;
402
403 value = values[y];
404 if (m_colourScale == LogScale) {
405 value = LogRange::map(value);
406 }
407
408 if (m_normalizeColumns) {
409 if (colMax != 0) {
410 value = max * (value / colMax);
411 } else {
412 value = 0;
413 }
414 }
415
416 values[y] = value;
417 }
418 }
419
420 void
421 Colour3DPlotLayer::fillCache(size_t firstBin, size_t lastBin) const
422 {
423 size_t modelStart = m_model->getStartFrame();
424 size_t modelEnd = m_model->getEndFrame();
425 size_t modelResolution = m_model->getResolution();
426
427 std::cerr << "Colour3DPlotLayer::fillCache: " << firstBin << " -> " << lastBin << std::endl;
428
429 if (!m_normalizeVisibleArea || m_normalizeColumns) {
430 firstBin = modelStart / modelResolution;
431 lastBin = modelEnd / modelResolution;
432 }
433
434 size_t cacheWidth = lastBin - firstBin + 1;
435 size_t cacheHeight = m_model->getHeight();
436
437 if (m_cache &&
438 (m_cacheStart != firstBin ||
439 m_cache->width() != cacheWidth ||
440 m_cache->height() != cacheHeight)) {
441
442 delete m_cache;
443 m_cache = 0;
444 }
445
446 if (m_cache) return;
447
448 m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8);
449 m_cacheStart = firstBin;
450
451 std::cerr << "Cache size " << cacheWidth << "x" << cacheHeight << " starting " << m_cacheStart << std::endl;
452
453 m_cache->setNumColors(256);
454 DenseThreeDimensionalModel::Column values;
455
456 float min = m_model->getMinimumLevel();
457 float max = m_model->getMaximumLevel();
458
459 if (m_colourScale == LogScale) {
460 LogRange::mapRange(min, max);
461 } else if (m_colourScale == PlusMinusOneScale) {
462 min = -1.f;
463 max = 1.f;
464 }
465
466 if (max == min) max = min + 1.0;
467
468 ColourMapper mapper(m_colourMap, 0.f, 255.f);
469
470 for (int index = 0; index < 256; ++index) {
471
472 QColor colour = mapper.map(index);
473 m_cache->setColor(index, qRgb(colour.red(), colour.green(), colour.blue()));
474 }
475
476 m_cache->fill(0);
477
478 float visibleMax = 0.f;
479
480 if (m_normalizeVisibleArea && !m_normalizeColumns) {
481
482 for (size_t c = firstBin; c <= lastBin; ++c) {
483
484 values.clear();
485 getColumn(c, values);
486
487 float colMax = 0.f;
488
489 for (size_t y = 0; y < m_model->getHeight(); ++y) {
490 if (y >= values.size()) break;
491 if (y == 0 || values[y] > colMax) colMax = values[y];
492 }
493
494 if (c == firstBin || colMax > visibleMax) visibleMax = colMax;
495 }
496 }
497
498 for (size_t c = firstBin; c <= lastBin; ++c) {
499
500 values.clear();
501 getColumn(c, values);
502
503 for (size_t y = 0; y < m_model->getHeight(); ++y) {
504
505 float value = min;
506 if (y < values.size()) {
507 value = values[y];
508 }
509
510 if (m_normalizeVisibleArea && !m_normalizeColumns) {
511 if (visibleMax != 0) {
512 value = max * (value / visibleMax);
513 }
514 }
515
516 int pixel = int(((value - min) * 256) / (max - min));
517 if (pixel < 0) pixel = 0;
518 if (pixel > 255) pixel = 255;
519
520 m_cache->setPixel(c - firstBin, y, pixel);
521 }
522 }
523 }
524
525 void
298 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const 526 Colour3DPlotLayer::paint(View *v, QPainter &paint, QRect rect) const
299 { 527 {
300 // Profiler profiler("Colour3DPlotLayer::paint"); 528 // Profiler profiler("Colour3DPlotLayer::paint");
301 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 529 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
302 std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl; 530 std::cerr << "Colour3DPlotLayer::paint(): m_model is " << m_model << ", zoom level is " << v->getZoomLevel() << std::endl;
309 10, QColor(120, 120, 120)); 537 10, QColor(120, 120, 120));
310 } 538 }
311 return; 539 return;
312 } 540 }
313 541
542 if (m_normalizeVisibleArea && !m_normalizeColumns) rect = v->rect();
543
314 size_t modelStart = m_model->getStartFrame(); 544 size_t modelStart = m_model->getStartFrame();
315 size_t modelEnd = m_model->getEndFrame(); 545 size_t modelEnd = m_model->getEndFrame();
316 size_t modelResolution = m_model->getResolution(); 546 size_t modelResolution = m_model->getResolution();
317 547
318 size_t cacheWidth = (modelEnd - modelStart) / modelResolution + 1; 548 // The cache is from the model's start frame to the model's end
319 size_t cacheHeight = m_model->getHeight(); 549 // frame at the model's window increment frames per pixel. We
320 550 // want to draw from our start frame + x0 * zoomLevel to our start
321 if (m_cache && 551 // frame + x1 * zoomLevel at zoomLevel frames per pixel.
322 (m_cache->width() != cacheWidth || 552
323 m_cache->height() != cacheHeight)) { 553 // We have quite different paint mechanisms for rendering "large"
324 554 // bins (more than one bin per pixel in both directions) and
325 delete m_cache; 555 // "small". This is "large"; see paintDense below for "small".
326 m_cache = 0; 556
327 } 557 int x0 = rect.left();
328 558 int x1 = rect.right() + 1;
329 if (!m_cache) { 559
330 560 int h = v->height();
331 m_cache = new QImage(cacheWidth, cacheHeight, QImage::Format_Indexed8); 561
332 562 float srRatio =
333 std::cerr << "Cache size " << cacheWidth << "x" << cacheHeight << std::endl; 563 float(v->getViewManager()->getMainModelSampleRate()) /
334 564 float(m_model->getSampleRate());
335 m_cache->setNumColors(256); 565
336 DenseThreeDimensionalModel::Column values; 566 int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart))
337 567 / long(modelResolution));
338 float min = m_model->getMinimumLevel(); 568 int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart))
339 float max = m_model->getMaximumLevel(); 569 / long(modelResolution));
340 570 int sh = m_model->getHeight();
341 if (max == min) max = min + 1.0; 571
342 572 if (sx0 > 0) --sx0;
343 int zeroIndex = 0; 573 fillCache(sx0 < 0 ? 0 : sx0,
344 if (min < 0.f) { 574 sx1 < 0 ? 0 : sx1);
345 if (m_colourScale == LinearScale) {
346 zeroIndex = int(((-min) * 256) / (max - min));
347 } else {
348 max = std::max(-min, max);
349 min = 0;
350 }
351 }
352 if (zeroIndex < 0) zeroIndex = 0;
353 if (zeroIndex > 255) zeroIndex = 255;
354
355 //!!! want this and spectrogram to share a colour mapping unit
356
357 for (int index = 0; index < 256; ++index) {
358 int effective = abs(((index - zeroIndex) * 255) /
359 std::max(255 - zeroIndex, zeroIndex));
360 int hue = 256 - effective;
361 if (zeroIndex > 0) {
362 if (index <= zeroIndex) hue = 255;
363 else hue = 0;
364 }
365 while (hue < 0) hue += 255;
366 while (hue > 255) hue -= 255;
367 int saturation = effective / 2 + 128;
368 if (saturation < 0) saturation = -saturation;
369 if (saturation > 255) saturation = 255;
370 int value = effective;
371 if (value < 0) value = -value;
372 if (value > 255) value = 255;
373 // std::cerr << "min: " << min << ", max: " << max << ", zi " << zeroIndex << ", index " << index << ": " << hue << ", " << saturation << ", " << value << std::endl;
374 QColor colour = QColor::fromHsv(hue, saturation, value);
375 // std::cerr << "rgb: " << colour.red() << "," << colour.green() << "," << colour.blue() << std::endl;
376 m_cache->setColor(index, qRgb(colour.red(), colour.green(), colour.blue()));
377 }
378
379 m_cache->fill(zeroIndex);
380
381 for (size_t f = modelStart; f <= modelEnd; f += modelResolution) {
382
383 values.clear();
384 m_model->getColumn(f / modelResolution, values);
385
386 for (size_t y = 0; y < m_model->getHeight(); ++y) {
387
388 float value = min;
389 if (y < values.size()) {
390 value = values[y];
391 if (m_colourScale != LinearScale) {
392 value = fabs(value);
393 }
394 }
395
396 int pixel = int(((value - min) * 256) / (max - min));
397 if (pixel < 0) pixel = 0;
398 if (pixel > 255) pixel = 255;
399
400 m_cache->setPixel(f / modelResolution, y, pixel);
401 }
402 }
403 }
404 575
405 if (m_model->getHeight() >= v->height() || 576 if (m_model->getHeight() >= v->height() ||
406 modelResolution < v->getZoomLevel() / 2) { 577 modelResolution < v->getZoomLevel() / 2) {
407 paintDense(v, paint, rect); 578 paintDense(v, paint, rect);
408 return; 579 return;
409 } 580 }
410 581
411 int x0 = rect.left();
412 int x1 = rect.right() + 1;
413
414 int h = v->height();
415
416 // The cache is from the model's start frame to the model's end
417 // frame at the model's window increment frames per pixel. We
418 // want to draw from our start frame + x0 * zoomLevel to our start
419 // frame + x1 * zoomLevel at zoomLevel frames per pixel.
420
421 //!!! Strictly speaking we want quite different paint mechanisms
422 //for models that have more than one bin per pixel in either
423 //direction. This one is only really appropriate for models with
424 //far fewer bins in both directions.
425
426 float srRatio =
427 float(v->getViewManager()->getMainModelSampleRate()) /
428 float(m_model->getSampleRate());
429
430 int sx0 = int((v->getFrameForX(x0) / srRatio - long(modelStart)) / long(modelResolution));
431 int sx1 = int((v->getFrameForX(x1) / srRatio - long(modelStart)) / long(modelResolution));
432 int sh = m_model->getHeight();
433
434 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT 582 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT
435 std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl; 583 std::cerr << "Colour3DPlotLayer::paint: w " << w << ", h " << h << ", sx0 " << sx0 << ", sx1 " << sx1 << ", sw " << sw << ", sh " << sh << std::endl;
436 std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << std::endl; 584 std::cerr << "Colour3DPlotLayer: sample rate is " << m_model->getSampleRate() << ", resolution " << m_model->getResolution() << std::endl;
437 #endif 585 #endif
438 586
439 QPoint illuminatePos; 587 QPoint illuminatePos;
440 bool illuminate = v->shouldIlluminateLocalFeatures(this, illuminatePos); 588 bool illuminate = v->shouldIlluminateLocalFeatures(this, illuminatePos);
441 char labelbuf[10]; 589 char labelbuf[10];
442 590
443 for (int sx = sx0 - 1; sx <= sx1; ++sx) { 591 for (int sx = sx0; sx <= sx1; ++sx) {
444 592
593 int scx = 0;
594 if (sx > m_cacheStart) scx = sx - m_cacheStart;
595
445 int fx = sx * int(modelResolution); 596 int fx = sx * int(modelResolution);
446 597
447 if (fx + modelResolution < int(modelStart) || 598 if (fx + modelResolution < int(modelStart) ||
448 fx > int(modelEnd)) continue; 599 fx > int(modelEnd)) continue;
449 600
459 610
460 for (int sy = 0; sy < sh; ++sy) { 611 for (int sy = 0; sy < sh; ++sy) {
461 612
462 int ry0 = h - (sy * h) / sh - 1; 613 int ry0 = h - (sy * h) / sh - 1;
463 QRgb pixel = qRgb(255, 255, 255); 614 QRgb pixel = qRgb(255, 255, 255);
464 if (sx >= 0 && sx < m_cache->width() && 615 if (scx >= 0 && scx < m_cache->width() &&
465 sy >= 0 && sy < m_cache->height()) { 616 sy >= 0 && sy < m_cache->height()) {
466 pixel = m_cache->pixel(sx, sy); 617 pixel = m_cache->pixel(scx, sy);
467 } 618 }
468 619
469 QRect r(rx0, ry0 - h / sh - 1, rw, h / sh + 1); 620 QRect r(rx0, ry0 - h / sh - 1, rw, h / sh + 1);
470 621
471 if (rw == 1) { 622 if (rw == 1) {
497 #endif 648 #endif
498 649
499 paint.drawRect(r); 650 paint.drawRect(r);
500 651
501 if (showLabel) { 652 if (showLabel) {
502 if (sx >= 0 && sx < m_cache->width() && 653 if (scx >= 0 && scx < m_cache->width() &&
503 sy >= 0 && sy < m_cache->height()) { 654 sy >= 0 && sy < m_cache->height()) {
504 float value = m_model->getValueAt(sx, sy); 655 float value = m_model->getValueAt(scx, sy);
505 sprintf(labelbuf, "%06f", value); 656 sprintf(labelbuf, "%06f", value);
506 QString text(labelbuf); 657 QString text(labelbuf);
507 paint.setPen(Qt::white); 658 paint.setPen(Qt::white);
508 paint.drawText(rx0 + 2, 659 paint.drawText(rx0 + 2,
509 ry0 - h / sh - 1 + 2 + paint.fontMetrics().ascent(), 660 ry0 - h / sh - 1 + 2 + paint.fontMetrics().ascent(),
564 float mag = 0.0, div = 0.0; 715 float mag = 0.0, div = 0.0;
565 int max = 0; 716 int max = 0;
566 717
567 for (int sx = sx0i; sx <= sx1i; ++sx) { 718 for (int sx = sx0i; sx <= sx1i; ++sx) {
568 719
569 if (sx < 0 || sx >= m_cache->width()) continue; 720 int scx = 0;
721 if (sx > m_cacheStart) scx = sx - m_cacheStart;
722
723 if (scx < 0 || scx >= m_cache->width()) continue;
570 724
571 for (int sy = sy0i; sy <= sy1i; ++sy) { 725 for (int sy = sy0i; sy <= sy1i; ++sy) {
572 726
573 if (sy < 0 || sy >= m_cache->height()) continue; 727 if (sy < 0 || sy >= m_cache->height()) continue;
574 728
576 if (sx == sx0i) prop *= (sx + 1) - sx0; 730 if (sx == sx0i) prop *= (sx + 1) - sx0;
577 if (sx == sx1i) prop *= sx1 - sx; 731 if (sx == sx1i) prop *= sx1 - sx;
578 if (sy == sy0i) prop *= (sy + 1) - sy0; 732 if (sy == sy0i) prop *= (sy + 1) - sy0;
579 if (sy == sy1i) prop *= sy1 - sy; 733 if (sy == sy1i) prop *= sy1 - sy;
580 734
581 mag += prop * m_cache->pixelIndex(sx, sy); 735 mag += prop * m_cache->pixelIndex(scx, sy);
582 max = std::max(max, m_cache->pixelIndex(sx, sy)); 736 max = std::max(max, m_cache->pixelIndex(scx, sy));
583 div += prop; 737 div += prop;
584 } 738 }
585 } 739 }
586 740
587 if (div != 0) mag /= div; 741 if (div != 0) mag /= div;
622 } 776 }
623 777
624 return true; 778 return true;
625 } 779 }
626 780
781 QString
782 Colour3DPlotLayer::toXmlString(QString indent, QString extraAttributes) const
783 {
784 QString s;
785
786 s += QString("scale=\"%1\" "
787 "colourScheme=\"%2\" "
788 "normalizeColumns=\"%3\" "
789 "normalizeVisibleArea=\"%4\"")
790 .arg((int)m_colourScale)
791 .arg(m_colourMap)
792 .arg(m_normalizeColumns ? "true" : "false")
793 .arg(m_normalizeVisibleArea ? "true" : "false");
794
795 return Layer::toXmlString(indent, extraAttributes + " " + s);
796 }
797
798 void
799 Colour3DPlotLayer::setProperties(const QXmlAttributes &attributes)
800 {
801 bool ok = false;
802
803 ColourScale scale = (ColourScale)attributes.value("scale").toInt(&ok);
804 if (ok) setColourScale(scale);
805
806 int colourMap = attributes.value("colourScheme").toInt(&ok);
807 if (ok) setColourMap(colourMap);
808
809 bool normalizeColumns =
810 (attributes.value("normalizeColumns").trimmed() == "true");
811 setNormalizeColumns(normalizeColumns);
812
813 bool normalizeVisibleArea =
814 (attributes.value("normalizeVisibleArea").trimmed() == "true");
815 setNormalizeVisibleArea(normalizeVisibleArea);
816 }
817
627 #ifdef INCLUDE_MOCFILES 818 #ifdef INCLUDE_MOCFILES
628 #include "Colour3DPlotLayer.moc.cpp" 819 #include "Colour3DPlotLayer.moc.cpp"
629 #endif 820 #endif
630 821
631 822