在项目菜单中增加替换材质功能

main v0.2.0
wuyize 2023-08-18 17:53:33 +08:00
parent b465b90195
commit df71b04e4c
13 changed files with 547 additions and 393 deletions

View File

@ -110,6 +110,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Editor\Properties\MaterialReplaceDialog.cpp" />
<ClCompile Include="src\Editor\util\JsonMerger.cpp" /> <ClCompile Include="src\Editor\util\JsonMerger.cpp" />
<ClCompile Include="src\Editor\Properties\ProjectPropertyWidget.cpp" /> <ClCompile Include="src\Editor\Properties\ProjectPropertyWidget.cpp" />
<ClCompile Include="src\Editor\Properties\ProjectPropertyDialog.cpp" /> <ClCompile Include="src\Editor\Properties\ProjectPropertyDialog.cpp" />
@ -222,6 +223,7 @@
<QtMoc Include="src\Editor\Properties\CanvasPropertyWidget.h" /> <QtMoc Include="src\Editor\Properties\CanvasPropertyWidget.h" />
<QtMoc Include="src\Editor\Properties\ProjectPropertyDialog.h" /> <QtMoc Include="src\Editor\Properties\ProjectPropertyDialog.h" />
<QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h" /> <QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h" />
<QtMoc Include="src\Editor\Properties\MaterialReplaceDialog.h" />
<ClInclude Include="src\Editor\util\JsonMerger.h" /> <ClInclude Include="src\Editor\util\JsonMerger.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="src\Editor\Properties\PropertyWidget.h" /> <ClInclude Include="src\Editor\Properties\PropertyWidget.h" />

View File

@ -288,6 +288,9 @@
<ClCompile Include="src\Editor\util\JsonMerger.cpp"> <ClCompile Include="src\Editor\util\JsonMerger.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\Editor\Properties\MaterialReplaceDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="src\Renderer\RendererGLWidget.h"> <QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -359,6 +362,9 @@
<QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h"> <QtMoc Include="src\Editor\Properties\ProjectPropertyWidget.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</QtMoc> </QtMoc>
<QtMoc Include="src\Editor\Properties\MaterialReplaceDialog.h">
<Filter>Header Files</Filter>
</QtMoc>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\data.json" /> <None Include="..\data.json" />

View File

@ -1,6 +1,7 @@
#include "EditorWidget.h" #include "EditorWidget.h"
#include "EditorWidgetItem.h" #include "EditorWidgetItem.h"
#include "Properties/ProjectPropertyDialog.h" #include "Properties/ProjectPropertyDialog.h"
#include "Properties/MaterialReplaceDialog.h"
#include <QInputDialog> #include <QInputDialog>
#include <QMenu> #include <QMenu>
#include <QFileDialog> #include <QFileDialog>
@ -149,8 +150,10 @@ void EditorWidget::initProjectMenu()
projectMenuButton->setDisabled(true); projectMenuButton->setDisabled(true);
} }
auto* actionProjectSettings = new QAction(QStringLiteral("ÏîÄ¿ÉèÖÃ"), projectMenuButton); auto actionProjectSettings = new QAction(QStringLiteral("ÏîÄ¿ÉèÖÃ"), projectMenuButton);
auto actionMaterialReplace = new QAction(QStringLiteral("²ÄÖÊÌæ»»"), projectMenuButton);
projectMenuButton->addMenuAction(actionProjectSettings); projectMenuButton->addMenuAction(actionProjectSettings);
projectMenuButton->addMenuAction(actionMaterialReplace);
connect(actionProjectSettings, &QAction::triggered, [this] connect(actionProjectSettings, &QAction::triggered, [this]
{ {
@ -170,4 +173,10 @@ void EditorWidget::initProjectMenu()
currentEditorWidgetItem, &EditorWidgetItem::handleCanvasMetallicChange); currentEditorWidgetItem, &EditorWidgetItem::handleCanvasMetallicChange);
dialog->exec(); dialog->exec();
}); });
connect(actionMaterialReplace, &QAction::triggered, [this]
{
auto* currentEditorWidgetItem = static_cast<EditorWidgetItem*>(this->tabWidget->currentWidget());
const auto dialog = new MaterialReplaceDialog(currentEditorWidgetItem, this);
dialog->exec();
});
} }

View File

@ -274,6 +274,11 @@ void EditorWidgetItem::handleCanvasMetallicChange(const float& metallic)
previewWindow->canvasMetallic = metallic; previewWindow->canvasMetallic = metallic;
} }
void EditorWidgetItem::handleMaterialReplace(const Renderer::Material& origin, const Renderer::Material& target)
{
}
QSize EditorWidgetItem::getCanvasReferSize() const QSize EditorWidgetItem::getCanvasReferSize() const
{ {
return previewWindow->referSize; return previewWindow->referSize;

View File

@ -50,6 +50,7 @@ class EditorWidgetItem : public QWidget
void handleCanvasSizeChange(const QSize& size); void handleCanvasSizeChange(const QSize& size);
void handleCanvasRoughnessChange(const float& roughness); void handleCanvasRoughnessChange(const float& roughness);
void handleCanvasMetallicChange(const float& metallic); void handleCanvasMetallicChange(const float& metallic);
void handleMaterialReplace(const Renderer::Material& origin, const Renderer::Material& target);
QSize getCanvasReferSize() const; QSize getCanvasReferSize() const;
float getCanvasRoughness() const; float getCanvasRoughness() const;
float getCanvasMetallic() const; float getCanvasMetallic() const;

View File

@ -146,6 +146,13 @@ QJsonArray LayerStyleContainer::toJson() const
return json; return json;
} }
void LayerStyleContainer::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
{
for (auto& style : styles | std::views::values)
style->replaceMaterial(origin, target);
computeNewHash();
}
QStringList LayerStyleContainer::unusedStyleNames() const QStringList LayerStyleContainer::unusedStyleNames() const
{ {
QStringList result; QStringList result;
@ -361,6 +368,19 @@ QJsonObject StrokeElementLayerStyle::toJson() const
return json; return json;
} }
void StrokeElementLayerStyle::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
{
auto styles = { strokePair.first, strokePair.second };
for (auto& style : styles)
{
if (!style) continue;
for (auto& material : std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(style->materialStroke)->materialMap | std::views::values)
if (material == origin)
material = target;
}
}
std::unique_ptr<LayerStyle> StrokeElementLayerStyle::clone() const std::unique_ptr<LayerStyle> StrokeElementLayerStyle::clone() const
{ {
return std::make_unique<StrokeElementLayerStyle>(StrokeElementLayerStyle(*this)); return std::make_unique<StrokeElementLayerStyle>(StrokeElementLayerStyle(*this));
@ -458,6 +478,13 @@ QJsonObject FillElementLayerStyle::toJson() const
return json; return json;
} }
void FillElementLayerStyle::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
{
auto materialFill = std::dynamic_pointer_cast<Renderer::FillPlain>(fillMaterialStyle->materialFill);
if (materialFill->material == origin)
materialFill->material = target;
}
std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const
{ {
return std::make_unique<FillElementLayerStyle>(FillElementLayerStyle(*this)); return std::make_unique<FillElementLayerStyle>(FillElementLayerStyle(*this));

View File

@ -42,6 +42,7 @@ public:
virtual QWidget* getListDisplayWidget() const = 0; virtual QWidget* getListDisplayWidget() const = 0;
virtual QJsonObject toJson() const; virtual QJsonObject toJson() const;
virtual void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) = 0;
virtual std::unique_ptr<LayerStyle> clone() const = 0; virtual std::unique_ptr<LayerStyle> clone() const = 0;
virtual std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const = 0; virtual std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const = 0;
@ -65,6 +66,7 @@ public:
QWidget* getInputWidget() override; QWidget* getInputWidget() override;
QWidget* getListDisplayWidget() const override; QWidget* getListDisplayWidget() const override;
QJsonObject toJson() const override; QJsonObject toJson() const override;
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
std::unique_ptr<LayerStyle> clone() const override; std::unique_ptr<LayerStyle> clone() const override;
std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const override; std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const override;
@ -90,6 +92,7 @@ public:
QWidget* getInputWidget() override; QWidget* getInputWidget() override;
QWidget* getListDisplayWidget() const override; QWidget* getListDisplayWidget() const override;
QJsonObject toJson() const override; QJsonObject toJson() const override;
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
std::unique_ptr<LayerStyle> clone() const override; std::unique_ptr<LayerStyle> clone() const override;
std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const override; std::unique_ptr<LayerStyle> fitForElementType(ElementType::ElementType type) const override;
@ -133,6 +136,7 @@ public:
LayerStyleContainer(ElementType::ElementType elementType); LayerStyleContainer(ElementType::ElementType elementType);
[[nodiscard]] std::vector<Renderer::BaseStyle> toBaseStyles() const override; [[nodiscard]] std::vector<Renderer::BaseStyle> toBaseStyles() const override;
[[nodiscard]] QJsonArray toJson() const; [[nodiscard]] QJsonArray toJson() const;
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target);
[[nodiscard]] bool empty() const; [[nodiscard]] bool empty() const;
[[nodiscard]] bool full() const; [[nodiscard]] bool full() const;

View File

@ -294,6 +294,13 @@ QJsonObject FolderLayerWrapper::toJson() const
return json; return json;
} }
void FolderLayerWrapper::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
{
for (auto& child : children)
if (child != nullptr)
child->replaceMaterial(origin, target);
}
QJsonObject LeafLayerWrapper::toJson() const QJsonObject LeafLayerWrapper::toJson() const
{ {
QJsonObject json = LayerWrapper::toJson(); QJsonObject json = LayerWrapper::toJson();
@ -303,6 +310,11 @@ QJsonObject LeafLayerWrapper::toJson() const
return json; return json;
} }
void LeafLayerWrapper::replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target)
{
styles->replaceMaterial(origin, target);
}
int FolderLayerWrapper::getReferencedBy()const int FolderLayerWrapper::getReferencedBy()const
{ {
if (this->elementManager != nullptr) if (this->elementManager != nullptr)

View File

@ -71,6 +71,7 @@ class LayerWrapper
virtual void del(); virtual void del();
virtual void delSelf(); virtual void delSelf();
virtual QJsonObject toJson() const; virtual QJsonObject toJson() const;
virtual void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) = 0;
~LayerWrapper() = default; ~LayerWrapper() = default;
virtual void collectUpReachable(std::set<LayerWrapper*>& reachable); virtual void collectUpReachable(std::set<LayerWrapper*>& reachable);
virtual void collectDownReachable(std::set<LayerWrapper*>& reachable); virtual void collectDownReachable(std::set<LayerWrapper*>& reachable);
@ -105,6 +106,7 @@ class FolderLayerWrapper : public LayerWrapper
void delSelf() override; void delSelf() override;
QTreeWidgetItem* getQTreeItem() override; QTreeWidgetItem* getQTreeItem() override;
QJsonObject toJson() const override; QJsonObject toJson() const override;
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
int getReferencedBy()const; int getReferencedBy()const;
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL)) override; void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL)) override;
void collectDownReachable(std::set<LayerWrapper*>& reachable) override; void collectDownReachable(std::set<LayerWrapper*>& reachable) override;
@ -125,6 +127,7 @@ class LeafLayerWrapper : public LayerWrapper
void refresh(LayerWrapper* layer = nullptr) override; void refresh(LayerWrapper* layer = nullptr) override;
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent); LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
QJsonObject toJson() const override; QJsonObject toJson() const override;
void replaceMaterial(const Renderer::Material& origin, const Renderer::Material& target) override;
void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL)) override; void paint(QPainter* painter, QTransform transform = QTransform(), bool force = false, LayerStyleContainer styles = LayerStyleContainer(ElementType::TYPE_ALL)) override;
void collectDownReachable(std::set<LayerWrapper*>& reachable) override; void collectDownReachable(std::set<LayerWrapper*>& reachable) override;
void collectDownUsedElements(std::set<GraphicElement*>& elements, bool deep = true) override; void collectDownUsedElements(std::set<GraphicElement*>& elements, bool deep = true) override;

View File

@ -0,0 +1,53 @@
#include "MaterialReplaceDialog.h"
#include <QFormLayout>
#include <QDialogButtonBox>
MaterialReplaceDialog::MaterialReplaceDialog(const EditorWidgetItem* editorWidgetItem, QWidget* parent)
: QDialog(parent),
editorWidgetItem(editorWidgetItem),
originColorPicker(new ColorPicker(ColorHelper::instance().getPrimary1(), this)),
originRoughnessField(new QtMaterialTextField(this)),
originMetallicField(new QtMaterialTextField(this)),
targetColorPicker(new ColorPicker(ColorHelper::instance().getPrimary1(), this)),
targetRoughnessField(new QtMaterialTextField(this)),
targetMetallicField(new QtMaterialTextField(this))
{
setWindowTitle(QStringLiteral("第窐杸遙"));
auto* vbox = new QVBoxLayout(this);
auto gridLayout = new QGridLayout(this);
auto* formLeft = new QFormLayout(this);
formLeft->addRow(QStringLiteral("埻價插伎"), originColorPicker);
formLeft->addRow(QStringLiteral("埻棉缽僅"), originRoughnessField);
formLeft->addRow(QStringLiteral("埻踢扽僅"), originMetallicField);
originRoughnessField->setText(QString::number(0.5));
originMetallicField->setText(QString::number(0));
auto* formRight = new QFormLayout(this);
formRight->addRow(QStringLiteral("醴梓價插伎"), targetColorPicker);
formRight->addRow(QStringLiteral("醴梓棉缽僅"), targetRoughnessField);
formRight->addRow(QStringLiteral("醴梓踢扽僅"), targetMetallicField);
targetRoughnessField->setText(QString::number(0.5));
targetMetallicField->setText(QString::number(0));
gridLayout->addLayout(formLeft, 0, 0);
gridLayout->addLayout(formRight, 0, 1);
vbox->addLayout(gridLayout);
auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
vbox->addWidget(buttonBox);
connect(buttonBox, &QDialogButtonBox::accepted, this, &MaterialReplaceDialog::accept);
connect(buttonBox, &QDialogButtonBox::rejected, this, &MaterialReplaceDialog::reject);
}
void MaterialReplaceDialog::accept()
{
editorWidgetItem->layerManager->getRoot()->replaceMaterial(
Renderer::Material(originColorPicker->getColor(), originMetallicField->text().toFloat(), originRoughnessField->text().toFloat()),
Renderer::Material(targetColorPicker->getColor(), targetMetallicField->text().toFloat(), targetRoughnessField->text().toFloat())
);
QDialog::accept();
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <QDialog>
#include "EditorWidgetItem.h"
#include "EditorWidgetComponent/ColorPicker.h"
#include "../Renderer/Painting/BaseStyle.h"
class MaterialReplaceDialog : public QDialog
{
Q_OBJECT
public:
MaterialReplaceDialog(const EditorWidgetItem* editorWidgetItem, QWidget* parent = nullptr);
private slots:
void accept() override;
private:
const EditorWidgetItem* editorWidgetItem;
ColorPicker* originColorPicker; QtMaterialTextField* originRoughnessField; QtMaterialTextField* originMetallicField;
ColorPicker* targetColorPicker; QtMaterialTextField* targetRoughnessField; QtMaterialTextField* targetMetallicField;
};

View File

@ -1,6 +1,7 @@
#include "BaseStyle.h" #include "BaseStyle.h"
#include "MaterialStyleFill.h" #include "MaterialStyleFill.h"
#include "MaterialStyleStroke.h" #include "MaterialStyleStroke.h"
#include <QDebug>
using namespace Renderer; using namespace Renderer;
using namespace glm; using namespace glm;
@ -107,3 +108,8 @@ std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vecto
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke), widthMap); return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke), widthMap);
} }
} }
QDebug operator<<(QDebug d, const Renderer::Material& m)
{
return d << m.color << " " << m.metallic << " " << m.roughness;
}

View File

@ -54,3 +54,5 @@ namespace Renderer
std::pair<glm::vec4, glm::vec2> toVec() const; std::pair<glm::vec4, glm::vec2> toVec() const;
}; };
} }
QDebug operator<<(QDebug, const Renderer::Material&);