diff --git a/ArchitectureColoredPainting/res/Shaders/element.comp b/ArchitectureColoredPainting/res/Shaders/element.comp index 66910e7..b44b514 100644 --- a/ArchitectureColoredPainting/res/Shaders/element.comp +++ b/ArchitectureColoredPainting/res/Shaders/element.comp @@ -1150,11 +1150,6 @@ void main() else tangentEnd = normalize(p[3] - p[1]); - // if (onBegin ? shouldFillBeginCap(localUV, onVeryBegin, endType, p[0], tangentBegin, - // tangentEndLast) - // : (onEnd ? shouldFillEndCap(localUV, onVeryEnd, endType, p[3], tangentEnd, - // tangentBeginNext) - // : d < minDistance)) bool hit = d < minDistance; if (onBegin) hit = hit && diff --git a/ArchitectureColoredPainting/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index 9ba19a9..50a32b8 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -1023,14 +1023,14 @@ void drawLine(in float d, in uint styleIndex, out vec4 elementColor, out vec2 me } } -bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, vec2 tangentBegin, vec2 tangentEndLast) +bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p0, vec2 tangentBegin, vec2 tangentEndLast) { vec2 normal; if (onVeryBegin) { - if (endType == 0) + if (endType % 2 == 0) return true; - else if (endType == 1) + else if (endType % 2 == 1) normal = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); } else @@ -1039,17 +1039,26 @@ bool shouldFillBeginCap(vec2 localUV, bool onVeryBegin, int endType, vec2 p3, ve vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBegin)); normal = normalLast + normalNow; } - return angleLargeThanPi(normal, localUV - p3); + return angleLargeThanPi(normal, localUV - p0); } -bool shouldFillEndCap(vec2 localUV, int endType, vec2 p0, vec2 tangentEnd) +bool shouldFillEndCap(vec2 localUV, bool onVeryEnd, int endType, vec2 p3, vec2 tangentEnd, vec2 tangentBeginNext) { vec2 normal; - if (endType == 0) - return true; - else if (endType == 1) - normal = normalize(mat2(0, 1, -1, 0) * tangentEnd); - return angleLargeThanPi(localUV - p0, normal); + if (onVeryEnd) + { + if ((endType / 2) % 2 == 0) + return true; + else if ((endType / 2) % 2 == 1) + normal = normalize(mat2(0, 1, -1, 0) * tangentEnd); + } + else + { + vec2 normalLast = normalize(mat2(0, 1, -1, 0) * tangentEnd); + vec2 normalNow = normalize(mat2(0, 1, -1, 0) * (-tangentBeginNext)); + normal = normalLast + normalNow; + } + return angleLargeThanPi(localUV - p3, normal); } bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, @@ -1100,8 +1109,8 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO return hitElement; } -bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, float widthHeightRatio, - inout vec4 elementColor, inout vec2 metallicRoughness) +bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, + float widthHeightRatio, inout vec4 elementColor, inout vec2 metallicRoughness) { bool hitElement = false; float strokeWidth = elementData[styleIndex]; @@ -1135,12 +1144,44 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point mat4x2 p = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]); - p[0] *= ratio; p[1] *= ratio; p[2] *= ratio; p[3] *= ratio; + vec2 tangentBeginNext; + if (contourIterator + 1 < contourIndex + 1 + lineCount) + { + uint lineIndex = elementIndexs[contourIterator + 1]; + uint pLocation = linesOffset + 3 * lineIndex; + //vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]); + uvec4 pxIndex = uvec4(pointsOffset) + + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF, + elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF); + uvec4 pyIndex = uvec4(1) + pxIndex; + + mat4x2 pNext = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], + elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], + elementData[pxIndex[3]], elementData[pyIndex[3]]); + pNext[0] *= ratio; + pNext[1] *= ratio; + pNext[2] *= ratio; + pNext[3] *= ratio; + + if (pNext[0] == pNext[1] && pNext[2] == pNext[3]) + { + pNext[1] = (pNext[0] + pNext[3]) / 2; + pNext[2] = pNext[1]; + } + + //if(pNext[0]!=p[3]) + // break; + if (pNext[0] != pNext[1]) + tangentBeginNext = normalize(pNext[0] - pNext[1]); + else + tangentBeginNext = normalize(pNext[0] - pNext[2]); + } + if (p[0] == p[1] && p[2] == p[3]) { p[1] = (p[0] + p[3]) / 2; @@ -1158,7 +1199,10 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point float d = cubic_bezier_dis(localUV, p[0], p[1], p[2], p[3], true); if (d <= strokeWidth) { - bool onBegin = distance(localUV, p[0]) <= strokeWidth && ( p3Last == p[0] || contourIterator==contourIndex + 1); + bool onBegin = + distance(localUV, p[0]) <= strokeWidth; //&& (p3Last == p[0] || contourIterator == contourIndex + 1); + bool onEnd = distance(localUV, p[3]) <= strokeWidth; + vec2 tangentBegin; vec2 tangentEnd; if (p[0] != p[1]) @@ -1170,30 +1214,36 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point else tangentEnd = normalize(p[3] - p[1]); - if (onBegin ? shouldFillBeginCap(localUV, percent[0]<1e-5, endType, p[0], tangentBegin, p3Last - p2Last) - : d < minDistance) + bool hit = d < minDistance; + if (onBegin) + hit = + hit && shouldFillBeginCap(localUV, percent[0] < 1e-5, endType, p[0], tangentBegin, p3Last - p2Last); + if (onEnd) + hit = hit && + shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p[3], tangentEnd, tangentBeginNext); + if (hit) { - minDistance = min(minDistance, d); bool reverse = p[3].y - p[0].y < 0.; - if (tangentBegin.y == 0.) - tangentBegin.y = reverse ? eps : -eps; - if (tangentEnd.y == 0.) - tangentEnd.y = reverse ? -eps : eps; + // if (tangentBegin.y == 0.) + // tangentBegin.y = reverse ? eps : -eps; + // if (tangentEnd.y == 0.) + // tangentEnd.y = reverse ? -eps : eps; int intTest = cubic_bezier_int_test2(localUV, p[0], p[1], p[2], p[3], reverse) + ray_int_test(localUV, p[0], tangentBegin, reverse) + ray_int_test(localUV, p[3], tangentEnd, reverse); if (lineType == 2 || (intTest % 2 == int(lineType))) { + minDistance = min(minDistance, d); hitElement = true; // elementColor = vec4(1, 1, 0, 1); vec2 metallicRoughness; drawLine(minDistance / strokeWidth, styleIndex, elementColor, metallicRoughness); } - else if (p3Last == p[0]) - hitElement = false; + // else if (p3Last == p[0]) + // hitElement = false; } tangentEndLast = tangentEnd; } @@ -1202,7 +1252,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point } if (hitElement && distance(localUV, p3Last) <= strokeWidth) { - hitElement = shouldFillEndCap(localUV, endType, p3Last, tangentEndLast); + // hitElement = shouldFillEndCap(localUV, percent[1] > 1 - 1e-5, endType, p3Last, tangentEndLast, vec2(0)); } // if (minDistance <= 0.001) @@ -1261,8 +1311,8 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou } else // 线 { - hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex, widthHeightRatio, - elementColor, metallicRoughness); + hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex, + widthHeightRatio, elementColor, metallicRoughness); } elementBvhIndex = elementBvhLength; @@ -1303,7 +1353,7 @@ void main() vec3 debugBVH = vec3(0); // bool debugHit = false; vec4 color = vec4(0.76, 0.33, 0.15, -1); - //vec4 color = vec4(1,1,1, -1); + // vec4 color = vec4(1,1,1, -1); vec2 metallicRoughness = vec2(0, 0.8); stack.top = 0; uint index = 0, visitTime = 0; @@ -1373,7 +1423,7 @@ void main() imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1)); imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1)); - return; + //return; if (/*color.a!=-1&&*/ debugBVH == vec3(0)) { // imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1)); diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index 45747dc..07e0224 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -8,6 +8,9 @@ using Renderer::Element; using Renderer::ElementTransform; using glm::bvec2; using std::max; +using std::min; + +const double PaintingUtil::pi = acos(-1); QJsonObject PaintingUtil::readJsonFile(QString jsonFilePath) { QFile jsonFile(jsonFilePath); @@ -27,74 +30,69 @@ Painting PaintingUtil::transfromToPainting(QString jsonFilePath) { ElementManager *elementManager = new ElementManager(jsonObj, Renderer::ElementRenderer::instance()); LayerManager* layerManager = new LayerManager(jsonObj, elementManager); traverseLayTree(layerManager->getRoot(), transform, flip, painting); - // FIXME: 为了编译通过添加的返回 return painting; } void PaintingUtil::traverseLayTree(LayerWrapper* nowLayer, QTransform transform, bvec2 flip, Painting& painting) { LeafLayerWrapper* leafLayer = dynamic_cast(nowLayer); PixelPath pixelPath = nowLayer->getCache(); - double centerX = pixelPath.getBoundingRect().center().x(); - double centerY = pixelPath.getBoundingRect().center().y(); + QPainterPath painterPath = pixelPath.getPainterPath(); + QRectF bound = painterPath.boundingRect(); flip ^= bvec2(nowLayer->property.flipHorizontally, nowLayer->property.flipVertically); - QRectF transBound = transform.map(pixelPath.getPainterPath()).boundingRect(); + transform = nowLayer->property.transform * transform; - transform.translate(nowLayer->property.offset.x(), nowLayer->property.offset.y()) - .translate(-centerX, -centerY) - .rotate(nowLayer->property.rotation) - .scale(nowLayer->property.scale.x(), nowLayer->property.scale.y()) - .translate(centerX, centerY); if (leafLayer != nullptr) { Element element; ElementTransform elementTrans; - QRectF bound = pixelPath.getBoundingRect(); element.ratio = bound.width() / bound.height(); // transform to initial painterPath - QTransform trans; - trans.translate(-centerX, -centerY) - .scale(1 / nowLayer->property.scale.x(), 1 / nowLayer->property.scale.y()) - .rotate(-nowLayer->property.rotation) - .translate(centerX, centerY) - .translate(-nowLayer->property.offset.x(), -nowLayer->property.offset.y()); - QPainterPath painterPath = trans.map(pixelPath.getPainterPath()); // transfrom to -1, 1 - bound = painterPath.boundingRect(); - trans.reset(); - trans.translate(1, 1); - trans.scale(2 / bound.width(), 2 / bound.height()); - trans.translate(bound.x(), bound.y()); - painterPath = trans.map(painterPath); + QTransform trans; + trans.scale(1 / bound.width(), 1 / bound.height()); + trans.translate(-bound.center().x(), -bound.center().y()); - element.contour.reset(new vector >(PainterPathUtil::transformToLines(painterPath))); + element.contour.reset(new vector >(PainterPathUtil::transformToLines(trans.map(painterPath)))); QSize screenSize = pixelPath.getPixmap().size(); + //element.style.reset(new Renderer::ElementStyleStrokeDemo(0.06)); + + painterPath = transform.map(painterPath); + bound = painterPath.boundingRect(); elementTrans.center = glm::vec2( - (2 * (transBound.x() + transBound.width()) - screenSize.width()) / screenSize.width(), - (2 * (transBound.y() + transBound.height()) - screenSize.height()) / screenSize.height() + (bound.center().x() - screenSize.width()) / screenSize.width(), + (bound.center().y() - screenSize.height()) / screenSize.height() ); decomposeTransform(transform, elementTrans.rotation, elementTrans.scale); elementTrans.flip = glm::bvec2( nowLayer->property.flipHorizontally, nowLayer->property.flipVertically ); + painting.addElement(element, elementTrans); return; } FolderLayerWrapper* folderLayer = dynamic_cast(nowLayer); - for (auto sonLayer : folderLayer->children) { - traverseLayTree(sonLayer.get(), transform, flip, painting); + if (folderLayer != nullptr) { + for (auto sonLayer : folderLayer->children) { + traverseLayTree(sonLayer.get(), transform, flip, painting); + } } return; } void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& scale) { - trans.translate(-trans.dx(), -trans.dy()); + qDebug() << trans; + trans.setMatrix( + trans.m11(), trans.m12(), trans.m13(), + trans.m21(), trans.m22(), trans.m23(), + 0, 0, 1); + //qDebug() << trans.dx() << trans.dy(); int count = 0; double norm = 0, n = 0; QTransform R = trans, Rit, Rnext; do { ++count; - Rit = R.inverted(); + Rit = R.transposed().inverted(); Rnext.setMatrix( (R.m11() + Rit.m11()) / 2, (R.m12() + Rit.m12()) / 2, @@ -121,7 +119,13 @@ void PaintingUtil::decomposeTransform(QTransform trans, float& angle, glm::vec2& + fabs(R.m33() - Rnext.m33())); R = Rnext; } while (count < 100 && norm > 0.0001); - angle = acos(R.m11()); + double cosValue = max(-1.0, min(R.m11(), 1.0)); + double sinValue = max(-1.0, min(R.m12(), 1.0)); + angle = acos(cosValue) * 180 / pi; + if (sinValue < 0) { + angle = 360 - angle; + } + qDebug() << angle; R = R.inverted() * trans; scale = glm::vec2(R.m11(), R.m22()); return; diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h index bb27a73..35ebe03 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.h @@ -5,11 +5,12 @@ class PaintingUtil { private: + static const double pi; static QJsonObject readJsonFile(QString jsonFilePath); static void traverseLayTree(LayerWrapper* nowLayer, QTransform transform, glm::bvec2 flip, Renderer::Painting& painting); - static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale); public: static Renderer::Painting transfromToPainting(QString jsonFilePath); + static void decomposeTransform(QTransform trans, float& angle, glm::vec2& scale); }; diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index fc9c585..7496155 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -14,6 +14,7 @@ #include "../Editor/util/PainterPathUtil.h" #include "../Editor/util/SvgFileLoader.h" #include +#include #include "Painting/MaterialStyleStroke.h" using namespace Renderer; @@ -228,104 +229,7 @@ GLuint Renderer::Model::loadPainting(std::string path) if (iter != paintingLoaded.end()) return iter->second; - //vector> contour = { - // std::make_shared(SvgParser("M100,100C-.5,100,0,100.5,0,0L40,.07C40,59.5,39.5,60,100,60Z", 100, 100).parse()), - // std::make_shared(SvgParser("M308.49,212.25l23,28.38-82,78.31c-14.28,13.64-26.34-20.6-53.44,9.32l-30.24-13.4,63.56-51.59L190.71,215.6l-32.92,26.72L149.5,232.1l32.92-26.72L173.2,194l-32.91,26.72-7.38-9.08L165.83,185l-38.69-47.66L94.22,164,85,152.65l32.91-26.72-9.21-11.35L75.79,141.3l-5.53-6.81,32.92-26.72L94,96.42,61.05,123.14l-12-14.76L37.72,117.6l12,14.75L30.41,148,0,110.55,136.2,0l30.4,37.46L147.31,53.12l-12-14.76L124,47.58l12,14.75L103.05,89.05l9.21,11.35,32.92-26.72,5.52,6.81-32.91,26.72L127,118.56l32.92-26.72,9.21,11.35-32.91,26.72,38.69,47.67,32.91-26.72,7.37,9.08-32.91,26.72L191.49,198l32.92-26.72,8.29,10.22-32.92,26.71,38.7,47.68L302,204.3l6.45,7.95Z", 331.52, 328.26).parse()), - // std::make_shared(SvgParser("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", 716.45, 716.44).parse()) - //}; - - vector, 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), ratio); - } - - vector> style = { - std::make_shared(), - std::make_shared(0.02), - std::make_shared(0.2) - }; - - vector> element = { - std::make_shared(Element{ contours[0].first, style[0], contours[0].second}), - std::make_shared(Element{ contours[1].first, style[2], contours[1].second}), - std::make_shared(Element{ contours[2].first, style[0], contours[2].second}), - }; - Painting painting; - - 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.13 * 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, 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), ratio); - } - class StyleStrokeRadialGradient : public Renderer::ElementStyle - { - public: - float width; - StrokeType type; - StyleStrokeRadialGradient(float width, StrokeType type) :width(width), type(type) {}; - virtual std::vector toBaseStyles() const override - { - std::map 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(), - std::make_shared(width, type, StrokeEndType::kFlat, - std::make_shared(materialMap, false))) }; - } - }; - vector> style = { - std::make_shared(widths[0], StrokeType::kLeftSide), - std::make_shared(widths[1], StrokeType::kRightSide), - std::make_shared(widths[2], StrokeType::kLeftSide), - }; - vector> element = { - std::make_shared(Element{ contours[0].first, style[0], contours[0].second}), - std::make_shared(Element{ contours[1].first, style[1], contours[1].second}), - std::make_shared(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 painting = PaintingUtil::transfromToPainting("D:\\BigC\\Project\\ArchitectureColoredPainting\\data.json"); painting.generateBuffers(glFunc); diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp index 2b4cd56..db84c3c 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/LineTree.cpp @@ -141,12 +141,13 @@ bool LineTree::handleShortCutNode(LineTreeNode& fa, LineTreeNode& nowTreeNode, d nowTreeNode.lineSet.push_back(lineIndex); } } - if (nowTreeNode.lineSet.size() <= requiredLineMin) { + if (nowTreeNode.lineSet.size() <= requiredLineMin + || (nowTreeNode.bound.z()-nowTreeNode.bound.x())*sqrt(2) <= lineWidth) { if (nowTreeNode.lineSet.empty()) return false; restOfTreeNodes.push_back(nowTreeNode); nowTreeNode.divided = false; - v.push_back(nowTreeNode); + //v.push_back(nowTreeNode); return false; } else { diff --git a/UnitTest/UnitTest.cpp b/UnitTest/UnitTest.cpp index 2d7d95a..25bcf67 100644 --- a/UnitTest/UnitTest.cpp +++ b/UnitTest/UnitTest.cpp @@ -7,6 +7,7 @@ #include "Renderer/Painting/CubicBezier.h" #include #include +#include using namespace Microsoft::VisualStudio::CppUnitTestFramework; @@ -119,4 +120,22 @@ namespace UnitTest a.exec(); } }; + 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; + } + }; }