From da7536ea8f604ad98d24367f71a00193e23f03ea Mon Sep 17 00:00:00 2001 From: Jeremy HU Date: Wed, 2 Nov 2022 23:12:59 +1100 Subject: [PATCH] Resolve seam UV coords --- application/sources/uv_map_generator.cc | 26 +++++++++++++++++++++---- dust3d/uv/uv_map_packer.cc | 16 ++++++++++++++- dust3d/uv/uv_map_packer.h | 6 ++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/application/sources/uv_map_generator.cc b/application/sources/uv_map_generator.cc index 2ec6f2d3..054a4b02 100644 --- a/application/sources/uv_map_generator.cc +++ b/application/sources/uv_map_generator.cc @@ -132,10 +132,28 @@ void UvMapGenerator::generateTextureColorImage() colorTexturePainter.setPen(Qt::NoPen); for (const auto& layout : m_mapPacker->packedLayouts()) { - const QImage* image = ImageForever::get(layout.id); - if (nullptr == image) { - dust3dDebug << "Find image failed:" << layout.id.toString(); - continue; + const QImage* image = nullptr; + std::unique_ptr seamImage; + if (layout.isSeam) { + seamImage = std::make_unique(layout.imageWidth, layout.imageHeight, QImage::Format_ARGB32); + seamImage->fill(Qt::red); + for (const auto& it : layout.uvCopyMap) { + const auto& sourceImageId = m_mapPacker->packedLayouts()[it.first].id; + const QImage* sourceImage = ImageForever::get(sourceImageId); + if (nullptr == sourceImage) { + dust3dDebug << "Find image failed:" << sourceImageId.toString(); + continue; + } + // TODO: copy triangle UV from source to seam image + } + //dust3dDebug << "layout.imageWidth:" << layout.imageWidth << "layout.imageHeight:" << layout.imageHeight; + image = seamImage.get(); + } else { + image = ImageForever::get(layout.id); + if (nullptr == image) { + dust3dDebug << "Find image failed:" << layout.id.toString(); + continue; + } } QPixmap brushPixmap; if (layout.flipped) { diff --git a/dust3d/uv/uv_map_packer.cc b/dust3d/uv/uv_map_packer.cc index fc54a9bb..9d768663 100644 --- a/dust3d/uv/uv_map_packer.cc +++ b/dust3d/uv/uv_map_packer.cc @@ -68,6 +68,7 @@ void UvMapPacker::resolveSeamUvs() const auto& seam = m_seams[seamIndex]; double seamUvMapWidth = 0.0; double seamUvMapHeight = 0.0; + std::unordered_map, 2>> uvCopyMap; for (const auto& triangle : seam) { auto findUv = halfEdgeToUvMap.find({ triangle.first[0], triangle.first[1] }); if (findUv == halfEdgeToUvMap.end()) @@ -76,10 +77,19 @@ void UvMapPacker::resolveSeamUvs() 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; + uvCopyMap.insert({ triangleUv.partIndex, { triangleUv.uv, triangle.second } }); } + if (uvCopyMap.empty()) + continue; + Part newPart; + newPart.isSeam = true; + newPart.width = seamUvMapWidth; + newPart.height = seamUvMapHeight; + newPart.uvCopyMap = std::move(uvCopyMap); + newPart.localUv = seam; + m_partTriangleUvs.emplace_back(newPart); // dust3dDebug << "Seam uv map size:" << seamUvMapWidth << seamUvMapHeight; } - // TODO: } void UvMapPacker::pack() @@ -111,6 +121,10 @@ void UvMapPacker::pack() //dust3dDebug << "left:" << left << "top:" << top << "width:" << width << "height:" << height << "flipped:" << flipped; Layout layout; layout.id = part.id; + layout.isSeam = part.isSeam; + layout.imageWidth = part.width; + layout.imageHeight = part.height; + layout.uvCopyMap = part.uvCopyMap; layout.flipped = flipped; if (flipped) { layout.left = left; diff --git a/dust3d/uv/uv_map_packer.h b/dust3d/uv/uv_map_packer.h index 5a71d0ab..3873514a 100644 --- a/dust3d/uv/uv_map_packer.h +++ b/dust3d/uv/uv_map_packer.h @@ -28,6 +28,7 @@ #include #include #include +#include #include namespace dust3d { @@ -36,8 +37,10 @@ class UvMapPacker { public: struct Part { Uuid id; + bool isSeam = false; double width = 0.0; double height = 0.0; + std::unordered_map, 2>> uvCopyMap; std::map, std::array> localUv; }; @@ -49,6 +52,9 @@ public: double height = 0.0; bool flipped = false; bool isSeam = false; + size_t imageWidth = 0; + size_t imageHeight = 0; + std::unordered_map, 2>> uvCopyMap; std::map, std::array> globalUv; };