mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
ifcgeom: fall back to unopened geometry when convert_openings() cleanly fails
Converter::create_brep_for_representation() called kernel_->convert_openings() without checking its return value. When every candidate kernel rejects the boolean operands (e.g. CgalKernel's Nef conversion refuses self-intersecting geometry and returns false without throwing), opened_shapes stays empty and the guard below, which exists to preserve the product's unopened geometry on failure, only looked at caught_error from a thrown exception. A clean `false` return slipped past it, so the empty opened_shapes silently replaced the product's valid solid and the element vanished instead of degrading to its unclipped shape, the way every other failure path in this code already does. Reproduced with the IfcWindow from #5880's attached file: `--kernel cgal` and `--kernel hybrid-cgal-opencascade` produced 0 vertices (window disappears) even though OpenCASCADE alone converts it fine (152 vertices). With this fix both now log the self-intersection error and still emit the window's unopened geometry (268 vertices) instead of nothing. Bonsai's actual default, hybrid-cgal-simple-opencascade, isn't affected by this particular file: HybridKernel already skips the non-boolean CGAL-simple kernel for elements with openings and goes straight to OpenCASCADE. Verified byte-identical output (0 diffs) on that path and on plain opencascade for both the reported window and a second reporter-attached roof file. Full regression pass over all 258 test/input/*.ifc fixtures: 244 byte-identical between the unpatched and patched binary, the remaining 14 fail identically before and after (pre-existing crash/timeout repro fixtures, e.g. outOfMemory/segfault/infiniteLoop/invalid.ifc), 0 new failures. Fixes #5880. This commit contains AI-generated code, generated with the assistance of an AI coding tool.
This commit is contained in:
@@ -205,8 +205,10 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
|
||||
if (opening_items.empty()) {
|
||||
opened_shapes = shapes;
|
||||
} else {
|
||||
kernel_->convert_openings(product, opening_items, shapes, *place, opened_shapes);
|
||||
} else if (!kernel_->convert_openings(product, opening_items, shapes, *place, opened_shapes)) {
|
||||
// A clean `false` return is a failure just like a thrown exception.
|
||||
logger_.Message(Logger::LOG_ERROR, "GEO", 34, "Error processing openings for:", product);
|
||||
caught_error = true;
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
logger_.Message(Logger::LOG_ERROR, "GEO", 33, std::string("Error processing openings for: ") + e.what() + ":", product);
|
||||
|
||||
Reference in New Issue
Block a user