Merge branch 'main' of http://101.34.228.45:3000/BigC/ArchitectureColoredPainting
commit
6d554ab265
|
@ -153,7 +153,7 @@
|
||||||
<ClCompile Include="src\Renderer\Painting\StraightLine.cpp" />
|
<ClCompile Include="src\Renderer\Painting\StraightLine.cpp" />
|
||||||
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp" />
|
<ClCompile Include="src\Renderer\VirtualTextureManager.cpp" />
|
||||||
<ClCompile Include="src\SvgParser.cpp" />
|
<ClCompile Include="src\SvgParser.cpp" />
|
||||||
<ClCompile Include="src\Editor\EditorWidgetComponent\StrokeStyleListView.cpp" />
|
<ClCompile Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.cpp" />
|
||||||
<QtUic Include="EditorWidget.ui" />
|
<QtUic Include="EditorWidget.ui" />
|
||||||
<QtUic Include="EditorWidgetItem.ui" />
|
<QtUic Include="EditorWidgetItem.ui" />
|
||||||
<QtUic Include="MainWindow.ui" />
|
<QtUic Include="MainWindow.ui" />
|
||||||
|
@ -189,7 +189,7 @@
|
||||||
<None Include="res\Shaders\ssgi.comp" />
|
<None Include="res\Shaders\ssgi.comp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtMoc Include="src\Editor\EditorWidgetComponent\StrokeStyleListView.h" />
|
<QtMoc Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.h" />
|
||||||
<QtMoc Include="src\Editor\RightBar\LayerTreeWidget.h" />
|
<QtMoc Include="src\Editor\RightBar\LayerTreeWidget.h" />
|
||||||
<QtMoc Include="src\Editor\RightBar\InfoDisplayWidget.h" />
|
<QtMoc Include="src\Editor\RightBar\InfoDisplayWidget.h" />
|
||||||
<QtMoc Include="src\MainWindow.h" />
|
<QtMoc Include="src\MainWindow.h" />
|
||||||
|
@ -197,6 +197,7 @@
|
||||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" />
|
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerCreateWidget.h" />
|
||||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" />
|
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h" />
|
||||||
<QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h" />
|
<QtMoc Include="src\Editor\EditorWidgetComponent\ColorPicker.h" />
|
||||||
|
<ClInclude Include="src\Editor\util\JsonUtil.hpp" />
|
||||||
<ClInclude Include="src\Editor\ElementManager.h" />
|
<ClInclude Include="src\Editor\ElementManager.h" />
|
||||||
<QtMoc Include="src\Editor\ElementPoolWidget.h" />
|
<QtMoc Include="src\Editor\ElementPoolWidget.h" />
|
||||||
<ClInclude Include="src\Editor\GraphicElement.h" />
|
<ClInclude Include="src\Editor\GraphicElement.h" />
|
||||||
|
|
|
@ -216,7 +216,7 @@
|
||||||
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.cpp">
|
<ClCompile Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.cpp">
|
||||||
<Filter>Source Files\Editor\Style</Filter>
|
<Filter>Source Files\Editor\Style</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\Editor\EditorWidgetComponent\StrokeStyleListView.cpp">
|
<ClCompile Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.cpp">
|
||||||
<Filter>Source Files\Editor\Style</Filter>
|
<Filter>Source Files\Editor\Style</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\Editor\RightBar\InfoDisplayWidget.cpp">
|
<ClCompile Include="src\Editor\RightBar\InfoDisplayWidget.cpp">
|
||||||
|
@ -254,7 +254,7 @@
|
||||||
<QtMoc Include="src\FluentMenu.h">
|
<QtMoc Include="src\FluentMenu.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
<QtMoc Include="src\Editor\EditorWidgetComponent\StrokeStyleListView.h">
|
<QtMoc Include="src\Editor\EditorWidgetComponent\StrokeStyleWidget.h">
|
||||||
<Filter>Header Files\Editor\Style</Filter>
|
<Filter>Header Files\Editor\Style</Filter>
|
||||||
</QtMoc>
|
</QtMoc>
|
||||||
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h">
|
<QtMoc Include="src\Editor\EditorWidgetComponent\LayerStyleDialog.h">
|
||||||
|
@ -477,6 +477,9 @@
|
||||||
<ClInclude Include="src\Editor\LayerStyle.h">
|
<ClInclude Include="src\Editor\LayerStyle.h">
|
||||||
<Filter>Header Files\Editor\Style</Filter>
|
<Filter>Header Files\Editor\Style</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\Editor\util\JsonUtil.hpp">
|
||||||
|
<Filter>Header Files\Editor\util</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<QtRcc Include="res\MainWindow.qrc">
|
<QtRcc Include="res\MainWindow.qrc">
|
||||||
|
|
|
@ -1149,7 +1149,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
p[2] *= ratio;
|
p[2] *= ratio;
|
||||||
p[3] *= ratio;
|
p[3] *= ratio;
|
||||||
|
|
||||||
vec2 tangentBeginNext;
|
vec2 tangentBeginNext = vec2(0);
|
||||||
if (contourIterator + 1 < contourIndex + 1 + lineCount)
|
if (contourIterator + 1 < contourIndex + 1 + lineCount)
|
||||||
{
|
{
|
||||||
uint lineIndex = elementIndexs[contourIterator + 1];
|
uint lineIndex = elementIndexs[contourIterator + 1];
|
||||||
|
@ -1217,10 +1217,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point
|
||||||
bool hit = d < minDistance;
|
bool hit = d < minDistance;
|
||||||
if (onBegin)
|
if (onBegin)
|
||||||
hit =
|
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)
|
if (onEnd)
|
||||||
hit = hit &&
|
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)
|
if (hit)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -36,11 +36,6 @@ void main()
|
||||||
lod++;
|
lod++;
|
||||||
gMetallicRoughness = mt.rg;
|
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);
|
uint w = 1<<(levels-1-lodExpect);
|
||||||
ivec2 page = ivec2(TexCoords * vec2(w));
|
ivec2 page = ivec2(TexCoords * vec2(w));
|
||||||
page = clamp(page, ivec2(0), ivec2(w-1));
|
page = clamp(page, ivec2(0), ivec2(w-1));
|
||||||
|
@ -49,7 +44,6 @@ void main()
|
||||||
gPaintingIndex = uvec2(0);
|
gPaintingIndex = uvec2(0);
|
||||||
else
|
else
|
||||||
gPaintingIndex = uvec2((paintingId<<4)+lodExpect, (page.y<<8)+page.x);
|
gPaintingIndex = uvec2((paintingId<<4)+lodExpect, (page.y<<8)+page.x);
|
||||||
gPaintingTexCoord = vec2(1., 1.) - TexCoords * 2;
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
|
@ -14,7 +14,6 @@ uniform mat4 projection;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
TexCoords = aTexCoords;
|
TexCoords = aTexCoords;
|
||||||
TexCoords.y = -TexCoords.y;
|
|
||||||
WorldPos = vec3(model * vec4(aPos, 1.0));
|
WorldPos = vec3(model * vec4(aPos, 1.0));
|
||||||
Normal = mat3(model) * aNormal;
|
Normal = mat3(model) * aNormal;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
#include "StrokeStyleWidget.h"
|
||||||
|
#include "ColorPicker.h"
|
||||||
|
#include <qtmaterialraisedbutton.h>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#define radialStroke(stroke) std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(stroke->materialStroke)
|
||||||
|
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;
|
||||||
|
|
||||||
|
// FIXME: Material的控件有显示bug
|
||||||
|
StrokeStyleWidget::StrokeStyleWidget(
|
||||||
|
std::shared_ptr<Renderer::MaterialStyleStroke> stroke,
|
||||||
|
QWidget* parent
|
||||||
|
) : QWidget(parent), stroke(stroke)
|
||||||
|
{
|
||||||
|
QVBoxLayout* viewLayout = new QVBoxLayout(this);
|
||||||
|
this->setLayout(viewLayout);
|
||||||
|
|
||||||
|
initStrokeSettings();
|
||||||
|
QWidget* strokeProperties = new QWidget(this);
|
||||||
|
QHBoxLayout* strokePropertiesLayout = new QHBoxLayout(strokeProperties);
|
||||||
|
strokePropertiesLayout->setMargin(0);
|
||||||
|
|
||||||
|
strokeProperties->setLayout(strokePropertiesLayout);
|
||||||
|
strokePropertiesLayout->addWidget(enableGradual);
|
||||||
|
strokePropertiesLayout->addWidget(endTypeBox);
|
||||||
|
|
||||||
|
viewLayout->addWidget(strokeProperties);
|
||||||
|
viewLayout->addWidget(widthField);
|
||||||
|
|
||||||
|
initTable(std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(stroke->materialStroke));
|
||||||
|
viewLayout->addWidget(strokeTable);
|
||||||
|
this->adjustSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StrokeStyleWidget::initStrokeSettings()
|
||||||
|
{
|
||||||
|
this->enableGradual = new QtMaterialCheckBox(this);
|
||||||
|
enableGradual->setText(QStringLiteral("启用渐变"));
|
||||||
|
enableGradual->setChecked(radialStroke(stroke)->gradual);
|
||||||
|
connect(enableGradual, &QtMaterialCheckBox::toggled, [this](bool checked) {
|
||||||
|
radialStroke(this->stroke)->gradual = checked;
|
||||||
|
});
|
||||||
|
|
||||||
|
#define endTypeBoxLabel(start, end) QStringLiteral(start##" -> "##end)
|
||||||
|
this->endTypeBox = new QComboBox(this);
|
||||||
|
endTypeBox->addItem(endTypeBoxLabel("圆头", "圆头")); // kRound
|
||||||
|
endTypeBox->addItem(endTypeBoxLabel("平头", "圆头")); // kFlatRound
|
||||||
|
endTypeBox->addItem(endTypeBoxLabel("圆头", "平头")); // kRoundFlat
|
||||||
|
endTypeBox->addItem(endTypeBoxLabel("平头", "平头")); // kFlat
|
||||||
|
endTypeBox->setCurrentIndex(static_cast<int>(this->stroke->endType));
|
||||||
|
connect(endTypeBox, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
this->stroke->endType = Renderer::StrokeEndType::kRound;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this->stroke->endType = Renderer::StrokeEndType::kFlatRound;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
this->stroke->endType = Renderer::StrokeEndType::kRoundFlat;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
this->stroke->endType = Renderer::StrokeEndType::kFlat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this->widthField = new QtMaterialTextField(this);
|
||||||
|
widthField->setLabel(QStringLiteral("本侧描边宽度"));
|
||||||
|
widthField->setText(QString::number(stroke->halfWidth));
|
||||||
|
QDoubleValidator* widthValidator = new QDoubleValidator(0.1, std::numeric_limits<float>::max(), 3, widthField);
|
||||||
|
widthValidator->setNotation(QDoubleValidator::StandardNotation);
|
||||||
|
widthField->setValidator(widthValidator);
|
||||||
|
connect(widthField, &QtMaterialTextField::textChanged, [this](const QString& changed) {
|
||||||
|
if (this->widthField->hasAcceptableInput())
|
||||||
|
{
|
||||||
|
this->stroke->halfWidth = changed.toFloat();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 新增时参数校验
|
||||||
|
void StrokeStyleWidget::initTable(std::shared_ptr<Renderer::StrokeRadialGradient> materialStroke)
|
||||||
|
{
|
||||||
|
this->strokeTable = new QTableWidget(this);
|
||||||
|
strokeTable->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContentsOnFirstShow);
|
||||||
|
strokeTable->setColumnCount(5);
|
||||||
|
strokeTable->setRowCount(materialStroke->materialMap.size() + 1);
|
||||||
|
QStringList headers;
|
||||||
|
headers << QStringLiteral("离心距离占比")
|
||||||
|
<< QStringLiteral("颜色")
|
||||||
|
<< QStringLiteral("金属度")
|
||||||
|
<< QStringLiteral("粗糙度")
|
||||||
|
<< QStringLiteral("其他操作");
|
||||||
|
strokeTable->setHorizontalHeaderLabels(headers);
|
||||||
|
int row = 0;
|
||||||
|
// 内容
|
||||||
|
for (auto & strokePair : materialStroke->materialMap)
|
||||||
|
{
|
||||||
|
setTableRow(row, strokePair.first, strokePair.second);
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
// 新增按钮
|
||||||
|
QtMaterialRaisedButton* addButton = new QtMaterialRaisedButton("+", strokeTable);
|
||||||
|
strokeTable->setSpan(row, 0, 1, 5);
|
||||||
|
strokeTable->setCellWidget(row, 0, addButton);
|
||||||
|
connect(addButton, &QtMaterialRaisedButton::clicked, [this]() {
|
||||||
|
handlingRowInsert = true;
|
||||||
|
auto materialMap = &(radialStroke(this->stroke)->materialMap);
|
||||||
|
float newWidth = 0;
|
||||||
|
if (materialMap->size() == 0)
|
||||||
|
{
|
||||||
|
newWidth = 0.1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto lastPair = materialMap->rbegin();
|
||||||
|
newWidth = lastPair->first + 0.01;
|
||||||
|
}
|
||||||
|
Renderer::Material newMaterial = { QColor::fromRgb(0,0,0), 0.f, .8f };
|
||||||
|
(*materialMap)[newWidth] = newMaterial;
|
||||||
|
int newRow = this->strokeTable->rowCount() - 1;
|
||||||
|
this->strokeTable->insertRow(newRow);
|
||||||
|
setTableRow(newRow, newWidth, (*materialMap)[newWidth]);
|
||||||
|
this->strokeTable->update();
|
||||||
|
handlingRowInsert = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onCurrentItemChanged);
|
||||||
|
connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onCellChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& material)
|
||||||
|
{
|
||||||
|
QTableWidgetItem* widthItem = new QTableWidgetItem;
|
||||||
|
widthItem->setData(Qt::EditRole, width);
|
||||||
|
strokeTable->setItem(row, COLUMN_WIDTH, widthItem);
|
||||||
|
|
||||||
|
QColor* colorPtr = &(material.color);
|
||||||
|
QTableWidgetItem* colorItem = new QTableWidgetItem;
|
||||||
|
colorItem->setData(Qt::DisplayRole, *colorPtr);
|
||||||
|
strokeTable->setItem(row, COLUMN_COLOR, colorItem);
|
||||||
|
ColorPicker* colorPicker = new ColorPicker(*colorPtr, strokeTable);
|
||||||
|
strokeTable->setCellWidget(row, COLUMN_COLOR, colorPicker);
|
||||||
|
connect(colorPicker, &ColorPicker::colorChanged, [this, colorPtr](QColor color) {
|
||||||
|
*colorPtr = color;
|
||||||
|
this->strokeTable->update();
|
||||||
|
});
|
||||||
|
|
||||||
|
QTableWidgetItem* metallicItem = new QTableWidgetItem;
|
||||||
|
metallicItem->setData(Qt::EditRole, material.metallic);
|
||||||
|
strokeTable->setItem(row, COLUMN_METALLIC, metallicItem);
|
||||||
|
|
||||||
|
QTableWidgetItem* roughnessItem = new QTableWidgetItem;
|
||||||
|
roughnessItem->setData(Qt::EditRole, material.roughness);
|
||||||
|
strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem);
|
||||||
|
|
||||||
|
QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable);
|
||||||
|
removeButton->setFixedSize(20, 20);
|
||||||
|
strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton);
|
||||||
|
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());
|
||||||
|
this->strokeTable->removeRow(row);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void StrokeStyleWidget::onCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous)
|
||||||
|
{
|
||||||
|
if (!current) return;
|
||||||
|
int column = current->column();
|
||||||
|
if (column != COLUMN_COLOR && column != COLUMN_OPERATIONS)
|
||||||
|
{
|
||||||
|
this->currentItemValue = current->data(Qt::EditRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void StrokeStyleWidget::onCellChanged(int row, int column)
|
||||||
|
{
|
||||||
|
if (handlingRowInsert) return;
|
||||||
|
auto changedItem = strokeTable->item(row, column);
|
||||||
|
auto changedItemValue = changedItem->text().toFloat();
|
||||||
|
if (changedItemValue < 0 || 1 < changedItemValue)
|
||||||
|
{
|
||||||
|
changedItem->setData(Qt::EditRole, this->currentItemValue.toFloat());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto changedWidth = strokeTable->item(row, COLUMN_WIDTH)->data(Qt::EditRole).toFloat();
|
||||||
|
switch (column)
|
||||||
|
{
|
||||||
|
case COLUMN_WIDTH:
|
||||||
|
{
|
||||||
|
float oldWidth = this->currentItemValue.toFloat();
|
||||||
|
auto node = radialStroke(stroke)->materialMap.extract(oldWidth);
|
||||||
|
node.key() = changedWidth;
|
||||||
|
radialStroke(stroke)->materialMap.insert(std::move(node));
|
||||||
|
strokeTable->sortItems(COLUMN_WIDTH);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COLUMN_METALLIC:
|
||||||
|
{
|
||||||
|
radialStroke(stroke)->materialMap[changedWidth].metallic = changedItemValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case COLUMN_ROUGHNESS:
|
||||||
|
{
|
||||||
|
radialStroke(stroke)->materialMap[changedWidth].roughness = changedItemValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#pragma once
|
||||||
|
#include "LayerStyle.h"
|
||||||
|
#include "../Renderer/Painting/MaterialStyleStroke.h"
|
||||||
|
#include <QTableWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <qtmaterialtextfield.h>
|
||||||
|
#include <qtmaterialcheckbox.h>
|
||||||
|
class StrokeStyleWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QVariant currentItemValue;
|
||||||
|
|
||||||
|
QtMaterialCheckBox* enableGradual;
|
||||||
|
QComboBox* endTypeBox;
|
||||||
|
QtMaterialTextField* widthField;
|
||||||
|
QTableWidget* strokeTable;
|
||||||
|
bool handlingRowInsert = false;
|
||||||
|
|
||||||
|
void initStrokeSettings();
|
||||||
|
void initTable(std::shared_ptr<Renderer::StrokeRadialGradient> materialStroke);
|
||||||
|
void setTableRow(int row, float width, Renderer::Material& material);
|
||||||
|
|
||||||
|
public:
|
||||||
|
StrokeStyleWidget(std::shared_ptr<Renderer::MaterialStyleStroke> stroke, QWidget* parent = nullptr);
|
||||||
|
std::shared_ptr<Renderer::MaterialStyleStroke> stroke;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void onCurrentItemChanged(QTableWidgetItem* current, QTableWidgetItem* previous);
|
||||||
|
void onCellChanged(int row, int column);
|
||||||
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "LayerStyle.h"
|
#include "LayerStyle.h"
|
||||||
#include "./EditorWidgetComponent/StrokeStyleListView.h"
|
#include "./EditorWidgetComponent/StrokeStyleWidget.h"
|
||||||
|
#include "./util/JsonUtil.hpp"
|
||||||
#include <qtmaterialcheckbox.h>
|
#include <qtmaterialcheckbox.h>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
|
@ -50,8 +51,7 @@ 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[0.3] = Renderer::Material{ QColor(0,255,255), 0.f, .8f };
|
materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f };
|
||||||
materialMap[1.0] = Renderer::Material{ QColor(80,25,255), 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,8 +63,7 @@ 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[0.3] = Renderer::Material{ QColor(0,255,255), 0.f, .8f };
|
materialMap[1.0] = Renderer::Material{ QColor(0, 0, 0), 0.f, .8f };
|
||||||
materialMap[1.0] = Renderer::Material{ QColor(80,25,255), 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,
|
||||||
|
@ -79,9 +78,7 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
|
||||||
QVBoxLayout* layout = new QVBoxLayout(w);
|
QVBoxLayout* layout = new QVBoxLayout(w);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
|
|
||||||
StrokeStyleListView* leftStrokeView = new StrokeStyleListView(
|
StrokeStyleWidget* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w);
|
||||||
std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(this->strokePair.first->materialStroke), w
|
|
||||||
);
|
|
||||||
layout->addWidget(leftStrokeView);
|
layout->addWidget(leftStrokeView);
|
||||||
|
|
||||||
QtMaterialCheckBox* checkEachSideIndependent = new QtMaterialCheckBox(w);
|
QtMaterialCheckBox* checkEachSideIndependent = new QtMaterialCheckBox(w);
|
||||||
|
@ -89,9 +86,7 @@ QWidget* StrokeElementLayerStyle::getInputWidget()
|
||||||
checkEachSideIndependent->setChecked(enableEachSideIndependent);
|
checkEachSideIndependent->setChecked(enableEachSideIndependent);
|
||||||
layout->addWidget(checkEachSideIndependent);
|
layout->addWidget(checkEachSideIndependent);
|
||||||
|
|
||||||
StrokeStyleListView* rightStrokeView = new StrokeStyleListView(
|
StrokeStyleWidget* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w);
|
||||||
std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(this->strokePair.second->materialStroke), w
|
|
||||||
);
|
|
||||||
layout->addWidget(rightStrokeView);
|
layout->addWidget(rightStrokeView);
|
||||||
rightStrokeView->setDisabled(!this->enableEachSideIndependent);
|
rightStrokeView->setDisabled(!this->enableEachSideIndependent);
|
||||||
|
|
||||||
|
@ -124,6 +119,16 @@ StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle&
|
||||||
enableEachSideIndependent = other.enableEachSideIndependent;
|
enableEachSideIndependent = other.enableEachSideIndependent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject StrokeElementLayerStyle::toJson() const
|
||||||
|
{
|
||||||
|
QJsonObject json;
|
||||||
|
json.insert("type", "stroke");
|
||||||
|
json.insert("enableEachSideIndependent", enableEachSideIndependent);
|
||||||
|
json.insert("left", JsonUtil::toQJsonArray<GLfloat>(strokePair.first->encoded()));
|
||||||
|
json.insert("right", JsonUtil::toQJsonArray<GLfloat>(strokePair.second->encoded()));
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
|
@ -167,7 +172,17 @@ FillElementLayerStyle::FillElementLayerStyle(const FillElementLayerStyle& other)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject FillElementLayerStyle::toJson() const
|
||||||
|
{
|
||||||
|
return QJsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<LayerStyle> LayerStyle::fromJson(const QJsonObject& json)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<LayerStyle>();
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QListWidget>
|
#include <QListWidget>
|
||||||
|
#include <QJsonObject>
|
||||||
#include "../Renderer/Painting/ElementStyle.h"
|
#include "../Renderer/Painting/ElementStyle.h"
|
||||||
#include "../Renderer/Painting/MaterialStyleStroke.h"
|
#include "../Renderer/Painting/MaterialStyleStroke.h"
|
||||||
#include "../Renderer/Painting/MaterialStyleFill.h"
|
#include "../Renderer/Painting/MaterialStyleFill.h"
|
||||||
|
@ -23,10 +24,13 @@ class LayerStyle : public Renderer::ElementStyle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const static std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()>>> types;
|
const static std::vector<std::pair<QString, std::function<std::unique_ptr<LayerStyle>()>>> types;
|
||||||
|
static std::unique_ptr<LayerStyle> fromJson(const QJsonObject& json);
|
||||||
|
|
||||||
virtual QString getStyleName() const = 0;
|
virtual QString getStyleName() const = 0;
|
||||||
virtual QWidget* getInputWidget() = 0;
|
virtual QWidget* getInputWidget() = 0;
|
||||||
virtual QWidget* getListDisplayWidget() const = 0;
|
virtual QWidget* getListDisplayWidget() const = 0;
|
||||||
virtual ~LayerStyle() {};
|
virtual ~LayerStyle() {};
|
||||||
|
virtual QJsonObject toJson() const = 0;
|
||||||
virtual std::unique_ptr<LayerStyle> clone() const = 0;
|
virtual std::unique_ptr<LayerStyle> clone() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,6 +47,7 @@ public:
|
||||||
StrokeElementLayerStyle() = default;
|
StrokeElementLayerStyle() = default;
|
||||||
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
StrokeElementLayerStyle(const StrokeElementLayerStyle& other);
|
||||||
~StrokeElementLayerStyle() = default;
|
~StrokeElementLayerStyle() = default;
|
||||||
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
std::unique_ptr<LayerStyle> clone() const override;
|
||||||
|
|
||||||
bool enableEachSideIndependent = false;
|
bool enableEachSideIndependent = false;
|
||||||
|
@ -59,5 +64,6 @@ public:
|
||||||
FillElementLayerStyle(const FillElementLayerStyle& other);
|
FillElementLayerStyle(const FillElementLayerStyle& other);
|
||||||
~FillElementLayerStyle() = default;
|
~FillElementLayerStyle() = default;
|
||||||
std::vector<std::shared_ptr<Renderer::MaterialStyleFill>> materialStyles;
|
std::vector<std::shared_ptr<Renderer::MaterialStyleFill>> materialStyles;
|
||||||
|
QJsonObject toJson() const override;
|
||||||
std::unique_ptr<LayerStyle> clone() const override;
|
std::unique_ptr<LayerStyle> clone() const override;
|
||||||
};
|
};
|
|
@ -240,6 +240,10 @@ QJsonObject LeafLayerWrapper::toJson() const
|
||||||
QJsonObject json = LayerWrapper::toJson();
|
QJsonObject json = LayerWrapper::toJson();
|
||||||
json.insert("element", wrappedElement->index);
|
json.insert("element", wrappedElement->index);
|
||||||
json.insert("is-folder", false);
|
json.insert("is-folder", false);
|
||||||
|
QJsonArray stylesJson;
|
||||||
|
for (auto& style : styles)
|
||||||
|
stylesJson.push_back(style->toJson());
|
||||||
|
json.insert("styles", stylesJson);
|
||||||
return json;
|
return json;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <QGraphicsItemGroup>
|
#include <QGraphicsItemGroup>
|
||||||
#include <QGraphicsScene>
|
#include <QGraphicsScene>
|
||||||
#include <QJSonObject>
|
#include <QJSonObject>
|
||||||
|
#include <QJsonArray>
|
||||||
#include <QLine>
|
#include <QLine>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPoint>
|
#include <QPoint>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#pragma once
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
namespace JsonUtil
|
||||||
|
{
|
||||||
|
#include <vector>
|
||||||
|
template<typename T>
|
||||||
|
QJsonArray toQJsonArray(const std::vector<T>& vec)
|
||||||
|
{
|
||||||
|
QJsonArray array;
|
||||||
|
std::copy(vec.begin(), vec.end(), std::back_inserter(array));
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ void Renderer::Model::loadModel(QString path)
|
||||||
directory = modelFile.dir();
|
directory = modelFile.dir();
|
||||||
|
|
||||||
Assimp::Importer importer;
|
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)
|
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||||
{
|
{
|
||||||
qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
||||||
|
@ -229,8 +229,104 @@ GLuint Renderer::Model::loadPainting(std::string path)
|
||||||
if (iter != paintingLoaded.end())
|
if (iter != paintingLoaded.end())
|
||||||
return iter->second;
|
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<std::pair<std::shared_ptr<Contour>, 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>(contour), ratio);
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<std::shared_ptr<ElementStyle>> style = {
|
||||||
|
std::make_shared<ElementStyleFillDemo>(),
|
||||||
|
std::make_shared<ElementStyleStrokeDemo>(0.02),
|
||||||
|
std::make_shared<ElementStyleStrokeRadialGradientDemo>(0.2)
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<std::shared_ptr<Element>> element = {
|
||||||
|
std::make_shared<Element>(Element{ contours[0].first, style[0], contours[0].second}),
|
||||||
|
std::make_shared<Element>(Element{ contours[1].first, style[2], contours[1].second}),
|
||||||
|
std::make_shared<Element>(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<std::pair<std::shared_ptr<Contour>, 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>(contour), ratio);
|
||||||
|
}
|
||||||
|
class StyleStrokeRadialGradient : public Renderer::ElementStyle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
float width;
|
||||||
|
StrokeType type;
|
||||||
|
StyleStrokeRadialGradient(float width, StrokeType type) :width(width), type(type) {};
|
||||||
|
virtual std::vector<Renderer::BaseStyle> toBaseStyles() const override
|
||||||
|
{
|
||||||
|
std::map<float, Material> 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<TransformStyle>(),
|
||||||
|
std::make_shared<MaterialStyleStroke>(width, type, StrokeEndType::kFlat,
|
||||||
|
std::make_shared<StrokeRadialGradient>(materialMap, false))) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
vector<std::shared_ptr<ElementStyle>> style = {
|
||||||
|
std::make_shared<StyleStrokeRadialGradient>(widths[0], StrokeType::kLeftSide),
|
||||||
|
std::make_shared<StyleStrokeRadialGradient>(widths[1], StrokeType::kRightSide),
|
||||||
|
std::make_shared<StyleStrokeRadialGradient>(widths[2], StrokeType::kLeftSide),
|
||||||
|
};
|
||||||
|
vector<std::shared_ptr<Element>> element = {
|
||||||
|
std::make_shared<Element>(Element{ contours[0].first, style[0], contours[0].second}),
|
||||||
|
std::make_shared<Element>(Element{ contours[1].first, style[1], contours[1].second}),
|
||||||
|
std::make_shared<Element>(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);
|
painting.generateBuffers(glFunc);
|
||||||
|
|
||||||
auto index = vtManager->createVirtualTexture(painting);
|
auto index = vtManager->createVirtualTexture(painting);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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