|
|
|
|
@ -794,31 +794,102 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
@@ -794,31 +794,102 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
|
|
|
|
|
Mesh::Octree octree; |
|
|
|
|
Mesh::FacesInserter::CreateOctree(octree, scene.mesh); |
|
|
|
|
|
|
|
|
|
#ifdef TEXOPT_USE_OPENMP |
|
|
|
|
#pragma omp critical(invalid_faces_access) |
|
|
|
|
#endif |
|
|
|
|
{ |
|
|
|
|
// scene.mesh.invalidFaces.clear();
|
|
|
|
|
} |
|
|
|
|
// #ifdef TEXOPT_USE_OPENMP
|
|
|
|
|
// #pragma omp critical(invalid_faces_access)
|
|
|
|
|
// #endif
|
|
|
|
|
// {
|
|
|
|
|
// // scene.mesh.invalidFaces.clear();
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
std::vector<int> faceViewCount(faces.size(), 0); |
|
|
|
|
std::vector<std::vector<Color>> faceViewColors(faces.size()); // 存储每个面片在各个视图下的颜色
|
|
|
|
|
std::vector<std::vector<float>> faceViewQualities(faces.size()); // 存储每个面片在各个视图下的质量
|
|
|
|
|
|
|
|
|
|
// extract array of faces viewed by each image
|
|
|
|
|
IIndexArr views(_views); |
|
|
|
|
if (views.empty()) { |
|
|
|
|
views.resize(images.size()); |
|
|
|
|
std::iota(views.begin(), views.end(), IIndex(0)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Util::Progress progress(_T("Initialized views"), views.size()); |
|
|
|
|
FaceMap faceMap; |
|
|
|
|
DepthMap depthMap; |
|
|
|
|
|
|
|
|
|
// Temp
|
|
|
|
|
/*
|
|
|
|
|
Util::Progress progress1(_T("Initialized views"), views.size()); |
|
|
|
|
for (IIndex idxView: views) { |
|
|
|
|
Image& imageData = images[idxView]; |
|
|
|
|
if (!imageData.IsValid()) { |
|
|
|
|
++progress; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::string strPath = imageData.name; |
|
|
|
|
size_t lastSlash = strPath.find_last_of("/\\"); |
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
// load image
|
|
|
|
|
unsigned level(nResolutionLevel); |
|
|
|
|
const unsigned imageSize(imageData.RecomputeMaxResolution(level, nMinResolution)); |
|
|
|
|
if ((imageData.image.empty() || MAXF(imageData.width,imageData.height) != imageSize) && !imageData.ReloadImage(imageSize)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
imageData.UpdateCamera(scene.platforms); |
|
|
|
|
|
|
|
|
|
// select faces inside view frustum
|
|
|
|
|
Mesh::FaceIdxArr cameraFaces; |
|
|
|
|
Mesh::FacesInserter inserter(cameraFaces); |
|
|
|
|
const TFrustum<float,5> frustum(Matrix3x4f(imageData.camera.P), (float)imageData.width, (float)imageData.height); |
|
|
|
|
octree.Traverse(frustum, inserter); |
|
|
|
|
|
|
|
|
|
// project all triangles in this view and keep the closest ones
|
|
|
|
|
faceMap.create(imageData.GetSize()); |
|
|
|
|
depthMap.create(imageData.GetSize()); |
|
|
|
|
|
|
|
|
|
RasterMesh rasterer(*this, vertices, imageData.camera, depthMap, faceMap, scene.mesh, false); |
|
|
|
|
RasterMesh::Triangle triangle; |
|
|
|
|
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer); |
|
|
|
|
|
|
|
|
|
// 简化后的可见性检查
|
|
|
|
|
for (FIndex idxFace : cameraFaces) { |
|
|
|
|
rasterer.validFace = true; |
|
|
|
|
const Face& facet = faces[idxFace]; |
|
|
|
|
rasterer.idxFace = idxFace; |
|
|
|
|
|
|
|
|
|
// 只进行基本的可见性检查
|
|
|
|
|
if (scene.is_face_visible(strName.c_str(), idxFace)) { |
|
|
|
|
// 尝试投影
|
|
|
|
|
rasterer.Project(facet, triangleRasterizer); |
|
|
|
|
|
|
|
|
|
// 如果投影成功,增加计数
|
|
|
|
|
if (rasterer.validFace) { |
|
|
|
|
faceViewCount[idxFace]++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
++progress; |
|
|
|
|
} |
|
|
|
|
//*/
|
|
|
|
|
// Temp
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<Color>> faceViewColors(faces.size()); // 存储每个面片在各个视图下的颜色
|
|
|
|
|
std::vector<std::vector<float>> faceViewQualities(faces.size()); // 存储每个面片在各个视图下的质量
|
|
|
|
|
|
|
|
|
|
facesDatas.resize(faces.size()); |
|
|
|
|
// viewDepthMaps.resize(views.size()); // 初始化深度图存储
|
|
|
|
|
Util::Progress progress(_T("Initialized views"), views.size()); |
|
|
|
|
typedef float real; |
|
|
|
|
TImage<real> imageGradMag; |
|
|
|
|
TImage<real>::EMat mGrad[2]; |
|
|
|
|
FaceMap faceMap; |
|
|
|
|
DepthMap depthMap; |
|
|
|
|
|
|
|
|
|
Util::Progress progress2(_T("Processing views"), views.size()); |
|
|
|
|
|
|
|
|
|
#ifdef TEXOPT_USE_OPENMP |
|
|
|
|
bool bAbort(false); |
|
|
|
|
#pragma omp parallel for private(imageGradMag, mGrad, faceMap, depthMap) |
|
|
|
|
@ -957,29 +1028,34 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
@@ -957,29 +1028,34 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
|
|
|
|
|
const Face& facet = faces[idxFace]; |
|
|
|
|
rasterer.idxFace = idxFace; |
|
|
|
|
|
|
|
|
|
bool skipVisibilityCheck = false; |
|
|
|
|
bool normal_visible_check = false; |
|
|
|
|
|
|
|
|
|
int coverage = faceViewCount[idxFace]; |
|
|
|
|
|
|
|
|
|
if (coverage < 5) { |
|
|
|
|
skipVisibilityCheck = true; |
|
|
|
|
} |
|
|
|
|
// if (coverage<2||coverage>=8) {
|
|
|
|
|
// normal_visible_check = true;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
bool is_face_visible = scene.is_face_visible(strName.c_str(), idxFace); |
|
|
|
|
// bool is_face_normal_visible_map = scene.is_face_normal_visible_map(strName.c_str(), idxFace);
|
|
|
|
|
bool is_face_normal_visible_map = scene.is_face_normal_visible_map(strName.c_str(), idxFace); |
|
|
|
|
bool is_face_edge = scene.is_face_edge(strName.c_str(), idxFace); |
|
|
|
|
bool is_face_delete_edge = scene.is_face_delete_edge(strName.c_str(), idxFace); |
|
|
|
|
|
|
|
|
|
// if (is_face_visible && is_face_normal_visible_map)
|
|
|
|
|
if (is_face_visible) |
|
|
|
|
// if (skipVisibilityCheck || scene.is_face_visible(strName.c_str(), idxFace))
|
|
|
|
|
if (!is_face_edge) |
|
|
|
|
is_face_normal_visible_map = true; |
|
|
|
|
|
|
|
|
|
if (is_face_visible && is_face_normal_visible_map) |
|
|
|
|
// if (is_face_visible)
|
|
|
|
|
{ |
|
|
|
|
rasterer.Project(facet, triangleRasterizer); |
|
|
|
|
if (!rasterer.validFace) |
|
|
|
|
rasterer.Project(facet, triangleRasterizer); |
|
|
|
|
|
|
|
|
|
// 如果投影成功,增加面片覆盖率计数
|
|
|
|
|
// if (rasterer.validFace) {
|
|
|
|
|
// faceViewCount[idxFace]++;
|
|
|
|
|
// }
|
|
|
|
|
// 如果投影成功,增加面片覆盖率计数
|
|
|
|
|
// if (rasterer.validFace)
|
|
|
|
|
// {
|
|
|
|
|
// faceViewCount[idxFace]++;
|
|
|
|
|
// }
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1146,94 +1222,6 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
@@ -1146,94 +1222,6 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
|
|
|
|
|
++progress; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Temp
|
|
|
|
|
/*
|
|
|
|
|
// 第一步:计算每个面片的最终颜色(基于最接近平均颜色的3个视图)
|
|
|
|
|
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA |
|
|
|
|
Colors faceFinalColors; // 存储每个面片的最终颜色
|
|
|
|
|
std::vector<float> faceFinalQualities(faces.size(), 0.0f); // 存储每个面片的最终质量
|
|
|
|
|
|
|
|
|
|
// 使用循环初始化
|
|
|
|
|
for (size_t i = 0; i < faces.size(); ++i) { |
|
|
|
|
faceFinalColors.push_back(Color::ZERO); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (FIndex idxFace = 0; idxFace < faces.size(); ++idxFace) { |
|
|
|
|
const std::vector<Color>& colors = faceViewColors[idxFace]; |
|
|
|
|
const std::vector<float>& qualities = faceViewQualities[idxFace]; |
|
|
|
|
|
|
|
|
|
if (colors.empty()) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 1. 计算所有视图颜色的平均值
|
|
|
|
|
Color avgColor = Color::ZERO; |
|
|
|
|
for (const Color& color : colors) { |
|
|
|
|
avgColor += color; |
|
|
|
|
} |
|
|
|
|
avgColor /= (float)colors.size(); |
|
|
|
|
|
|
|
|
|
// 2. 计算每个视图颜色与平均值的差异
|
|
|
|
|
std::vector<std::pair<float, int>> colorDistances; // (距离, 索引)
|
|
|
|
|
colorDistances.reserve(colors.size()); |
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < colors.size(); ++i) { |
|
|
|
|
float distance = cv::norm(colors[i] - avgColor); |
|
|
|
|
colorDistances.emplace_back(distance, i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 3. 按距离排序(从小到大)
|
|
|
|
|
std::sort(colorDistances.begin(), colorDistances.end(), |
|
|
|
|
[](const std::pair<float, int>& a, const std::pair<float, int>& b) { |
|
|
|
|
return a.first < b.first; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
const Image& imageData = images[idxView]; |
|
|
|
|
std::string strPath = imageData.name; |
|
|
|
|
size_t lastSlash = strPath.find_last_of("/\\"); |
|
|
|
|
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); |
|
|
|
|
bool is_face_normal_visible_map = scene.is_face_normal_visible_map(strName.c_str(), idxFace); |
|
|
|
|
|
|
|
|
|
// 4. 只保留最接近的3个视图
|
|
|
|
|
size_t numToKeep = colorDistances.size(); // std::min((size_t)3, colorDistances.size());
|
|
|
|
|
Color finalColor = Color::ZERO; |
|
|
|
|
float finalQuality = 0.0f; |
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < numToKeep; ++i) { |
|
|
|
|
int viewIdx = colorDistances[i].second; |
|
|
|
|
finalColor += colors[viewIdx]; |
|
|
|
|
finalQuality += qualities[viewIdx]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// 5. 计算最终颜色和质量
|
|
|
|
|
finalColor /= (float)numToKeep; |
|
|
|
|
finalQuality /= (float)numToKeep; |
|
|
|
|
|
|
|
|
|
faceFinalColors[idxFace] = finalColor; |
|
|
|
|
faceFinalQualities[idxFace] = finalQuality; |
|
|
|
|
|
|
|
|
|
// 第二步:更新facesDatas,只保留最终颜色和质量
|
|
|
|
|
FaceDataArr& faceDatas = facesDatas[idxFace]; |
|
|
|
|
if (!faceDatas.empty()) { |
|
|
|
|
// 只保留第一个FaceData,并用最终颜色和质量更新它
|
|
|
|
|
faceDatas.resize(1); |
|
|
|
|
FaceData& faceData = faceDatas.back(); |
|
|
|
|
faceData.quality = finalQuality; |
|
|
|
|
faceData.color = finalColor; |
|
|
|
|
// 注意:这里不再保留原始的idxView,因为颜色是多个视图的混合
|
|
|
|
|
// 您可能需要根据需要调整idxView的值
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
//*/
|
|
|
|
|
// Temp
|
|
|
|
|
|
|
|
|
|
#ifdef TEXOPT_USE_OPENMP |
|
|
|
|
if (bAbort) |
|
|
|
|
return false; |
|
|
|
|
|