From f5a70dfd9e9653cd6245733055bb7505e79a0ee4 Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Fri, 9 Aug 2019 19:56:31 +0930 Subject: [PATCH] Segment UV by normal --- src/uvunwrap.cpp | 7 +++++++ thirdparty/simpleuv/simpleuv/chartpacker.h | 1 + thirdparty/simpleuv/simpleuv/meshdatatype.h | 5 ++++- thirdparty/simpleuv/simpleuv/uvunwrapper.cpp | 15 +++++++++++++++ thirdparty/simpleuv/simpleuv/uvunwrapper.h | 3 +++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/uvunwrap.cpp b/src/uvunwrap.cpp index c1993aed..59544d8e 100644 --- a/src/uvunwrap.cpp +++ b/src/uvunwrap.cpp @@ -10,6 +10,7 @@ void uvUnwrap(const Outcome &outcome, { const auto &choosenVertices = outcome.vertices; const auto &choosenTriangles = outcome.triangles; + const auto &choosenTriangleNormals = outcome.triangleNormals; triangleVertexUvs.resize(choosenTriangles.size(), { QVector2D(), QVector2D(), QVector2D() }); @@ -32,11 +33,17 @@ void uvUnwrap(const Outcome &outcome, for (decltype(choosenTriangles.size()) i = 0; i < choosenTriangles.size(); ++i) { const auto &triangle = choosenTriangles[i]; const auto &sourceNode = triangleSourceNodes[i]; + const auto &normal = choosenTriangleNormals[i]; simpleuv::Face f; f.indices[0] = triangle[0]; f.indices[1] = triangle[1]; f.indices[2] = triangle[2]; 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); if (findPartitionResult == partIdToPartitionMap.end()) { partitionPartUuids.push_back(sourceNode.first); diff --git a/thirdparty/simpleuv/simpleuv/chartpacker.h b/thirdparty/simpleuv/simpleuv/chartpacker.h index 732a86e2..fd28edce 100644 --- a/thirdparty/simpleuv/simpleuv/chartpacker.h +++ b/thirdparty/simpleuv/simpleuv/chartpacker.h @@ -25,6 +25,7 @@ private: size_t m_tryNum = 0; float m_textureSizeFactor = 1.0; size_t m_maxTryNum = 100; + float m_texelSizePerUnit = 1.0f; }; } diff --git a/thirdparty/simpleuv/simpleuv/meshdatatype.h b/thirdparty/simpleuv/simpleuv/meshdatatype.h index 594fc3ed..e83bd17e 100644 --- a/thirdparty/simpleuv/simpleuv/meshdatatype.h +++ b/thirdparty/simpleuv/simpleuv/meshdatatype.h @@ -6,11 +6,13 @@ namespace simpleuv { -struct Vertex +struct Vector3 { float xyz[3]; }; +typedef Vector3 Vertex; + struct Face { size_t indices[3]; @@ -30,6 +32,7 @@ struct Mesh { std::vector vertices; std::vector faces; + std::vector faceNormals; std::vector facePartitions; }; diff --git a/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp b/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp index 1beccd30..d14d50af 100644 --- a/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp +++ b/thirdparty/simpleuv/simpleuv/uvunwrapper.cpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace simpleuv { @@ -60,6 +61,7 @@ void UvUnwrapper::splitPartitionToIslands(const std::vector &group, std: { std::map, size_t> edgeToFaceMap; buildEdgeToFaceMap(group, edgeToFaceMap); + bool segmentByNormal = !m_mesh.faceNormals.empty() && m_segmentByNormal; std::unordered_set processedFaces; std::queue waitFaces; @@ -79,6 +81,12 @@ void UvUnwrapper::splitPartitionToIslands(const std::vector &group, std: auto findOppositeFaceResult = edgeToFaceMap.find({face.indices[j], face.indices[i]}); if (findOppositeFaceResult == edgeToFaceMap.end()) continue; + if (segmentByNormal) { + if (dotProduct(m_mesh.faceNormals[findOppositeFaceResult->second], + m_mesh.faceNormals[index]) < m_segmentDotProductThreshold) { + continue; + } + } waitFaces.push(findOppositeFaceResult->second); } 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); } +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, float &left, float &top, float &right, float &bottom) { diff --git a/thirdparty/simpleuv/simpleuv/uvunwrapper.h b/thirdparty/simpleuv/simpleuv/uvunwrapper.h index 546390bc..ab01b222 100644 --- a/thirdparty/simpleuv/simpleuv/uvunwrapper.h +++ b/thirdparty/simpleuv/simpleuv/uvunwrapper.h @@ -37,6 +37,7 @@ private: void buildEdgeToFaceMap(const std::vector &group, std::map, size_t> &edgeToFaceMap); void buildEdgeToFaceMap(const std::vector &faces, std::map, size_t> &edgeToFaceMap); double distanceBetweenVertices(const Vertex &first, const Vertex &second); + double dotProduct(const Vertex &first, const Vertex &second); void triangulateRing(const std::vector &verticies, std::vector &faces, const std::vector &ring); void calculateFaceTextureBoundingBox(const std::vector &faceTextureCoords, @@ -49,6 +50,8 @@ private: std::vector> m_chartSizes; std::vector m_chartRects; std::vector m_chartSourcePartitions; + bool m_segmentByNormal = true; + float m_segmentDotProductThreshold = 0.00; }; }