|
|
|
|
@ -5883,120 +5883,6 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
@@ -5883,120 +5883,6 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
|
|
|
|
|
cameraForwards[v] = forward; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
// 1. 计算每个视图的覆盖情况
|
|
|
|
|
Util::Progress progress1(_T("计算视图覆盖"), images.size()); |
|
|
|
|
for (IIndex idxView = 0; idxView < images.size(); ++idxView) { |
|
|
|
|
|
|
|
|
|
if (mapViewCoverageData.find(idxView) == mapViewCoverageData.end()) |
|
|
|
|
{ |
|
|
|
|
// 插入新对象
|
|
|
|
|
mapViewCoverageData.emplace(idxView, ViewCoverageData(idxView)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ViewCoverageData& viewData = mapViewCoverageData[idxView]; |
|
|
|
|
|
|
|
|
|
if (!images[idxView].IsValid()) { |
|
|
|
|
++progress1; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int coverageCount = 0; |
|
|
|
|
const Image& imageData = images[idxView]; |
|
|
|
|
|
|
|
|
|
// 计算相机方向
|
|
|
|
|
const RMatrix& R = imageData.camera.R; |
|
|
|
|
Point3f cameraForward( |
|
|
|
|
-R(0,2), // 相机坐标系中-Z轴是向前方向(从相机指向场景)
|
|
|
|
|
-R(1,2), |
|
|
|
|
-R(2,2) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// 归一化相机方向
|
|
|
|
|
const float normCameraForward = std::sqrt( |
|
|
|
|
cameraForward.x * cameraForward.x + |
|
|
|
|
cameraForward.y * cameraForward.y + |
|
|
|
|
cameraForward.z * cameraForward.z |
|
|
|
|
); |
|
|
|
|
if (normCameraForward > 0) { |
|
|
|
|
cameraForward /= normCameraForward; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
FaceDataViewArr facesDatasPreprocess; |
|
|
|
|
facesDatasPreprocess.resize(faces.size()); |
|
|
|
|
|
|
|
|
|
// 遍历所有面片,统计满足条件的面片
|
|
|
|
|
for (FIndex idxFace = 0; idxFace < faces.size(); ++idxFace) { |
|
|
|
|
// 跳过已处理的面片
|
|
|
|
|
if (processedFaces[idxFace]) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 检查面片是否有视图数据
|
|
|
|
|
if (facesDatas[idxFace].empty()) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 检查视图是否能看到这个面片
|
|
|
|
|
bool viewSeesFace = false; |
|
|
|
|
float bestQuality = 0.0f; |
|
|
|
|
|
|
|
|
|
for (const FaceData& fd : facesDatas[idxFace]) { |
|
|
|
|
if (fd.idxView == idxView && !fd.bInvalidFacesRelative) { |
|
|
|
|
viewSeesFace = true; |
|
|
|
|
if (fd.quality > bestQuality) { |
|
|
|
|
bestQuality = fd.quality; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!viewSeesFace) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 检查面片法线与相机方向的夹角
|
|
|
|
|
const Normal& faceNormal = scene.mesh.faceNormals[idxFace]; |
|
|
|
|
const float cosAngle = cameraForward.dot(Point3f(faceNormal.x, faceNormal.y, faceNormal.z)); |
|
|
|
|
|
|
|
|
|
if (cosAngle > fAngleThreshold2) |
|
|
|
|
{ |
|
|
|
|
coverageCount++; |
|
|
|
|
|
|
|
|
|
viewData.faceToIndexMap[idxFace] = idxFace; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cosAngle > fAngleThreshold1) |
|
|
|
|
{ |
|
|
|
|
// viewData.faceToIndexMap[idxFace] = idxFace;
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (coverageCount > 0) { |
|
|
|
|
viewCoverage.emplace_back(idxView, coverageCount); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
++progress1; |
|
|
|
|
} |
|
|
|
|
progress1.close(); |
|
|
|
|
|
|
|
|
|
// 2. 按覆盖数量对视图排序(从高到低)
|
|
|
|
|
std::sort(viewCoverage.begin(), viewCoverage.end(), |
|
|
|
|
[](const auto& a, const auto& b) { return a.second > b.second; }); |
|
|
|
|
|
|
|
|
|
// 打印排序结果
|
|
|
|
|
DEBUG_EXTRA("视图覆盖统计(按覆盖数量从高到低排序):"); |
|
|
|
|
int totalCoverage = 0; |
|
|
|
|
for (const auto& [idxView, coverage] : viewCoverage) { |
|
|
|
|
const Image& imageData = images[idxView]; |
|
|
|
|
DEBUG_EXTRA("视图 %s (索引 %d): 覆盖 %d 个面片", |
|
|
|
|
imageData.name.c_str(), idxView, coverage); |
|
|
|
|
totalCoverage += coverage; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DEBUG_EXTRA("排序后视图数量: %zu,最大覆盖: %d, 共%d", viewCoverage.size(), |
|
|
|
|
viewCoverage.empty() ? 0 : viewCoverage[0].second, totalCoverage); |
|
|
|
|
//*/
|
|
|
|
|
|
|
|
|
|
float thMaxColorDeviation = 130.0f; |
|
|
|
|
|
|
|
|
|
const float ratioAngleToQuality(0.67f); |
|
|
|
|
@ -6233,27 +6119,8 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
@@ -6233,27 +6119,8 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
|
|
|
|
|
for (IIndex idxView : selectedCams) |
|
|
|
|
{ |
|
|
|
|
const Image& imageData = images[idxView]; |
|
|
|
|
// 计算相机在世界坐标系中的朝向向量(相机镜面法线)
|
|
|
|
|
const RMatrix& R = imageData.camera.R; |
|
|
|
|
// 相机局部坐标系中的向前向量 (0,0,-1)
|
|
|
|
|
Point3f localForward(0.0f, 0.0f, -1.0f); |
|
|
|
|
// 手动计算矩阵乘法:cameraForward = R * localForward
|
|
|
|
|
Point3f cameraForward; |
|
|
|
|
cameraForward.x = R(0,0) * localForward.x + R(0,1) * localForward.y + R(0,2) * localForward.z; |
|
|
|
|
cameraForward.y = R(1,0) * localForward.x + R(1,1) * localForward.y + R(1,2) * localForward.z; |
|
|
|
|
cameraForward.z = R(2,0) * localForward.x + R(2,1) * localForward.y + R(2,2) * localForward.z; |
|
|
|
|
|
|
|
|
|
// 手动归一化 cameraForward
|
|
|
|
|
float norm = std::sqrt(cameraForward.x * cameraForward.x + |
|
|
|
|
cameraForward.y * cameraForward.y + |
|
|
|
|
cameraForward.z * cameraForward.z); |
|
|
|
|
if (norm > 0.0f) { |
|
|
|
|
cameraForward.x /= norm; |
|
|
|
|
cameraForward.y /= norm; |
|
|
|
|
cameraForward.z /= norm; |
|
|
|
|
} else { |
|
|
|
|
cameraForward = Point3f(0, 0, -1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const Point3f& cameraForward = cameraForwards[idxView]; |
|
|
|
|
|
|
|
|
|
Point3f normalPoint(normalCenter.x, normalCenter.y, normalCenter.z); |
|
|
|
|
float cosAngle = cameraForward.dot(normalPoint); |
|
|
|
|
@ -6322,63 +6189,6 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
@@ -6322,63 +6189,6 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
|
|
|
|
|
return a.second < b.second; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// if (filteredCams.empty()) {
|
|
|
|
|
// size_t count = std::min(sortedCams.size(), static_cast<size_t>(3));
|
|
|
|
|
// for (size_t i = 0; i < count; ++i) {
|
|
|
|
|
|
|
|
|
|
// // IIndex viewIdx = sortedCams[i].first;
|
|
|
|
|
// // float val = sortedCams[i].second;
|
|
|
|
|
// // const Image& imageData = images[viewIdx];
|
|
|
|
|
// // std::string strPath = imageData.name;
|
|
|
|
|
// // std::string strName = MeshTexture::GetFileNameWithoutExtension(strPath);
|
|
|
|
|
// // if (strName!="94_2")
|
|
|
|
|
// // continue;
|
|
|
|
|
|
|
|
|
|
// filteredCams.push_back(sortedCams[i].first);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (filteredCams.empty()) {
|
|
|
|
|
// // 处理所有视图都被过滤的情况...
|
|
|
|
|
// // DEBUG_EXTRA("Warning: All views filtered for virtual face due to angle condition.");
|
|
|
|
|
|
|
|
|
|
// selectedCams = SelectBestView(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality);
|
|
|
|
|
// isVirtualFace[virtualFaceCenterFaceID] = false;
|
|
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
// selectedCams = filteredCams;
|
|
|
|
|
// isVirtualFace[virtualFaceCenterFaceID] = true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// if (filteredCams.empty()) {
|
|
|
|
|
// // 尝试从 initialCams 或 viewCoverage 中找一个视图
|
|
|
|
|
// if (!initialCams.empty()) {
|
|
|
|
|
// filteredCams.push_back(initialCams[0]);
|
|
|
|
|
// } else if (!viewCoverage.empty()) {
|
|
|
|
|
// filteredCams.push_back(viewCoverage[0].first);
|
|
|
|
|
// } else {
|
|
|
|
|
// // 实在找不到任何视图,则作为孤立虚拟面片处理
|
|
|
|
|
// virtualFace.push_back(virtualFaceCenterFaceID);
|
|
|
|
|
// selectedFaces[virtualFaceCenterFaceID] = true;
|
|
|
|
|
// const auto pos = remainingFaces.FindFirst(virtualFaceCenterFaceID);
|
|
|
|
|
// if (pos != Mesh::FaceIdxArr::NO_INDEX) {
|
|
|
|
|
// remainingFaces.RemoveAtMove(pos);
|
|
|
|
|
// }
|
|
|
|
|
// // 创建空的虚拟面片数据(或使用默认视图)
|
|
|
|
|
// FaceDataArr vfd;
|
|
|
|
|
// vfd.emplace_back().quality = 0;
|
|
|
|
|
// vfd.back().idxView = NO_ID; // 或任意有效视图
|
|
|
|
|
// virtualFacesDatas.emplace_back(std::move(vfd));
|
|
|
|
|
// virtualFaces.emplace_back(std::move(virtualFace));
|
|
|
|
|
// continue; // 跳过后续区域增长
|
|
|
|
|
// }
|
|
|
|
|
// selectedCams = filteredCams;
|
|
|
|
|
// isVirtualFace[virtualFaceCenterFaceID] = true;
|
|
|
|
|
// } else {
|
|
|
|
|
// selectedCams = filteredCams;
|
|
|
|
|
// isVirtualFace[virtualFaceCenterFaceID] = true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
//*
|
|
|
|
|
int nViewCoverage = 0; |
|
|
|
|
int nViewCoverageMax = 100; |
|
|
|
|
@ -6513,28 +6323,6 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
@@ -6513,28 +6323,6 @@ bool MeshTexture::CreateVirtualFaces65(FaceDataViewArr& facesDatas, FaceDataView
|
|
|
|
|
isVirtualFace[virtualFaceCenterFaceID] = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 检查中心面片可见性
|
|
|
|
|
// if (!IsFaceVisible(facesDatas[virtualFaceCenterFaceID], selectedCams)) {
|
|
|
|
|
// virtualFace.push_back(virtualFaceCenterFaceID);
|
|
|
|
|
// selectedFaces[virtualFaceCenterFaceID] = true;
|
|
|
|
|
// const auto posToErase = remainingFaces.FindFirst(virtualFaceCenterFaceID);
|
|
|
|
|
// if (posToErase != Mesh::FaceIdxArr::NO_INDEX) {
|
|
|
|
|
// remainingFaces.RemoveAtMove(posToErase);
|
|
|
|
|
// }
|
|
|
|
|
// FaceDataArr virtualFaceData;
|
|
|
|
|
// FaceData& vfd = virtualFaceData.emplace_back();
|
|
|
|
|
// vfd.idxView = selectedCams[0]; // 此时 selectedCams 非空
|
|
|
|
|
// vfd.quality = 0.0f;
|
|
|
|
|
// for (const FaceData& fd : facesDatas[virtualFaceCenterFaceID]) {
|
|
|
|
|
// if (fd.idxView == selectedCams[0]) {
|
|
|
|
|
// vfd.quality = fd.quality;
|
|
|
|
|
// break;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// virtualFacesDatas.emplace_back(std::move(virtualFaceData));
|
|
|
|
|
// virtualFaces.emplace_back(std::move(virtualFace));
|
|
|
|
|
// continue;
|
|
|
|
|
// }
|
|
|
|
|
//*/
|
|
|
|
|
|
|
|
|
|
currentVirtualFaceQueue.AddTail(virtualFaceCenterFaceID); |
|
|
|
|
|