From 073f68e36060a127a42876d40822a2193830ab57 Mon Sep 17 00:00:00 2001 From: ArgonarioD Date: Wed, 15 Mar 2023 11:43:16 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=BA=86=E7=BC=96=E8=BE=91=E5=99=A8=E4=B8=AD=E7=9A=84StrokeSty?= =?UTF-8?q?le=20[style/stroke]=20=E5=AE=9E=E7=8E=B0=E4=BA=86=E8=A1=8C?= =?UTF-8?q?=E5=88=A0=E9=99=A4=20[style/stroke]=20=E5=9F=BA=E6=9C=AC?= =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E4=BA=86strokeStyle=E7=9A=84=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20[paint]=20=E4=BB=A4drawElement=E6=97=B6=E4=BC=9A?= =?UTF-8?q?=E5=BA=94=E7=94=A8style=20[style]=20=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?LayerStyle=20[editor]=20=E6=96=B0=E5=A2=9E=E4=BA=86ColorPicker?= =?UTF-8?q?=E7=B1=BB=E5=92=8CStrokeStyleListView=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchitectureColoredPainting.vcxproj | 4 + ...rchitectureColoredPainting.vcxproj.filters | 86 ++++++++------ .../EditorWidgetComponent/ColorPicker.cpp | 38 ++++++ .../EditorWidgetComponent/ColorPicker.h | 16 +++ .../LayerStyleDialog.cpp | 2 +- .../StrokeStyleListView.cpp | 108 ++++++++++++++++++ .../StrokeStyleListView.h | 21 ++++ .../src/Editor/GraphicElement.cpp | 41 +++++-- .../src/Editor/GraphicElement.h | 6 +- .../src/Editor/LayerStyle.cpp | 98 +++++++++++++--- .../src/Editor/LayerStyle.h | 27 +++-- .../Renderer/Painting/MaterialStyleStroke.cpp | 1 + .../src/Renderer/Preview/ElementRenderer.cpp | 1 + 13 files changed, 380 insertions(+), 69 deletions(-) create mode 100644 ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.cpp create mode 100644 ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h create mode 100644 ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.cpp create mode 100644 ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.h diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj index bc422d1..a0e5563 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj @@ -104,6 +104,7 @@ + @@ -152,6 +153,7 @@ + @@ -187,12 +189,14 @@ + + diff --git a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters index f7e8d97..e019bc3 100644 --- a/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters +++ b/ArchitectureColoredPainting/ArchitectureColoredPainting.vcxproj.filters @@ -65,6 +65,12 @@ {7ead1a66-586a-4584-ae80-9e7a4e667364} + + {be3f4585-c8ba-410f-8619-2adcd4349f02} + + + {b9732a33-aa2e-4f8d-886f-1b1730c66519} + @@ -111,9 +117,6 @@ Source Files\Renderer - - Source Files - Source Files\Renderer\Painting @@ -156,12 +159,6 @@ Source Files\Renderer\Painting - - Source Files - - - Source Files - Source Files\Renderer\Painting @@ -189,9 +186,6 @@ Source Files\Renderer\Preview - - Source Files - Source Files\Renderer @@ -216,11 +210,29 @@ Source Files\Editor\util - - Source Files + + Source Files\Editor\Style - Source Files + Source Files\Editor\Style + + + Source Files\Editor\Style + + + Source Files\Editor + + + Source Files\Editor + + + Source Files\Editor + + + Source Files\Editor + + + Source Files\Editor @@ -233,35 +245,41 @@ Header Files\Renderer - - Header Files - - - Header Files - Header Files\Editor - - Header Files - - - Header Files - - - Header Files - Header Files\Editor Header Files - - Header Files + + Header Files\Editor\Style - Header Files + Header Files\Editor\Style + + + Header Files\Editor + + + Header Files\Editor + + + Header Files\Editor + + + Header Files\Editor + + + Header Files\Editor + + + Header Files\Editor + + + Header Files\Editor @@ -457,7 +475,7 @@ Header Files\Editor\util - Header Files\Editor + Header Files\Editor\Style diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.cpp new file mode 100644 index 0000000..7010ae4 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.cpp @@ -0,0 +1,38 @@ +#include "ColorPicker.h" +#include + +QString getStyleSheet(const QColor& color) +{ + return + "QPushButton#colorPicker {" + " border-style: solid;" + " border-width: 1px;" + " border-color: black;" + " background-color: " + color.name() + ";" + "}"; +} + +ColorPicker::ColorPicker(const QColor& color, QWidget* parent) : QPushButton(parent), color(color) +{ + this->setObjectName("colorPicker"); + this->setStyleSheet(getStyleSheet(color)); + connect(this, &QPushButton::clicked, this, &ColorPicker::onClicked); +} + +QColor ColorPicker::getColor() const +{ + return color; +} + +void ColorPicker::onClicked() +{ + QColorDialog dialog(this->color, this); + dialog.exec(); + QColor newColor = dialog.selectedColor(); + if (newColor.isValid() && this->color != newColor) + { + this->color = newColor; + this->setStyleSheet(getStyleSheet(newColor)); + emit colorChanged(newColor); + } +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h new file mode 100644 index 0000000..aca00ea --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/ColorPicker.h @@ -0,0 +1,16 @@ +#pragma once +#include +class ColorPicker : public QPushButton +{ + Q_OBJECT +private: + QColor color; +public: + ColorPicker(const QColor& color, QWidget* parent = nullptr); + QColor getColor() const; +public slots: + void onClicked(); +signals: + void colorChanged(QColor newColor); +}; + diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp index 7a7db8d..478301a 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp @@ -18,7 +18,7 @@ LayerStyleDialog::LayerStyleDialog( if (existedStyle) { - this->modifyingStyle = existedStyle->clonePtr(); + this->modifyingStyle = existedStyle->clone(); this->styleContainer = nullptr; this->styleWidget = modifyingStyle->getInputWidget(); diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.cpp new file mode 100644 index 0000000..5b011a7 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.cpp @@ -0,0 +1,108 @@ +#include "StrokeStyleListView.h" +#include "ColorPicker.h" +#include + +constexpr int COLUMN_WIDTH = 0; +constexpr int COLUMN_COLOR = 1; +constexpr int COLUMN_METALLIC = 2; +constexpr int COLUMN_ROUGHNESS = 3; +constexpr int COLUMN_OPERATIONS = 4; + +// TODO: 将这个类改为继承QWidget,把table转为其中的一个元素,加上新增行按钮和宽度设置 +StrokeStyleListView::StrokeStyleListView( + std::shared_ptr stroke, + QWidget* parent +) : QTableWidget(parent), stroke(stroke) +{ + this->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow); + this->setColumnCount(5); + this->setRowCount(stroke->materialMap.size()); + QStringList headers; + headers.append(QStringLiteral("离心距离占比")); + headers.append(QStringLiteral("颜色")); + headers.append(QStringLiteral("金属度")); + headers.append(QStringLiteral("粗糙度")); + headers.append(QStringLiteral("其他操作")); + this->setHorizontalHeaderLabels(headers); + for (int row = 0; auto& strokePair : stroke->materialMap) + { + QTableWidgetItem* widthItem = new QTableWidgetItem; + widthItem->setData(Qt::EditRole, strokePair.first); + this->setItem(row, COLUMN_WIDTH, widthItem); + + QColor* colorPtr = &(strokePair.second.color); + QTableWidgetItem* colorItem = new QTableWidgetItem; + colorItem->setData(Qt::DisplayRole, *colorPtr); + this->setItem(row, COLUMN_COLOR, colorItem); + ColorPicker* colorPicker = new ColorPicker(*colorPtr, this); + this->setCellWidget(row, COLUMN_COLOR, colorPicker); + connect(colorPicker, &ColorPicker::colorChanged, [this, colorPtr](QColor color) { + *colorPtr = color; + this->update(); + }); + + QTableWidgetItem* metallicItem = new QTableWidgetItem; + metallicItem->setData(Qt::EditRole, strokePair.second.metallic); + this->setItem(row, COLUMN_METALLIC, metallicItem); + + QTableWidgetItem* roughnessItem = new QTableWidgetItem; + roughnessItem->setData(Qt::EditRole, strokePair.second.roughness); + this->setItem(row, COLUMN_ROUGHNESS, roughnessItem); + + QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", this); + removeButton->setFixedSize(20, 20); + this->setCellWidget(row, COLUMN_OPERATIONS, removeButton); + connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() { + this->stroke->materialMap.erase(this->item(row, COLUMN_WIDTH)->text().toFloat()); + this->removeRow(row); + }); + + row++; + } + connect(this, &StrokeStyleListView::currentItemChanged, this, &StrokeStyleListView::onCurrentItemChanged); + connect(this, &StrokeStyleListView::cellChanged, this, &StrokeStyleListView::onCellChanged); + this->adjustSize(); +} + +void StrokeStyleListView::onCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous) +{ + if (!current) return; + int column = current->column(); + if (column != COLUMN_COLOR && column != COLUMN_OPERATIONS) + { + this->currentItemValue = current->text(); + } +} + +void StrokeStyleListView::onCellChanged(int row, int column) +{ + auto changedItem = this->item(row, column); + auto changedItemValue = changedItem->text().toFloat(); + if (changedItemValue < 0 || 1 < changedItemValue) + { + changedItem->setData(Qt::EditRole, this->currentItemValue.toFloat()); + return; + } + auto changedWidth = this->item(row, COLUMN_WIDTH)->text().toFloat(); + switch (row) + { + case COLUMN_WIDTH: + { + float oldWidth = this->currentItemValue.toFloat(); + auto node = stroke->materialMap.extract(oldWidth); + node.key() = changedWidth; + stroke->materialMap.insert(std::move(node)); + break; + } + case COLUMN_METALLIC: + { + stroke->materialMap[changedWidth].metallic = changedItemValue; + break; + } + case COLUMN_ROUGHNESS: + { + stroke->materialMap[changedWidth].roughness = changedItemValue; + break; + } + } +} \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.h new file mode 100644 index 0000000..f12e400 --- /dev/null +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleListView.h @@ -0,0 +1,21 @@ +#pragma once +#include "LayerStyle.h" +#include "../Renderer/Painting/MaterialStyleStroke.h" +#include +#include +#include +class StrokeStyleListView : public QTableWidget +{ + Q_OBJECT +private: + QString currentItemValue; + +public: + StrokeStyleListView(std::shared_ptr stroke, QWidget* parent = nullptr); + std::shared_ptr stroke; + +protected slots: + void onCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous); + void onCellChanged(int row, int column); +}; + diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 9602f2d..2775fe5 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -45,9 +45,22 @@ PixelPath GroupElement::getPaintObject() const //TODO: apply styles and send back PixelPath SimpleElement::getPaintObject(std::vector>* styles) const { PixelPath result; - Renderer::ElementStyleStrokeDemo demo(2); - auto [img, mov] = renderer->drawElement(painterPath, demo, 1.0); - //qDebug() << mov; + std::shared_ptr style; + if ((*styles).empty()) + { + style = std::make_shared(2); + } + else + { + style = (*styles)[0]; + /*qDebug() << std::dynamic_pointer_cast( + std::dynamic_pointer_cast(style)->materialStyles[0]->materialStroke + )->material.color.name();*/ + /*qDebug() << std::dynamic_pointer_cast( + std::dynamic_pointer_cast(style)->materialStyles[0]->materialStroke + )->materialMap[1.0].color;*/ + } + auto [img, mov] = renderer->drawElement(painterPath, *style, 1.0); //qDebug() << img << " ------"; result.addImage(img, mov); //result.addPath(painterPath); @@ -85,7 +98,7 @@ QJsonObject GraphicElement::toJson() const return result; } -void SimpleElement::paint(QPainter* painter, QTransform transform, vector> styles) +void SimpleElement::paint(QPainter* painter, QTransform transform, const vector> &styles) { painter->save(); painter->setTransform(transform); @@ -95,16 +108,30 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, vectordrawElement(painterPath, demo, 1.0); + std::shared_ptr style; + if (styles.empty()) + { + style = std::make_shared(2); + } + else + { + style = styles[0]; + /*qDebug() << std::dynamic_pointer_cast( + std::dynamic_pointer_cast(style)->materialStyles[0]->materialStroke + )->material.color.name();*/ + /*qDebug() << std::dynamic_pointer_cast( + std::dynamic_pointer_cast(style)->materialStyles[0]->materialStroke + )->materialMap[1.0].color;*/ + } + auto [img, mov] = renderer->drawElement(painterPath, *style, 1.0); painter->drawImage(mov, img); } painter->restore(); } -void GroupElement::paint(QPainter* painter, QTransform transform, vector> styles) +void GroupElement::paint(QPainter* painter, QTransform transform, const vector> &styles) { sourceLayer->paint(painter, transform); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index 577f7db..ce54ad7 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -28,7 +28,7 @@ public: virtual QJsonObject toJson() const; virtual PixelPath getPaintObject() const = 0; virtual PixelPath getPaintObject(std::vector>*) const = 0; - virtual void paint(QPainter* painter, QTransform transform, std::vector> styles) = 0; + virtual void paint(QPainter* painter, QTransform transform, const std::vector> &styles) = 0; }; class SimpleElement : public GraphicElement @@ -45,7 +45,7 @@ public: ~SimpleElement() = default; PixelPath getPaintObject() const override; PixelPath getPaintObject(std::vector>*) const override; - void paint(QPainter* painter, QTransform transform, std::vector> styles) override; + void paint(QPainter* painter, QTransform transform, const std::vector> &styles) override; }; class GroupElement : public GraphicElement @@ -60,7 +60,7 @@ public: PixelPath getPaintObject() const override; PixelPath getPaintObject(std::vector>*) const override; void setSourceLayer(FolderLayerWrapper* sourceLayer); - void paint(QPainter* painter, QTransform transform, std::vector> styles) override; + void paint(QPainter* painter, QTransform transform, const std::vector> &styles) override; }; //******************************** BitmapPath ********************************// diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index c76432f..e44e855 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -1,9 +1,13 @@ #include "LayerStyle.h" +#include "./EditorWidgetComponent/StrokeStyleListView.h" +#include #include #include #include #include #include +#include +#include const std::vector()>>> LayerStyle::types = { { @@ -18,7 +22,22 @@ const std::vector() std::vector StrokeElementLayerStyle::toBaseStyles() const { - return std::vector(); + std::vector baseStyles; + if (enableEachSideIndependent) + { + baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), + strokePair.first)); + baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), + strokePair.second)); + } + else + { + auto material = std::shared_ptr(std::move(strokePair.first->clone())); + std::dynamic_pointer_cast(material)->strokeType = Renderer::StrokeType::kBothSides; + + baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), material)); + } + return baseStyles; } QString StrokeElementLayerStyle::getStyleName() const @@ -26,12 +45,61 @@ QString StrokeElementLayerStyle::getStyleName() const return QStringLiteral("描边"); } -QWidget* StrokeElementLayerStyle::getInputWidget() const +QWidget* StrokeElementLayerStyle::getInputWidget() { - // TODO - QLabel* le = new QLabel; - le->setText(QStringLiteral("描边")); - return le; + if (this->strokePair.first == nullptr) + { + auto materialMap = std::map(); + materialMap[0.3] = Renderer::Material{ QColor(0,255,255), 0.f, .8f }; + materialMap[1.0] = Renderer::Material{ QColor(80,25,255), 0.f, .8f }; + this->strokePair.first = std::shared_ptr(new Renderer::MaterialStyleStroke( + 15, + Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, + std::shared_ptr(new Renderer::StrokeRadialGradient( + materialMap, false + )) + )); + } + if (this->strokePair.second == nullptr) + { + auto materialMap = std::map(); + materialMap[0.3] = Renderer::Material{ QColor(0,255,255), 0.f, .8f }; + materialMap[1.0] = Renderer::Material{ QColor(80,25,255), 0.f, .8f }; + this->strokePair.second = std::shared_ptr(new Renderer::MaterialStyleStroke( + 15, + Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, + std::shared_ptr(new Renderer::StrokeRadialGradient( + materialMap, false + )) + )); + } + QWidget* w = new QWidget; + QListView* materialList = new QListView; + + QVBoxLayout* layout = new QVBoxLayout(w); + layout->setMargin(0); + + StrokeStyleListView* leftStrokeView = new StrokeStyleListView( + std::dynamic_pointer_cast(this->strokePair.first->materialStroke), w + ); + layout->addWidget(leftStrokeView); + + QtMaterialCheckBox* checkEachSideIndependent = new QtMaterialCheckBox(w); + checkEachSideIndependent->setText(QStringLiteral("启用两侧独立描边")); + checkEachSideIndependent->setChecked(enableEachSideIndependent); + layout->addWidget(checkEachSideIndependent); + + StrokeStyleListView* rightStrokeView = new StrokeStyleListView( + std::dynamic_pointer_cast(this->strokePair.second->materialStroke), w + ); + layout->addWidget(rightStrokeView); + rightStrokeView->setDisabled(!this->enableEachSideIndependent); + + QObject::connect(checkEachSideIndependent, &QtMaterialCheckBox::toggled, [this, rightStrokeView](bool toggled) { + this->enableEachSideIndependent = toggled; + rightStrokeView->setDisabled(!toggled); + }); + return w; } QWidget* StrokeElementLayerStyle::getListDisplayWidget() const @@ -47,14 +115,16 @@ QWidget* StrokeElementLayerStyle::getListDisplayWidget() const StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other) { - materialStyles = std::vector>(other.materialStyles.size()); - for (size_t i = 0; i < other.materialStyles.size(); i++) - { - materialStyles[i] = std::make_shared(*other.materialStyles[i]); - } + strokePair.first = std::dynamic_pointer_cast( + std::shared_ptr(std::move(other.strokePair.first->clone())) + ); + strokePair.second = std::dynamic_pointer_cast( + std::shared_ptr(std::move(other.strokePair.second->clone())) + ); + enableEachSideIndependent = other.enableEachSideIndependent; } -std::unique_ptr StrokeElementLayerStyle::clonePtr() const +std::unique_ptr StrokeElementLayerStyle::clone() const { return std::make_unique(StrokeElementLayerStyle(*this)); } @@ -69,7 +139,7 @@ QString FillElementLayerStyle::getStyleName() const return QStringLiteral("填充"); } -QWidget* FillElementLayerStyle::getInputWidget() const +QWidget* FillElementLayerStyle::getInputWidget() { // TODO QLineEdit* name = new QLineEdit; @@ -97,7 +167,7 @@ FillElementLayerStyle::FillElementLayerStyle(const FillElementLayerStyle& other) } } -std::unique_ptr FillElementLayerStyle::clonePtr() const +std::unique_ptr FillElementLayerStyle::clone() const { return std::make_unique(FillElementLayerStyle(*this)); } diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.h b/ArchitectureColoredPainting/src/Editor/LayerStyle.h index 79a49ec..7d5fb25 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.h +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.h @@ -9,6 +9,9 @@ #include "../Renderer/Painting/MaterialStyleStroke.h" #include "../Renderer/Painting/MaterialStyleFill.h" +using Renderer::MaterialStyle; +using Renderer::MaterialStyleStroke; + /** * 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法 * 在进行Style的修改时,直接调用getInputWidget()方法 @@ -16,41 +19,45 @@ * 对于LayerStyle的实现类,应该同时实现ElementStyle,并将相同种类的(如描边或填充)的style整合成一个类, * 对于相同的类,一个图层应该只拥有一个 */ -class LayerStyle +class LayerStyle : public Renderer::ElementStyle { public: const static std::vector()>>> types; virtual QString getStyleName() const = 0; - virtual QWidget* getInputWidget() const = 0; + virtual QWidget* getInputWidget() = 0; virtual QWidget* getListDisplayWidget() const = 0; virtual ~LayerStyle() {}; - virtual std::unique_ptr clonePtr() const = 0; + virtual std::unique_ptr clone() const = 0; }; -class StrokeElementLayerStyle : public Renderer::ElementStyle, public LayerStyle +class StrokeElementLayerStyle : public LayerStyle { +private: + std::pair, std::shared_ptr> strokePair; + public: std::vector toBaseStyles() const override; QString getStyleName() const override; - QWidget* getInputWidget() const override; + QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; StrokeElementLayerStyle() = default; StrokeElementLayerStyle(const StrokeElementLayerStyle& other); ~StrokeElementLayerStyle() = default; - std::vector> materialStyles; - std::unique_ptr clonePtr() const override; + std::unique_ptr clone() const override; + + bool enableEachSideIndependent = false; }; -class FillElementLayerStyle : public Renderer::ElementStyle, public LayerStyle +class FillElementLayerStyle : public LayerStyle { public: std::vector toBaseStyles() const override; QString getStyleName() const override; - QWidget* getInputWidget() const override; + QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; FillElementLayerStyle() = default; FillElementLayerStyle(const FillElementLayerStyle& other); ~FillElementLayerStyle() = default; std::vector> materialStyles; - std::unique_ptr clonePtr() const override; + std::unique_ptr clone() const override; }; \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp index 8af376d..371cb86 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp @@ -25,6 +25,7 @@ std::unique_ptr Renderer::StrokePlain::clone() const std::vector Renderer::StrokePlain::encoded() const { + qDebug() << material.color; return { glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(material.toVec().second, 0.f, 0.f))), glm::uintBitsToFloat(glm::packUnorm4x8(material.toVec().first)) }; } diff --git a/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp b/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp index 471d931..45b700a 100644 --- a/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp @@ -75,6 +75,7 @@ std::vector generateStyleBuffer(const std::vector& styles) styleBuffer.push_back(style.transform->scale.y); styleBuffer.push_back(style.transform->rotation); styleBuffer.push_back(glm::uintBitsToFloat(glm::packUnorm2x16(style.transform->flip))); + auto encoded = style.material->encoded(); styleBuffer.insert(styleBuffer.end(), encoded.begin(), encoded.end()); qDebug() << "style size" << styleBuffer.size(); From 3b87644e21f40f0a90cf998d4e6e1e7acfbe9e2d Mon Sep 17 00:00:00 2001 From: karlis <2995621482@qq.com> Date: Wed, 15 Mar 2023 16:16:59 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86PixelPath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Editor/EditorWidgetItem.cpp | 2 +- .../src/Editor/GraphicElement.cpp | 15 +++++++-- .../src/Editor/GraphicElement.h | 2 +- .../src/Editor/LayerWrapper.cpp | 3 ++ .../src/Editor/PixelPath.cpp | 2 ++ .../src/Editor/PixelPath.h | 2 +- .../src/Editor/util/PaintingUtil.cpp | 14 +++++++-- .../src/Renderer/Model.cpp | 2 +- svg/4_L0.svg | 5 +++ svg/ex.json | 31 +++++++++++++++++++ 10 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 svg/4_L0.svg create mode 100644 svg/ex.json diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp index 0a3f01b..ab1f096 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp @@ -41,7 +41,7 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p layerManager = new LayerManager(source, elementManager); elementInfoDisplayWidget->setElementManager(elementManager); treeWidget->elementManager = elementManager; - qDebug() << layerManager->toJson(); + //qDebug() << layerManager->toJson(); previewWindow->initialize(layerManager,QSize(jsonDoc.object().value("width").toDouble(),jsonDoc.object().value("height").toDouble())); diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 2775fe5..6be59ff 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -1,11 +1,14 @@ #include "GraphicElement.h" #include "util/SvgFileLoader.h" +#include +#include using namespace std; PixelPath SimpleElement::getPaintObject() const { PixelPath result; result.addPath(painterPath); + qDebug() << result.getPainterPath(); return result; } @@ -48,7 +51,7 @@ PixelPath SimpleElement::getPaintObject(std::vector> std::shared_ptr style; if ((*styles).empty()) { - style = std::make_shared(2); + return this->getPaintObject(); } else { @@ -63,6 +66,7 @@ PixelPath SimpleElement::getPaintObject(std::vector> auto [img, mov] = renderer->drawElement(painterPath, *style, 1.0); //qDebug() << img << " ------"; result.addImage(img, mov); + result.addPath(painterPath); //result.addPath(painterPath); // QImage img(80,80,QImage::Format_ARGB32); // QPainter pt(&img); @@ -124,8 +128,15 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< std::dynamic_pointer_cast(style)->materialStyles[0]->materialStroke )->materialMap[1.0].color;*/ } - auto [img, mov] = renderer->drawElement(painterPath, *style, 1.0); + QVector2D scale(transform.m11(), transform.m22()); + scale /= transform.m33(); + double maxScale = std::max(scale.x(), scale.y()); + double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio(); + auto [img, mov] = renderer->drawElement(painterPath, *style, pixelRatio); + painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio)); + //img = img.scaled(img.width() / pixelRatio, img.height() / pixelRatio, Qt::KeepAspectRatio, Qt::SmoothTransformation); painter->drawImage(mov, img); + } painter->restore(); diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index ce54ad7..6e63e92 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -33,7 +33,7 @@ public: class SimpleElement : public GraphicElement { -private: +public: QJsonObject jsonSource; // TODO: 改为ComposedPainterPath QPainterPath painterPath; diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index d5f28e7..8b07e72 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -26,6 +26,7 @@ FolderLayerWrapper*LayerWrapper::getParent() const PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer) { this->refresh(selectedLayer); + qDebug() << cache.painterPath; if (selectedLayer == this) { this->cache.highLight(); @@ -130,7 +131,9 @@ void LeafLayerWrapper::refresh(LayerWrapper* layer) cache.clear(); if (wrappedElement != nullptr) { + qDebug() << cache.painterPath; cache.addPath(wrappedElement->getPaintObject(&(this->styles))); + qDebug() << cache.painterPath; } LayerWrapper::refresh(); } diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp index 89f4bbc..c770411 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp @@ -66,6 +66,7 @@ void PixelPath::clear() { pixmap.fill(Qt::transparent); boundingRect = QRectF(0, 0, 0, 0); + painterPath.clear(); } PixelPath PixelPath::trans(QTransform& mat)const @@ -76,6 +77,7 @@ PixelPath PixelPath::trans(QTransform& mat)const painter.setRenderHint(QPainter::HighQualityAntialiasing); painter.setTransform(mat); painter.drawPixmap(0, 0, pixmap); + result.addPath(this->painterPath); result.boundingRect = mat.mapRect(boundingRect); return result; } diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.h b/ArchitectureColoredPainting/src/Editor/PixelPath.h index a764ce8..ced76ff 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.h +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.h @@ -7,7 +7,7 @@ class PixelPath { -private: +public: QRectF boundingRect; QPixmap pixmap; QPainterPath painterPath; diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index 07e0224..b863fcd 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -27,8 +27,15 @@ Painting PaintingUtil::transfromToPainting(QString jsonFilePath) { QTransform transform; glm::bvec2 flip(0, 0); QJsonObject jsonObj = readJsonFile(jsonFilePath); + qDebug() << jsonObj; ElementManager *elementManager = new ElementManager(jsonObj, Renderer::ElementRenderer::instance()); LayerManager* layerManager = new LayerManager(jsonObj, elementManager); + //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; + + traverseLayTree(layerManager->getRoot(), transform, flip, painting); return painting; } @@ -43,6 +50,7 @@ void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, transform = nowLayer->property.transform * transform; if (leafLayer != nullptr) { + qDebug() << leafLayer<<"------" << painterPath; Element element; ElementTransform elementTrans; element.ratio = bound.width() / bound.height(); @@ -52,10 +60,10 @@ void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, trans.scale(1 / bound.width(), 1 / bound.height()); trans.translate(-bound.center().x(), -bound.center().y()); - element.contour.reset(new vector >(PainterPathUtil::transformToLines(trans.map(painterPath)))); + element.contour = std::make_shared >>(PainterPathUtil::transformToLines(trans.map(painterPath))); QSize screenSize = pixelPath.getPixmap().size(); - //element.style.reset(new Renderer::ElementStyleStrokeDemo(0.06)); - + element.style = std::make_shared(0.06); + painterPath = transform.map(painterPath); bound = painterPath.boundingRect(); diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 7496155..917ecc9 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -229,7 +229,7 @@ GLuint Renderer::Model::loadPainting(std::string path) if (iter != paintingLoaded.end()) return iter->second; - Painting painting = PaintingUtil::transfromToPainting("D:\\BigC\\Project\\ArchitectureColoredPainting\\data.json"); + Painting painting = PaintingUtil::transfromToPainting("../data.json"); painting.generateBuffers(glFunc); diff --git a/svg/4_L0.svg b/svg/4_L0.svg new file mode 100644 index 0000000..58facaf --- /dev/null +++ b/svg/4_L0.svg @@ -0,0 +1,5 @@ + + 4_L0 + + + diff --git a/svg/ex.json b/svg/ex.json new file mode 100644 index 0000000..9b3f948 --- /dev/null +++ b/svg/ex.json @@ -0,0 +1,31 @@ +{ + "height": 1080, + "width": 1080, + "elements": [ + { + "name": "ababa", + "type": "svg-file", + "data": { + "include": "./svg/0.svg" + } + } + ], + "root-layer": { + "name": "root", + "transform": { + "offset": { + "x": 0, + "y": 0 + }, + "scale": { + "x": 1.0, + "y": 1.0 + }, + "rotation": 0.0 + }, + "effects": [], + "is-folder": true, + "referenced-by": null, + "children":[] + } +} \ No newline at end of file From fa91d80b709d2ea1b4c908727bcf2f43a84334a8 Mon Sep 17 00:00:00 2001 From: karlis <2995621482@qq.com> Date: Wed, 15 Mar 2023 16:36:46 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E5=AE=8C=E5=96=84Element=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Editor/GraphicElement.cpp | 20 +++++++++++++++++-- .../src/Editor/GraphicElement.h | 5 ++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 6be59ff..02af86d 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -23,6 +23,7 @@ void SimpleElement::loadSvgFile(const QString& filePath) SimpleElement::SimpleElement(QJsonObject jsonSource) : jsonSource(jsonSource) { painterPath.clear(); + filePath = jsonSource["data"].toObject()["include"].toString(); //loadSvgFile("D:\\Projects\\BigC\\svg\\3.svg"); loadSvgFile("../"/*TODO: 改成json文件所在文件夹路径*/ + jsonSource.value("data").toObject().value("include").toString()); } @@ -95,10 +96,25 @@ PixelPath GroupElement::getPaintObject(std::vector>* // } //} //TODO : 添加细节 -QJsonObject GraphicElement::toJson() const +QJsonObject SimpleElement::toJson() const { QJsonObject result; - result.insert("name", name); + QJsonObject data; + data["include"] = filePath; + result["type"] = "svg-file"; + result["data"] = data; + result["name"] = name; + return result; +} + +QJsonObject GroupElement::toJson() const +{ + QJsonObject result; + QJsonObject data; + data["reference-layer"] = "0.0"; + result["type"] = "group"; + result["data"] = data; + result["name"] = name; return result; } diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index 6e63e92..f375c63 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -25,7 +25,7 @@ public: QString name = ""; int index; // TODO: 改为BitmapPath - virtual QJsonObject toJson() const; + virtual QJsonObject toJson() const = 0; virtual PixelPath getPaintObject() const = 0; virtual PixelPath getPaintObject(std::vector>*) const = 0; virtual void paint(QPainter* painter, QTransform transform, const std::vector> &styles) = 0; @@ -37,9 +37,11 @@ public: QJsonObject jsonSource; // TODO: 改为ComposedPainterPath QPainterPath painterPath; + QString filePath; void loadSvgFile(const QString& filePath); public: + QJsonObject toJson() const override; SimpleElement(QJsonObject jsonSource); SimpleElement(QString filePath); ~SimpleElement() = default; @@ -54,6 +56,7 @@ public: FolderLayerWrapper* sourceLayer; public: + QJsonObject toJson() const override; GroupElement() = default; GroupElement(FolderLayerWrapper* mSourceLayer); ~GroupElement() = default; From 5d88ddf0ca42cf5af8324c1b6f478fb99aad549f Mon Sep 17 00:00:00 2001 From: "yang.yongquan" <3395816735@qq.com> Date: Wed, 15 Mar 2023 17:37:12 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E7=9A=84=E6=A7=BD=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/Editor/ElementPoolWidget.cpp | 10 +++ .../src/Editor/ElementPoolWidget.h | 1 + .../src/Editor/util/PaintingUtil.cpp | 81 +++++++++++++------ .../src/Editor/util/PaintingUtil.h | 2 +- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp index 64fadfd..1c5dc3c 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp @@ -78,4 +78,14 @@ void ElementPoolWidget::setElementManager(ElementManager* element) void ElementPoolWidget::refresh() { this->setElementList(this->elementManager->elements); // update(); +} + +void ElementPoolWidget::refreshPicture(GraphicElement* element) { + for (int i = 0; i < elements.size(); i++) { + if (element == elements[i]) { + pictureList->item(i)->setIcon(element->getPaintObject().getDetail().scaled(QSize(iconWidth - 25, iconHeight - 25))); + // update(); + return; + } + } } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h index 2a880a7..f6c253e 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h +++ b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h @@ -28,5 +28,6 @@ signals: public slots: int pictureItemClicked(QListWidgetItem* item); void refresh(); + void refreshPicture(GraphicElement* element); }; diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index b863fcd..7c66c24 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -2,16 +2,26 @@ #include #include #include "PainterPathUtil.h" +#include using Renderer::Painting; using Renderer::Element; using Renderer::ElementTransform; using glm::bvec2; using std::max; +using std::shared_ptr; +using std::make_shared; using std::min; +using std::queue; const double PaintingUtil::pi = acos(-1); +struct LayerNode { + LayerWrapper* nowLayer; + QTransform transfrom; + bvec2 flip; +}; + QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) { QFile jsonFile(jsonFilePath); jsonFile.open(QFile::ReadOnly); @@ -28,29 +38,47 @@ Painting PaintingUtil::transfromToPainting(QString jsonFilePath) { glm::bvec2 flip(0, 0); QJsonObject jsonObj = readJsonFile(jsonFilePath); qDebug() << jsonObj; - ElementManager *elementManager = new ElementManager(jsonObj, Renderer::ElementRenderer::instance()); - LayerManager* layerManager = new LayerManager(jsonObj, elementManager); + 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; - - - traverseLayTree(layerManager->getRoot(), transform, flip, painting); + //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, 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; } -void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, bvec2 flip, Painting& painting) { +FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, bvec2& flip, Painting& painting) { LeafLayerWrapper* leafLayer = dynamic_cast(nowLayer); - PixelPath pixelPath = nowLayer->getCache(); - QPainterPath painterPath = pixelPath.getPainterPath(); - QRectF bound = painterPath.boundingRect(); flip ^= bvec2(nowLayer->property.flipHorizontally, nowLayer->property.flipVertically); transform = nowLayer->property.transform * transform; if (leafLayer != nullptr) { - qDebug() << leafLayer<<"------" << painterPath; + + GroupElement* wrapperElement = dynamic_cast(leafLayer->wrappedElement); + if (wrapperElement != nullptr) + 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(); @@ -60,36 +88,40 @@ void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, 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 = pixelPath.getPixmap().size(); element.style = std::make_shared(0.06); painterPath = transform.map(painterPath); + qDebug() << painterPath; bound = painterPath.boundingRect(); + qDebug() << bound; elementTrans.center = glm::vec2( - (bound.center().x() - screenSize.width()) / screenSize.width(), - (bound.center().y() - screenSize.height()) / screenSize.height() + (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() / screenSize.width(), + bound.height() / screenSize.height() + ); elementTrans.flip = glm::bvec2( nowLayer->property.flipHorizontally, nowLayer->property.flipVertically ); + qDebug() << elementTrans.scale.x << elementTrans.scale.y; painting.addElement(element, elementTrans); - return; + return nullptr; } FolderLayerWrapper* folderLayer = dynamic_cast(nowLayer); - if (folderLayer != nullptr) { - for (auto sonLayer : folderLayer->children) { - traverseLayTree(sonLayer.get(), transform, flip, painting); - } - } - return; + return folderLayer; } void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& scale) { - qDebug() << trans; + //qDebug() << trans; trans.setMatrix( trans.m11(), trans.m12(), trans.m13(), trans.m21(), trans.m22(), trans.m23(), @@ -134,7 +166,8 @@ void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& angle = 360 - angle; } qDebug() << angle; - R = R.inverted() * trans; - scale = glm::vec2(R.m11(), R.m22()); + //R = R.inverted() * trans; + //scale = glm::vec2(R.m11(), R.m22()); + //qDebug() << scale.x << scale.y; return; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h index 35ebe03..77e6ea2 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h @@ -7,7 +7,7 @@ class PaintingUtil private: static const double pi; static QJsonObject readJsonFile(QString jsonFilePath); - static void traverseLayTree(LayerWrapper* nowLayer, QTransform transform, glm::bvec2 flip, Renderer::Painting& painting); + static FolderLayerWrapper* handleLayerWrapper(LayerWrapper* nowLayer, QTransform& transform, glm::bvec2& flip, Renderer::Painting& painting); public: static Renderer::Painting transfromToPainting(QString jsonFilePath); static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale); From 3abc0d9bcdf5858c5c12f698022e4b347642b823 Mon Sep 17 00:00:00 2001 From: wuyize Date: Wed, 15 Mar 2023 19:24:33 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=8C=E6=88=90json?= =?UTF-8?q?=E5=88=B0Painting=E7=9A=84=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/Shaders/painting.comp | 6 +++--- .../res/Shaders/painting.vert | 1 + .../src/Editor/util/PaintingUtil.cpp | 13 +++++++------ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index 50a32b8..c0af01c 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -1352,8 +1352,8 @@ void main() vec3 debugBVH = vec3(0); // bool debugHit = false; - vec4 color = vec4(0.76, 0.33, 0.15, -1); - // vec4 color = vec4(1,1,1, -1); + //vec4 color = vec4(0.76, 0.33, 0.15, -1); + vec4 color = vec4(1,1,1, -1); vec2 metallicRoughness = vec2(0, 0.8); stack.top = 0; uint index = 0, visitTime = 0; @@ -1423,7 +1423,7 @@ void main() imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1)); imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1)); - //return; + return; if (/*color.a!=-1&&*/ debugBVH == vec3(0)) { // imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1)); diff --git a/ArchitectureColoredPainting/res/Shaders/painting.vert b/ArchitectureColoredPainting/res/Shaders/painting.vert index f294dc6..9c5f22f 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.vert +++ b/ArchitectureColoredPainting/res/Shaders/painting.vert @@ -14,6 +14,7 @@ uniform mat4 projection; void main() { TexCoords = aTexCoords; + TexCoords.y = -TexCoords.y; WorldPos = vec3(model * vec4(aPos, 1.0)); Normal = mat3(model) * aNormal; diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index 7c66c24..8c4ec74 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -34,7 +34,6 @@ QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) { Painting PaintingUtil::transfromToPainting(QString jsonFilePath) { Painting painting; - QTransform transform; glm::bvec2 flip(0, 0); QJsonObject jsonObj = readJsonFile(jsonFilePath); qDebug() << jsonObj; @@ -47,7 +46,7 @@ Painting PaintingUtil::transfromToPainting(QString jsonFilePath) { queue layerQueue; LayerWrapper* root = layerManager->getRoot(); root->getCache(); - layerQueue.push({ root, transform, flip }); + layerQueue.push({ root, root->property.transform, flip }); while (!layerQueue.empty()) { auto layerNode = layerQueue.front(); layerQueue.pop(); @@ -71,8 +70,10 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr if (leafLayer != nullptr) { GroupElement* wrapperElement = dynamic_cast(leafLayer->wrappedElement); - if (wrapperElement != nullptr) + if (wrapperElement != nullptr) { + transform = wrapperElement->sourceLayer->property.transform * transform; return wrapperElement->sourceLayer; + } PixelPath pixelPath = nowLayer->getCache(); QPainterPath painterPath = pixelPath.getPainterPath(); @@ -90,7 +91,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr qDebug() << trans.map(painterPath); element.contour = std::make_shared >>(PainterPathUtil::transformToLines(trans.map(painterPath))); - QSize screenSize = pixelPath.getPixmap().size(); + QSize screenSize = QSize(1024, 1024); element.style = std::make_shared(0.06); @@ -105,8 +106,8 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr qDebug() << elementTrans.center.x << elementTrans.center.y; decomposeTransform(transform, elementTrans.rotation, elementTrans.scale); elementTrans.scale = glm::vec2( - bound.width() / screenSize.width(), - bound.height() / screenSize.height() + bound.width() * 2 / screenSize.width(), + bound.height() * 2 / screenSize.height() ); elementTrans.flip = glm::bvec2( nowLayer->property.flipHorizontally, From c234c0e9b321b3598358ef53474c7ebe7e3802b9 Mon Sep 17 00:00:00 2001 From: karlis <2995621482@qq.com> Date: Wed, 15 Mar 2023 20:10:14 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=AE=9E=E7=8E=B0element=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=BB=9A=E5=8A=A8=E6=9D=A1=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A9=BA=E7=99=BD=E6=89=93=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../EditorWidgetItem.ui | 98 +++++++++++++++---- .../src/Editor/EditorWidget.cpp | 3 +- .../src/Editor/EditorWidgetItem.cpp | 3 +- .../src/Editor/ElementManager.cpp | 1 + .../src/Editor/ElementPoolWidget.cpp | 53 +++++++++- .../src/Editor/ElementPoolWidget.h | 2 + .../src/Editor/GraphicElement.cpp | 3 +- .../src/Editor/LayerWrapper.cpp | 3 - .../src/Editor/PixelPath.h | 4 +- .../src/Editor/PreviewWindow.cpp | 3 +- .../src/Editor/RightBar/LayerTreeWidget.cpp | 14 +-- data.json | 9 +- 12 files changed, 160 insertions(+), 36 deletions(-) diff --git a/ArchitectureColoredPainting/EditorWidgetItem.ui b/ArchitectureColoredPainting/EditorWidgetItem.ui index aea28b0..73f9357 100644 --- a/ArchitectureColoredPainting/EditorWidgetItem.ui +++ b/ArchitectureColoredPainting/EditorWidgetItem.ui @@ -37,38 +37,87 @@ - - - 0 - - - 0 - - - 0 - - - 0 - + - + + + + 0 + 0 + + - 1080 - 1080 + 0 + 0 - 1080 - 1080 + 10801080 + 10801080 + + true + + + + + 0 + 0 + 1024 + 1024 + + + + + 0 + 0 + + + + + 1024 + 1024 + + + + + 10241024 + 10241024 + + + + + + + + 0 + 0 + + + + + 1024 + 1024 + + + + + 1024 + 1024 + + + + + + @@ -138,6 +187,19 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp index 2c990de..b51987b 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidget.cpp @@ -24,7 +24,8 @@ EditorWidget::EditorWidget(QWidget* parent) : QWidget(parent) }); connect(this->openButton, &QPushButton::clicked, this, [this]() { QString fileName = QFileDialog::getOpenFileName(this->saveAsButton, QString::fromLocal8Bit("打开"), "", QString::fromLocal8Bit("JSON文件(*.json)")); - this->tabWidget->addTab(new EditorWidgetItem(fileName, this), fileName); + if(!fileName.isEmpty()) + this->tabWidget->addTab(new EditorWidgetItem(fileName, this), fileName); }); connect(this->closeButton, &QPushButton::clicked, this, [this]() { this->tabWidget->removeTab(this->tabWidget->currentIndex()); diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp index ab1f096..9525287 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetItem.cpp @@ -12,6 +12,7 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p this->filePath = filePath; layerInfoDisplayWidget = dynamic_cast(tabWidget->widget(0)); elementInfoDisplayWidget = dynamic_cast(tabWidget->widget(1)); + elementInfoDisplayWidget->enableEdit(); qDebug() << layerInfoDisplayWidget; qDebug() << elementInfoDisplayWidget; connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh); @@ -37,7 +38,7 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p qDebug() << jError.errorString(); // end test QJsonObject source = jsonDoc.object(); - elementManager = new ElementManager(source,previewWindow->getRenderer()); + elementManager = new ElementManager(source,Renderer::ElementRenderer::instance()); layerManager = new LayerManager(source, elementManager); elementInfoDisplayWidget->setElementManager(elementManager); treeWidget->elementManager = elementManager; diff --git a/ArchitectureColoredPainting/src/Editor/ElementManager.cpp b/ArchitectureColoredPainting/src/Editor/ElementManager.cpp index daed263..7b5b80c 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementManager.cpp +++ b/ArchitectureColoredPainting/src/Editor/ElementManager.cpp @@ -97,6 +97,7 @@ void ElementManager::createSimpleElement(QString name, QString filePath) { data.insert("include", filePath); json.insert("data", data); auto element = new SimpleElement(json); + qDebug() << element->painterPath; element->name = name; addElement(element); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp index 1c5dc3c..0ec51b0 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.cpp @@ -1,11 +1,16 @@ #include "ElementPoolWidget.h" +#include +#include +#include +#include ElementPoolWidget::ElementPoolWidget(QWidget* parent) : QWidget(parent) { elementManager = nullptr; iconWidth = 120, iconHeight = 90; - pictureList = new QListWidget(); + pictureList = new QListWidget(this); + pictureList->setContextMenuPolicy(Qt::CustomContextMenu); pictureList->setIconSize(QSize(iconWidth, iconHeight)); pictureList->setWindowFlags(Qt::FramelessWindowHint); pictureList->setResizeMode(QListWidget::Adjust); @@ -88,4 +93,50 @@ void ElementPoolWidget::refreshPicture(GraphicElement* element) { return; } } +} + +void ElementPoolWidget::enableEdit() +{ + connect(this->pictureList, &QListWidget::customContextMenuRequested, this, &ElementPoolWidget::popMenu); +} + +void ElementPoolWidget::popMenu(const QPoint& pos) +{ + QListWidgetItem* item = pictureList->itemAt(pos); + int currentIndex = -1; + if (item != nullptr) + { + currentIndex = pictureList->row(item); + } + QMenu* menu = new QMenu(this); + if (currentIndex >= 0 && currentIndex < elementManager->elements.size()) + { + auto currentElement = this->elementManager->elements[currentIndex]; + menu->addAction(QString::fromLocal8Bit("重命名"), this, [this, currentElement]() { + bool bOk = false; + QString sName = + QInputDialog::getText(this, QString::fromLocal8Bit("重命名"), QString::fromLocal8Bit("新名称:"), QLineEdit::Normal, currentElement->name, &bOk); + if (bOk && !sName.isEmpty()) + { + currentElement->name = sName; + refresh(); + } + }); + menu->addAction(QString::fromLocal8Bit("删除"), this, [this, currentElement]() { + this->elementManager->removeElement(currentElement); + refresh(); + }); + } + else + { + menu->addAction(QString::fromLocal8Bit("添加元素(从svg导入)"), this, [this]() { + QString filePath = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("打开文件"), "", "SVG Files (*.svg)"); + QFileInfo fileInfo(filePath); + QString fileName = fileInfo.fileName(); + qDebug() << fileName << " " << filePath; + this->elementManager->createSimpleElement(fileName, filePath); + refresh(); + }); + } + menu->popup(mapToGlobal(pos)); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h index f6c253e..d4c9cef 100644 --- a/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h +++ b/ArchitectureColoredPainting/src/Editor/ElementPoolWidget.h @@ -21,6 +21,7 @@ public: void setElementList(std::vector elementList); void setElementManager(ElementManager* element); ~ElementPoolWidget(); + void enableEdit(); signals: void elementSelected(GraphicElement* element); @@ -29,5 +30,6 @@ public slots: int pictureItemClicked(QListWidgetItem* item); void refresh(); void refreshPicture(GraphicElement* element); + void popMenu(const QPoint& pos); }; diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 02af86d..36f81dc 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -25,7 +25,8 @@ SimpleElement::SimpleElement(QJsonObject jsonSource) : jsonSource(jsonSource) painterPath.clear(); filePath = jsonSource["data"].toObject()["include"].toString(); //loadSvgFile("D:\\Projects\\BigC\\svg\\3.svg"); - loadSvgFile("../"/*TODO: 改成json文件所在文件夹路径*/ + jsonSource.value("data").toObject().value("include").toString()); + QFileInfo info(filePath); + loadSvgFile(filePath); } GroupElement::GroupElement(FolderLayerWrapper* sourceLayer) diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index 8b07e72..d5f28e7 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -26,7 +26,6 @@ FolderLayerWrapper*LayerWrapper::getParent() const PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer) { this->refresh(selectedLayer); - qDebug() << cache.painterPath; if (selectedLayer == this) { this->cache.highLight(); @@ -131,9 +130,7 @@ void LeafLayerWrapper::refresh(LayerWrapper* layer) cache.clear(); if (wrappedElement != nullptr) { - qDebug() << cache.painterPath; cache.addPath(wrappedElement->getPaintObject(&(this->styles))); - qDebug() << cache.painterPath; } LayerWrapper::refresh(); } diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.h b/ArchitectureColoredPainting/src/Editor/PixelPath.h index ced76ff..5ab8614 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.h +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.h @@ -13,8 +13,8 @@ public: QPainterPath painterPath; int w,h; public: - PixelPath(int w=1080, int h= 1080); - PixelPath(QPainterPath painterPath,int w = 1080, int h = 1080); + PixelPath(int w=1024, int h= 1024); + PixelPath(QPainterPath painterPath,int w = 1024, int h = 1024); ~PixelPath() = default; QRectF getBoundingRect() const; QPixmap getPixmap() const; diff --git a/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp b/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp index 485977d..9fb8060 100644 --- a/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp +++ b/ArchitectureColoredPainting/src/Editor/PreviewWindow.cpp @@ -2,7 +2,8 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent) { - this->setFixedSize(QSize(1080, 1080)); + //this->setFixedSize(QSize(108, 108)); + this->setStyleSheet("border: 1px solid black"); this->renderer = Renderer::ElementRenderer::instance(); QSurfaceFormat surfaceFormat; surfaceFormat.setSamples(16); diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp index 1e84c88..a27da25 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp @@ -68,13 +68,6 @@ void LayerTreeWidget::popMenu(const QPoint &pos) }); dialog->exec(); }); - 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(); - }); } if (layer != root) { menu.addAction(QString::fromLocal8Bit("删除"), this, [this]() { @@ -85,6 +78,13 @@ void LayerTreeWidget::popMenu(const QPoint &pos) emit requireRefreshPreview(); }); menu.addAction(QString::fromLocal8Bit("重命名"), this, &LayerTreeWidget::onRenameEvent); + 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(); + }); } if (typeid(*layer) == typeid(FolderLayerWrapper) && ((FolderLayerWrapper*)layer)->getReferencedBy() == -1) { menu.addAction(QString::fromLocal8Bit("创建组合元素"), this, [this]() { diff --git a/data.json b/data.json index 150cb6c..4f381cb 100644 --- a/data.json +++ b/data.json @@ -6,7 +6,7 @@ "name": "ababa", "type": "svg-file", "data": { - "include": "./svg/2.svg" + "include": "../svg/2.svg" } }, { @@ -15,6 +15,13 @@ "data": { "reference-layer": "0.0" } + }, + { + "name": "ababa2", + "type": "svg-file", + "data": { + "include": "../svg/0.svg" + } } ], "root-layer": { From 70d5973a90cb50617ffa668bbde367f124130dde Mon Sep 17 00:00:00 2001 From: karlis <2995621482@qq.com> Date: Wed, 15 Mar 2023 21:04:21 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86yyq=E9=BB=84?= =?UTF-8?q?=E8=89=B2=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchitectureColoredPainting/src/Editor/PixelPath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp index c770411..3087f39 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp @@ -77,7 +77,7 @@ PixelPath PixelPath::trans(QTransform& mat)const painter.setRenderHint(QPainter::HighQualityAntialiasing); painter.setTransform(mat); painter.drawPixmap(0, 0, pixmap); - result.addPath(this->painterPath); + result.painterPath.addPath(this->painterPath); result.boundingRect = mat.mapRect(boundingRect); return result; } From 89034197990cc185ea400b48ce5175d3289bc8b1 Mon Sep 17 00:00:00 2001 From: karlis <2995621482@qq.com> Date: Wed, 15 Mar 2023 21:04:21 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86zt=E9=BB=84?= =?UTF-8?q?=E8=89=B2=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchitectureColoredPainting/src/Editor/PixelPath.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp index c770411..3087f39 100644 --- a/ArchitectureColoredPainting/src/Editor/PixelPath.cpp +++ b/ArchitectureColoredPainting/src/Editor/PixelPath.cpp @@ -77,7 +77,7 @@ PixelPath PixelPath::trans(QTransform& mat)const painter.setRenderHint(QPainter::HighQualityAntialiasing); painter.setTransform(mat); painter.drawPixmap(0, 0, pixmap); - result.addPath(this->painterPath); + result.painterPath.addPath(this->painterPath); result.boundingRect = mat.mapRect(boundingRect); return result; } From 78c24ad373f997f1138c2e2645c253d89aaeb4ae Mon Sep 17 00:00:00 2001 From: wuyize Date: Wed, 15 Mar 2023 22:43:51 +0800 Subject: [PATCH 9/9] =?UTF-8?q?FIX:=20painting=E6=B8=B2=E6=9F=93bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/Shaders/painting.comp | 6 +- .../res/Shaders/painting.frag | 6 -- .../res/Shaders/painting.vert | 1 - .../src/Renderer/Model.cpp | 100 +++++++++++++++++- 4 files changed, 101 insertions(+), 12 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index c0af01c..3e8ede4 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -1149,7 +1149,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point p[2] *= ratio; p[3] *= ratio; - vec2 tangentBeginNext; + vec2 tangentBeginNext = vec2(0); if (contourIterator + 1 < contourIndex + 1 + lineCount) { uint lineIndex = elementIndexs[contourIterator + 1]; @@ -1217,10 +1217,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point bool hit = d < minDistance; if (onBegin) hit = - hit && shouldFillBeginCap(localUV, percent[0] < 1e-5, endType, p[0], tangentBegin, p3Last - p2Last); + hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0], tangentBegin, p3Last - p2Last); if (onEnd) hit = hit && - shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p[3], tangentEnd, tangentBeginNext); + shouldFillEndCap(localUV, tangentBeginNext==vec2(0), endType, p[3], tangentEnd, tangentBeginNext); if (hit) { diff --git a/ArchitectureColoredPainting/res/Shaders/painting.frag b/ArchitectureColoredPainting/res/Shaders/painting.frag index 5fed343..4f69ed9 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.frag +++ b/ArchitectureColoredPainting/res/Shaders/painting.frag @@ -36,11 +36,6 @@ void main() lod++; gMetallicRoughness = mt.rg; -// int pageSize = textureSize(texture_basecolor, levels-1).x; - -// uint pageId = 0; -// for(uint i = 0; i < lodExpect; i++) -// pageId += 1<<(2*(levels-1-i)); uint w = 1<<(levels-1-lodExpect); ivec2 page = ivec2(TexCoords * vec2(w)); page = clamp(page, ivec2(0), ivec2(w-1)); @@ -49,7 +44,6 @@ void main() gPaintingIndex = uvec2(0); else gPaintingIndex = uvec2((paintingId<<4)+lodExpect, (page.y<<8)+page.x); - gPaintingTexCoord = vec2(1., 1.) - TexCoords * 2; return; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/res/Shaders/painting.vert b/ArchitectureColoredPainting/res/Shaders/painting.vert index 9c5f22f..f294dc6 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.vert +++ b/ArchitectureColoredPainting/res/Shaders/painting.vert @@ -14,7 +14,6 @@ uniform mat4 projection; void main() { TexCoords = aTexCoords; - TexCoords.y = -TexCoords.y; WorldPos = vec3(model * vec4(aPos, 1.0)); Normal = mat3(model) * aNormal; diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index 917ecc9..4f62c3b 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -52,7 +52,7 @@ void Renderer::Model::loadModel(QString path) directory = modelFile.dir(); Assimp::Importer importer; - const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate /*| aiProcess_FlipUVs*/); + const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl; @@ -229,8 +229,104 @@ GLuint Renderer::Model::loadPainting(std::string path) if (iter != paintingLoaded.end()) return iter->second; - Painting painting = PaintingUtil::transfromToPainting("../data.json"); + Painting painting; + if (auto file = QFileInfo(QString(path.c_str())); file.isFile()) + painting = PaintingUtil::transfromToPainting(file.path()); + else + { + qDebug() << path.c_str() << "Not Found, Using Default Painting"; + vector, float>> contours; + QPainterPath painterPaths[3]; + QQuickSvgParser::parsePathDataFast("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", + painterPaths[0]); + if (!SvgFileLoader().loadSvgFile("../svg/2.svg", painterPaths[1])) + qCritical() << "load error"; + /*QQuickSvgParser::parsePathDataFast("M292.82,107.78s0,0,0,0,0,3.59,0,7.62c0,3.85,0,5.78.06,6.43a19.94,19.94,0,0,0,2.87,7.58,15.85,15.85,0,0,0,6.61,6.23A14.75,14.75,0,0,0,310,137a11.69,11.69,0,0,0,7.59-2.92,11,11,0,0,0,3.2-6.84c.15-1.27.58-4.84-1.79-7.64a8.54,8.54,0,0,0-3.56-2.44c-1.32-.52-3.32-1.31-5.06-.33a5.41,5.41,0,0,0-2.14,3,3.48,3.48,0,0,0-.16,2.71c.78,1.86,3.36,2.14,3.47,2.15", + painterPaths[1]);*/ + QQuickSvgParser::parsePathDataFast("M377,459.61a11.26,11.26,0,0,1,11.27-11.27H696.12a11.27,11.27,0,0,0,11-8.62A359.84,359.84,0,0,0,708,280.56a11.26,11.26,0,0,0-11-8.73H388.27A11.26,11.26,0,0,1,377,260.57h0a11.26,11.26,0,0,1,11.27-11.26H683.71A11.32,11.32,0,0,0,694.28,234C649.8,113.69,542.57,23.85,412.3,4.12a11.22,11.22,0,0,0-12.76,11.17v158.9a11.26,11.26,0,0,0,11.26,11.27H583.12a11.32,11.32,0,0,0,9.26-17.75c-31.67-46.59-78.51-75.2-109.11-90.07a11.25,11.25,0,0,0-16.13,10.17V115.2a11.24,11.24,0,0,0,6.22,10.07l7.51,3.76a11.28,11.28,0,0,1,5,15.12h0a11.27,11.27,0,0,1-15.11,5l-20-10a11.27,11.27,0,0,1-6.22-10.07V54a11.27,11.27,0,0,1,14.62-10.75c5.11,1.59,125.66,40.35,172.24,149A11.27,11.27,0,0,1,621.11,208H388.27A11.26,11.26,0,0,1,377,196.73V11.36A11.32,11.32,0,0,0,365.89.08C363.34,0,360.79,0,358.22,0s-5.11,0-7.66.08a11.32,11.32,0,0,0-11.11,11.28V196.74A11.26,11.26,0,0,1,328.18,208H95.35A11.27,11.27,0,0,1,85,192.3c46.57-108.67,167.12-147.42,172.23-149A11.26,11.26,0,0,1,271.86,54v75.11a11.25,11.25,0,0,1-6.23,10.07l-20,10a11.27,11.27,0,0,1-15.11-5h0a11.26,11.26,0,0,1,5-15.11l7.52-3.76a11.27,11.27,0,0,0,6.22-10.07V87.82a11.25,11.25,0,0,0-16.14-10.16c-30.6,14.87-77.45,43.48-109.1,90.07a11.3,11.3,0,0,0,9.25,17.74H305.66a11.26,11.26,0,0,0,11.27-11.26V15.31A11.22,11.22,0,0,0,304.17,4.14C173.88,23.86,66.66,113.71,22.17,234a11.32,11.32,0,0,0,10.56,15.29H328.18a11.26,11.26,0,0,1,11.27,11.26v0a11.26,11.26,0,0,1-11.27,11.26H19.52a11.26,11.26,0,0,0-11,8.72,359.84,359.84,0,0,0,.83,159.16,11.26,11.26,0,0,0,11,8.61H328.18a11.26,11.26,0,0,1,11.27,11.27h0a11.26,11.26,0,0,1-11.27,11.26h-294a11.32,11.32,0,0,0-10.53,15.4C69,604.65,175.3,692.78,304.16,712.3a11.21,11.21,0,0,0,12.76-11.16V542.22A11.26,11.26,0,0,0,305.66,531h-166c-9.53,0-14.89,11.22-8.69,18.47,34.09,39.77,74.45,65.66,101.77,80.18a11.25,11.25,0,0,0,16.53-10V591a11.26,11.26,0,0,1,11.26-11.26h0A11.26,11.26,0,0,1,271.85,591v63.85A11.27,11.27,0,0,1,256.8,665.5c-4.45-1.59-109.58-40-171-139.9a11.27,11.27,0,0,1,9.59-17.17H328.18a11.26,11.26,0,0,1,11.27,11.26V705.08a11.32,11.32,0,0,0,11.11,11.28q3.82.07,7.66.08c2.57,0,5.12,0,7.67-.08A11.32,11.32,0,0,0,377,705.08V519.69a11.25,11.25,0,0,1,11.27-11.26H621.1a11.26,11.26,0,0,1,9.59,17.16c-61.46,99.87-166.59,138.3-171,139.9a11.27,11.27,0,0,1-15-10.61V591a11.26,11.26,0,0,1,11.26-11.26h0A11.26,11.26,0,0,1,467.14,591v28.6a11.25,11.25,0,0,0,16.53,10c27.33-14.53,67.68-40.42,101.77-80.19,6.2-7.23.85-18.46-8.69-18.46h-166a11.26,11.26,0,0,0-11.26,11.26V701.12a11.21,11.21,0,0,0,12.76,11.17c128.86-19.51,235.14-107.66,280.48-226a11.33,11.33,0,0,0-10.53-15.41h-294A11.25,11.25,0,0,1,377,459.61ZM35.27,399.53V316.9a11.26,11.26,0,0,1,11.27-11.26H669.92a11.25,11.25,0,0,1,11.26,11.26v82.63a11.25,11.25,0,0,1-11.26,11.26H46.54a11.27,11.27,0,0,1-11.27-11.26Z", + painterPaths[2]); + + for (auto& i : painterPaths) + { + auto [contour, ratio] = PainterPathUtil::toNormalizedLines(i); + contours.emplace_back(std::make_shared(contour), ratio); + } + + vector> style = { + std::make_shared(), + std::make_shared(0.02), + std::make_shared(0.2) + }; + + vector> element = { + std::make_shared(Element{ contours[0].first, style[0], contours[0].second}), + std::make_shared(Element{ contours[1].first, style[2], contours[1].second}), + std::make_shared(Element{ contours[2].first, style[0], contours[2].second}), + }; + + if (path == "0.json") + { + painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); + painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); + painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 }); + } + else if (path == "1.json") + { + float widths[] = { 0.43, 0.43 * 0.25 / 0.15, 0.43 * 0.25 / 0.15 }; + QPainterPath painterPaths[6]; + for (int i = 0; i < 6; i++) + if (!SvgFileLoader().loadSvgFile(QString(std::format("../svg/{}.svg", i + 1).c_str()), painterPaths[i])) + qCritical() << "load error"; + + vector, float>> contours; + for (int i = 0; i < 3; i++) + { + auto [contour, ratio] = PainterPathUtil::toNormalizedLines(painterPaths[i], widths[i]); + contours.emplace_back(std::make_shared(contour), ratio); + } + class StyleStrokeRadialGradient : public Renderer::ElementStyle + { + public: + float width; + StrokeType type; + StyleStrokeRadialGradient(float width, StrokeType type) :width(width), type(type) {}; + virtual std::vector toBaseStyles() const override + { + std::map materialMap = { + {0.09, Material{QColor(255,255,255),0,0.8}}, + {0.63, Material{QColor(165,176,207),0,0.8}}, + {1.00, Material{QColor(58,64,151),0,0.8}} + }; + return { BaseStyle(std::make_shared(), + std::make_shared(width, type, StrokeEndType::kFlat, + std::make_shared(materialMap, false))) }; + } + }; + vector> style = { + std::make_shared(widths[0], StrokeType::kLeftSide), + std::make_shared(widths[1], StrokeType::kRightSide), + std::make_shared(widths[2], StrokeType::kLeftSide), + }; + vector> element = { + std::make_shared(Element{ contours[0].first, style[0], contours[0].second}), + std::make_shared(Element{ contours[1].first, style[1], contours[1].second}), + std::make_shared(Element{ contours[2].first, style[2], contours[2].second}), + }; + painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.25), 0, glm::bvec2(false), 0 }); + painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.535,0.33), glm::vec2(0.15), 0, glm::bvec2(false), 0 }); + painting.addElement(*element[2], ElementTransform{ glm::vec2(-0.535,0.23), glm::vec2(0.15), 0, glm::bvec2(false), 0 }); + } + else + { + for (int i = 0; i < 1000; i++) + { + float x = (float)rand() / RAND_MAX * 2 - 1; + float y = (float)rand() / RAND_MAX * 2 - 1; + painting.addElement(*element[i % 3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.025), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 }); + } + } + } painting.generateBuffers(glFunc); auto index = vtManager->createVirtualTexture(painting);