Compare commits
10 Commits
ce7f2ae8fa
...
7da01fbe92
Author | SHA1 | Date |
---|---|---|
ArgonarioD | 7da01fbe92 | |
ArgonarioD | 9984dd23f8 | |
ArgonarioD | 200dccff46 | |
ArgonarioD | fef34280c6 | |
wuyize | 4ff5406acc | |
ArgonarioD | 50a1bdaff4 | |
karlis | 6d554ab265 | |
karlis | a9fb9197e6 | |
wuyize | 15a41d61a5 | |
ArgonarioD | 03a06ce426 |
|
@ -10,7 +10,6 @@ constexpr int COLUMN_METALLIC = 2;
|
||||||
constexpr int COLUMN_ROUGHNESS = 3;
|
constexpr int COLUMN_ROUGHNESS = 3;
|
||||||
constexpr int COLUMN_OPERATIONS = 4;
|
constexpr int COLUMN_OPERATIONS = 4;
|
||||||
|
|
||||||
// FIXME: Material的控件有显示bug
|
|
||||||
StrokeStyleWidget::StrokeStyleWidget(
|
StrokeStyleWidget::StrokeStyleWidget(
|
||||||
std::shared_ptr<Renderer::MaterialStyleStroke> stroke,
|
std::shared_ptr<Renderer::MaterialStyleStroke> stroke,
|
||||||
QWidget* parent
|
QWidget* parent
|
||||||
|
@ -122,7 +121,7 @@ void StrokeStyleWidget::initTable(std::shared_ptr<Renderer::StrokeRadialGradient
|
||||||
auto lastPair = materialMap->rbegin();
|
auto lastPair = materialMap->rbegin();
|
||||||
newWidth = lastPair->first + 0.01;
|
newWidth = lastPair->first + 0.01;
|
||||||
}
|
}
|
||||||
Renderer::Material newMaterial = { QColor::fromRgb(0,0,0), 0.f, .8f };
|
Renderer::Material newMaterial(QColor::fromRgb(0, 0, 0));
|
||||||
(*materialMap)[newWidth] = newMaterial;
|
(*materialMap)[newWidth] = newMaterial;
|
||||||
int newRow = this->strokeTable->rowCount() - 1;
|
int newRow = this->strokeTable->rowCount() - 1;
|
||||||
this->strokeTable->insertRow(newRow);
|
this->strokeTable->insertRow(newRow);
|
||||||
|
@ -153,18 +152,17 @@ void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& ma
|
||||||
});
|
});
|
||||||
|
|
||||||
QTableWidgetItem* metallicItem = new QTableWidgetItem;
|
QTableWidgetItem* metallicItem = new QTableWidgetItem;
|
||||||
metallicItem->setData(Qt::EditRole, material.metallic);
|
metallicItem->setData(Qt::EditRole, material.metallicF());
|
||||||
strokeTable->setItem(row, COLUMN_METALLIC, metallicItem);
|
strokeTable->setItem(row, COLUMN_METALLIC, metallicItem);
|
||||||
|
|
||||||
QTableWidgetItem* roughnessItem = new QTableWidgetItem;
|
QTableWidgetItem* roughnessItem = new QTableWidgetItem;
|
||||||
roughnessItem->setData(Qt::EditRole, material.roughness);
|
roughnessItem->setData(Qt::EditRole, material.roughnessF());
|
||||||
strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem);
|
strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem);
|
||||||
|
|
||||||
QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable);
|
QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable);
|
||||||
removeButton->setFixedSize(20, 20);
|
removeButton->setFixedSize(20, 20);
|
||||||
strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton);
|
strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton);
|
||||||
connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() {
|
connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() {
|
||||||
if (this->strokeTable->rowCount() <= 1) return;
|
|
||||||
radialStroke(this->stroke)->materialMap.erase(this->strokeTable->item(row, COLUMN_WIDTH)->text().toFloat());
|
radialStroke(this->stroke)->materialMap.erase(this->strokeTable->item(row, COLUMN_WIDTH)->text().toFloat());
|
||||||
this->strokeTable->removeRow(row);
|
this->strokeTable->removeRow(row);
|
||||||
});
|
});
|
||||||
|
@ -204,12 +202,12 @@ void StrokeStyleWidget::onCellChanged(int row, int column)
|
||||||
}
|
}
|
||||||
case COLUMN_METALLIC:
|
case COLUMN_METALLIC:
|
||||||
{
|
{
|
||||||
radialStroke(stroke)->materialMap[changedWidth].metallic = changedItemValue;
|
radialStroke(stroke)->materialMap[changedWidth].setMetallicF(changedItemValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COLUMN_ROUGHNESS:
|
case COLUMN_ROUGHNESS:
|
||||||
{
|
{
|
||||||
radialStroke(stroke)->materialMap[changedWidth].roughness = changedItemValue;
|
radialStroke(stroke)->materialMap[changedWidth].setRoughnessF(changedItemValue);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
|
||||||
elementInfoDisplayWidget->enableEdit();
|
elementInfoDisplayWidget->enableEdit();
|
||||||
qDebug() << layerInfoDisplayWidget;
|
qDebug() << layerInfoDisplayWidget;
|
||||||
qDebug() << elementInfoDisplayWidget;
|
qDebug() << elementInfoDisplayWidget;
|
||||||
|
connect(previewWindow, &PreviewWindow::refreshElementPreviewByIndex, elementInfoDisplayWidget, &ElementPoolWidget::refreshPictureByIndex);
|
||||||
connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh);
|
connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh);
|
||||||
connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged);
|
connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged);
|
||||||
connect(treeWidget, &LayerTreeWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh);
|
connect(treeWidget, &LayerTreeWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh);
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
ElementManager::ElementManager(QJsonObject source,Renderer::ElementRenderer* renderer)
|
ElementManager::ElementManager(QJsonObject source,Renderer::ElementRenderer* renderer)
|
||||||
{
|
{
|
||||||
auto elementsJson = source.value("elements").toArray();
|
auto elementsJson = source.value("elements").toArray();
|
||||||
qDebug() << elementsJson.size();
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto elementJson : elementsJson)
|
for (auto elementJson : elementsJson)
|
||||||
{
|
{
|
||||||
|
@ -68,9 +67,6 @@ int ElementManager::getLayerReferencedBy(const FolderLayerWrapper* layer)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < elements.size(); i++)
|
for (int i = 0; i < elements.size(); i++)
|
||||||
if (typeid(*elements[i]) == typeid(GroupElement)) {
|
if (typeid(*elements[i]) == typeid(GroupElement)) {
|
||||||
qDebug() << ((GroupElement*)elements[i])->sourceLayer;
|
|
||||||
qDebug() << layer;
|
|
||||||
qDebug() << "------------";
|
|
||||||
if (((GroupElement*)elements[i])->sourceLayer == layer)
|
if (((GroupElement*)elements[i])->sourceLayer == layer)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +93,6 @@ void ElementManager::createSimpleElement(QString name, QString filePath) {
|
||||||
data.insert("include", filePath);
|
data.insert("include", filePath);
|
||||||
json.insert("data", data);
|
json.insert("data", data);
|
||||||
auto element = new SimpleElement(json);
|
auto element = new SimpleElement(json);
|
||||||
qDebug() << element->painterPath;
|
|
||||||
element->name = name;
|
element->name = name;
|
||||||
addElement(element);
|
addElement(element);
|
||||||
}
|
}
|
|
@ -37,23 +37,8 @@ void ElementPoolWidget::setElementList(std::vector<GraphicElement*> elements) {
|
||||||
pictureList->clear();
|
pictureList->clear();
|
||||||
this->elements = elements;
|
this->elements = elements;
|
||||||
for (int index = 0; index < elements.size(); index++) {
|
for (int index = 0; index < elements.size(); index++) {
|
||||||
//
|
|
||||||
//QString strPath = QString("C:\\Users\\86177\\Pictures\\Screenshots\\test.png");
|
|
||||||
//QPixmap itemPixmap(strPath);
|
|
||||||
//QPixmap itemPixmap(QSize(200, 200));
|
|
||||||
//itemPixmap.fill(Qt::red);
|
|
||||||
QPixmap itemPixmap = elements[index]->getPaintObject().getDetail();
|
|
||||||
qDebug() << this->parentWidget()->size();
|
|
||||||
//auto p = new QWidget();
|
|
||||||
//auto lb = new QLabel(p);
|
|
||||||
//lb->setPixmap(itemPixmap);
|
|
||||||
//lb->setFixedSize(1920, 1080);
|
|
||||||
//p->setFixedSize(1920, 1080);
|
|
||||||
//lb->show();
|
|
||||||
//p->show();
|
|
||||||
|
|
||||||
QListWidgetItem* pItem = new QListWidgetItem(
|
QListWidgetItem* pItem = new QListWidgetItem(
|
||||||
itemPixmap.scaled(QSize(iconWidth - 25, iconHeight - 25)),
|
elements[index]->getPreview(QSize(iconWidth - 25, iconHeight - 25)),
|
||||||
elements[index]->name);
|
elements[index]->name);
|
||||||
pItem->setSizeHint(QSize(iconWidth, iconHeight));
|
pItem->setSizeHint(QSize(iconWidth, iconHeight));
|
||||||
pictureList->insertItem(index, pItem);
|
pictureList->insertItem(index, pItem);
|
||||||
|
@ -88,13 +73,21 @@ void ElementPoolWidget::refresh() {
|
||||||
void ElementPoolWidget::refreshPicture(GraphicElement* element) {
|
void ElementPoolWidget::refreshPicture(GraphicElement* element) {
|
||||||
for (int i = 0; i < elements.size(); i++) {
|
for (int i = 0; i < elements.size(); i++) {
|
||||||
if (element == elements[i]) {
|
if (element == elements[i]) {
|
||||||
pictureList->item(i)->setIcon(element->getPaintObject().getDetail().scaled(QSize(iconWidth - 25, iconHeight - 25)));
|
pictureList->item(i)->setIcon(elements[i]->getPreview(QSize(iconWidth - 25, iconHeight - 25)));
|
||||||
// update();
|
// update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElementPoolWidget::refreshPictureByIndex(int index) {
|
||||||
|
if (index >= 0 && index < elements.size())
|
||||||
|
{
|
||||||
|
pictureList->item(index)->setIcon(elements[index]->getPreview(QSize(iconWidth - 25, iconHeight - 25)));
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ElementPoolWidget::enableEdit()
|
void ElementPoolWidget::enableEdit()
|
||||||
{
|
{
|
||||||
connect(this->pictureList, &QListWidget::customContextMenuRequested, this, &ElementPoolWidget::popMenu);
|
connect(this->pictureList, &QListWidget::customContextMenuRequested, this, &ElementPoolWidget::popMenu);
|
||||||
|
|
|
@ -30,6 +30,7 @@ public slots:
|
||||||
int pictureItemClicked(QListWidgetItem* item);
|
int pictureItemClicked(QListWidgetItem* item);
|
||||||
void refresh();
|
void refresh();
|
||||||
void refreshPicture(GraphicElement* element);
|
void refreshPicture(GraphicElement* element);
|
||||||
|
void refreshPictureByIndex(int index);
|
||||||
void popMenu(const QPoint& pos);
|
void popMenu(const QPoint& pos);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -49,35 +49,7 @@ PixelPath GroupElement::getPaintObject() const
|
||||||
|
|
||||||
//TODO: apply styles and send back
|
//TODO: apply styles and send back
|
||||||
PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
||||||
PixelPath result;
|
return this->getPaintObject();
|
||||||
std::shared_ptr<Renderer::ElementStyle> style;
|
|
||||||
if ((*styles).empty())
|
|
||||||
{
|
|
||||||
return this->getPaintObject();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
style = (*styles)[0];
|
|
||||||
/*qDebug() << std::dynamic_pointer_cast<Renderer::StrokePlain>(
|
|
||||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(style)->materialStyles[0]->materialStroke
|
|
||||||
)->material.color.name();*/
|
|
||||||
/*qDebug() << std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(
|
|
||||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(style)->materialStyles[0]->materialStroke
|
|
||||||
)->materialMap[1.0].color;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
auto [img, mov] = Renderer::ElementRenderer::instance()->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);
|
|
||||||
//pt.setPen(QPen(Qt::red, 2));
|
|
||||||
//pt.drawLine(0, 0, 80, 80);
|
|
||||||
//pt.end();
|
|
||||||
//result.addImage(img, QPoint(0, 0));
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PixelPath GroupElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
PixelPath GroupElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
||||||
|
@ -132,35 +104,48 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector<
|
||||||
{
|
{
|
||||||
Renderer::ElementStyleStrokeDemo demo(2);
|
Renderer::ElementStyleStrokeDemo demo(2);
|
||||||
std::shared_ptr<Renderer::ElementStyle> style;
|
std::shared_ptr<Renderer::ElementStyle> style;
|
||||||
if (styles.empty())
|
style = styles[0];
|
||||||
{
|
|
||||||
style = std::make_shared<Renderer::ElementStyleStrokeDemo>(2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
style = styles[0];
|
|
||||||
/*qDebug() << std::dynamic_pointer_cast<Renderer::StrokePlain>(
|
|
||||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(style)->materialStyles[0]->materialStroke
|
|
||||||
)->material.color.name();*/
|
|
||||||
/*qDebug() << std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(
|
|
||||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(style)->materialStyles[0]->materialStroke
|
|
||||||
)->materialMap[1.0].color;*/
|
|
||||||
}
|
|
||||||
QVector2D scale(transform.m11(), transform.m22());
|
QVector2D scale(transform.m11(), transform.m22());
|
||||||
scale /= transform.m33();
|
scale /= transform.m33();
|
||||||
double maxScale = std::max(scale.x(), scale.y());
|
double maxScale = std::max(scale.x(), scale.y());
|
||||||
double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio();
|
double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio();
|
||||||
auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, *style, pixelRatio);
|
auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, *style, pixelRatio);
|
||||||
|
transform.translate(mov.x(), mov.y());
|
||||||
painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio));
|
painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio));
|
||||||
//img = img.scaled(img.width() / pixelRatio, img.height() / pixelRatio, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
painter->drawImage(0, 0, img);
|
||||||
painter->drawImage(mov, img);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupElement::paint(QPainter* painter, QTransform transform, const vector<std::shared_ptr<LayerStyle>> &styles)
|
void GroupElement::paint(QPainter* painter, QTransform transform, const vector<std::shared_ptr<LayerStyle>> &styles)
|
||||||
{
|
{
|
||||||
sourceLayer->paint(painter, transform);
|
sourceLayer->paint(painter, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QPixmap SimpleElement::getPreview(QSize size)
|
||||||
|
{
|
||||||
|
QPixmap result(size + QSize(5,5));
|
||||||
|
QPainter painter(&result);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
painter.scale(size.width() / painterPath.boundingRect().width(), size.height() / painterPath.boundingRect().height());
|
||||||
|
painter.drawPath(painterPath);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap GroupElement::getPreview(QSize size)
|
||||||
|
{
|
||||||
|
auto cache = sourceLayer->getCache();
|
||||||
|
QPixmap result(QSize(1024, 1024));
|
||||||
|
QPainter painter(&result);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
sourceLayer->paint(&painter, QTransform(), true);
|
||||||
|
painter.end();
|
||||||
|
QRect rect (cache.getBoundingRect().toRect());
|
||||||
|
rect.setTopLeft(rect.topLeft() - QPoint(5, 5));
|
||||||
|
rect.setBottomRight(rect.bottomRight() + QPoint(5, 5));
|
||||||
|
result = result.copy(rect);
|
||||||
|
return result.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
}
|
}
|
|
@ -29,6 +29,7 @@ public:
|
||||||
virtual PixelPath getPaintObject() const = 0;
|
virtual PixelPath getPaintObject() const = 0;
|
||||||
virtual PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const = 0;
|
virtual PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const = 0;
|
||||||
virtual void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) = 0;
|
virtual void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) = 0;
|
||||||
|
virtual QPixmap getPreview(QSize size) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SimpleElement : public GraphicElement
|
class SimpleElement : public GraphicElement
|
||||||
|
@ -48,6 +49,7 @@ public:
|
||||||
PixelPath getPaintObject() const override;
|
PixelPath getPaintObject() const override;
|
||||||
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
||||||
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override;
|
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override;
|
||||||
|
QPixmap getPreview(QSize size) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GroupElement : public GraphicElement
|
class GroupElement : public GraphicElement
|
||||||
|
@ -64,6 +66,7 @@ public:
|
||||||
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
||||||
void setSourceLayer(FolderLayerWrapper* sourceLayer);
|
void setSourceLayer(FolderLayerWrapper* sourceLayer);
|
||||||
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override;
|
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override;
|
||||||
|
QPixmap getPreview(QSize size) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//******************************** BitmapPath ********************************//
|
//******************************** BitmapPath ********************************//
|
||||||
|
|
|
@ -51,7 +51,6 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
|
||||||
if (this->strokePair.first == nullptr)
|
if (this->strokePair.first == nullptr)
|
||||||
{
|
{
|
||||||
auto materialMap = std::map<float, Renderer::Material>();
|
auto materialMap = std::map<float, Renderer::Material>();
|
||||||
materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f };
|
|
||||||
this->strokePair.first = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
|
this->strokePair.first = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
|
||||||
15,
|
15,
|
||||||
Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat,
|
Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat,
|
||||||
|
@ -63,7 +62,6 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
|
||||||
if (this->strokePair.second == nullptr)
|
if (this->strokePair.second == nullptr)
|
||||||
{
|
{
|
||||||
auto materialMap = std::map<float, Renderer::Material>();
|
auto materialMap = std::map<float, Renderer::Material>();
|
||||||
materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f };
|
|
||||||
this->strokePair.second = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
|
this->strokePair.second = std::shared_ptr<Renderer::MaterialStyleStroke>(new Renderer::MaterialStyleStroke(
|
||||||
15,
|
15,
|
||||||
Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat,
|
Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat,
|
||||||
|
@ -108,6 +106,14 @@ QWidget* StrokeElementLayerStyle::getListDisplayWidget() const
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right)
|
||||||
|
{
|
||||||
|
this->strokePair.first = left;
|
||||||
|
this->strokePair.second = right ? right : std::dynamic_pointer_cast<MaterialStyleStroke>(
|
||||||
|
std::shared_ptr<Renderer::MaterialStyle>(std::move(left->clone()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
|
StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other)
|
||||||
{
|
{
|
||||||
strokePair.first = std::dynamic_pointer_cast<MaterialStyleStroke>(
|
strokePair.first = std::dynamic_pointer_cast<MaterialStyleStroke>(
|
||||||
|
@ -121,11 +127,12 @@ StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle&
|
||||||
|
|
||||||
QJsonObject StrokeElementLayerStyle::toJson() const
|
QJsonObject StrokeElementLayerStyle::toJson() const
|
||||||
{
|
{
|
||||||
|
// todo: Ð޸Ĵò¿ªÂß¼
|
||||||
QJsonObject json;
|
QJsonObject json;
|
||||||
json.insert("type", "stroke");
|
json["type"] = getTypeName();
|
||||||
json.insert("enableEachSideIndependent", enableEachSideIndependent);
|
json["enableEachSideIndependent"] = enableEachSideIndependent;
|
||||||
json.insert("left", EncodeUtil::toBase64<GLfloat>(strokePair.first->encoded()));
|
json["left"] = EncodeUtil::toBase64<GLfloat>(strokePair.first->encoded());
|
||||||
json.insert("right", EncodeUtil::toBase64<GLfloat>(strokePair.second->encoded()));
|
json["right"] = EncodeUtil::toBase64<GLfloat>(strokePair.second->encoded());
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,5 +191,26 @@ std::unique_ptr<LayerStyle> FillElementLayerStyle::clone() const
|
||||||
|
|
||||||
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
|
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
|
||||||
{
|
{
|
||||||
return std::unique_ptr<LayerStyle>();
|
QString type = json["type"].toString();
|
||||||
|
if (type == StrokeElementLayerStyle::getTypeName())
|
||||||
|
{
|
||||||
|
auto ptr = std::make_unique<StrokeElementLayerStyle>(
|
||||||
|
std::dynamic_pointer_cast<MaterialStyleStroke>(
|
||||||
|
std::shared_ptr<Renderer::MaterialStyle>(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["left"].toString()))))
|
||||||
|
),
|
||||||
|
std::dynamic_pointer_cast<MaterialStyleStroke>(
|
||||||
|
std::shared_ptr<Renderer::MaterialStyle>(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64<GLfloat>(json["right"].toString()))))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool();
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
else if (type == FillElementLayerStyle::getTypeName())
|
||||||
|
{
|
||||||
|
return std::make_unique<FillElementLayerStyle>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
using Renderer::MaterialStyle;
|
using Renderer::MaterialStyle;
|
||||||
using Renderer::MaterialStyleStroke;
|
using Renderer::MaterialStyleStroke;
|
||||||
|
|
||||||
|
#define STYLE_TYPENAME(name) static QString getTypeName() { return name; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法
|
* 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法
|
||||||
* 在进行Style的修改时,直接调用getInputWidget()方法
|
* 在进行Style的修改时,直接调用getInputWidget()方法
|
||||||
|
@ -36,17 +38,22 @@ public:
|
||||||
|
|
||||||
class StrokeElementLayerStyle : public LayerStyle
|
class StrokeElementLayerStyle : public LayerStyle
|
||||||
{
|
{
|
||||||
|
using PMaterialStyleStroke = std::shared_ptr<MaterialStyleStroke>;
|
||||||
private:
|
private:
|
||||||
std::pair<std::shared_ptr<MaterialStyleStroke>, std::shared_ptr<MaterialStyleStroke>> strokePair;
|
std::pair<PMaterialStyleStroke, PMaterialStyleStroke> strokePair;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
STYLE_TYPENAME("stroke")
|
||||||
|
|
||||||
|
StrokeElementLayerStyle() = default;
|
||||||
|
StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr);
|
||||||
|
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
||||||
|
~StrokeElementLayerStyle() = default;
|
||||||
|
|
||||||
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||||
QString getStyleName() const override;
|
QString getStyleName() const override;
|
||||||
QWidget* getInputWidget() override;
|
QWidget* getInputWidget() override;
|
||||||
QWidget* getListDisplayWidget() const override;
|
QWidget* getListDisplayWidget() const override;
|
||||||
StrokeElementLayerStyle() = default;
|
|
||||||
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
|
||||||
~StrokeElementLayerStyle() = default;
|
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
std::unique_ptr<LayerStyle> clone() const override;
|
||||||
|
|
||||||
|
@ -56,6 +63,7 @@ public:
|
||||||
class FillElementLayerStyle : public LayerStyle
|
class FillElementLayerStyle : public LayerStyle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
STYLE_TYPENAME("fill")
|
||||||
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
std::vector<Renderer::BaseStyle> toBaseStyles() const override;
|
||||||
QString getStyleName() const override;
|
QString getStyleName() const override;
|
||||||
QWidget* getInputWidget() override;
|
QWidget* getInputWidget() override;
|
||||||
|
|
|
@ -79,6 +79,11 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana
|
||||||
qDebug() << json.value("name").toString() << " " << this;
|
qDebug() << json.value("name").toString() << " " << this;
|
||||||
int elementIndex = json.value("element").toInt();
|
int elementIndex = json.value("element").toInt();
|
||||||
wrappedElement = elementManager->getElementById(elementIndex);
|
wrappedElement = elementManager->getElementById(elementIndex);
|
||||||
|
QJsonArray stylesArray = json.value("styles").toArray();
|
||||||
|
for (const auto& style : stylesArray)
|
||||||
|
{
|
||||||
|
styles.push_back(LayerStyle::fromJson(style.toObject()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerWrapper::SimpleProperty::apply(PixelPath&cache)
|
void LayerWrapper::SimpleProperty::apply(PixelPath&cache)
|
||||||
|
@ -255,12 +260,12 @@ int FolderLayerWrapper::getReferencedBy()const
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerWrapper::paint(QPainter* painter, QTransform transform)
|
void LayerWrapper::paint(QPainter* painter, QTransform transform, bool ignoreSelected)
|
||||||
{
|
{
|
||||||
if (this->selected)
|
if (!ignoreSelected && this->selected)
|
||||||
{
|
{
|
||||||
painter->save();
|
painter->save();
|
||||||
painter->setTransform(transform);
|
painter->setTransform(transform, ignoreSelected);
|
||||||
painter->setPen(QPen(Qt::gray, 2));
|
painter->setPen(QPen(Qt::gray, 2));
|
||||||
painter->setPen(Qt::DashLine);
|
painter->setPen(Qt::DashLine);
|
||||||
painter->drawRect(cache.getBoundingRect());
|
painter->drawRect(cache.getBoundingRect());
|
||||||
|
@ -268,18 +273,18 @@ void LayerWrapper::paint(QPainter* painter, QTransform transform)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FolderLayerWrapper::paint(QPainter* painter, QTransform transform)
|
void FolderLayerWrapper::paint(QPainter* painter, QTransform transform, bool ignoreSelected)
|
||||||
{
|
{
|
||||||
LayerWrapper::paint(painter, transform);
|
LayerWrapper::paint(painter, transform, ignoreSelected);
|
||||||
transform = property.transform * transform;
|
transform = property.transform * transform;
|
||||||
//qDebug() << transform;
|
//qDebug() << transform;
|
||||||
for (auto& child : children)
|
for (auto& child : children)
|
||||||
child->paint(painter, transform);
|
child->paint(painter, transform, ignoreSelected);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LeafLayerWrapper::paint(QPainter* painter, QTransform transform)
|
void LeafLayerWrapper::paint(QPainter* painter, QTransform transform, bool ignoreSelected)
|
||||||
{
|
{
|
||||||
LayerWrapper::paint(painter, transform);
|
LayerWrapper::paint(painter, transform, ignoreSelected);
|
||||||
transform = property.transform * transform;
|
transform = property.transform * transform;
|
||||||
//qDebug() << transform;
|
//qDebug() << transform;
|
||||||
if (wrappedElement != nullptr)
|
if (wrappedElement != nullptr)
|
||||||
|
|
|
@ -58,7 +58,7 @@ class LayerWrapper
|
||||||
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
|
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
|
||||||
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
|
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
|
||||||
LayerWrapper() = default;
|
LayerWrapper() = default;
|
||||||
virtual void paint(QPainter* painter, QTransform transform=QTransform());
|
virtual void paint(QPainter* painter, QTransform transform=QTransform(), bool ignoreSelected = false);
|
||||||
// TODO : export Function
|
// TODO : export Function
|
||||||
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
|
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
|
||||||
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
|
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
|
||||||
|
@ -91,7 +91,7 @@ class FolderLayerWrapper : public LayerWrapper
|
||||||
QTreeWidgetItem* getQTreeItem() override;
|
QTreeWidgetItem* getQTreeItem() override;
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
int getReferencedBy()const;
|
int getReferencedBy()const;
|
||||||
void paint(QPainter* painter, QTransform transform = QTransform()) override;
|
void paint(QPainter* painter, QTransform transform = QTransform(), bool ignoreSelected = false) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LeafLayerWrapper : public LayerWrapper
|
class LeafLayerWrapper : public LayerWrapper
|
||||||
|
@ -107,7 +107,7 @@ class LeafLayerWrapper : public LayerWrapper
|
||||||
LeafLayerWrapper() = default;
|
LeafLayerWrapper() = default;
|
||||||
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
||||||
QJsonObject toJson() const override;
|
QJsonObject toJson() const override;
|
||||||
void paint(QPainter* painter, QTransform transform = QTransform()) override;
|
void paint(QPainter* painter, QTransform transform = QTransform(), bool ignoreSelected = false) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(LayerWrapper *)
|
Q_DECLARE_METATYPE(LayerWrapper *)
|
||||||
|
|
|
@ -13,8 +13,8 @@ public:
|
||||||
QPainterPath painterPath;
|
QPainterPath painterPath;
|
||||||
int w,h;
|
int w,h;
|
||||||
public:
|
public:
|
||||||
PixelPath(int w=1024, int h= 1024);
|
PixelPath(int w=16, int h= 16);
|
||||||
PixelPath(QPainterPath painterPath,int w = 1024, int h = 1024);
|
PixelPath(QPainterPath painterPath,int w = 16, int h = 16);
|
||||||
~PixelPath() = default;
|
~PixelPath() = default;
|
||||||
QRectF getBoundingRect() const;
|
QRectF getBoundingRect() const;
|
||||||
QPixmap getPixmap() const;
|
QPixmap getPixmap() const;
|
||||||
|
|
|
@ -87,13 +87,22 @@ void PreviewWindow::mouseMoveEvent(QMouseEvent* event)
|
||||||
// 如果按下的是左键,那么平移图形
|
// 如果按下的是左键,那么平移图形
|
||||||
currentLayer->property.offset.setX(currentLayer->property.offset.x() + dx);
|
currentLayer->property.offset.setX(currentLayer->property.offset.x() + dx);
|
||||||
currentLayer->property.offset.setY(currentLayer->property.offset.y() + dy);
|
currentLayer->property.offset.setY(currentLayer->property.offset.y() + dy);
|
||||||
qDebug() << dx << "----" << dy;
|
|
||||||
}
|
}
|
||||||
else if (event->buttons() & Qt::RightButton) {
|
else if (event->buttons() & Qt::RightButton) {
|
||||||
// 如果按下的是右键,那么旋转图形
|
// 如果按下的是右键,那么旋转图形
|
||||||
qreal angle = dx;
|
qreal angle = dx;
|
||||||
currentLayer->property.rotation += angle;
|
currentLayer->property.rotation += angle;
|
||||||
}
|
}
|
||||||
|
auto layer = currentLayer;
|
||||||
|
while (layer != nullptr)
|
||||||
|
{
|
||||||
|
auto index = -1;
|
||||||
|
if (typeid(*layer) == typeid(FolderLayerWrapper))
|
||||||
|
index = dynamic_cast<FolderLayerWrapper*>(layer)->getReferencedBy();
|
||||||
|
if (index != -1)
|
||||||
|
emit refreshElementPreviewByIndex(index);
|
||||||
|
layer = layer->getParent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 更新上一次的位置
|
// 更新上一次的位置
|
||||||
m_lastPos = event->pos();
|
m_lastPos = event->pos();
|
||||||
|
|
|
@ -42,4 +42,6 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void layerInfoChanged();
|
void layerInfoChanged();
|
||||||
|
void refreshElementPreview(GraphicElement*);
|
||||||
|
void refreshElementPreviewByIndex(int);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace EncodeUtil
|
||||||
{
|
{
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
ba.resize(vec.size() * sizeof(S));
|
ba.resize(vec.size() * sizeof(S));
|
||||||
memcpy_s(ba.data(), ba.size(), vec.data(), vec.size());
|
memcpy_s(ba.data(), ba.size(), vec.data(), vec.size() * sizeof(S));
|
||||||
return ba.toBase64();
|
return ba.toBase64();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ vector<vector<Point>> PainterPathUtil::transformToLines(const QPainterPath& pai
|
||||||
for (int elementIndex = 0; elementIndex < painterPath.elementCount(); elementIndex++) {
|
for (int elementIndex = 0; elementIndex < painterPath.elementCount(); elementIndex++) {
|
||||||
auto element = painterPath.elementAt(elementIndex);
|
auto element = painterPath.elementAt(elementIndex);
|
||||||
point = element;
|
point = element;
|
||||||
qDebug() << element;
|
//qDebug() << element;
|
||||||
if (element.isMoveTo()) {
|
if (element.isMoveTo()) {
|
||||||
if (line.size() >= 2) {
|
if (line.size() >= 2) {
|
||||||
lines.push_back(line);
|
lines.push_back(line);
|
||||||
|
@ -43,7 +43,7 @@ vector<vector<Point>> PainterPathUtil::transformToLines(const QPainterPath& pai
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainterPath PainterPathUtil::monotonization(QPainterPath& painterPath) {
|
QPainterPath PainterPathUtil::monotonization(const QPainterPath& painterPath) {
|
||||||
QPainterPath resPath;
|
QPainterPath resPath;
|
||||||
vector<vector<Point> > lines = transformToLines(painterPath);
|
vector<vector<Point> > lines = transformToLines(painterPath);
|
||||||
vector<shared_ptr<Line>> linePtrVector;
|
vector<shared_ptr<Line>> linePtrVector;
|
||||||
|
|
|
@ -7,7 +7,7 @@ class PainterPathUtil
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::vector<std::vector<Renderer::Point>> transformToLines(const QPainterPath& painterPath);
|
static std::vector<std::vector<Renderer::Point>> transformToLines(const QPainterPath& painterPath);
|
||||||
static QPainterPath monotonization(QPainterPath& painterPath);
|
static QPainterPath monotonization(const QPainterPath& painterPath);
|
||||||
static std::pair<QPainterPath, float> normalized(const QPainterPath& path, float width = 0);
|
static std::pair<QPainterPath, float> normalized(const QPainterPath& path, float width = 0);
|
||||||
static std::pair<std::vector<std::vector<Renderer::Point>>, float> toNormalizedLines(const QPainterPath& path, float width = 0);
|
static std::pair<std::vector<std::vector<Renderer::Point>>, float> toNormalizedLines(const QPainterPath& path, float width = 0);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,43 @@
|
||||||
#include "BaseStyle.h"
|
#include "BaseStyle.h"
|
||||||
|
#include "MaterialStyleFill.h"
|
||||||
|
#include "MaterialStyleStroke.h"
|
||||||
|
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
Renderer::Material::Material(const QColor& color, float metallic, float roughness)
|
||||||
|
: color(color)
|
||||||
|
{
|
||||||
|
setMetallicF(metallic);
|
||||||
|
setRoughnessF(roughness);
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::Material::Material(const glm::vec4& color, const glm::vec2& metallicRoughness)
|
||||||
|
: color(QColor::fromRgbF(color.r, color.g, color.b, color.a))
|
||||||
|
{
|
||||||
|
setMetallicF(metallicRoughness.r);
|
||||||
|
setRoughnessF(metallicRoughness.g);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::Material::metallicF() const
|
||||||
|
{
|
||||||
|
return metallic / 255.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Renderer::Material::roughnessF() const
|
||||||
|
{
|
||||||
|
return roughness / 255.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::Material::setMetallicF(float metallic)
|
||||||
|
{
|
||||||
|
this->metallic = metallic * 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::Material::setRoughnessF(float roughness)
|
||||||
|
{
|
||||||
|
this->roughness = roughness * 255;
|
||||||
|
}
|
||||||
|
|
||||||
bool Renderer::Material::operator==(const Material& m) const
|
bool Renderer::Material::operator==(const Material& m) const
|
||||||
{
|
{
|
||||||
|
@ -9,5 +46,52 @@ bool Renderer::Material::operator==(const Material& m) const
|
||||||
|
|
||||||
std::pair<glm::vec4, glm::vec2> Renderer::Material::toVec() const
|
std::pair<glm::vec4, glm::vec2> Renderer::Material::toVec() const
|
||||||
{
|
{
|
||||||
return { glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()), glm::vec2(metallic, roughness)};
|
return { glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF()), glm::vec2(metallicF(), roughnessF())};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<MaterialStyle> Renderer::MaterialStyle::decoded(const std::vector<GLfloat>& encoded)
|
||||||
|
{
|
||||||
|
if (encoded[0] <= 0) /// MaterialStyleFill
|
||||||
|
{
|
||||||
|
std::unique_ptr<MaterialFill> materiallFill;
|
||||||
|
glm::vec4 head = glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[0]));
|
||||||
|
if (head.z == 0)
|
||||||
|
{
|
||||||
|
materiallFill = std::make_unique<FillPlain>(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[1])), glm::vec2(head.r, head.g)));
|
||||||
|
}
|
||||||
|
return std::make_unique<MaterialStyleFill>(std::move(materiallFill));
|
||||||
|
}
|
||||||
|
else /// MaterialStyleStroke
|
||||||
|
{
|
||||||
|
std::unique_ptr<MaterialStroke> materialStroke;
|
||||||
|
uint headUint = floatBitsToUint(encoded[1]);
|
||||||
|
vec4 head = unpackUnorm4x8(headUint);
|
||||||
|
StrokeType strokeType = (StrokeType)floor(head.b * 10);
|
||||||
|
StrokeEndType endType = (StrokeEndType)(int(round(head.b * 100)) % 10);
|
||||||
|
switch (int(head.a * 100) % 10)
|
||||||
|
{
|
||||||
|
/// Plain
|
||||||
|
case 0: {
|
||||||
|
materialStroke = std::make_unique<StrokePlain>(Material(glm::unpackUnorm4x8(glm::floatBitsToUint(encoded[2])), glm::vec2(head.r, head.g)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/// RadialGradient
|
||||||
|
case 1: {
|
||||||
|
uint size = headUint % (1 << 15);
|
||||||
|
bool gradual = (headUint & (1 << 15)) != 0;
|
||||||
|
std::map<float, Material> materialMap;
|
||||||
|
for (uint i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
auto data = floatBitsToUint(encoded[2 + i * 2]);
|
||||||
|
auto level = unpackUnorm2x16(data).y;
|
||||||
|
auto color = unpackUnorm4x8(floatBitsToUint(encoded[3 + i * 2]));
|
||||||
|
auto metallicRoughness = unpackUnorm4x8(data);
|
||||||
|
materialMap.emplace(level, Material(color, glm::vec2(metallicRoughness.r, metallicRoughness.g)));
|
||||||
|
}
|
||||||
|
materialStroke = std::make_unique<StrokeRadialGradient>(materialMap, gradual);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::make_unique<MaterialStyleStroke>(encoded[0], strokeType, endType, std::move(materialStroke));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ namespace Renderer
|
||||||
virtual std::vector<GLfloat> encoded() const = 0;
|
virtual std::vector<GLfloat> encoded() const = 0;
|
||||||
virtual std::unique_ptr<MaterialStyle> clone() const = 0;
|
virtual std::unique_ptr<MaterialStyle> clone() const = 0;
|
||||||
virtual bool operator==(const MaterialStyle&) const = 0;
|
virtual bool operator==(const MaterialStyle&) const = 0;
|
||||||
|
static std::unique_ptr<MaterialStyle> decoded(const std::vector<GLfloat>& encoded);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BaseStyle
|
struct BaseStyle
|
||||||
|
@ -36,8 +37,16 @@ namespace Renderer
|
||||||
struct Material
|
struct Material
|
||||||
{
|
{
|
||||||
QColor color;
|
QColor color;
|
||||||
float metallic;
|
std::uint8_t metallic;
|
||||||
float roughness;
|
std::uint8_t roughness;
|
||||||
|
|
||||||
|
Material() = default;
|
||||||
|
Material(const QColor& color, float metallic = 0, float roughness = 0.5);
|
||||||
|
Material(const glm::vec4& color, const glm::vec2& metallicRoughness);
|
||||||
|
float metallicF() const;
|
||||||
|
float roughnessF() const;
|
||||||
|
void setMetallicF(float metallic);
|
||||||
|
void setRoughnessF(float roughness);
|
||||||
bool operator==(const Material&) const;
|
bool operator==(const Material&) const;
|
||||||
std::pair<glm::vec4, glm::vec2> toVec() const;
|
std::pair<glm::vec4, glm::vec2> toVec() const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,7 +3,12 @@
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
|
||||||
Renderer::FillPlain::FillPlain(QColor color, float metallic, float roughness)
|
Renderer::FillPlain::FillPlain(QColor color, float metallic, float roughness)
|
||||||
: color(color), metallic(metallic), roughness(roughness)
|
: material(color, metallic, roughness)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer::FillPlain::FillPlain(const Material& material)
|
||||||
|
: material(material)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +19,9 @@ MaterialFillType Renderer::FillPlain::type() const
|
||||||
|
|
||||||
std::vector<GLfloat> Renderer::FillPlain::encoded() const
|
std::vector<GLfloat> Renderer::FillPlain::encoded() const
|
||||||
{
|
{
|
||||||
return { glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(metallic, roughness, 0, 1))),
|
auto pair = material.toVec();
|
||||||
glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(color.redF(), color.greenF(), color.blueF(), color.alphaF())))};
|
return { glm::uintBitsToFloat(glm::packUnorm4x8(glm::vec4(pair.second, 0, 1))),
|
||||||
|
glm::uintBitsToFloat(glm::packUnorm4x8(pair.first))};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
||||||
|
@ -26,9 +32,7 @@ std::unique_ptr<MaterialFill> Renderer::FillPlain::clone() const
|
||||||
bool Renderer::FillPlain::operator==(const MaterialFill& m) const
|
bool Renderer::FillPlain::operator==(const MaterialFill& m) const
|
||||||
{
|
{
|
||||||
return type() == m.type()
|
return type() == m.type()
|
||||||
&& color == static_cast<const FillPlain&>(m).color
|
&& material == static_cast<const FillPlain&>(m).material;
|
||||||
&& metallic == static_cast<const FillPlain&>(m).metallic
|
|
||||||
&& roughness == static_cast<const FillPlain&>(m).roughness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,14 +18,13 @@ namespace Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FillPlain(QColor color, float metallic, float roughness);
|
FillPlain(QColor color, float metallic, float roughness);
|
||||||
|
FillPlain(const Material& material);
|
||||||
virtual MaterialFillType type() const override;
|
virtual MaterialFillType type() const override;
|
||||||
virtual std::vector<GLfloat> encoded() const override;
|
virtual std::vector<GLfloat> encoded() const override;
|
||||||
virtual std::unique_ptr<MaterialFill> clone() const override;
|
virtual std::unique_ptr<MaterialFill> clone() const override;
|
||||||
virtual bool operator==(const MaterialFill&) const override;
|
virtual bool operator==(const MaterialFill&) const override;
|
||||||
|
|
||||||
QColor color;
|
Material material;
|
||||||
float metallic;
|
|
||||||
float roughness;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MaterialStyleFill : public MaterialStyle
|
class MaterialStyleFill : public MaterialStyle
|
||||||
|
|
|
@ -59,7 +59,7 @@ std::vector<GLfloat> Renderer::StrokeRadialGradient::encoded() const
|
||||||
v.y = pair.first;
|
v.y = pair.first;
|
||||||
result.push_back(glm::uintBitsToFloat(glm::packUnorm2x16(v)));
|
result.push_back(glm::uintBitsToFloat(glm::packUnorm2x16(v)));
|
||||||
result.push_back(glm::uintBitsToFloat(glm::packUnorm4x8(color)));
|
result.push_back(glm::uintBitsToFloat(glm::packUnorm4x8(color)));
|
||||||
qDebug() << pair.first;
|
//qDebug() << pair.first;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,8 @@ bool Renderer::StrokeRadialGradient::operator==(const MaterialStroke& m) const
|
||||||
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
|
&& materialMap == static_cast<const StrokeRadialGradient&>(m).materialMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer::MaterialStyleStroke::MaterialStyleStroke(float width, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke)
|
Renderer::MaterialStyleStroke::MaterialStyleStroke(float halfWidth, StrokeType strokeType, StrokeEndType endType, std::shared_ptr<MaterialStroke> materialStroke)
|
||||||
: halfWidth(width/2), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
|
: halfWidth(halfWidth), strokeType(strokeType), endType(endType), materialStroke(materialStroke)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ std::vector<GLfloat> Renderer::MaterialStyleStroke::encoded() const
|
||||||
|
|
||||||
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
|
std::unique_ptr<MaterialStyle> Renderer::MaterialStyleStroke::clone() const
|
||||||
{
|
{
|
||||||
return std::make_unique<MaterialStyleStroke>(halfWidth*2, strokeType, endType, materialStroke->clone());
|
return std::make_unique<MaterialStyleStroke>(halfWidth, strokeType, endType, materialStroke->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "../Painting/Element.h"
|
#include "../Painting/Element.h"
|
||||||
#include "../Painting/Painting.h"
|
#include "../Painting/Painting.h"
|
||||||
#include "../Painting/MaterialStyleStroke.h"
|
#include "../Painting/MaterialStyleStroke.h"
|
||||||
|
#include <util/PainterPathUtil.h>
|
||||||
using namespace Renderer;
|
using namespace Renderer;
|
||||||
|
|
||||||
std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
std::vector<glm::vec2> generatePathBuffer(const QPainterPath& path)
|
||||||
|
@ -78,7 +79,7 @@ std::vector<GLfloat> generateStyleBuffer(const std::vector<BaseStyle>& styles)
|
||||||
|
|
||||||
auto encoded = style.material->encoded();
|
auto encoded = style.material->encoded();
|
||||||
styleBuffer.insert(styleBuffer.end(), encoded.begin(), encoded.end());
|
styleBuffer.insert(styleBuffer.end(), encoded.begin(), encoded.end());
|
||||||
qDebug() << "style size" << styleBuffer.size();
|
//qDebug() << "style size" << styleBuffer.size();
|
||||||
}
|
}
|
||||||
return styleBuffer;
|
return styleBuffer;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +200,8 @@ std::pair<QImage, QPointF> Renderer::ElementRenderer::drawElement(const QPainter
|
||||||
std::unique_lock<std::mutex> lock(drawMutex);
|
std::unique_lock<std::mutex> lock(drawMutex);
|
||||||
draw.wait(lock, [&] {return drawFinished; });
|
draw.wait(lock, [&] {return drawFinished; });
|
||||||
drawFinished = false;
|
drawFinished = false;
|
||||||
this->path = &path;
|
QPainterPath monotonized = PainterPathUtil::monotonization(path);
|
||||||
|
this->path = &monotonized;
|
||||||
this->style = &style;
|
this->style = &style;
|
||||||
this->pixelRatio = pixelRatio;
|
this->pixelRatio = pixelRatio;
|
||||||
needDraw = true;
|
needDraw = true;
|
||||||
|
|
|
@ -49,6 +49,7 @@ int main(int argc, char* argv[])
|
||||||
//QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
//QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
Q_INIT_RESOURCE(resources);
|
||||||
//FramelessHelper::Core::setApplicationOSThemeAware();
|
//FramelessHelper::Core::setApplicationOSThemeAware();
|
||||||
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
|
FramelessConfig::instance()->set(Global::Option::ForceNonNativeBackgroundBlur);
|
||||||
//FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
//FramelessConfig::instance()->set(Global::Option::EnableBlurBehindWindow);
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -61,7 +61,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kFlat,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kFlat,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -82,7 +82,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kLeftSide, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kLeftSide, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -103,7 +103,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kLeftSide, StrokeEndType::kFlat,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kLeftSide, StrokeEndType::kFlat,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -124,7 +124,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(160, StrokeType::kRightSide, StrokeEndType::kFlatRound,
|
std::make_shared<MaterialStyleStroke>(80, StrokeType::kRightSide, StrokeEndType::kFlatRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -149,7 +149,7 @@ namespace UnitTest
|
||||||
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||||
{
|
{
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokePlain>(QColor(255,255,255),1,1))) };
|
std::make_shared<StrokePlain>(QColor(255,255,255),1,1))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
@ -170,7 +170,7 @@ namespace UnitTest
|
||||||
{1.00, Material{QColor(58,64,151)}}
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
};
|
};
|
||||||
return { BaseStyle(std::make_shared<TransformStyle>(),
|
return { BaseStyle(std::make_shared<TransformStyle>(),
|
||||||
std::make_shared<MaterialStyleStroke>(60, StrokeType::kBothSides, StrokeEndType::kRound,
|
std::make_shared<MaterialStyleStroke>(30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
}
|
}
|
||||||
} style;
|
} style;
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include <QGuiApplication>
|
||||||
|
#include <QtWidgets/QApplication>
|
||||||
|
#include "Renderer/Painting/ElementStyle.h"
|
||||||
|
#include <Renderer/Painting/MaterialStyleStroke.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
using namespace Renderer;
|
||||||
|
|
||||||
|
namespace UnitTest
|
||||||
|
{
|
||||||
|
TEST_CLASS(StyleTest)
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TEST_METHOD(TestEncodeDecode)
|
||||||
|
{
|
||||||
|
std::map<float, Material> materialMap = {
|
||||||
|
{0.20, Material{QColor(255,255,255)}},
|
||||||
|
{0.60, Material{QColor(165,176,207)}},
|
||||||
|
{1.00, Material{QColor(58,64,151)}}
|
||||||
|
};
|
||||||
|
auto style = std::make_unique<MaterialStyleStroke>(
|
||||||
|
30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokeRadialGradient>(materialMap, false)
|
||||||
|
);
|
||||||
|
/* auto style = std::make_shared<MaterialStyleStroke>(
|
||||||
|
30, StrokeType::kBothSides, StrokeEndType::kRound,
|
||||||
|
std::make_shared<StrokePlain>(Material(QColor(255, 255, 255)))
|
||||||
|
);*/
|
||||||
|
std::shared_ptr<MaterialStyle> decoded = MaterialStyle::decoded(style->encoded());
|
||||||
|
/* Assert::IsTrue(decoded->type() == MaterialStyleType::kStroke);
|
||||||
|
Assert::IsTrue(std::static_pointer_cast<MaterialStyleStroke>(decoded)->halfWidth == 30);
|
||||||
|
Assert::IsTrue(std::static_pointer_cast<MaterialStyleStroke>(decoded)->strokeType == StrokeType::kBothSides);
|
||||||
|
Assert::IsTrue(std::static_pointer_cast<MaterialStyleStroke>(decoded)->endType == StrokeEndType::kRound);
|
||||||
|
std::shared_ptr<MaterialStroke> materialStroke = std::static_pointer_cast<MaterialStyleStroke>(decoded)->materialStroke;
|
||||||
|
Assert::IsTrue(materialStroke->type() == MaterialStrokeType::kPlain);
|
||||||
|
Material material = std::static_pointer_cast<StrokePlain>(materialStroke)->material;
|
||||||
|
Assert::IsTrue(material == Material(QColor(255, 255, 255)));
|
||||||
|
Logger::WriteMessage(std::format("({} {} {} {}), ({} {})\n",
|
||||||
|
material.color.red(),
|
||||||
|
material.color.green(),
|
||||||
|
material.color.blue(),
|
||||||
|
material.color.alpha(),
|
||||||
|
material.metallic,
|
||||||
|
material.roughness
|
||||||
|
).c_str());*/
|
||||||
|
|
||||||
|
|
||||||
|
Assert::IsTrue(*style == *decoded);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -117,6 +117,7 @@
|
||||||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
||||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="StyleTest.cpp" />
|
||||||
<ClCompile Include="UnitTest.cpp" />
|
<ClCompile Include="UnitTest.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -48,5 +48,8 @@
|
||||||
<ClCompile Include="PaintingTest.cpp">
|
<ClCompile Include="PaintingTest.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="StyleTest.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue