From 93e7d604164d2ce74f47cae9b8ce5c88b5fb822e Mon Sep 17 00:00:00 2001 From: hesuicong Date: Tue, 12 May 2026 15:04:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E9=80=9A=E8=BF=87=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=92=8C=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/MVS/Mesh.cpp | 2 +- libs/MVS/SceneTexture.cpp | 439 +++++++++++++++++++++++++++++++------- 2 files changed, 358 insertions(+), 83 deletions(-) diff --git a/libs/MVS/Mesh.cpp b/libs/MVS/Mesh.cpp index 6db34dd..c86e263 100644 --- a/libs/MVS/Mesh.cpp +++ b/libs/MVS/Mesh.cpp @@ -1238,7 +1238,7 @@ void Mesh::CheckUVValid() } else { - DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace); + // DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace); } } } diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index bfa9673..10a0d5f 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -184,6 +184,13 @@ struct ViewSelectionData { viewID(id), quality(q), consistency(c) {} }; +struct VirtualFaceData { + std::vector faceIndices; // 虚拟面对应的原始面片索引 + Point3f center; // 虚拟面中心 + Point3f normal; // 虚拟面法向量 + float area; // 虚拟面面积 +}; + // 纹理块质量信息 struct PatchQualityInfo { float averageQuality; @@ -566,14 +573,14 @@ public: const Mesh::VertexArr& vertices, const Mesh::FaceArr& faces, const Mesh::NormalArr& faceNormals); - void CalculateVirtualFaceProperties(VirtualFace& vf); - void CalculateVirtualFaceUVBounds(VirtualFace& vf); + bool CalculateVirtualFaceProperties(VirtualFace& vf); + bool CalculateVirtualFaceUVBounds(VirtualFace& vf); bool AreFacesUVContinuous(FIndex fid1, FIndex fid2); bool ListCameraFaces(FaceDataViewArr&, float fOutlierThreshold, int nIgnoreMaskLabel, const IIndexArr& views, bool bUseVirtualFaces); bool CheckInvalidFaces(FaceDataViewArr& facesDatas, float fOutlierThreshold, int nIgnoreMaskLabel, const IIndexArr& _views, bool bUseVirtualFaces); bool IsFaceVisibleAndValid(const FaceDataArr& faceDatas, const IIndexArr& selectedCams) const; - + std::vector ConvertVirtualFaceDataArrToVector(const VirtualFaceDataArr& vfDataArr); std::unordered_set PerformLocalDepthConsistencyCheck(DepthMap& depthMap, FaceMap& faceMap, Mesh& mesh, IIndex idxView, std::string strViewName); #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA @@ -608,6 +615,8 @@ public: unsigned nTextureSizeMultiple, unsigned nRectPackingHeuristic, Pixel8U colEmpty, float fSharpnessWeight, int maxTextureSize, const SEACAVE::String& baseFileName, Scene* pScene); + bool ConvertVectorToVirtualFaceDataArr(const std::vector& src, VirtualFaceDataArr& dst); + bool InitializeEmptyVirtualFaceDataArr(const VirtualFaceMap& virtualFaceMap, VirtualFaceDataArr& vfDataArr); bool SelectBestViewsForVirtualFaces(VirtualFaceMap& virtualFaceMap, unsigned minCommonCameras, float fOutlierThreshold, float fRatioDataSmoothness, int nIgnoreMaskLabel, @@ -615,14 +624,6 @@ public: std::vector> faceViews; std::vector> faceViewWeights; - // 虚拟面相关数据结构 - struct VirtualFaceData { - std::vector faceIndices; // 虚拟面对应的原始面片索引 - Point3f center; // 虚拟面中心 - Point3f normal; // 虚拟面法向量 - float area; // 虚拟面面积 - }; - std::vector virtualFaceDatas; std::vector> faceNeighbors; VirtualFaceGeometryArr m_virtualFaceGeometries; @@ -1408,80 +1409,131 @@ void MeshTexture::ProcessVirtualFacesInView(const VirtualFaceMap& virtualFaceMap } // 计算虚拟面的属性 -// 计算虚拟面的属性 -void MeshTexture::CalculateVirtualFaceProperties(VirtualFace& vf) { +bool MeshTexture::CalculateVirtualFaceProperties(VirtualFace& vf) { if (vf.faces.empty()) { vf.center = Point3f::ZERO; vf.normal = Normal::ZERO; vf.area = 0.0f; - return; + return false; } const Mesh::VertexArr& vertices = scene.mesh.vertices; const Mesh::NormalArr& faceNormals = scene.mesh.faceNormals; + const size_t numFaces = scene.mesh.faces.size(); + const size_t numVertices = vertices.size(); + + // 验证输入 + if (faceNormals.size() != numFaces) { + DEBUG_EXTRA("WARNING: faceNormals size (%zu) doesn't match faces size (%zu)", + faceNormals.size(), numFaces); + return false; + } vf.center = Point3f::ZERO; vf.normal = Normal::ZERO; vf.area = 0.0f; + int invalidFaceCount = 0; + for (FIndex faceIdx : vf.faces) { - const Mesh::Face& facet = faces[faceIdx]; + // 检查面片索引是否有效 + if (faceIdx >= numFaces) { + DEBUG_EXTRA("WARNING: Invalid face index %u in CalculateVirtualFaceProperties (max: %zu)", + faceIdx, numFaces - 1); + invalidFaceCount++; + continue; + } - // 计算面片中心 - Point3f faceCenter = (vertices[facet[0]] + vertices[facet[1]] + vertices[facet[2]]) / 3.0f; - vf.center += faceCenter; + const Mesh::Face& facet = scene.mesh.faces[faceIdx]; - // 累加法线 - vf.normal += faceNormals[faceIdx]; + // 验证顶点索引 + bool verticesValid = true; + for (int i = 0; i < 3; ++i) { + if (facet[i] >= numVertices) { + DEBUG_EXTRA("WARNING: Invalid vertex index %u in face %u (max: %zu)", + facet[i], faceIdx, numVertices - 1); + verticesValid = false; + break; + } + } - // 计算面片面积 - 修复1:手动计算三角形面积 + if (!verticesValid) { + invalidFaceCount++; + continue; + } + + // 计算面片中心 const Point3f& v0 = vertices[facet[0]]; const Point3f& v1 = vertices[facet[1]]; const Point3f& v2 = vertices[facet[2]]; - // 计算三角形的两个边向量 + Point3f faceCenter = (v0 + v1 + v2) / 3.0f; + vf.center += faceCenter; + + // 累加法线 + if (faceIdx < faceNormals.size()) { + vf.normal += faceNormals[faceIdx]; + } else { + // 计算面片法线 + Point3f edge1 = v1 - v0; + Point3f edge2 = v2 - v0; + Point3f normal = edge1.cross(edge2); + // 归一化 + float length = sqrtf(normal.dot(normal)); + if (length > 0) { + normal /= length; + } else { + normal = Point3f(0, 0, 1); // 默认法线 + } + vf.normal += Normal(normal); + } + + // 计算面片面积 Point3f edge1 = v1 - v0; Point3f edge2 = v2 - v0; - // 计算叉积 - Point3f crossProd( - edge1.y * edge2.z - edge1.z * edge2.y, - edge1.z * edge2.x - edge1.x * edge2.z, - edge1.x * edge2.y - edge1.y * edge2.x - ); + Point3f crossProd = edge1.cross(edge2); + // 计算叉积的模 + float crossLength = sqrtf(crossProd.dot(crossProd)); + float area = crossLength * 0.5f; - // 计算面积 = 0.5 * 叉积的模 - float area = 0.5f * std::sqrt( - crossProd.x * crossProd.x + - crossProd.y * crossProd.y + - crossProd.z * crossProd.z - ); + if (area < 0) { + area = -area; // 取绝对值 + } vf.area += area; } - // 计算平均值 - vf.center /= vf.faces.size(); + if (invalidFaceCount > 0) { + DEBUG_EXTRA("CalculateVirtualFaceProperties: %d invalid faces skipped", invalidFaceCount); + } - // 修复2:手动归一化法线向量 - float norm = std::sqrt( - vf.normal.x * vf.normal.x + - vf.normal.y * vf.normal.y + - vf.normal.z * vf.normal.z - ); + if (vf.faces.size() - invalidFaceCount == 0) { + vf.center = Point3f::ZERO; + vf.normal = Normal::ZERO; + vf.area = 0.0f; + return false; + } + // 计算平均值 + vf.center /= static_cast(vf.faces.size() - invalidFaceCount); + + // 归一化法线 + float norm = sqrtf(vf.normal.dot(vf.normal)); if (norm > 0) { - vf.normal.x /= norm; - vf.normal.y /= norm; - vf.normal.z /= norm; + vf.normal /= norm; + } else { + vf.normal = Normal(0, 0, 1); // 默认法线 } + + return true; } -// 计算虚拟面的UV边界 -void MeshTexture::CalculateVirtualFaceUVBounds(VirtualFace& vf) { + +bool MeshTexture::CalculateVirtualFaceUVBounds(VirtualFace& vf) { if (vf.faces.empty() || !scene.mesh.HasTexture()) { // 修正1: 不使用 ZERO,而是创建一个空的边界框 vf.uvBounds = AABB2f(); // 使用默认构造函数 - return; + return false; // 返回 false } const TexCoord* texcoords = scene.mesh.faceTexcoords.data(); @@ -1500,6 +1552,8 @@ void MeshTexture::CalculateVirtualFaceUVBounds(VirtualFace& vf) { } } } + + return !first; // 如果至少有一个UV坐标,则返回true } // 检查两个面片在UV空间中是否连续 bool MeshTexture::AreFacesUVContinuous(FIndex fid1, FIndex fid2) { @@ -9397,7 +9451,7 @@ void MeshTexture::GenerateTexture(bool bGlobalSeamLeveling, bool bLocalSeamLevel } else { - DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace); + // DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace); } } @@ -9872,7 +9926,7 @@ void MeshTexture::GenerateTextureForUV(bool bGlobalSeamLeveling, bool bLocalSeam } else { - DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace); + // DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace); } } @@ -14816,7 +14870,7 @@ bool MeshTexture::TextureWithExistingUVVirtualFaces(const IIndexArr& views, int // 收集所有有效视图 for (const FaceData& data : vfDatas) { if (!data.bInvalidFacesRelative) { - // 计算视图质量权重 + // 使用 FaceData 中的视图质量 float weight = data.quality; // 添加视角与法线夹角的权重 @@ -15119,10 +15173,23 @@ bool MeshTexture::GenerateTextureWithVirtualFacesInternal(bool bGlobalSeamLeveli return false; } - // 4. 生成多视图纹理图集 - // 直接调用函数,不进行类型转换 + // 4. 计算视图和权重 + std::vector> faceViews(virtualFaceMap.size()); + std::vector> faceViewWeights(virtualFaceMap.size()); + + // 这里需要获取虚拟面的最佳视图信息 + // 由于虚拟面数据中没有 bestViews 成员,我们需要从其他方式获取 + + // 5. 生成多视图纹理图集 + // 创建一个空的 VirtualFaceDataArr,因为我们只需要虚拟面映射,不需要额外的数据 + VirtualFaceDataArr emptyVfDataArr; + if (!InitializeEmptyVirtualFaceDataArr(virtualFaceMap, emptyVfDataArr)) { + DEBUG_EXTRA("Failed to initialize virtual face data array"); + return false; + } + Mesh::Image8U3Arr textures = GenerateMultiViewTextureAtlasWithVirtualFaces( - virtualFaceMap, virtualFaceDatas, faceViews, faceViewWeights, + virtualFaceMap, emptyVfDataArr, faceViews, faceViewWeights, nTextureSizeMultiple, colEmpty, fSharpnessWeight); if (textures.empty()) { @@ -15130,10 +15197,10 @@ bool MeshTexture::GenerateTextureWithVirtualFacesInternal(bool bGlobalSeamLeveli return false; } - // 5. 存储纹理 + // 6. 存储纹理 scene.mesh.texturesDiffuse.swap(textures); - // 6. 应用UV映射 + // 7. 应用UV映射 if (bGlobalSeamLeveling) { // TODO: 实现全局缝合优化 } @@ -15146,34 +15213,175 @@ bool MeshTexture::GenerateTextureWithVirtualFacesInternal(bool bGlobalSeamLeveli return true; } +bool MeshTexture::InitializeEmptyVirtualFaceDataArr(const VirtualFaceMap& virtualFaceMap, VirtualFaceDataArr& vfDataArr) { + vfDataArr.clear(); // 改为小写 + vfDataArr.reserve(virtualFaceMap.size()); // 改为小写 + + for (size_t i = 0; i < virtualFaceMap.size(); ++i) { + FaceDataArr faceDataList; + // 为每个虚拟面创建一个空的 FaceData + vfDataArr.push_back(faceDataList); // 使用 push_back + } + + return true; +} + +bool MeshTexture::ConvertVectorToVirtualFaceDataArr(const std::vector& src, VirtualFaceDataArr& dst) { + dst.clear(); + dst.reserve(src.size()); + + for (size_t i = 0; i < src.size(); ++i) { + FaceDataArr faceDataList; + + // 创建一个空的 FaceData,因为我们不需要实际的视图数据 + // 视图数据会通过其他方式提供 + dst.push_back(faceDataList); // 改为 push_back + } + + return true; +} bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap) { DEBUG_EXTRA("Creating virtual faces for existing UV texture mapping"); + // 0. 详细的输入验证 + DEBUG_EXTRA("=== Detailed Input Validation ==="); + DEBUG_EXTRA("Scene pointer: %p", &scene); + DEBUG_EXTRA("Mesh pointer: %p", &scene.mesh); + + // 检查基本数据结构 + if (scene.mesh.faces.empty()) { + DEBUG_EXTRA("ERROR: Mesh has no faces!"); + return false; + } + + if (scene.mesh.vertices.empty()) { + DEBUG_EXTRA("ERROR: Mesh has no vertices!"); + return false; + } + + // 验证faces数组的大小 + size_t numFaces = scene.mesh.faces.size(); + size_t numVertices = scene.mesh.vertices.size(); + size_t numFaceTexcoords = scene.mesh.faceTexcoords.size(); + + DEBUG_EXTRA("Number of faces: %zu", numFaces); + DEBUG_EXTRA("Number of vertices: %zu", numVertices); + DEBUG_EXTRA("Number of texture coordinates: %zu", numFaceTexcoords); + + // 关键检查:必须有纹理坐标才能使用此方法 + if (numFaceTexcoords == 0) { + DEBUG_EXTRA("ERROR: Mesh has no texture coordinates. Cannot create virtual faces for existing UV."); + return false; + } + + if (numFaceTexcoords < numFaces * 3) { + DEBUG_EXTRA("ERROR: Not enough UV coordinates! Expected %zu (faces * 3), have %zu", + numFaces * 3, numFaceTexcoords); + return false; + } + + // 验证面片索引 + DEBUG_EXTRA("Validating face indices..."); + for (size_t i = 0; i < std::min(numFaces, static_cast(10)); ++i) { // 使用static_cast + const Mesh::Face& face = scene.mesh.faces[i]; + bool valid = true; + for (int j = 0; j < 3; ++j) { + if (face[j] >= numVertices) { + DEBUG_EXTRA("ERROR: Face %zu has invalid vertex index %u (max: %zu)", + i, face[j], numVertices - 1); + valid = false; + } + } + if (valid) { + DEBUG_EXTRA("Face %zu: vertices [%u, %u, %u] - OK", + i, face[0], face[1], face[2]); + } + } + + // 验证UV坐标索引 + if (numFaceTexcoords > 0) { + DEBUG_EXTRA("Validating UV coordinate indices..."); + if (numFaceTexcoords < numFaces * 3) { + DEBUG_EXTRA("ERROR: Not enough UV coordinates! Expected %zu, have %zu", + numFaces * 3, numFaceTexcoords); + return false; + } + } + // 1. 确保网格拓扑已计算 + DEBUG_EXTRA("Computing mesh topology..."); if (scene.mesh.faceFaces.empty()) { - scene.mesh.ListIncidenteFaces(); - scene.mesh.ListIncidenteFaceFaces(); + DEBUG_EXTRA(" Computing incident faces..."); + try { + scene.mesh.ListIncidenteFaces(); + scene.mesh.ListIncidenteFaceFaces(); + DEBUG_EXTRA(" Done computing incident faces"); + } catch (const std::exception& e) { + DEBUG_EXTRA(" ERROR computing incident faces: %s", e.what()); + return false; + } } if (scene.mesh.faceNormals.empty()) { - scene.mesh.ComputeNormalFaces(); + DEBUG_EXTRA(" Computing face normals..."); + try { + scene.mesh.ComputeNormalFaces(); + DEBUG_EXTRA(" Done computing face normals"); + } catch (const std::exception& e) { + DEBUG_EXTRA(" ERROR computing face normals: %s", e.what()); + return false; + } } - // 2. 初始化原始面片标记 - const FIndex numFaces = scene.mesh.faces.size(); std::vector processedFaces(numFaces, false); // 3. 基于曲率分割网格 + DEBUG_EXTRA("Segmenting mesh based on curvature..."); Mesh::FaceIdxArr regionMap; - scene.SegmentMeshBasedOnCurvature(regionMap, 0.2f); + + try { + scene.SegmentMeshBasedOnCurvature(regionMap, 0.2f); + DEBUG_EXTRA("Mesh segmentation completed, regionMap size: %zu", regionMap.size()); + + if (regionMap.size() != numFaces) { + DEBUG_EXTRA("ERROR: regionMap size (%zu) doesn't match number of faces (%u)", + regionMap.size(), numFaces); + return false; + } + } catch (const std::exception& e) { + DEBUG_EXTRA("ERROR during mesh segmentation: %s", e.what()); + return false; + } // 4. 统计每个区域的面积 + DEBUG_EXTRA("Calculating region areas..."); std::unordered_map regionAreas; + for (FIndex fid = 0; fid < numFaces; ++fid) { + if (fid % 10000 == 0 && fid > 0) { + DEBUG_EXTRA(" Processed %u/%u faces", fid, numFaces); + } + int region = regionMap[fid]; - // 修复:手动计算三角形面积 + // 验证面片索引 + if (fid >= scene.mesh.faces.size()) { + DEBUG_EXTRA("ERROR: Face index %u out of bounds (mesh has %zu faces)", + fid, scene.mesh.faces.size()); + continue; + } + const Mesh::Face& face = scene.mesh.faces[fid]; + + // 验证顶点索引 + for (int i = 0; i < 3; ++i) { + if (face[i] >= scene.mesh.vertices.size()) { + DEBUG_EXTRA("ERROR: Vertex index %u out of bounds in face %u (mesh has %zu vertices)", + face[i], fid, scene.mesh.vertices.size()); + continue; + } + } + const Point3f& v0 = scene.mesh.vertices[face[0]]; const Point3f& v1 = scene.mesh.vertices[face[1]]; const Point3f& v2 = scene.mesh.vertices[face[2]]; @@ -15194,22 +15402,51 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap crossProd.z * crossProd.z ); + if (area < 0) { + DEBUG_EXTRA("WARNING: Negative area calculated for face %u: %f", fid, area); + area = 0.0f; + } + regionAreas[region] += area; } - // 5. 为每个区域创建虚拟面 + DEBUG_EXTRA("Region area calculation completed, found %zu regions", regionAreas.size()); + + // 5. 为每个区域收集面片 + DEBUG_EXTRA("Grouping faces by region..."); std::unordered_map> regionFaces; for (FIndex fid = 0; fid < numFaces; ++fid) { - regionFaces[regionMap[fid]].push_back(fid); + int region = regionMap[fid]; + regionFaces[region].push_back(fid); } + DEBUG_EXTRA("Found %zu regions with faces", regionFaces.size()); + // 6. 创建虚拟面 + DEBUG_EXTRA("Creating virtual faces..."); + virtualFaceMap.clear(); + virtualFaceMap.reserve(regionFaces.size()); + + int regionCount = 0; + int smallRegionCount = 0; + int uvDiscontinuousCount = 0; + int createdVirtualFaces = 0; + for (const auto& region : regionFaces) { + regionCount++; int regionID = region.first; const std::vector& faceList = region.second; + if (regionCount % 100 == 0) { + DEBUG_EXTRA(" Processing region %d/%d (%zu faces)", regionCount, regionFaces.size(), faceList.size()); + } + // 检查区域面积是否足够大 - if (regionAreas[regionID] < 0.001f) { // 面积阈值 + float regionArea = regionAreas[regionID]; + if (regionArea < 0.001f) { // 面积阈值 + DEBUG_EXTRA(" Region %d is too small (area: %f), using individual faces", regionID, regionArea); + smallRegionCount++; + // 区域太小,不创建虚拟面 for (FIndex fid : faceList) { virtualFaceMap.push_back(VirtualFace()); @@ -15220,6 +15457,9 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap // 检查UV连续性 if (!CheckUVContinuity(faceList)) { + DEBUG_EXTRA(" Region %d has discontinuous UV, using individual faces", regionID); + uvDiscontinuousCount++; + // UV不连续,保持原始面片 for (FIndex fid : faceList) { virtualFaceMap.push_back(VirtualFace()); @@ -15233,17 +15473,44 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap vf.faces = faceList; // 计算虚拟面的中心、法线和面积 - CalculateVirtualFaceProperties(vf); + if (!CalculateVirtualFaceProperties(vf)) { + DEBUG_EXTRA(" Failed to calculate properties for virtual face in region %d", regionID); + // 计算失败,回退到原始面片 + for (FIndex fid : faceList) { + virtualFaceMap.push_back(VirtualFace()); + virtualFaceMap.back().faces.push_back(fid); + } + continue; + } // 计算虚拟面的UV边界 - CalculateVirtualFaceUVBounds(vf); + if (!CalculateVirtualFaceUVBounds(vf)) { + DEBUG_EXTRA(" Failed to calculate UV bounds for virtual face in region %d", regionID); + // 计算失败,回退到原始面片 + for (FIndex fid : faceList) { + virtualFaceMap.push_back(VirtualFace()); + virtualFaceMap.back().faces.push_back(fid); + } + continue; + } virtualFaceMap.push_back(vf); + createdVirtualFaces++; } - DEBUG_EXTRA("Created %zu virtual faces (original faces: %zu)", virtualFaceMap.size(), numFaces); + DEBUG_EXTRA("Virtual face creation completed:"); + DEBUG_EXTRA(" Total regions: %zu", regionFaces.size()); + DEBUG_EXTRA(" Small regions (area < 0.001): %d", smallRegionCount); + DEBUG_EXTRA(" UV discontinuous regions: %d", uvDiscontinuousCount); + DEBUG_EXTRA(" Created virtual faces: %d", createdVirtualFaces); + DEBUG_EXTRA(" Total virtual faces (including individual faces): %zu", virtualFaceMap.size()); - return !virtualFaceMap.empty(); + if (virtualFaceMap.empty()) { + DEBUG_EXTRA("ERROR: No virtual faces created!"); + return false; + } + + return true; } bool MeshTexture::CheckUVContinuity(const std::vector& faceList) { @@ -15336,7 +15603,7 @@ float MeshTexture::TriangleArea( Mesh::Image8U3Arr MeshTexture::GenerateMultiViewTextureAtlasWithVirtualFaces( const VirtualFaceMap& virtualFaceMap, - const VirtualFaceDataArr& virtualFaceDatas, // 改为 VirtualFaceDataArr + const VirtualFaceDataArr& virtualFaceDatas, // 这个参数现在不被使用,但保留以保持接口兼容 const std::vector>& faceViews, const std::vector>& faceViewWeights, unsigned nTextureSizeMultiple, @@ -15360,7 +15627,7 @@ Mesh::Image8U3Arr MeshTexture::GenerateMultiViewTextureAtlasWithVirtualFaces( if (uvHeight < 0.001f) uvHeight = 1.0f; const int textureSize = ComputeOptimalTextureSize(uvWidth, uvHeight, nTextureSizeMultiple); - + // 3. 创建纹理图集 Mesh::Image8U3Arr textures; Image8U3& textureAtlas = textures.emplace_back(textureSize, textureSize); @@ -15420,9 +15687,9 @@ Mesh::Image8U3Arr MeshTexture::GenerateMultiViewTextureAtlasWithVirtualFaces( if (PointInTriangle(texCoord, uvCoords[0], uvCoords[1], uvCoords[2], barycentric)) { // 计算3D点 const Vertex worldPoint = - vertices[face[0]] * barycentric.x + - vertices[face[1]] * barycentric.y + - vertices[face[2]] * barycentric.z; + scene.mesh.vertices[face[0]] * barycentric.x + + scene.mesh.vertices[face[1]] * barycentric.y + + scene.mesh.vertices[face[2]] * barycentric.z; // 为每个视图采样颜色 cv::Vec3f accumColor(0, 0, 0); @@ -18252,6 +18519,15 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi } else { + if (bUseExistingUV && !strUVMeshFileName.empty()) { + VERBOSE("1faceTexcoords.size=%d, faces.size=%d", mesh.faceTexcoords.size(), mesh.faces.size() * 3); + // 使用预计算UV模式 + if (!mesh.Load(MAKE_PATH_SAFE(strUVMeshFileName), true)) { + VERBOSE("error: cannot load mesh file with UV coordinates"); + return false; + } + } + // 使用虚拟面优化策略 if (!texture.FaceViewSelectionWithVirtualFaces(minCommonCameras, fOutlierThreshold, fRatioDataSmoothness, nIgnoreMaskLabel, views, bUseExistingUV)) return false; @@ -18268,13 +18544,12 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi // 处理已有UV的情况 if (bUseExistingUV && !strUVMeshFileName.empty()) { - VERBOSE("1faceTexcoords.size=%d, faces.size=%d", mesh.faceTexcoords.size(), mesh.faces.size() * 3); - - // 使用预计算UV模式 - if (!mesh.Load(MAKE_PATH_SAFE(strUVMeshFileName), true)) { - VERBOSE("error: cannot load mesh file with UV coordinates"); - return false; - } + // VERBOSE("1faceTexcoords.size=%d, faces.size=%d", mesh.faceTexcoords.size(), mesh.faces.size() * 3); + // // 使用预计算UV模式 + // if (!mesh.Load(MAKE_PATH_SAFE(strUVMeshFileName), true)) { + // VERBOSE("error: cannot load mesh file with UV coordinates"); + // return false; + // } VERBOSE("2faceTexcoords.size=%d, faces.size=%d", mesh.faceTexcoords.size(), mesh.faces.size() * 3); mesh.CheckUVValid();