From ec7bbbfdd4d6cf3c01ec3366c6e9e5c84b75c370 Mon Sep 17 00:00:00 2001 From: Louis Gombert Date: Sun, 14 Dec 2025 11:31:08 +0100 Subject: [PATCH] TechDraw: improve draw performance call 'boundingRect' only after all items have been drawn, using a custom 'addToGroup' function that does not trigger an update. --- src/Mod/TechDraw/Gui/QGIViewPart.cpp | 59 ++++++++++++++++++++++------ src/Mod/TechDraw/Gui/QGIViewPart.h | 1 + 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 4fbf327567..12a4289855 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -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(viewSection->SectionSymbol.getValue())); Base::Color color = Preferences::getAccessibleColor(vp->SectionLineColor.getValue()); sectionLine->setSectionColor(color.asValue()); @@ -807,7 +810,7 @@ void QGIViewPart::drawComplexSectionLine(TechDraw::DrawViewSection* viewSection, QGISectionLine* sectionLine = new QGISectionLine(); - addToGroup(sectionLine); + addToGroupWithoutUpdate(sectionLine); sectionLine->setSymbol(const_cast(viewSection->SectionSymbol.getValue())); Base::Color color = Preferences::getAccessibleColor(vp->SectionLineColor.getValue()); sectionLine->setSectionColor(color.asValue()); @@ -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 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); } diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.h b/src/Mod/TechDraw/Gui/QGIViewPart.h index 234f6edeb5..f243596b8b 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.h +++ b/src/Mod/TechDraw/Gui/QGIViewPart.h @@ -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 &subNames) override;