Browse Source

代码整理

ManualUV
hesuicong 3 weeks ago
parent
commit
56ad2c49cb
  1. 137
      libs/MVS/SceneTexture.cpp

137
libs/MVS/SceneTexture.cpp

@ -18717,99 +18717,82 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi @@ -18717,99 +18717,82 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi
}
#endif
// assign the best view to each face
// ========== 视图选择总入口 ==========
{
TD_TIMER_STARTD();
if (bOriginFaceview)
{
// 使用原始面片视图选择
if (bOriginFaceview) {
// 1. 原始面片模式
if (!texture.FaceViewSelection(minCommonCameras, fOutlierThreshold, fRatioDataSmoothness, nIgnoreMaskLabel, views))
return false;
}
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;
} else if (bUseExistingUV && !strUVMeshFileName.empty()) {
// 2. 已有UV专用模式(只走这里,不要后面的重复分支)
VERBOSE("faceTexcoords.size=%d, faces.size=%d", mesh.faceTexcoords.size(), mesh.faces.size() * 3);
DEBUG_EXTRA("Virtual face view selection completed: %u faces (%s)", mesh.faces.size(), TD_TIMER_GET_FMT().c_str());
}
DEBUG_EXTRA("Assigning the best view to each face completed: %u faces (%s)", mesh.faces.size(), TD_TIMER_GET_FMT().c_str());
}
// 检查UV有效性
// mesh.CheckUVValid();
DEBUG_EXTRA("TextureMesh bUseExistingUV=%d, UVMeshFile=%s", bUseExistingUV, strUVMeshFileName.c_str());
// 处理已有UV的情况
if (bUseExistingUV && !strUVMeshFileName.empty()) {
MeshTexture texture(*this, nResolutionLevel, nMinResolution);
// 加载带UV的mesh
if (!mesh.Load(MAKE_PATH_SAFE(strUVMeshFileName), true)) {
VERBOSE("error: cannot load mesh file with UV coordinates");
return false;
}
// ✅ 只用“纯可见性”,绝不碰 FaceViewSelection
if (!texture.ComputePureFaceVisibility(
fOutlierThreshold,
nIgnoreMaskLabel,
views)) {
return false;
}
// 纯可见性计算(初始化faceNeighbors)
if (!texture.ComputePureFaceVisibility(fOutlierThreshold, nIgnoreMaskLabel, views)) {
// ❗ 兜底:如果ComputePureFaceVisibility没初始化faceNeighbors,手动填充
if (texture.faceNeighbors.empty()) {
texture.faceNeighbors.resize(mesh.faces.size());
for (FIndex fid = 0; fid < (FIndex)mesh.faces.size(); ++fid) {
if (!views.empty()) {
texture.faceNeighbors[fid].insert(texture.faceNeighbors[fid].end(), views.begin(), views.end());
} else {
for (IIndex vid = 0; vid < (IIndex)images.size(); ++vid)
texture.faceNeighbors[fid].push_back(vid);
}
}
DEBUG_EXTRA("Forced fill faceNeighbors for %zu faces", mesh.faces.size());
}
return false;
}
// ✅ 现在 faces 没动过,faceNeighbors 是对齐的
MeshTexture::VirtualFaceMap virtualFaceMap;
if (!texture.CreateVirtualFacesForExistingUV(virtualFaceMap)) {
return false;
}
// 创建虚拟面(1:1映射)
MeshTexture::VirtualFaceMap virtualFaceMap;
if (!texture.CreateVirtualFacesForExistingUV(virtualFaceMap)) return false;
if (!texture.SelectBestViewsForVirtualFaces(
virtualFaceMap,
1, // 单视图就够了
fOutlierThreshold,
fRatioDataSmoothness,
nIgnoreMaskLabel,
views)) {
return false;
}
// 选最佳视图(带patch一致性)
if (!texture.SelectBestViewsForVirtualFaces(
virtualFaceMap, 1, fOutlierThreshold, fRatioDataSmoothness, nIgnoreMaskLabel, views))
return false;
// 直接光栅化
Mesh::Image8U3Arr textures;
if (!texture.RasterizeVirtualFaces(
virtualFaceMap,
texture.faceViews,
texture.faceViewWeights,
nTextureSizeMultiple,
colEmpty,
textures)) {
return false;
}
// 直接光栅化(不需要生成图集)
Mesh::Image8U3Arr textures;
if (!texture.RasterizeVirtualFaces(
virtualFaceMap, texture.faceViews, texture.faceViewWeights,
nTextureSizeMultiple, colEmpty, textures))
return false;
mesh.texturesDiffuse = std::move(textures);
return true;
}
mesh.texturesDiffuse = std::move(textures);
DEBUG_EXTRA("Existing UV texturing completed: %u faces (%s)", mesh.faces.size(), TD_TIMER_GET_FMT().c_str());
return true; // 直接返回,不走后面的图集逻辑
} else {
// 3. 通用虚拟面模式(无预计算UV)
if (!texture.FaceViewSelectionWithVirtualFaces(
minCommonCameras, fOutlierThreshold, fRatioDataSmoothness,
nIgnoreMaskLabel, views, bUseExistingUV))
return false;
DEBUG_EXTRA("Virtual face view selection completed: %u faces (%s)", mesh.faces.size(), TD_TIMER_GET_FMT().c_str());
}
DEBUG_EXTRA("Assigning the best view to each face completed: %u faces (%s)", mesh.faces.size(), TD_TIMER_GET_FMT().c_str());
}
// generate the texture image and atlas
// ========== 非UV模式:生成纹理图集 ==========
{
TD_TIMER_STARTD();
if (!texture.GenerateTextureWithVirtualFaces(bGlobalSeamLeveling, bLocalSeamLeveling, nTextureSizeMultiple, nRectPackingHeuristic,
colEmpty, fSharpnessWeight, maxTextureSize, baseFileName, bOriginFaceview, this))
{
if (!texture.GenerateTextureWithVirtualFaces(
bGlobalSeamLeveling, bLocalSeamLeveling, nTextureSizeMultiple, nRectPackingHeuristic,
colEmpty, fSharpnessWeight, maxTextureSize, baseFileName, bOriginFaceview, this))
return false;
}
DEBUG_EXTRA("Generating texture atlas and image completed: %u patches, %u image size, %u textures (%s)",
texture.texturePatches.size(), mesh.texturesDiffuse[0].width(), mesh.texturesDiffuse.size(), TD_TIMER_GET_FMT().c_str());
DEBUG_EXTRA("Generating texture atlas completed: %u textures (%s)",
mesh.texturesDiffuse.size(), TD_TIMER_GET_FMT().c_str());
}
// 最终UV检查
// mesh.CheckUVValid();
return true;
} // TextureMesh

Loading…
Cancel
Save