Browse Source

通过编译

ManualUV
hesuicong 1 month ago
parent
commit
29388cf341
  1. 2
      CMakeLists.txt
  2. 228
      libs/MVS/SceneTexture.cpp

2
CMakeLists.txt

@ -52,7 +52,7 @@ ENDIF()
PROJECT(OpenMVS) PROJECT(OpenMVS)
SET(ENV_PYTHON_PATH "/home/algo/.conda/envs/py310_pyt210/lib/python3.10/site-packages") SET(ENV_PYTHON_PATH "/home/algo/.conda/envs/py310_pyt210/lib/python3.10/site-packages")
SET(ENV_MVS_PATH "/home/algo/Documents/openMVS/openMVS/libs/MVS") SET(ENV_MVS_PATH "/home/algo/Documents/openMVS/openMVS.ManualUV/libs/MVS")
CONFIGURE_FILE( CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/build/Templates/ConfigEnv.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/build/Templates/ConfigEnv.h.in"

228
libs/MVS/SceneTexture.cpp

@ -670,6 +670,10 @@ public:
bool CreateVirtualFacesForExistingUVImpl(VirtualFaceMap& virtualFaceMap); bool CreateVirtualFacesForExistingUVImpl(VirtualFaceMap& virtualFaceMap);
void CalculateVirtualFaceUVBoundsSafe(VirtualFace& vf); void CalculateVirtualFaceUVBoundsSafe(VirtualFace& vf);
void CalculateVirtualFacePropertiesSafe(VirtualFace& vf); void CalculateVirtualFacePropertiesSafe(VirtualFace& vf);
bool IsFaceUVValid(FIndex fid) const;
// 获取面片的UV中心
TexCoord GetFaceUVCenter(FIndex fid) const;
bool CheckUVContinuityForRegion(const std::vector<FIndex>& faceList); bool CheckUVContinuityForRegion(const std::vector<FIndex>& faceList);
bool CheckUVContinuityForRegion(const MVS::Mesh::FaceIdxArr& faceList); bool CheckUVContinuityForRegion(const MVS::Mesh::FaceIdxArr& faceList);
@ -14922,19 +14926,55 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap
m_virtualFaceMapCached = true; m_virtualFaceMapCached = true;
return true; return true;
} }
// 检查面片的UV是否有效
bool MeshTexture::IsFaceUVValid(FIndex fid) const {
if (fid >= scene.mesh.faces.size()) {
return false;
}
if (scene.mesh.faceTexcoords.size() <= fid * 3 + 2) {
return false;
}
// 检查UV坐标是否有效(非NaN、有限值)
for (int i = 0; i < 3; ++i) {
const TexCoord& uv = scene.mesh.faceTexcoords[fid * 3 + i];
if (std::isnan(uv.x) || std::isnan(uv.y) ||
!std::isfinite(uv.x) || !std::isfinite(uv.y)) {
return false;
}
}
return true;
}
void MeshTexture::CalculateVirtualFacePropertiesSafe(VirtualFace& vf) { // 获取面片的UV中心
if (vf.faces.empty()) { TexCoord MeshTexture::GetFaceUVCenter(FIndex fid) const {
vf.center = Point3f(0, 0, 0); TexCoord center(0, 0);
vf.normal = Point3f(0, 0, 1);
vf.area = 0.0f; if (!IsFaceUVValid(fid)) {
return; return center;
}
for (int i = 0; i < 3; ++i) {
const TexCoord& uv = scene.mesh.faceTexcoords[fid * 3 + i];
center.x += uv.x;
center.y += uv.y;
} }
center.x /= 3.0f;
center.y /= 3.0f;
return center;
}
// 计算虚拟面的属性(安全版本)
void MeshTexture::CalculateVirtualFacePropertiesSafe(VirtualFace& vf) {
// 与之前的 CalculateVirtualFaceProperties 类似,但更安全
Point3f centerSum(0, 0, 0); Point3f centerSum(0, 0, 0);
Point3f normalSum(0, 0, 0); Point3f normalSum(0, 0, 0);
float areaSum = 0.0f; float areaSum = 0.0f;
size_t validFaces = 0; int validFaces = 0;
for (FIndex fid : vf.faces) { for (FIndex fid : vf.faces) {
if (fid >= scene.mesh.faces.size()) { if (fid >= scene.mesh.faces.size()) {
@ -14943,14 +14983,19 @@ void MeshTexture::CalculateVirtualFacePropertiesSafe(VirtualFace& vf) {
const Mesh::Face& face = scene.mesh.faces[fid]; const Mesh::Face& face = scene.mesh.faces[fid];
// 检查顶点索引 // 检查顶点索引是否有效
bool validVertices = true;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (face[i] >= scene.mesh.vertices.size()) { if (face[i] >= scene.mesh.vertices.size()) {
// 跳过无效的面 validVertices = false;
goto skip_face; break;
} }
} }
if (!validVertices) {
continue; // 跳过无效的面
}
// 计算面中心 // 计算面中心
Point3f faceCenter(0, 0, 0); Point3f faceCenter(0, 0, 0);
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
@ -14966,11 +15011,16 @@ void MeshTexture::CalculateVirtualFacePropertiesSafe(VirtualFace& vf) {
Point3f edge1 = v1 - v0; Point3f edge1 = v1 - v0;
Point3f edge2 = v2 - v0; Point3f edge2 = v2 - v0;
Point3f faceNormal = edge1.cross(edge2); Point3f faceNormal = edge1.cross(edge2);
float faceArea = faceNormal.norm();
if (faceArea > 0) { // 计算法向量的长度
float faceAreaSq = faceNormal.dot(faceNormal);
if (faceAreaSq > 0) {
float faceArea = sqrt(faceAreaSq);
// 归一化法向量
faceNormal /= faceArea; faceNormal /= faceArea;
faceArea *= 0.5f; faceArea *= 0.5f; // 三角形面积是平行四边形的一半
// 加权平均 // 加权平均
centerSum += faceCenter * faceArea; centerSum += faceCenter * faceArea;
@ -14978,14 +15028,20 @@ void MeshTexture::CalculateVirtualFacePropertiesSafe(VirtualFace& vf) {
areaSum += faceArea; areaSum += faceArea;
validFaces++; validFaces++;
} }
skip_face:
continue;
} }
if (validFaces > 0 && areaSum > 0) { if (validFaces > 0 && areaSum > 0) {
vf.center = centerSum / areaSum; vf.center = centerSum / areaSum;
vf.normal = normalSum.normalized();
// 手动计算法向量长度并归一化
float normalLengthSq = normalSum.dot(normalSum);
if (normalLengthSq > 0) {
float normalLength = sqrt(normalLengthSq);
vf.normal = normalSum / normalLength;
} else {
vf.normal = Point3f(0, 0, 1); // 默认法向量
}
vf.area = areaSum; vf.area = areaSum;
} else { } else {
vf.center = Point3f(0, 0, 0); vf.center = Point3f(0, 0, 0);
@ -14995,37 +15051,45 @@ void MeshTexture::CalculateVirtualFacePropertiesSafe(VirtualFace& vf) {
} }
void MeshTexture::CalculateVirtualFaceUVBoundsSafe(VirtualFace& vf) { void MeshTexture::CalculateVirtualFaceUVBoundsSafe(VirtualFace& vf) {
if (vf.faces.empty()) { vf.uvBounds.ptMin = TexCoord(FLT_MAX, FLT_MAX);
vf.uvBounds.ptMin = TexCoord(0, 0); vf.uvBounds.ptMax = TexCoord(-FLT_MAX, -FLT_MAX);
vf.uvBounds.ptMax = TexCoord(1, 1);
return; bool hasValidUV = false;
}
bool first = true;
for (FIndex fid : vf.faces) { for (FIndex fid : vf.faces) {
if (fid * 3 + 2 >= scene.mesh.faceTexcoords.size()) { if (!IsFaceUVValid(fid)) {
continue; // 跳过无效索引 continue;
} }
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
const TexCoord& uv = scene.mesh.faceTexcoords[fid * 3 + i]; const TexCoord& uv = scene.mesh.faceTexcoords[fid * 3 + i];
if (!std::isfinite(uv.x) || !std::isfinite(uv.y)) { // 处理UV环绕
continue; // 跳过无效UV TexCoord wrappedUV = uv;
}
if (first) { // 使用 .x() 和 .y() 函数访问和修改分量
vf.uvBounds.ptMin = uv; float u = wrappedUV.x - floor(wrappedUV.x);
vf.uvBounds.ptMax = uv; float v = wrappedUV.y - floor(wrappedUV.y);
first = false; if (u < 0) u += 1.0f;
} else { if (v < 0) v += 1.0f;
vf.uvBounds.Insert(uv);
} // 使用 .x() 和 .y() 函数设置值
wrappedUV.x = u;
wrappedUV.y = v;
// 更新最小边界
vf.uvBounds.ptMin.x() = std::min(vf.uvBounds.ptMin.x(), wrappedUV.x);
vf.uvBounds.ptMin.y() = std::min(vf.uvBounds.ptMin.y(), wrappedUV.y);
// 更新最大边界
vf.uvBounds.ptMax.x() = std::max(vf.uvBounds.ptMax.x(), wrappedUV.x);
vf.uvBounds.ptMax.y() = std::max(vf.uvBounds.ptMax.y(), wrappedUV.y);
hasValidUV = true;
} }
} }
if (first) { if (!hasValidUV) {
// 没有有效的UV
vf.uvBounds.ptMin = TexCoord(0, 0); vf.uvBounds.ptMin = TexCoord(0, 0);
vf.uvBounds.ptMax = TexCoord(1, 1); vf.uvBounds.ptMax = TexCoord(1, 1);
} }
@ -15157,9 +15221,11 @@ bool MeshTexture::CreateVirtualFacesForExistingUVImpl(VirtualFaceMap& virtualFac
VirtualFace vf; VirtualFace vf;
vf.faces.reserve(end - start); vf.faces.reserve(end - start);
vf.faces.insert(vf.faces.end(),
cell.begin() + start, // 修复:使用循环添加,因为 cList 没有接受迭代器的 insert 方法
cell.begin() + end); for (size_t idx = start; idx < end; ++idx) {
vf.faces.push_back(cell[idx]);
}
// 计算属性 // 计算属性
CalculateVirtualFacePropertiesSafe(vf); CalculateVirtualFacePropertiesSafe(vf);
@ -15169,7 +15235,12 @@ bool MeshTexture::CreateVirtualFacesForExistingUVImpl(VirtualFaceMap& virtualFac
} }
} else { } else {
VirtualFace vf; VirtualFace vf;
vf.faces = cell; // 复制 vf.faces.reserve(cellSize);
// 修复:使用循环添加
for (FIndex fid : cell) {
vf.faces.push_back(fid);
}
// 计算属性 // 计算属性
CalculateVirtualFacePropertiesSafe(vf); CalculateVirtualFacePropertiesSafe(vf);
@ -15193,43 +15264,44 @@ bool MeshTexture::CreateVirtualFacesForExistingUVImpl(VirtualFaceMap& virtualFac
DEBUG_EXTRA("警告: 没有创建任何虚拟面"); DEBUG_EXTRA("警告: 没有创建任何虚拟面");
return false; return false;
} }
try { try {
size_t minFaces = SIZE_MAX, maxFaces = 0, totalFaces = 0; size_t minFaces = SIZE_MAX, maxFaces = 0, totalFaces = 0;
float minArea = FLT_MAX, maxArea = 0.0f, totalArea = 0.0f; float minArea = FLT_MAX, maxArea = 0.0f, totalArea = 0.0f;
for (const VirtualFace& vf : virtualFaceMap) { for (const VirtualFace& vf : virtualFaceMap) {
size_t numFacesInVF = vf.faces.size(); size_t numFacesInVF = vf.faces.size();
minFaces = std::min(minFaces, numFacesInVF); minFaces = std::min(minFaces, numFacesInVF);
maxFaces = std::max(maxFaces, numFacesInVF); maxFaces = std::max(maxFaces, numFacesInVF);
totalFaces += numFacesInVF; totalFaces += numFacesInVF;
if (vf.uvBounds.ptMax.x() >= vf.uvBounds.ptMin.x() && if (vf.uvBounds.ptMax.x() >= vf.uvBounds.ptMin.x() &&
vf.uvBounds.ptMax.y() >= vf.uvBounds.ptMin.y()) { vf.uvBounds.ptMax.y() >= vf.uvBounds.ptMin.y()) {
float width = vf.uvBounds.ptMax.x() - vf.uvBounds.ptMin.x(); float width = vf.uvBounds.ptMax.x() - vf.uvBounds.ptMin.x();
float height = vf.uvBounds.ptMax.y() - vf.uvBounds.ptMin.y(); float height = vf.uvBounds.ptMax.y() - vf.uvBounds.ptMin.y();
float area = width * height; float area = width * height;
minArea = std::min(minArea, area); minArea = std::min(minArea, area);
maxArea = std::max(maxArea, area); maxArea = std::max(maxArea, area);
totalArea += area; totalArea += area;
} else { } else {
DEBUG_EXTRA("警告: 虚拟面UV边界无效"); DEBUG_EXTRA("警告: 虚拟面UV边界无效");
} }
} }
DEBUG_EXTRA("虚拟面统计:"); DEBUG_EXTRA("虚拟面统计:");
DEBUG_EXTRA(" - 每个虚拟面的面片数: 最小=%zu, 最大=%zu, 平均=%.1f", DEBUG_EXTRA(" - 每个虚拟面的面片数: 最小=%zu, 最大=%zu, 平均=%.1f",
minFaces, maxFaces, static_cast<float>(totalFaces) / virtualFaceMap.size()); minFaces, maxFaces, static_cast<float>(totalFaces) / virtualFaceMap.size());
if (virtualFaceMap.size() > 0) { if (virtualFaceMap.size() > 0) {
DEBUG_EXTRA(" - 每个虚拟面的UV面积: 最小=%.6e, 最大=%.6e, 平均=%.6e", DEBUG_EXTRA(" - 每个虚拟面的UV面积: 最小=%.6e, 最大=%.6e, 平均=%.6e",
minArea, maxArea, totalArea / virtualFaceMap.size()); minArea, maxArea, totalArea / virtualFaceMap.size());
} }
} catch (const std::exception& e) { } catch (const std::exception& e) {
DEBUG_EXTRA("计算虚拟面统计时发生异常: %s", e.what()); DEBUG_EXTRA("计算虚拟面统计时发生异常: %s", e.what());
} catch (...) { } catch (...) {
DEBUG_EXTRA("计算虚拟面统计时发生未知异常"); DEBUG_EXTRA("计算虚拟面统计时发生未知异常");
} }
return true; return true;
} }

Loading…
Cancel
Save