Python提取Mesh边界边生成多边形:仅获小三角边界的问题
问题分析与修复方案
核心问题
- 未筛选边界边:你当前把所有面的边都加入了列表,包括内部边(每个内部边会在两个相邻面中各出现一次),但边界边的定义是仅在单个面中出现的边,这是导致你得到错误结果的根本原因。
- 用坐标存储边存在精度风险:直接用浮点坐标作为边的标识,可能因浮点精度误差导致同一个边被判定为不同的边,影响后续的去重和遍历逻辑。
- 边的遍历逻辑依赖错误的边集合:基于包含内部边的集合构建多边形,自然无法得到正确的外边界。
修复后的代码
import plyfile def get_boundary_edges(faces): # 用顶点索引统计每条边的出现次数,边用排序后的索引元组存储(确保(v1,v2)和(v2,v1)视为同一条边) edge_count = {} for face in faces: vertex_indices = face['vertex_indices'] face_len = len(vertex_indices) for i in range(face_len): v1 = vertex_indices[i] v2 = vertex_indices[(i+1) % face_len] # 排序索引,统一边的存储形式 edge = tuple(sorted((v1, v2))) edge_count[edge] = edge_count.get(edge, 0) + 1 # 筛选出仅出现一次的边(边界边),并恢复为有向边的形式 boundary_edges = [] for face in faces: vertex_indices = face['vertex_indices'] face_len = len(vertex_indices) for i in range(face_len): v1 = vertex_indices[i] v2 = vertex_indices[(i+1) % face_len] edge = tuple(sorted((v1, v2))) if edge_count[edge] == 1: boundary_edges.append((v1, v2)) return boundary_edges def edges_to_polygon_loop(boundary_edges, vertices): if not boundary_edges: return [] # 构建顶点到相邻边的映射,方便快速查找下一条边 vertex_edge_map = {} for edge in boundary_edges: v_start, v_end = edge if v_start not in vertex_edge_map: vertex_edge_map[v_start] = [] vertex_edge_map[v_start].append(edge) if v_end not in vertex_edge_map: vertex_edge_map[v_end] = [] vertex_edge_map[v_end].append(edge) # 从第一条边开始构建环 start_edge = boundary_edges[0] current_v = start_edge[1] polygon_loop = [vertices[start_edge[0]], vertices[current_v]] visited_edges = set([start_edge]) while current_v != start_edge[0]: # 找到当前顶点出发的未访问边 for edge in vertex_edge_map.get(current_v, []): if edge not in visited_edges: next_v = edge[1] if edge[0] == current_v else edge[0] polygon_loop.append(vertices[next_v]) visited_edges.add(edge) current_v = next_v break return polygon_loop # 读取PLY文件 with open('M:\\volume.ply', 'rb') as f: ply = plyfile.PlyData.read(f) vertices = ply['vertex'] faces = ply['face'] # 获取边界边 boundary_edges = get_boundary_edges(faces) # 构建多边形环 polygon = edges_to_polygon_loop(boundary_edges, vertices) # 输出结果示例 print("生成的多边形顶点数量:", len(polygon))
关键修复点说明
- 筛选边界边:通过统计每条边的出现次数,仅保留出现一次的边,确保后续处理的是真正的边界。
- 用顶点索引处理边:避免浮点坐标的精度问题,同时统一边的存储形式(排序索引),确保(v1,v2)和(v2,v1)被识别为同一条边。
- 优化遍历逻辑:构建顶点到边的映射,提升查找下一条边的效率,同时保证环的正确闭合。
内容的提问来源于stack exchange,提问作者Purple_Ad
相关产品推荐
相关产品推荐

