From 50acb3b625ab65238442d4454837c6c7c7f84eac Mon Sep 17 00:00:00 2001 From: "yang.yongquan" <3395816735@qq.com> Date: Sat, 11 Mar 2023 19:52:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E4=B8=BAPainting=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=EF=BC=88z=E8=BD=B4=E3=80=81=E7=BA=BF=E5=AE=BD?= =?UTF-8?q?=E3=80=81=E6=B5=8B=E8=AF=95=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Editor/LayerWrapper.cpp | 8 +- .../src/Editor/PixelPath.cpp | 7 + .../src/Editor/PixelPath.h | 6 +- .../src/Editor/util/PaintingUtil.cpp | 124 ++++++++++++++++++ .../src/Editor/util/PaintingUtil.h | 11 +- .../src/Editor/util/SvgFileLoader.cpp | 1 - 6 files changed, 148 insertions(+), 9 deletions(-) diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index 9135744..4ba041f 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -80,11 +80,11 @@ void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const double centerY = cache.getBoundingRect().center().y(); //qDebug() << name << " " << cache.boundingRect().center(); //qDebug() << name << " " << cache.boundingRect(); - trans.translate(centerX, centerY); - trans.scale(scale.x(), scale.y()); - trans.rotate(rotation); - trans.translate(-centerX, -centerY); trans.translate(offset.x(), offset.y()); + trans.translate(-centerX, -centerY); + trans.rotate(rotation); + trans.scale(scale.x(), scale.y()); + trans.translate(centerX, centerY); cache = cache.trans(trans); } void LayerWrapper::refresh() diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp index 2d710e1..447f8aa 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp @@ -32,10 +32,15 @@ QPixmap PixelPath::getPixmap() const return pixmap; } +QPainterPath PixelPath::getPainterPath() const { + return painterPath; +} + void PixelPath::addPath(const PixelPath& path) { QPainter painter(&pixmap); painter.drawPixmap(0, 0, path.getPixmap()); + this->painterPath.addPath(path.getPainterPath()); boundingRect = boundingRect.united(path.getBoundingRect()); } @@ -46,6 +51,7 @@ void PixelPath::addPath(const QPainterPath& path) painter.setRenderHint(QPainter::HighQualityAntialiasing); painter.setPen(QPen(Qt::black,1)); painter.drawPath(path); + this->painterPath.addPath(path); boundingRect = boundingRect.united(path.boundingRect()); } @@ -83,6 +89,7 @@ QPixmap PixelPath::resizedPixel(QSize size)const painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.setRenderHint(QPainter::HighQualityAntialiasing); painter.drawPixmap(0, 0, pixmap.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); + return result; } diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.h b/ArchitectureColoredPainting/src/Editor/PixelPath.h index be80950..33268db 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.h +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.h @@ -10,13 +10,15 @@ class PixelPath private: QRectF boundingRect; QPixmap pixmap; + QPainterPath painterPath; int w,h; public: - PixelPath(int w=1920, int h= 1080); - PixelPath(QPainterPath painterPath,int w = 1920, int h = 1080); + PixelPath(int w=1080, int h= 1080); + PixelPath(QPainterPath painterPath,int w = 1080, int h = 1080); ~PixelPath() = default; QRectF getBoundingRect() const; QPixmap getPixmap() const; + QPainterPath getPainterPath() const; void addPath(const PixelPath& path); void addPath(const QPainterPath& path); void addImage(const QImage& image,const QPointF& pos); diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index 7064a16..99188b2 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -1,2 +1,126 @@ #include "PaintingUtil.h" +#include +#include +#include "PainterPathUtil.h" +using Renderer::Painting; +using Renderer::Element; +using Renderer::ElementTransform; +using glm::bvec2; +using std::max; + +QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) { + QFile jsonFile(jsonFilePath); + jsonFile.open(QFile::ReadOnly); + QByteArray fileContent = jsonFile.readAll().trimmed(); + jsonFile.close(); + QJsonParseError jError; + QJsonDocument jsonDoc(QJsonDocument::fromJson(fileContent, &jError)); + return jsonDoc.object(); +} + +Painting PaintingUtil::transfromToPainting(QString jsonFilePath) { + Painting painting; + QTransform transform; + glm::bvec2 flip(0, 0); + QJsonObject jsonObj = readJsonFile(jsonFilePath); + ElementManager *elementManager = new ElementManager(jsonObj, Renderer::ElementRenderer::instance()); + LayerManager* layerManager = new LayerManager(jsonObj, elementManager); + traverseLayTree(layerManager->getRoot(), transform, flip, painting); +} + +void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, bvec2 flip, Painting& painting) { + LeafLayerWrapper* leafLayer = dynamic_cast(nowLayer); + PixelPath pixelPath = nowLayer->getCache(); + double centerX = pixelPath.getBoundingRect().center().x(); + double centerY = pixelPath.getBoundingRect().center().y(); + flip ^= bvec2(nowLayer->property.flipHorizontally, nowLayer->property.flipVertically); + + QRectF transBound = transform.map(pixelPath.getPainterPath()).boundingRect(); + + transform.translate(nowLayer->property.offset.x(), nowLayer->property.offset.y()) + .translate(-centerX, -centerY) + .rotate(nowLayer->property.rotation) + .scale(nowLayer->property.scale.x(), nowLayer->property.scale.y()) + .translate(centerX, centerY); + if (leafLayer != nullptr) { + Element element; + ElementTransform elementTrans; + QRectF bound = pixelPath.getBoundingRect(); + element.ratio = bound.width() / bound.height(); + // transform to initial painterPath + QTransform trans; + trans.translate(-centerX, -centerY) + .scale(1 / nowLayer->property.scale.x(), 1 / nowLayer->property.scale.y()) + .rotate(-nowLayer->property.rotation) + .translate(centerX, centerY) + .translate(-nowLayer->property.offset.x(), -nowLayer->property.offset.y()); + QPainterPath painterPath = trans.map(pixelPath.getPainterPath()); + // transfrom to -1£¬ 1 + bound = painterPath.boundingRect(); + trans.reset(); + trans.translate(1, 1); + trans.scale(2 / bound.width(), 2 / bound.height()); + trans.translate(bound.x(), bound.y()); + painterPath = trans.map(painterPath); + + element.contour.reset(new vector >(PainterPathUtil::transformToLines(painterPath))); + QSize screenSize = pixelPath.getPixmap().size(); + + elementTrans.center = glm::vec2( + (2 * (transBound.x() + transBound.width()) - screenSize.width()) / screenSize.width(), + (2 * (transBound.y() + transBound.height()) - screenSize.height()) / screenSize.height() + ); + decomposeTransform(transform, elementTrans.rotation, elementTrans.scale); + elementTrans.flip = glm::bvec2( + nowLayer->property.flipHorizontally, + nowLayer->property.flipVertically + ); + return; + } + + FolderLayerWrapper* folderLayer = dynamic_cast(nowLayer); + for (auto sonLayer : folderLayer->children) { + traverseLayTree(sonLayer.get(), transform, flip, painting); + } + return; +} +void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& scale) { + trans.translate(-trans.dx(), -trans.dy()); + int count = 0; + double norm = 0, n = 0; + QTransform R = trans, Rit, Rnext; + do { + ++count; + Rit = R.inverted(); + Rnext.setMatrix( + (R.m11() + Rit.m11()) / 2, + (R.m12() + Rit.m12()) / 2, + (R.m13() + Rit.m13()) / 2, + (R.m21() + Rit.m21()) / 2, + (R.m22() + Rit.m22()) / 2, + (R.m23() + Rit.m23()) / 2, + (R.m31() + Rit.m31()) / 2, + (R.m32() + Rit.m32()) / 2, + (R.m33() + Rit.m33()) / 2 + ); + norm = 0; + norm = max(norm, + fabs(R.m11() - Rnext.m11()) + + fabs(R.m12() - Rnext.m12()) + + fabs(R.m13() - Rnext.m13())); + norm = max(norm, + fabs(R.m21() - Rnext.m21()) + + fabs(R.m22() - Rnext.m22()) + + fabs(R.m23() - Rnext.m23())); + norm = max(norm, + fabs(R.m31() - Rnext.m31()) + + fabs(R.m32() - Rnext.m32()) + + fabs(R.m33() - Rnext.m33())); + R = Rnext; + } while (count < 100 && norm > 0.0001); + angle = acos(R.m11()); + R = R.inverted() * trans; + scale = glm::vec2(R.m11(), R.m22()); + return; +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h index 83dbac3..bb27a73 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h @@ -1,8 +1,15 @@ #pragma once #include "../../Renderer/Painting/Painting.h" +#include +#include class PaintingUtil { -public: - //static Renderer::Painting transfromToPainting(); +private: + static QJsonObject readJsonFile(QString jsonFilePath); + static void traverseLayTree(LayerWrapper* nowLayer, QTransform transform, glm::bvec2 flip, Renderer::Painting& painting); + static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale); +public: + static Renderer::Painting transfromToPainting(QString jsonFilePath); + }; diff --git a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp index 81d8966..cf1d718 100644 --- a/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/SvgFileLoader.cpp @@ -86,7 +86,6 @@ QPolygonF SvgFileLoader::handleAttrPoints(QString points) { void SvgFileLoader::handleAttrTransform(QString transformStyle, QPainterPath& painterPath) { QTransform trans; QStringList ops = transformStyle.split(')'); - reverse(ops.begin(), ops.end()); vector numbers; for (auto op : ops) { op = op.simplified();