From 8944a9cfbefa2cad9740923f92f20c80f2d961aa Mon Sep 17 00:00:00 2001 From: wandererfan Date: Thu, 28 May 2020 15:42:07 -0400 Subject: [PATCH] [TD]Export Svg hatch as bitmap --- src/Mod/TechDraw/App/DrawViewPart.cpp | 3 +- src/Mod/TechDraw/Gui/QGCustomImage.cpp | 9 +++ src/Mod/TechDraw/Gui/QGCustomImage.h | 1 + src/Mod/TechDraw/Gui/QGIFace.cpp | 93 ++++++++++++++++++++++++- src/Mod/TechDraw/Gui/QGIFace.h | 9 ++- src/Mod/TechDraw/Gui/QGIViewPart.cpp | 25 +++---- src/Mod/TechDraw/Gui/QGIViewSection.cpp | 15 ++-- src/Mod/TechDraw/Gui/QGVPage.cpp | 8 ++- 8 files changed, 134 insertions(+), 29 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index cb26efa37e..7c779d7108 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -625,8 +625,7 @@ std::vector DrawViewPart::getHatches() const std::vector result; std::vector children = getInList(); for (std::vector::iterator it = children.begin(); it != children.end(); ++it) { - if ( ((*it)->getTypeId().isDerivedFrom(DrawHatch::getClassTypeId())) && - (!(*it)->isRemoving()) ) { + if ((*it)->getTypeId().isDerivedFrom(DrawHatch::getClassTypeId())) { TechDraw::DrawHatch* hatch = dynamic_cast(*it); result.push_back(hatch); } diff --git a/src/Mod/TechDraw/Gui/QGCustomImage.cpp b/src/Mod/TechDraw/Gui/QGCustomImage.cpp index c8765dcd61..81435098bf 100644 --- a/src/Mod/TechDraw/Gui/QGCustomImage.cpp +++ b/src/Mod/TechDraw/Gui/QGCustomImage.cpp @@ -74,6 +74,15 @@ bool QGCustomImage::load(QString fileSpec) return(success); } +bool QGCustomImage::load(QPixmap map) +{ + bool success = true; + m_px = map; + prepareGeometryChange(); + setPixmap(m_px); + return(success); +} + QSize QGCustomImage::imageSize(void) { QSize result = m_px.size(); diff --git a/src/Mod/TechDraw/Gui/QGCustomImage.h b/src/Mod/TechDraw/Gui/QGCustomImage.h index 9b8947fcf9..b17d5119fe 100644 --- a/src/Mod/TechDraw/Gui/QGCustomImage.h +++ b/src/Mod/TechDraw/Gui/QGCustomImage.h @@ -53,6 +53,7 @@ public: virtual void centerAt(QPointF centerPos); virtual void centerAt(double cX, double cY); virtual bool load(QString fileSpec); + virtual bool load(QPixmap map); virtual QSize imageSize(void); protected: diff --git a/src/Mod/TechDraw/Gui/QGIFace.cpp b/src/Mod/TechDraw/Gui/QGIFace.cpp index b8174c958e..e12eedb956 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.cpp +++ b/src/Mod/TechDraw/Gui/QGIFace.cpp @@ -58,7 +58,9 @@ #include "ZVALUE.h" // #include "Rez.h" +#include "DrawGuiUtil.h" #include "QGCustomSvg.h" +#include "QGCustomImage.h" #include "QGCustomRect.h" #include "QGIViewPart.h" #include "QGIPrimPath.h" @@ -84,6 +86,9 @@ QGIFace::QGIFace(int index) : setPrettyNormal(); m_texture = QPixmap(); //empty texture + m_image = new QGCustomImage(); + m_image->setParentItem(this); + m_svg = new QGCustomSvg(); m_rect = new QGCustomRect(); @@ -139,10 +144,13 @@ void QGIFace::draw() m_styleNormal = m_styleDef; m_fillStyleCurrent = m_styleNormal; loadSvgHatch(m_fileSpec); - buildSvgHatch(); if (m_hideSvgTiles) { + buildPixHatch(); m_rect->hide(); + m_image->show(); } else { + buildSvgHatch(); + m_image->hide(); m_rect->show(); } } else if ((ext.toUpper() == QString::fromUtf8("JPG")) || @@ -553,6 +561,89 @@ void QGIFace::clearSvg() hideSvg(true); } +void QGIFace::buildPixHatch() +{ + double wTile = SVGSIZEW * m_fillScale; + double hTile = SVGSIZEH * m_fillScale; + double w = m_outline.boundingRect().width(); + double h = m_outline.boundingRect().height(); + QRectF r = m_outline.boundingRect(); + QPointF fCenter = r.center(); + double nw = ceil(w / wTile); + double nh = ceil(h / hTile); + w = nw * wTile; + h = nh * hTile; + + m_rect->setRect(0.,0.,w,-h); + m_rect->centerAt(fCenter); + + r = m_rect->rect(); + QByteArray before,after; + before.append(QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT)); + after.append(QString::fromStdString(SVGCOLPREFIX + m_svgCol)); + QByteArray colorXML = m_svgXML.replace(before,after); + QSvgRenderer renderer; + bool success = renderer.load(colorXML); + if (!success) { + Base::Console().Error("QGIF::buildPixHatch - renderer failed to load\n"); + } + + QImage imageIn(64, 64, QImage::Format_ARGB32); + imageIn.fill(Qt::transparent); + QPainter painter(&imageIn); + + renderer.render(&painter); + if (imageIn.isNull()) { + Base::Console().Error("QGIF::buildPixHatch - imageIn is null\n"); + return; + } + + QPixmap pm(64, 64); + pm = QPixmap::fromImage(imageIn); + pm = pm.scaled(wTile, hTile); + if (pm.isNull()) { + Base::Console().Error("QGIF::buildPixHatch - pm is null\n"); + return; + } + + QImage tileField(w, h, QImage::Format_ARGB32); + QPointF fieldCenter(w / 2.0, h / 2.0); + + tileField.fill(Qt::transparent); + QPainter painter2(&tileField); + QPainter::RenderHints hints = painter2.renderHints(); + hints = hints & QPainter::Antialiasing; + painter2.setRenderHints(hints); + QPainterPath clipper = path(); + QPointF offset = (fieldCenter - fCenter); + clipper.translate(offset); + painter2.setClipPath(clipper); + + long int tileCount = 0; + for (int iw = 0; iw < int(nw); iw++) { + for (int ih = 0; ih < int(nh); ih++) { + painter2.drawPixmap(QRectF(iw*wTile, ih*hTile, wTile, hTile), //target rect + pm, //map + QRectF(0, 0, wTile, hTile)); //source rect + tileCount++; + if (tileCount > m_maxTile) { + Base::Console().Warning("Pixmap tile count exceeded: %ld\n",tileCount); + break; + } + } + if (tileCount > m_maxTile) { + break; + } + } + QPixmap bigMap(fabs(r.width()), fabs(r.height())); + bigMap = QPixmap::fromImage(tileField); + + QPixmap nothing; + m_image->setPixmap(nothing); + m_image->load(bigMap); + m_image->centerAt(fCenter); +} + //this isn't used currently QPixmap QGIFace::textureFromSvg(std::string fileSpec) { diff --git a/src/Mod/TechDraw/Gui/QGIFace.h b/src/Mod/TechDraw/Gui/QGIFace.h index 0e1ffdf7b1..a7f5c3f355 100644 --- a/src/Mod/TechDraw/Gui/QGIFace.h +++ b/src/Mod/TechDraw/Gui/QGIFace.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ namespace TechDrawGui { class QGCustomSvg; class QGCustomRect; +class QGCustomImage; const double SVGSIZEW = 64.0; //width and height of standard FC SVG pattern const double SVGSIZEH = 64.0; @@ -92,7 +94,10 @@ public: void buildSvgHatch(void); void hideSvg(bool b); void clearSvg(void); - + + //tiled pixmap fill from svg + void buildPixHatch(); + //PAT fill parms & methods void setGeomHatchWeight(double w) { m_geomWeight = w; } void setLineWeight(double w); @@ -128,6 +133,8 @@ protected: std::string m_svgCol; std::string m_fileSpec; //for svg & bitmaps + QGCustomImage* m_image; + double m_fillScale; bool m_isHatched; QGIFace::fillMode m_mode; diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index f4e568cb11..e217b4b499 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -424,7 +424,6 @@ void QGIViewPart::updateView(bool update) } void QGIViewPart::draw() { -// Base::Console().Message("QGIVP::draw()\n"); if (!isVisible()) { return; } @@ -507,22 +506,20 @@ void QGIViewPart::drawViewPart() if (!fHatch->SvgIncluded.isEmpty()) { if (getExporting()) { newFace->hideSvg(true); - newFace->isHatched(false); - newFace->setFillMode(QGIFace::PlainFill); } else { newFace->hideSvg(false); - newFace->isHatched(true); - newFace->setFillMode(QGIFace::FromFile); - newFace->setHatchFile(fHatch->SvgIncluded.getValue()); - Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch); - ViewProviderHatch* hatchVp = dynamic_cast(gvp); - if (hatchVp != nullptr) { - double hatchScale = hatchVp->HatchScale.getValue(); - if (hatchScale > 0.0) { - newFace->setHatchScale(hatchVp->HatchScale.getValue()); - } - newFace->setHatchColor(hatchVp->HatchColor.getValue()); + } + newFace->isHatched(true); + newFace->setFillMode(QGIFace::SvgFill); + newFace->setHatchFile(fHatch->SvgIncluded.getValue()); + Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch); + ViewProviderHatch* hatchVp = dynamic_cast(gvp); + if (hatchVp != nullptr) { + double hatchScale = hatchVp->HatchScale.getValue(); + if (hatchScale > 0.0) { + newFace->setHatchScale(hatchVp->HatchScale.getValue()); } + newFace->setHatchColor(hatchVp->HatchColor.getValue()); } } } diff --git a/src/Mod/TechDraw/Gui/QGIViewSection.cpp b/src/Mod/TechDraw/Gui/QGIViewSection.cpp index 40df1aea90..0e8abbebcc 100644 --- a/src/Mod/TechDraw/Gui/QGIViewSection.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewSection.cpp @@ -115,18 +115,15 @@ void QGIViewSection::drawSectionFace() } else if (section->CutSurfaceDisplay.isValue("SvgHatch")) { if (getExporting()) { newFace->hideSvg(true); - newFace->isHatched(false); - newFace->setFillMode(QGIFace::PlainFill); } else { newFace->hideSvg(false); - newFace->isHatched(true); - newFace->setFillMode(QGIFace::SvgFill); - newFace->setHatchColor(sectionVp->HatchColor.getValue()); - newFace->setHatchScale(section->HatchScale.getValue()); -// std::string hatchSpec = section->FileHatchPattern.getValue(); - std::string hatchSpec = section->SvgIncluded.getValue(); - newFace->setHatchFile(hatchSpec); } + newFace->setFillMode(QGIFace::SvgFill); + newFace->setHatchColor(sectionVp->HatchColor.getValue()); + newFace->setHatchScale(section->HatchScale.getValue()); +// std::string hatchSpec = section->FileHatchPattern.getValue(); + std::string hatchSpec = section->SvgIncluded.getValue(); + newFace->setHatchFile(hatchSpec); } else if (section->CutSurfaceDisplay.isValue("PatHatch")) { newFace->isHatched(true); newFace->setFillMode(QGIFace::GeomHatchFill); diff --git a/src/Mod/TechDraw/Gui/QGVPage.cpp b/src/Mod/TechDraw/Gui/QGVPage.cpp index 1c30fc1fb5..15fe50760d 100644 --- a/src/Mod/TechDraw/Gui/QGVPage.cpp +++ b/src/Mod/TechDraw/Gui/QGVPage.cpp @@ -773,18 +773,22 @@ void QGVPage::refreshViews(void) void QGVPage::setExporting(bool enable) { -// Base::Console().Message("QGVP::setExporting(%d)\n", enable); QList sceneItems = scene()->items(); + std::vector dvps; for (auto& qgi:sceneItems) { QGIViewPart* qgiPart = dynamic_cast(qgi); QGIRichAnno* qgiRTA = dynamic_cast(qgi); if(qgiPart) { qgiPart->setExporting(enable); + dvps.push_back(qgiPart); } if (qgiRTA) { qgiRTA->setExporting(enable); } } + for (auto& v: dvps) { + v->draw(); + } } void QGVPage::saveSvg(QString filename) @@ -848,7 +852,7 @@ void QGVPage::saveSvg(QString filename) QPainter p; p.begin(&svgGen); - scene()->render(&p, targetRect,sourceRect); + scene()->render(&p, targetRect,sourceRect); //note: scene render, not item render! p.end(); m_vpPage->setFrameState(saveState);