From debbe84898424d28c119c26b3d577699cc638aba Mon Sep 17 00:00:00 2001 From: hesuicong Date: Tue, 28 Jul 2026 16:41:08 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/MVS/SceneTexture.cpp | 76 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 734d156..e011a5b 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -5993,6 +5993,36 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView IIndexArr selectedCams = SelectBestViews(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality); // IIndexArr selectedCams = SelectBestViews2(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality, facesDatas); + // ============ 新增:确定主视图 ============ + IIndex mainView = NO_ID; + float bestScore = -1.0f; + + for (const FaceData& fd : centerFaceDatas) { + if (fd.bInvalidFacesRelative) continue; + + const Image& img = images[fd.idxView]; + const RMatrix& R = img.camera.R; + Point3f camDir(-R(0,2), -R(1,2), -R(2,2)); + float norm = std::sqrt(camDir.x*camDir.x + camDir.y*camDir.y + camDir.z*camDir.z); + if (norm > 0) camDir /= norm; + + const Normal& n = scene.mesh.faceNormals[virtualFaceCenterFaceID]; + float cosAngle = camDir.dot(Point3f(n.x, n.y, n.z)); + + // 评分:质量为主,角度为辅 + float score = fd.quality * 0.7f + cosAngle * 0.3f; + if (score > bestScore) { + bestScore = score; + mainView = fd.idxView; + } + } + + // 保底:防止空虚拟面 + if (mainView == NO_ID && !selectedCams.empty()) { + mainView = selectedCams[0]; + } + // ========================================== + IIndexArr initialCams = selectedCams; IIndexArr filteredCams; @@ -6234,7 +6264,7 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView } } - printf("oldpush1 viewIdx=%d\n", viewIdx); + // printf("oldpush1 viewIdx=%d\n", viewIdx); if (mapProcessedViewIdx.count(viewIdx) > 0) continue; @@ -6338,11 +6368,55 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView if (cosFaceToCenter < dynamicCosTh) continue; + if (meshCurvatures[currentFaceId] > 0.2f) + continue; + // check if current face is seen by all cameras in selectedCams ASSERT(!selectedCams.empty()); if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams)) continue; + /* + // 获取主视图方向 + const Point3f& mainCamDir = cameraForwards[mainView]; + const Normal& n = scene.mesh.faceNormals[currentFaceId]; + float mainCosAngle = mainCamDir.dot(Point3f(n.x, n.y, n.z)); + + bool acceptable = false; + + for (const FaceData& fd : facesDatas[currentFaceId]) { + // if (fd.bInvalidFacesRelative) + // continue; + + const Point3f& camDir = cameraForwards[fd.idxView]; + float cosAngle = camDir.dot(Point3f(n.x, n.y, n.z)); + + // 如果是主视图,直接通过 + if (fd.idxView == mainView) { + acceptable = true; + break; + } + + // 如果不是主视图,但角度差不多(比如差10°以内) + float angleDiff = std::abs(std::acos(cosAngle) - std::acos(mainCosAngle)); + if (angleDiff < FD2R(60.0f)) + { // 10度以内 + acceptable = true; + break; + } + else + { + // DEBUG_EXTRA("!acceptable, angleDiff=%f, FD2R(50.0f)=%f\n", angleDiff, FD2R(50.0f)); + } + } + + if (!acceptable) + { + // DEBUG_EXTRA("!acceptable\n"); + continue; + } + */ + // 3. 放宽颜色差异条件 const Color& centerColor = faceColors[virtualFaceCenterFaceID]; const Color& currentColor = faceColors[currentFaceId];