Mercurial > hg > svgui
comparison layer/Colour3DPlotLayer.cpp @ 535:78f9436195b1
* Add smoothing option to colour 3d plot
| author | Chris Cannam | 
|---|---|
| date | Fri, 22 May 2009 13:54:45 +0000 | 
| parents | 7a560380b6e2 | 
| children | aca01b3af29f | 
   comparison
  equal
  deleted
  inserted
  replaced
| 534:7a560380b6e2 | 535:78f9436195b1 | 
|---|---|
| 47 m_binScale(LinearBinScale), | 47 m_binScale(LinearBinScale), | 
| 48 m_normalizeColumns(false), | 48 m_normalizeColumns(false), | 
| 49 m_normalizeVisibleArea(false), | 49 m_normalizeVisibleArea(false), | 
| 50 m_invertVertical(false), | 50 m_invertVertical(false), | 
| 51 m_opaque(false), | 51 m_opaque(false), | 
| 52 m_smooth(false), | |
| 52 m_miny(0), | 53 m_miny(0), | 
| 53 m_maxy(0) | 54 m_maxy(0) | 
| 54 { | 55 { | 
| 55 | 56 | 
| 56 } | 57 } | 
| 153 list.push_back("Normalize Visible Area"); | 154 list.push_back("Normalize Visible Area"); | 
| 154 list.push_back("Gain"); | 155 list.push_back("Gain"); | 
| 155 list.push_back("Bin Scale"); | 156 list.push_back("Bin Scale"); | 
| 156 list.push_back("Invert Vertical Scale"); | 157 list.push_back("Invert Vertical Scale"); | 
| 157 list.push_back("Opaque"); | 158 list.push_back("Opaque"); | 
| 159 list.push_back("Smooth"); | |
| 158 return list; | 160 return list; | 
| 159 } | 161 } | 
| 160 | 162 | 
| 161 QString | 163 QString | 
| 162 Colour3DPlotLayer::getPropertyLabel(const PropertyName &name) const | 164 Colour3DPlotLayer::getPropertyLabel(const PropertyName &name) const | 
| 166 if (name == "Normalize Columns") return tr("Normalize Columns"); | 168 if (name == "Normalize Columns") return tr("Normalize Columns"); | 
| 167 if (name == "Normalize Visible Area") return tr("Normalize Visible Area"); | 169 if (name == "Normalize Visible Area") return tr("Normalize Visible Area"); | 
| 168 if (name == "Invert Vertical Scale") return tr("Invert Vertical Scale"); | 170 if (name == "Invert Vertical Scale") return tr("Invert Vertical Scale"); | 
| 169 if (name == "Gain") return tr("Gain"); | 171 if (name == "Gain") return tr("Gain"); | 
| 170 if (name == "Opaque") return tr("Always Opaque"); | 172 if (name == "Opaque") return tr("Always Opaque"); | 
| 173 if (name == "Smooth") return tr("Smooth"); | |
| 171 if (name == "Bin Scale") return tr("Bin Scale"); | 174 if (name == "Bin Scale") return tr("Bin Scale"); | 
| 172 return ""; | 175 return ""; | 
| 173 } | 176 } | 
| 174 | 177 | 
| 175 QString | 178 QString | 
| 177 { | 180 { | 
| 178 if (name == "Normalize Columns") return "normalise-columns"; | 181 if (name == "Normalize Columns") return "normalise-columns"; | 
| 179 if (name == "Normalize Visible Area") return "normalise"; | 182 if (name == "Normalize Visible Area") return "normalise"; | 
| 180 if (name == "Invert Vertical Scale") return "invert-vertical"; | 183 if (name == "Invert Vertical Scale") return "invert-vertical"; | 
| 181 if (name == "Opaque") return "opaque"; | 184 if (name == "Opaque") return "opaque"; | 
| 185 if (name == "Smooth") return "smooth"; | |
| 182 return ""; | 186 return ""; | 
| 183 } | 187 } | 
| 184 | 188 | 
| 185 Layer::PropertyType | 189 Layer::PropertyType | 
| 186 Colour3DPlotLayer::getPropertyType(const PropertyName &name) const | 190 Colour3DPlotLayer::getPropertyType(const PropertyName &name) const | 
| 188 if (name == "Gain") return RangeProperty; | 192 if (name == "Gain") return RangeProperty; | 
| 189 if (name == "Normalize Columns") return ToggleProperty; | 193 if (name == "Normalize Columns") return ToggleProperty; | 
| 190 if (name == "Normalize Visible Area") return ToggleProperty; | 194 if (name == "Normalize Visible Area") return ToggleProperty; | 
| 191 if (name == "Invert Vertical Scale") return ToggleProperty; | 195 if (name == "Invert Vertical Scale") return ToggleProperty; | 
| 192 if (name == "Opaque") return ToggleProperty; | 196 if (name == "Opaque") return ToggleProperty; | 
| 197 if (name == "Smooth") return ToggleProperty; | |
| 193 return ValueProperty; | 198 return ValueProperty; | 
| 194 } | 199 } | 
| 195 | 200 | 
| 196 QString | 201 QString | 
| 197 Colour3DPlotLayer::getPropertyGroupName(const PropertyName &name) const | 202 Colour3DPlotLayer::getPropertyGroupName(const PropertyName &name) const | 
| 201 name == "Colour Scale" || | 206 name == "Colour Scale" || | 
| 202 name == "Gain") return tr("Scale"); | 207 name == "Gain") return tr("Scale"); | 
| 203 if (name == "Bin Scale" || | 208 if (name == "Bin Scale" || | 
| 204 name == "Invert Vertical Scale") return tr("Bins"); | 209 name == "Invert Vertical Scale") return tr("Bins"); | 
| 205 if (name == "Opaque" || | 210 if (name == "Opaque" || | 
| 211 name == "Smooth" || | |
| 206 name == "Colour") return tr("Colour"); | 212 name == "Colour") return tr("Colour"); | 
| 207 return QString(); | 213 return QString(); | 
| 208 } | 214 } | 
| 209 | 215 | 
| 210 int | 216 int | 
| 271 | 277 | 
| 272 } else if (name == "Opaque") { | 278 } else if (name == "Opaque") { | 
| 273 | 279 | 
| 274 *deflt = 0; | 280 *deflt = 0; | 
| 275 val = (m_opaque ? 1 : 0); | 281 val = (m_opaque ? 1 : 0); | 
| 282 | |
| 283 } else if (name == "Smooth") { | |
| 284 | |
| 285 *deflt = 0; | |
| 286 val = (m_smooth ? 1 : 0); | |
| 276 | 287 | 
| 277 } else { | 288 } else { | 
| 278 val = Layer::getPropertyRangeAndValue(name, min, max, deflt); | 289 val = Layer::getPropertyRangeAndValue(name, min, max, deflt); | 
| 279 } | 290 } | 
| 280 | 291 | 
| 337 setNormalizeVisibleArea(value ? true : false); | 348 setNormalizeVisibleArea(value ? true : false); | 
| 338 } else if (name == "Invert Vertical Scale") { | 349 } else if (name == "Invert Vertical Scale") { | 
| 339 setInvertVertical(value ? true : false); | 350 setInvertVertical(value ? true : false); | 
| 340 } else if (name == "Opaque") { | 351 } else if (name == "Opaque") { | 
| 341 setOpaque(value ? true : false); | 352 setOpaque(value ? true : false); | 
| 353 } else if (name == "Smooth") { | |
| 354 setSmooth(value ? true : false); | |
| 342 } else if (name == "Bin Scale") { | 355 } else if (name == "Bin Scale") { | 
| 343 switch (value) { | 356 switch (value) { | 
| 344 default: | 357 default: | 
| 345 case 0: setBinScale(LinearBinScale); break; | 358 case 0: setBinScale(LinearBinScale); break; | 
| 346 case 1: setBinScale(LogBinScale); break; | 359 case 1: setBinScale(LogBinScale); break; | 
| 442 if (m_opaque == n) return; | 455 if (m_opaque == n) return; | 
| 443 m_opaque = n; | 456 m_opaque = n; | 
| 444 emit layerParametersChanged(); | 457 emit layerParametersChanged(); | 
| 445 } | 458 } | 
| 446 | 459 | 
| 460 void | |
| 461 Colour3DPlotLayer::setSmooth(bool n) | |
| 462 { | |
| 463 if (m_smooth == n) return; | |
| 464 m_smooth = n; | |
| 465 emit layerParametersChanged(); | |
| 466 } | |
| 467 | |
| 447 bool | 468 bool | 
| 448 Colour3DPlotLayer::getInvertVertical() const | 469 Colour3DPlotLayer::getInvertVertical() const | 
| 449 { | 470 { | 
| 450 return m_invertVertical; | 471 return m_invertVertical; | 
| 451 } | 472 } | 
| 452 | 473 | 
| 453 bool | 474 bool | 
| 454 Colour3DPlotLayer::getOpaque() const | 475 Colour3DPlotLayer::getOpaque() const | 
| 455 { | 476 { | 
| 456 return m_opaque; | 477 return m_opaque; | 
| 478 } | |
| 479 | |
| 480 bool | |
| 481 Colour3DPlotLayer::getSmooth() const | |
| 482 { | |
| 483 return m_smooth; | |
| 457 } | 484 } | 
| 458 | 485 | 
| 459 void | 486 void | 
| 460 Colour3DPlotLayer::setLayerDormant(const View *v, bool dormant) | 487 Colour3DPlotLayer::setLayerDormant(const View *v, bool dormant) | 
| 461 { | 488 { | 
| 1184 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT | 1211 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT | 
| 1185 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; | 1212 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; | 
| 1186 #endif | 1213 #endif | 
| 1187 | 1214 | 
| 1188 if (m_opaque || | 1215 if (m_opaque || | 
| 1216 m_smooth || | |
| 1189 int(m_model->getHeight()) >= v->height() || | 1217 int(m_model->getHeight()) >= v->height() || | 
| 1190 ((modelResolution * srRatio) / v->getZoomLevel()) < 2) { | 1218 ((modelResolution * srRatio) / v->getZoomLevel()) < 2) { | 
| 1191 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT | 1219 #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT | 
| 1192 std::cerr << "calling paintDense" << std::endl; | 1220 std::cerr << "calling paintDense" << std::endl; | 
| 1193 #endif | 1221 #endif | 
| 1340 int sw = source->width(); | 1368 int sw = source->width(); | 
| 1341 | 1369 | 
| 1342 long xf = -1; | 1370 long xf = -1; | 
| 1343 long nxf = v->getFrameForX(x0); | 1371 long nxf = v->getFrameForX(x0); | 
| 1344 | 1372 | 
| 1345 int sxa[w * 2]; | 1373 float epsilon = 0.000001; | 
| 1374 | |
| 1375 float sxa[w * 2]; | |
| 1346 for (int x = 0; x < w; ++x) { | 1376 for (int x = 0; x < w; ++x) { | 
| 1347 | 1377 | 
| 1348 xf = nxf; | 1378 xf = nxf; | 
| 1349 nxf = xf + zoomLevel; | 1379 nxf = xf + zoomLevel; | 
| 1350 | 1380 | 
| 1351 float sx0 = (float(xf) / srRatio - modelStart) / modelResolution; | 1381 float sx0 = (float(xf) / srRatio - modelStart) / modelResolution; | 
| 1352 float sx1 = (float(nxf) / srRatio - modelStart) / modelResolution; | 1382 float sx1 = (float(nxf) / srRatio - modelStart) / modelResolution; | 
| 1353 | 1383 | 
| 1354 int sx0i = int(sx0 + 0.001); | 1384 sxa[x*2] = sx0; | 
| 1355 int sx1i = int(sx1); | 1385 sxa[x*2 + 1] = sx1; | 
| 1356 | |
| 1357 sxa[x*2] = sx0i; | |
| 1358 sxa[x*2 + 1] = sx1i; | |
| 1359 } | 1386 } | 
| 1360 | 1387 | 
| 1361 float logmin = symin+1, logmax = symax+1; | 1388 float logmin = symin+1, logmax = symax+1; | 
| 1362 LogRange::mapRange(logmin, logmax); | 1389 LogRange::mapRange(logmin, logmax); | 
| 1363 | 1390 | 
| 1364 for (int y = 0; y < h; ++y) { | 1391 if (m_smooth) { | 
| 1365 | |
| 1366 float sy0, sy1; | |
| 1367 | |
| 1368 sy0 = getBinForY(v, y + 1); | |
| 1369 sy1 = getBinForY(v, y); | |
| 1370 /* | |
| 1371 if (m_binScale == LinearBinScale) { | |
| 1372 sy0 = symin + (float(h - y - 1) * (symax - symin)) / h; | |
| 1373 sy1 = symin + (float(h - y) * (symax - symin)) / h; | |
| 1374 } else { | |
| 1375 // float logmin = LogRange::map(symin); | |
| 1376 // float logmax = LogRange::map(symax); | |
| 1377 sy0 = logmin + (float(h - y - 1) * (logmax - logmin)) / h; | |
| 1378 sy1 = logmin + (float(h - y) * (logmax - logmin)) / h; | |
| 1379 sy0 = LogRange::unmap(sy0)-1; | |
| 1380 sy1 = LogRange::unmap(sy1)-1; | |
| 1381 // sy0 = pow10f(sy0); | |
| 1382 // sy1 = pow10f(sy1); | |
| 1383 } | |
| 1384 */ | |
| 1385 int sy0i = int(sy0 + 0.001); | |
| 1386 int sy1i = int(sy1); | |
| 1387 | |
| 1388 uchar *targetLine = img.scanLine(y); | |
| 1389 | |
| 1390 if (sy0i == sy1i && sy0i == psy1i) { // same scan line as just computed | |
| 1391 goto copy; | |
| 1392 } | |
| 1393 | |
| 1394 for (int x = 0; x < w; ++x) { | |
| 1395 peaks[x] = 0; | |
| 1396 } | |
| 1397 | 1392 | 
| 1398 for (int sy = sy0i; sy <= sy1i; ++sy) { | 1393 for (int y = 0; y < h; ++y) { | 
| 1399 | 1394 | 
| 1400 if (sy < 0 || sy >= source->height()) continue; | 1395 float sy = getBinForY(v, y) - 0.5; | 
| 1401 | 1396 int syi = int(sy + epsilon); | 
| 1402 uchar *sourceLine = source->scanLine(sy); | 1397 if (syi < 0 || syi >= source->height()) continue; | 
| 1398 | |
| 1399 uchar *targetLine = img.scanLine(y); | |
| 1400 uchar *sourceLine = source->scanLine(syi); | |
| 1401 uchar *nextSource; | |
| 1402 if (syi + 1 < source->height()) { | |
| 1403 nextSource = source->scanLine(syi + 1); | |
| 1404 } else { | |
| 1405 nextSource = sourceLine; | |
| 1406 } | |
| 1407 | |
| 1408 for (int x = 0; x < w; ++x) { | |
| 1409 | |
| 1410 targetLine[x] = 0; | |
| 1411 | |
| 1412 float sx0 = sxa[x*2]; | |
| 1413 int sx0i = int(sx0 + epsilon); | |
| 1414 if (sx0i >= sw) break; | |
| 1415 if (sx0i < 0) continue; | |
| 1416 | |
| 1417 float a, b, value; | |
| 1418 | |
| 1419 float sx1 = sxa[x*2+1]; | |
| 1420 if (sx1 > sx0 + 1.f) { | |
| 1421 int sx1i = int(sx1); | |
| 1422 bool have = false; | |
| 1423 for (int sx = sx0i; sx <= sx1i; ++sx) { | |
| 1424 if (sx < 0 || sx >= sw) continue; | |
| 1425 if (!have) { | |
| 1426 a = float(sourceLine[sx]); | |
| 1427 b = float(nextSource[sx]); | |
| 1428 have = true; | |
| 1429 } else { | |
| 1430 a = std::max(a, float(sourceLine[sx])); | |
| 1431 b = std::max(b, float(nextSource[sx])); | |
| 1432 } | |
| 1433 } | |
| 1434 float yprop = sy - syi; | |
| 1435 value = (a * (1.f - yprop) + b * yprop); | |
| 1436 } else { | |
| 1437 a = float(sourceLine[sx0i]); | |
| 1438 b = float(nextSource[sx0i]); | |
| 1439 float yprop = sy - syi; | |
| 1440 value = (a * (1.f - yprop) + b * yprop); | |
| 1441 int oi = sx0i + 1; | |
| 1442 float xprop = sx0 - sx0i; | |
| 1443 xprop -= 0.5; | |
| 1444 if (xprop < 0) { | |
| 1445 oi = sx0i - 1; | |
| 1446 xprop = -xprop; | |
| 1447 } | |
| 1448 if (oi < 0 || oi >= sw) oi = sx0i; | |
| 1449 a = float(sourceLine[oi]); | |
| 1450 b = float(nextSource[oi]); | |
| 1451 value = (value * (1.f - xprop) + | |
| 1452 (a * (1.f - yprop) + b * yprop) * xprop); | |
| 1453 } | |
| 1454 | |
| 1455 int vi = lrintf(value); | |
| 1456 if (vi > 255) vi = 255; | |
| 1457 if (vi < 0) vi = 0; | |
| 1458 targetLine[x] = uchar(vi); | |
| 1459 } | |
| 1460 } | |
| 1461 } else { | |
| 1462 | |
| 1463 for (int y = 0; y < h; ++y) { | |
| 1464 | |
| 1465 float sy0, sy1; | |
| 1466 | |
| 1467 sy0 = getBinForY(v, y + 1); | |
| 1468 sy1 = getBinForY(v, y); | |
| 1469 | |
| 1470 int sy0i = int(sy0 + epsilon); | |
| 1471 int sy1i = int(sy1); | |
| 1472 | |
| 1473 uchar *targetLine = img.scanLine(y); | |
| 1474 | |
| 1475 if (sy0i == sy1i && sy0i == psy1i) { // same source scan line as just computed | |
| 1476 goto copy; | |
| 1477 } | |
| 1478 | |
| 1479 for (int x = 0; x < w; ++x) { | |
| 1480 peaks[x] = 0; | |
| 1481 } | |
| 1482 | |
| 1483 for (int sy = sy0i; sy <= sy1i; ++sy) { | |
| 1484 | |
| 1485 if (sy < 0 || sy >= source->height()) continue; | |
| 1486 | |
| 1487 uchar *sourceLine = source->scanLine(sy); | |
| 1403 | 1488 | 
| 1489 for (int x = 0; x < w; ++x) { | |
| 1490 | |
| 1491 int sx1i = int(sxa[x*2 + 1]); | |
| 1492 if (sx1i < 0) continue; | |
| 1493 | |
| 1494 int sx0i = int(sxa[x*2] + epsilon); | |
| 1495 if (sx0i >= sw) break; | |
| 1496 | |
| 1497 uchar peak = 0; | |
| 1498 for (int sx = sx0i; sx <= sx1i; ++sx) { | |
| 1499 if (sx < 0 || sx >= sw) continue; | |
| 1500 if (sourceLine[sx] > peak) peak = sourceLine[sx]; | |
| 1501 } | |
| 1502 peaks[x] = peak; | |
| 1503 } | |
| 1504 } | |
| 1505 | |
| 1506 copy: | |
| 1404 for (int x = 0; x < w; ++x) { | 1507 for (int x = 0; x < w; ++x) { | 
| 1405 | 1508 targetLine[x] = peaks[x]; | 
| 1406 int sx1i = sxa[x*2 + 1]; | 1509 } | 
| 1407 if (sx1i < 0) continue; | |
| 1408 | |
| 1409 int sx0i = sxa[x*2]; | |
| 1410 if (sx0i >= sw) break; | |
| 1411 | |
| 1412 uchar peak = 0; | |
| 1413 for (int sx = sx0i; sx <= sx1i; ++sx) { | |
| 1414 if (sx < 0 || sx >= sw) continue; | |
| 1415 if (sourceLine[sx] > peak) peak = sourceLine[sx]; | |
| 1416 } | |
| 1417 peaks[x] = peak; | |
| 1418 } | |
| 1419 } | |
| 1420 | |
| 1421 copy: | |
| 1422 for (int x = 0; x < w; ++x) { | |
| 1423 targetLine[x] = peaks[x]; | |
| 1424 } | 1510 } | 
| 1425 } | 1511 } | 
| 1426 | 1512 | 
| 1427 delete[] peaks; | 1513 delete[] peaks; | 
| 1428 | 1514 | 
| 1429 paint.drawImage(x0, 0, img); | |
| 1430 } | |
| 1431 | |
| 1432 void | |
| 1433 Colour3DPlotLayer::paintSmooth(View *v, QPainter &paint, QRect rect) const | |
| 1434 { | |
| 1435 Profiler profiler("Colour3DPlotLayer:paintSmooth"); | |
| 1436 if (!m_cache) return; | |
| 1437 | |
| 1438 float modelStart = m_model->getStartFrame(); | |
| 1439 float modelResolution = m_model->getResolution(); | |
| 1440 | |
| 1441 int mmsr = v->getViewManager()->getMainModelSampleRate(); | |
| 1442 int msr = m_model->getSampleRate(); | |
| 1443 float srRatio = float(mmsr) / float(msr); | |
| 1444 | |
| 1445 int x0 = rect.left(); | |
| 1446 int x1 = rect.right() + 1; | |
| 1447 | |
| 1448 int h = v->height(); // we always paint full height | |
| 1449 int sh = m_model->getHeight(); | |
| 1450 | |
| 1451 int symin = m_miny; | |
| 1452 int symax = m_maxy; | |
| 1453 if (symax <= symin) { | |
| 1454 symin = 0; | |
| 1455 symax = sh; | |
| 1456 } | |
| 1457 if (symin < 0) symin = 0; | |
| 1458 if (symax > sh) symax = sh; | |
| 1459 | |
| 1460 // QImage img(w, h, QImage::Format_Indexed8); | |
| 1461 // img.setColorTable(m_cache->colorTable()); | |
| 1462 | |
| 1463 int zoomLevel = v->getZoomLevel(); | |
| 1464 | |
| 1465 QImage *source = m_cache; | |
| 1466 if (m_peaksCache && | |
| 1467 ((modelResolution * srRatio * m_peakResolution) / zoomLevel) < 1) { | |
| 1468 std::cerr << "using peaks cache" << std::endl; | |
| 1469 source = m_peaksCache; | |
| 1470 modelResolution *= m_peakResolution; | |
| 1471 } else { | |
| 1472 std::cerr << "not using peaks cache" << std::endl; | |
| 1473 } | |
| 1474 | |
| 1475 float sx0 = (float(v->getFrameForX(x0)) / srRatio - modelStart) / modelResolution; | |
| 1476 float sx1 = (float(v->getFrameForX(x1)) / srRatio - modelStart) / modelResolution; | |
| 1477 int sx0i = int(sx0 + 0.001); | |
| 1478 int sx1i = int(sx1); | |
| 1479 | |
| 1480 if (sx0i < 0) sx0i = 0; | |
| 1481 if (sx0i > source->width()) sx0i = source->width(); | |
| 1482 | |
| 1483 int tx0 = v->getXForFrame(((sx0i * modelResolution) + modelStart) * srRatio + 0.001); | |
| 1484 int tx1 = v->getXForFrame(((sx1i * modelResolution) + modelStart) * srRatio); | |
| 1485 | |
| 1486 std::cerr << "x0 " << x0 << ", x1 " << x1 << " -> sx0 " << sx0i << ", sx1 " << sx1i << " -> tx0 " << tx0 << ", tx1 " << tx1 << std::endl; | |
| 1487 | |
| 1488 QImage img = source->copy(sx0i, 0, sx1i - sx0i, source->height()) | |
| 1489 .scaled(QSize(tx1 - tx0, h), | |
| 1490 Qt::IgnoreAspectRatio, Qt::SmoothTransformation); | |
| 1491 paint.drawImage(x0, 0, img); | 1515 paint.drawImage(x0, 0, img); | 
| 1492 } | 1516 } | 
| 1493 | 1517 | 
| 1494 bool | 1518 bool | 
| 1495 Colour3DPlotLayer::snapToFeatureFrame(View *v, int &frame, | 1519 Colour3DPlotLayer::snapToFeatureFrame(View *v, int &frame, | 
| 1526 "normalizeColumns=\"%3\" " | 1550 "normalizeColumns=\"%3\" " | 
| 1527 "normalizeVisibleArea=\"%4\" " | 1551 "normalizeVisibleArea=\"%4\" " | 
| 1528 "minY=\"%5\" " | 1552 "minY=\"%5\" " | 
| 1529 "maxY=\"%6\" " | 1553 "maxY=\"%6\" " | 
| 1530 "invertVertical=\"%7\" " | 1554 "invertVertical=\"%7\" " | 
| 1531 "opaque=\"%8\" " | 1555 "opaque=\"%8\" %9") | 
| 1532 "binScale=\"%9\"") | |
| 1533 .arg((int)m_colourScale) | 1556 .arg((int)m_colourScale) | 
| 1534 .arg(m_colourMap) | 1557 .arg(m_colourMap) | 
| 1535 .arg(m_normalizeColumns ? "true" : "false") | 1558 .arg(m_normalizeColumns ? "true" : "false") | 
| 1536 .arg(m_normalizeVisibleArea ? "true" : "false") | 1559 .arg(m_normalizeVisibleArea ? "true" : "false") | 
| 1537 .arg(m_miny) | 1560 .arg(m_miny) | 
| 1538 .arg(m_maxy) | 1561 .arg(m_maxy) | 
| 1539 .arg(m_invertVertical ? "true" : "false") | 1562 .arg(m_invertVertical ? "true" : "false") | 
| 1540 .arg(m_opaque ? "true" : "false") | 1563 .arg(m_opaque ? "true" : "false") | 
| 1541 .arg((int)m_binScale); | 1564 .arg(QString("binScale=\"%1\" smooth=\"%2\" ") | 
| 1542 | 1565 .arg((int)m_binScale) | 
| 1566 .arg(m_smooth ? "true" : "false")); | |
| 1567 | |
| 1543 Layer::toXml(stream, indent, extraAttributes + " " + s); | 1568 Layer::toXml(stream, indent, extraAttributes + " " + s); | 
| 1544 } | 1569 } | 
| 1545 | 1570 | 
| 1546 void | 1571 void | 
| 1547 Colour3DPlotLayer::setProperties(const QXmlAttributes &attributes) | 1572 Colour3DPlotLayer::setProperties(const QXmlAttributes &attributes) | 
| 1569 (attributes.value("invertVertical").trimmed() == "true"); | 1594 (attributes.value("invertVertical").trimmed() == "true"); | 
| 1570 setInvertVertical(invertVertical); | 1595 setInvertVertical(invertVertical); | 
| 1571 | 1596 | 
| 1572 bool opaque = | 1597 bool opaque = | 
| 1573 (attributes.value("opaque").trimmed() == "true"); | 1598 (attributes.value("opaque").trimmed() == "true"); | 
| 1574 setNormalizeVisibleArea(opaque); | 1599 setOpaque(opaque); | 
| 1600 | |
| 1601 bool smooth = | |
| 1602 (attributes.value("smooth").trimmed() == "true"); | |
| 1603 setSmooth(smooth); | |
| 1575 | 1604 | 
| 1576 float min = attributes.value("minY").toFloat(&ok); | 1605 float min = attributes.value("minY").toFloat(&ok); | 
| 1577 float max = attributes.value("maxY").toFloat(&alsoOk); | 1606 float max = attributes.value("maxY").toFloat(&alsoOk); | 
| 1578 if (ok && alsoOk) setDisplayExtents(min, max); | 1607 if (ok && alsoOk) setDisplayExtents(min, max); | 
| 1579 } | 1608 } | 
