mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 22:11:36 +00:00
Fix dissolve_faces polygon reconstruction with merge_coplanar
When merge_coplanar merges two sub-faces that share an edge from the original BRep (e.g. two rectangles forming an L-shape cap), that shared edge remained in boundary_edges via original_edges filtering, causing the edge_adjacency walk to produce wrong polygons. Fix: after coplanar merging, use edge frequency (edges used by exactly 1 triangle = boundary) instead of original_edges filtering, which correctly identifies only outer boundary edges. Also add safety checks: edge_adjacency emptiness guard, infinite loop protection, and minimum polygon length check. Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -914,11 +914,16 @@ def dissolve_faces(
|
|||||||
result = []
|
result = []
|
||||||
for tri_indices in ngons.values():
|
for tri_indices in ngons.values():
|
||||||
tri_edge_set = set()
|
tri_edge_set = set()
|
||||||
|
edge_count: dict[frozenset, int] = {}
|
||||||
for tri_idx in tri_indices:
|
for tri_idx in tri_indices:
|
||||||
for e in tri_edges[tri_idx]:
|
for e in tri_edges[tri_idx]:
|
||||||
tri_edge_set.add(e)
|
tri_edge_set.add(e)
|
||||||
|
edge_count[e] = edge_count.get(e, 0) + 1
|
||||||
|
|
||||||
boundary_edges = [e for e in tri_edge_set if e in original_edges]
|
if merge_coplanar:
|
||||||
|
boundary_edges = [e for e in tri_edge_set if edge_count.get(e, 0) == 1]
|
||||||
|
else:
|
||||||
|
boundary_edges = [e for e in tri_edge_set if e in original_edges]
|
||||||
|
|
||||||
if not boundary_edges:
|
if not boundary_edges:
|
||||||
result.append(list(faces[tri_indices[0]]))
|
result.append(list(faces[tri_indices[0]]))
|
||||||
@@ -938,15 +943,21 @@ def dissolve_faces(
|
|||||||
continue
|
continue
|
||||||
break
|
break
|
||||||
|
|
||||||
|
if not edge_adjacency:
|
||||||
|
result.append(list(faces[tri_indices[0]]))
|
||||||
|
continue
|
||||||
|
|
||||||
start = next(iter(edge_adjacency))
|
start = next(iter(edge_adjacency))
|
||||||
polygon = [start]
|
polygon = [start]
|
||||||
current = edge_adjacency[start]
|
current = edge_adjacency[start]
|
||||||
while current != start:
|
while current != start and current in edge_adjacency:
|
||||||
polygon.append(current)
|
polygon.append(current)
|
||||||
if current not in edge_adjacency:
|
|
||||||
break
|
|
||||||
current = edge_adjacency[current]
|
current = edge_adjacency[current]
|
||||||
result.append(polygon)
|
|
||||||
|
if len(polygon) >= 3:
|
||||||
|
result.append(polygon)
|
||||||
|
else:
|
||||||
|
result.append(list(faces[tri_indices[0]]))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user