mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
ifcgeom: fall back to unsliced representation when layerset slicing fails #6607
--enable-layerset-slicing aborted the entire IfcConvert run (0 objects) on the first element whose layerset could not be resolved. get_layerset_information can throw (e.g. a wall Axis representation that is not castable to a curve -> "Unexpected topology"), and apply_layerset / apply_folded_layerset resolve to the AbstractKernel stubs that throw not_implemented on the OpenCascade kernel. That exception was uncaught at the call site, so it propagated out and dropped every element, not just the one that failed. Wrap the layerset block in a try/catch: on failure, log GEO 260 and keep the element's already-built unsliced body representation instead of letting the exception abort the conversion. Elements that slice successfully are untouched (the previous return values were already ignored). Verified with a local OpenCascade build (OCC 7.9.2) on the reporter's Cassiopae sample: --enable-layerset-slicing before the fix exits 1 with 0 objects (GEO060 Unexpected topology); after the fix it emits all 215 objects (90 GEO260 fallback warnings), and default (no-slicing) output is byte-identical before and after. Note: geometric slicing itself is not implemented on the OpenCascade kernel on this line, so the recovered elements are emitted unsliced; this change only stops the flag from silently dropping them. Generated with the assistance of an AI coding tool. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -55,17 +55,29 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
|
||||
std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information> neigbour_layers;
|
||||
int layerset_id, lid;
|
||||
|
||||
if (mapping_->get_layerset_information(product, layerinfo, layerset_id)) {
|
||||
representation_id_builder << "-layerset-" << layerset_id;
|
||||
if (mapping_->get_wall_neighbours(product, neighbours)) {
|
||||
for (auto& n : neighbours) {
|
||||
auto p = std::get<2>(n);
|
||||
mapping_->get_layerset_information(p, neigbour_layers[p], lid);
|
||||
// Layerset slicing is best-effort: gathering the layerset information or
|
||||
// applying it may throw (e.g. when the axis representation cannot be cast
|
||||
// to a curve, or when the active kernel does not implement slicing). In
|
||||
// that case the element still has a perfectly valid unsliced body
|
||||
// representation in `shapes`, so we fall back to that rather than letting
|
||||
// the exception propagate and silently drop the element entirely (#6607).
|
||||
try {
|
||||
if (mapping_->get_layerset_information(product, layerinfo, layerset_id)) {
|
||||
representation_id_builder << "-layerset-" << layerset_id;
|
||||
if (mapping_->get_wall_neighbours(product, neighbours)) {
|
||||
for (auto& n : neighbours) {
|
||||
auto p = std::get<2>(n);
|
||||
mapping_->get_layerset_information(p, neigbour_layers[p], lid);
|
||||
}
|
||||
kernel_->apply_folded_layerset(shapes, layerinfo, neigbour_layers);
|
||||
} else {
|
||||
kernel_->apply_layerset(shapes, layerinfo);
|
||||
}
|
||||
kernel_->apply_folded_layerset(shapes, layerinfo, neigbour_layers);
|
||||
} else {
|
||||
kernel_->apply_layerset(shapes, layerinfo);
|
||||
}
|
||||
} catch (const std::exception& e) {
|
||||
logger_.Message(Logger::LOG_WARNING, "GEO", 260, std::string("Layerset slicing failed, falling back to unsliced representation: ") + e.what(), product);
|
||||
} catch (...) {
|
||||
logger_.Message(Logger::LOG_WARNING, "GEO", 260, "Layerset slicing failed, falling back to unsliced representation", product);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user