diff --git a/application/sources/uv_map_generator.cc b/application/sources/uv_map_generator.cc index dda507a8..2ec6f2d3 100644 --- a/application/sources/uv_map_generator.cc +++ b/application/sources/uv_map_generator.cc @@ -115,31 +115,9 @@ void UvMapGenerator::packUvs() m_mapPacker->addPart(part); } - m_mapPacker->pack(); -} + m_mapPacker->addSeams(m_object->seamTriangleUvs); -void UvMapGenerator::filterSeamUvs() -{ - /* - dust3dDebug << "m_object->seamTriangleUvs.size():" << m_object->seamTriangleUvs.size(); - std::map, size_t> triangleMap; - for (size_t i = 0; i < m_object->seamTriangleUvs.size(); ++i) { - for (const auto& it : m_object->seamTriangleUvs[i]) { - triangleMap.insert({ it.first, i }); - } - // TODO: - } - std::unordered_set seams; - size_t uvTriangleCount = 0; - for (const auto& triangle : m_object->triangles) { - auto findResult = triangleMap.find(std::array { m_object->vertices[triangle[0]], m_object->vertices[triangle[1]], m_object->vertices[triangle[2]] }); - if (triangleMap.end() != findResult) { - ++uvTriangleCount; - seams.insert(findResult->second); - } - } - dust3dDebug << "uvTriangleCount:" << uvTriangleCount << "seams:" << seams.size(); - */ + m_mapPacker->pack(); } void UvMapGenerator::generateTextureColorImage() @@ -214,7 +192,6 @@ void UvMapGenerator::generate() if (nullptr == m_snapshot) return; - filterSeamUvs(); packUvs(); generateTextureColorImage(); generateUvCoords(); diff --git a/application/sources/uv_map_generator.h b/application/sources/uv_map_generator.h index 404598cc..9e216ce5 100644 --- a/application/sources/uv_map_generator.h +++ b/application/sources/uv_map_generator.h @@ -45,7 +45,6 @@ private: void packUvs(); void generateTextureColorImage(); void generateUvCoords(); - void filterSeamUvs(); }; #endif diff --git a/dust3d/uv/uv_map_packer.cc b/dust3d/uv/uv_map_packer.cc index 3d92b69c..fc54a9bb 100644 --- a/dust3d/uv/uv_map_packer.cc +++ b/dust3d/uv/uv_map_packer.cc @@ -35,11 +35,60 @@ void UvMapPacker::addPart(const Part& part) m_partTriangleUvs.push_back(part); } +void UvMapPacker::addSeams(const std::vector, std::array>>& seamTriangleUvs) +{ + for (const auto& it : seamTriangleUvs) + m_seams.push_back(it); +} + +void UvMapPacker::resolveSeamUvs() +{ + struct TriangleUv { + size_t partIndex; + std::array uv; + }; + + std::map, TriangleUv> halfEdgeToUvMap; + for (size_t partIndex = 0; partIndex < m_partTriangleUvs.size(); ++partIndex) { + const auto& part = m_partTriangleUvs[partIndex]; + for (const auto& it : part.localUv) { + halfEdgeToUvMap.insert(std::make_pair(std::array { + it.first[1], it.first[0] }, + TriangleUv { partIndex, it.second })); + halfEdgeToUvMap.insert(std::make_pair(std::array { + it.first[2], it.first[1] }, + TriangleUv { partIndex, it.second })); + halfEdgeToUvMap.insert(std::make_pair(std::array { + it.first[0], it.first[2] }, + TriangleUv { partIndex, it.second })); + } + } + + for (size_t seamIndex = 0; seamIndex < m_seams.size(); ++seamIndex) { + const auto& seam = m_seams[seamIndex]; + double seamUvMapWidth = 0.0; + double seamUvMapHeight = 0.0; + for (const auto& triangle : seam) { + auto findUv = halfEdgeToUvMap.find({ triangle.first[0], triangle.first[1] }); + if (findUv == halfEdgeToUvMap.end()) + continue; + const auto& triangleUv = findUv->second; + const auto& part = m_partTriangleUvs[triangleUv.partIndex]; + seamUvMapWidth += std::abs(triangleUv.uv[0].x() - triangleUv.uv[1].x()) * part.width; + seamUvMapHeight += std::abs(triangleUv.uv[0].y() - triangleUv.uv[1].y()) * part.height; + } + // dust3dDebug << "Seam uv map size:" << seamUvMapWidth << seamUvMapHeight; + } + // TODO: +} + void UvMapPacker::pack() { if (m_partTriangleUvs.empty()) return; + resolveSeamUvs(); + std::vector> chartSizes(m_partTriangleUvs.size()); for (size_t i = 0; i < m_partTriangleUvs.size(); ++i) { const auto& part = m_partTriangleUvs[i]; diff --git a/dust3d/uv/uv_map_packer.h b/dust3d/uv/uv_map_packer.h index 9b0084a4..5a71d0ab 100644 --- a/dust3d/uv/uv_map_packer.h +++ b/dust3d/uv/uv_map_packer.h @@ -36,23 +36,25 @@ class UvMapPacker { public: struct Part { Uuid id; - double width; - double height; + double width = 0.0; + double height = 0.0; std::map, std::array> localUv; }; struct Layout { Uuid id; - double left; - double top; - double width; - double height; - bool flipped; + double left = 0.0; + double top = 0.0; + double width = 0.0; + double height = 0.0; + bool flipped = false; + bool isSeam = false; std::map, std::array> globalUv; }; UvMapPacker(); void addPart(const Part& part); + void addSeams(const std::vector, std::array>>& seamTriangleUvs); void pack(); const std::vector& packedLayouts(); double packedTextureSize(); @@ -60,7 +62,10 @@ public: private: std::vector m_partTriangleUvs; std::vector m_packedLayouts; + std::vector, std::array>> m_seams; double m_packedTextureSize = 0.0; + + void resolveSeamUvs(); }; }