From 86c93ac1e76c5b042075a782cdb4259594fbaf78 Mon Sep 17 00:00:00 2001 From: Chetan Date: Wed, 7 Jun 2023 16:54:28 +0800 Subject: [PATCH] If an IFC file has an IFCRELASSOCIATESMATERIAL but did not supply an IFCMATERIAL, IfcConvert will crash. This commit prevents the crash, catches the exception and prints an error on the terminal --- src/ifcgeom/mapping/mapping.cpp | 28 ++++++++++++++++++---------- src/ifcparse/IfcFile.h | 5 ----- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/ifcgeom/mapping/mapping.cpp b/src/ifcgeom/mapping/mapping.cpp index 1f05206e45..9867683cf8 100644 --- a/src/ifcgeom/mapping/mapping.cpp +++ b/src/ifcgeom/mapping/mapping.cpp @@ -250,17 +250,25 @@ const IfcUtil::IfcBaseEntity* mapping::get_single_material_association(const Ifc IfcSchema::IfcMaterial* single_material = 0; IfcSchema::IfcRelAssociatesMaterial::list::ptr associated_materials = product->HasAssociations()->as(); if (associated_materials->size() == 1) { - IfcSchema::IfcMaterialSelect* associated_material = (*associated_materials->begin())->RelatingMaterial(); - single_material = associated_material->as(); + IfcSchema::IfcMaterialSelect* associated_material = nullptr; - // NB: Single-layer layersets are also considered, regardless of --enable-layerset-slicing, this - // in accordance with other viewers. - if (!single_material && associated_material->as()) { - IfcSchema::IfcMaterialLayerSet* layerset = associated_material->as()->ForLayerSet(); - if (layerset->MaterialLayers()->size() == 1) { - IfcSchema::IfcMaterialLayer* layer = (*layerset->MaterialLayers()->begin()); - if (layer->Material()) { - single_material = layer->Material(); + try { + associated_material = (*associated_materials->begin())->RelatingMaterial(); + } catch(IfcParse::IfcException& e) { + Logger::Error(e.what()); + } + + if (associated_material) { + single_material = associated_material->as(); + // NB: Single-layer layersets are also considered, regardless of --enable-layerset-slicing, this + // in accordance with other viewers. + if (!single_material && associated_material->as()) { + IfcSchema::IfcMaterialLayerSet* layerset = associated_material->as()->ForLayerSet(); + if (settings_.get().value ? layerset->MaterialLayers()->size() >= 1 : layerset->MaterialLayers()->size() == 1) { + IfcSchema::IfcMaterialLayer* layer = (*layerset->MaterialLayers()->begin()); + if (layer->Material()) { + single_material = layer->Material(); + } } } } diff --git a/src/ifcparse/IfcFile.h b/src/ifcparse/IfcFile.h index f63d3eeae7..b62126841a 100644 --- a/src/ifcparse/IfcFile.h +++ b/src/ifcparse/IfcFile.h @@ -266,11 +266,6 @@ class IFC_PARSE_API IfcFile { int getTotalInverses(int instance_id); - template - typename T::list::ptr getInverse(int instance_id, int attribute_index) { - return getInverse(instance_id, &T::Class(), attribute_index)->template as(); - } - unsigned int FreshId() { return ++MaxId; } unsigned int getMaxId() const { return MaxId; }