mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-06 07:51:47 +00:00
Fix shapely topology crash in boundary generation
Add buffer(0) validation for space_face_polygon and face_polygon before intersection, following the same pattern as tool/cad.py. Wrap the intersection in try/except for shapely.errors.GEOSException to catch remaining topology errors. On exception, set bonsai.last_error (so the 'Copy Error Message To Clipboard' button appears in the UI), report an ERROR to the operator, and continue processing other face pairs instead of crashing. Generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
|
||||
import logging
|
||||
import multiprocessing
|
||||
import traceback
|
||||
from math import acos, degrees, inf, pi, radians
|
||||
from typing import Optional, Union
|
||||
|
||||
@@ -38,6 +39,7 @@ import shapely.ops
|
||||
from ifcopenshell.util.shape_builder import ShapeBuilder
|
||||
from mathutils import Matrix, Vector
|
||||
|
||||
import bonsai
|
||||
import bonsai.bim.import_ifc as import_ifc
|
||||
import bonsai.core.attribute as core
|
||||
import bonsai.core.geometry
|
||||
@@ -804,12 +806,26 @@ class AddBoundary(bpy.types.Operator, tool.Ifc.Operator):
|
||||
space_face_polygon = shapely.Polygon(
|
||||
[tuple((space_face_matrix_i @ v).xy) for v in space_face_verts]
|
||||
)
|
||||
if not space_face_polygon.is_valid:
|
||||
space_face_polygon = space_face_polygon.buffer(0)
|
||||
|
||||
space_matrix_world_i = space_obj.matrix_world.inverted()
|
||||
face_verts = [space_matrix_world_i @ building_obj.matrix_world @ v.co.copy() for v in face.verts]
|
||||
face_polygon = shapely.Polygon([tuple((space_face_matrix_i @ v).xy) for v in face_verts])
|
||||
if not face_polygon.is_valid:
|
||||
face_polygon = face_polygon.buffer(0)
|
||||
|
||||
gross_boundary_polygon = space_face_polygon.intersection(face_polygon)
|
||||
try:
|
||||
gross_boundary_polygon = space_face_polygon.intersection(face_polygon)
|
||||
except shapely.errors.GEOSException:
|
||||
bonsai.last_error = traceback.format_exc()
|
||||
element_name = building_element.Name or building_element.is_a()
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
f"Skipping invalid geometry for {element_name} (shapely topology error). "
|
||||
"See 'Copy Error Message To Clipboard' for details.",
|
||||
)
|
||||
continue
|
||||
|
||||
if type(gross_boundary_polygon) == shapely.GeometryCollection:
|
||||
for geom in gross_boundary_polygon.geoms:
|
||||
|
||||
Reference in New Issue
Block a user