version 2.1.0_beta
Graphic first LOD optimization try, now works only on setGraphicData
This commit is contained in:
@@ -117,7 +117,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
|
||||
icon_pause_f = QImage(":/icons/pause-front.png");
|
||||
aupdate = grid = isFit = navigation = true;
|
||||
aalias = bufferActive = isOGL = cancel = guides = hasLblX = hasLblY = isHover = false;
|
||||
pause_ = only_expand_x = only_expand_y = false;
|
||||
pause_ = only_expand_x = only_expand_y = m_LODOptimization = false;
|
||||
limit_.setCoords(-DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX);
|
||||
eminx = eminy = DBL_MAX;
|
||||
emaxx = emaxy = DBL_MIN;
|
||||
@@ -150,6 +150,7 @@ Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this),
|
||||
setButtonsPosition(Graphic::Left);
|
||||
setAntialiasing(false);
|
||||
setCaption("");
|
||||
setBorderInputsVisible(false);
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
ui->layoutButtons->update();
|
||||
updateLegend();
|
||||
@@ -583,6 +584,8 @@ void Graphic::clear() {
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
graphics[i].polyline.clear();
|
||||
graphics[i].polyline_pause.clear();
|
||||
graphics[i]._lod.clear();
|
||||
graphics[i]._lod_pause.clear();
|
||||
graphics[i].max_x = 0.;
|
||||
graphics[i].cvrect = QRectF();
|
||||
}
|
||||
@@ -613,6 +616,8 @@ void Graphic::setPaused(bool yes) {
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
graphics[i].polyline_pause = graphics[i].polyline;
|
||||
graphics[i].polyline_pause.detach();
|
||||
graphics[i]._lod_pause = graphics[i]._lod;
|
||||
graphics[i]._lod_pause.detach();
|
||||
graphics[i].max_x_pause = graphics[i].max_x;
|
||||
}
|
||||
timer_pause = startTimer(40);
|
||||
@@ -1183,7 +1188,8 @@ void Graphic::drawGraphics() {
|
||||
ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
|
||||
QPointF srp = -selrect.topLeft();
|
||||
double sclx, scly, wid = canvas->width(), hei = canvas->height();
|
||||
sclx = (wid - gridborder.x() - margins_.left() - margins_.width()) / selrect.width();
|
||||
int cwid = (wid - gridborder.x() - margins_.left() - margins_.width());
|
||||
sclx = cwid / selrect.width();
|
||||
scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height();
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
@@ -1197,27 +1203,36 @@ void Graphic::drawGraphics() {
|
||||
QPen pen;
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
GraphicType & t(graphics[i]);
|
||||
QPolygonF & rpol(pause_ ? t.polyline_pause : t.polyline);
|
||||
if (t.visible && !rpol.isEmpty()) {
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
QPolygonF & src_pol(pause_ ? t.polyline_pause : t.polyline);
|
||||
if (!t.visible || src_pol.isEmpty()) continue;
|
||||
QVector<QPolygonF> & src_lod(pause_ ? t._lod_pause : t._lod);
|
||||
int lod = 0;
|
||||
if (m_LODOptimization) {
|
||||
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<int>(0, qFloor(log2(ppp) - 2), src_lod.size());
|
||||
//qDebug() << "draw lod" << lod;
|
||||
}
|
||||
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));
|
||||
}
|
||||
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));
|
||||
}
|
||||
}
|
||||
painter->setWorldMatrixEnabled(true);
|
||||
@@ -1524,6 +1539,8 @@ void Graphic::tick(int index, bool slide, bool update_) {
|
||||
}
|
||||
t.polyline.pop_front();
|
||||
}
|
||||
} else {
|
||||
calcLOD(index);
|
||||
}
|
||||
if (!update_) {
|
||||
if (isFit) findGraphicsRect();
|
||||
@@ -1538,6 +1555,49 @@ void Graphic::tick(int index, bool slide, bool update_) {
|
||||
}
|
||||
|
||||
|
||||
void Graphic::calcLOD(int index) {
|
||||
if (!m_LODOptimization) return;
|
||||
GraphicType & t(graphics[index]);
|
||||
t._lod.clear();
|
||||
int pcnt = t.polyline.size();
|
||||
//qDebug() << "calcLOD" << index;
|
||||
while (pcnt >= 10) {
|
||||
QPolygonF & pl(t._lod.isEmpty() ? t.polyline : t._lod.back());
|
||||
t._lod.append(QPolygonF());
|
||||
QPolygonF & cl(t._lod.back());
|
||||
cl << pl.front();
|
||||
int qcnt = (pl.size() + 1) / 4;
|
||||
pcnt = qcnt * 2 + 2;
|
||||
int pc = 4;
|
||||
qreal mx[2] = {0., 0.}, my[2] = {0., 0.}, my_x[2] = {0., 0.}, px, py;
|
||||
for (int i = 0; i < qcnt; ++i) {
|
||||
int j = i*4 + 1;
|
||||
if (i == qcnt - 1) pc = pl.size() - j - 1;
|
||||
mx[0] = mx[1] = my_x[0] = my_x[1] = pl[j].x(); my[0] = my[1] = pl[j].y();
|
||||
for (int k = 1; k < pc; ++k) {
|
||||
px = pl[j + k].x(); py = pl[j + k].y();
|
||||
mx[0] = qMin(mx[0], px); mx[1] = qMax(mx[1], px);
|
||||
if (my[0] > py) {
|
||||
my[0] = py;
|
||||
my_x[0] = px;
|
||||
}
|
||||
if (my[1] < py) {
|
||||
my[1] = py;
|
||||
my_x[1] = px;
|
||||
}
|
||||
}
|
||||
qreal dx =(mx[1] - mx[0]) / 4., cx = (mx[1] + mx[0]) / 2.;
|
||||
if (my_x[1] >= my_x[0])
|
||||
cl << QPointF(cx - dx, my[0]) << QPointF(cx + dx, my[1]);
|
||||
else
|
||||
cl << QPointF(cx - dx, my[1]) << QPointF(cx + dx, my[0]);
|
||||
}
|
||||
cl << pl.back();
|
||||
//qDebug() << "lod" << t._lod.size() << "->" << cl.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_graphic_buttonAutofit_clicked() {
|
||||
isFit = true;
|
||||
bool isEmpty = true;
|
||||
|
||||
Reference in New Issue
Block a user