TechDraw: improve draw performance

call 'boundingRect' only after all items have been drawn, using a custom 'addToGroup' function that does not trigger an update.
This commit is contained in:
Louis Gombert
2025-12-14 11:31:08 +01:00
committed by Max Wilfinger
parent 850ad9e0fc
commit ec7bbbfdd4
2 changed files with 49 additions and 11 deletions

View File

@@ -22,6 +22,7 @@
#include <QPainterPath>
#include <QKeyEvent>
#include <QGraphicsTransform>
#include <cstdio>
#include <qmath.h>
@@ -259,6 +260,8 @@ void QGIViewPart::draw()
//this is old C/L
drawCenterLines(true);//have to draw centerlines after border to get size correct.
drawAllSectionLines();//same for section lines
prepareGeometryChange();
}
void QGIViewPart::drawViewPart()
@@ -390,7 +393,7 @@ void QGIViewPart::drawAllEdges()
}
item = new QGIEdge(iEdge);
addToGroup(item); //item is created at scene(0, 0), not group(0, 0)
addToGroupWithoutUpdate(item); //item is created at scene(0, 0), not group(0, 0)
item->setPath(drawPainterPath(*itGeom));
item->setSource((*itGeom)->source());
@@ -474,7 +477,7 @@ void QGIViewPart::drawAllVertexes()
for (int i = 0; vert != verts.end(); ++vert, i++) {
if ((*vert)->isCenter()) {
auto* cmItem = new QGICMark(i);
addToGroup(cmItem);
addToGroupWithoutUpdate(cmItem);
cmItem->setPos(Rez::guiX((*vert)->x()), Rez::guiX((*vert)->y()));
cmItem->setThick(0.5F * getLineWidth()); //need minimum?
cmItem->setSize(getVertexSize() * vp->CenterScale.getValue());
@@ -488,7 +491,7 @@ void QGIViewPart::drawAllVertexes()
//regular Vertex
if (showVertices()) {
auto* item = new QGIVertex(i);
addToGroup(item);
addToGroupWithoutUpdate(item);
item->setPos(Rez::guiX((*vert)->x()), Rez::guiX((*vert)->y()));
item->setNormalColor(vertexColor);
item->setFillColor(vertexColor);
@@ -606,7 +609,7 @@ QGIFace* QGIViewPart::drawFace(TechDraw::FacePtr f, int idx)
facePath.setFillRule(Qt::OddEvenFill);
QGIFace* gFace = new QGIFace(idx);
addToGroup(gFace);
addToGroupWithoutUpdate(gFace);
gFace->setPos(0.0, 0.0);
gFace->setOutline(facePath);
//debug a path
@@ -712,7 +715,7 @@ void QGIViewPart::drawSectionLine(TechDraw::DrawViewSection* viewSection, bool b
}
QGISectionLine* sectionLine = new QGISectionLine();
addToGroup(sectionLine);
addToGroupWithoutUpdate(sectionLine);
sectionLine->setSymbol(const_cast<char*>(viewSection->SectionSymbol.getValue()));
Base::Color color = Preferences::getAccessibleColor(vp->SectionLineColor.getValue());
sectionLine->setSectionColor(color.asValue<QColor>());
@@ -807,7 +810,7 @@ void QGIViewPart::drawComplexSectionLine(TechDraw::DrawViewSection* viewSection,
QGISectionLine* sectionLine = new QGISectionLine();
addToGroup(sectionLine);
addToGroupWithoutUpdate(sectionLine);
sectionLine->setSymbol(const_cast<char*>(viewSection->SectionSymbol.getValue()));
Base::Color color = Preferences::getAccessibleColor(vp->SectionLineColor.getValue());
sectionLine->setSectionColor(color.asValue<QColor>());
@@ -867,7 +870,7 @@ void QGIViewPart::drawCenterLines(bool b)
double xVal, yVal;
if (horiz) {
centerLine = new QGICenterLine();
addToGroup(centerLine);
addToGroupWithoutUpdate(centerLine);
centerLine->setPos(0.0, 0.0);
double width = Rez::guiX(viewPart->getBoxX());
sectionSpan = width + sectionFudge;
@@ -884,7 +887,7 @@ void QGIViewPart::drawCenterLines(bool b)
}
if (vert) {
centerLine = new QGICenterLine();
addToGroup(centerLine);
addToGroupWithoutUpdate(centerLine);
centerLine->setPos(0.0, 0.0);
double height = Rez::guiX(viewPart->getBoxY());
sectionSpan = height + sectionFudge;
@@ -946,7 +949,7 @@ void QGIViewPart::drawHighlight(TechDraw::DrawViewDetail* viewDetail, bool b)
highlight->setInteractive(false);
addToGroup(highlight);
addToGroupWithoutUpdate(highlight);
highlight->setPos(0.0, 0.0);//sb setPos(center.x, center.y)?
Base::Vector3d center = viewDetail->AnchorPoint.getValue() * viewPart->getScale();
@@ -1011,7 +1014,7 @@ void QGIViewPart::drawMatting()
double scale = dvd->getScale();
double radius = dvd->Radius.getValue() * scale;
QGIMatting* mat = new QGIMatting();
addToGroup(mat);
addToGroupWithoutUpdate(mat);
mat->setRadius(Rez::guiX(radius));
mat->setPos(0.0, 0.0);
mat->draw();
@@ -1038,7 +1041,7 @@ void QGIViewPart::drawBreakLines()
auto breaks = dbv->Breaks.getValues();
for (auto& breakObj : breaks) {
QGIBreakLine* breakLine = new QGIBreakLine();
addToGroup(breakLine);
addToGroupWithoutUpdate(breakLine);
Base::Vector3d direction = dbv->guiDirectionFromObj(*breakObj);
breakLine->setDirection(direction);
@@ -1250,6 +1253,40 @@ QGraphicsItem *QGIViewPart::getQGISubItemByName(const std::string &subName) cons
return nullptr;
}
void QGIViewPart::addToGroupWithoutUpdate(QGraphicsItem* item)
{
// Implementation taken from QGraphicsItemGroup::addToGroup,
// But delaying the costly bounding box calculation and update until all items are added
bool ok;
QTransform itemTransform = item->itemTransform(this, &ok);
if (!ok) {
qWarning("QGIViewPart::addToGroup: could not find a valid transformation from item to group coordinates");
return;
}
QTransform newItemTransform(itemTransform);
item->setPos(mapFromItem(item, 0, 0));
item->setParentItem(this);
if (!item->pos().isNull()) {
newItemTransform *= QTransform::fromTranslate(-item->x(), -item->y());
}
// removing additional transformations properties applied with itemTransform()
QPointF origin = item->transformOriginPoint();
QMatrix4x4 m;
QList<QGraphicsTransform*> transformList = item->transformations();
for (int i = 0; i < transformList.size(); ++i)
{
transformList.at(i)->applyTo(&m);
}
newItemTransform *= m.toTransform().inverted();
newItemTransform.translate(origin.x(), origin.y());
newItemTransform.rotate(-item->rotation());
newItemTransform.scale(1/item->scale(), 1/item->scale());
newItemTransform.translate(-origin.x(), -origin.y());
item->setTransform(newItemTransform);
}
bool QGIViewPart::getGroupSelection() {
return DrawGuiUtil::isSelectedInTree(this);
}

View File

@@ -115,6 +115,7 @@ public:
double x, double y,
double curx, double cury);
void addToGroupWithoutUpdate(QGraphicsItem* item);
bool getGroupSelection() override;
void setGroupSelection(bool isSelected) override;
void setGroupSelection(bool isSelected, const std::vector<std::string> &subNames) override;