From e55259e8d7e400b29dd1e5a6247d3dc82d0c6417 Mon Sep 17 00:00:00 2001 From: peri4 Date: Thu, 27 May 2021 10:21:21 +0300 Subject: [PATCH] Graphic LODoptimization improvements - now draw only points in visible rect --- libs/graphic/graphic.cpp | 70 ++++++++++++++++++++++--------- utils/qpicalculator/mainwindow.ui | 22 ++++++---- 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/libs/graphic/graphic.cpp b/libs/graphic/graphic.cpp index 15fb527..c3e9e9d 100644 --- a/libs/graphic/graphic.cpp +++ b/libs/graphic/graphic.cpp @@ -1202,7 +1202,6 @@ void Graphic::drawGraphics() { QTransform mat = painter->transform(); painter->resetTransform(); painter->setWorldMatrixEnabled(false); - QPolygonF cpol; QPen pen; for (int i = 0; i < graphics.size(); ++i) { GraphicType & t(graphics[i]); @@ -1214,28 +1213,59 @@ void Graphic::drawGraphics() { int gpcnt = src_pol.size(); qreal range = src_pol.back().x() - src_pol.front().x(); qreal ppp = (gpcnt * selrect.width() / qMax(range, 1.E-9) / cwid); - lod = qBound(0, qFloor(log2(ppp) - 2), src_lod.size()); - //qDebug() << "draw lod" << lod; + lod = qBound(0, qFloor(log2(ppp) - 1), src_lod.size()); + //qDebug() << "draw lod" << lod << src_lod[lod - 1].size(); } QPolygonF & rpol(lod == 0 ? src_pol : src_lod[lod - 1]); - pen = t.pen; - if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick); - else pen.setWidthF(pen.widthF()*thick); - pen.setCosmetic(true); - if (t.lines) { - painter->setPen(pen); - if (t.fill) { - cpol = rpol; - painter->setBrush(t.fill_color); - painter->drawPolygon(mat.map(cpol)); - } else - painter->drawPolyline(mat.map(rpol)); + int ind_start = -1, ind_end = -1; + if (m_LODOptimization) { + qreal xs = selrect.left(), xe = selrect.right(), _offset = 2. / cwid * selrect.width(); + xs -= _offset; xe += _offset; + for (int i = 0; i < rpol.size(); ++i) { + qreal px = rpol[i].x(); + if (px < xs) continue; + if (ind_start < 0) + ind_start = qMax(0, i - 1); + if (px > xe && ind_end < 0) { + ind_end = qMin(rpol.size(), i + 1); + break; + } + } + if (ind_start < 0) ind_start = 0; + if (ind_end < 0) ind_end = rpol.size(); + //qDebug() << "bound" << ind_start << ind_end << rpol.size(); + } else { + ind_start = 0; + ind_end = rpol.size(); } - if (t.points) { - if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick)); - else pen.setWidthF(t.pointWidth*thick); - painter->setPen(pen); - painter->drawPoints(mat.map(rpol)); + int polsize = ind_end - ind_start; + if (polsize > 0) { + QPolygonF cpol; + if (m_LODOptimization && polsize < rpol.size()) { + cpol.resize(polsize); + memcpy(cpol.data(), &(rpol[ind_start]), polsize * sizeof(QPointF)); + //qDebug() << "copy" << polsize; + } else { + cpol = rpol; + } + pen = t.pen; + if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick); + else pen.setWidthF(pen.widthF()*thick); + pen.setCosmetic(true); + if (t.lines) { + painter->setPen(pen); + if (t.fill) { + painter->setBrush(t.fill_color); + painter->drawPolygon(mat.map(cpol)); + } else + painter->drawPolyline(mat.map(cpol)); + } + if (t.points) { + if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick)); + else pen.setWidthF(t.pointWidth*thick); + painter->setPen(pen); + painter->drawPoints(mat.map(cpol)); + } } } painter->setWorldMatrixEnabled(true); diff --git a/utils/qpicalculator/mainwindow.ui b/utils/qpicalculator/mainwindow.ui index dae08e6..b3e0c6c 100644 --- a/utils/qpicalculator/mainwindow.ui +++ b/utils/qpicalculator/mainwindow.ui @@ -151,7 +151,7 @@ - + :/icons/list-add.png:/icons/list-add.png @@ -162,7 +162,7 @@ false - + :/icons/edit-delete.png:/icons/edit-delete.png @@ -192,7 +192,7 @@ false - + :/icons/edit-clear.png:/icons/edit-clear.png @@ -224,7 +224,7 @@ Qt::Horizontal - + @@ -272,7 +272,7 @@ - + :/icons/list-add.png:/icons/list-add.png @@ -283,7 +283,7 @@ false - + :/icons/edit-delete.png:/icons/edit-delete.png @@ -313,7 +313,7 @@ false - + :/icons/edit-clear.png:/icons/edit-clear.png @@ -372,7 +372,13 @@ - + + + + + + +