From ae641bb87c0bfd434d81a097a32cb90e2a1c51ea Mon Sep 17 00:00:00 2001 From: wuyize Date: Mon, 20 Mar 2023 17:48:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=86StrokeEndType::kClos?= =?UTF-8?q?ed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../res/Shaders/element.comp | 25 ++++++++++++++-- .../src/Editor/util/PaintingUtil.cpp | 25 +++++++--------- .../Renderer/Painting/MaterialStyleStroke.cpp | 13 +++++++-- .../Renderer/Painting/MaterialStyleStroke.h | 3 +- UnitTest/ElementRendererTest.cpp | 29 ++++++++++++++++--- UnitTest/UnitTest.cpp | 16 +--------- test.json | 2 +- 7 files changed, 72 insertions(+), 41 deletions(-) diff --git a/ArchitectureColoredPainting/res/Shaders/element.comp b/ArchitectureColoredPainting/res/Shaders/element.comp index fd09af8..511c470 100644 --- a/ArchitectureColoredPainting/res/Shaders/element.comp +++ b/ArchitectureColoredPainting/res/Shaders/element.comp @@ -1093,6 +1093,7 @@ void main() bool onVeryBegin = false; bool onVeryEnd = false; vec2 tangentEndLast; + vec2 tangentFirstBegin; uint lastHitIndex = 0; bool lastHitElement = false; hitElement = false; @@ -1108,7 +1109,19 @@ void main() pBegin = path[++pathIndex]; p3Last = pBegin; p2Last = pBegin; - onVeryBegin = true; + if(endType == 4) + { + //onVeryBegin = false; + vec2 lastP1 = path[pathSize-3]; + vec2 lastP2 = path[pathSize-2]; + vec2 lastP3 = path[pathSize-1]; + if (lastP3 != lastP2) + tangentEndLast = normalize(lastP3 - lastP2); + else + tangentEndLast = normalize(lastP3 - lastP1); + } + else + onVeryBegin = true; continue; } mat4x2 p = mat4x2(p3Last, pTemp, path[++pathIndex], path[++pathIndex]); @@ -1119,7 +1132,13 @@ void main() vec2 pTemp = path[pathIndex + 1]; if (isinf(pTemp.x)) { - onVeryEnd = true; + if(endType == 4) + { + //onVeryEnd = false; + tangentBeginNext = tangentFirstBegin; + } + else + onVeryEnd = true; } else { @@ -1180,6 +1199,8 @@ void main() } } tangentEndLast = tangentEnd; + if(pathIndex == 0) + tangentFirstBegin = tangentBegin; } p3Last = p[3]; p2Last = p[2]; diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index ce93afb..aa23ce6 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -83,9 +83,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr QPainterPath painterPath = pixelPath.getPainterPath(); QRectF bound = painterPath.boundingRect(); //qDebug() << leafLayer<<"------" << painterPath; - //qDebug() << transform; - // transform to initial painterPath - // transfrom to -1, 1 + // transform to -1, 1 QTransform trans; double maxLen = std::max(bound.width(), bound.height()); qDebug() << maxLen << bound; @@ -102,22 +100,19 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr auto baseStyles = leafLayer->styles.toBaseStyles(); Renderer::BaseElement element; element.contour = contour; - for (auto baseStyle : baseStyles) { + for (auto& baseStyle : baseStyles) { double lineWidth = 0; if (baseStyle.material->type() == Renderer::MaterialStyleType::kStroke) { - auto material = dynamic_cast(baseStyle.material.get()); - material->halfWidth = material->halfWidth / maxLen; + auto material = std::static_pointer_cast(baseStyle.material); + material->halfWidth /= maxLen; lineWidth = material->halfWidth; qDebug() << material->halfWidth; } - QRectF rect = painterPath.boundingRect(); - rect.setX(-lineWidth + rect.x()); - rect.setY(-lineWidth + rect.y()); - rect.setWidth(lineWidth * 2 + rect.width()); - rect.setHeight(lineWidth * 2 + rect.height()); - QPainterPath path; - path.addRect(rect); - rect = transform.map(path).boundingRect(); + QPainterPathStroker stroker; + stroker.setWidth(lineWidth); + stroker.setCapStyle(Qt::RoundCap); + QPainterPath strokePath = stroker.createStroke(painterPath); + auto rect = transform.map(strokePath).boundingRect(); elementTransform.bound = glm::vec4(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height()); qDebug() << elementTransform.bound.x << elementTransform.bound.y << elementTransform.bound.z << elementTransform.bound.z; transform = transform.inverted(); @@ -125,7 +120,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr transform.m11(), transform.m12(), transform.m21(), transform.m22(), transform.m31(), transform.m32() ); - qDebug() << transform; + //qDebug() << transform; elementTransform.zIndex = 0; element.style = baseStyle.material; diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp index 0d72542..9919f73 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.cpp @@ -1,5 +1,6 @@ #include "MaterialStyleStroke.h" #include +#include using namespace Renderer; @@ -105,8 +106,8 @@ std::unique_ptr Renderer::MaterialStyleStroke::clone() const bool Renderer::MaterialStyleStroke::operator==(const MaterialStyle& m) const { - return type() == m.type() - && halfWidth == static_cast(m).halfWidth + return type() == m.type() + && halfWidth == static_cast(m).halfWidth && strokeType == static_cast(m).strokeType && endType == static_cast(m).endType && *materialStroke == *static_cast(m).materialStroke; @@ -117,4 +118,10 @@ float Renderer::MaterialStyleStroke::getHalfWidth() const return halfWidth; } - +#define endTypeBoxLabel(start, end) QStringLiteral(start##" -> "##end) +const std::array, 4> Renderer::MaterialStyleStroke::strokeEndTypeNames = { + std::pair{endTypeBoxLabel("圆头", "圆头"), StrokeEndType::kRound}, + std::pair{endTypeBoxLabel("平头", "圆头"), StrokeEndType::kFlatRound}, + std::pair{endTypeBoxLabel("圆头", "平头"), StrokeEndType::kRoundFlat}, + std::pair{endTypeBoxLabel("平头", "平头"), StrokeEndType::kFlat} +}; \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h index 29fd55b..e6bf8af 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/MaterialStyleStroke.h @@ -43,7 +43,7 @@ namespace Renderer }; enum class StrokeType { kBothSides = 2, kLeftSide = 1, kRightSide = 0 }; - enum class StrokeEndType { kRound = 0b00, kFlat = 0b11, kRoundFlat = 0b10, kFlatRound = 0b01 }; + enum class StrokeEndType { kRound = 0b00, kFlat = 0b11, kRoundFlat = 0b10, kFlatRound = 0b01, kClosed = 0b100/*用于封闭图形*/ }; class MaterialStyleStroke : public MaterialStyle { @@ -59,5 +59,6 @@ namespace Renderer StrokeType strokeType; StrokeEndType endType; std::shared_ptr materialStroke; + static const std::array, 4> strokeEndTypeNames; }; } diff --git a/UnitTest/ElementRendererTest.cpp b/UnitTest/ElementRendererTest.cpp index aba0474..5760980 100644 --- a/UnitTest/ElementRendererTest.cpp +++ b/UnitTest/ElementRendererTest.cpp @@ -42,17 +42,38 @@ namespace UnitTest { virtual std::vector toBaseStyles() const override { - return { BaseStyle(std::make_shared(), - std::make_shared( - std::make_shared(Material(QColor(255,255,0))))) }; + std::make_shared(std::make_shared(Material(QColor(255,255,0))))) }; + } + } style; + TestGLWidget w(style, path); + w.show(); + a.exec(); + } + TEST_METHOD(TestFillPlainAndStrokeRadialGradient) + { + QApplication a(argc, argv); + class Style : public Renderer::ElementStyle + { + virtual std::vector toBaseStyles() const override + { + std::map materialMap = { + {0.20, Material{QColor(255,255,255)}}, + {0.60, Material{QColor(165,176,207)}}, + {1.00, Material{QColor(58,64,151)}} + }; + return { BaseStyle(std::make_shared(), + std::make_shared( + std::make_shared(Material(QColor(255,255,0))))), + BaseStyle(std::make_shared(), + std::make_shared(10, StrokeType::kBothSides, StrokeEndType::kRound, + std::make_shared(materialMap, false))) }; } } style; TestGLWidget w(style, path); w.show(); a.exec(); } - }; TEST_CLASS(ElementRendererStokeTypeTest) diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index 25bcf67..0005c41 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -122,20 +122,6 @@ namespace UnitTest }; TEST_CLASS(PaintingUtilTest) { - TEST_METHOD(TransfromTest) - { - qInstallMessageHandler(messageHandler); - QPainterPath path; - path.addRect(0, 0, 20, 20); - QTransform trans; - qDebug() << path.boundingRect(); - //qDebug() << trans; - //qDebug() << acos(-0.707107); - glm::vec2 scale; - float rotate; - PaintingUtil::decomposeTransform(trans, rotate, scale); - qDebug() << rotate; - qDebug() << scale.x << scale.y; - } + }; } diff --git a/test.json b/test.json index 15441e2..ce11428 100644 --- a/test.json +++ b/test.json @@ -59,7 +59,7 @@ "name": "Leaf2", "styles": [ { - "enableEachSideIndependent": false, + "enableEachSideIndependent": true, "left": "AAAAQAEAIZwAf////1UA/w==", "right": "AADgQAAACJw=", "type": "stroke"