|
|
|
@ -4433,7 +4433,76 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView |
|
|
|
//*
|
|
|
|
//*
|
|
|
|
// 获取中心面片的法线 (注意变量名是 normalCenter, 不是 centerNormal)
|
|
|
|
// 获取中心面片的法线 (注意变量名是 normalCenter, 不是 centerNormal)
|
|
|
|
const Normal& normalCenter = scene.mesh.faceNormals[virtualFaceCenterFaceID]; |
|
|
|
const Normal& normalCenter = scene.mesh.faceNormals[virtualFaceCenterFaceID]; |
|
|
|
// 过滤selectedCams:只保留夹角小于30度的视图
|
|
|
|
|
|
|
|
|
|
|
|
std::map<IIndex, float> mapSortedcams; |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Point3f normalPoint(normalCenter.x, normalCenter.y, normalCenter.z); |
|
|
|
|
|
|
|
float cosAngle = cameraForward.dot(normalPoint); |
|
|
|
|
|
|
|
float angleDeg = std::acos(cosAngle) * 180.0f / M_PI; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::string strPath = imageData.name; |
|
|
|
|
|
|
|
std::string strName = MeshTexture::GetFileNameWithoutExtension(strPath); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!scene.is_face_delete_edge(strName, virtualFaceCenterFaceID)) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (scene.is_face_edge(strName, virtualFaceCenterFaceID)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (angleDeg <= 40.0f) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
mapSortedcams[idxView] = angleDeg; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
mapSortedcams[idxView] = angleDeg; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 将map中的元素放入vector以便排序
|
|
|
|
|
|
|
|
std::vector<std::pair<IIndex, float>> sortedCams; |
|
|
|
|
|
|
|
sortedCams.reserve(mapSortedcams.size()); |
|
|
|
|
|
|
|
for (const auto& pair : mapSortedcams) { |
|
|
|
|
|
|
|
sortedCams.emplace_back(pair.first, pair.second); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按angleDeg从小到大排序
|
|
|
|
|
|
|
|
std::sort(sortedCams.begin(), sortedCams.end(), |
|
|
|
|
|
|
|
[](const std::pair<IIndex, float>& a, const std::pair<IIndex, float>& b) { |
|
|
|
|
|
|
|
return a.second < b.second; // 按angleDeg排序
|
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IIndexArr filteredCams; |
|
|
|
|
|
|
|
size_t count = std::min(sortedCams.size(), static_cast<size_t>(3)); |
|
|
|
|
|
|
|
for (size_t i = 0; i < count; ++i) { |
|
|
|
|
|
|
|
filteredCams.push_back(sortedCams[i].first); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
IIndexArr filteredCams; // 用于存储过滤后的视图索引
|
|
|
|
IIndexArr filteredCams; // 用于存储过滤后的视图索引
|
|
|
|
for (IIndex idxView : selectedCams) { |
|
|
|
for (IIndex idxView : selectedCams) { |
|
|
|
const Image& imageData = images[idxView]; |
|
|
|
const Image& imageData = images[idxView]; |
|
|
|
@ -4467,17 +4536,18 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView |
|
|
|
float angleDeg = std::acos(cosAngle) * 180.0f / M_PI; // 将弧度转换为角度
|
|
|
|
float angleDeg = std::acos(cosAngle) * 180.0f / M_PI; // 将弧度转换为角度
|
|
|
|
|
|
|
|
|
|
|
|
std::string strPath = imageData.name; |
|
|
|
std::string strPath = imageData.name; |
|
|
|
size_t lastSlash = strPath.find_last_of("/\\"); |
|
|
|
std::string strName = MeshTexture::GetFileNameWithoutExtension(strPath); |
|
|
|
if (lastSlash == std::string::npos) lastSlash = 0; // 若无分隔符,从头开始
|
|
|
|
// size_t lastSlash = strPath.find_last_of("/\\");
|
|
|
|
else lastSlash++; // 跳过分隔符
|
|
|
|
// if (lastSlash == std::string::npos) lastSlash = 0; // 若无分隔符,从头开始
|
|
|
|
|
|
|
|
// else lastSlash++; // 跳过分隔符
|
|
|
|
// 查找扩展名分隔符 '.' 的位置
|
|
|
|
|
|
|
|
size_t lastDot = strPath.find_last_of('.'); |
|
|
|
|
|
|
|
if (lastDot == std::string::npos) lastDot = strPath.size(); // 若无扩展名,截到末尾
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 截取文件名(不含路径和扩展名)
|
|
|
|
// // 查找扩展名分隔符 '.' 的位置
|
|
|
|
std::string strName = strPath.substr(lastSlash, lastDot - lastSlash); |
|
|
|
// size_t lastDot = strPath.find_last_of('.');
|
|
|
|
|
|
|
|
// if (lastDot == std::string::npos) lastDot = strPath.size(); // 若无扩展名,截到末尾
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 截取文件名(不含路径和扩展名)
|
|
|
|
|
|
|
|
// std::string strName = strPath.substr(lastSlash, lastDot - lastSlash);
|
|
|
|
|
|
|
|
|
|
|
|
// printf("CreateVirtualFace %s, %d\n", strName.c_str(), virtualFaceCenterFaceID);
|
|
|
|
// printf("CreateVirtualFace %s, %d\n", strName.c_str(), virtualFaceCenterFaceID);
|
|
|
|
|
|
|
|
|
|
|
|
if (!scene.is_face_delete_edge(strName, virtualFaceCenterFaceID)) |
|
|
|
if (!scene.is_face_delete_edge(strName, virtualFaceCenterFaceID)) |
|
|
|
@ -4486,26 +4556,25 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView |
|
|
|
{ |
|
|
|
{ |
|
|
|
// printf("CreateVirtualFace %s, %d, %f\n", strName.c_str(), virtualFaceCenterFaceID, angleLimit);
|
|
|
|
// printf("CreateVirtualFace %s, %d, %f\n", strName.c_str(), virtualFaceCenterFaceID, angleLimit);
|
|
|
|
|
|
|
|
|
|
|
|
if (angleDeg <= 35.0f) |
|
|
|
if (angleDeg <= 40.0f) |
|
|
|
{ |
|
|
|
{ |
|
|
|
filteredCams.push_back(idxView); |
|
|
|
filteredCams.push_back(idxView); |
|
|
|
/*
|
|
|
|
|
|
|
|
float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数
|
|
|
|
// float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数
|
|
|
|
float angleScore = 1.0f - (angleDeg / 45.0f); |
|
|
|
// float angleScore = 1.0f - (angleDeg / 45.0f);
|
|
|
|
float qualityScore = 0.0f; |
|
|
|
// float qualityScore = 0.0f;
|
|
|
|
const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID]; |
|
|
|
// const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID];
|
|
|
|
for (const FaceData& fd : centerFaceDatas) { |
|
|
|
// for (const FaceData& fd : centerFaceDatas) {
|
|
|
|
if (fd.idxView == idxView) { |
|
|
|
// if (fd.idxView == idxView) {
|
|
|
|
qualityScore = fd.quality; |
|
|
|
// qualityScore = fd.quality;
|
|
|
|
break; |
|
|
|
// break;
|
|
|
|
} |
|
|
|
// }
|
|
|
|
} |
|
|
|
// }
|
|
|
|
qualityScore = std::max(0.0f, std::min(1.0f, qualityScore)); |
|
|
|
// qualityScore = std::max(0.0f, std::min(1.0f, qualityScore));
|
|
|
|
float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore; |
|
|
|
// float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore;
|
|
|
|
if (overallScore > 0.04f) { |
|
|
|
// if (overallScore > 0.04f) {
|
|
|
|
filteredCams.push_back(idxView); |
|
|
|
// filteredCams.push_back(idxView);
|
|
|
|
} |
|
|
|
// }
|
|
|
|
//*/
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
@ -4516,26 +4585,25 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView |
|
|
|
filteredCams.push_back(idxView); |
|
|
|
filteredCams.push_back(idxView); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
// float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数
|
|
|
|
float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数
|
|
|
|
// float angleScore = 1.0f - (angleDeg / 45.0f);
|
|
|
|
float angleScore = 1.0f - (angleDeg / 45.0f); |
|
|
|
// float qualityScore = 0.0f;
|
|
|
|
float qualityScore = 0.0f; |
|
|
|
// const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID];
|
|
|
|
const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID]; |
|
|
|
// for (const FaceData& fd : centerFaceDatas) {
|
|
|
|
for (const FaceData& fd : centerFaceDatas) { |
|
|
|
// if (fd.idxView == idxView) {
|
|
|
|
if (fd.idxView == idxView) { |
|
|
|
// qualityScore = fd.quality;
|
|
|
|
qualityScore = fd.quality; |
|
|
|
// break;
|
|
|
|
break; |
|
|
|
// }
|
|
|
|
} |
|
|
|
// }
|
|
|
|
} |
|
|
|
// qualityScore = std::max(0.0f, std::min(1.0f, qualityScore));
|
|
|
|
qualityScore = std::max(0.0f, std::min(1.0f, qualityScore)); |
|
|
|
// float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore;
|
|
|
|
float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore; |
|
|
|
// if (overallScore > 0.02f) {
|
|
|
|
if (overallScore > 0.02f) { |
|
|
|
// filteredCams.push_back(idxView);
|
|
|
|
filteredCams.push_back(idxView); |
|
|
|
// }
|
|
|
|
} |
|
|
|
|
|
|
|
//*/
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
// 确保 selectedCams 是非 const 的,才能对其进行赋值
|
|
|
|
// 确保 selectedCams 是非 const 的,才能对其进行赋值
|
|
|
|
// 例如,其声明应为:IIndexArr selectedCams = ...; (不能是 const IIndexArr)
|
|
|
|
// 例如,其声明应为:IIndexArr selectedCams = ...; (不能是 const IIndexArr)
|
|
|
|
|