Fix texture generation
parent
7e0591de6b
commit
7fa29dcc48
|
@ -33,7 +33,7 @@ public:
|
||||||
static int m_textureSize;
|
static int m_textureSize;
|
||||||
private:
|
private:
|
||||||
void prepare();
|
void prepare();
|
||||||
QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=3);
|
QPainterPath expandedPainterPath(const QPainterPath &painterPath, int expandSize=7);
|
||||||
private:
|
private:
|
||||||
MeshResultContext *m_resultContext;
|
MeshResultContext *m_resultContext;
|
||||||
QImage *m_resultTextureGuideImage;
|
QImage *m_resultTextureGuideImage;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
#include <set>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <simpleuv/uvunwrapper.h>
|
#include <simpleuv/uvunwrapper.h>
|
||||||
#include <simpleuv/parametrize.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;
|
std::map<std::pair<size_t, size_t>, size_t> edgeToFaceMap;
|
||||||
buildEdgeToFaceMap(faces, 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 (const auto &face: faces) {
|
||||||
for (size_t i = 0; i < 3; i++) {
|
for (size_t i = 0; i < 3; i++) {
|
||||||
size_t j = (i + 1) % 3;
|
size_t j = (i + 1) % 3;
|
||||||
auto findOppositeFaceResult = edgeToFaceMap.find({face.indicies[j], face.indicies[i]});
|
auto findOppositeFaceResult = edgeToFaceMap.find({face.indicies[j], face.indicies[i]});
|
||||||
if (findOppositeFaceResult != edgeToFaceMap.end())
|
if (findOppositeFaceResult != edgeToFaceMap.end())
|
||||||
continue;
|
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::vector<std::pair<std::vector<size_t>, double>> holeRings;
|
||||||
std::unordered_set<size_t> visited;
|
|
||||||
while (!holeVertexLink.empty()) {
|
while (!holeVertexLink.empty()) {
|
||||||
|
bool foundRing = false;
|
||||||
std::vector<size_t> ring;
|
std::vector<size_t> ring;
|
||||||
|
std::unordered_set<size_t> visited;
|
||||||
|
std::set<std::pair<size_t, size_t>> visitedPath;
|
||||||
double ringLength = 0;
|
double ringLength = 0;
|
||||||
auto first = holeVertexLink.begin()->first;
|
while (!foundRing) {
|
||||||
auto index = first;
|
ring.clear();
|
||||||
auto prev = first;
|
visited.clear();
|
||||||
ring.push_back(first);
|
ringLength = 0;
|
||||||
visited.insert(first);
|
auto first = holeVertexLink.begin()->first;
|
||||||
while (true) {
|
auto index = first;
|
||||||
auto findLinkResult = holeVertexLink.find(index);
|
auto prev = first;
|
||||||
if (findLinkResult == holeVertexLink.end()) {
|
ring.push_back(first);
|
||||||
qDebug() << "Search ring failed";
|
visited.insert(first);
|
||||||
return false;
|
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) {
|
if (ring.size() < 3) {
|
||||||
break;
|
qDebug() << "Ring too short, size:" << ring.size();
|
||||||
}
|
return false;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
holeRings.push_back({ring, ringLength});
|
holeRings.push_back({ring, ringLength});
|
||||||
for (const auto &index: ring)
|
for (size_t i = 0; i < ring.size(); ++i) {
|
||||||
holeVertexLink.erase(index);
|
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) {
|
if (holeRings.size() > 1) {
|
||||||
|
|
Loading…
Reference in New Issue