Browse Source

编译通过,可以生成纹理,但是还是模糊

ManualUV
hesuicong 1 month ago
parent
commit
82c019ee49
  1. 686
      libs/MVS/SceneTexture.cpp

686
libs/MVS/SceneTexture.cpp

@ -660,6 +660,8 @@ public: @@ -660,6 +660,8 @@ public:
float fOutlierThreshold, unsigned nTextureSizeMultiple,
Pixel8U colEmpty, float fSharpnessWeight);
bool CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap);
bool CheckUVContinuityForRegion(const std::vector<FIndex>& faceList);
bool CheckUVContinuityForRegion(const MVS::Mesh::FaceIdxArr& faceList);
bool CheckUVContinuity(const std::vector<FIndex>& faceList);
Mesh::Image8U3Arr GenerateMultiViewTextureAtlasWithVirtualFaces(
const VirtualFaceMap& virtualFaceMap,
@ -1411,9 +1413,18 @@ bool MeshTexture::CalculateVirtualFaceProperties(VirtualFace& vf) { @@ -1411,9 +1413,18 @@ bool MeshTexture::CalculateVirtualFaceProperties(VirtualFace& vf) {
vf.center = Point3f::ZERO;
vf.normal = Normal::ZERO;
vf.area = 0.0f;
DEBUG_EXTRA("ERROR: Virtual face has no faces");
return false;
}
for (FIndex fid : vf.faces) {
if (fid >= scene.mesh.faces.size()) {
DEBUG_EXTRA("ERROR: Face index %u out of bounds in virtual face", fid);
return false;
}
}
const Mesh::VertexArr& vertices = scene.mesh.vertices;
const Mesh::NormalArr& faceNormals = scene.mesh.faceNormals;
const size_t numFaces = scene.mesh.faces.size();
@ -1527,31 +1538,136 @@ bool MeshTexture::CalculateVirtualFaceProperties(VirtualFace& vf) { @@ -1527,31 +1538,136 @@ bool MeshTexture::CalculateVirtualFaceProperties(VirtualFace& vf) {
}
bool MeshTexture::CalculateVirtualFaceUVBounds(VirtualFace& vf) {
if (vf.faces.empty() || !scene.mesh.HasTexture()) {
// 修正1: 不使用 ZERO,而是创建一个空的边界框
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: Starting for virtual face with %zu faces", vf.faces.size());
if (vf.faces.empty()) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: ERROR - Virtual face has no faces");
vf.uvBounds = AABB2f(); // 使用默认构造函数
return false; // 返回 false
}
// if (!scene.mesh.HasTexture()) {
// DEBUG_EXTRA("CalculateVirtualFaceUVBounds: ERROR - Mesh has no texture");
// vf.uvBounds = AABB2f(); // 使用默认构造函数
// return false; // 返回 false
// }
if (scene.mesh.faceTexcoords.empty()) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: ERROR - No texture coordinates in mesh");
vf.uvBounds = AABB2f();
return false;
}
const TexCoord* texcoords = scene.mesh.faceTexcoords.data();
bool first = true;
int uv_count = 0;
for (FIndex faceIdx : vf.faces) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: Processing %zu faces", vf.faces.size());
for (size_t idx = 0; idx < vf.faces.size(); ++idx) {
FIndex faceIdx = vf.faces[idx];
// 检查面片索引是否有效
if (faceIdx >= scene.mesh.faces.size()) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: ERROR - Face index %u out of bounds (max=%zu)",
faceIdx, scene.mesh.faces.size());
continue;
}
// 检查UV坐标索引是否有效
size_t base_uv_idx = faceIdx * 3;
if (base_uv_idx + 2 >= scene.mesh.faceTexcoords.size()) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: ERROR - Face %u has insufficient UV coordinates (base_idx=%zu, total_uvs=%zu)",
faceIdx, base_uv_idx, scene.mesh.faceTexcoords.size());
continue;
}
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: Processing face %u (index %zu/%zu)",
faceIdx, idx + 1, vf.faces.size());
for (int i = 0; i < 3; ++i) {
const TexCoord& uv = texcoords[faceIdx * 3 + i];
uv_count++;
// 检查UV值是否有效 - 注意:对于Eigen向量,使用x()和y()函数访问分量
if (!std::isfinite(uv.x) || !std::isfinite(uv.y)) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: WARNING - Face %u UV[%d] = (%.6f, %.6f) contains NaN or Inf",
faceIdx, i, uv.x, uv.y);
continue;
}
// 检查UV值是否在合理范围内
if (uv.x < -100.0f || uv.x > 100.0f || uv.y < -100.0f || uv.y > 100.0f) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: WARNING - Face %u UV[%d] = (%.6f, %.6f) is out of expected range [-100, 100]",
faceIdx, i, uv.x, uv.y);
}
if (first) {
// 修正2: 使用 ptMin 和 ptMax
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: Setting initial bounds with UV[%d] = (%.6f, %.6f)",
i, uv.x, uv.y);
vf.uvBounds.ptMin = uv;
vf.uvBounds.ptMax = uv;
first = false;
} else {
// 记录扩展前的边界
Point2f oldMin = vf.uvBounds.ptMin;
Point2f oldMax = vf.uvBounds.ptMax;
vf.uvBounds.Insert(uv);
// 检查边界是否发生变化
if (oldMin.x != vf.uvBounds.ptMin.x() ||
oldMin.y != vf.uvBounds.ptMin.y() ||
oldMax.x != vf.uvBounds.ptMax.x() ||
oldMax.y != vf.uvBounds.ptMax.y()){
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: UV[%d] = (%.6f, %.6f) expanded bounds: min(%.6f,%.6f)->max(%.6f,%.6f)",
i, uv.x, uv.y,
oldMin.x, oldMin.y,
vf.uvBounds.ptMax.x(), vf.uvBounds.ptMax.y());
}
}
}
}
return !first; // 如果至少有一个UV坐标,则返回true
if (first) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: ERROR - No valid UV coordinates found for virtual face");
vf.uvBounds = AABB2f();
return false;
}
// 计算UV边界尺寸 - 修正:AABB2f没有GetWidth和GetHeight,需要手动计算
float uv_width = vf.uvBounds.ptMax.x() - vf.uvBounds.ptMin.x();
float uv_height = vf.uvBounds.ptMax.y() - vf.uvBounds.ptMin.y();
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: Completed successfully");
DEBUG_EXTRA(" - Processed %zu faces", vf.faces.size());
DEBUG_EXTRA(" - Valid UV coordinates: %d", uv_count);
// 修正:使用x()和y()函数而不是直接访问成员
DEBUG_EXTRA(" - UV bounds: min(%.6f, %.6f) max(%.6f, %.6f)",
vf.uvBounds.ptMin.x(), vf.uvBounds.ptMin.y(),
vf.uvBounds.ptMax.x(), vf.uvBounds.ptMax.y());
DEBUG_EXTRA(" - UV size: %.6f x %.6f (width x height)", uv_width, uv_height);
DEBUG_EXTRA(" - UV area: %.6f", uv_width * uv_height);
// 检查UV边界是否合理
if (uv_width <= 0.0f || uv_height <= 0.0f) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: WARNING - Invalid UV dimensions: %.6f x %.6f",
uv_width, uv_height);
}
if (uv_width > 10.0f || uv_height > 10.0f) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: WARNING - UV bounds unusually large: %.6f x %.6f",
uv_width, uv_height);
}
if (uv_width * uv_height < 1e-10f) {
DEBUG_EXTRA("CalculateVirtualFaceUVBounds: WARNING - UV area extremely small: %.6e",
uv_width * uv_height);
}
return true;
}
// 检查两个面片在UV空间中是否连续
bool MeshTexture::AreFacesUVContinuous(FIndex fid1, FIndex fid2) {
if (!scene.mesh.HasTexture()) {
@ -14643,150 +14759,101 @@ bool MeshTexture::ConvertVectorToVirtualFaceDataArr(const std::vector<VirtualFac @@ -14643,150 +14759,101 @@ bool MeshTexture::ConvertVectorToVirtualFaceDataArr(const std::vector<VirtualFac
bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap) {
DEBUG_EXTRA("Creating virtual faces for existing UV texture mapping");
// 0. 详细的输入验证
DEBUG_EXTRA("=== Detailed Input Validation ===");
DEBUG_EXTRA("Scene pointer: %p", &scene);
DEBUG_EXTRA("Mesh pointer: %p", &scene.mesh);
// 检查基本数据结构
// 0. 输入验证
if (scene.mesh.faces.empty()) {
DEBUG_EXTRA("ERROR: Mesh has no faces!");
return false;
}
if (scene.mesh.vertices.empty()) {
DEBUG_EXTRA("ERROR: Mesh has no vertices!");
if (scene.mesh.faceTexcoords.empty()) {
DEBUG_EXTRA("ERROR: Mesh has no texture coordinates.");
return false;
}
// 验证faces数组的大小
size_t numFaces = scene.mesh.faces.size();
size_t numVertices = scene.mesh.vertices.size();
size_t numFaceTexcoords = scene.mesh.faceTexcoords.size();
DEBUG_EXTRA("Number of faces: %zu", numFaces);
DEBUG_EXTRA("Number of vertices: %zu", numVertices);
DEBUG_EXTRA("Number of texture coordinates: %zu", numFaceTexcoords);
// 关键检查:必须有纹理坐标才能使用此方法
if (numFaceTexcoords == 0) {
DEBUG_EXTRA("ERROR: Mesh has no texture coordinates. Cannot create virtual faces for existing UV.");
if (scene.mesh.faceTexcoords.size() < numFaces * 3) {
DEBUG_EXTRA("ERROR: Not enough UV coordinates!");
return false;
}
if (numFaceTexcoords < numFaces * 3) {
DEBUG_EXTRA("ERROR: Not enough UV coordinates! Expected %zu (faces * 3), have %zu",
numFaces * 3, numFaceTexcoords);
return false;
// 检查法线数组
if (scene.mesh.faceNormals.empty()) {
DEBUG_EXTRA("WARNING: faceNormals is empty, computing...");
scene.mesh.ComputeNormalFaces();
}
// 验证面片索引
DEBUG_EXTRA("Validating face indices...");
for (size_t i = 0; i < std::min(numFaces, static_cast<size_t>(10)); ++i) { // 使用static_cast
const Mesh::Face& face = scene.mesh.faces[i];
bool valid = true;
for (int j = 0; j < 3; ++j) {
if (face[j] >= numVertices) {
DEBUG_EXTRA("ERROR: Face %zu has invalid vertex index %u (max: %zu)",
i, face[j], numVertices - 1);
valid = false;
}
}
if (valid) {
DEBUG_EXTRA("Face %zu: vertices [%u, %u, %u] - OK",
i, face[0], face[1], face[2]);
}
}
// 验证UV坐标索引
if (numFaceTexcoords > 0) {
DEBUG_EXTRA("Validating UV coordinate indices...");
if (numFaceTexcoords < numFaces * 3) {
DEBUG_EXTRA("ERROR: Not enough UV coordinates! Expected %zu, have %zu",
numFaces * 3, numFaceTexcoords);
return false;
}
if (scene.mesh.faceNormals.size() != numFaces) {
DEBUG_EXTRA("ERROR: faceNormals size mismatch!");
return false;
}
// 1. 确保网格拓扑已计算
DEBUG_EXTRA("Computing mesh topology...");
// 检查面-面邻接关系
if (scene.mesh.faceFaces.empty()) {
DEBUG_EXTRA(" Computing incident faces...");
try {
scene.mesh.ListIncidenteFaces();
scene.mesh.ListIncidenteFaceFaces();
DEBUG_EXTRA(" Done computing incident faces");
} catch (const std::exception& e) {
DEBUG_EXTRA(" ERROR computing incident faces: %s", e.what());
return false;
}
DEBUG_EXTRA("Computing face adjacency...");
scene.mesh.ListIncidenteFaces();
scene.mesh.ListIncidenteFaceFaces();
}
if (scene.mesh.faceNormals.empty()) {
DEBUG_EXTRA(" Computing face normals...");
try {
scene.mesh.ComputeNormalFaces();
DEBUG_EXTRA(" Done computing face normals");
} catch (const std::exception& e) {
DEBUG_EXTRA(" ERROR computing face normals: %s", e.what());
return false;
}
if (scene.mesh.faceFaces.size() != numFaces) {
DEBUG_EXTRA("ERROR: faceFaces size mismatch!");
return false;
}
std::vector<bool> processedFaces(numFaces, false);
// 3. 基于曲率分割网格
// 1. 基于曲率分割网格
DEBUG_EXTRA("Segmenting mesh based on curvature...");
Mesh::FaceIdxArr regionMap;
try {
scene.SegmentMeshBasedOnCurvature(regionMap, 0.2f);
DEBUG_EXTRA("Mesh segmentation completed, regionMap size: %zu", regionMap.size());
if (regionMap.size() != numFaces) {
DEBUG_EXTRA("ERROR: regionMap size (%zu) doesn't match number of faces (%u)",
regionMap.size(), numFaces);
// 使用更大的曲率阈值以获得更大的区域
scene.SegmentMeshBasedOnCurvature(regionMap, 0.5f);
DEBUG_EXTRA("Region map computed, size: %zu", regionMap.size());
if (regionMap.empty()) {
DEBUG_EXTRA("ERROR: regionMap is empty!");
return false;
}
if (regionMap.size() != numFaces) {
DEBUG_EXTRA("ERROR: regionMap size doesn't match number of faces");
return false;
}
// 检查区域映射的有效性
int minRegion = INT_MAX, maxRegion = INT_MIN;
for (FIndex fid = 0; fid < numFaces; ++fid) {
if (fid >= regionMap.size()) {
DEBUG_EXTRA("ERROR: regionMap index out of bounds: %u >= %zu", fid, regionMap.size());
return false;
}
} catch (const std::exception& e) {
DEBUG_EXTRA("ERROR during mesh segmentation: %s", e.what());
return false;
int region = regionMap[fid];
if (region < minRegion) minRegion = region;
if (region > maxRegion) maxRegion = region;
}
DEBUG_EXTRA("Region map: min=%d, max=%d", minRegion, maxRegion);
// 4. 统计每个区域的面积
DEBUG_EXTRA("Calculating region areas...");
// 3. 统计区域信息
std::unordered_map<int, std::vector<FIndex>> regionFaces;
std::unordered_map<int, float> regionAreas;
for (FIndex fid = 0; fid < numFaces; ++fid) {
if (fid % 10000 == 0 && fid > 0) {
DEBUG_EXTRA(" Processed %u/%u faces", fid, numFaces);
}
int region = regionMap[fid];
regionFaces[region].push_back(fid);
// 验证面片索引
if (fid >= scene.mesh.faces.size()) {
DEBUG_EXTRA("ERROR: Face index %u out of bounds (mesh has %zu faces)",
fid, scene.mesh.faces.size());
continue;
}
// 计算面片面积
const Mesh::Face& face = scene.mesh.faces[fid];
// 验证顶点索引
for (int i = 0; i < 3; ++i) {
if (face[i] >= scene.mesh.vertices.size()) {
DEBUG_EXTRA("ERROR: Vertex index %u out of bounds in face %u (mesh has %zu vertices)",
face[i], fid, scene.mesh.vertices.size());
continue;
}
// 检查顶点索引是否有效
if (face[0] >= scene.mesh.vertices.size() ||
face[1] >= scene.mesh.vertices.size() ||
face[2] >= scene.mesh.vertices.size()) {
DEBUG_EXTRA("WARNING: Face %u has invalid vertex indices, skipping area calculation", fid);
continue;
}
const Point3f& v0 = scene.mesh.vertices[face[0]];
const Point3f& v1 = scene.mesh.vertices[face[1]];
const Point3f& v2 = scene.mesh.vertices[face[2]];
// 计算三角形面积
Point3f edge1 = v1 - v0;
Point3f edge2 = v2 - v0;
@ -14802,108 +14869,340 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap @@ -14802,108 +14869,340 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap
crossProd.z * crossProd.z
);
if (area < 0) {
DEBUG_EXTRA("WARNING: Negative area calculated for face %u: %f", fid, area);
area = 0.0f;
}
regionAreas[region] += area;
}
DEBUG_EXTRA("Region area calculation completed, found %zu regions", regionAreas.size());
DEBUG_EXTRA("Found %zu regions", regionFaces.size());
// 5. 为每个区域收集面片
DEBUG_EXTRA("Grouping faces by region...");
std::unordered_map<int, std::vector<FIndex>> regionFaces;
for (FIndex fid = 0; fid < numFaces; ++fid) {
int region = regionMap[fid];
regionFaces[region].push_back(fid);
// 检查regionAreas是否计算正确
for (const auto& entry : regionAreas) {
DEBUG_EXTRA("Region %d: area=%.6f, faces=%zu",
entry.first, entry.second, regionFaces[entry.first].size());
}
DEBUG_EXTRA("Found %zu regions with faces", regionFaces.size());
// 6. 创建虚拟面
DEBUG_EXTRA("Creating virtual faces...");
// 4. 创建虚拟面
std::vector<bool> processedFaces(numFaces, false);
virtualFaceMap.clear();
virtualFaceMap.reserve(regionFaces.size());
virtualFaceMap.reserve(numFaces); // 每个面单独处理
int regionCount = 0;
int smallRegionCount = 0;
int uvDiscontinuousCount = 0;
int createdVirtualFaces = 0;
int smallRegions = 0;
int uvDiscontinuousRegions = 0;
// 参数设置
const float thMaxNormalDeviation = 30.0f; // 法线最大偏差角度
const float cosMaxNormalDeviation = cos(FD2R(thMaxNormalDeviation));
const float maxUVSize = 1.0f; // UV边界最大尺寸
const float minRegionArea = 0.01f; // 最小区域面积
// 遍历每个区域
for (const auto& region : regionFaces) {
regionCount++;
int regionID = region.first;
const std::vector<FIndex>& faceList = region.second;
if (regionCount % 100 == 0) {
DEBUG_EXTRA(" Processing region %d/%d (%zu faces)", regionCount, regionFaces.size(), faceList.size());
}
DEBUG_EXTRA("Processing region %d with %zu faces", regionID, faceList.size());
// 检查区域面积是否足够大
// 检查区域面积
float regionArea = regionAreas[regionID];
if (regionArea < 0.001f) { // 面积阈值
DEBUG_EXTRA(" Region %d is too small (area: %f), using individual faces", regionID, regionArea);
smallRegionCount++;
// 小区域:直接为每个面单独创建虚拟面
if (regionArea < minRegionArea) {
DEBUG_EXTRA(" Small region (area=%.6f < %.6f), creating individual faces",
regionArea, minRegionArea);
smallRegions++;
// 区域太小,不创建虚拟面
for (FIndex fid : faceList) {
virtualFaceMap.push_back(VirtualFace());
virtualFaceMap.back().faces.push_back(fid);
// 添加调试代码
// DEBUG_EXTRA("Processing face %u for virtual face creation", fid);
// 检查面片数据
if (fid >= scene.mesh.faces.size()) {
DEBUG_EXTRA("ERROR: Face index %u out of bounds (max=%zu)", fid, scene.mesh.faces.size());
continue;
}
// 检查顶点索引
const Mesh::Face& face = scene.mesh.faces[fid];
if (face[0] >= scene.mesh.vertices.size() ||
face[1] >= scene.mesh.vertices.size() ||
face[2] >= scene.mesh.vertices.size()) {
DEBUG_EXTRA("ERROR: Face %u has invalid vertex indices: %u, %u, %u",
fid, face[0], face[1], face[2]);
continue;
}
// 检查法线
if (fid >= scene.mesh.faceNormals.size()) {
DEBUG_EXTRA("ERROR: Face %u has no normal data", fid);
continue;
}
// 检查UV坐标
if (fid * 3 + 2 >= scene.mesh.faceTexcoords.size()) {
DEBUG_EXTRA("ERROR: Face %u has insufficient UV coordinates", fid);
continue;
}
// 调试代码结束
if (fid >= scene.mesh.faces.size()) {
DEBUG_EXTRA(" WARNING: Invalid face index %u, skipping", fid);
continue;
}
VirtualFace singleFace;
singleFace.faces.push_back(fid);
// 计算单个面的属性
if (CalculateVirtualFaceProperties(singleFace) &&
CalculateVirtualFaceUVBounds(singleFace)) {
virtualFaceMap.push_back(singleFace);
createdVirtualFaces++;
} else {
// DEBUG_EXTRA(" WARNING: Failed to create virtual face for face %u", fid);
}
if (fid < processedFaces.size()) {
processedFaces[fid] = true;
}
}
DEBUG_EXTRA(" Created %d virtual faces for small region %d", createdVirtualFaces, regionID);
continue;
}
// 检查UV连续性
if (!CheckUVContinuity(faceList)) {
DEBUG_EXTRA(" Region %d has discontinuous UV, using individual faces", regionID);
uvDiscontinuousCount++;
// 大区域:正常处理
DEBUG_EXTRA(" Large region (area=%.6f), using region growing", regionArea);
// 创建虚拟面列表
std::vector<VirtualFace> regionVirtualFaces;
// 遍历区域中的每个面片
for (FIndex seedFace : faceList) {
// 添加调试代码
// DEBUG_EXTRA("Processing seed face %u for virtual face creation", seedFace);
// UV不连续,保持原始面片
for (FIndex fid : faceList) {
virtualFaceMap.push_back(VirtualFace());
virtualFaceMap.back().faces.push_back(fid);
// 检查面片数据
if (seedFace >= scene.mesh.faces.size()) {
DEBUG_EXTRA("ERROR: Seed face index %u out of bounds (max=%zu)", seedFace, scene.mesh.faces.size());
continue;
}
// 检查顶点索引
const Mesh::Face& face = scene.mesh.faces[seedFace];
if (face[0] >= scene.mesh.vertices.size() ||
face[1] >= scene.mesh.vertices.size() ||
face[2] >= scene.mesh.vertices.size()) {
DEBUG_EXTRA("ERROR: Seed face %u has invalid vertex indices: %u, %u, %u",
seedFace, face[0], face[1], face[2]);
continue;
}
// 检查法线
if (seedFace >= scene.mesh.faceNormals.size()) {
DEBUG_EXTRA("ERROR: Seed face %u has no normal data", seedFace);
continue;
}
// 检查UV坐标
if (seedFace * 3 + 2 >= scene.mesh.faceTexcoords.size()) {
DEBUG_EXTRA("ERROR: Seed face %u has insufficient UV coordinates", seedFace);
continue;
}
// 调试代码结束
if (seedFace >= scene.mesh.faces.size()) {
DEBUG_EXTRA(" WARNING: Invalid seed face index %u, skipping", seedFace);
continue;
}
// 检查面片是否已处理
if (seedFace < processedFaces.size() && processedFaces[seedFace]) {
continue;
}
// 创建新的虚拟面
VirtualFace vf;
vf.faces.push_back(seedFace);
// 计算虚拟面属性
if (!CalculateVirtualFaceProperties(vf) || !CalculateVirtualFaceUVBounds(vf)) {
// DEBUG_EXTRA(" WARNING: Failed to calculate properties for seed face %u", seedFace);
continue;
}
// 区域增长队列
std::queue<FIndex> faceQueue;
faceQueue.push(seedFace);
std::unordered_set<FIndex> inQueue;
inQueue.insert(seedFace);
while (!faceQueue.empty()) {
FIndex currentFace = faceQueue.front();
faceQueue.pop();
// 获取相邻面片
if (currentFace >= scene.mesh.faceFaces.size()) {
continue;
}
const Mesh::FaceFaces& neighbors = scene.mesh.faceFaces[currentFace];
for (int i = 0; i < 3; ++i) {
FIndex neighborFace = neighbors[i];
if (neighborFace == NO_ID) continue;
if (neighborFace >= scene.mesh.faces.size()) {
continue;
}
// 检查邻居是否在同一区域
bool inSameRegion = false;
for (FIndex fid : faceList) {
if (fid == neighborFace) {
inSameRegion = true;
break;
}
}
if (!inSameRegion) continue;
// 检查邻居是否已处理
if (neighborFace < processedFaces.size() && processedFaces[neighborFace]) {
continue;
}
// 检查是否已在队列中
if (inQueue.find(neighborFace) != inQueue.end()) continue;
// 检查邻居是否已在当前虚拟面中
bool alreadyInVirtual = false;
for (FIndex fid : vf.faces) {
if (fid == neighborFace) {
alreadyInVirtual = true;
break;
}
}
if (alreadyInVirtual) continue;
// 1. 检查法线相似性
FIndex firstFace = vf.faces[0];
if (firstFace >= scene.mesh.faceNormals.size() ||
neighborFace >= scene.mesh.faceNormals.size()) {
continue;
}
const Normal& seedNormal = scene.mesh.faceNormals[firstFace];
const Normal& neighborNormal = scene.mesh.faceNormals[neighborFace];
float cosAngle = seedNormal.dot(neighborNormal);
if (cosAngle < cosMaxNormalDeviation) continue;
// 2. 临时添加面片检查UV连续性
MVS::Mesh::FaceIdxArr tempFaces = vf.faces;
tempFaces.push_back(neighborFace);
if (!CheckUVContinuityForRegion(tempFaces)) continue;
// 3. 检查UV边界
AABB2f tempBounds = vf.uvBounds;
// 扩展UV边界
for (int k = 0; k < 3; ++k) {
size_t uvIndex = neighborFace * 3 + k;
if (uvIndex >= scene.mesh.faceTexcoords.size()) {
break;
}
const Point2f& uv = scene.mesh.faceTexcoords[uvIndex];
float minX = tempBounds.ptMin.x();
float minY = tempBounds.ptMin.y();
float maxX = tempBounds.ptMax.x();
float maxY = tempBounds.ptMax.y();
if (uv.x < minX) minX = uv.x;
if (uv.y < minY) minY = uv.y;
if (uv.x > maxX) maxX = uv.x;
if (uv.y > maxY) maxY = uv.y;
// 检查UV边界尺寸
if (maxX - minX > maxUVSize || maxY - minY > maxUVSize) {
break; // UV边界过大,跳过
}
tempBounds.ptMin.x() = minX;
tempBounds.ptMin.y() = minY;
tempBounds.ptMax.x() = maxX;
tempBounds.ptMax.y() = maxY;
}
// 所有检查通过,添加面片到虚拟面
vf.faces.push_back(neighborFace);
vf.uvBounds = tempBounds;
// 重新计算虚拟面属性
if (!CalculateVirtualFaceProperties(vf)) {
vf.faces.pop_back(); // 移除添加的面片
continue;
}
// 添加到队列继续扩展
faceQueue.push(neighborFace);
inQueue.insert(neighborFace);
}
}
// 将虚拟面添加到区域虚拟面列表
regionVirtualFaces.push_back(vf);
// 标记面片为已处理
for (FIndex fid : vf.faces) {
if (fid < processedFaces.size()) {
processedFaces[fid] = true;
}
}
continue;
}
// 创建虚拟面
VirtualFace vf;
vf.faces = faceList;
// 计算虚拟面的中心、法线和面积
if (!CalculateVirtualFaceProperties(vf)) {
DEBUG_EXTRA(" Failed to calculate properties for virtual face in region %d", regionID);
// 计算失败,回退到原始面片
for (FIndex fid : faceList) {
virtualFaceMap.push_back(VirtualFace());
virtualFaceMap.back().faces.push_back(fid);
}
continue;
// 将区域虚拟面添加到全局虚拟面列表
for (const auto& vf : regionVirtualFaces) {
virtualFaceMap.push_back(vf);
}
// 计算虚拟面的UV边界
if (!CalculateVirtualFaceUVBounds(vf)) {
DEBUG_EXTRA(" Failed to calculate UV bounds for virtual face in region %d", regionID);
// 计算失败,回退到原始面片
for (FIndex fid : faceList) {
virtualFaceMap.push_back(VirtualFace());
virtualFaceMap.back().faces.push_back(fid);
createdVirtualFaces += regionVirtualFaces.size();
DEBUG_EXTRA(" Region %d: created %zu virtual faces", regionID, regionVirtualFaces.size());
}
// 处理未包含在区域中的面片
int unprocessedCount = 0;
for (FIndex fid = 0; fid < numFaces; ++fid) {
if (!processedFaces[fid]) {
VirtualFace singleFace;
singleFace.faces.push_back(fid);
if (CalculateVirtualFaceProperties(singleFace) &&
CalculateVirtualFaceUVBounds(singleFace)) {
virtualFaceMap.push_back(singleFace);
createdVirtualFaces++;
}
continue;
unprocessedCount++;
}
virtualFaceMap.push_back(vf);
createdVirtualFaces++;
}
if (unprocessedCount > 0) {
DEBUG_EXTRA(" Processed %d unassigned faces", unprocessedCount);
}
DEBUG_EXTRA("Virtual face creation completed:");
DEBUG_EXTRA(" Total regions: %zu", regionFaces.size());
DEBUG_EXTRA(" Small regions (area < 0.001): %d", smallRegionCount);
DEBUG_EXTRA(" UV discontinuous regions: %d", uvDiscontinuousCount);
DEBUG_EXTRA(" Total faces: %zu", numFaces);
DEBUG_EXTRA(" Total virtual faces: %zu", virtualFaceMap.size());
DEBUG_EXTRA(" Small regions (< %.3f): %d", minRegionArea, smallRegions);
DEBUG_EXTRA(" Created virtual faces: %d", createdVirtualFaces);
DEBUG_EXTRA(" Total virtual faces (including individual faces): %zu", virtualFaceMap.size());
// 统计合并比例
size_t totalFacesInVirtual = 0;
for (const auto& vf : virtualFaceMap) {
totalFacesInVirtual += vf.faces.size();
}
float mergeRatio = (float)totalFacesInVirtual / (numFaces * 1.0f);
DEBUG_EXTRA(" Average faces per virtual face: %.2f", mergeRatio);
if (virtualFaceMap.empty()) {
DEBUG_EXTRA("ERROR: No virtual faces created!");
@ -14913,6 +15212,39 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap @@ -14913,6 +15212,39 @@ bool MeshTexture::CreateVirtualFacesForExistingUV(VirtualFaceMap& virtualFaceMap
return true;
}
bool MeshTexture::CheckUVContinuityForRegion(const std::vector<FIndex>& faceList) {
if (faceList.size() <= 1) return true;
// 检查UV是否在合理范围内
for (FIndex fid : faceList) {
for (int i = 0; i < 3; ++i) {
const Point2f& uv = scene.mesh.faceTexcoords[fid * 3 + i];
if (std::isnan(uv.x) || std::isnan(uv.y) ||
std::isinf(uv.x) || std::isinf(uv.y)) {
return false;
}
}
}
return true;
}
bool MeshTexture::CheckUVContinuityForRegion(const MVS::Mesh::FaceIdxArr& faceList) {
if (faceList.size() <= 1) return true;
for (FIndex fid : faceList) {
for (int i = 0; i < 3; ++i) {
const Point2f& uv = scene.mesh.faceTexcoords[fid * 3 + i];
if (std::isnan(uv.x) || std::isnan(uv.y) ||
std::isinf(uv.x) || std::isinf(uv.y)) {
return false;
}
}
}
return true;
}
bool MeshTexture::CheckUVContinuity(const std::vector<FIndex>& faceList) {
if (faceList.empty()) return false;
@ -17145,7 +17477,7 @@ bool MeshTexture::ValidateProjection(const Vertex& worldPoint, @@ -17145,7 +17477,7 @@ bool MeshTexture::ValidateProjection(const Vertex& worldPoint,
// 3. 设置误差阈值
if (reprojectionError > maxReprojectionError) {
DEBUG_EXTRA("重投影误差过大: %.3f像素,跳过该采样点", reprojectionError);
// DEBUG_EXTRA("重投影误差过大: %.3f像素,跳过该采样点", reprojectionError);
return false;
}

Loading…
Cancel
Save