diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp index bef3c7c..eb5f228 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp @@ -19,6 +19,15 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p elementInfoDisplayWidget->enableEdit(); qDebug() << layerInfoDisplayWidget; qDebug() << elementInfoDisplayWidget; + auto centralRefresh = [this]() { + layerInfoDisplayWidget->refresh(); + elementInfoDisplayWidget->refresh(); + treeWidget->refresh(); + previewWindow->refresh(); + }; + connect(layerInfoDisplayWidget, &InfoDisplayWidget::triggerCentralRefresh, centralRefresh); + connect(elementInfoDisplayWidget, &ElementPoolWidget::triggerCentralRefresh, centralRefresh); + connect(treeWidget, &LayerTreeWidget::triggerCentralRefresh, centralRefresh); connect(editorSettingWidget, &EditorSettingWidget::backgroundColorChanged, this, &EditorWidgetItem::handleBackgroundColorChange); connect(editorSettingWidget, &EditorSettingWidget::projectNameChanged, this, &EditorWidgetItem::handleProjectNameChange); connect(previewWindow, &PreviewWindow::refreshElementPreviewByIndex, elementInfoDisplayWidget, &ElementPoolWidget::refreshPictureByIndex); diff --git a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp index 17ec55a..74453d0 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp @@ -67,7 +67,6 @@ void ElementPoolWidget::setElementManager(ElementManager* element) void ElementPoolWidget::refresh() { this->setElementList(this->elementManager->elements); - emit refreshLayerTree(); // update(); } @@ -113,13 +112,14 @@ void ElementPoolWidget::popMenu(const QPoint& pos) if (bOk && !sName.isEmpty()) { currentElement->name = sName; - refresh(); + emit triggerCentralRefresh(); } }); menu->addAction(QString::fromLocal8Bit("删除"), this, [this, currentElement]() { this->elementManager->removeElement(currentElement); - refresh(); + emit triggerCentralRefresh(); }); + menu->actions().last()->setDisabled(currentElement->referencedCount > 0); } else { @@ -129,7 +129,7 @@ void ElementPoolWidget::popMenu(const QPoint& pos) QString fileName = fileInfo.fileName(); qDebug() << fileName << " " << filePath; this->elementManager->createSimpleElement(fileName, filePath); - refresh(); + emit triggerCentralRefresh(); }); } menu->popup(mapToGlobal(pos)); diff --git a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h index 82ee0ff..472b1ba 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h +++ b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h @@ -26,6 +26,7 @@ public: signals: void elementSelected(GraphicElement* element); void refreshLayerTree(); + void triggerCentralRefresh(); public slots: int pictureItemClicked(QListWidgetItem* item); diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index 377b9e5..8ce9bf2 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -20,6 +20,7 @@ class ComposedPainterPath; class GraphicElement { public: + size_t referencedCount = 0; Renderer::ElementRenderer *renderer; QString name = ""; int index; diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index 04ea5fd..292d0ca 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -207,11 +207,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/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index f131f27..bf0222b 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -79,6 +79,14 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager* elementMana styles(LayerStyleContainer::fromJson(wrappedElement->isClosed(), json.value("styles").toArray())) { qDebug() << json.value("name").toString() << " " << this; + if(wrappedElement != nullptr) + wrappedElement->referencedCount++; +} + +LeafLayerWrapper::~LeafLayerWrapper() +{ + if (wrappedElement != nullptr) + wrappedElement->referencedCount--; } void LayerWrapper::SimpleProperty::apply(PixelPath&cache) @@ -368,4 +376,56 @@ void FolderLayerWrapper::refreshTreeItem() this->qTreeWidgetItem->setText(1, "<< " + ele->name); this->qTreeWidgetItem->setTextColor(1, Qt::darkGreen); } + if (this->referencedCount() > 0) + { + this->qTreeWidgetItem->setToolTip(0,QString::fromLocal8Bit("子树被引用计数:") + QString::number(this->referencedCount(true)) + "\n" + + QString::fromLocal8Bit("当前节点被引用计数:") + QString::number(this->getReferencedBy() != -1)); + } + else + { + this->qTreeWidgetItem->setToolTip(0, ""); + } } + +size_t LayerWrapper::referencedCount(bool excludeSelf) const +{ + return 0; +} + +size_t FolderLayerWrapper::referencedCount(bool excludeSelf) const +{ + size_t count = 0; + for (auto& child : children) + count += child->referencedCount(); + if (!excludeSelf && this->getReferencedBy() != -1) + count++; + return count; +} + +bool LayerWrapper::deleteable(bool excludeSubTree) const +{ + return true; +} + +bool FolderLayerWrapper::deleteable(bool excludeSubTree) const +{ + if (excludeSubTree) + return this->getReferencedBy() == -1; + else + return this->referencedCount() == 0; +} + +bool LayerWrapper::referencingGroupElement() const +{ + return false; +} + +bool LeafLayerWrapper::referencingGroupElement() const +{ + return typeid(*wrappedElement) == typeid(GroupElement); +} + +bool LayerWrapper::canApplyStyles() const +{ + return typeid(*this) == typeid(LeafLayerWrapper) && !referencingGroupElement(); +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index 3b82b86..947d90c 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -71,6 +71,10 @@ class LayerWrapper virtual void collectUpReachable(std::set& reachable); virtual void collectDownReachable(std::set& reachable); virtual void refreshTreeItem(); + virtual size_t referencedCount(bool excludeSelf = false) const; + virtual bool deleteable(bool excludeSubTree = false) const; + virtual bool referencingGroupElement() const; + bool canApplyStyles() const; }; class FolderLayerWrapper : public LayerWrapper @@ -96,6 +100,8 @@ class FolderLayerWrapper : public LayerWrapper void paint(QPainter* painter, QTransform transform = QTransform(), bool ignoreSelected = false) override; void collectDownReachable(std::set& reachable) override; void refreshTreeItem() override; + size_t referencedCount(bool excludeSelf = false) const override; + bool deleteable(bool excludeSubTree = false) const override; }; class LeafLayerWrapper : public LayerWrapper @@ -105,7 +111,7 @@ class LeafLayerWrapper : public LayerWrapper LayerStyleContainer styles; public: - ~LeafLayerWrapper() = default; + ~LeafLayerWrapper(); void refresh(LayerWrapper* layer = nullptr) override; LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent); QJsonObject toJson() const override; @@ -113,6 +119,7 @@ class LeafLayerWrapper : public LayerWrapper void collectDownReachable(std::set& reachable) override; QTreeWidgetItem* getQTreeItem() override; void refreshTreeItem() override; + bool referencingGroupElement() const override; }; Q_DECLARE_METATYPE(LayerWrapper *) diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp index 1db2940..6869729 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp @@ -45,32 +45,27 @@ void InfoDisplayWidget::generateLayerForm() rotation->setValidator(new QIntValidator(-10000, 10000, this)); connect(rotation, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.rotation = content.toDouble(); - emit requireRefreshElementWidget(); - emit requireRefreshPreview(); + emit triggerCentralRefresh(); }); offsetX->setValidator(new QIntValidator(-10000, 10000, this)); connect(offsetX, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.offset = {content.toDouble(), this->displayLayer->property.offset.y()}; - emit requireRefreshElementWidget(); - emit requireRefreshPreview(); + emit triggerCentralRefresh(); }); offsetY->setValidator(new QIntValidator(-10000, 10000, this)); connect(offsetY, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.offset = {this->displayLayer->property.offset.x(), content.toDouble()}; - emit requireRefreshElementWidget(); - emit requireRefreshPreview(); + emit triggerCentralRefresh(); }); scaleX->setValidator(new QDoubleValidator(-1000, 1000, 4, this)); connect(scaleX, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.scale = {content.toDouble(), this->displayLayer->property.scale.y()}; - emit requireRefreshElementWidget(); - emit requireRefreshPreview(); + emit triggerCentralRefresh(); }); scaleY->setValidator(new QDoubleValidator(-1000, 1000, 4, this)); connect(scaleY, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.scale = {this->displayLayer->property.scale.x(), content.toDouble()}; - emit requireRefreshElementWidget(); - emit requireRefreshPreview(); + emit triggerCentralRefresh(); }); layout->addRow("layer name:", name); @@ -108,10 +103,7 @@ void InfoDisplayWidget::generateLayerForm() { leafP->styles.useStyle(dialog->layerStyle); leafP->styles.computeNewHash(); - - emit requireRefreshPreview(); - emit requireSelfRefresh(); - emit requireRefreshElementWidget(); + emit triggerCentralRefresh(); } }); } @@ -153,10 +145,7 @@ void InfoDisplayWidget::generateLayerForm() { styleIterator->second = dialog->layerStyle; styles->computeNewHash(); - - emit requireRefreshPreview(); - emit requireSelfRefresh(); - emit requireRefreshElementWidget(); + emit triggerCentralRefresh(); } }); @@ -165,10 +154,7 @@ void InfoDisplayWidget::generateLayerForm() { styles->dropStyle(styleIterator->first); styles->computeNewHash(); - - emit requireRefreshPreview(); - emit requireSelfRefresh(); - emit requireRefreshElementWidget(); + emit triggerCentralRefresh(); }); QWidget* styleDisplayWidget = styleIterator->second->getListDisplayWidget(); @@ -190,6 +176,12 @@ void InfoDisplayWidget::generateLayerForm() } void InfoDisplayWidget::triggerSelfRefresh() +{ + if (this->displayLayer != nullptr) + this->generateLayerForm(); +} + +void InfoDisplayWidget::refresh() { if (this->displayLayer != nullptr) this->generateLayerForm(); diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.h b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.h index 37b259c..da314f5 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.h +++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.h @@ -16,11 +16,13 @@ class InfoDisplayWidget : public QWidget public: void setLayer(LayerWrapper *layer); void generateLayerForm(); + void refresh(); public slots: void triggerSelfRefresh(); - signals: +signals: + void triggerCentralRefresh(); void requireRefreshPreview(); void requireSelfRefresh(); void requireRefreshElementWidget(); diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp index 69a67b9..a8ba44e 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp @@ -24,7 +24,7 @@ LayerTreeWidget::LayerTreeWidget(QWidget *parent) else { emit displayLayerChange(nullptr); } - emit requireRefreshPreview(); + emit triggerCentralRefresh(); }); // connect(this, &QTreeWidget::itemDoubleClicked, this, &LayerTreeWidget::onItemDoubleClicked); } @@ -62,9 +62,7 @@ void LayerTreeWidget::popMenu(const QPoint &pos) folderLayer->addChild(std::shared_ptr(newLayer)); folderLayer->qTreeWidgetItem->addChild(newLayer->getQTreeItem()); qDebug() << jsonObj<<"----------------------"; - this->refresh(); - emit requireRefreshPreview(); - emit requireRefreshElementWidget(); + emit triggerCentralRefresh(); }); dialog->exec(); }); @@ -74,20 +72,20 @@ void LayerTreeWidget::popMenu(const QPoint &pos) auto layer = this->selectedItem->data(0, Qt::UserRole).value(); layer->del(); layer->getParent()->removeChild(layer); - this->refresh(); - emit requireRefreshPreview(); - emit requireRefreshElementWidget(); + emit triggerCentralRefresh(); }); + menu.actions().last()->setEnabled(layer->deleteable()); menu.addAction(QString::fromLocal8Bit("重命名"), this, &LayerTreeWidget::onRenameEvent); if(typeid(*layer) == typeid(FolderLayerWrapper)) + { menu.addAction(QString::fromLocal8Bit("删除(保留子节点)"), this, [this]() { auto layer = this->selectedItem->data(0, Qt::UserRole).value(); - layer->delSelf(); - layer->getParent()->removeChild(layer); - this->refresh(); - emit requireRefreshPreview(); - emit requireRefreshElementWidget(); + layer->delSelf(); + layer->getParent()->removeChild(layer); + emit triggerCentralRefresh(); }); + menu.actions().last()->setEnabled(layer->deleteable(true)); + } } if (typeid(*layer) == typeid(FolderLayerWrapper) && ((FolderLayerWrapper*)layer)->getReferencedBy() == -1) { menu.addAction(QString::fromLocal8Bit("创建组合元素"), this, [this]() { @@ -99,7 +97,7 @@ void LayerTreeWidget::popMenu(const QPoint &pos) "", &ok); if (ok && !name.isEmpty()) { elementManager->createGroupElement(name, layer); - emit requireRefreshElementWidget(); + emit triggerCentralRefresh(); } } }); diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h index e7472dd..a7f4c93 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h +++ b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.h @@ -21,6 +21,7 @@ class LayerTreeWidget : public QTreeWidget // void onItemDoubleClicked(QTreeWidgetItem *item, int column = 0); signals: + void triggerCentralRefresh(); void displayLayerChange(LayerWrapper *); void requireRefreshPreview(); void requireRefreshElementWidget(); 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 +}