diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index 3351b34..16ff56c 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -206,11 +206,11 @@ bool LayerStyleContainer::dropStyle(const QString& styleName) float LayerStyleContainer::boundingBoxAffectValue() const { float maxLineWidth = 0; - const auto strokeStyle = styles.at(StrokeElementLayerStyle::displayName()); - if (strokeStyle != nullptr) + const auto strokeStyle = styles.find(StrokeElementLayerStyle::displayName()); + if (strokeStyle != styles.end()) { if (const auto strokeElementLayerStyle = - std::dynamic_pointer_cast(strokeStyle); + std::dynamic_pointer_cast(strokeStyle->second); strokeElementLayerStyle != nullptr) { const auto& leftStyleStroke = strokeElementLayerStyle->strokePair.first; diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index aea42d4..ce93afb 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -5,7 +5,7 @@ #include using Renderer::Painting; -using Renderer::Element; +using Renderer::BaseElement; using Renderer::ElementTransform; using glm::bvec2; using std::max; @@ -17,161 +17,124 @@ using std::queue; const double PaintingUtil::pi = acos(-1); struct LayerNode { - LayerWrapper* nowLayer; - QTransform transfrom; - bvec2 flip; + LayerWrapper* nowLayer; + QTransform transfrom; }; 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(); + QFile jsonFile(jsonFilePath); + qDebug() << 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; - glm::bvec2 flip(0, 0); - QJsonObject jsonObj = readJsonFile(jsonFilePath); - qDebug() << jsonObj; - shared_ptr elementManager = make_shared(jsonObj, Renderer::ElementRenderer::instance()); - shared_ptr layerManager = make_shared(jsonObj, elementManager.get()); - //qDebug() << elementManager->toJson(); - //qDebug() << layerManager->toJson(); + Painting painting; + glm::bvec2 flip(0, 0); + QJsonObject jsonObj = readJsonFile(jsonFilePath); + qDebug() << jsonObj; + shared_ptr elementManager = make_shared(jsonObj, Renderer::ElementRenderer::instance()); + shared_ptr layerManager = make_shared(jsonObj, elementManager.get()); + //qDebug() << elementManager->toJson(); + //qDebug() << layerManager->toJson(); //qDebug() << ((SimpleElement*)((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->wrappedElement)->painterPath; - //qDebug() << ((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->getCache().painterPath; - queue layerQueue; - LayerWrapper* root = layerManager->getRoot(); - root->getCache(); - layerQueue.push({ root, root->property.transform, flip }); - while (!layerQueue.empty()) { - auto layerNode = layerQueue.front(); - layerQueue.pop(); - FolderLayerWrapper* nowLayer = handleLayerWrapper(layerNode.nowLayer, layerNode.transfrom, layerNode.flip, painting); - if (nowLayer != nullptr) { - for (auto sonLayer : nowLayer->children) { - layerQueue.push({ sonLayer.get(), layerNode.transfrom, layerNode.flip}); - } - } - } - - return painting; + //qDebug() << ((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->getCache().painterPath; + //qDebug() << elementManager->toJson(); + //qDebug() << layerManager->toJson(); + //qDebug() << ((SimpleElement*)((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->wrappedElement)->painterPath; + //qDebug() << ((LeafLayerWrapper*)((FolderLayerWrapper*)((FolderLayerWrapper*)layerManager->getRoot())->children[0].get())->children[0].get())->getCache().painterPath; + queue layerQueue; + LayerWrapper* root = layerManager->getRoot(); + root->getCache(); + //double maxLineWidth = getMaxLineWidth(root); + layerQueue.push({ root, root->property.transform }); + while (!layerQueue.empty()) { + auto layerNode = layerQueue.front(); + layerQueue.pop(); + FolderLayerWrapper* nowLayer = handleLayerWrapper(layerNode.nowLayer, layerNode.transfrom, painting); + if (nowLayer != nullptr) { + for (auto sonLayer : nowLayer->children) { + layerQueue.push({ sonLayer.get(), layerNode.transfrom }); + } + } + } + + return painting; } -FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, bvec2& flip, Painting& painting) { - LeafLayerWrapper* leafLayer = dynamic_cast(nowLayer); - flip ^= bvec2(nowLayer->property.flipHorizontally, nowLayer->property.flipVertically); +FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, Painting& painting) { + LeafLayerWrapper* leafLayer = dynamic_cast(nowLayer); - transform = nowLayer->property.transform * transform; + transform = nowLayer->property.transform * transform; - if (leafLayer != nullptr) { + if (leafLayer != nullptr) { - GroupElement* wrapperElement = dynamic_cast(leafLayer->wrappedElement); - if (wrapperElement != nullptr) { - transform = wrapperElement->sourceLayer->property.transform * transform; - return wrapperElement->sourceLayer; - } + GroupElement* wrapperElement = dynamic_cast(leafLayer->wrappedElement); + if (wrapperElement != nullptr) { + transform = wrapperElement->sourceLayer->property.transform * transform; + return wrapperElement->sourceLayer; + } - PixelPath pixelPath = nowLayer->getCache(); - QPainterPath painterPath = pixelPath.getPainterPath(); - QRectF bound = painterPath.boundingRect(); - //qDebug() << leafLayer<<"------" << painterPath; - //qDebug() << transform; - Element element; - ElementTransform elementTrans; - element.ratio = bound.width() / bound.height(); - // transform to initial painterPath - // transfrom to -1£¬ 1 - QTransform trans; - trans.scale(1 / bound.width(), 1 / bound.height()); - trans.translate(-bound.center().x(), -bound.center().y()); - - qDebug() << trans.map(painterPath); - element.contour = std::make_shared >>(PainterPathUtil::transformToLines(trans.map(painterPath))); - QSize screenSize = QSize(1024, 1024); - element.style = std::make_shared(0.06); - - - painterPath = transform.map(painterPath); - qDebug() << painterPath; - bound = painterPath.boundingRect(); - qDebug() << bound; + PixelPath pixelPath = nowLayer->getCache(); + QPainterPath painterPath = pixelPath.getPainterPath(); + QRectF bound = painterPath.boundingRect(); + //qDebug() << leafLayer<<"------" << painterPath; + //qDebug() << transform; + // transform to initial painterPath + // transfrom to -1£¬ 1 + QTransform trans; + double maxLen = std::max(bound.width(), bound.height()); + qDebug() << maxLen << bound; + trans.scale(1 / maxLen, 1 / maxLen); + trans.translate(-bound.center().x(), -bound.center().y()); - // TODO ¸ÄÓþØÕó + painterPath = trans.map(painterPath); + shared_ptr >> contour = std::make_shared >>(PainterPathUtil::transformToLines(painterPath)); + QSize screenSize = QSize(1024, 1024); - /* elementTrans.center = glm::vec2( - (2 * bound.center().x() - screenSize.width()) / screenSize.width(), - (2 * bound.center().y() - screenSize.height()) / screenSize.height() - ); - qDebug() << elementTrans.center.x << elementTrans.center.y; - decomposeTransform(transform, elementTrans.rotation, elementTrans.scale); - elementTrans.scale = glm::vec2( - bound.width() * 2 / screenSize.width(), - bound.height() * 2 / screenSize.height() - ); - elementTrans.flip = glm::bvec2( - nowLayer->property.flipHorizontally, - nowLayer->property.flipVertically - ); - qDebug() << elementTrans.scale.x << elementTrans.scale.y; - painting.addElement(element, elementTrans);*/ - return nullptr; - } - - FolderLayerWrapper* folderLayer = dynamic_cast(nowLayer); - return folderLayer; -} -void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& scale) { - //qDebug() << trans; - trans.setMatrix( - trans.m11(), trans.m12(), trans.m13(), - trans.m21(), trans.m22(), trans.m23(), - 0, 0, 1); - //qDebug() << trans.dx() << trans.dy(); - int count = 0; - double norm = 0, n = 0; - QTransform R = trans, Rit, Rnext; - do { - ++count; - Rit = R.transposed().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); - double cosValue = max(-1.0, min(R.m11(), 1.0)); - double sinValue = max(-1.0, min(R.m12(), 1.0)); - angle = acos(cosValue) * 180 / pi; - if (sinValue < 0) { - angle = 360 - angle; - } - qDebug() << angle; - //R = R.inverted() * trans; - //scale = glm::vec2(R.m11(), R.m22()); - //qDebug() << scale.x << scale.y; - return; + ElementTransform elementTransform; + transform = trans.inverted() * transform * QTransform::fromScale(2. / screenSize.width(), 2. / screenSize.height()) * QTransform::fromTranslate(-1, -1) * QTransform::fromScale(1, -1); + + auto baseStyles = leafLayer->styles.toBaseStyles(); + Renderer::BaseElement element; + element.contour = contour; + for (auto baseStyle : baseStyles) { + double lineWidth = 0; + if (baseStyle.material->type() == Renderer::MaterialStyleType::kStroke) { + auto material = dynamic_cast(baseStyle.material.get()); + material->halfWidth = material->halfWidth / maxLen; + lineWidth = material->halfWidth; + qDebug() << material->halfWidth; + } + QRectF rect = painterPath.boundingRect(); + rect.setX(-lineWidth + rect.x()); + rect.setY(-lineWidth + rect.y()); + rect.setWidth(lineWidth * 2 + rect.width()); + rect.setHeight(lineWidth * 2 + rect.height()); + QPainterPath path; + path.addRect(rect); + rect = transform.map(path).boundingRect(); + elementTransform.bound = glm::vec4(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); + qDebug() << elementTransform.bound.x << elementTransform.bound.y << elementTransform.bound.z << elementTransform.bound.z; + transform = transform.inverted(); + elementTransform.transform = glm::mat3x2( + transform.m11(), transform.m12(), transform.m21(), + transform.m22(), transform.m31(), transform.m32() + ); + qDebug() << transform; + elementTransform.zIndex = 0; + + element.style = baseStyle.material; + painting.addElement(element, elementTransform); + } + + return nullptr; + } + + FolderLayerWrapper* folderLayer = dynamic_cast(nowLayer); + return folderLayer; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h index 77e6ea2..850bfc0 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h @@ -7,10 +7,9 @@ class PaintingUtil private: static const double pi; static QJsonObject readJsonFile(QString jsonFilePath); - static FolderLayerWrapper* handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, glm::bvec2& flip, Renderer::Painting& painting); -public: + static FolderLayerWrapper* handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, Renderer::Painting& painting); + //static double getMaxLineWidth(LayerWrapper* root); +public: static Renderer::Painting transfromToPainting(QString jsonFilePath); - static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale); - }; diff --git a/ArchitectureColoredPainting/src/FluentMenu.cpp b/ArchitectureColoredPainting/src/FluentMenu.cpp index 42b0f7d..2119311 100644 --- a/ArchitectureColoredPainting/src/FluentMenu.cpp +++ b/ArchitectureColoredPainting/src/FluentMenu.cpp @@ -21,4 +21,9 @@ void ::FluentMenu::paintEvent(QPaintEvent* event) painter.drawRoundedRect(QRectF(shadowRadius - i, shadowRadius - i, width() - (shadowRadius - i) * 2, height() - (shadowRadius - i) * 2), borderRadius + i, borderRadius + i); } QMenu::paintEvent(event); -} \ No newline at end of file +} + +QAction* FluentMenu::exec(const QPoint& pos, QAction* at) +{ + return QMenu::exec(parentWidget()->mapToGlobal(parentWidget()->mapFromGlobal(pos) + QPoint(-shadowRadius, -shadowRadius)), at); +} diff --git a/ArchitectureColoredPainting/src/FluentMenu.h b/ArchitectureColoredPainting/src/FluentMenu.h index 480f6e2..f0ac3fe 100644 --- a/ArchitectureColoredPainting/src/FluentMenu.h +++ b/ArchitectureColoredPainting/src/FluentMenu.h @@ -7,6 +7,7 @@ class FluentMenu : public QMenu public: explicit FluentMenu(QWidget* parent = nullptr); void paintEvent(QPaintEvent* event) override; + QAction* exec(const QPoint& pos, QAction* at = nullptr); int shadowRadius = 16; int borderRadius = 6; int itemBorderRadius = 4; diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 3510ed7..9251d9c 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -244,8 +244,9 @@ GLuint Renderer::Model::loadPainting(std::string path) return iter->second; Painting painting; + path = "../test.json"; if (auto file = QFileInfo(QString(path.c_str())); file.isFile()) - painting = PaintingUtil::transfromToPainting(file.path()); + painting = PaintingUtil::transfromToPainting(file.filePath()); else { qDebug() << path.c_str() << "Not Found, Using Default Painting"; diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp index 82edf94..000fec3 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/BvhTree.cpp @@ -20,12 +20,12 @@ QVector4D BvhTree::Union(QVector4D a, QVector4D b) { QVector4D BvhTree::merge(BvhPtr lp, BvhPtr rp) { QVector4D a = lp->bound, b = rp->bound; - if (lp->isLeaf) { + /*if (lp->isLeaf) { a = BvhTreeData::boundWithRotation(a, lp->getRightSon()); } if (rp->isLeaf) { b = BvhTreeData::boundWithRotation(b, rp->getRightSon()); - } + }*/ return Union(a, b); } diff --git a/ArchitectureColoredPainting/src/Renderer/RendererWidget.cpp b/ArchitectureColoredPainting/src/Renderer/RendererWidget.cpp index d0df771..7e1e03a 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererWidget.cpp +++ b/ArchitectureColoredPainting/src/Renderer/RendererWidget.cpp @@ -29,7 +29,7 @@ Renderer::RendererWidget::RendererWidget(QWidget* parent) ui.openButton->setChecked(false); }); QObject::connect(ui.openButton, &QPushButton::clicked, [&, menu]() { - menu->exec(ui.openButton->mapToGlobal(QPoint(-menu->shadowRadius, ui.openButton->height() - menu->shadowRadius))); + menu->exec(ui.openButton->mapToGlobal(QPoint(0, ui.openButton->height()))); }); QObject::connect(ui.horizontalSlider, &QSlider::valueChanged, diff --git a/test.json b/test.json new file mode 100644 index 0000000..15441e2 --- /dev/null +++ b/test.json @@ -0,0 +1,131 @@ +{ + "background-color": "#ffffff", + "elements": [ + { + "data": { + "include": "../svg/2.svg" + }, + "name": "ababa", + "type": "svg-file" + }, + { + "data": { + "reference-layer": "0.0" + }, + "name": "ababa-group", + "type": "group" + }, + { + "data": { + "include": "../svg/0.svg" + }, + "name": "ababa2", + "type": "svg-file" + } + ], + "height": 1080, + "project-name": "样例1", + "root-layer": { + "children": [ + { + "children": [ + { + "element": 0, + "is-folder": false, + "name": "Leaf1", + "styles": [ + { + "enableEachSideIndependent": false, + "left": "AAAAQAEAIZwAf///qqr//w==", + "right": "AADgQAAACJw=", + "type": "stroke" + } + ], + "transform": { + "offset": { + "x": 0, + "y": 0 + }, + "rotation": 0, + "scale": { + "x": 1, + "y": 1 + } + } + }, + { + "element": 0, + "is-folder": false, + "name": "Leaf2", + "styles": [ + { + "enableEachSideIndependent": false, + "left": "AAAAQAEAIZwAf////1UA/w==", + "right": "AADgQAAACJw=", + "type": "stroke" + } + ], + "transform": { + "offset": { + "x": 150, + "y": 0 + }, + "rotation": 0, + "scale": { + "x": 1.5, + "y": 1.5 + } + } + } + ], + "is-folder": true, + "name": "GroupFolderExample", + "referenced-by": 1, + "transform": { + "offset": { + "x": 50, + "y": 50 + }, + "rotation": 0, + "scale": { + "x": 1, + "y": 1 + } + } + }, + { + "element": 1, + "is-folder": false, + "name": "ReferencingGroupLayer", + "styles": [ + ], + "transform": { + "offset": { + "x": 100, + "y": 0 + }, + "rotation": 45, + "scale": { + "x": 1, + "y": 1 + } + } + } + ], + "is-folder": true, + "name": "root", + "referenced-by": null, + "transform": { + "offset": { + "x": 0, + "y": 0 + }, + "rotation": 0, + "scale": { + "x": 1, + "y": 1 + } + } + }, + "width": 1080 +}