diff --git a/src/texturegenerator.h b/src/texturegenerator.h index 7ff2c327..801e803e 100644 --- a/src/texturegenerator.h +++ b/src/texturegenerator.h @@ -33,7 +33,7 @@ public: static int m_textureSize; private: void prepare(); - QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=3); + QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=7); private: MeshResultContext *m_resultContext; QImage *m_resultTextureGuideImage; diff --git a/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp b/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp index 40884cb6..4c4ed99e 100644 --- a/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp +++ b/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -129,49 +130,93 @@ bool UvUnwrapper::fixHolesExceptTheLongestRing(const std::vector &vertic std::map, size_t> edgeToFaceMap; buildEdgeToFaceMap(faces, edgeToFaceMap); - std::map holeVertexLink; + std::map> holeVertexLink; for (const auto &face: faces) { for (size_t i = 0; i < 3; i++) { size_t j = (i + 1) % 3; auto findOppositeFaceResult = edgeToFaceMap.find({face.indicies[j], face.indicies[i]}); if (findOppositeFaceResult != edgeToFaceMap.end()) continue; - holeVertexLink[face.indicies[j]] = face.indicies[i]; + holeVertexLink[face.indicies[j]].push_back(face.indicies[i]); } } std::vector, double>> holeRings; - std::unordered_set visited; while (!holeVertexLink.empty()) { + bool foundRing = false; std::vector ring; + std::unordered_set visited; + std::set> visitedPath; double ringLength = 0; - auto first = holeVertexLink.begin()->first; - auto index = first; - auto prev = first; - ring.push_back(first); - visited.insert(first); - while (true) { - auto findLinkResult = holeVertexLink.find(index); - if (findLinkResult == holeVertexLink.end()) { - qDebug() << "Search ring failed"; - return false; + while (!foundRing) { + ring.clear(); + visited.clear(); + ringLength = 0; + auto first = holeVertexLink.begin()->first; + auto index = first; + auto prev = first; + ring.push_back(first); + visited.insert(first); + while (true) { + auto findLinkResult = holeVertexLink.find(index); + if (findLinkResult == holeVertexLink.end()) { + qDebug() << "Search ring failed"; + return false; + } + for (const auto &item: findLinkResult->second) { + if (item == first) { + foundRing = true; + break; + } + } + if (foundRing) + break; + if (findLinkResult->second.size() > 1) { + bool foundNewPath = false; + for (const auto &item: findLinkResult->second) { + if (visitedPath.find({prev, item}) == visitedPath.end()) { + index = item; + foundNewPath = true; + break; + } + } + if (!foundNewPath) { + qDebug() << "No new path to try"; + return false; + } + visitedPath.insert({prev, index}); + } else { + index = *findLinkResult->second.begin(); + } + if (visited.find(index) != visited.end()) { + while (index != *ring.begin()) + ring.erase(ring.begin()); + foundRing = true; + break; + } + ring.push_back(index); + visited.insert(index); + ringLength += distanceBetweenVertices(verticies[index], verticies[prev]); + prev = index; } - index = findLinkResult->second; - if (index == first) { - break; - } - if (visited.find(index) != visited.end()) { - qDebug() << "Found infinite ring"; - return false; - } - visited.insert(index); - ring.push_back(index); - ringLength += distanceBetweenVertices(verticies[index], verticies[prev]); - prev = index; + } + if (ring.size() < 3) { + qDebug() << "Ring too short, size:" << ring.size(); + return false; } holeRings.push_back({ring, ringLength}); - for (const auto &index: ring) - holeVertexLink.erase(index); + for (size_t i = 0; i < ring.size(); ++i) { + size_t j = (i + 1) % ring.size(); + auto findLinkResult = holeVertexLink.find(ring[i]); + for (auto it = findLinkResult->second.begin(); it != findLinkResult->second.end(); ++it) { + if (*it == ring[j]) { + findLinkResult->second.erase(it); + if (findLinkResult->second.empty()) + holeVertexLink.erase(ring[i]); + break; + } + } + } } if (holeRings.size() > 1) {