Fix texture generation

master
Jeremy Hu 2018-10-16 08:04:08 +08:00
parent 7e0591de6b
commit 7fa29dcc48
2 changed files with 73 additions and 28 deletions

View File

@ -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;

View File

@ -1,5 +1,6 @@
#include <map>
#include <unordered_set>
#include <set>
#include <queue>
#include <simpleuv/uvunwrapper.h>
#include <simpleuv/parametrize.h>
@ -129,49 +130,93 @@ bool UvUnwrapper::fixHolesExceptTheLongestRing(const std::vector<Vertex> &vertic
std::map<std::pair<size_t, size_t>, size_t> edgeToFaceMap;
buildEdgeToFaceMap(faces, edgeToFaceMap);
std::map<size_t, size_t> holeVertexLink;
std::map<size_t, std::vector<size_t>> 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<std::pair<std::vector<size_t>, double>> holeRings;
std::unordered_set<size_t> visited;
while (!holeVertexLink.empty()) {
bool foundRing = false;
std::vector<size_t> ring;
std::unordered_set<size_t> visited;
std::set<std::pair<size_t, size_t>> 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) {