diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 10a0d5f..e183d82 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -645,9 +645,6 @@ public: void LocalSeamLevelingExternalUV(); void GenerateTexture(bool bGlobalSeamLeveling, bool bLocalSeamLeveling, unsigned nTextureSizeMultiple, unsigned nRectPackingHeuristic, Pixel8U colEmpty, float fSharpnessWeight, int maxTextureSize, const SEACAVE::String& baseFileName, bool bOriginFaceview, Scene *pScene); - - void GenerateTextureForUV(bool bGlobalSeamLeveling, bool bLocalSeamLeveling, unsigned nTextureSizeMultiple, unsigned nRectPackingHeuristic, Pixel8U colEmpty, float fSharpnessWeight, int maxTextureSize, const SEACAVE::String& basename, bool bOriginFaceview, Scene *pScene, Mesh::TexCoordArr& existingTexcoords, Mesh::TexIndexArr& existingTexindices); - void GenerateTexture2(bool bGlobalSeamLeveling, bool bLocalSeamLeveling, unsigned nTextureSizeMultiple, unsigned nRectPackingHeuristic, Pixel8U colEmpty, float fSharpnessWeight, int maxTextureSize, const SEACAVE::String& baseFileName); bool TextureWithExistingUV( const IIndexArr& views, int nIgnoreMaskLabel, @@ -9870,358 +9867,6 @@ void MeshTexture::GenerateTexture(bool bGlobalSeamLeveling, bool bLocalSeamLevel } } -void MeshTexture::GenerateTextureForUV(bool bGlobalSeamLeveling, bool bLocalSeamLeveling, unsigned nTextureSizeMultiple, unsigned nRectPackingHeuristic, Pixel8U colEmpty, float fSharpnessWeight, int maxTextureSize, const SEACAVE::String& basename, bool bOriginFaceview, Scene *pScene, Mesh::TexCoordArr& existingTexcoords, Mesh::TexIndexArr& existingTexindices) -{ - int border = 2; - if (!bOriginFaceview) - border = 4; - - Mesh::TexCoordArr& faceTexcoords2 = existingTexcoords; - Mesh::TexIndexArr& faceTexindices2 = existingTexindices; - - faceTexcoords2.resize(faces.size()*3); - faceTexindices2.resize(faces.size()); - - #ifdef TEXOPT_USE_OPENMP - // LOG_OUT() << "def TEXOPT_USE_OPENMP" << std::endl; - const unsigned numPatches(texturePatches.size()-1); - - // ===== 修改:只在非外部UV模式下执行投影计算 ===== - - { - #pragma omp parallel for schedule(dynamic) - for (int_t idx=0; idx<(int_t)numPatches; ++idx) { - TexturePatch& texturePatch = texturePatches[(uint32_t)idx]; - #else - for (TexturePatch *pTexturePatch=texturePatches.Begin(), *pTexturePatchEnd=texturePatches.End()-1; pTexturePatch 2 && (bGlobalSeamLeveling || bLocalSeamLeveling)) { - // create seam vertices and edges - CreateSeamVertices(); - - // perform global seam leveling - if (bGlobalSeamLeveling) { - TD_TIMER_STARTD(); - if (bUseExternalUV) { - // 外部UV数据可能需要更温和的接缝处理 - GlobalSeamLevelingExternalUV(); - } else { - GlobalSeamLeveling3(); - } - DEBUG_EXTRA("\tglobal seam leveling completed (%s)", TD_TIMER_GET_FMT().c_str()); - } - - // perform local seam leveling - if (bLocalSeamLeveling) { - TD_TIMER_STARTD(); - // LocalSeamLeveling(); - if (bUseExternalUV) { - // 外部UV数据可能需要不同的局部接缝处理 - LocalSeamLevelingExternalUV(); - } else { - LocalSeamLeveling3(); - } - DEBUG_EXTRA("\tlocal seam leveling completed (%s)", TD_TIMER_GET_FMT().c_str()); - } - } - DEBUG_EXTRA("seam (%s)", TD_TIMER_GET_FMT().c_str()); - */ - - { - // merge texture patches with overlapping rectangles - for (unsigned i=0; i 0 && (texturePatches[i].rect.width > maxTextureSize || texturePatches[i].rect.height > maxTextureSize)) { - DEBUG("error: a patch of size %u x %u does not fit the texture", texturePatches[i].rect.width, texturePatches[i].rect.height); - ABORT("the maximum texture size chosen cannot fit a patch"); - } - unplacedRects[i] = {texturePatches[i].rect, i}; - } - LOG_OUT() << "unplacedRects loop completed" << std::endl; - - LOG_OUT() << "pack patches: one pack per texture file loop completed" << std::endl; - // pack patches: one pack per texture file - CLISTDEF2IDX(RectsBinPack::RectWIdxArr, TexIndex) placedRects; { - // increase texture size till all patches fit - // Bruce - unsigned typeRectsBinPack(nRectPackingHeuristic/100); - unsigned typeSplit((nRectPackingHeuristic-typeRectsBinPack*100)/10); - unsigned typeHeuristic(nRectPackingHeuristic%10); - if (!bOriginFaceview && false) - { - typeRectsBinPack = 1; - typeSplit = 0; - typeHeuristic = 1; - } - int textureSize = 0; - - { - while (!unplacedRects.empty()) { - TD_TIMER_STARTD(); - if (textureSize == 0) { - textureSize = RectsBinPack::ComputeTextureSize(unplacedRects, nTextureSizeMultiple); - if (maxTextureSize > 0 && textureSize > maxTextureSize) - textureSize = maxTextureSize; - } - - RectsBinPack::RectWIdxArr newPlacedRects; - switch (typeRectsBinPack) { - case 0: { - MaxRectsBinPack pack(textureSize, textureSize); - newPlacedRects = pack.Insert(unplacedRects, (MaxRectsBinPack::FreeRectChoiceHeuristic)typeHeuristic); - break; } - case 1: { - SkylineBinPack pack(textureSize, textureSize, typeSplit!=0); - newPlacedRects = pack.Insert(unplacedRects, (SkylineBinPack::LevelChoiceHeuristic)typeHeuristic); - break; } - case 2: { - GuillotineBinPack pack(textureSize, textureSize); - newPlacedRects = pack.Insert(unplacedRects, false, (GuillotineBinPack::FreeRectChoiceHeuristic)typeHeuristic, (GuillotineBinPack::GuillotineSplitHeuristic)typeSplit); - break; } - default: - ABORT("error: unknown RectsBinPack type"); - } - DEBUG_ULTIMATE("\tpacking texture completed: %u initial patches, %u placed patches, %u texture-size, %u textures (%s)", texturePatches.size(), newPlacedRects.size(), textureSize, placedRects.size(), TD_TIMER_GET_FMT().c_str()); - - if (textureSize == maxTextureSize || unplacedRects.empty()) { - // create texture image - placedRects.emplace_back(std::move(newPlacedRects)); - // Pixel8U colEmpty2=Pixel8U(0,0,255); - texturesDiffuseTemp.emplace_back(textureSize, textureSize).setTo(cv::Scalar(colEmpty.b, colEmpty.g, colEmpty.r)); - textureSize = 0; - } else { - // try again with a bigger texture - textureSize *= 2; - if (maxTextureSize > 0) - textureSize = std::max(textureSize, maxTextureSize); - unplacedRects.JoinRemove(newPlacedRects); - } - } - } - } - LOG_OUT() << "Third loop completed" << std::endl; - - Mesh::FaceIdxArr emptyFaceIndexes; - - { - #ifdef TEXOPT_USE_OPENMP - #pragma omp parallel for schedule(dynamic) - for (int_t i=0; i<(int_t)placedRects.size(); ++i) { - for (int_t j=0; j<(int_t)placedRects[(TexIndex)i].size(); ++j) { - const TexIndex idxTexture((TexIndex)i); - const uint32_t idxPlacedPatch((uint32_t)j); - #else - FOREACH(idxTexture, placedRects) { - FOREACH(idxPlacedPatch, placedRects[idxTexture]) { - #endif - const TexturePatch& texturePatch = texturePatches[placedRects[idxTexture][idxPlacedPatch].patchIdx]; - const RectsBinPack::Rect& rect = placedRects[idxTexture][idxPlacedPatch].rect; - // copy patch image - ASSERT((rect.width == texturePatch.rect.width && rect.height == texturePatch.rect.height) || - (rect.height == texturePatch.rect.width && rect.width == texturePatch.rect.height)); - int x(0), y(1); - if (texturePatch.label != NO_ID) { - const Image& imageData = images[texturePatch.label]; - cv::Mat patch(imageData.image(texturePatch.rect)); - if (rect.width != texturePatch.rect.width) { - // flip patch and texture-coordinates - patch = patch.t(); - x = 1; y = 0; - } - - patch.copyTo(texturesDiffuseTemp[idxTexture](rect)); - } - else - { - auto it = texturePatch.faces.begin(); - while (it != texturePatch.faces.end()) - { - emptyFaceIndexes.push_back(*it); - ++it; - } - } - // compute final texture coordinates - const TexCoord offset(rect.tl()); - for (const FIndex idxFace: texturePatch.faces) { - TexCoord* texcoords = faceTexcoords2.data()+idxFace*3; - faceTexindices2[idxFace] = idxTexture; - for (int v=0; v<3; ++v) { - TexCoord& texcoord = texcoords[v]; - texcoord = TexCoord( - texcoord[x]+offset.x, - texcoord[y]+offset.y - ); - } - } - } - } - } - if (texturesDiffuseTemp.size() == 1) - faceTexindices2.Release(); - - // apply some sharpening - if (fSharpnessWeight > 0) { - constexpr double sigma = 1.5; - for (auto &textureDiffuse: texturesDiffuseTemp) { - Image8U3 blurryTextureDiffuse; - cv::GaussianBlur(textureDiffuse, blurryTextureDiffuse, cv::Size(), sigma); - cv::addWeighted(textureDiffuse, 1+fSharpnessWeight, blurryTextureDiffuse, -fSharpnessWeight, 0, textureDiffuse); - } - } - LOG_OUT() << "Fourth loop completed" << std::endl; - - std::ofstream out(basename + "_empty_color_triangles.txt"); - RFOREACHPTR(pIdxF, emptyFaceIndexes) { - out << *pIdxF << "\n"; - } - out.close(); - } -} - void MeshTexture::GlobalSeamLevelingExternalUV() { // 针对外部UV数据的全局接缝处理 @@ -10679,251 +10324,6 @@ void MeshTexture::LocalSeamLeveling() } } -void MeshTexture::GenerateTexture2(bool bGlobalSeamLeveling, bool bLocalSeamLeveling, unsigned nTextureSizeMultiple, unsigned nRectPackingHeuristic, Pixel8U colEmpty, float fSharpnessWeight, int maxTextureSize, const SEACAVE::String& basename) -{ - // Bruce - bGlobalSeamLeveling = false; - bLocalSeamLeveling = false; - // project patches in the corresponding view and compute texture-coordinates and bounding-box - const int border(2); - faceTexcoords.resize(faces.size()*3); - faceTexindices.resize(faces.size()); - #ifdef TEXOPT_USE_OPENMP - // LOG_OUT() << "def TEXOPT_USE_OPENMP" << std::endl; - const unsigned numPatches(texturePatches.size()-1); - #pragma omp parallel for schedule(dynamic) - for (int_t idx=0; idx<(int_t)numPatches; ++idx) { - TexturePatch& texturePatch = texturePatches[(uint32_t)idx]; - #else - for (TexturePatch *pTexturePatch=texturePatches.Begin(), *pTexturePatchEnd=texturePatches.End()-1; pTexturePatch 2 && (bGlobalSeamLeveling || bLocalSeamLeveling)) { - // create seam vertices and edges - CreateSeamVertices(); - - // perform global seam leveling - if (bGlobalSeamLeveling) { - TD_TIMER_STARTD(); - GlobalSeamLeveling(); - DEBUG_ULTIMATE("\tglobal seam leveling completed (%s)", TD_TIMER_GET_FMT().c_str()); - } - - // perform local seam leveling - if (bLocalSeamLeveling) { - TD_TIMER_STARTD(); - LocalSeamLeveling(); - DEBUG_ULTIMATE("\tlocal seam leveling completed (%s)", TD_TIMER_GET_FMT().c_str()); - } - } - - // merge texture patches with overlapping rectangles - for (unsigned i=0; i 0 && (texturePatches[i].rect.width > maxTextureSize || texturePatches[i].rect.height > maxTextureSize)) { - DEBUG("error: a patch of size %u x %u does not fit the texture", texturePatches[i].rect.width, texturePatches[i].rect.height); - ABORT("the maximum texture size chosen cannot fit a patch"); - } - unplacedRects[i] = {texturePatches[i].rect, i}; - } - LOG_OUT() << "unplacedRects loop completed" << std::endl; - - LOG_OUT() << "pack patches: one pack per texture file loop completed" << std::endl; - // pack patches: one pack per texture file - CLISTDEF2IDX(RectsBinPack::RectWIdxArr, TexIndex) placedRects; { - // increase texture size till all patches fit - const unsigned typeRectsBinPack(nRectPackingHeuristic/100); - const unsigned typeSplit((nRectPackingHeuristic-typeRectsBinPack*100)/10); - const unsigned typeHeuristic(nRectPackingHeuristic%10); - int textureSize = 0; - while (!unplacedRects.empty()) { - TD_TIMER_STARTD(); - if (textureSize == 0) { - textureSize = RectsBinPack::ComputeTextureSize(unplacedRects, nTextureSizeMultiple); - if (maxTextureSize > 0 && textureSize > maxTextureSize) - textureSize = maxTextureSize; - } - - RectsBinPack::RectWIdxArr newPlacedRects; - switch (typeRectsBinPack) { - case 0: { - MaxRectsBinPack pack(textureSize, textureSize); - newPlacedRects = pack.Insert(unplacedRects, (MaxRectsBinPack::FreeRectChoiceHeuristic)typeHeuristic); - break; } - case 1: { - SkylineBinPack pack(textureSize, textureSize, typeSplit!=0); - newPlacedRects = pack.Insert(unplacedRects, (SkylineBinPack::LevelChoiceHeuristic)typeHeuristic); - break; } - case 2: { - GuillotineBinPack pack(textureSize, textureSize); - newPlacedRects = pack.Insert(unplacedRects, false, (GuillotineBinPack::FreeRectChoiceHeuristic)typeHeuristic, (GuillotineBinPack::GuillotineSplitHeuristic)typeSplit); - break; } - default: - ABORT("error: unknown RectsBinPack type"); - } - DEBUG_ULTIMATE("\tpacking texture completed: %u initial patches, %u placed patches, %u texture-size, %u textures (%s)", texturePatches.size(), newPlacedRects.size(), textureSize, placedRects.size(), TD_TIMER_GET_FMT().c_str()); - - if (textureSize == maxTextureSize || unplacedRects.empty()) { - // create texture image - placedRects.emplace_back(std::move(newPlacedRects)); - texturesDiffuse.emplace_back(textureSize, textureSize).setTo(cv::Scalar(colEmpty.b, colEmpty.g, colEmpty.r)); - textureSize = 0; - } else { - // try again with a bigger texture - textureSize *= 2; - if (maxTextureSize > 0) - textureSize = std::max(textureSize, maxTextureSize); - unplacedRects.JoinRemove(newPlacedRects); - } - } - } - LOG_OUT() << "Third loop completed" << std::endl; - Mesh::FaceIdxArr emptyFaceIndexes; - - #ifdef TEXOPT_USE_OPENMP - #pragma omp parallel for schedule(dynamic) - for (int_t i=0; i<(int_t)placedRects.size(); ++i) { - for (int_t j=0; j<(int_t)placedRects[(TexIndex)i].size(); ++j) { - const TexIndex idxTexture((TexIndex)i); - const uint32_t idxPlacedPatch((uint32_t)j); - #else - FOREACH(idxTexture, placedRects) { - FOREACH(idxPlacedPatch, placedRects[idxTexture]) { - #endif - const TexturePatch& texturePatch = texturePatches[placedRects[idxTexture][idxPlacedPatch].patchIdx]; - const RectsBinPack::Rect& rect = placedRects[idxTexture][idxPlacedPatch].rect; - // copy patch image - ASSERT((rect.width == texturePatch.rect.width && rect.height == texturePatch.rect.height) || - (rect.height == texturePatch.rect.width && rect.width == texturePatch.rect.height)); - int x(0), y(1); - if (texturePatch.label != NO_ID) { - const Image& imageData = images[texturePatch.label]; - cv::Mat patch(imageData.image(texturePatch.rect)); - if (rect.width != texturePatch.rect.width) { - // flip patch and texture-coordinates - patch = patch.t(); - x = 1; y = 0; - } - patch.copyTo(texturesDiffuse[idxTexture](rect)); - } - else - { - auto it = texturePatch.faces.begin(); - while (it != texturePatch.faces.end()) - { - emptyFaceIndexes.push_back(*it); - ++it; - } - } - // compute final texture coordinates - const TexCoord offset(rect.tl()); - for (const FIndex idxFace: texturePatch.faces) { - TexCoord* texcoords = faceTexcoords.data()+idxFace*3; - faceTexindices[idxFace] = idxTexture; - for (int v=0; v<3; ++v) { - TexCoord& texcoord = texcoords[v]; - texcoord = TexCoord( - texcoord[x]+offset.x, - texcoord[y]+offset.y - ); - } - } - } - } - if (texturesDiffuse.size() == 1) - faceTexindices.Release(); - // apply some sharpening - if (fSharpnessWeight > 0) { - constexpr double sigma = 1.5; - for (auto &textureDiffuse: texturesDiffuse) { - Image8U3 blurryTextureDiffuse; - cv::GaussianBlur(textureDiffuse, blurryTextureDiffuse, cv::Size(), sigma); - cv::addWeighted(textureDiffuse, 1+fSharpnessWeight, blurryTextureDiffuse, -fSharpnessWeight, 0, textureDiffuse); - } - } - LOG_OUT() << "Fourth loop completed" << std::endl; - - std::ofstream out(basename + "_empty_color_triangles.txt"); - RFOREACHPTR(pIdxF, emptyFaceIndexes) { - out << *pIdxF << "\n"; - } - out.close(); - } -} - #include // 保存生成的纹理图集 @@ -18538,7 +17938,7 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi } // 检查UV有效性 - mesh.CheckUVValid(); + // mesh.CheckUVValid(); DEBUG_EXTRA("TextureMesh bUseExistingUV=%d, UVMeshFile=%s", bUseExistingUV, strUVMeshFileName.c_str()); @@ -18552,7 +17952,7 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi // } VERBOSE("2faceTexcoords.size=%d, faces.size=%d", mesh.faceTexcoords.size(), mesh.faces.size() * 3); - mesh.CheckUVValid(); + // mesh.CheckUVValid(); // 确保网格包含UV坐标 if (mesh.faceTexcoords.empty()) { @@ -18580,7 +17980,7 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi } // 最终UV检查 - mesh.CheckUVValid(); + // mesh.CheckUVValid(); return true; } // TextureMesh