Segment UV by normal
parent
bde3c01da0
commit
f5a70dfd9e
|
@ -10,6 +10,7 @@ void uvUnwrap(const Outcome &outcome,
|
||||||
{
|
{
|
||||||
const auto &choosenVertices = outcome.vertices;
|
const auto &choosenVertices = outcome.vertices;
|
||||||
const auto &choosenTriangles = outcome.triangles;
|
const auto &choosenTriangles = outcome.triangles;
|
||||||
|
const auto &choosenTriangleNormals = outcome.triangleNormals;
|
||||||
triangleVertexUvs.resize(choosenTriangles.size(), {
|
triangleVertexUvs.resize(choosenTriangles.size(), {
|
||||||
QVector2D(), QVector2D(), QVector2D()
|
QVector2D(), QVector2D(), QVector2D()
|
||||||
});
|
});
|
||||||
|
@ -32,11 +33,17 @@ void uvUnwrap(const Outcome &outcome,
|
||||||
for (decltype(choosenTriangles.size()) i = 0; i < choosenTriangles.size(); ++i) {
|
for (decltype(choosenTriangles.size()) i = 0; i < choosenTriangles.size(); ++i) {
|
||||||
const auto &triangle = choosenTriangles[i];
|
const auto &triangle = choosenTriangles[i];
|
||||||
const auto &sourceNode = triangleSourceNodes[i];
|
const auto &sourceNode = triangleSourceNodes[i];
|
||||||
|
const auto &normal = choosenTriangleNormals[i];
|
||||||
simpleuv::Face f;
|
simpleuv::Face f;
|
||||||
f.indices[0] = triangle[0];
|
f.indices[0] = triangle[0];
|
||||||
f.indices[1] = triangle[1];
|
f.indices[1] = triangle[1];
|
||||||
f.indices[2] = triangle[2];
|
f.indices[2] = triangle[2];
|
||||||
inputMesh.faces.push_back(f);
|
inputMesh.faces.push_back(f);
|
||||||
|
simpleuv::Vector3 n;
|
||||||
|
n.xyz[0] = normal.x();
|
||||||
|
n.xyz[1] = normal.y();
|
||||||
|
n.xyz[2] = normal.z();
|
||||||
|
inputMesh.faceNormals.push_back(n);
|
||||||
auto findPartitionResult = partIdToPartitionMap.find(sourceNode.first);
|
auto findPartitionResult = partIdToPartitionMap.find(sourceNode.first);
|
||||||
if (findPartitionResult == partIdToPartitionMap.end()) {
|
if (findPartitionResult == partIdToPartitionMap.end()) {
|
||||||
partitionPartUuids.push_back(sourceNode.first);
|
partitionPartUuids.push_back(sourceNode.first);
|
||||||
|
|
|
@ -25,6 +25,7 @@ private:
|
||||||
size_t m_tryNum = 0;
|
size_t m_tryNum = 0;
|
||||||
float m_textureSizeFactor = 1.0;
|
float m_textureSizeFactor = 1.0;
|
||||||
size_t m_maxTryNum = 100;
|
size_t m_maxTryNum = 100;
|
||||||
|
float m_texelSizePerUnit = 1.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
namespace simpleuv
|
namespace simpleuv
|
||||||
{
|
{
|
||||||
|
|
||||||
struct Vertex
|
struct Vector3
|
||||||
{
|
{
|
||||||
float xyz[3];
|
float xyz[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef Vector3 Vertex;
|
||||||
|
|
||||||
struct Face
|
struct Face
|
||||||
{
|
{
|
||||||
size_t indices[3];
|
size_t indices[3];
|
||||||
|
@ -30,6 +32,7 @@ struct Mesh
|
||||||
{
|
{
|
||||||
std::vector<Vertex> vertices;
|
std::vector<Vertex> vertices;
|
||||||
std::vector<Face> faces;
|
std::vector<Face> faces;
|
||||||
|
std::vector<Vector3> faceNormals;
|
||||||
std::vector<int> facePartitions;
|
std::vector<int> facePartitions;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <simpleuv/chartpacker.h>
|
#include <simpleuv/chartpacker.h>
|
||||||
#include <simpleuv/triangulate.h>
|
#include <simpleuv/triangulate.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QVector3D>
|
||||||
|
|
||||||
namespace simpleuv
|
namespace simpleuv
|
||||||
{
|
{
|
||||||
|
@ -60,6 +61,7 @@ void UvUnwrapper::splitPartitionToIslands(const std::vector<size_t> &group, std:
|
||||||
{
|
{
|
||||||
std::map<std::pair<size_t, size_t>, size_t> edgeToFaceMap;
|
std::map<std::pair<size_t, size_t>, size_t> edgeToFaceMap;
|
||||||
buildEdgeToFaceMap(group, edgeToFaceMap);
|
buildEdgeToFaceMap(group, edgeToFaceMap);
|
||||||
|
bool segmentByNormal = !m_mesh.faceNormals.empty() && m_segmentByNormal;
|
||||||
|
|
||||||
std::unordered_set<size_t> processedFaces;
|
std::unordered_set<size_t> processedFaces;
|
||||||
std::queue<size_t> waitFaces;
|
std::queue<size_t> waitFaces;
|
||||||
|
@ -79,6 +81,12 @@ void UvUnwrapper::splitPartitionToIslands(const std::vector<size_t> &group, std:
|
||||||
auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]});
|
auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]});
|
||||||
if (findOppositeFaceResult == edgeToFaceMap.end())
|
if (findOppositeFaceResult == edgeToFaceMap.end())
|
||||||
continue;
|
continue;
|
||||||
|
if (segmentByNormal) {
|
||||||
|
if (dotProduct(m_mesh.faceNormals[findOppositeFaceResult->second],
|
||||||
|
m_mesh.faceNormals[index]) < m_segmentDotProductThreshold) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
waitFaces.push(findOppositeFaceResult->second);
|
waitFaces.push(findOppositeFaceResult->second);
|
||||||
}
|
}
|
||||||
island.push_back(index);
|
island.push_back(index);
|
||||||
|
@ -98,6 +106,13 @@ double UvUnwrapper::distanceBetweenVertices(const Vertex &first, const Vertex &s
|
||||||
return std::sqrt(x*x + y*y + z*z);
|
return std::sqrt(x*x + y*y + z*z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double UvUnwrapper::dotProduct(const Vertex &first, const Vertex &second)
|
||||||
|
{
|
||||||
|
const QVector3D &firstVector = QVector3D(first.xyz[0], first.xyz[1], first.xyz[2]);
|
||||||
|
const QVector3D &secondVector = QVector3D(second.xyz[0], second.xyz[1], second.xyz[2]);
|
||||||
|
return QVector3D::dotProduct(firstVector, secondVector);
|
||||||
|
}
|
||||||
|
|
||||||
void UvUnwrapper::calculateFaceTextureBoundingBox(const std::vector<FaceTextureCoords> &faceTextureCoords,
|
void UvUnwrapper::calculateFaceTextureBoundingBox(const std::vector<FaceTextureCoords> &faceTextureCoords,
|
||||||
float &left, float &top, float &right, float &bottom)
|
float &left, float &top, float &right, float &bottom)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,6 +37,7 @@ private:
|
||||||
void buildEdgeToFaceMap(const std::vector<size_t> &group, std::map<std::pair<size_t, size_t>, size_t> &edgeToFaceMap);
|
void buildEdgeToFaceMap(const std::vector<size_t> &group, std::map<std::pair<size_t, size_t>, size_t> &edgeToFaceMap);
|
||||||
void buildEdgeToFaceMap(const std::vector<Face> &faces, std::map<std::pair<size_t, size_t>, size_t> &edgeToFaceMap);
|
void buildEdgeToFaceMap(const std::vector<Face> &faces, std::map<std::pair<size_t, size_t>, size_t> &edgeToFaceMap);
|
||||||
double distanceBetweenVertices(const Vertex &first, const Vertex &second);
|
double distanceBetweenVertices(const Vertex &first, const Vertex &second);
|
||||||
|
double dotProduct(const Vertex &first, const Vertex &second);
|
||||||
void triangulateRing(const std::vector<Vertex> &verticies,
|
void triangulateRing(const std::vector<Vertex> &verticies,
|
||||||
std::vector<Face> &faces, const std::vector<size_t> &ring);
|
std::vector<Face> &faces, const std::vector<size_t> &ring);
|
||||||
void calculateFaceTextureBoundingBox(const std::vector<FaceTextureCoords> &faceTextureCoords,
|
void calculateFaceTextureBoundingBox(const std::vector<FaceTextureCoords> &faceTextureCoords,
|
||||||
|
@ -49,6 +50,8 @@ private:
|
||||||
std::vector<std::pair<float, float>> m_chartSizes;
|
std::vector<std::pair<float, float>> m_chartSizes;
|
||||||
std::vector<QRectF> m_chartRects;
|
std::vector<QRectF> m_chartRects;
|
||||||
std::vector<int> m_chartSourcePartitions;
|
std::vector<int> m_chartSourcePartitions;
|
||||||
|
bool m_segmentByNormal = true;
|
||||||
|
float m_segmentDotProductThreshold = 0.00;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue