Files
Vulkan-Samples/python/find_same_point.py
T
2025-09-27 18:44:23 +08:00

170 lines
6.3 KiB
Python

def process_obj_file(input_file):
"""
读取OBJ文件,找出相同坐标的顶点并打印出来
Args:
input_file (str): OBJ文件路径
"""
# 存储所有顶点坐标和对应的顶点索引
vertices = []
vertex_dict = {} # 用于记录相同坐标的顶点
try:
with open(input_file, 'r', encoding='utf-8') as file:
for line_num, line in enumerate(file, 1):
line = line.strip()
if not line or line.startswith('#'):
continue
parts = line.split()
if not parts:
continue
# 处理顶点数据 (v x y z [w])
if parts[0] == 'v':
try:
# 提取顶点坐标 (x, y, z)
x = float(parts[1])
y = float(parts[2])
z = float(parts[3])
vertex_index = len(vertices) + 1 # OBJ顶点索引从1开始
vertex_coord = (x, y, z)
vertices.append((vertex_index, vertex_coord))
# 将坐标转换为字符串作为字典的键(避免浮点数精度问题)
coord_key = f"{x:.6f},{y:.6f},{z:.6f}"
if coord_key not in vertex_dict:
vertex_dict[coord_key] = []
vertex_dict[coord_key].append(vertex_index)
except (ValueError, IndexError) as e:
print(f"警告: 第{line_num}行顶点数据格式错误: {line}")
continue
# 找出重复的顶点坐标
duplicate_vertices = {coord: indices for coord, indices in vertex_dict.items()
if len(indices) > 1}
# 打印结果
if duplicate_vertices:
print(f"在文件 '{input_file}' 中找到 {len(duplicate_vertices)} 组重复的顶点坐标:")
print("=" * 60)
for i, (coord, indices) in enumerate(duplicate_vertices.items(), 1):
x, y, z = map(float, coord.split(','))
print(f"第{i}组重复顶点 - 坐标 ({x:.6f}, {y:.6f}, {z:.6f}):")
print(f" 顶点索引: {indices}")
print(f" 重复次数: {len(indices)}次")
print("-" * 40)
print(f"\n总计: {sum(len(indices) for indices in duplicate_vertices.values())} 个顶点存在重复")
else:
print(f"在文件 '{input_file}' 中未找到重复的顶点坐标")
return duplicate_vertices
except FileNotFoundError:
print(f"错误: 找不到文件 '{input_file}'")
return None
except Exception as e:
print(f"错误: 读取文件时发生异常 - {e}")
return None
def process_obj_file_advanced(input_file, tolerance=1e-6):
"""
高级版本:考虑浮点数精度容差的顶点查重
Args:
input_file (str): OBJ文件路径
tolerance (float): 浮点数比较容差
"""
vertices = []
try:
with open(input_file, 'r', encoding='utf-8') as file:
for line_num, line in enumerate(file, 1):
line = line.strip()
if not line or line.startswith('#'):
continue
parts = line.split()
if not parts:
continue
if parts[0] == 'v':
try:
x = float(parts[1])
y = float(parts[2])
z = float(parts[3])
vertex_index = len(vertices)# + 1
vertices.append((vertex_index, (x, y, z)))
except (ValueError, IndexError):
continue
# 使用容差比较找出重复顶点
duplicate_groups = []
processed_indices = set()
for i, (idx1, coord1) in enumerate(vertices):
if idx1 in processed_indices:
continue
duplicates = [idx1]
x1, y1, z1 = coord1
for j, (idx2, coord2) in enumerate(vertices[i+1:], i+1):
if idx2 in processed_indices:
continue
x2, y2, z2 = coord2
# 使用容差比较坐标
if (abs(x1 - x2) < tolerance and
abs(y1 - y2) < tolerance and
abs(z1 - z2) < tolerance):
duplicates.append(idx2)
processed_indices.add(idx2)
if len(duplicates) > 1:
duplicate_groups.append((coord1, duplicates))
processed_indices.add(idx1)
# 打印结果
if duplicate_groups:
print(f"在文件 '{input_file}' 中找到 {len(duplicate_groups)} 组重复的顶点坐标 (容差: {tolerance}):")
print("=" * 70)
for i, (coord, indices) in enumerate(duplicate_groups, 1):
x, y, z = coord
print(f"第{i}组重复顶点 - 坐标 ({x:.6f} {y:.6f} {z:.6f}):")
print(f" 顶点索引: {indices}")
print(f" 重复次数: {len(indices)}次")
print("-" * 50)
total_duplicates = sum(len(indices) for _, indices in duplicate_groups)
print(f"\n总计: {total_duplicates} 个顶点存在重复")
else:
print(f"在文件 '{input_file}' 中未找到重复的顶点坐标")
return duplicate_groups
except Exception as e:
print(f"错误: {e}")
return None
if __name__ == "__main__":
input_file = "face.obj" # 默认输入文件
# 使用基本版本
print("基本版本结果:")
process_obj_file(input_file)
print("\n" + "="*80 + "\n")
# 使用高级版本(带容差)
print("高级版本结果(带容差):")
process_obj_file_advanced(input_file, tolerance=0.0024)