From aa0a6aa5d13ceb8bf14f45b608472164f17d87ea Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Tue, 1 Aug 2017 16:45:11 +0200 Subject: [PATCH] Fix #178 --- src/ifcconvert/IfcConvert.cpp | 5 +- src/ifcconvert/XmlSerializer.cpp | 4 +- src/ifcgeom/IfcGeomElement.h | 3 +- src/ifcgeom/IfcGeomFilter.h | 4 +- src/ifcgeom/IfcGeomFunctions.cpp | 101 ++++++++++++++++++++++++++----- src/ifcgeom/IfcGeomIterator.h | 74 +++++++++++++++++----- src/ifcgeom/IfcGeomShapes.cpp | 12 +++- src/ifcgeom/IfcGeomWires.cpp | 24 +++++++- src/ifcparse/IfcLogger.cpp | 6 ++ src/ifcparse/IfcLogger.h | 12 +++- src/ifcparse/IfcParse.cpp | 14 ++++- src/ifcparse/IfcSpfHeader.cpp | 5 +- 12 files changed, 222 insertions(+), 42 deletions(-) diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 3b97df7abc..d6720e70f4 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -322,6 +322,7 @@ int main(int argc, char** argv) print_usage(); return EXIT_FAILURE; } catch (...) { + std::cerr << "[Error] Unknown error parsing command line options\n\n"; print_usage(); return EXIT_FAILURE; } @@ -441,7 +442,9 @@ int main(int argc, char** argv) rename_file(output_temp_filename, output_filename); exit_code = EXIT_SUCCESS; } - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } write_log(); return exit_code; } diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index dc0f142d45..c9c99d8976 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -149,7 +149,9 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, pt boost::optional value; try { value = format_attribute(argument, argument_type, qualified_name); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } if (value) { if (as_link) { diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index b27f335ade..16c123b600 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -142,8 +142,9 @@ namespace IfcGeom { } else { try { oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); - } catch (const std::exception&) { + } catch (const std::exception& e) { oss << "product"; + Logger::Error(e); } } diff --git a/src/ifcgeom/IfcGeomFilter.h b/src/ifcgeom/IfcGeomFilter.h index 20cbd52653..043de7639a 100644 --- a/src/ifcgeom/IfcGeomFilter.h +++ b/src/ifcgeom/IfcGeomFilter.h @@ -189,7 +189,9 @@ namespace IfcGeom IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy); try { ss << " " << IfcSchema::Type::ToString(it->first) << "." << base->getArgumentName(it->second); - } catch(...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } delete base; } diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index e3ce460745..5711110c42 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -177,7 +177,15 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l builder.Perform(); shape = builder.SewedShape(); valid_shell = BRepCheck_Analyzer(shape).IsValid() != 0 && count(shape, TopAbs_SHELL) > 0; - } catch (...) {} + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error sewing shell"); + } + } catch (...) { + Logger::Error("Unknown error sewing shell"); + } if (valid_shell) { TopoDS_Shape complete_shape; @@ -197,9 +205,25 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l if (classifier.State() == TopAbs_IN) { shape.Reverse(); } - } catch (...) {} + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error classifying solid"); + } + } catch (...) { + Logger::Error("Unknown error classifying solid"); + } } - } catch (...) {} + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error creating solid"); + } + } catch (...) { + Logger::Error("Unknown error creating solid"); + } if (complete_shape.IsNull()) { complete_shape = result_shape; @@ -269,7 +293,11 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons if (fes->hasObjectPlacement()) { try { convert(fes->ObjectPlacement(),opening_trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } } // Move the opening into the coordinate system of the IfcProduct @@ -438,7 +466,11 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, if (fes->hasObjectPlacement()) { try { convert(fes->ObjectPlacement(),opening_trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } } // Move the opening into the coordinate system of the IfcProduct @@ -513,7 +545,11 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, if (fes->hasObjectPlacement()) { try { convert(fes->ObjectPlacement(),opening_trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } } // Move the opening into the coordinate system of the IfcProduct @@ -597,8 +633,17 @@ bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& bool IfcGeom::Kernel::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire) { try { wire = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(curve)); - } catch(...) { return false; } - return true; + return true; + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error convering curve to wire"); + } + } catch (...) { + Logger::Error("Unknown error convering curve to wire"); + } + return false; } bool IfcGeom::Kernel::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face_shape) { @@ -896,7 +941,15 @@ bool IfcGeom::Kernel::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& sha ShapeFix_Solid solid; solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); shape = solid.SolidFromShell(TopoDS::Shell(shape)); - } catch(...) {} + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error creating solid"); + } + } catch (...) { + Logger::Error("Unknown error creating solid"); + } return true; } @@ -1133,7 +1186,9 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_representation_and_pro if (parent_object) { parent_id = parent_object->entity->id(); } - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } const std::string name = product->hasName() ? product->Name() : ""; const std::string guid = product->GlobalId(); @@ -1141,7 +1196,11 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_representation_and_pro gp_Trsf trsf; try { convert(product->ObjectPlacement(),trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } // Does the IfcElement have any IfcOpenings? // Note that openings for IfcOpeningElements are not processed @@ -1225,7 +1284,9 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_processed_representati if (parent_object) { parent_id = parent_object->entity->id(); } - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } const std::string name = product->hasName() ? product->Name() : ""; const std::string guid = product->GlobalId(); @@ -1233,7 +1294,11 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_processed_representati gp_Trsf trsf; try { convert(product->ObjectPlacement(),trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } std::string context_string = ""; if (representation->hasRepresentationIdentifier()) { @@ -2255,7 +2320,15 @@ bool IfcGeom::Kernel::split_solid_by_shell(const TopoDS_Shape& input, const Topo if (fix.Perform()) { shape = fix.Shape(); } - } catch(...) {} + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error performing fixes"); + } + } catch (...) { + Logger::Error("Unknown error performing fixes"); + } BRepCheck_Analyzer analyser(shape); bool is_valid = analyser.IsValid() != 0; if (!is_valid) { diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index f8cb45c983..e8df3f0c3c 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -159,7 +159,9 @@ namespace IfcGeom { bool initialize() { try { initUnits(); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } std::set allowed_context_types; allowed_context_types.insert("model"); @@ -212,7 +214,9 @@ namespace IfcGeom { filtered_contexts->push(context); } } - } catch (const IfcParse::IfcException&) {} + } catch (const std::exception& e) { + Logger::Error(e); + } } // In case no contexts are identified based on their ContextType, all contexts are @@ -235,7 +239,10 @@ namespace IfcGeom { lowest_precision_encountered = context->Precision(); any_precision_encountered = true; } - } catch (const IfcParse::IfcException&) {} + } catch (const std::exception& e) { + Logger::Error(e); + } + IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts(); for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) { representations->push((*jt)->RepresentationsInContext()); @@ -286,9 +293,15 @@ namespace IfcGeom { // Use a fresh trsf every time in order to prevent the result to be concatenated gp_Trsf trsf; bool success = false; + try { success = kernel.convert(product->ObjectPlacement(), trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } + if (!success) { continue; } @@ -590,9 +603,10 @@ namespace IfcGeom { bool hasParent = true; // get the parent - try { parent_object = getObject(ret->parent_id()); } - catch (std::exception e) - { + try { + parent_object = getObject(parent_object->parent_id()); + } catch (const std::exception& e) { + Logger::Error(e); hasParent = false; } @@ -603,10 +617,10 @@ namespace IfcGeom { while (parent_object != NULL && hasParent) { // Find the next parent - try { parent_object = getObject(parent_object->parent_id()); } - catch (std::exception e) - { - std::cout << e.what(); + try { + parent_object = getObject(parent_object->parent_id()); + } catch (const std::exception& e) { + Logger::Error(e); hasParent = false; } @@ -650,12 +664,32 @@ namespace IfcGeom { if (parent_object) { parent_id = parent_object->entity->id(); } - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to find decomposing entity"); + } + try { kernel.convert(ifc_product->ObjectPlacement(), trsf); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } } - } catch(...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error returning product"); + } + } catch (...) { + Logger::Error("Unknown error returning product"); + } + ElementSettings element_settings(settings, unit_magnitude, instance_type); Element

* ifc_object = new Element

(element_settings, id, parent_id, product_name, instance_type, product_guid, "", trsf, ifc_product); @@ -669,7 +703,17 @@ namespace IfcGeom { try { next_shape_model = create_shape_model_for_next_entity(); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error creating geometry"); + } + } catch (...) { + Logger::Error("Unknown error creating geometry"); + } if (next_shape_model) { if (settings.get(IteratorSettings::USE_BREP_DATA)) { diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index ee2071b656..c8ca507b52 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -579,7 +579,17 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh try { success = convert_face(*it, face); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Error(e.GetMessageString()); + } else { + Logger::Error("Unknown error creating face"); + } + } catch (...) { + Logger::Error("Unknown error creating face"); + } if (!success) { Logger::Message(Logger::LOG_WARNING, "Failed to convert face:", (*it)->entity); diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp index 3af5c6a6eb..8fea27700d 100644 --- a/src/ifcgeom/IfcGeomWires.cpp +++ b/src/ifcgeom/IfcGeomWires.cpp @@ -104,13 +104,33 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire TopoDS_Wire wire_radians, wire_degrees; try { succes_radians = IfcGeom::Kernel::convert(l,wire_radians); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Notice(e); + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Notice(e.GetMessageString()); + } else { + Logger::Notice("Unknown error using radians"); + } + } catch (...) { + Logger::Notice("Unknown error using radians"); + } // Now try degrees setValue(GV_PLANEANGLE_UNIT,0.0174532925199433); try { succes_degrees = IfcGeom::Kernel::convert(l,wire_degrees); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Notice(e); + } catch (const Standard_Failure& e) { + if (e.GetMessageString() && strlen(e.GetMessageString())) { + Logger::Notice(e.GetMessageString()); + } else { + Logger::Notice("Unknown error using degrees"); + } + } catch (...) { + Logger::Notice("Unknown error using degrees"); + } // Restore to unknown unit state setValue(GV_PLANEANGLE_UNIT,-1.0); diff --git a/src/ifcparse/IfcLogger.cpp b/src/ifcparse/IfcLogger.cpp index e7dd2d9a2e..4fe538365e 100644 --- a/src/ifcparse/IfcLogger.cpp +++ b/src/ifcparse/IfcLogger.cpp @@ -37,6 +37,7 @@ void Logger::SetOutput(std::ostream* l1, std::ostream* l2) { log2 = &log_stream; } } + void Logger::Message(Logger::Severity type, const std::string& message, IfcEntityInstanceData* entity) { if ( log2 && type >= verbosity ) { (*log2) << "[" << severity_strings[type] << "] "; @@ -47,6 +48,11 @@ void Logger::Message(Logger::Severity type, const std::string& message, IfcEntit if ( entity ) (*log2) << entity->toString() << std::endl; } } + +void Logger::Message(Logger::Severity type, const std::exception& exception, IfcEntityInstanceData* entity) { + Message(type, exception.what(), entity); +} + void Logger::Status(const std::string& message, bool new_line) { if ( log1 ) { (*log1) << message; diff --git a/src/ifcparse/IfcLogger.h b/src/ifcparse/IfcLogger.h index 2ff2228b1b..f5e6f9c0ee 100644 --- a/src/ifcparse/IfcLogger.h +++ b/src/ifcparse/IfcLogger.h @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef USE_IFC4 #include "../ifcparse/Ifc4.h" @@ -53,12 +54,21 @@ public: /// Determines the types of log messages to get logged static void Verbosity(Severity v); static Severity Verbosity(); + /// Log a message to the output stream static void Message(Severity type, const std::string& message, IfcEntityInstanceData* entity=0); - static void Notice(const std::string& message, IfcEntityInstanceData* entity = 0) { Message(LOG_NOTICE, message, entity); } + static void Message(Severity type, const std::exception& message, IfcEntityInstanceData* entity = 0); + + static void Notice(const std::string& message, IfcEntityInstanceData* entity = 0) { Message(LOG_NOTICE, message, entity); } static void Warning(const std::string& message, IfcEntityInstanceData* entity=0) { Message(LOG_WARNING, message, entity); } static void Error(const std::string& message, IfcEntityInstanceData* entity=0) { Message(LOG_ERROR, message, entity); } + + static void Notice(const std::exception& exception, IfcEntityInstanceData* entity = 0) { Message(LOG_NOTICE, exception, entity); } + static void Warning(const std::exception& exception, IfcEntityInstanceData* entity = 0) { Message(LOG_WARNING, exception, entity); } + static void Error(const std::exception& exception, IfcEntityInstanceData* entity = 0) { Message(LOG_ERROR, exception, entity); } + static void Status(const std::string& message, bool new_line=true); + static void ProgressBar(int progress); static std::string GetLog(); }; diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index e5f3a6ebce..71bba0b599 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -1254,7 +1254,10 @@ bool IfcFile::Init(IfcParse::IfcSpfStream* s) { std::vector schemas; try { schemas = _header.file_schema().schema_identifiers(); - } catch (...) {} + } catch (...) { + // Purposely empty catch block + } + if (schemas.size() != 1 || schemas[0] != IfcSchema::Identifier) { Logger::Message(Logger::LOG_ERROR, std::string("File schema encountered different from expected '") + IfcSchema::Identifier + "'"); } @@ -1558,7 +1561,10 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) { IfcEntityList::ptr entity_attributes(new IfcEntityList); try { entity_attributes = traverse(entity, 1); - } catch (...) {} + } catch (const std::exception& e) { + Logger::Error(e); + } + for (IfcEntityList::it it = entity_attributes->begin(); it != entity_attributes->end(); ++it) { IfcUtil::IfcBaseClass* entity_attribute = *it; if (*it == entity) continue; @@ -1567,7 +1573,9 @@ IfcUtil::IfcBaseClass* IfcFile::addEntity(IfcUtil::IfcBaseClass* entity) { unsigned entity_attribute_id = entity_attribute->entity->id(); byref[entity_attribute_id].push_back(entity->entity->id()); } - } catch (const IfcParse::IfcException&) {} + } catch (const std::exception& e) { + Logger::Error(e); + } } return entity; diff --git a/src/ifcparse/IfcSpfHeader.cpp b/src/ifcparse/IfcSpfHeader.cpp index ce1dcf87c0..df55a0bf07 100644 --- a/src/ifcparse/IfcSpfHeader.cpp +++ b/src/ifcparse/IfcSpfHeader.cpp @@ -104,9 +104,10 @@ bool IfcSpfHeader::tryRead() { try { read(); return true; - } catch(const IfcException&) { + } catch (const std::exception& e) { + Logger::Error(e); return false; - } + } } void IfcSpfHeader::write(std::ostream& os) const {