用PixelPath更换了QPainterPath,一系列更改

dev-VirtualTexture
karlis 2023-02-08 15:38:03 +08:00
parent b562ff5053
commit 870531a0be
17 changed files with 225 additions and 97 deletions

1
.gitignore vendored
View File

@ -361,3 +361,4 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
/UnitTest/Qt.x64.runsettings

View File

@ -105,6 +105,7 @@
<ClCompile Include="src\Editor\GraphicElement.cpp" />
<ClCompile Include="src\Editor\LayerManager.cpp" />
<ClCompile Include="src\Editor\LayerWrapper.cpp" />
<ClCompile Include="src\Editor\PixelPath.cpp" />
<ClCompile Include="src\Editor\PreviewWindow.cpp" />
<ClCompile Include="src\Editor\RightBar\InfoDisplayWidget.cpp" />
<ClCompile Include="src\Editor\RightBar\LayerTreeWidget.cpp" />
@ -181,6 +182,7 @@
<ClInclude Include="src\Editor\LayerManager.h" />
<ClInclude Include="src\Editor\LayerStyle.h" />
<QtMoc Include="src\Editor\PreviewWindow.h" />
<ClInclude Include="src\Editor\PixelPath.h" />
<ClInclude Include="src\Editor\ThirdPartyLib\qquick\qquicksvgparser_p.h" />
<ClInclude Include="src\Editor\ThirdPartyLib\qquick\qtquickglobal.h" />
<ClInclude Include="src\Editor\ThirdPartyLib\qquick\qtquickglobal_p.h" />

View File

@ -204,6 +204,9 @@
<ClCompile Include="src\Renderer\Preview\ElementRenderer.cpp">
<Filter>Source Files\Renderer\Preview</Filter>
</ClCompile>
<ClCompile Include="src\Editor\PixelPath.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="src\Renderer\RendererGLWidget.h">
@ -408,6 +411,9 @@
<ClInclude Include="src\Renderer\Preview\ElementRenderer.h">
<Filter>Header Files\Renderer\Preview</Filter>
</ClInclude>
<ClInclude Include="src\Editor\PixelPath.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtRcc Include="MainWindow.qrc">

View File

@ -2,6 +2,7 @@
EditorWidget::EditorWidget(QWidget *parent) : QWidget(parent)
{
QImage x;
displayLayer = nullptr;
displayElement = nullptr;
ui.setupUi(this);
@ -25,7 +26,7 @@ EditorWidget::EditorWidget(QWidget *parent) : QWidget(parent)
qDebug() << jError.errorString();
// end test
QJsonObject source = jsonDoc.object();
elementManager = new ElementManager(source);
elementManager = new ElementManager(source,previewWindow->getRenderer());
layerManager = new LayerManager(source, elementManager);
previewWindow->initialize(layerManager);
if (layerManager->getRoot() != nullptr)

View File

@ -9,6 +9,7 @@
#include <QPainter>
#include <QTreeWidget>
#include <QWidget>
class EditorWidget : public QWidget
{
Q_OBJECT

View File

@ -1,5 +1,5 @@
#include "ElementManager.h"
ElementManager::ElementManager(QJsonObject source)
ElementManager::ElementManager(QJsonObject source,Renderer::ElementRenderer* renderer)
{
auto elementsJson = source.value("elements").toArray();
qDebug() << elementsJson.size();
@ -9,6 +9,8 @@ ElementManager::ElementManager(QJsonObject source)
elements.push_back(new GroupElement());
else
elements.push_back(new SimpleElement(elementJson.toObject()));
(*elements.rbegin())->renderer = renderer;
}
}

View File

@ -2,10 +2,12 @@
#include "GraphicElement.h"
#include "LayerManager.h"
#include <QJsonArray>
#include "../Renderer/Preview/ElementRenderer.h"
#include <vector>
using std::vector;
class LayerManager;
class GraphicElement;
class Renderer::ElementRenderer;
class ElementManager
{
@ -13,7 +15,7 @@ class ElementManager
vector<GraphicElement *> elements;
public:
ElementManager(QJsonObject source);
ElementManager(QJsonObject source,Renderer::ElementRenderer *renderer);
~ElementManager();
void addElement(GraphicElement *element);
void removeElement(GraphicElement *pElement);

View File

@ -1,9 +1,12 @@
#include "GraphicElement.h"
#include "util/SvgFileLoader.h"
using namespace std;
QPainterPath SimpleElement::getPaintObject() const
PixelPath SimpleElement::getPaintObject() const
{
return painterPath;
PixelPath result;
result.addPath(painterPath);
return result;
}
void SimpleElement::loadSvgFile(const QString& filePath)
@ -29,26 +32,48 @@ void GroupElement::setSourceLayer(FolderLayerWrapper *sourceLayer)
{
this->sourceLayer = sourceLayer;
}
QPainterPath GroupElement::getPaintObject() const
PixelPath GroupElement::getPaintObject() const
{
if (sourceLayer != nullptr) {
sourceLayer->refresh();
return sourceLayer->getCache();
}
else
return QPainterPath();
return PixelPath();
}
void BitmapPath::applyTransformation(QTransform& transformation)
{
//TODO: apply styles and send back
PixelPath SimpleElement::getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo> styles) const {
PixelPath result;
Renderer::ElementStyleStrokeDemo demo;
qDebug() << (renderer==nullptr)<<"------------";
//auto [img, mov] = renderer->drawElement(painterPath,demo,1.0,false);
//qDebug() << img << " ------";
//result.addImage(img, mov);
result.addPath(painterPath);
// QImage img(80,80,QImage::Format_ARGB32);
// QPainter pt(&img);
//pt.setPen(QPen(Qt::red, 2));
//pt.drawLine(0, 0, 80, 80);
//pt.end();
//result.addImage(img, QPoint(0, 0));
return result;
}
QImage FolderBitmapPath::getStylesAppliedCache() const
{
return QImage();
PixelPath GroupElement::getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo> styles) const {
return getPaintObject();
}
QImage ComposedPainterPath::getStylesAppliedCache() const
{
return QImage();
}
//BitmapPath::BitmapPath() {
// pathCount = 0u;
//}
//
//void BitmapPath::initialize(vector<QPainterPath>& paths) {
// cache.clear();
// rawPath.clear();
// pathCount = 1u;
// bound
// for (auto& path : paths) {
// rawPath.addPath(path);
// }
//}

View File

@ -1,12 +1,16 @@
#pragma once
#include "LayerWrapper.h"
#include <QJsonArray>
#include <QJsonObject>
#include <QPainterPath>
#include <QImage>
#include <vector>
#include <string>
#include "../Renderer/Preview/ElementRenderer.h"
#include "../Renderer/Painting/ElementStyle.h"
#include "PixelPath.h"
#include <functional>
class LayerWrapper;
class LeafLayerWrapper;
@ -16,9 +20,11 @@ class ComposedPainterPath;
class GraphicElement
{
public:
Renderer::ElementRenderer *renderer;
QString name = "";
// TODO: ¸ÄΪBitmapPath
virtual QPainterPath getPaintObject() const = 0;
virtual PixelPath getPaintObject() const = 0;
virtual PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const = 0;
};
class SimpleElement : public GraphicElement
@ -32,7 +38,8 @@ private:
public:
SimpleElement(QJsonObject jsonSource);
~SimpleElement() = default;
QPainterPath getPaintObject() const override;
PixelPath getPaintObject() const override;
PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const override;
};
class GroupElement : public GraphicElement
@ -44,51 +51,31 @@ public:
GroupElement() = default;
GroupElement(FolderLayerWrapper* mSourceLayer);
~GroupElement() = default;
QPainterPath getPaintObject() const override;
PixelPath getPaintObject() const override;
PixelPath getPaintObject(std::vector<Renderer::ElementStyleStrokeDemo>) const override;
void setSourceLayer(FolderLayerWrapper* sourceLayer);
};
//******************************** BitmapPath ********************************//
using std::vector;
using std::shared_ptr;
class BitmapPath
{
protected:
QRectF boundingRect;
QImage stylesAppliedCache;
void applyTransformation(QTransform &transformation);
public:
/**
* painterQImage
*/
virtual void paint(QPainter* painter) const = 0;
virtual QImage getStylesAppliedCache() const = 0;
};
class FolderBitmapPath : public BitmapPath
{
public:
const vector<BitmapPath*> children;
virtual QImage getStylesAppliedCache() const override;
};
/**
* cacheRender
*/
class ComposedPainterPath : public BitmapPath
{
public:
/**
* ElementStylezealedStylePath
*/
struct SinglePath {
shared_ptr<QPainterPath> path;
bool zealed;
};
const vector<SinglePath> paths;
virtual QImage getStylesAppliedCache() const override;
};
//using std::vector;
//using std::shared_ptr;
//
//class BitmapPath
//{
//private:
// QRectF *boundingRect;
// QPainterPath cache;
// QPainterPath rawPath;
// size_t pathCount;
//
//public:
// BitmapPath();
// void initialize(std::vector<QPainterPath>& paths);
// void styles(Renderer::ElementStyle* style);
// void trans(QTransform& transform);
// QPainterPath getPainterPath() const;
// void addBitmapPath(BitmapPath& path);
// QRectF boundingRect()const;
// void clear();
//};

View File

@ -13,7 +13,8 @@ LayerWrapper *LayerManager::getRoot() const
}
void LayerManager::paint(QPainter *painter) const
{
painter->drawPath(root->getCache());
auto p = root->getCache().getPixmap();
painter->drawPixmap(0, 0, p);
}
bool LayerManager::singleSelectedCheck() const
{

View File

@ -23,11 +23,12 @@ LayerWrapper *LayerWrapper::getParent() const
return this == nullptr ? nullptr : this->parent.get();
}
QPainterPath LayerWrapper::getCache()
PixelPath LayerWrapper::getCache()
{
this->refresh();
return cache;
}
// TODO: undone
LayerWrapper::LayerWrapper(QJsonObject json, LayerWrapper *parent)
{
@ -76,19 +77,19 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana
int elementIndex = json.value("element").toInt();
wrappedElement = elementManager->getElementById(elementIndex);
}
void LayerWrapper::SimpleProperty::apply(QPainterPath &cache) const
void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const
{
QTransform trans;
double centerX = cache.boundingRect().center().x();
double centerY = cache.boundingRect().center().y();
qDebug() << name << " " << cache.boundingRect().center();
qDebug() << name << " " << cache.boundingRect();
double centerX = cache.getBoundingRect().center().x();
double centerY = cache.getBoundingRect().center().y();
//qDebug() << name << " " << cache.boundingRect().center();
//qDebug() << name << " " << cache.boundingRect();
trans.translate(centerX, centerY);
trans.scale(scale.x(), scale.y());
trans.rotate(rotation);
trans.translate(-centerX, -centerY);
trans.translate(offset.x(), offset.y());
cache = trans.map(cache);
cache = cache.trans(trans);
}
void LayerWrapper::refresh()
{
@ -108,7 +109,7 @@ void LeafLayerWrapper::refresh()
cache.clear();
if (wrappedElement != nullptr)
{
cache.addPath(wrappedElement->getPaintObject());
cache.addPath(wrappedElement->getPaintObject(this->styles));
}
LayerWrapper::refresh();
}

View File

@ -12,7 +12,7 @@
#include <QTreeWidget>
#include <memory>
#include <vector>
#include "PixelPath.h"
#include "../Renderer/Painting/ElementStyle.h"
using std::shared_ptr;
using std::vector;
@ -29,7 +29,7 @@ class LayerWrapper
QPointF referencePoint;
// vector<LayerStyle> styles;
// TODO: 将cache移到子类对Leaf用ComposedPainterPath对Folder用FolderBitmapPath
QPainterPath cache;
PixelPath cache;
public:
QTreeWidgetItem *qTreeItem;
@ -42,12 +42,12 @@ class LayerWrapper
bool flipHorizontally = 0;
bool flipVertically = 0;
// TODO: 将QPainterPath改为BitmapPath
void apply(QPainterPath &cache) const;
void apply(PixelPath&cache) const;
} property;
void setParent(LayerWrapper *newParent);
virtual void refresh();
// TODO: 将QPainterPath改为BitmapPath/QImage或者直接将其删除绘制时直接使用BitmapPath的paint方法
QPainterPath getCache();
virtual PixelPath getCache();
LayerWrapper *getParent() const; // invoke by manager, then invoke parent's applyStyles
LayerWrapper(QJsonObject json, LayerWrapper *parent);
LayerWrapper() = default;
@ -76,7 +76,7 @@ class LeafLayerWrapper : public LayerWrapper
{
public:
GraphicElement *wrappedElement;
const vector<Renderer::ElementStyle> styles;
const vector<Renderer::ElementStyleStrokeDemo> styles;
public:
void refresh() override;

View File

@ -0,0 +1,70 @@
#include "PixelPath.h"
#include <QPainter>
using namespace std;
PixelPath::PixelPath(int w, int h) :w(w), h(h)
{
pixmap = QPixmap(w, h);
pixmap.fill(Qt::transparent);
boundingRect = QRectF(0, 0, 0, 0);
}
PixelPath::PixelPath(QPainterPath painterPath, int w, int h) :w(w), h(h)
{
pixmap = QPixmap(w, h);
pixmap.fill(Qt::transparent);
boundingRect = QRectF(0, 0, 0, 0);
addPath(painterPath);
}
QRectF PixelPath::getBoundingRect() const
{
return boundingRect;
}
QPixmap PixelPath::getPixmap() const
{
return pixmap;
}
void PixelPath::addPath(const PixelPath& path)
{
QPainter painter(&pixmap);
painter.drawPixmap(0, 0, path.getPixmap());
boundingRect = boundingRect.united(path.getBoundingRect());
}
void PixelPath::addPath(const QPainterPath& path)
{
QPainter painter(&pixmap);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setPen(QPen(Qt::black,1));
painter.drawPath(path);
boundingRect = boundingRect.united(path.boundingRect());
}
void PixelPath::addImage(const QImage& image,const QPointF& pos)
{
QPainter painter(&pixmap);
painter.drawImage(pos, image);
boundingRect = boundingRect.united(QRectF(pos, image.size()));
}
void PixelPath::clear()
{
pixmap.fill(Qt::transparent);
boundingRect = QRectF(0, 0, 0, 0);
}
PixelPath PixelPath::trans(QTransform& mat)const
{
PixelPath result(w, h);
QPainter painter(&result.pixmap);
painter.setRenderHint(QPainter::SmoothPixmapTransform);
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setTransform(mat);
painter.drawPixmap(0, 0, pixmap);
result.boundingRect = mat.mapRect(boundingRect);
return result;
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <QImage>
#include <QPixmap>
#include <QTransform>
#include <QPainterPath>
class PixelPath
{
private:
QRectF boundingRect;
QPixmap pixmap;
int w,h;
public:
PixelPath(int w=1280, int h=720);
PixelPath(QPainterPath painterPath,int w = 1280, int h = 720);
~PixelPath() = default;
QRectF getBoundingRect() const;
QPixmap getPixmap() const;
void addPath(const PixelPath& path);
void addPath(const QPainterPath& path);
void addImage(const QImage& image,const QPointF& pos);
void clear();
PixelPath trans(QTransform& mat)const;
};

View File

@ -2,10 +2,13 @@
PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
{
this->renderer = new Renderer::ElementRenderer(this);
QSurfaceFormat surfaceFormat;
surfaceFormat.setSamples(16);
setFormat(surfaceFormat);
painter = new QPainter(this);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->setRenderHint(QPainter::HighQualityAntialiasing);
layerManager = nullptr;
}
@ -16,28 +19,29 @@ void PreviewWindow::initialize(LayerManager *layerManager)
void PreviewWindow::show()
{
QFile settingFile;
settingFile.setFileName("../data.json");
settingFile.open(QFile::ReadOnly);
QByteArray setting = settingFile.readAll().trimmed();
QJsonDocument jsonDoc(QJsonDocument::fromJson(setting));
auto jElements = jsonDoc.object().value("elements").toArray();
//QFile settingFile;
//settingFile.setFileName("../data.json");
//settingFile.open(QFile::ReadOnly);
//QByteArray setting = settingFile.readAll().trimmed();
//QJsonDocument jsonDoc(QJsonDocument::fromJson(setting));
//auto jElements = jsonDoc.object().value("elements").toArray();
for (auto &&ele : jElements)
{
SimpleElement element(ele.toObject());
painter->drawPath(element.getPaintObject());
}
//for (auto &&ele : jElements)
//{
// SimpleElement element(ele.toObject());
// painter->drawPath(element.getPaintObject());
//}
}
void PreviewWindow::initializeGL()
{
this->renderer->initialize();
initializeOpenGLFunctions();
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void PreviewWindow::paintGL()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
painter->begin(this);
painter->setRenderHint(QPainter::Antialiasing);
@ -49,3 +53,7 @@ void PreviewWindow::paintGL()
void PreviewWindow::resizeGL(int w, int h)
{
}
Renderer::ElementRenderer* const PreviewWindow::getRenderer()const {
return this->renderer;
}

View File

@ -8,6 +8,8 @@
#include <QJsonValue>
#include <QOpenGLFunctions>
#include <QOpenGLWidget>
#include "../Renderer/Preview/ElementRenderer.h"
class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
@ -15,6 +17,7 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
private:
QPainter *painter;
LayerManager *layerManager;
Renderer::ElementRenderer* renderer;
public:
PreviewWindow(QWidget *parent = nullptr);
@ -23,4 +26,5 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
void initializeGL() override;
void paintGL() override;
void resizeGL(int w, int h) override;
Renderer::ElementRenderer* const getRenderer()const;
};

View File

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<EnvironmentVariables>
<PATH>%PATH%;E:/Qt/5.15.2/msvc2019_64/bin</PATH>
</EnvironmentVariables>
</RunConfiguration>
</RunSettings>