Segment UV by normal
parent
bde3c01da0
commit
f5a70dfd9e
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Vertex> vertices;
|
||||
std::vector<Face> faces;
|
||||
std::vector<Vector3> faceNormals;
|
||||
std::vector<int> facePartitions;
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <simpleuv/chartpacker.h>
|
||||
#include <simpleuv/triangulate.h>
|
||||
#include <QDebug>
|
||||
#include <QVector3D>
|
||||
|
||||
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;
|
||||
buildEdgeToFaceMap(group, edgeToFaceMap);
|
||||
bool segmentByNormal = !m_mesh.faceNormals.empty() && m_segmentByNormal;
|
||||
|
||||
std::unordered_set<size_t> processedFaces;
|
||||
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]});
|
||||
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> &faceTextureCoords,
|
||||
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<Face> &faces, std::map<std::pair<size_t, size_t>, size_t> &edgeToFaceMap);
|
||||
double distanceBetweenVertices(const Vertex &first, const Vertex &second);
|
||||
double dotProduct(const Vertex &first, const Vertex &second);
|
||||
void triangulateRing(const std::vector<Vertex> &verticies,
|
||||
std::vector<Face> &faces, const std::vector<size_t> &ring);
|
||||
void calculateFaceTextureBoundingBox(const std::vector<FaceTextureCoords> &faceTextureCoords,
|
||||
|
@ -49,6 +50,8 @@ private:
|
|||
std::vector<std::pair<float, float>> m_chartSizes;
|
||||
std::vector<QRectF> m_chartRects;
|
||||
std::vector<int> m_chartSourcePartitions;
|
||||
bool m_segmentByNormal = true;
|
||||
float m_segmentDotProductThreshold = 0.00;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue